1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46#define MODULE_NAME "sonixb"
47
48#include <linux/input.h>
49#include "gspca.h"
50
51MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
52MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
53MODULE_LICENSE("GPL");
54
55
56struct sd {
57 struct gspca_dev gspca_dev;
58
59 struct v4l2_ctrl *brightness;
60 struct v4l2_ctrl *plfreq;
61
62 atomic_t avg_lum;
63 int prev_avg_lum;
64 int exposure_knee;
65 int header_read;
66 u8 header[12];
67
68 unsigned char autogain_ignore_frames;
69 unsigned char frames_to_drop;
70
71 __u8 bridge;
72#define BRIDGE_101 0
73#define BRIDGE_102 0
74#define BRIDGE_103 1
75
76 __u8 sensor;
77#define SENSOR_HV7131D 0
78#define SENSOR_HV7131R 1
79#define SENSOR_OV6650 2
80#define SENSOR_OV7630 3
81#define SENSOR_PAS106 4
82#define SENSOR_PAS202 5
83#define SENSOR_TAS5110C 6
84#define SENSOR_TAS5110D 7
85#define SENSOR_TAS5130CXX 8
86 __u8 reg11;
87};
88
89typedef const __u8 sensor_init_t[8];
90
91struct sensor_data {
92 const __u8 *bridge_init;
93 sensor_init_t *sensor_init;
94 int sensor_init_size;
95 int flags;
96 __u8 sensor_addr;
97};
98
99
100#define F_SIF 0x01
101
102
103#define MODE_RAW 0x10
104#define MODE_REDUCED_SIF 0x20
105
106#define COMP 0xc7
107#define COMP1 0xc9
108
109#define MCK_INIT 0x63
110#define MCK_INIT1 0x20
111
112#define SYS_CLK 0x04
113
114#define SENS(bridge, sensor, _flags, _sensor_addr) \
115{ \
116 .bridge_init = bridge, \
117 .sensor_init = sensor, \
118 .sensor_init_size = sizeof(sensor), \
119 .flags = _flags, .sensor_addr = _sensor_addr \
120}
121
122
123
124
125
126#define AUTOGAIN_IGNORE_FRAMES 1
127
128static const struct v4l2_pix_format vga_mode[] = {
129 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
130 .bytesperline = 160,
131 .sizeimage = 160 * 120,
132 .colorspace = V4L2_COLORSPACE_SRGB,
133 .priv = 2 | MODE_RAW},
134 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
135 .bytesperline = 160,
136 .sizeimage = 160 * 120 * 5 / 4,
137 .colorspace = V4L2_COLORSPACE_SRGB,
138 .priv = 2},
139 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
140 .bytesperline = 320,
141 .sizeimage = 320 * 240 * 5 / 4,
142 .colorspace = V4L2_COLORSPACE_SRGB,
143 .priv = 1},
144 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
145 .bytesperline = 640,
146 .sizeimage = 640 * 480 * 5 / 4,
147 .colorspace = V4L2_COLORSPACE_SRGB,
148 .priv = 0},
149};
150static const struct v4l2_pix_format sif_mode[] = {
151 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
152 .bytesperline = 160,
153 .sizeimage = 160 * 120,
154 .colorspace = V4L2_COLORSPACE_SRGB,
155 .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
156 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
157 .bytesperline = 160,
158 .sizeimage = 160 * 120 * 5 / 4,
159 .colorspace = V4L2_COLORSPACE_SRGB,
160 .priv = 1 | MODE_REDUCED_SIF},
161 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
162 .bytesperline = 176,
163 .sizeimage = 176 * 144,
164 .colorspace = V4L2_COLORSPACE_SRGB,
165 .priv = 1 | MODE_RAW},
166 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
167 .bytesperline = 176,
168 .sizeimage = 176 * 144 * 5 / 4,
169 .colorspace = V4L2_COLORSPACE_SRGB,
170 .priv = 1},
171 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
172 .bytesperline = 320,
173 .sizeimage = 320 * 240 * 5 / 4,
174 .colorspace = V4L2_COLORSPACE_SRGB,
175 .priv = 0 | MODE_REDUCED_SIF},
176 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
177 .bytesperline = 352,
178 .sizeimage = 352 * 288 * 5 / 4,
179 .colorspace = V4L2_COLORSPACE_SRGB,
180 .priv = 0},
181};
182
183static const __u8 initHv7131d[] = {
184 0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
185 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
187 0x28, 0x1e, 0x60, 0x8e, 0x42,
188};
189static const __u8 hv7131d_sensor_init[][8] = {
190 {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
191 {0xa0, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x17},
192 {0xa0, 0x11, 0x28, 0x00, 0x00, 0x00, 0x00, 0x17},
193 {0xa0, 0x11, 0x30, 0x30, 0x00, 0x00, 0x00, 0x17},
194 {0xa0, 0x11, 0x34, 0x02, 0x00, 0x00, 0x00, 0x17},
195};
196
197static const __u8 initHv7131r[] = {
198 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
199 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
201 0x28, 0x1e, 0x60, 0x8a, 0x20,
202};
203static const __u8 hv7131r_sensor_init[][8] = {
204 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
205 {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
206 {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
207 {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
208 {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
209};
210static const __u8 initOv6650[] = {
211 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
212 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
214 0x10,
215};
216static const __u8 ov6650_sensor_init[][8] = {
217
218
219
220
221
222 {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
223
224 {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
225
226 {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
227
228
229
230
231 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
232 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
233 {0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10},
234
235 {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
236
237
238
239
240
241
242
243
244 {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
245 {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10},
246};
247
248static const __u8 initOv7630[] = {
249 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
250 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00, 0x01, 0x01, 0x0a,
252 0x28, 0x1e,
253 0x68, 0x8f, MCK_INIT1,
254};
255static const __u8 ov7630_sensor_init[][8] = {
256 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
257 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
258
259 {0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10},
260 {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
261 {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
262 {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
263 {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
264 {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
265 {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
266 {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
267 {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
268
269 {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
270 {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
271 {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
272 {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
273 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
274 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
275};
276
277static const __u8 initPas106[] = {
278 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
279 0x00, 0x00,
280 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
281 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
282};
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308static const __u8 pas106_sensor_init[][8] = {
309
310 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
311
312 { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
313
314 { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
315
316 { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
317
318 { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
319
320 { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
321
322 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
323 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
324
325 { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
326
327 { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
328
329 { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
330
331 { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
332
333 { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
334
335 { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
336
337 { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
338
339 { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
340
341 { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
342
343 { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
344
345 { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
346
347 { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
348};
349
350static const __u8 initPas202[] = {
351 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
352 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
354 0x28, 0x1e, 0x20, 0x89, 0x20,
355};
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374static const __u8 pas202_sensor_init[][8] = {
375
376
377
378 {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
379 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
380 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
381 {0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10},
382 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
383 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
384 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
385 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
386 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
387 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
388};
389
390static const __u8 initTas5110c[] = {
391 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
392 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
394 0x16, 0x12, 0x60, 0x86, 0x2b,
395};
396
397static const __u8 initTas5110d[] = {
398 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
399 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
401 0x16, 0x12, 0x60, 0x86, 0x2b,
402};
403
404static const __u8 tas5110c_sensor_init[][8] = {
405 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
406 {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
407};
408
409
410
411
412
413static const __u8 tas5110d_sensor_init[][8] = {
414 {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
415};
416
417static const __u8 initTas5130[] = {
418 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
419 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
421 0x28, 0x1e, 0x60, COMP, MCK_INIT,
422};
423static const __u8 tas5130_sensor_init[][8] = {
424
425
426 {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
427
428 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
429};
430
431static const struct sensor_data sensor_data[] = {
432 SENS(initHv7131d, hv7131d_sensor_init, 0, 0),
433 SENS(initHv7131r, hv7131r_sensor_init, 0, 0),
434 SENS(initOv6650, ov6650_sensor_init, F_SIF, 0x60),
435 SENS(initOv7630, ov7630_sensor_init, 0, 0x21),
436 SENS(initPas106, pas106_sensor_init, F_SIF, 0),
437 SENS(initPas202, pas202_sensor_init, 0, 0),
438 SENS(initTas5110c, tas5110c_sensor_init, F_SIF, 0),
439 SENS(initTas5110d, tas5110d_sensor_init, F_SIF, 0),
440 SENS(initTas5130, tas5130_sensor_init, 0, 0),
441};
442
443
444static void reg_r(struct gspca_dev *gspca_dev,
445 __u16 value)
446{
447 int res;
448
449 if (gspca_dev->usb_err < 0)
450 return;
451
452 res = usb_control_msg(gspca_dev->dev,
453 usb_rcvctrlpipe(gspca_dev->dev, 0),
454 0,
455 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
456 value,
457 0,
458 gspca_dev->usb_buf, 1,
459 500);
460
461 if (res < 0) {
462 dev_err(gspca_dev->v4l2_dev.dev,
463 "Error reading register %02x: %d\n", value, res);
464 gspca_dev->usb_err = res;
465 }
466}
467
468static void reg_w(struct gspca_dev *gspca_dev,
469 __u16 value,
470 const __u8 *buffer,
471 int len)
472{
473 int res;
474
475 if (gspca_dev->usb_err < 0)
476 return;
477
478 memcpy(gspca_dev->usb_buf, buffer, len);
479 res = usb_control_msg(gspca_dev->dev,
480 usb_sndctrlpipe(gspca_dev->dev, 0),
481 0x08,
482 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
483 value,
484 0,
485 gspca_dev->usb_buf, len,
486 500);
487
488 if (res < 0) {
489 dev_err(gspca_dev->v4l2_dev.dev,
490 "Error writing register %02x: %d\n", value, res);
491 gspca_dev->usb_err = res;
492 }
493}
494
495static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buf)
496{
497 int retry = 60;
498
499 if (gspca_dev->usb_err < 0)
500 return;
501
502
503 reg_w(gspca_dev, 0x08, buf, 8);
504 while (retry--) {
505 if (gspca_dev->usb_err < 0)
506 return;
507 msleep(1);
508 reg_r(gspca_dev, 0x08);
509 if (gspca_dev->usb_buf[0] & 0x04) {
510 if (gspca_dev->usb_buf[0] & 0x08) {
511 dev_err(gspca_dev->v4l2_dev.dev,
512 "i2c error writing %8ph\n", buf);
513 gspca_dev->usb_err = -EIO;
514 }
515 return;
516 }
517 }
518
519 dev_err(gspca_dev->v4l2_dev.dev, "i2c write timeout\n");
520 gspca_dev->usb_err = -EIO;
521}
522
523static void i2c_w_vector(struct gspca_dev *gspca_dev,
524 const __u8 buffer[][8], int len)
525{
526 for (;;) {
527 if (gspca_dev->usb_err < 0)
528 return;
529 i2c_w(gspca_dev, *buffer);
530 len -= 8;
531 if (len <= 0)
532 break;
533 buffer++;
534 }
535}
536
537static void setbrightness(struct gspca_dev *gspca_dev)
538{
539 struct sd *sd = (struct sd *) gspca_dev;
540
541 switch (sd->sensor) {
542 case SENSOR_OV6650:
543 case SENSOR_OV7630: {
544 __u8 i2cOV[] =
545 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
546
547
548 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
549 i2cOV[3] = sd->brightness->val;
550 i2c_w(gspca_dev, i2cOV);
551 break;
552 }
553 case SENSOR_PAS106:
554 case SENSOR_PAS202: {
555 __u8 i2cpbright[] =
556 {0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
557 __u8 i2cpdoit[] =
558 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
559
560
561 if (sd->sensor == SENSOR_PAS106) {
562 i2cpbright[2] = 7;
563 i2cpdoit[2] = 0x13;
564 }
565
566 if (sd->brightness->val < 127) {
567
568 i2cpbright[3] = 0x01;
569
570 i2cpbright[4] = 127 - sd->brightness->val;
571 } else
572 i2cpbright[4] = sd->brightness->val - 127;
573
574 i2c_w(gspca_dev, i2cpbright);
575 i2c_w(gspca_dev, i2cpdoit);
576 break;
577 }
578 default:
579 break;
580 }
581}
582
583static void setgain(struct gspca_dev *gspca_dev)
584{
585 struct sd *sd = (struct sd *) gspca_dev;
586 u8 gain = gspca_dev->gain->val;
587
588 switch (sd->sensor) {
589 case SENSOR_HV7131D: {
590 __u8 i2c[] =
591 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
592
593 i2c[3] = 0x3f - gain;
594 i2c[4] = 0x3f - gain;
595 i2c[5] = 0x3f - gain;
596
597 i2c_w(gspca_dev, i2c);
598 break;
599 }
600 case SENSOR_TAS5110C:
601 case SENSOR_TAS5130CXX: {
602 __u8 i2c[] =
603 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
604
605 i2c[4] = 255 - gain;
606 i2c_w(gspca_dev, i2c);
607 break;
608 }
609 case SENSOR_TAS5110D: {
610 __u8 i2c[] = {
611 0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 };
612 gain = 255 - gain;
613
614 i2c[3] |= (gain & 0x80) >> 7;
615 i2c[3] |= (gain & 0x40) >> 5;
616 i2c[3] |= (gain & 0x20) >> 3;
617 i2c[3] |= (gain & 0x10) >> 1;
618 i2c[3] |= (gain & 0x08) << 1;
619 i2c[3] |= (gain & 0x04) << 3;
620 i2c[3] |= (gain & 0x02) << 5;
621 i2c[3] |= (gain & 0x01) << 7;
622 i2c_w(gspca_dev, i2c);
623 break;
624 }
625 case SENSOR_OV6650:
626 case SENSOR_OV7630: {
627 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
628
629
630
631
632
633 if (sd->sensor == SENSOR_OV7630 && gain >= 32)
634 gain += 16;
635
636 i2c[1] = sensor_data[sd->sensor].sensor_addr;
637 i2c[3] = gain;
638 i2c_w(gspca_dev, i2c);
639 break;
640 }
641 case SENSOR_PAS106:
642 case SENSOR_PAS202: {
643 __u8 i2cpgain[] =
644 {0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
645 __u8 i2cpcolorgain[] =
646 {0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
647 __u8 i2cpdoit[] =
648 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
649
650
651 if (sd->sensor == SENSOR_PAS106) {
652 i2cpgain[2] = 0x0e;
653 i2cpcolorgain[0] = 0xd0;
654 i2cpcolorgain[2] = 0x09;
655 i2cpdoit[2] = 0x13;
656 }
657
658 i2cpgain[3] = gain;
659 i2cpcolorgain[3] = gain >> 1;
660 i2cpcolorgain[4] = gain >> 1;
661 i2cpcolorgain[5] = gain >> 1;
662 i2cpcolorgain[6] = gain >> 1;
663
664 i2c_w(gspca_dev, i2cpgain);
665 i2c_w(gspca_dev, i2cpcolorgain);
666 i2c_w(gspca_dev, i2cpdoit);
667 break;
668 }
669 default:
670 if (sd->bridge == BRIDGE_103) {
671 u8 buf[3] = { gain, gain, gain };
672 reg_w(gspca_dev, 0x05, buf, 3);
673 } else {
674 u8 buf[2];
675 buf[0] = gain << 4 | gain;
676 buf[1] = gain;
677 reg_w(gspca_dev, 0x10, buf, 2);
678 }
679 }
680}
681
682static void setexposure(struct gspca_dev *gspca_dev)
683{
684 struct sd *sd = (struct sd *) gspca_dev;
685
686 switch (sd->sensor) {
687 case SENSOR_HV7131D: {
688
689
690 __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17};
691 u16 reg = gspca_dev->exposure->val;
692
693 i2c[3] = reg >> 8;
694 i2c[4] = reg & 0xff;
695 i2c_w(gspca_dev, i2c);
696 break;
697 }
698 case SENSOR_TAS5110C:
699 case SENSOR_TAS5110D: {
700
701
702
703 u8 reg = gspca_dev->exposure->val;
704
705 reg = (reg << 4) | 0x0b;
706 reg_w(gspca_dev, 0x19, ®, 1);
707 break;
708 }
709 case SENSOR_OV6650:
710 case SENSOR_OV7630: {
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
726 int reg10, reg11, reg10_max;
727
728
729
730
731
732
733
734 if (sd->sensor == SENSOR_OV6650) {
735 reg10_max = 0x4d;
736 i2c[4] = 0xc0;
737 } else
738 reg10_max = 0x41;
739
740 reg11 = (15 * gspca_dev->exposure->val + 999) / 1000;
741 if (reg11 < 1)
742 reg11 = 1;
743 else if (reg11 > 16)
744 reg11 = 16;
745
746
747
748
749 if (gspca_dev->pixfmt.width == 640 && reg11 < 4)
750 reg11 = 4;
751
752
753
754
755 reg10 = (gspca_dev->exposure->val * 15 * reg10_max)
756 / (1000 * reg11);
757
758
759
760
761
762 if (gspca_dev->autogain->val && reg10 < 10)
763 reg10 = 10;
764 else if (reg10 > reg10_max)
765 reg10 = reg10_max;
766
767
768 i2c[1] = sensor_data[sd->sensor].sensor_addr;
769 i2c[3] = reg10;
770 i2c[4] |= reg11 - 1;
771
772
773 if (sd->reg11 == reg11)
774 i2c[0] = 0xa0;
775
776 i2c_w(gspca_dev, i2c);
777 if (gspca_dev->usb_err == 0)
778 sd->reg11 = reg11;
779 break;
780 }
781 case SENSOR_PAS202: {
782 __u8 i2cpframerate[] =
783 {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
784 __u8 i2cpexpo[] =
785 {0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
786 const __u8 i2cpdoit[] =
787 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
788 int framerate_ctrl;
789
790
791
792
793
794
795
796
797
798
799
800 if (gspca_dev->exposure->val < 200) {
801 i2cpexpo[3] = 255 - (gspca_dev->exposure->val * 255)
802 / 200;
803 framerate_ctrl = 500;
804 } else {
805
806
807
808 framerate_ctrl = (gspca_dev->exposure->val - 200)
809 * 1000 / 229 + 500;
810 }
811
812 i2cpframerate[3] = framerate_ctrl >> 6;
813 i2cpframerate[4] = framerate_ctrl & 0x3f;
814 i2c_w(gspca_dev, i2cpframerate);
815 i2c_w(gspca_dev, i2cpexpo);
816 i2c_w(gspca_dev, i2cpdoit);
817 break;
818 }
819 case SENSOR_PAS106: {
820 __u8 i2cpframerate[] =
821 {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
822 __u8 i2cpexpo[] =
823 {0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
824 const __u8 i2cpdoit[] =
825 {0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
826 int framerate_ctrl;
827
828
829
830 if (gspca_dev->exposure->val < 150) {
831 i2cpexpo[3] = 150 - gspca_dev->exposure->val;
832 framerate_ctrl = 300;
833 } else {
834
835
836
837 framerate_ctrl = (gspca_dev->exposure->val - 150)
838 * 1000 / 230 + 300;
839 }
840
841 i2cpframerate[3] = framerate_ctrl >> 4;
842 i2cpframerate[4] = framerate_ctrl & 0x0f;
843 i2c_w(gspca_dev, i2cpframerate);
844 i2c_w(gspca_dev, i2cpexpo);
845 i2c_w(gspca_dev, i2cpdoit);
846 break;
847 }
848 default:
849 break;
850 }
851}
852
853static void setfreq(struct gspca_dev *gspca_dev)
854{
855 struct sd *sd = (struct sd *) gspca_dev;
856
857 if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630) {
858
859
860
861
862 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
863 switch (sd->plfreq->val) {
864 default:
865
866
867 i2c[3] = 0;
868 break;
869 case 1:
870 i2c[3] = (sd->sensor == SENSOR_OV6650)
871 ? 0x4f : 0x8a;
872 break;
873 }
874 i2c[1] = sensor_data[sd->sensor].sensor_addr;
875 i2c_w(gspca_dev, i2c);
876 }
877}
878
879static void do_autogain(struct gspca_dev *gspca_dev)
880{
881 struct sd *sd = (struct sd *) gspca_dev;
882 int deadzone, desired_avg_lum, avg_lum;
883
884 avg_lum = atomic_read(&sd->avg_lum);
885 if (avg_lum == -1)
886 return;
887
888 if (sd->autogain_ignore_frames > 0) {
889 sd->autogain_ignore_frames--;
890 return;
891 }
892
893
894
895 if (sensor_data[sd->sensor].flags & F_SIF) {
896 deadzone = 500;
897
898 desired_avg_lum = 5000;
899 } else {
900 deadzone = 1500;
901 desired_avg_lum = 13000;
902 }
903
904 if (sd->brightness)
905 desired_avg_lum = sd->brightness->val * desired_avg_lum / 127;
906
907 if (gspca_dev->exposure->maximum < 500) {
908 if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
909 desired_avg_lum, deadzone))
910 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
911 } else {
912 int gain_knee = (s32)gspca_dev->gain->maximum * 9 / 10;
913 if (gspca_expo_autogain(gspca_dev, avg_lum, desired_avg_lum,
914 deadzone, gain_knee, sd->exposure_knee))
915 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
916 }
917}
918
919
920static int sd_config(struct gspca_dev *gspca_dev,
921 const struct usb_device_id *id)
922{
923 struct sd *sd = (struct sd *) gspca_dev;
924 struct cam *cam;
925
926 reg_r(gspca_dev, 0x00);
927 if (gspca_dev->usb_buf[0] != 0x10)
928 return -ENODEV;
929
930
931 sd->sensor = id->driver_info >> 8;
932 sd->bridge = id->driver_info & 0xff;
933
934 cam = &gspca_dev->cam;
935 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
936 cam->cam_mode = vga_mode;
937 cam->nmodes = ARRAY_SIZE(vga_mode);
938 } else {
939 cam->cam_mode = sif_mode;
940 cam->nmodes = ARRAY_SIZE(sif_mode);
941 }
942 cam->npkt = 36;
943
944 return 0;
945}
946
947
948static int sd_init(struct gspca_dev *gspca_dev)
949{
950 const __u8 stop = 0x09;
951
952 reg_w(gspca_dev, 0x01, &stop, 1);
953
954 return gspca_dev->usb_err;
955}
956
957static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
958{
959 struct gspca_dev *gspca_dev =
960 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
961 struct sd *sd = (struct sd *)gspca_dev;
962
963 gspca_dev->usb_err = 0;
964
965 if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
966
967
968
969
970 gspca_dev->gain->val = gspca_dev->gain->default_value;
971 gspca_dev->exposure->val = gspca_dev->exposure->default_value;
972 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
973 }
974
975 if (!gspca_dev->streaming)
976 return 0;
977
978 switch (ctrl->id) {
979 case V4L2_CID_BRIGHTNESS:
980 setbrightness(gspca_dev);
981 break;
982 case V4L2_CID_AUTOGAIN:
983 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
984 setexposure(gspca_dev);
985 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
986 setgain(gspca_dev);
987 break;
988 case V4L2_CID_POWER_LINE_FREQUENCY:
989 setfreq(gspca_dev);
990 break;
991 default:
992 return -EINVAL;
993 }
994 return gspca_dev->usb_err;
995}
996
997static const struct v4l2_ctrl_ops sd_ctrl_ops = {
998 .s_ctrl = sd_s_ctrl,
999};
1000
1001
1002static int sd_init_controls(struct gspca_dev *gspca_dev)
1003{
1004 struct sd *sd = (struct sd *) gspca_dev;
1005 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1006
1007 gspca_dev->vdev.ctrl_handler = hdl;
1008 v4l2_ctrl_handler_init(hdl, 5);
1009
1010 if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630 ||
1011 sd->sensor == SENSOR_PAS106 || sd->sensor == SENSOR_PAS202)
1012 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1013 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1014
1015
1016 switch (sd->sensor) {
1017 case SENSOR_OV6650:
1018 case SENSOR_PAS106:
1019 case SENSOR_PAS202:
1020 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1021 V4L2_CID_GAIN, 0, 31, 1, 15);
1022 break;
1023 case SENSOR_OV7630:
1024 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1025 V4L2_CID_GAIN, 0, 47, 1, 31);
1026 break;
1027 case SENSOR_HV7131D:
1028 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1029 V4L2_CID_GAIN, 0, 63, 1, 31);
1030 break;
1031 case SENSOR_TAS5110C:
1032 case SENSOR_TAS5110D:
1033 case SENSOR_TAS5130CXX:
1034 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1035 V4L2_CID_GAIN, 0, 255, 1, 127);
1036 break;
1037 default:
1038 if (sd->bridge == BRIDGE_103) {
1039 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1040 V4L2_CID_GAIN, 0, 127, 1, 63);
1041 } else {
1042 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1043 V4L2_CID_GAIN, 0, 15, 1, 7);
1044 }
1045 }
1046
1047
1048 switch (sd->sensor) {
1049 case SENSOR_HV7131D:
1050 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1051 V4L2_CID_EXPOSURE, 0, 8191, 1, 482);
1052 sd->exposure_knee = 964;
1053 break;
1054 case SENSOR_OV6650:
1055 case SENSOR_OV7630:
1056 case SENSOR_PAS106:
1057 case SENSOR_PAS202:
1058 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1059 V4L2_CID_EXPOSURE, 0, 1023, 1, 66);
1060 sd->exposure_knee = 200;
1061 break;
1062 case SENSOR_TAS5110C:
1063 case SENSOR_TAS5110D:
1064 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1065 V4L2_CID_EXPOSURE, 2, 15, 1, 2);
1066 break;
1067 }
1068
1069 if (gspca_dev->exposure) {
1070 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1071 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1072 }
1073
1074 if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630)
1075 sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1076 V4L2_CID_POWER_LINE_FREQUENCY,
1077 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
1078 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
1079
1080 if (hdl->error) {
1081 pr_err("Could not initialize controls\n");
1082 return hdl->error;
1083 }
1084
1085 if (gspca_dev->autogain)
1086 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
1087
1088 return 0;
1089}
1090
1091
1092static int sd_start(struct gspca_dev *gspca_dev)
1093{
1094 struct sd *sd = (struct sd *) gspca_dev;
1095 struct cam *cam = &gspca_dev->cam;
1096 int i, mode;
1097 __u8 regs[0x31];
1098
1099 mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
1100
1101 memcpy(®s[0x01], sensor_data[sd->sensor].bridge_init, 0x19);
1102
1103 regs[0x18] |= mode << 4;
1104
1105
1106 if (sd->bridge == BRIDGE_103) {
1107 regs[0x05] = 0x20;
1108 regs[0x06] = 0x20;
1109 regs[0x07] = 0x20;
1110 } else {
1111 regs[0x10] = 0x00;
1112 regs[0x11] = 0x00;
1113 }
1114
1115
1116 if (sensor_data[sd->sensor].flags & F_SIF) {
1117 regs[0x1a] = 0x14;
1118 regs[0x1b] = 0x0a;
1119 regs[0x1c] = 0x02;
1120 regs[0x1d] = 0x02;
1121 regs[0x1e] = 0x09;
1122 regs[0x1f] = 0x07;
1123 } else {
1124 regs[0x1a] = 0x1d;
1125 regs[0x1b] = 0x10;
1126 regs[0x1c] = 0x05;
1127 regs[0x1d] = 0x03;
1128 regs[0x1e] = 0x0f;
1129 regs[0x1f] = 0x0c;
1130 }
1131
1132
1133 for (i = 0; i < 16; i++)
1134 regs[0x20 + i] = i * 16;
1135 regs[0x20 + i] = 255;
1136
1137
1138 switch (sd->sensor) {
1139 case SENSOR_TAS5130CXX:
1140
1141
1142
1143
1144 regs[0x19] = mode ? 0x23 : 0x43;
1145 break;
1146 case SENSOR_OV7630:
1147
1148
1149
1150
1151 if (sd->bridge == BRIDGE_103) {
1152 regs[0x01] = 0x44;
1153 regs[0x12] = 0x02;
1154 }
1155 break;
1156 case SENSOR_PAS202:
1157
1158
1159 if (sd->bridge == BRIDGE_103)
1160 regs[0x12] += 1;
1161 break;
1162 }
1163
1164 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
1165 regs[0x18] &= ~0x80;
1166
1167
1168 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
1169 regs[0x12] += 16;
1170 regs[0x13] += 24;
1171 regs[0x15] = 320 / 16;
1172 regs[0x16] = 240 / 16;
1173 }
1174
1175
1176 reg_w(gspca_dev, 0x01, ®s[0x01], 1);
1177
1178 reg_w(gspca_dev, 0x17, ®s[0x17], 1);
1179
1180 reg_w(gspca_dev, 0x01, ®s[0x01],
1181 (sd->bridge == BRIDGE_103) ? 0x30 : 0x1f);
1182
1183
1184 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
1185 sensor_data[sd->sensor].sensor_init_size);
1186
1187
1188 switch (sd->sensor) {
1189 case SENSOR_PAS202: {
1190 const __u8 i2cpclockdiv[] =
1191 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
1192
1193 if (mode)
1194 i2c_w(gspca_dev, i2cpclockdiv);
1195 break;
1196 }
1197 case SENSOR_OV7630:
1198
1199
1200 if (sd->bridge == BRIDGE_103) {
1201 const __u8 i2c[] = { 0xa0, 0x21, 0x13,
1202 0x80, 0x00, 0x00, 0x00, 0x10 };
1203 i2c_w(gspca_dev, i2c);
1204 }
1205 break;
1206 }
1207
1208 reg_w(gspca_dev, 0x15, ®s[0x15], 2);
1209
1210 reg_w(gspca_dev, 0x18, ®s[0x18], 1);
1211
1212 reg_w(gspca_dev, 0x12, ®s[0x12], 1);
1213
1214 reg_w(gspca_dev, 0x13, ®s[0x13], 1);
1215
1216
1217 reg_w(gspca_dev, 0x17, ®s[0x17], 1);
1218
1219 reg_w(gspca_dev, 0x19, ®s[0x19], 1);
1220
1221 reg_w(gspca_dev, 0x1c, ®s[0x1c], 4);
1222
1223 reg_w(gspca_dev, 0x01, ®s[0x01], 1);
1224
1225 reg_w(gspca_dev, 0x18, ®s[0x18], 2);
1226 msleep(20);
1227
1228 sd->reg11 = -1;
1229
1230 setgain(gspca_dev);
1231 setbrightness(gspca_dev);
1232 setexposure(gspca_dev);
1233 setfreq(gspca_dev);
1234
1235 sd->frames_to_drop = 0;
1236 sd->autogain_ignore_frames = 0;
1237 gspca_dev->exp_too_high_cnt = 0;
1238 gspca_dev->exp_too_low_cnt = 0;
1239 atomic_set(&sd->avg_lum, -1);
1240 return gspca_dev->usb_err;
1241}
1242
1243static void sd_stopN(struct gspca_dev *gspca_dev)
1244{
1245 sd_init(gspca_dev);
1246}
1247
1248static u8* find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
1249{
1250 struct sd *sd = (struct sd *) gspca_dev;
1251 int i, header_size = (sd->bridge == BRIDGE_103) ? 18 : 12;
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262 for (i = 0; i < len; i++) {
1263 switch (sd->header_read) {
1264 case 0:
1265 if (data[i] == 0xff)
1266 sd->header_read++;
1267 break;
1268 case 1:
1269 if (data[i] == 0xff)
1270 sd->header_read++;
1271 else
1272 sd->header_read = 0;
1273 break;
1274 case 2:
1275 if (data[i] == 0x00)
1276 sd->header_read++;
1277 else if (data[i] != 0xff)
1278 sd->header_read = 0;
1279 break;
1280 case 3:
1281 if (data[i] == 0xc4)
1282 sd->header_read++;
1283 else if (data[i] == 0xff)
1284 sd->header_read = 1;
1285 else
1286 sd->header_read = 0;
1287 break;
1288 case 4:
1289 if (data[i] == 0xc4)
1290 sd->header_read++;
1291 else if (data[i] == 0xff)
1292 sd->header_read = 1;
1293 else
1294 sd->header_read = 0;
1295 break;
1296 case 5:
1297 if (data[i] == 0x96)
1298 sd->header_read++;
1299 else if (data[i] == 0xff)
1300 sd->header_read = 1;
1301 else
1302 sd->header_read = 0;
1303 break;
1304 default:
1305 sd->header[sd->header_read - 6] = data[i];
1306 sd->header_read++;
1307 if (sd->header_read == header_size) {
1308 sd->header_read = 0;
1309 return data + i + 1;
1310 }
1311 }
1312 }
1313 return NULL;
1314}
1315
1316static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1317 u8 *data,
1318 int len)
1319{
1320 int fr_h_sz = 0, lum_offset = 0, len_after_sof = 0;
1321 struct sd *sd = (struct sd *) gspca_dev;
1322 struct cam *cam = &gspca_dev->cam;
1323 u8 *sof;
1324
1325 sof = find_sof(gspca_dev, data, len);
1326 if (sof) {
1327 if (sd->bridge == BRIDGE_103) {
1328 fr_h_sz = 18;
1329 lum_offset = 3;
1330 } else {
1331 fr_h_sz = 12;
1332 lum_offset = 2;
1333 }
1334
1335 len_after_sof = len - (sof - data);
1336 len = (sof - data) - fr_h_sz;
1337 if (len < 0)
1338 len = 0;
1339 }
1340
1341 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1342
1343
1344 int used;
1345 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1346
1347 used = gspca_dev->image_len;
1348 if (used + len > size)
1349 len = size - used;
1350 }
1351
1352 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1353
1354 if (sof) {
1355 int lum = sd->header[lum_offset] +
1356 (sd->header[lum_offset + 1] << 8);
1357
1358
1359
1360
1361
1362
1363
1364
1365 if (lum == 0 && sd->prev_avg_lum != 0) {
1366 lum = -1;
1367 sd->frames_to_drop = 2;
1368 sd->prev_avg_lum = 0;
1369 } else
1370 sd->prev_avg_lum = lum;
1371 atomic_set(&sd->avg_lum, lum);
1372
1373 if (sd->frames_to_drop)
1374 sd->frames_to_drop--;
1375 else
1376 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1377
1378 gspca_frame_add(gspca_dev, FIRST_PACKET, sof, len_after_sof);
1379 }
1380}
1381
1382#if IS_ENABLED(CONFIG_INPUT)
1383static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1384 u8 *data,
1385 int len)
1386{
1387 int ret = -EINVAL;
1388
1389 if (len == 1 && data[0] == 1) {
1390 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1391 input_sync(gspca_dev->input_dev);
1392 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1393 input_sync(gspca_dev->input_dev);
1394 ret = 0;
1395 }
1396
1397 return ret;
1398}
1399#endif
1400
1401
1402static const struct sd_desc sd_desc = {
1403 .name = MODULE_NAME,
1404 .config = sd_config,
1405 .init = sd_init,
1406 .init_controls = sd_init_controls,
1407 .start = sd_start,
1408 .stopN = sd_stopN,
1409 .pkt_scan = sd_pkt_scan,
1410 .dq_callback = do_autogain,
1411#if IS_ENABLED(CONFIG_INPUT)
1412 .int_pkt_scan = sd_int_pkt_scan,
1413#endif
1414};
1415
1416
1417#define SB(sensor, bridge) \
1418 .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1419
1420
1421static const struct usb_device_id device_table[] = {
1422 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)},
1423 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)},
1424 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)},
1425 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1426 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1427 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1428 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1429 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1430 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1431 {USB_DEVICE(0x0c45, 0x6027), SB(OV7630, 101)},
1432 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1433 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1434 {USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)},
1435
1436 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1437 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1438 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1439
1440
1441 {USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)},
1442 {USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)},
1443
1444 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1445 {USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)},
1446 {USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)},
1447 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1448 {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1449 {}
1450};
1451MODULE_DEVICE_TABLE(usb, device_table);
1452
1453
1454static int sd_probe(struct usb_interface *intf,
1455 const struct usb_device_id *id)
1456{
1457 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1458 THIS_MODULE);
1459}
1460
1461static struct usb_driver sd_driver = {
1462 .name = MODULE_NAME,
1463 .id_table = device_table,
1464 .probe = sd_probe,
1465 .disconnect = gspca_disconnect,
1466#ifdef CONFIG_PM
1467 .suspend = gspca_suspend,
1468 .resume = gspca_resume,
1469 .reset_resume = gspca_resume,
1470#endif
1471};
1472
1473module_usb_driver(sd_driver);
1474