]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/media/video/gspca/pac207.c
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux...
[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
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 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 void 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 }
327
328 static void sd_stopN(struct gspca_dev *gspca_dev)
329 {
330         pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */
331         pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */
332         pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
333 }
334
335 /* Include pac common sof detection functions */
336 #include "pac_common.h"
337
338 static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
339 {
340         struct sd *sd = (struct sd *) gspca_dev;
341         int avg_lum = atomic_read(&sd->avg_lum);
342
343         if (avg_lum == -1)
344                 return;
345
346         if (sd->autogain_ignore_frames > 0)
347                 sd->autogain_ignore_frames--;
348         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
349                         100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
350                         PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
351                 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
352 }
353
354 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
355                         struct gspca_frame *frame,
356                         __u8 *data,
357                         int len)
358 {
359         struct sd *sd = (struct sd *) gspca_dev;
360         unsigned char *sof;
361
362         sof = pac_find_sof(gspca_dev, data, len);
363         if (sof) {
364                 int n;
365
366                 /* finish decoding current frame */
367                 n = sof - data;
368                 if (n > sizeof pac_sof_marker)
369                         n -= sizeof pac_sof_marker;
370                 else
371                         n = 0;
372                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
373                                         data, n);
374                 sd->header_read = 0;
375                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
376                 len -= sof - data;
377                 data = sof;
378         }
379         if (sd->header_read < 11) {
380                 int needed;
381
382                 /* get average lumination from frame header (byte 5) */
383                 if (sd->header_read < 5) {
384                         needed = 5 - sd->header_read;
385                         if (len >= needed)
386                                 atomic_set(&sd->avg_lum, data[needed - 1]);
387                 }
388                 /* skip the rest of the header */
389                 needed = 11 - sd->header_read;
390                 if (len <= needed) {
391                         sd->header_read += len;
392                         return;
393                 }
394                 data += needed;
395                 len -= needed;
396                 sd->header_read = 11;
397         }
398
399         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
400 }
401
402 static void setbrightness(struct gspca_dev *gspca_dev)
403 {
404         struct sd *sd = (struct sd *) gspca_dev;
405
406         pac207_write_reg(gspca_dev, 0x08, sd->brightness);
407         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
408         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
409 }
410
411 static void setexposure(struct gspca_dev *gspca_dev)
412 {
413         struct sd *sd = (struct sd *) gspca_dev;
414
415         pac207_write_reg(gspca_dev, 0x02, sd->exposure);
416         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
417         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
418 }
419
420 static void setgain(struct gspca_dev *gspca_dev)
421 {
422         struct sd *sd = (struct sd *) gspca_dev;
423
424         pac207_write_reg(gspca_dev, 0x0e, sd->gain);
425         pac207_write_reg(gspca_dev, 0x13, 0x01);        /* Bit 0, auto clear */
426         pac207_write_reg(gspca_dev, 0x1c, 0x01);        /* not documented */
427 }
428
429 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
430 {
431         struct sd *sd = (struct sd *) gspca_dev;
432
433         sd->brightness = val;
434         if (gspca_dev->streaming)
435                 setbrightness(gspca_dev);
436         return 0;
437 }
438
439 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
440 {
441         struct sd *sd = (struct sd *) gspca_dev;
442
443         *val = sd->brightness;
444         return 0;
445 }
446
447 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
448 {
449         struct sd *sd = (struct sd *) gspca_dev;
450
451         sd->exposure = val;
452         if (gspca_dev->streaming)
453                 setexposure(gspca_dev);
454         return 0;
455 }
456
457 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
458 {
459         struct sd *sd = (struct sd *) gspca_dev;
460
461         *val = sd->exposure;
462         return 0;
463 }
464
465 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
466 {
467         struct sd *sd = (struct sd *) gspca_dev;
468
469         sd->gain = val;
470         if (gspca_dev->streaming)
471                 setgain(gspca_dev);
472         return 0;
473 }
474
475 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
476 {
477         struct sd *sd = (struct sd *) gspca_dev;
478
479         *val = sd->gain;
480         return 0;
481 }
482
483 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
484 {
485         struct sd *sd = (struct sd *) gspca_dev;
486
487         sd->autogain = val;
488         /* when switching to autogain set defaults to make sure
489            we are on a valid point of the autogain gain /
490            exposure knee graph, and give this change time to
491            take effect before doing autogain. */
492         if (sd->autogain) {
493                 sd->exposure = PAC207_EXPOSURE_DEFAULT;
494                 sd->gain = PAC207_GAIN_DEFAULT;
495                 if (gspca_dev->streaming) {
496                         sd->autogain_ignore_frames =
497                                 PAC_AUTOGAIN_IGNORE_FRAMES;
498                         setexposure(gspca_dev);
499                         setgain(gspca_dev);
500                 }
501         }
502
503         return 0;
504 }
505
506 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
507 {
508         struct sd *sd = (struct sd *) gspca_dev;
509
510         *val = sd->autogain;
511         return 0;
512 }
513
514 /* sub-driver description */
515 static const struct sd_desc sd_desc = {
516         .name = MODULE_NAME,
517         .ctrls = sd_ctrls,
518         .nctrls = ARRAY_SIZE(sd_ctrls),
519         .config = sd_config,
520         .init = sd_init,
521         .start = sd_start,
522         .stopN = sd_stopN,
523         .dq_callback = pac207_do_auto_gain,
524         .pkt_scan = sd_pkt_scan,
525 };
526
527 /* -- module initialisation -- */
528 static const __devinitdata struct usb_device_id device_table[] = {
529         {USB_DEVICE(0x041e, 0x4028)},
530         {USB_DEVICE(0x093a, 0x2460)},
531         {USB_DEVICE(0x093a, 0x2463)},
532         {USB_DEVICE(0x093a, 0x2464)},
533         {USB_DEVICE(0x093a, 0x2468)},
534         {USB_DEVICE(0x093a, 0x2470)},
535         {USB_DEVICE(0x093a, 0x2471)},
536         {USB_DEVICE(0x093a, 0x2472)},
537         {USB_DEVICE(0x2001, 0xf115)},
538         {}
539 };
540 MODULE_DEVICE_TABLE(usb, device_table);
541
542 /* -- device connect -- */
543 static int sd_probe(struct usb_interface *intf,
544                         const struct usb_device_id *id)
545 {
546         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
547                                 THIS_MODULE);
548 }
549
550 static struct usb_driver sd_driver = {
551         .name = MODULE_NAME,
552         .id_table = device_table,
553         .probe = sd_probe,
554         .disconnect = gspca_disconnect,
555 #ifdef CONFIG_PM
556         .suspend = gspca_suspend,
557         .resume = gspca_resume,
558 #endif
559 };
560
561 /* -- module insert / remove -- */
562 static int __init sd_mod_init(void)
563 {
564         if (usb_register(&sd_driver) < 0)
565                 return -1;
566         PDEBUG(D_PROBE, "registered");
567         return 0;
568 }
569 static void __exit sd_mod_exit(void)
570 {
571         usb_deregister(&sd_driver);
572         PDEBUG(D_PROBE, "deregistered");
573 }
574
575 module_init(sd_mod_init);
576 module_exit(sd_mod_exit);