]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/pac207.c
wireless: remove duplicated .ndo_set_mac_address
[linux-2.6-omap-h63xx.git] / drivers / media / video / gspca / pac207.c
1 /*
2  * Pixart PAC207BCA library
3  *
4  * Copyright (C) 2008 Hans de Goede <hdgoede@redhat.com>
5  * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
6  * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
7  *
8  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  */
25
26 #define MODULE_NAME "pac207"
27
28 #include "gspca.h"
29
30 MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
31 MODULE_DESCRIPTION("Pixart PAC207");
32 MODULE_LICENSE("GPL");
33
34 #define PAC207_CTRL_TIMEOUT             100  /* ms */
35
36 #define PAC207_BRIGHTNESS_MIN           0
37 #define PAC207_BRIGHTNESS_MAX           255
38 #define PAC207_BRIGHTNESS_DEFAULT       4 /* power on default: 4 */
39
40 /* An exposure value of 4 also works (3 does not) but then we need to lower
41    the compression balance setting when in 352x288 mode, otherwise the usb
42    bandwidth is not enough and packets get dropped resulting in corrupt
43    frames. The problem with this is that when the compression balance gets
44    lowered below 0x80, the pac207 starts using a different compression
45    algorithm for some lines, these lines get prefixed with a 0x2dd2 prefix
46    and currently we do not know how to decompress these lines, so for now
47    we use a minimum exposure value of 5 */
48 #define PAC207_EXPOSURE_MIN             5
49 #define PAC207_EXPOSURE_MAX             26
50 #define PAC207_EXPOSURE_DEFAULT         5 /* power on default: 3 ?? */
51 #define PAC207_EXPOSURE_KNEE            11 /* 4 = 30 fps, 11 = 8, 15 = 6 */
52
53 #define PAC207_GAIN_MIN                 0
54 #define PAC207_GAIN_MAX                 31
55 #define PAC207_GAIN_DEFAULT             9 /* power on default: 9 */
56 #define PAC207_GAIN_KNEE                20
57
58 #define PAC207_AUTOGAIN_DEADZONE        30
59
60 /* specific webcam descriptor */
61 struct sd {
62         struct gspca_dev gspca_dev;             /* !! must be the first item */
63
64         u8 mode;
65
66         u8 brightness;
67         u8 exposure;
68         u8 autogain;
69         u8 gain;
70
71         u8 sof_read;
72         u8 header_read;
73         u8 autogain_ignore_frames;
74
75         atomic_t avg_lum;
76 };
77
78 /* V4L2 controls supported by the driver */
79 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
80 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
81 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
82 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
83 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
84 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
85 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
86 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
87
88 static struct ctrl sd_ctrls[] = {
89 #define SD_BRIGHTNESS 0
90         {
91             {
92                 .id      = V4L2_CID_BRIGHTNESS,
93                 .type    = V4L2_CTRL_TYPE_INTEGER,
94                 .name    = "Brightness",
95                 .minimum = PAC207_BRIGHTNESS_MIN,
96                 .maximum = PAC207_BRIGHTNESS_MAX,
97                 .step = 1,
98                 .default_value = PAC207_BRIGHTNESS_DEFAULT,
99                 .flags = 0,
100             },
101             .set = sd_setbrightness,
102             .get = sd_getbrightness,
103         },
104 #define SD_EXPOSURE 1
105         {
106             {
107                 .id = V4L2_CID_EXPOSURE,
108                 .type = V4L2_CTRL_TYPE_INTEGER,
109                 .name = "exposure",
110                 .minimum = PAC207_EXPOSURE_MIN,
111                 .maximum = PAC207_EXPOSURE_MAX,
112                 .step = 1,
113                 .default_value = PAC207_EXPOSURE_DEFAULT,
114                 .flags = 0,
115             },
116             .set = sd_setexposure,
117             .get = sd_getexposure,
118         },
119 #define SD_AUTOGAIN 2
120         {
121             {
122                 .id       = V4L2_CID_AUTOGAIN,
123                 .type   = V4L2_CTRL_TYPE_BOOLEAN,
124                 .name   = "Auto Gain",
125                 .minimum = 0,
126                 .maximum = 1,
127                 .step   = 1,
128 #define AUTOGAIN_DEF 1
129                 .default_value = AUTOGAIN_DEF,
130                 .flags = 0,
131             },
132             .set = sd_setautogain,
133             .get = sd_getautogain,
134         },
135 #define SD_GAIN 3
136         {
137             {
138                 .id = V4L2_CID_GAIN,
139                 .type = V4L2_CTRL_TYPE_INTEGER,
140                 .name = "gain",
141                 .minimum = PAC207_GAIN_MIN,
142                 .maximum = PAC207_GAIN_MAX,
143                 .step = 1,
144                 .default_value = PAC207_GAIN_DEFAULT,
145                 .flags = 0,
146             },
147             .set = sd_setgain,
148             .get = sd_getgain,
149         },
150 };
151
152 static const struct v4l2_pix_format sif_mode[] = {
153         {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
154                 .bytesperline = 176,
155                 .sizeimage = (176 + 2) * 144,
156                         /* uncompressed, add 2 bytes / line for line header */
157                 .colorspace = V4L2_COLORSPACE_SRGB,
158                 .priv = 1},
159         {352, 288, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
160                 .bytesperline = 352,
161                         /* compressed, but only when needed (not compressed
162                            when the framerate is low) */
163                 .sizeimage = (352 + 2) * 288,
164                 .colorspace = V4L2_COLORSPACE_SRGB,
165                 .priv = 0},
166 };
167
168 static const __u8 pac207_sensor_init[][8] = {
169         {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0},
170         {0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
171         {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
172         {0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xa2, 0x02},
173         {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
174 };
175
176                         /* 48 reg_72 Rate Control end BalSize_4a =0x36 */
177 static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
178
179 static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
180         const u8 *buffer, u16 length)
181 {
182         struct usb_device *udev = gspca_dev->dev;
183         int err;
184
185         memcpy(gspca_dev->usb_buf, buffer, length);
186
187         err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
188                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
189                         0x00, index,
190                         gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT);
191         if (err < 0)
192                 PDEBUG(D_ERR,
193                         "Failed to write registers to index 0x%04X, error %d)",
194                         index, err);
195
196         return err;
197 }
198
199
200 static int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
201 {
202         struct usb_device *udev = gspca_dev->dev;
203         int err;
204
205         err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
206                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
207                         value, index, NULL, 0, PAC207_CTRL_TIMEOUT);
208         if (err)
209                 PDEBUG(D_ERR, "Failed to write a register (index 0x%04X,"
210                         " value 0x%02X, error %d)", index, value, err);
211
212         return err;
213 }
214
215 static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
216 {
217         struct usb_device *udev = gspca_dev->dev;
218         int res;
219
220         res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00,
221                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
222                         0x00, index,
223                         gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT);
224         if (res < 0) {
225                 PDEBUG(D_ERR,
226                         "Failed to read a register (index 0x%04X, error %d)",
227                         index, res);
228                 return res;
229         }
230
231         return gspca_dev->usb_buf[0];
232 }
233
234 /* this function is called at probe time */
235 static int sd_config(struct gspca_dev *gspca_dev,
236                         const struct usb_device_id *id)
237 {
238         struct sd *sd = (struct sd *) gspca_dev;
239         struct cam *cam;
240         u8 idreg[2];
241
242         idreg[0] = pac207_read_reg(gspca_dev, 0x0000);
243         idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
244         idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4);
245         idreg[1] = idreg[1] & 0x0f;
246         PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
247                 idreg[0], idreg[1]);
248
249         if (idreg[0] != 0x27) {
250                 PDEBUG(D_PROBE, "Error invalid sensor ID!");
251                 return -ENODEV;
252         }
253
254         PDEBUG(D_PROBE,
255                 "Pixart PAC207BCA Image Processor and Control Chip detected"
256                 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
257
258         cam = &gspca_dev->cam;
259         cam->epaddr = 0x05;
260         cam->cam_mode = sif_mode;
261         cam->nmodes = ARRAY_SIZE(sif_mode);
262         sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
263         sd->exposure = PAC207_EXPOSURE_DEFAULT;
264         sd->gain = PAC207_GAIN_DEFAULT;
265         sd->autogain = AUTOGAIN_DEF;
266
267         return 0;
268 }
269
270 /* this function is called at probe and resume time */
271 static int sd_init(struct gspca_dev *gspca_dev)
272 {
273         pac207_write_reg(gspca_dev, 0x41, 0x00);
274                                 /* Bit_0=Image Format,
275                                  * Bit_1=LED,
276                                  * Bit_2=Compression test mode enable */
277         pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
278         pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
279
280         return 0;
281 }
282
283 /* -- start the camera -- */
284 static int sd_start(struct gspca_dev *gspca_dev)
285 {
286         struct sd *sd = (struct sd *) gspca_dev;
287         __u8 mode;
288
289         pac207_write_reg(gspca_dev, 0x0f, 0x10); /* Power control (Bit 6-0) */
290         pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8);
291         pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8);
292         pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8);
293         pac207_write_regs(gspca_dev, 0x0040, pac207_sensor_init[3], 8);
294         pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[4], 8);
295         pac207_write_regs(gspca_dev, 0x0048, PacReg72, 4);
296
297         /* Compression Balance */
298         if (gspca_dev->width == 176)
299                 pac207_write_reg(gspca_dev, 0x4a, 0xff);
300         else
301                 pac207_write_reg(gspca_dev, 0x4a, 0x88);
302         pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
303         pac207_write_reg(gspca_dev, 0x08, sd->brightness);
304
305         /* PGA global gain (Bit 4-0) */
306         pac207_write_reg(gspca_dev, 0x0e, sd->gain);
307         pac207_write_reg(gspca_dev, 0x02, sd->exposure); /* PXCK = 12MHz /n */
308
309         mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */
310         if (gspca_dev->width == 176) {  /* 176x144 */
311                 mode |= 0x01;
312                 PDEBUG(D_STREAM, "pac207_start mode 176x144");
313         } else {                                /* 352x288 */
314                 PDEBUG(D_STREAM, "pac207_start mode 352x288");
315         }
316         pac207_write_reg(gspca_dev, 0x41, mode);
317
318         pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
319         pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
320         msleep(10);
321         pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */
322
323         sd->sof_read = 0;
324         sd->autogain_ignore_frames = 0;
325         atomic_set(&sd->avg_lum, -1);
326         return 0;
327 }
328
329 static void sd_stopN(struct gspca_dev *gspca_dev)
330 {
331         pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */
332         pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */
333         pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
334 }
335
336 /* Include pac common sof detection functions */
337 #include "pac_common.h"
338
339 static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
340 {
341         struct sd *sd = (struct sd *) gspca_dev;
342         int avg_lum = atomic_read(&sd->avg_lum);
343
344         if (avg_lum == -1)
345                 return;
346
347         if (sd->autogain_ignore_frames > 0)
348                 sd->autogain_ignore_frames--;
349         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
350                         100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
351                         PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
352                 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
353 }
354
355 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
356                         struct gspca_frame *frame,
357                         __u8 *data,
358                         int len)
359 {
360         struct sd *sd = (struct sd *) gspca_dev;
361         unsigned char *sof;
362
363         sof = pac_find_sof(gspca_dev, data, len);
364         if (sof) {
365                 int n;
366
367                 /* finish decoding current frame */
368                 n = sof - data;
369                 if (n > sizeof pac_sof_marker)
370                         n -= sizeof pac_sof_marker;
371                 else
372                         n = 0;
373                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
374                                         data, n);
375                 sd->header_read = 0;
376                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
377                 len -= sof - data;
378                 data = sof;
379         }
380         if (sd->header_read < 11) {
381                 int needed;
382
383                 /* get average lumination from frame header (byte 5) */
384                 if (sd->header_read < 5) {
385                         needed = 5 - sd->header_read;
386                         if (len >= needed)
387                                 atomic_set(&sd->avg_lum, data[needed - 1]);
388                 }
389                 /* skip the rest of the header */
390                 needed = 11 - sd->header_read;
391                 if (len <= needed) {
392                         sd->header_read += len;
393                         return;
394                 }
395                 data += needed;
396                 len -= needed;
397                 sd->header_read = 11;
398         }
399
400         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
401 }
402
403 static void setbrightness(struct gspca_dev *gspca_dev)
404 {
405         struct sd *sd = (struct sd *) gspca_dev;
406
407         pac207_write_reg(gspca_dev, 0x08, sd->brightness);
408         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
409         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
410 }
411
412 static void setexposure(struct gspca_dev *gspca_dev)
413 {
414         struct sd *sd = (struct sd *) gspca_dev;
415
416         pac207_write_reg(gspca_dev, 0x02, sd->exposure);
417         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
418         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
419 }
420
421 static void setgain(struct gspca_dev *gspca_dev)
422 {
423         struct sd *sd = (struct sd *) gspca_dev;
424
425         pac207_write_reg(gspca_dev, 0x0e, sd->gain);
426         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
427         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
428 }
429
430 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
431 {
432         struct sd *sd = (struct sd *) gspca_dev;
433
434         sd->brightness = val;
435         if (gspca_dev->streaming)
436                 setbrightness(gspca_dev);
437         return 0;
438 }
439
440 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
441 {
442         struct sd *sd = (struct sd *) gspca_dev;
443
444         *val = sd->brightness;
445         return 0;
446 }
447
448 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
449 {
450         struct sd *sd = (struct sd *) gspca_dev;
451
452         sd->exposure = val;
453         if (gspca_dev->streaming)
454                 setexposure(gspca_dev);
455         return 0;
456 }
457
458 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
459 {
460         struct sd *sd = (struct sd *) gspca_dev;
461
462         *val = sd->exposure;
463         return 0;
464 }
465
466 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
467 {
468         struct sd *sd = (struct sd *) gspca_dev;
469
470         sd->gain = val;
471         if (gspca_dev->streaming)
472                 setgain(gspca_dev);
473         return 0;
474 }
475
476 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
477 {
478         struct sd *sd = (struct sd *) gspca_dev;
479
480         *val = sd->gain;
481         return 0;
482 }
483
484 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
485 {
486         struct sd *sd = (struct sd *) gspca_dev;
487
488         sd->autogain = val;
489         /* when switching to autogain set defaults to make sure
490            we are on a valid point of the autogain gain /
491            exposure knee graph, and give this change time to
492            take effect before doing autogain. */
493         if (sd->autogain) {
494                 sd->exposure = PAC207_EXPOSURE_DEFAULT;
495                 sd->gain = PAC207_GAIN_DEFAULT;
496                 if (gspca_dev->streaming) {
497                         sd->autogain_ignore_frames =
498                                 PAC_AUTOGAIN_IGNORE_FRAMES;
499                         setexposure(gspca_dev);
500                         setgain(gspca_dev);
501                 }
502         }
503
504         return 0;
505 }
506
507 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
508 {
509         struct sd *sd = (struct sd *) gspca_dev;
510
511         *val = sd->autogain;
512         return 0;
513 }
514
515 /* sub-driver description */
516 static const struct sd_desc sd_desc = {
517         .name = MODULE_NAME,
518         .ctrls = sd_ctrls,
519         .nctrls = ARRAY_SIZE(sd_ctrls),
520         .config = sd_config,
521         .init = sd_init,
522         .start = sd_start,
523         .stopN = sd_stopN,
524         .dq_callback = pac207_do_auto_gain,
525         .pkt_scan = sd_pkt_scan,
526 };
527
528 /* -- module initialisation -- */
529 static const __devinitdata struct usb_device_id device_table[] = {
530         {USB_DEVICE(0x041e, 0x4028)},
531         {USB_DEVICE(0x093a, 0x2460)},
532         {USB_DEVICE(0x093a, 0x2461)},
533         {USB_DEVICE(0x093a, 0x2463)},
534         {USB_DEVICE(0x093a, 0x2464)},
535         {USB_DEVICE(0x093a, 0x2468)},
536         {USB_DEVICE(0x093a, 0x2470)},
537         {USB_DEVICE(0x093a, 0x2471)},
538         {USB_DEVICE(0x093a, 0x2472)},
539         {USB_DEVICE(0x093a, 0x2476)},
540         {USB_DEVICE(0x145f, 0x013a)},
541         {USB_DEVICE(0x2001, 0xf115)},
542         {}
543 };
544 MODULE_DEVICE_TABLE(usb, device_table);
545
546 /* -- device connect -- */
547 static int sd_probe(struct usb_interface *intf,
548                         const struct usb_device_id *id)
549 {
550         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
551                                 THIS_MODULE);
552 }
553
554 static struct usb_driver sd_driver = {
555         .name = MODULE_NAME,
556         .id_table = device_table,
557         .probe = sd_probe,
558         .disconnect = gspca_disconnect,
559 #ifdef CONFIG_PM
560         .suspend = gspca_suspend,
561         .resume = gspca_resume,
562 #endif
563 };
564
565 /* -- module insert / remove -- */
566 static int __init sd_mod_init(void)
567 {
568         if (usb_register(&sd_driver) < 0)
569                 return -1;
570         PDEBUG(D_PROBE, "registered");
571         return 0;
572 }
573 static void __exit sd_mod_exit(void)
574 {
575         usb_deregister(&sd_driver);
576         PDEBUG(D_PROBE, "deregistered");
577 }
578
579 module_init(sd_mod_init);
580 module_exit(sd_mod_exit);