1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#define MODULE_NAME "spca561"
26
27#include <linux/input.h>
28#include "gspca.h"
29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34
35struct sd {
36 struct gspca_dev gspca_dev;
37
38 __u16 exposure;
39#define EXPOSURE_MIN 1
40#define EXPOSURE_DEF 700
41#define EXPOSURE_MAX (2047 + 325)
42
43 __u8 contrast;
44#define CONTRAST_MIN 0x00
45#define CONTRAST_DEF 0x20
46#define CONTRAST_MAX 0x3f
47
48 __u8 brightness;
49#define BRIGHTNESS_MIN 0
50#define BRIGHTNESS_DEF 0x20
51#define BRIGHTNESS_MAX 0x3f
52
53 __u8 white;
54#define HUE_MIN 1
55#define HUE_DEF 0x40
56#define HUE_MAX 0x7f
57
58 __u8 autogain;
59#define AUTOGAIN_MIN 0
60#define AUTOGAIN_DEF 1
61#define AUTOGAIN_MAX 1
62
63 __u8 gain;
64#define GAIN_MIN 0
65#define GAIN_DEF 63
66#define GAIN_MAX 255
67
68#define EXPO12A_DEF 3
69 __u8 expo12a;
70
71 __u8 chip_revision;
72#define Rev012A 0
73#define Rev072A 1
74
75 signed char ag_cnt;
76#define AG_CNT_START 13
77};
78
79static const struct v4l2_pix_format sif_012a_mode[] = {
80 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
81 .bytesperline = 160,
82 .sizeimage = 160 * 120,
83 .colorspace = V4L2_COLORSPACE_SRGB,
84 .priv = 3},
85 {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
86 .bytesperline = 176,
87 .sizeimage = 176 * 144,
88 .colorspace = V4L2_COLORSPACE_SRGB,
89 .priv = 2},
90 {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
91 .bytesperline = 320,
92 .sizeimage = 320 * 240 * 4 / 8,
93 .colorspace = V4L2_COLORSPACE_SRGB,
94 .priv = 1},
95 {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
96 .bytesperline = 352,
97 .sizeimage = 352 * 288 * 4 / 8,
98 .colorspace = V4L2_COLORSPACE_SRGB,
99 .priv = 0},
100};
101
102static const struct v4l2_pix_format sif_072a_mode[] = {
103 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
104 .bytesperline = 160,
105 .sizeimage = 160 * 120,
106 .colorspace = V4L2_COLORSPACE_SRGB,
107 .priv = 3},
108 {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
109 .bytesperline = 176,
110 .sizeimage = 176 * 144,
111 .colorspace = V4L2_COLORSPACE_SRGB,
112 .priv = 2},
113 {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
114 .bytesperline = 320,
115 .sizeimage = 320 * 240,
116 .colorspace = V4L2_COLORSPACE_SRGB,
117 .priv = 1},
118 {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
119 .bytesperline = 352,
120 .sizeimage = 352 * 288,
121 .colorspace = V4L2_COLORSPACE_SRGB,
122 .priv = 0},
123};
124
125
126
127
128
129
130
131#define SPCA561_OFFSET_SNAP 1
132#define SPCA561_OFFSET_TYPE 2
133#define SPCA561_OFFSET_COMPRESS 3
134#define SPCA561_OFFSET_FRAMSEQ 4
135#define SPCA561_OFFSET_GPIO 5
136#define SPCA561_OFFSET_USBBUFF 6
137#define SPCA561_OFFSET_WIN2GRAVE 7
138#define SPCA561_OFFSET_WIN2RAVE 8
139#define SPCA561_OFFSET_WIN2BAVE 9
140#define SPCA561_OFFSET_WIN2GBAVE 10
141#define SPCA561_OFFSET_WIN1GRAVE 11
142#define SPCA561_OFFSET_WIN1RAVE 12
143#define SPCA561_OFFSET_WIN1BAVE 13
144#define SPCA561_OFFSET_WIN1GBAVE 14
145#define SPCA561_OFFSET_FREQ 15
146#define SPCA561_OFFSET_VSYNC 16
147#define SPCA561_INDEX_I2C_BASE 0x8800
148#define SPCA561_SNAPBIT 0x20
149#define SPCA561_SNAPCTRL 0x40
150
151static const u16 rev72a_reset[][2] = {
152 {0x0000, 0x8114},
153 {0x0001, 0x8114},
154 {0x0000, 0x8112},
155 {}
156};
157static const __u16 rev72a_init_data1[][2] = {
158 {0x0003, 0x8701},
159 {0x0001, 0x8703},
160 {0x0011, 0x8118},
161 {0x0001, 0x8118},
162 {0x0092, 0x8804},
163 {0x0010, 0x8802},
164 {}
165};
166static const u16 rev72a_init_sensor1[][2] = {
167 {0x0001, 0x000d},
168 {0x0002, 0x0018},
169 {0x0004, 0x0165},
170 {0x0005, 0x0021},
171 {0x0007, 0x00aa},
172 {0x0020, 0x1504},
173 {0x0039, 0x0002},
174 {0x0035, 0x0010},
175 {0x0009, 0x1049},
176 {0x0028, 0x000b},
177 {0x003b, 0x000f},
178 {0x003c, 0x0000},
179 {}
180};
181static const __u16 rev72a_init_data2[][2] = {
182 {0x0018, 0x8601},
183 {0x0000, 0x8602},
184 {0x0060, 0x8604},
185 {0x0002, 0x8605},
186 {0x0000, 0x8603},
187 {0x0002, 0x865b},
188 {0x0000, 0x865f},
189 {0x00b0, 0x865d},
190 {0x0090, 0x865e},
191 {0x00e0, 0x8406},
192 {0x0000, 0x8660},
193 {0x0002, 0x8201},
194 {0x0008, 0x8200},
195 {0x0001, 0x8200},
196
197 {0x0000, 0x8611},
198 {0x00fd, 0x8612},
199 {0x0003, 0x8613},
200 {0x0000, 0x8614},
201
202 {0x0035, 0x8651},
203 {0x0040, 0x8652},
204 {0x005f, 0x8653},
205 {0x0040, 0x8654},
206 {0x0002, 0x8502},
207 {0x0011, 0x8802},
208
209 {0x0087, 0x8700},
210 {0x0081, 0x8702},
211
212 {0x0000, 0x8500},
213
214
215 {0x0002, 0x865b},
216 {0x0003, 0x865c},
217 {}
218};
219static const u16 rev72a_init_sensor2[][2] = {
220 {0x0003, 0x0121},
221 {0x0004, 0x0165},
222 {0x0005, 0x002f},
223 {0x0006, 0x0000},
224 {0x000a, 0x0002},
225 {0x0009, 0x1061},
226
227 {0x0035, 0x0014},
228 {}
229};
230
231
232static const __u16 Pb100_1map8300[][2] = {
233
234 {0x8320, 0x3304},
235
236 {0x8303, 0x0125},
237 {0x8304, 0x0169},
238 {0x8328, 0x000b},
239 {0x833c, 0x0001},
240
241 {0x832f, 0x1904},
242 {0x8307, 0x00aa},
243 {0x8301, 0x0003},
244 {0x8302, 0x000e},
245 {}
246};
247static const __u16 Pb100_2map8300[][2] = {
248
249 {0x8339, 0x0000},
250 {0x8307, 0x00aa},
251 {}
252};
253
254static const __u16 spca561_161rev12A_data1[][2] = {
255 {0x29, 0x8118},
256 {0x08, 0x8114},
257 {0x0e, 0x8112},
258 {0x00, 0x8102},
259 {0x92, 0x8804},
260 {0x04, 0x8802},
261 {}
262};
263static const __u16 spca561_161rev12A_data2[][2] = {
264 {0x21, 0x8118},
265 {0x10, 0x8500},
266 {0x07, 0x8601},
267 {0x07, 0x8602},
268 {0x04, 0x8501},
269
270 {0x07, 0x8201},
271 {0x08, 0x8200},
272 {0x01, 0x8200},
273
274 {0x90, 0x8604},
275 {0x00, 0x8605},
276 {0xb0, 0x8603},
277
278
279 {0x07, 0x8601},
280 {0x07, 0x8602},
281 {0x00, 0x8610},
282 {0x00, 0x8611},
283 {0x00, 0x8612},
284 {0x00, 0x8613},
285 {0x43, 0x8614},
286 {0x40, 0x8615},
287 {0x71, 0x8616},
288 {0x40, 0x8617},
289
290 {0x0c, 0x8620},
291 {0xc8, 0x8631},
292 {0xc8, 0x8634},
293 {0x23, 0x8635},
294 {0x1f, 0x8636},
295 {0xdd, 0x8637},
296 {0xe1, 0x8638},
297 {0x1d, 0x8639},
298 {0x21, 0x863a},
299 {0xe3, 0x863b},
300 {0xdf, 0x863c},
301 {0xf0, 0x8505},
302 {0x32, 0x850a},
303
304
305
306 {0x29, 0x8118},
307 {}
308};
309
310static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
311{
312 int ret;
313
314 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
315 0,
316 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
317 value, index, NULL, 0, 500);
318 PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
319 if (ret < 0)
320 pr_err("reg write: error %d\n", ret);
321}
322
323static void write_vector(struct gspca_dev *gspca_dev,
324 const __u16 data[][2])
325{
326 struct usb_device *dev = gspca_dev->dev;
327 int i;
328
329 i = 0;
330 while (data[i][1] != 0) {
331 reg_w_val(dev, data[i][1], data[i][0]);
332 i++;
333 }
334}
335
336
337static void reg_r(struct gspca_dev *gspca_dev,
338 __u16 index, __u16 length)
339{
340 usb_control_msg(gspca_dev->dev,
341 usb_rcvctrlpipe(gspca_dev->dev, 0),
342 0,
343 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
344 0,
345 index, gspca_dev->usb_buf, length, 500);
346}
347
348
349static void reg_w_buf(struct gspca_dev *gspca_dev,
350 __u16 index, __u16 len)
351{
352 usb_control_msg(gspca_dev->dev,
353 usb_sndctrlpipe(gspca_dev->dev, 0),
354 0,
355 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
356 0,
357 index, gspca_dev->usb_buf, len, 500);
358}
359
360static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
361{
362 int retry = 60;
363
364 reg_w_val(gspca_dev->dev, 0x8801, reg);
365 reg_w_val(gspca_dev->dev, 0x8805, value);
366 reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
367 do {
368 reg_r(gspca_dev, 0x8803, 1);
369 if (!gspca_dev->usb_buf[0])
370 return;
371 msleep(10);
372 } while (--retry);
373}
374
375static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
376{
377 int retry = 60;
378 __u8 value;
379
380 reg_w_val(gspca_dev->dev, 0x8804, 0x92);
381 reg_w_val(gspca_dev->dev, 0x8801, reg);
382 reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
383 do {
384 reg_r(gspca_dev, 0x8803, 1);
385 if (!gspca_dev->usb_buf[0]) {
386 reg_r(gspca_dev, 0x8800, 1);
387 value = gspca_dev->usb_buf[0];
388 reg_r(gspca_dev, 0x8805, 1);
389 return ((int) value << 8) | gspca_dev->usb_buf[0];
390 }
391 msleep(10);
392 } while (--retry);
393 return -1;
394}
395
396static void sensor_mapwrite(struct gspca_dev *gspca_dev,
397 const __u16 (*sensormap)[2])
398{
399 while ((*sensormap)[0]) {
400 gspca_dev->usb_buf[0] = (*sensormap)[1];
401 gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
402 reg_w_buf(gspca_dev, (*sensormap)[0], 2);
403 sensormap++;
404 }
405}
406
407static void write_sensor_72a(struct gspca_dev *gspca_dev,
408 const __u16 (*sensor)[2])
409{
410 while ((*sensor)[0]) {
411 i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
412 sensor++;
413 }
414}
415
416static void init_161rev12A(struct gspca_dev *gspca_dev)
417{
418 write_vector(gspca_dev, spca561_161rev12A_data1);
419 sensor_mapwrite(gspca_dev, Pb100_1map8300);
420
421 write_vector(gspca_dev, spca561_161rev12A_data2);
422 sensor_mapwrite(gspca_dev, Pb100_2map8300);
423}
424
425
426static int sd_config(struct gspca_dev *gspca_dev,
427 const struct usb_device_id *id)
428{
429 struct sd *sd = (struct sd *) gspca_dev;
430 struct cam *cam;
431 __u16 vendor, product;
432 __u8 data1, data2;
433
434
435
436
437
438 reg_r(gspca_dev, 0x8104, 1);
439 data1 = gspca_dev->usb_buf[0];
440 reg_r(gspca_dev, 0x8105, 1);
441 data2 = gspca_dev->usb_buf[0];
442 vendor = (data2 << 8) | data1;
443 reg_r(gspca_dev, 0x8106, 1);
444 data1 = gspca_dev->usb_buf[0];
445 reg_r(gspca_dev, 0x8107, 1);
446 data2 = gspca_dev->usb_buf[0];
447 product = (data2 << 8) | data1;
448 if (vendor != id->idVendor || product != id->idProduct) {
449 PDEBUG(D_PROBE, "Bad vendor / product from device");
450 return -EINVAL;
451 }
452
453 cam = &gspca_dev->cam;
454 gspca_dev->nbalt = 7 + 1;
455
456 sd->chip_revision = id->driver_info;
457 if (sd->chip_revision == Rev012A) {
458 cam->cam_mode = sif_012a_mode;
459 cam->nmodes = ARRAY_SIZE(sif_012a_mode);
460 } else {
461 cam->cam_mode = sif_072a_mode;
462 cam->nmodes = ARRAY_SIZE(sif_072a_mode);
463 }
464 sd->brightness = BRIGHTNESS_DEF;
465 sd->contrast = CONTRAST_DEF;
466 sd->white = HUE_DEF;
467 sd->exposure = EXPOSURE_DEF;
468 sd->autogain = AUTOGAIN_DEF;
469 sd->gain = GAIN_DEF;
470 sd->expo12a = EXPO12A_DEF;
471 return 0;
472}
473
474
475static int sd_init_12a(struct gspca_dev *gspca_dev)
476{
477 PDEBUG(D_STREAM, "Chip revision: 012a");
478 init_161rev12A(gspca_dev);
479 return 0;
480}
481static int sd_init_72a(struct gspca_dev *gspca_dev)
482{
483 PDEBUG(D_STREAM, "Chip revision: 072a");
484 write_vector(gspca_dev, rev72a_reset);
485 msleep(200);
486 write_vector(gspca_dev, rev72a_init_data1);
487 write_sensor_72a(gspca_dev, rev72a_init_sensor1);
488 write_vector(gspca_dev, rev72a_init_data2);
489 write_sensor_72a(gspca_dev, rev72a_init_sensor2);
490 reg_w_val(gspca_dev->dev, 0x8112, 0x30);
491 return 0;
492}
493
494
495static void setbrightness(struct gspca_dev *gspca_dev)
496{
497 struct sd *sd = (struct sd *) gspca_dev;
498 struct usb_device *dev = gspca_dev->dev;
499 __u8 value;
500
501 value = sd->brightness;
502
503
504 reg_w_val(dev, 0x8611, value);
505 reg_w_val(dev, 0x8612, value);
506 reg_w_val(dev, 0x8613, value);
507 reg_w_val(dev, 0x8614, value);
508}
509
510static void setwhite(struct gspca_dev *gspca_dev)
511{
512 struct sd *sd = (struct sd *) gspca_dev;
513 __u16 white;
514 __u8 blue, red;
515 __u16 reg;
516
517
518 white = sd->white;
519 red = 0x20 + white * 3 / 8;
520 blue = 0x90 - white * 5 / 8;
521 if (sd->chip_revision == Rev012A) {
522 reg = 0x8614;
523 } else {
524 reg = 0x8651;
525 red += sd->contrast - 0x20;
526 blue += sd->contrast - 0x20;
527 }
528 reg_w_val(gspca_dev->dev, reg, red);
529 reg_w_val(gspca_dev->dev, reg + 2, blue);
530}
531
532static void setcontrast(struct gspca_dev *gspca_dev)
533{
534 struct sd *sd = (struct sd *) gspca_dev;
535 struct usb_device *dev = gspca_dev->dev;
536 __u8 value;
537
538 if (sd->chip_revision != Rev072A)
539 return;
540 value = sd->contrast + 0x20;
541
542
543 setwhite(gspca_dev);
544
545 reg_w_val(dev, 0x8652, value);
546
547 reg_w_val(dev, 0x8654, value);
548}
549
550
551static void setexposure(struct gspca_dev *gspca_dev)
552{
553 struct sd *sd = (struct sd *) gspca_dev;
554 int i, expo = 0;
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572 int table[] = { 0, 450, 550, 625, EXPOSURE_MAX };
573
574 for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
575 if (sd->exposure <= table[i + 1]) {
576 expo = sd->exposure - table[i];
577 if (i)
578 expo += 300;
579 expo |= i << 11;
580 break;
581 }
582 }
583
584 gspca_dev->usb_buf[0] = expo;
585 gspca_dev->usb_buf[1] = expo >> 8;
586 reg_w_buf(gspca_dev, 0x8309, 2);
587}
588
589
590static void setgain(struct gspca_dev *gspca_dev)
591{
592 struct sd *sd = (struct sd *) gspca_dev;
593
594
595
596
597 if (sd->gain < 64)
598 gspca_dev->usb_buf[0] = sd->gain;
599 else if (sd->gain < 128)
600 gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
601 else
602 gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xc0;
603
604 gspca_dev->usb_buf[1] = 0;
605 reg_w_buf(gspca_dev, 0x8335, 2);
606}
607
608static void setautogain(struct gspca_dev *gspca_dev)
609{
610 struct sd *sd = (struct sd *) gspca_dev;
611
612 if (sd->autogain)
613 sd->ag_cnt = AG_CNT_START;
614 else
615 sd->ag_cnt = -1;
616}
617
618static int sd_start_12a(struct gspca_dev *gspca_dev)
619{
620 struct usb_device *dev = gspca_dev->dev;
621 int mode;
622 static const __u8 Reg8391[8] =
623 {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
624
625 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
626 if (mode <= 1) {
627
628 reg_w_val(dev, 0x8500, 0x10 | mode);
629 } else {
630
631
632
633 reg_w_val(dev, 0x8500, mode);
634 }
635
636 gspca_dev->usb_buf[0] = 0xaa;
637 gspca_dev->usb_buf[1] = 0x00;
638 reg_w_buf(gspca_dev, 0x8307, 2);
639
640 reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
641
642 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
643 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
644 memcpy(gspca_dev->usb_buf, Reg8391, 8);
645 reg_w_buf(gspca_dev, 0x8391, 8);
646 reg_w_buf(gspca_dev, 0x8390, 8);
647 setwhite(gspca_dev);
648 setgain(gspca_dev);
649 setexposure(gspca_dev);
650
651
652 reg_w_val(gspca_dev->dev, 0x8114, 0x00);
653 return 0;
654}
655static int sd_start_72a(struct gspca_dev *gspca_dev)
656{
657 struct usb_device *dev = gspca_dev->dev;
658 int Clck;
659 int mode;
660
661 write_vector(gspca_dev, rev72a_reset);
662 msleep(200);
663 write_vector(gspca_dev, rev72a_init_data1);
664 write_sensor_72a(gspca_dev, rev72a_init_sensor1);
665
666 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
667 switch (mode) {
668 default:
669 case 0:
670 Clck = 0x27;
671 break;
672 case 1:
673 Clck = 0x25;
674 break;
675 case 2:
676 Clck = 0x22;
677 break;
678 case 3:
679 Clck = 0x21;
680 break;
681 }
682 reg_w_val(dev, 0x8700, Clck);
683 reg_w_val(dev, 0x8702, 0x81);
684 reg_w_val(dev, 0x8500, mode);
685 write_sensor_72a(gspca_dev, rev72a_init_sensor2);
686 setcontrast(gspca_dev);
687
688 setautogain(gspca_dev);
689 reg_w_val(dev, 0x8112, 0x10 | 0x20);
690 return 0;
691}
692
693static void sd_stopN(struct gspca_dev *gspca_dev)
694{
695 struct sd *sd = (struct sd *) gspca_dev;
696
697 if (sd->chip_revision == Rev012A) {
698 reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
699
700 reg_w_val(gspca_dev->dev, 0x8114, 0x08);
701 } else {
702 reg_w_val(gspca_dev->dev, 0x8112, 0x20);
703
704 }
705}
706
707static void do_autogain(struct gspca_dev *gspca_dev)
708{
709 struct sd *sd = (struct sd *) gspca_dev;
710 int expotimes;
711 int pixelclk;
712 int gainG;
713 __u8 R, Gr, Gb, B;
714 int y;
715 __u8 luma_mean = 110;
716 __u8 luma_delta = 20;
717 __u8 spring = 4;
718
719 if (sd->ag_cnt < 0)
720 return;
721 if (--sd->ag_cnt >= 0)
722 return;
723 sd->ag_cnt = AG_CNT_START;
724
725 switch (sd->chip_revision) {
726 case Rev072A:
727 reg_r(gspca_dev, 0x8621, 1);
728 Gr = gspca_dev->usb_buf[0];
729 reg_r(gspca_dev, 0x8622, 1);
730 R = gspca_dev->usb_buf[0];
731 reg_r(gspca_dev, 0x8623, 1);
732 B = gspca_dev->usb_buf[0];
733 reg_r(gspca_dev, 0x8624, 1);
734 Gb = gspca_dev->usb_buf[0];
735 y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
736
737
738
739
740 if (y < luma_mean - luma_delta ||
741 y > luma_mean + luma_delta) {
742 expotimes = i2c_read(gspca_dev, 0x09, 0x10);
743 pixelclk = 0x0800;
744 expotimes = expotimes & 0x07ff;
745
746
747
748 gainG = i2c_read(gspca_dev, 0x35, 0x10);
749
750
751
752 expotimes += (luma_mean - y) >> spring;
753 gainG += (luma_mean - y) / 50;
754
755
756
757
758 if (gainG > 0x3f)
759 gainG = 0x3f;
760 else if (gainG < 3)
761 gainG = 3;
762 i2c_write(gspca_dev, gainG, 0x35);
763
764 if (expotimes > 0x0256)
765 expotimes = 0x0256;
766 else if (expotimes < 3)
767 expotimes = 3;
768 i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
769 }
770 break;
771 }
772}
773
774static void sd_pkt_scan(struct gspca_dev *gspca_dev,
775 u8 *data,
776 int len)
777{
778 struct sd *sd = (struct sd *) gspca_dev;
779
780 len--;
781 switch (*data++) {
782 case 0:
783 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
784
785
786 if (len < 2) {
787 PDEBUG(D_ERR, "Short SOF packet, ignoring");
788 gspca_dev->last_packet_type = DISCARD_PACKET;
789 return;
790 }
791
792#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
793 if (data[0] & 0x20) {
794 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
795 input_sync(gspca_dev->input_dev);
796 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
797 input_sync(gspca_dev->input_dev);
798 }
799#endif
800
801 if (data[1] & 0x10) {
802
803 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
804 } else {
805
806 if (sd->chip_revision == Rev012A) {
807 data += 20;
808 len -= 20;
809 } else {
810 data += 16;
811 len -= 16;
812 }
813 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
814 }
815 return;
816 case 0xff:
817 return;
818 }
819 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
820}
821
822
823static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
824{
825 struct sd *sd = (struct sd *) gspca_dev;
826
827 sd->brightness = val;
828 if (gspca_dev->streaming)
829 setbrightness(gspca_dev);
830 return 0;
831}
832
833static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
834{
835 struct sd *sd = (struct sd *) gspca_dev;
836
837 *val = sd->brightness;
838 return 0;
839}
840
841
842static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
843{
844 struct sd *sd = (struct sd *) gspca_dev;
845
846 sd->contrast = val;
847 if (gspca_dev->streaming)
848 setcontrast(gspca_dev);
849 return 0;
850}
851
852static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
853{
854 struct sd *sd = (struct sd *) gspca_dev;
855
856 *val = sd->contrast;
857 return 0;
858}
859
860static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
861{
862 struct sd *sd = (struct sd *) gspca_dev;
863
864 sd->autogain = val;
865 if (gspca_dev->streaming)
866 setautogain(gspca_dev);
867 return 0;
868}
869
870static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
871{
872 struct sd *sd = (struct sd *) gspca_dev;
873
874 *val = sd->autogain;
875 return 0;
876}
877
878static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
879{
880 struct sd *sd = (struct sd *) gspca_dev;
881
882 sd->white = val;
883 if (gspca_dev->streaming)
884 setwhite(gspca_dev);
885 return 0;
886}
887
888static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
889{
890 struct sd *sd = (struct sd *) gspca_dev;
891
892 *val = sd->white;
893 return 0;
894}
895
896
897static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
898{
899 struct sd *sd = (struct sd *) gspca_dev;
900
901 sd->exposure = val;
902 if (gspca_dev->streaming)
903 setexposure(gspca_dev);
904 return 0;
905}
906
907static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
908{
909 struct sd *sd = (struct sd *) gspca_dev;
910
911 *val = sd->exposure;
912 return 0;
913}
914
915
916static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
917{
918 struct sd *sd = (struct sd *) gspca_dev;
919
920 sd->gain = val;
921 if (gspca_dev->streaming)
922 setgain(gspca_dev);
923 return 0;
924}
925
926static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
927{
928 struct sd *sd = (struct sd *) gspca_dev;
929
930 *val = sd->gain;
931 return 0;
932}
933
934
935static const struct ctrl sd_ctrls_12a[] = {
936 {
937 {
938 .id = V4L2_CID_HUE,
939 .type = V4L2_CTRL_TYPE_INTEGER,
940 .name = "Hue",
941 .minimum = HUE_MIN,
942 .maximum = HUE_MAX,
943 .step = 1,
944 .default_value = HUE_DEF,
945 },
946 .set = sd_setwhite,
947 .get = sd_getwhite,
948 },
949 {
950 {
951 .id = V4L2_CID_EXPOSURE,
952 .type = V4L2_CTRL_TYPE_INTEGER,
953 .name = "Exposure",
954 .minimum = EXPOSURE_MIN,
955 .maximum = EXPOSURE_MAX,
956 .step = 1,
957 .default_value = EXPOSURE_DEF,
958 },
959 .set = sd_setexposure,
960 .get = sd_getexposure,
961 },
962 {
963 {
964 .id = V4L2_CID_GAIN,
965 .type = V4L2_CTRL_TYPE_INTEGER,
966 .name = "Gain",
967 .minimum = GAIN_MIN,
968 .maximum = GAIN_MAX,
969 .step = 1,
970 .default_value = GAIN_DEF,
971 },
972 .set = sd_setgain,
973 .get = sd_getgain,
974 },
975};
976
977static const struct ctrl sd_ctrls_72a[] = {
978 {
979 {
980 .id = V4L2_CID_HUE,
981 .type = V4L2_CTRL_TYPE_INTEGER,
982 .name = "Hue",
983 .minimum = HUE_MIN,
984 .maximum = HUE_MAX,
985 .step = 1,
986 .default_value = HUE_DEF,
987 },
988 .set = sd_setwhite,
989 .get = sd_getwhite,
990 },
991 {
992 {
993 .id = V4L2_CID_BRIGHTNESS,
994 .type = V4L2_CTRL_TYPE_INTEGER,
995 .name = "Brightness",
996 .minimum = BRIGHTNESS_MIN,
997 .maximum = BRIGHTNESS_MAX,
998 .step = 1,
999 .default_value = BRIGHTNESS_DEF,
1000 },
1001 .set = sd_setbrightness,
1002 .get = sd_getbrightness,
1003 },
1004 {
1005 {
1006 .id = V4L2_CID_CONTRAST,
1007 .type = V4L2_CTRL_TYPE_INTEGER,
1008 .name = "Contrast",
1009 .minimum = CONTRAST_MIN,
1010 .maximum = CONTRAST_MAX,
1011 .step = 1,
1012 .default_value = CONTRAST_DEF,
1013 },
1014 .set = sd_setcontrast,
1015 .get = sd_getcontrast,
1016 },
1017 {
1018 {
1019 .id = V4L2_CID_AUTOGAIN,
1020 .type = V4L2_CTRL_TYPE_BOOLEAN,
1021 .name = "Auto Gain",
1022 .minimum = AUTOGAIN_MIN,
1023 .maximum = AUTOGAIN_MAX,
1024 .step = 1,
1025 .default_value = AUTOGAIN_DEF,
1026 },
1027 .set = sd_setautogain,
1028 .get = sd_getautogain,
1029 },
1030};
1031
1032
1033static const struct sd_desc sd_desc_12a = {
1034 .name = MODULE_NAME,
1035 .ctrls = sd_ctrls_12a,
1036 .nctrls = ARRAY_SIZE(sd_ctrls_12a),
1037 .config = sd_config,
1038 .init = sd_init_12a,
1039 .start = sd_start_12a,
1040 .stopN = sd_stopN,
1041 .pkt_scan = sd_pkt_scan,
1042#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1043 .other_input = 1,
1044#endif
1045};
1046static const struct sd_desc sd_desc_72a = {
1047 .name = MODULE_NAME,
1048 .ctrls = sd_ctrls_72a,
1049 .nctrls = ARRAY_SIZE(sd_ctrls_72a),
1050 .config = sd_config,
1051 .init = sd_init_72a,
1052 .start = sd_start_72a,
1053 .stopN = sd_stopN,
1054 .pkt_scan = sd_pkt_scan,
1055 .dq_callback = do_autogain,
1056#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1057 .other_input = 1,
1058#endif
1059};
1060static const struct sd_desc *sd_desc[2] = {
1061 &sd_desc_12a,
1062 &sd_desc_72a
1063};
1064
1065
1066static const struct usb_device_id device_table[] = {
1067 {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
1068 {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
1069 {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
1070 {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
1071 {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
1072 {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
1073 {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
1074 {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
1075 {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
1076 {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
1077 {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
1078 {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
1079 {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
1080 {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
1081 {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
1082 {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
1083 {}
1084};
1085
1086MODULE_DEVICE_TABLE(usb, device_table);
1087
1088
1089static int sd_probe(struct usb_interface *intf,
1090 const struct usb_device_id *id)
1091{
1092 return gspca_dev_probe(intf, id,
1093 sd_desc[id->driver_info],
1094 sizeof(struct sd),
1095 THIS_MODULE);
1096}
1097
1098static struct usb_driver sd_driver = {
1099 .name = MODULE_NAME,
1100 .id_table = device_table,
1101 .probe = sd_probe,
1102 .disconnect = gspca_disconnect,
1103#ifdef CONFIG_PM
1104 .suspend = gspca_suspend,
1105 .resume = gspca_resume,
1106#endif
1107};
1108
1109
1110static int __init sd_mod_init(void)
1111{
1112 return usb_register(&sd_driver);
1113}
1114static void __exit sd_mod_exit(void)
1115{
1116 usb_deregister(&sd_driver);
1117}
1118
1119module_init(sd_mod_init);
1120module_exit(sd_mod_exit);
1121