V4L/DVB (12616): gspca_pac207: remove a number of unneeded (repeated) register writes
[safe/jmp/linux-2.6] / 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         {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
173 };
174
175 static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
176         const u8 *buffer, u16 length)
177 {
178         struct usb_device *udev = gspca_dev->dev;
179         int err;
180
181         memcpy(gspca_dev->usb_buf, buffer, length);
182
183         err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
184                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
185                         0x00, index,
186                         gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT);
187         if (err < 0)
188                 PDEBUG(D_ERR,
189                         "Failed to write registers to index 0x%04X, error %d)",
190                         index, err);
191
192         return err;
193 }
194
195
196 static int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
197 {
198         struct usb_device *udev = gspca_dev->dev;
199         int err;
200
201         err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
202                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
203                         value, index, NULL, 0, PAC207_CTRL_TIMEOUT);
204         if (err)
205                 PDEBUG(D_ERR, "Failed to write a register (index 0x%04X,"
206                         " value 0x%02X, error %d)", index, value, err);
207
208         return err;
209 }
210
211 static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
212 {
213         struct usb_device *udev = gspca_dev->dev;
214         int res;
215
216         res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00,
217                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
218                         0x00, index,
219                         gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT);
220         if (res < 0) {
221                 PDEBUG(D_ERR,
222                         "Failed to read a register (index 0x%04X, error %d)",
223                         index, res);
224                 return res;
225         }
226
227         return gspca_dev->usb_buf[0];
228 }
229
230 /* this function is called at probe time */
231 static int sd_config(struct gspca_dev *gspca_dev,
232                         const struct usb_device_id *id)
233 {
234         struct sd *sd = (struct sd *) gspca_dev;
235         struct cam *cam;
236         u8 idreg[2];
237
238         idreg[0] = pac207_read_reg(gspca_dev, 0x0000);
239         idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
240         idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4);
241         idreg[1] = idreg[1] & 0x0f;
242         PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
243                 idreg[0], idreg[1]);
244
245         if (idreg[0] != 0x27) {
246                 PDEBUG(D_PROBE, "Error invalid sensor ID!");
247                 return -ENODEV;
248         }
249
250         PDEBUG(D_PROBE,
251                 "Pixart PAC207BCA Image Processor and Control Chip detected"
252                 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
253
254         cam = &gspca_dev->cam;
255         cam->cam_mode = sif_mode;
256         cam->nmodes = ARRAY_SIZE(sif_mode);
257         sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
258         sd->exposure = PAC207_EXPOSURE_DEFAULT;
259         sd->gain = PAC207_GAIN_DEFAULT;
260         sd->autogain = AUTOGAIN_DEF;
261
262         return 0;
263 }
264
265 /* this function is called at probe and resume time */
266 static int sd_init(struct gspca_dev *gspca_dev)
267 {
268         pac207_write_reg(gspca_dev, 0x41, 0x00);
269                                 /* Bit_0=Image Format,
270                                  * Bit_1=LED,
271                                  * Bit_2=Compression test mode enable */
272         pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
273
274         return 0;
275 }
276
277 /* -- start the camera -- */
278 static int sd_start(struct gspca_dev *gspca_dev)
279 {
280         struct sd *sd = (struct sd *) gspca_dev;
281         __u8 mode;
282
283         pac207_write_reg(gspca_dev, 0x0f, 0x10); /* Power control (Bit 6-0) */
284         pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8);
285         pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8);
286         pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8);
287         pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[3], 8);
288
289         /* Compression Balance */
290         if (gspca_dev->width == 176)
291                 pac207_write_reg(gspca_dev, 0x4a, 0xff);
292         else
293                 pac207_write_reg(gspca_dev, 0x4a, 0x88);
294         pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
295         pac207_write_reg(gspca_dev, 0x08, sd->brightness);
296
297         /* PGA global gain (Bit 4-0) */
298         pac207_write_reg(gspca_dev, 0x0e, sd->gain);
299         pac207_write_reg(gspca_dev, 0x02, sd->exposure); /* PXCK = 12MHz /n */
300
301         mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */
302         if (gspca_dev->width == 176) {  /* 176x144 */
303                 mode |= 0x01;
304                 PDEBUG(D_STREAM, "pac207_start mode 176x144");
305         } else {                                /* 352x288 */
306                 PDEBUG(D_STREAM, "pac207_start mode 352x288");
307         }
308         pac207_write_reg(gspca_dev, 0x41, mode);
309
310         pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
311         pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
312         msleep(10);
313         pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */
314
315         sd->sof_read = 0;
316         sd->autogain_ignore_frames = 0;
317         atomic_set(&sd->avg_lum, -1);
318         return 0;
319 }
320
321 static void sd_stopN(struct gspca_dev *gspca_dev)
322 {
323         pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */
324         pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */
325         pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
326 }
327
328 /* Include pac common sof detection functions */
329 #include "pac_common.h"
330
331 static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
332 {
333         struct sd *sd = (struct sd *) gspca_dev;
334         int avg_lum = atomic_read(&sd->avg_lum);
335
336         if (avg_lum == -1)
337                 return;
338
339         if (sd->autogain_ignore_frames > 0)
340                 sd->autogain_ignore_frames--;
341         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
342                         100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
343                         PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
344                 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
345 }
346
347 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
348                         struct gspca_frame *frame,
349                         __u8 *data,
350                         int len)
351 {
352         struct sd *sd = (struct sd *) gspca_dev;
353         unsigned char *sof;
354
355         sof = pac_find_sof(gspca_dev, data, len);
356         if (sof) {
357                 int n;
358
359                 /* finish decoding current frame */
360                 n = sof - data;
361                 if (n > sizeof pac_sof_marker)
362                         n -= sizeof pac_sof_marker;
363                 else
364                         n = 0;
365                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
366                                         data, n);
367                 sd->header_read = 0;
368                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
369                 len -= sof - data;
370                 data = sof;
371         }
372         if (sd->header_read < 11) {
373                 int needed;
374
375                 /* get average lumination from frame header (byte 5) */
376                 if (sd->header_read < 5) {
377                         needed = 5 - sd->header_read;
378                         if (len >= needed)
379                                 atomic_set(&sd->avg_lum, data[needed - 1]);
380                 }
381                 /* skip the rest of the header */
382                 needed = 11 - sd->header_read;
383                 if (len <= needed) {
384                         sd->header_read += len;
385                         return;
386                 }
387                 data += needed;
388                 len -= needed;
389                 sd->header_read = 11;
390         }
391
392         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
393 }
394
395 static void setbrightness(struct gspca_dev *gspca_dev)
396 {
397         struct sd *sd = (struct sd *) gspca_dev;
398
399         pac207_write_reg(gspca_dev, 0x08, sd->brightness);
400         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
401         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
402 }
403
404 static void setexposure(struct gspca_dev *gspca_dev)
405 {
406         struct sd *sd = (struct sd *) gspca_dev;
407
408         pac207_write_reg(gspca_dev, 0x02, sd->exposure);
409         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
410         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
411 }
412
413 static void setgain(struct gspca_dev *gspca_dev)
414 {
415         struct sd *sd = (struct sd *) gspca_dev;
416
417         pac207_write_reg(gspca_dev, 0x0e, sd->gain);
418         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
419         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
420 }
421
422 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
423 {
424         struct sd *sd = (struct sd *) gspca_dev;
425
426         sd->brightness = val;
427         if (gspca_dev->streaming)
428                 setbrightness(gspca_dev);
429         return 0;
430 }
431
432 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
433 {
434         struct sd *sd = (struct sd *) gspca_dev;
435
436         *val = sd->brightness;
437         return 0;
438 }
439
440 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
441 {
442         struct sd *sd = (struct sd *) gspca_dev;
443
444         sd->exposure = val;
445         if (gspca_dev->streaming)
446                 setexposure(gspca_dev);
447         return 0;
448 }
449
450 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
451 {
452         struct sd *sd = (struct sd *) gspca_dev;
453
454         *val = sd->exposure;
455         return 0;
456 }
457
458 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
459 {
460         struct sd *sd = (struct sd *) gspca_dev;
461
462         sd->gain = val;
463         if (gspca_dev->streaming)
464                 setgain(gspca_dev);
465         return 0;
466 }
467
468 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
469 {
470         struct sd *sd = (struct sd *) gspca_dev;
471
472         *val = sd->gain;
473         return 0;
474 }
475
476 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
477 {
478         struct sd *sd = (struct sd *) gspca_dev;
479
480         sd->autogain = val;
481         /* when switching to autogain set defaults to make sure
482            we are on a valid point of the autogain gain /
483            exposure knee graph, and give this change time to
484            take effect before doing autogain. */
485         if (sd->autogain) {
486                 sd->exposure = PAC207_EXPOSURE_DEFAULT;
487                 sd->gain = PAC207_GAIN_DEFAULT;
488                 if (gspca_dev->streaming) {
489                         sd->autogain_ignore_frames =
490                                 PAC_AUTOGAIN_IGNORE_FRAMES;
491                         setexposure(gspca_dev);
492                         setgain(gspca_dev);
493                 }
494         }
495
496         return 0;
497 }
498
499 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
500 {
501         struct sd *sd = (struct sd *) gspca_dev;
502
503         *val = sd->autogain;
504         return 0;
505 }
506
507 /* sub-driver description */
508 static const struct sd_desc sd_desc = {
509         .name = MODULE_NAME,
510         .ctrls = sd_ctrls,
511         .nctrls = ARRAY_SIZE(sd_ctrls),
512         .config = sd_config,
513         .init = sd_init,
514         .start = sd_start,
515         .stopN = sd_stopN,
516         .dq_callback = pac207_do_auto_gain,
517         .pkt_scan = sd_pkt_scan,
518 };
519
520 /* -- module initialisation -- */
521 static const __devinitdata struct usb_device_id device_table[] = {
522         {USB_DEVICE(0x041e, 0x4028)},
523         {USB_DEVICE(0x093a, 0x2460)},
524         {USB_DEVICE(0x093a, 0x2461)},
525         {USB_DEVICE(0x093a, 0x2463)},
526         {USB_DEVICE(0x093a, 0x2464)},
527         {USB_DEVICE(0x093a, 0x2468)},
528         {USB_DEVICE(0x093a, 0x2470)},
529         {USB_DEVICE(0x093a, 0x2471)},
530         {USB_DEVICE(0x093a, 0x2472)},
531         {USB_DEVICE(0x093a, 0x2474)},
532         {USB_DEVICE(0x093a, 0x2476)},
533         {USB_DEVICE(0x145f, 0x013a)},
534         {USB_DEVICE(0x2001, 0xf115)},
535         {}
536 };
537 MODULE_DEVICE_TABLE(usb, device_table);
538
539 /* -- device connect -- */
540 static int sd_probe(struct usb_interface *intf,
541                         const struct usb_device_id *id)
542 {
543         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
544                                 THIS_MODULE);
545 }
546
547 static struct usb_driver sd_driver = {
548         .name = MODULE_NAME,
549         .id_table = device_table,
550         .probe = sd_probe,
551         .disconnect = gspca_disconnect,
552 #ifdef CONFIG_PM
553         .suspend = gspca_suspend,
554         .resume = gspca_resume,
555 #endif
556 };
557
558 /* -- module insert / remove -- */
559 static int __init sd_mod_init(void)
560 {
561         int ret;
562         ret = usb_register(&sd_driver);
563         if (ret < 0)
564                 return ret;
565         PDEBUG(D_PROBE, "registered");
566         return 0;
567 }
568 static void __exit sd_mod_exit(void)
569 {
570         usb_deregister(&sd_driver);
571         PDEBUG(D_PROBE, "deregistered");
572 }
573
574 module_init(sd_mod_init);
575 module_exit(sd_mod_exit);