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