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