V4L/DVB (8812): gspca: Do pac73xx webcams work.
[linux-2.6.git] / drivers / media / video / gspca / pac207.c
1 /*
2  * Pixart PAC207BCA library
3  *
4  * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
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 <j.w.r.degoede@hhs.nl>");
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 /* We calculating the autogain at the end of the transfer of a frame, at this
60    moment a frame with the old settings is being transmitted, and a frame is
61    being captured with the old settings. So if we adjust the autogain we must
62    ignore atleast the 2 next frames for the new settings to come into effect
63    before doing any other adjustments */
64 #define PAC207_AUTOGAIN_IGNORE_FRAMES   3
65
66 /* specific webcam descriptor */
67 struct sd {
68         struct gspca_dev gspca_dev;             /* !! must be the first item */
69
70         u8 mode;
71
72         u8 brightness;
73         u8 exposure;
74         u8 autogain;
75         u8 gain;
76
77         u8 sof_read;
78         u8 header_read;
79         u8 autogain_ignore_frames;
80
81         atomic_t avg_lum;
82 };
83
84 /* V4L2 controls supported by the driver */
85 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
86 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
87 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
88 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
89 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
90 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
91 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
92 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
93
94 static struct ctrl sd_ctrls[] = {
95 #define SD_BRIGHTNESS 0
96         {
97             {
98                 .id      = V4L2_CID_BRIGHTNESS,
99                 .type    = V4L2_CTRL_TYPE_INTEGER,
100                 .name    = "Brightness",
101                 .minimum = PAC207_BRIGHTNESS_MIN,
102                 .maximum = PAC207_BRIGHTNESS_MAX,
103                 .step = 1,
104                 .default_value = PAC207_BRIGHTNESS_DEFAULT,
105                 .flags = 0,
106             },
107             .set = sd_setbrightness,
108             .get = sd_getbrightness,
109         },
110 #define SD_EXPOSURE 1
111         {
112             {
113                 .id = V4L2_CID_EXPOSURE,
114                 .type = V4L2_CTRL_TYPE_INTEGER,
115                 .name = "exposure",
116                 .minimum = PAC207_EXPOSURE_MIN,
117                 .maximum = PAC207_EXPOSURE_MAX,
118                 .step = 1,
119                 .default_value = PAC207_EXPOSURE_DEFAULT,
120                 .flags = 0,
121             },
122             .set = sd_setexposure,
123             .get = sd_getexposure,
124         },
125 #define SD_AUTOGAIN 2
126         {
127             {
128                 .id       = V4L2_CID_AUTOGAIN,
129                 .type   = V4L2_CTRL_TYPE_BOOLEAN,
130                 .name   = "Auto Gain",
131                 .minimum = 0,
132                 .maximum = 1,
133                 .step   = 1,
134                 .default_value = 1,
135                 .flags = 0,
136             },
137             .set = sd_setautogain,
138             .get = sd_getautogain,
139         },
140 #define SD_GAIN 3
141         {
142             {
143                 .id = V4L2_CID_GAIN,
144                 .type = V4L2_CTRL_TYPE_INTEGER,
145                 .name = "gain",
146                 .minimum = PAC207_GAIN_MIN,
147                 .maximum = PAC207_GAIN_MAX,
148                 .step = 1,
149                 .default_value = PAC207_GAIN_DEFAULT,
150                 .flags = 0,
151             },
152             .set = sd_setgain,
153             .get = sd_getgain,
154         },
155 };
156
157 static struct v4l2_pix_format sif_mode[] = {
158         {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
159                 .bytesperline = 176,
160                 .sizeimage = (176 + 2) * 144,
161                         /* uncompressed, add 2 bytes / line for line header */
162                 .colorspace = V4L2_COLORSPACE_SRGB,
163                 .priv = 1},
164         {352, 288, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
165                 .bytesperline = 352,
166                         /* compressed, but only when needed (not compressed
167                            when the framerate is low) */
168                 .sizeimage = (352 + 2) * 288,
169                 .colorspace = V4L2_COLORSPACE_SRGB,
170                 .priv = 0},
171 };
172
173 static const __u8 pac207_sensor_init[][8] = {
174         {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0},
175         {0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
176         {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
177         {0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xa2, 0x02},
178         {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
179 };
180
181                         /* 48 reg_72 Rate Control end BalSize_4a =0x36 */
182 static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
183
184 static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
185         const u8 *buffer, u16 length)
186 {
187         struct usb_device *udev = gspca_dev->dev;
188         int err;
189
190         memcpy(gspca_dev->usb_buf, buffer, length);
191
192         err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
193                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
194                         0x00, index,
195                         gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT);
196         if (err < 0)
197                 PDEBUG(D_ERR,
198                         "Failed to write registers to index 0x%04X, error %d)",
199                         index, err);
200
201         return err;
202 }
203
204
205 static int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
206 {
207         struct usb_device *udev = gspca_dev->dev;
208         int err;
209
210         err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
211                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
212                         value, index, NULL, 0, PAC207_CTRL_TIMEOUT);
213         if (err)
214                 PDEBUG(D_ERR, "Failed to write a register (index 0x%04X,"
215                         " value 0x%02X, error %d)", index, value, err);
216
217         return err;
218 }
219
220 static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
221 {
222         struct usb_device *udev = gspca_dev->dev;
223         int res;
224
225         res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00,
226                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
227                         0x00, index,
228                         gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT);
229         if (res < 0) {
230                 PDEBUG(D_ERR,
231                         "Failed to read a register (index 0x%04X, error %d)",
232                         index, res);
233                 return res;
234         }
235
236         return gspca_dev->usb_buf[0];
237 }
238
239 /* this function is called at probe time */
240 static int sd_config(struct gspca_dev *gspca_dev,
241                         const struct usb_device_id *id)
242 {
243         struct sd *sd = (struct sd *) gspca_dev;
244         struct cam *cam;
245         u8 idreg[2];
246
247         idreg[0] = pac207_read_reg(gspca_dev, 0x0000);
248         idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
249         idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4);
250         idreg[1] = idreg[1] & 0x0f;
251         PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
252                 idreg[0], idreg[1]);
253
254         if (idreg[0] != 0x27) {
255                 PDEBUG(D_PROBE, "Error invalid sensor ID!");
256                 return -ENODEV;
257         }
258
259         pac207_write_reg(gspca_dev, 0x41, 0x00);
260                                 /* Bit_0=Image Format,
261                                  * Bit_1=LED,
262                                  * Bit_2=Compression test mode enable */
263         pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
264         pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
265
266         PDEBUG(D_PROBE,
267                 "Pixart PAC207BCA Image Processor and Control Chip detected"
268                 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
269
270         cam = &gspca_dev->cam;
271         cam->epaddr = 0x05;
272         cam->cam_mode = sif_mode;
273         cam->nmodes = ARRAY_SIZE(sif_mode);
274         sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
275         sd->exposure = PAC207_EXPOSURE_DEFAULT;
276         sd->gain = PAC207_GAIN_DEFAULT;
277
278         return 0;
279 }
280
281 /* this function is called at open time */
282 static int sd_open(struct gspca_dev *gspca_dev)
283 {
284         struct sd *sd = (struct sd *) gspca_dev;
285
286         sd->autogain = 1;
287         return 0;
288 }
289
290 /* -- start the camera -- */
291 static void sd_start(struct gspca_dev *gspca_dev)
292 {
293         struct sd *sd = (struct sd *) gspca_dev;
294         __u8 mode;
295
296         pac207_write_reg(gspca_dev, 0x0f, 0x10); /* Power control (Bit 6-0) */
297         pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8);
298         pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8);
299         pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8);
300         pac207_write_regs(gspca_dev, 0x0040, pac207_sensor_init[3], 8);
301         pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[4], 8);
302         pac207_write_regs(gspca_dev, 0x0048, PacReg72, 4);
303
304         /* Compression Balance */
305         if (gspca_dev->width == 176)
306                 pac207_write_reg(gspca_dev, 0x4a, 0xff);
307         else
308                 pac207_write_reg(gspca_dev, 0x4a, 0x88);
309         pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
310         pac207_write_reg(gspca_dev, 0x08, sd->brightness);
311
312         /* PGA global gain (Bit 4-0) */
313         pac207_write_reg(gspca_dev, 0x0e, sd->gain);
314         pac207_write_reg(gspca_dev, 0x02, sd->exposure); /* PXCK = 12MHz /n */
315
316         mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */
317         if (gspca_dev->width == 176) {  /* 176x144 */
318                 mode |= 0x01;
319                 PDEBUG(D_STREAM, "pac207_start mode 176x144");
320         } else {                                /* 352x288 */
321                 PDEBUG(D_STREAM, "pac207_start mode 352x288");
322         }
323         pac207_write_reg(gspca_dev, 0x41, mode);
324
325         pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
326         pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
327         msleep(10);
328         pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */
329
330         sd->sof_read = 0;
331         sd->autogain_ignore_frames = 0;
332         atomic_set(&sd->avg_lum, -1);
333 }
334
335 static void sd_stopN(struct gspca_dev *gspca_dev)
336 {
337         pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */
338         pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */
339         pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
340 }
341
342 static void sd_stop0(struct gspca_dev *gspca_dev)
343 {
344 }
345
346 /* this function is called at close time */
347 static void sd_close(struct gspca_dev *gspca_dev)
348 {
349 }
350
351 static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
352 {
353         struct sd *sd = (struct sd *) gspca_dev;
354         int avg_lum = atomic_read(&sd->avg_lum);
355
356         if (avg_lum == -1)
357                 return;
358
359         if (sd->autogain_ignore_frames > 0)
360                 sd->autogain_ignore_frames--;
361         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
362                         100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
363                         PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
364                 sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES;
365 }
366
367 /* Include pac common sof detection functions */
368 #include "pac_common.h"
369
370 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
371                         struct gspca_frame *frame,
372                         __u8 *data,
373                         int len)
374 {
375         struct sd *sd = (struct sd *) gspca_dev;
376         unsigned char *sof;
377
378         sof = pac_find_sof(gspca_dev, data, len);
379         if (sof) {
380                 int n;
381
382                 /* finish decoding current frame */
383                 n = sof - data;
384                 if (n > sizeof pac_sof_marker)
385                         n -= sizeof pac_sof_marker;
386                 else
387                         n = 0;
388                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
389                                         data, n);
390                 sd->header_read = 0;
391                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
392                 len -= sof - data;
393                 data = sof;
394         }
395         if (sd->header_read < 11) {
396                 int needed;
397
398                 /* get average lumination from frame header (byte 5) */
399                 if (sd->header_read < 5) {
400                         needed = 5 - sd->header_read;
401                         if (len >= needed)
402                                 atomic_set(&sd->avg_lum, data[needed - 1]);
403                 }
404                 /* skip the rest of the header */
405                 needed = 11 - sd->header_read;
406                 if (len <= needed) {
407                         sd->header_read += len;
408                         return;
409                 }
410                 data += needed;
411                 len -= needed;
412                 sd->header_read = 11;
413         }
414
415         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
416 }
417
418 static void setbrightness(struct gspca_dev *gspca_dev)
419 {
420         struct sd *sd = (struct sd *) gspca_dev;
421
422         pac207_write_reg(gspca_dev, 0x08, sd->brightness);
423         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
424         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
425 }
426
427 static void setexposure(struct gspca_dev *gspca_dev)
428 {
429         struct sd *sd = (struct sd *) gspca_dev;
430
431         pac207_write_reg(gspca_dev, 0x02, sd->exposure);
432         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
433         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
434 }
435
436 static void setgain(struct gspca_dev *gspca_dev)
437 {
438         struct sd *sd = (struct sd *) gspca_dev;
439
440         pac207_write_reg(gspca_dev, 0x0e, sd->gain);
441         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
442         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
443 }
444
445 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
446 {
447         struct sd *sd = (struct sd *) gspca_dev;
448
449         sd->brightness = val;
450         if (gspca_dev->streaming)
451                 setbrightness(gspca_dev);
452         return 0;
453 }
454
455 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
456 {
457         struct sd *sd = (struct sd *) gspca_dev;
458
459         *val = sd->brightness;
460         return 0;
461 }
462
463 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
464 {
465         struct sd *sd = (struct sd *) gspca_dev;
466
467         sd->exposure = val;
468         if (gspca_dev->streaming)
469                 setexposure(gspca_dev);
470         return 0;
471 }
472
473 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
474 {
475         struct sd *sd = (struct sd *) gspca_dev;
476
477         *val = sd->exposure;
478         return 0;
479 }
480
481 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
482 {
483         struct sd *sd = (struct sd *) gspca_dev;
484
485         sd->gain = val;
486         if (gspca_dev->streaming)
487                 setgain(gspca_dev);
488         return 0;
489 }
490
491 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
492 {
493         struct sd *sd = (struct sd *) gspca_dev;
494
495         *val = sd->gain;
496         return 0;
497 }
498
499 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
500 {
501         struct sd *sd = (struct sd *) gspca_dev;
502
503         sd->autogain = val;
504         /* when switching to autogain set defaults to make sure
505            we are on a valid point of the autogain gain /
506            exposure knee graph, and give this change time to
507            take effect before doing autogain. */
508         if (sd->autogain) {
509                 sd->exposure = PAC207_EXPOSURE_DEFAULT;
510                 sd->gain = PAC207_GAIN_DEFAULT;
511                 if (gspca_dev->streaming) {
512                         sd->autogain_ignore_frames =
513                                 PAC207_AUTOGAIN_IGNORE_FRAMES;
514                         setexposure(gspca_dev);
515                         setgain(gspca_dev);
516                 }
517         }
518
519         return 0;
520 }
521
522 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
523 {
524         struct sd *sd = (struct sd *) gspca_dev;
525
526         *val = sd->autogain;
527         return 0;
528 }
529
530 /* sub-driver description */
531 static const struct sd_desc sd_desc = {
532         .name = MODULE_NAME,
533         .ctrls = sd_ctrls,
534         .nctrls = ARRAY_SIZE(sd_ctrls),
535         .config = sd_config,
536         .open = sd_open,
537         .start = sd_start,
538         .stopN = sd_stopN,
539         .stop0 = sd_stop0,
540         .close = sd_close,
541         .dq_callback = pac207_do_auto_gain,
542         .pkt_scan = sd_pkt_scan,
543 };
544
545 /* -- module initialisation -- */
546 static const __devinitdata struct usb_device_id device_table[] = {
547         {USB_DEVICE(0x041e, 0x4028)},
548         {USB_DEVICE(0x093a, 0x2460)},
549         {USB_DEVICE(0x093a, 0x2463)},
550         {USB_DEVICE(0x093a, 0x2464)},
551         {USB_DEVICE(0x093a, 0x2468)},
552         {USB_DEVICE(0x093a, 0x2470)},
553         {USB_DEVICE(0x093a, 0x2471)},
554         {USB_DEVICE(0x093a, 0x2472)},
555         {USB_DEVICE(0x2001, 0xf115)},
556         {}
557 };
558 MODULE_DEVICE_TABLE(usb, device_table);
559
560 /* -- device connect -- */
561 static int sd_probe(struct usb_interface *intf,
562                         const struct usb_device_id *id)
563 {
564         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
565                                 THIS_MODULE);
566 }
567
568 static struct usb_driver sd_driver = {
569         .name = MODULE_NAME,
570         .id_table = device_table,
571         .probe = sd_probe,
572         .disconnect = gspca_disconnect,
573 #ifdef CONFIG_PM
574         .suspend = gspca_suspend,
575         .resume = gspca_resume,
576 #endif
577 };
578
579 /* -- module insert / remove -- */
580 static int __init sd_mod_init(void)
581 {
582         if (usb_register(&sd_driver) < 0)
583                 return -1;
584         PDEBUG(D_PROBE, "registered");
585         return 0;
586 }
587 static void __exit sd_mod_exit(void)
588 {
589         usb_deregister(&sd_driver);
590         PDEBUG(D_PROBE, "deregistered");
591 }
592
593 module_init(sd_mod_init);
594 module_exit(sd_mod_exit);