2 * Sunplus spca561 subdriver
4 * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define MODULE_NAME "spca561"
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
29 MODULE_LICENSE("GPL");
31 /* specific webcam descriptor */
33 struct gspca_dev gspca_dev; /* !! must be the first item */
35 __u16 exposure; /* rev12a only */
36 #define EXPOSURE_MIN 1
37 #define EXPOSURE_DEF 700 /* == 10 fps */
38 #define EXPOSURE_MAX (2047 + 325) /* see setexposure */
40 __u8 contrast; /* rev72a only */
41 #define CONTRAST_MIN 0x00
42 #define CONTRAST_DEF 0x20
43 #define CONTRAST_MAX 0x3f
45 __u8 brightness; /* rev72a only */
46 #define BRIGHTNESS_MIN 0
47 #define BRIGHTNESS_DEF 0x20
48 #define BRIGHTNESS_MAX 0x3f
56 #define AUTOGAIN_MIN 0
57 #define AUTOGAIN_DEF 1
58 #define AUTOGAIN_MAX 1
60 __u8 gain; /* rev12a only */
66 __u8 expo12a; /* expo/gain? for rev 12a */
73 #define AG_CNT_START 13
76 static const struct v4l2_pix_format sif_012a_mode[] = {
77 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
79 .sizeimage = 160 * 120,
80 .colorspace = V4L2_COLORSPACE_SRGB,
82 {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
84 .sizeimage = 176 * 144,
85 .colorspace = V4L2_COLORSPACE_SRGB,
87 {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
89 .sizeimage = 320 * 240 * 4 / 8,
90 .colorspace = V4L2_COLORSPACE_SRGB,
92 {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
94 .sizeimage = 352 * 288 * 4 / 8,
95 .colorspace = V4L2_COLORSPACE_SRGB,
99 static const struct v4l2_pix_format sif_072a_mode[] = {
100 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
102 .sizeimage = 160 * 120,
103 .colorspace = V4L2_COLORSPACE_SRGB,
105 {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
107 .sizeimage = 176 * 144,
108 .colorspace = V4L2_COLORSPACE_SRGB,
110 {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
112 .sizeimage = 320 * 240,
113 .colorspace = V4L2_COLORSPACE_SRGB,
115 {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
117 .sizeimage = 352 * 288,
118 .colorspace = V4L2_COLORSPACE_SRGB,
123 * Initialization data
124 * I'm not very sure how to split initialization from open data
125 * chunks. For now, we'll consider everything as initialization
127 /* Frame packet header offsets for the spca561 */
128 #define SPCA561_OFFSET_SNAP 1
129 #define SPCA561_OFFSET_TYPE 2
130 #define SPCA561_OFFSET_COMPRESS 3
131 #define SPCA561_OFFSET_FRAMSEQ 4
132 #define SPCA561_OFFSET_GPIO 5
133 #define SPCA561_OFFSET_USBBUFF 6
134 #define SPCA561_OFFSET_WIN2GRAVE 7
135 #define SPCA561_OFFSET_WIN2RAVE 8
136 #define SPCA561_OFFSET_WIN2BAVE 9
137 #define SPCA561_OFFSET_WIN2GBAVE 10
138 #define SPCA561_OFFSET_WIN1GRAVE 11
139 #define SPCA561_OFFSET_WIN1RAVE 12
140 #define SPCA561_OFFSET_WIN1BAVE 13
141 #define SPCA561_OFFSET_WIN1GBAVE 14
142 #define SPCA561_OFFSET_FREQ 15
143 #define SPCA561_OFFSET_VSYNC 16
144 #define SPCA561_INDEX_I2C_BASE 0x8800
145 #define SPCA561_SNAPBIT 0x20
146 #define SPCA561_SNAPCTRL 0x40
148 static const u16 rev72a_reset[][2] = {
149 {0x0000, 0x8114}, /* Software GPIO output data */
150 {0x0001, 0x8114}, /* Software GPIO output data */
151 {0x0000, 0x8112}, /* Some kind of reset */
154 static const __u16 rev72a_init_data1[][2] = {
155 {0x0003, 0x8701}, /* PCLK clock delay adjustment */
156 {0x0001, 0x8703}, /* HSYNC from cmos inverted */
157 {0x0011, 0x8118}, /* Enable and conf sensor */
158 {0x0001, 0x8118}, /* Conf sensor */
159 {0x0092, 0x8804}, /* I know nothing about these */
160 {0x0010, 0x8802}, /* 0x88xx registers, so I won't */
163 static const u16 rev72a_init_sensor1[][2] = {
178 static const __u16 rev72a_init_data2[][2] = {
179 {0x0018, 0x8601}, /* Pixel/line selection for color separation */
180 {0x0000, 0x8602}, /* Optical black level for user setting */
181 {0x0060, 0x8604}, /* Optical black horizontal offset */
182 {0x0002, 0x8605}, /* Optical black vertical offset */
183 {0x0000, 0x8603}, /* Non-automatic optical black level */
184 {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
185 {0x0000, 0x865f}, /* Vertical valid pixels window (x2) */
186 {0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */
187 {0x0090, 0x865e}, /* Vertical valid lines window (x2) */
188 {0x00e0, 0x8406}, /* Memory buffer threshold */
189 {0x0000, 0x8660}, /* Compensation memory stuff */
190 {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */
191 {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
192 {0x0001, 0x8200}, /* OprMode to be executed by hardware */
194 {0x0000, 0x8611}, /* R offset for white balance */
195 {0x00fd, 0x8612}, /* Gr offset for white balance */
196 {0x0003, 0x8613}, /* B offset for white balance */
197 {0x0000, 0x8614}, /* Gb offset for white balance */
199 {0x0035, 0x8651}, /* R gain for white balance */
200 {0x0040, 0x8652}, /* Gr gain for white balance */
201 {0x005f, 0x8653}, /* B gain for white balance */
202 {0x0040, 0x8654}, /* Gb gain for white balance */
203 {0x0002, 0x8502}, /* Maximum average bit rate stuff */
206 {0x0087, 0x8700}, /* Set master clock (96Mhz????) */
207 {0x0081, 0x8702}, /* Master clock output enable */
209 {0x0000, 0x8500}, /* Set image type (352x288 no compression) */
210 /* Originally was 0x0010 (352x288 compression) */
212 {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
213 {0x0003, 0x865c}, /* Vertical offset for valid lines */
216 static const u16 rev72a_init_sensor2[][2] = {
219 {0x0005, 0x002f}, /* blanking control column */
220 {0x0006, 0x0000}, /* blanking mode row*/
222 {0x0009, 0x1061}, /* setexposure times && pixel clock
223 * 0001 0 | 000 0110 0001 */
228 /******************** QC Express etch2 stuff ********************/
229 static const __u16 Pb100_1map8300[][2] = {
233 {0x8303, 0x0125}, /* image area */
236 {0x833c, 0x0001}, /*fixme: win:07*/
238 {0x832f, 0x1904}, /*fixme: was 0419*/
244 static const __u16 Pb100_2map8300[][2] = {
251 static const __u16 spca561_161rev12A_data1[][2] = {
252 {0x29, 0x8118}, /* Control register (various enable bits) */
253 {0x08, 0x8114}, /* GPIO: Led off */
254 {0x0e, 0x8112}, /* 0x0e stream off 0x3e stream on */
255 {0x00, 0x8102}, /* white balance - new */
257 {0x04, 0x8802}, /* windows uses 08 */
260 static const __u16 spca561_161rev12A_data2[][2] = {
267 {0x07, 0x8201}, /* windows uses 02 */
276 {0x07, 0x8601}, /* white balance - new */
277 {0x07, 0x8602}, /* white balance - new */
278 {0x00, 0x8610}, /* *red */
279 {0x00, 0x8611}, /* 3f *green */
280 {0x00, 0x8612}, /* green *blue */
281 {0x00, 0x8613}, /* blue *green */
282 {0x43, 0x8614}, /* green *red - white balance - was 0x35 */
283 {0x40, 0x8615}, /* 40 *green - white balance - was 0x35 */
284 {0x71, 0x8616}, /* 7a *blue - white balance - was 0x35 */
285 {0x40, 0x8617}, /* 40 *green - white balance - was 0x35 */
287 {0x0c, 0x8620}, /* 0c */
288 {0xc8, 0x8631}, /* c8 */
289 {0xc8, 0x8634}, /* c8 */
290 {0x23, 0x8635}, /* 23 */
291 {0x1f, 0x8636}, /* 1f */
292 {0xdd, 0x8637}, /* dd */
293 {0xe1, 0x8638}, /* e1 */
294 {0x1d, 0x8639}, /* 1d */
295 {0x21, 0x863a}, /* 21 */
296 {0xe3, 0x863b}, /* e3 */
297 {0xdf, 0x863c}, /* df */
300 /* {0x99, 0x8700}, * - white balance - new (removed) */
301 /* HDG we used to do this in stop0, making the init state and the state
302 after a start / stop different, so do this here instead. */
307 static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
311 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
313 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
314 value, index, NULL, 0, 500);
315 PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
317 PDEBUG(D_ERR, "reg write: error %d", ret);
320 static void write_vector(struct gspca_dev *gspca_dev,
321 const __u16 data[][2])
323 struct usb_device *dev = gspca_dev->dev;
327 while (data[i][1] != 0) {
328 reg_w_val(dev, data[i][1], data[i][0]);
333 /* read 'len' bytes to gspca_dev->usb_buf */
334 static void reg_r(struct gspca_dev *gspca_dev,
335 __u16 index, __u16 length)
337 usb_control_msg(gspca_dev->dev,
338 usb_rcvctrlpipe(gspca_dev->dev, 0),
340 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
342 index, gspca_dev->usb_buf, length, 500);
345 /* write 'len' bytes from gspca_dev->usb_buf */
346 static void reg_w_buf(struct gspca_dev *gspca_dev,
347 __u16 index, __u16 len)
349 usb_control_msg(gspca_dev->dev,
350 usb_sndctrlpipe(gspca_dev->dev, 0),
352 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
354 index, gspca_dev->usb_buf, len, 500);
357 static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
361 reg_w_val(gspca_dev->dev, 0x8801, reg);
362 reg_w_val(gspca_dev->dev, 0x8805, value);
363 reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
365 reg_r(gspca_dev, 0x8803, 1);
366 if (!gspca_dev->usb_buf[0])
372 static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
377 reg_w_val(gspca_dev->dev, 0x8804, 0x92);
378 reg_w_val(gspca_dev->dev, 0x8801, reg);
379 reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
381 reg_r(gspca_dev, 0x8803, 1);
382 if (!gspca_dev->usb_buf[0]) {
383 reg_r(gspca_dev, 0x8800, 1);
384 value = gspca_dev->usb_buf[0];
385 reg_r(gspca_dev, 0x8805, 1);
386 return ((int) value << 8) | gspca_dev->usb_buf[0];
393 static void sensor_mapwrite(struct gspca_dev *gspca_dev,
394 const __u16 (*sensormap)[2])
396 while ((*sensormap)[0]) {
397 gspca_dev->usb_buf[0] = (*sensormap)[1];
398 gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
399 reg_w_buf(gspca_dev, (*sensormap)[0], 2);
404 static void write_sensor_72a(struct gspca_dev *gspca_dev,
405 const __u16 (*sensor)[2])
407 while ((*sensor)[0]) {
408 i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
413 static void init_161rev12A(struct gspca_dev *gspca_dev)
415 write_vector(gspca_dev, spca561_161rev12A_data1);
416 sensor_mapwrite(gspca_dev, Pb100_1map8300);
417 /*fixme: should be in sd_start*/
418 write_vector(gspca_dev, spca561_161rev12A_data2);
419 sensor_mapwrite(gspca_dev, Pb100_2map8300);
422 /* this function is called at probe time */
423 static int sd_config(struct gspca_dev *gspca_dev,
424 const struct usb_device_id *id)
426 struct sd *sd = (struct sd *) gspca_dev;
428 __u16 vendor, product;
431 /* Read frm global register the USB product and vendor IDs, just to
432 * prove that we can communicate with the device. This works, which
433 * confirms at we are communicating properly and that the device
435 reg_r(gspca_dev, 0x8104, 1);
436 data1 = gspca_dev->usb_buf[0];
437 reg_r(gspca_dev, 0x8105, 1);
438 data2 = gspca_dev->usb_buf[0];
439 vendor = (data2 << 8) | data1;
440 reg_r(gspca_dev, 0x8106, 1);
441 data1 = gspca_dev->usb_buf[0];
442 reg_r(gspca_dev, 0x8107, 1);
443 data2 = gspca_dev->usb_buf[0];
444 product = (data2 << 8) | data1;
445 if (vendor != id->idVendor || product != id->idProduct) {
446 PDEBUG(D_PROBE, "Bad vendor / product from device");
450 cam = &gspca_dev->cam;
451 gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
453 sd->chip_revision = id->driver_info;
454 if (sd->chip_revision == Rev012A) {
455 cam->cam_mode = sif_012a_mode;
456 cam->nmodes = ARRAY_SIZE(sif_012a_mode);
458 cam->cam_mode = sif_072a_mode;
459 cam->nmodes = ARRAY_SIZE(sif_072a_mode);
461 sd->brightness = BRIGHTNESS_DEF;
462 sd->contrast = CONTRAST_DEF;
464 sd->exposure = EXPOSURE_DEF;
465 sd->autogain = AUTOGAIN_DEF;
467 sd->expo12a = EXPO12A_DEF;
471 /* this function is called at probe and resume time */
472 static int sd_init_12a(struct gspca_dev *gspca_dev)
474 PDEBUG(D_STREAM, "Chip revision: 012a");
475 init_161rev12A(gspca_dev);
478 static int sd_init_72a(struct gspca_dev *gspca_dev)
480 PDEBUG(D_STREAM, "Chip revision: 072a");
481 write_vector(gspca_dev, rev72a_reset);
483 write_vector(gspca_dev, rev72a_init_data1);
484 write_sensor_72a(gspca_dev, rev72a_init_sensor1);
485 write_vector(gspca_dev, rev72a_init_data2);
486 write_sensor_72a(gspca_dev, rev72a_init_sensor2);
487 reg_w_val(gspca_dev->dev, 0x8112, 0x30);
492 static void setbrightness(struct gspca_dev *gspca_dev)
494 struct sd *sd = (struct sd *) gspca_dev;
495 struct usb_device *dev = gspca_dev->dev;
498 value = sd->brightness;
500 /* offsets for white balance */
501 reg_w_val(dev, 0x8611, value); /* R */
502 reg_w_val(dev, 0x8612, value); /* Gr */
503 reg_w_val(dev, 0x8613, value); /* B */
504 reg_w_val(dev, 0x8614, value); /* Gb */
507 static void setwhite(struct gspca_dev *gspca_dev)
509 struct sd *sd = (struct sd *) gspca_dev;
514 /* try to emulate MS-win as possible */
516 red = 0x20 + white * 3 / 8;
517 blue = 0x90 - white * 5 / 8;
518 if (sd->chip_revision == Rev012A) {
522 red += sd->contrast - 0x20;
523 blue += sd->contrast - 0x20;
525 reg_w_val(gspca_dev->dev, reg, red);
526 reg_w_val(gspca_dev->dev, reg + 2, blue);
529 static void setcontrast(struct gspca_dev *gspca_dev)
531 struct sd *sd = (struct sd *) gspca_dev;
532 struct usb_device *dev = gspca_dev->dev;
535 if (sd->chip_revision != Rev072A)
537 value = sd->contrast + 0x20;
539 /* gains for white balance */
541 /* reg_w_val(dev, 0x8651, value); * R - done by setwhite */
542 reg_w_val(dev, 0x8652, value); /* Gr */
543 /* reg_w_val(dev, 0x8653, value); * B - done by setwhite */
544 reg_w_val(dev, 0x8654, value); /* Gb */
548 static void setexposure(struct gspca_dev *gspca_dev)
550 struct sd *sd = (struct sd *) gspca_dev;
553 /* Register 0x8309 controls exposure for the spca561,
554 the basic exposure setting goes from 1-2047, where 1 is completely
555 dark and 2047 is very bright. It not only influences exposure but
556 also the framerate (to allow for longer exposure) from 1 - 300 it
557 only raises the exposure time then from 300 - 600 it halves the
558 framerate to be able to further raise the exposure time and for every
559 300 more it halves the framerate again. This allows for a maximum
560 exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
561 Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
562 configure a divider for the base framerate which us used at the
563 exposure setting of 1-300. These bits configure the base framerate
564 according to the following formula: fps = 60 / (value + 2) */
566 /* We choose to use the high bits setting the fixed framerate divisor
567 asap, as setting high basic exposure setting without the fixed
568 divider in combination with high gains makes the cam stop */
569 int table[] = { 0, 450, 550, 625, EXPOSURE_MAX };
571 for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
572 if (sd->exposure <= table[i + 1]) {
573 expo = sd->exposure - table[i];
581 gspca_dev->usb_buf[0] = expo;
582 gspca_dev->usb_buf[1] = expo >> 8;
583 reg_w_buf(gspca_dev, 0x8309, 2);
587 static void setgain(struct gspca_dev *gspca_dev)
589 struct sd *sd = (struct sd *) gspca_dev;
591 /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the
592 sensitivity when set, so 31 + one of them set == 63, and 15
593 with both of them set == 63 */
595 gspca_dev->usb_buf[0] = sd->gain;
596 else if (sd->gain < 128)
597 gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
599 gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0;
601 gspca_dev->usb_buf[1] = 0;
602 reg_w_buf(gspca_dev, 0x8335, 2);
605 static void setautogain(struct gspca_dev *gspca_dev)
607 struct sd *sd = (struct sd *) gspca_dev;
610 sd->ag_cnt = AG_CNT_START;
615 static int sd_start_12a(struct gspca_dev *gspca_dev)
617 struct usb_device *dev = gspca_dev->dev;
619 static const __u8 Reg8391[8] =
620 {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
622 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
624 /* Use compression on 320x240 and above */
625 reg_w_val(dev, 0x8500, 0x10 | mode);
627 /* I couldn't get the compression to work below 320x240
628 * Fortunately at these resolutions the bandwidth
629 * is sufficient to push raw frames at ~20fps */
630 reg_w_val(dev, 0x8500, mode);
631 } /* -- qq@kuku.eu.org */
633 gspca_dev->usb_buf[0] = 0xaa;
634 gspca_dev->usb_buf[1] = 0x00;
635 reg_w_buf(gspca_dev, 0x8307, 2);
636 /* clock - lower 0x8X values lead to fps > 30 */
637 reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
638 /* 0x8f 0x85 0x27 clock */
639 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
640 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
641 memcpy(gspca_dev->usb_buf, Reg8391, 8);
642 reg_w_buf(gspca_dev, 0x8391, 8);
643 reg_w_buf(gspca_dev, 0x8390, 8);
646 setexposure(gspca_dev);
648 /* Led ON (bit 3 -> 0 */
649 reg_w_val(gspca_dev->dev, 0x8114, 0x00);
652 static int sd_start_72a(struct gspca_dev *gspca_dev)
654 struct usb_device *dev = gspca_dev->dev;
658 write_vector(gspca_dev, rev72a_reset);
660 write_vector(gspca_dev, rev72a_init_data1);
661 write_sensor_72a(gspca_dev, rev72a_init_sensor1);
663 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
667 Clck = 0x27; /* ms-win 0x87 */
679 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
680 reg_w_val(dev, 0x8702, 0x81);
681 reg_w_val(dev, 0x8500, mode); /* mode */
682 write_sensor_72a(gspca_dev, rev72a_init_sensor2);
683 setcontrast(gspca_dev);
684 /* setbrightness(gspca_dev); * fixme: bad values */
685 setautogain(gspca_dev);
686 reg_w_val(dev, 0x8112, 0x10 | 0x20);
690 static void sd_stopN(struct gspca_dev *gspca_dev)
692 struct sd *sd = (struct sd *) gspca_dev;
694 if (sd->chip_revision == Rev012A) {
695 reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
696 /* Led Off (bit 3 -> 1 */
697 reg_w_val(gspca_dev->dev, 0x8114, 0x08);
699 reg_w_val(gspca_dev->dev, 0x8112, 0x20);
700 /* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
704 static void do_autogain(struct gspca_dev *gspca_dev)
706 struct sd *sd = (struct sd *) gspca_dev;
712 __u8 luma_mean = 110;
713 __u8 luma_delta = 20;
718 if (--sd->ag_cnt >= 0)
720 sd->ag_cnt = AG_CNT_START;
722 switch (sd->chip_revision) {
724 reg_r(gspca_dev, 0x8621, 1);
725 Gr = gspca_dev->usb_buf[0];
726 reg_r(gspca_dev, 0x8622, 1);
727 R = gspca_dev->usb_buf[0];
728 reg_r(gspca_dev, 0x8623, 1);
729 B = gspca_dev->usb_buf[0];
730 reg_r(gspca_dev, 0x8624, 1);
731 Gb = gspca_dev->usb_buf[0];
732 y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
733 /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
734 /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
735 /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
737 if (y < luma_mean - luma_delta ||
738 y > luma_mean + luma_delta) {
739 expotimes = i2c_read(gspca_dev, 0x09, 0x10);
741 expotimes = expotimes & 0x07ff;
743 "Exposition Times 0x%03X Clock 0x%04X ",
744 expotimes,pixelclk); */
745 gainG = i2c_read(gspca_dev, 0x35, 0x10);
747 "reading Gain register %d", gainG); */
749 expotimes += (luma_mean - y) >> spring;
750 gainG += (luma_mean - y) / 50;
752 "compute expotimes %d gain %d",
759 i2c_write(gspca_dev, gainG, 0x35);
761 if (expotimes > 0x0256)
763 else if (expotimes < 3)
765 i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
771 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
772 u8 *data, /* isoc packet */
773 int len) /* iso packet length */
775 struct sd *sd = (struct sd *) gspca_dev;
778 switch (*data++) { /* sequence number */
779 case 0: /* start of frame */
780 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
781 if (data[1] & 0x10) {
782 /* compressed bayer */
783 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
785 /* raw bayer (with a header, which we skip) */
786 if (sd->chip_revision == Rev012A) {
793 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
796 case 0xff: /* drop (empty mpackets) */
799 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
803 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
805 struct sd *sd = (struct sd *) gspca_dev;
807 sd->brightness = val;
808 if (gspca_dev->streaming)
809 setbrightness(gspca_dev);
813 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
815 struct sd *sd = (struct sd *) gspca_dev;
817 *val = sd->brightness;
822 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
824 struct sd *sd = (struct sd *) gspca_dev;
827 if (gspca_dev->streaming)
828 setcontrast(gspca_dev);
832 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
834 struct sd *sd = (struct sd *) gspca_dev;
840 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
842 struct sd *sd = (struct sd *) gspca_dev;
845 if (gspca_dev->streaming)
846 setautogain(gspca_dev);
850 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
852 struct sd *sd = (struct sd *) gspca_dev;
858 static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
860 struct sd *sd = (struct sd *) gspca_dev;
863 if (gspca_dev->streaming)
868 static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
870 struct sd *sd = (struct sd *) gspca_dev;
877 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
879 struct sd *sd = (struct sd *) gspca_dev;
882 if (gspca_dev->streaming)
883 setexposure(gspca_dev);
887 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
889 struct sd *sd = (struct sd *) gspca_dev;
896 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
898 struct sd *sd = (struct sd *) gspca_dev;
901 if (gspca_dev->streaming)
906 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
908 struct sd *sd = (struct sd *) gspca_dev;
915 static const struct ctrl sd_ctrls_12a[] = {
919 .type = V4L2_CTRL_TYPE_INTEGER,
924 .default_value = HUE_DEF,
931 .id = V4L2_CID_EXPOSURE,
932 .type = V4L2_CTRL_TYPE_INTEGER,
934 .minimum = EXPOSURE_MIN,
935 .maximum = EXPOSURE_MAX,
937 .default_value = EXPOSURE_DEF,
939 .set = sd_setexposure,
940 .get = sd_getexposure,
945 .type = V4L2_CTRL_TYPE_INTEGER,
950 .default_value = GAIN_DEF,
957 static const struct ctrl sd_ctrls_72a[] = {
961 .type = V4L2_CTRL_TYPE_INTEGER,
966 .default_value = HUE_DEF,
973 .id = V4L2_CID_BRIGHTNESS,
974 .type = V4L2_CTRL_TYPE_INTEGER,
975 .name = "Brightness",
976 .minimum = BRIGHTNESS_MIN,
977 .maximum = BRIGHTNESS_MAX,
979 .default_value = BRIGHTNESS_DEF,
981 .set = sd_setbrightness,
982 .get = sd_getbrightness,
986 .id = V4L2_CID_CONTRAST,
987 .type = V4L2_CTRL_TYPE_INTEGER,
989 .minimum = CONTRAST_MIN,
990 .maximum = CONTRAST_MAX,
992 .default_value = CONTRAST_DEF,
994 .set = sd_setcontrast,
995 .get = sd_getcontrast,
999 .id = V4L2_CID_AUTOGAIN,
1000 .type = V4L2_CTRL_TYPE_BOOLEAN,
1001 .name = "Auto Gain",
1002 .minimum = AUTOGAIN_MIN,
1003 .maximum = AUTOGAIN_MAX,
1005 .default_value = AUTOGAIN_DEF,
1007 .set = sd_setautogain,
1008 .get = sd_getautogain,
1012 /* sub-driver description */
1013 static const struct sd_desc sd_desc_12a = {
1014 .name = MODULE_NAME,
1015 .ctrls = sd_ctrls_12a,
1016 .nctrls = ARRAY_SIZE(sd_ctrls_12a),
1017 .config = sd_config,
1018 .init = sd_init_12a,
1019 .start = sd_start_12a,
1021 .pkt_scan = sd_pkt_scan,
1023 static const struct sd_desc sd_desc_72a = {
1024 .name = MODULE_NAME,
1025 .ctrls = sd_ctrls_72a,
1026 .nctrls = ARRAY_SIZE(sd_ctrls_72a),
1027 .config = sd_config,
1028 .init = sd_init_72a,
1029 .start = sd_start_72a,
1031 .pkt_scan = sd_pkt_scan,
1032 .dq_callback = do_autogain,
1034 static const struct sd_desc *sd_desc[2] = {
1039 /* -- module initialisation -- */
1040 static const __devinitdata struct usb_device_id device_table[] = {
1041 {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
1042 {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
1043 {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
1044 {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
1045 {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
1046 {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
1047 {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
1048 {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
1049 {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
1050 {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
1051 {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
1052 {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
1053 {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
1054 {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
1055 {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
1056 {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
1060 MODULE_DEVICE_TABLE(usb, device_table);
1062 /* -- device connect -- */
1063 static int sd_probe(struct usb_interface *intf,
1064 const struct usb_device_id *id)
1066 return gspca_dev_probe(intf, id,
1067 sd_desc[id->driver_info],
1072 static struct usb_driver sd_driver = {
1073 .name = MODULE_NAME,
1074 .id_table = device_table,
1076 .disconnect = gspca_disconnect,
1078 .suspend = gspca_suspend,
1079 .resume = gspca_resume,
1083 /* -- module insert / remove -- */
1084 static int __init sd_mod_init(void)
1087 ret = usb_register(&sd_driver);
1090 PDEBUG(D_PROBE, "registered");
1093 static void __exit sd_mod_exit(void)
1095 usb_deregister(&sd_driver);
1096 PDEBUG(D_PROBE, "deregistered");
1099 module_init(sd_mod_init);
1100 module_exit(sd_mod_exit);