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