diff options
author | Hans de Goede <j.w.r.degoede@hhs.nl> | 2008-09-03 16:12:21 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-09-03 17:37:46 -0400 |
commit | f45f06b648bad82430c64a2e1ad67dc616eb54c6 (patch) | |
tree | 7fdd6993668421269cd817c7e4f06a519259feae /drivers | |
parent | 20122542df420a31532c8e2b5d4107e9846bac6b (diff) |
V4L/DVB (8833): gspca: Cleanup the sonixb code.
-the usb-id table caried several flags which were not usb-id specific but
sensor specific, add a sensor_data array and move these flag there
-fr_h_sz was being abused to store and check which bridge was being used
instead add a bridge member to the sd struct
-now that we have a sensor_data table use that to store pointers to
init_sequences instead of using switch cases on sd->sensor
Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/gspca/sonixb.c | 365 |
1 files changed, 162 insertions, 203 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index f30e6ec91375..8eaeaa3a96d7 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -41,8 +41,12 @@ struct sd { | |||
41 | unsigned char frames_to_drop; | 41 | unsigned char frames_to_drop; |
42 | unsigned char freq; /* light freq filter setting */ | 42 | unsigned char freq; /* light freq filter setting */ |
43 | 43 | ||
44 | unsigned char fr_h_sz; /* size of frame header */ | 44 | __u8 bridge; /* Type of bridge */ |
45 | char sensor; /* Type of image sensor chip */ | 45 | #define BRIDGE_101 0 |
46 | #define BRIDGE_102 0 /* We make no difference between 101 and 102 */ | ||
47 | #define BRIDGE_103 1 | ||
48 | |||
49 | __u8 sensor; /* Type of image sensor chip */ | ||
46 | #define SENSOR_HV7131R 0 | 50 | #define SENSOR_HV7131R 0 |
47 | #define SENSOR_OV6650 1 | 51 | #define SENSOR_OV6650 1 |
48 | #define SENSOR_OV7630 2 | 52 | #define SENSOR_OV7630 2 |
@@ -50,15 +54,31 @@ struct sd { | |||
50 | #define SENSOR_PAS202 4 | 54 | #define SENSOR_PAS202 4 |
51 | #define SENSOR_TAS5110 5 | 55 | #define SENSOR_TAS5110 5 |
52 | #define SENSOR_TAS5130CXX 6 | 56 | #define SENSOR_TAS5130CXX 6 |
53 | char sensor_has_gain; | ||
54 | __u8 sensor_addr; | ||
55 | __u8 reg11; | 57 | __u8 reg11; |
56 | }; | 58 | }; |
57 | 59 | ||
58 | /* flags used in the device id table */ | 60 | typedef const __u8 sensor_init_t[8]; |
61 | |||
62 | struct sensor_data { | ||
63 | const __u8 *bridge_init[2]; | ||
64 | int bridge_init_size[2]; | ||
65 | sensor_init_t *sensor_init; | ||
66 | int sensor_init_size; | ||
67 | sensor_init_t *sensor_bridge_init[2]; | ||
68 | int sensor_bridge_init_size[2]; | ||
69 | int flags; | ||
70 | unsigned ctrl_dis; | ||
71 | __u8 sensor_addr; | ||
72 | }; | ||
73 | |||
74 | /* sensor_data flags */ | ||
59 | #define F_GAIN 0x01 /* has gain */ | 75 | #define F_GAIN 0x01 /* has gain */ |
60 | #define F_SIF 0x02 /* sif or vga */ | 76 | #define F_SIF 0x02 /* sif or vga */ |
61 | #define F_H18 0x04 /* long (18 b) or short (12 b) frame header */ | 77 | |
78 | /* ctrl_dis helper macros */ | ||
79 | #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) | ||
80 | #define NO_FREQ (1 << FREQ_IDX) | ||
81 | #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) | ||
62 | 82 | ||
63 | #define COMP2 0x8f | 83 | #define COMP2 0x8f |
64 | #define COMP 0xc7 /* 0x87 //0x07 */ | 84 | #define COMP 0xc7 /* 0x87 //0x07 */ |
@@ -69,6 +89,18 @@ struct sd { | |||
69 | 89 | ||
70 | #define SYS_CLK 0x04 | 90 | #define SYS_CLK 0x04 |
71 | 91 | ||
92 | #define SENS(bridge_1, bridge_3, sensor, sensor_1, \ | ||
93 | sensor_3, _flags, _ctrl_dis, _sensor_addr) \ | ||
94 | { \ | ||
95 | .bridge_init = { bridge_1, bridge_3 }, \ | ||
96 | .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \ | ||
97 | .sensor_init = sensor, \ | ||
98 | .sensor_init_size = sizeof(sensor), \ | ||
99 | .sensor_bridge_init = { sensor_1, sensor_3,}, \ | ||
100 | .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \ | ||
101 | .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \ | ||
102 | } | ||
103 | |||
72 | /* We calculate the autogain at the end of the transfer of a frame, at this | 104 | /* We calculate the autogain at the end of the transfer of a frame, at this |
73 | moment a frame with the old settings is being transmitted, and a frame is | 105 | moment a frame with the old settings is being transmitted, and a frame is |
74 | being captured with the old settings. So if we adjust the autogain we must | 106 | being captured with the old settings. So if we adjust the autogain we must |
@@ -219,7 +251,7 @@ static const __u8 hv7131_sensor_init[][8] = { | |||
219 | static const __u8 initOv6650[] = { | 251 | static const __u8 initOv6650[] = { |
220 | 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | 252 | 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, |
221 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 253 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
222 | 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b, | 254 | 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, |
223 | 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 | 255 | 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 |
224 | }; | 256 | }; |
225 | static const __u8 ov6650_sensor_init[][8] = | 257 | static const __u8 ov6650_sensor_init[][8] = |
@@ -260,7 +292,7 @@ static const __u8 initOv7630[] = { | |||
260 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ | 292 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ |
261 | 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ | 293 | 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ |
262 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ | 294 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ |
263 | 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ | 295 | 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */ |
264 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ | 296 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ |
265 | }; | 297 | }; |
266 | static const __u8 initOv7630_3[] = { | 298 | static const __u8 initOv7630_3[] = { |
@@ -295,47 +327,65 @@ static const __u8 ov7630_sensor_init[][8] = { | |||
295 | {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, | 327 | {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, |
296 | }; | 328 | }; |
297 | 329 | ||
330 | static const __u8 ov7630_sensor_init_3[][8] = { | ||
331 | {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
332 | }; | ||
333 | |||
298 | static const __u8 initPas106[] = { | 334 | static const __u8 initPas106[] = { |
299 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, | 335 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, |
300 | 0x00, 0x00, | 336 | 0x00, 0x00, |
301 | 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, | 337 | 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, |
302 | 0x16, 0x12, 0x28, COMP1, MCK_INIT1, | 338 | 0x16, 0x12, 0x24, COMP1, MCK_INIT1, |
303 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c | 339 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c |
304 | }; | 340 | }; |
305 | /* compression 0x86 mckinit1 0x2b */ | 341 | /* compression 0x86 mckinit1 0x2b */ |
306 | static const __u8 pas106_data[][2] = { | 342 | static const __u8 pas106_sensor_init[][8] = { |
307 | {0x02, 0x04}, /* Pixel Clock Divider 6 */ | 343 | /* Pixel Clock Divider 6 */ |
308 | {0x03, 0x13}, /* Frame Time MSB */ | 344 | { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 }, |
309 | /* {0x03, 0x12}, * Frame Time MSB */ | 345 | /* Frame Time MSB (also seen as 0x12) */ |
310 | {0x04, 0x06}, /* Frame Time LSB */ | 346 | { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 }, |
311 | /* {0x04, 0x05}, * Frame Time LSB */ | 347 | /* Frame Time LSB (also seen as 0x05) */ |
312 | {0x05, 0x65}, /* Shutter Time Line Offset */ | 348 | { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 }, |
313 | /* {0x05, 0x6d}, * Shutter Time Line Offset */ | 349 | /* Shutter Time Line Offset (also seen as 0x6d) */ |
314 | /* {0x06, 0xb1}, * Shutter Time Pixel Offset */ | 350 | { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 }, |
315 | {0x06, 0xcd}, /* Shutter Time Pixel Offset */ | 351 | /* Shutter Time Pixel Offset (also seen as 0xb1) */ |
316 | {0x07, 0xc1}, /* Black Level Subtract Sign */ | 352 | { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 }, |
317 | /* {0x07, 0x00}, * Black Level Subtract Sign */ | 353 | /* Black Level Subtract Sign (also seen 0x00) */ |
318 | {0x08, 0x06}, /* Black Level Subtract Level */ | 354 | { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 }, |
319 | {0x08, 0x06}, /* Black Level Subtract Level */ | 355 | /* Black Level Subtract Level (also seen 0x01) */ |
320 | /* {0x08, 0x01}, * Black Level Subtract Level */ | 356 | { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 }, |
321 | {0x09, 0x05}, /* Color Gain B Pixel 5 a */ | 357 | { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 }, |
322 | {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */ | 358 | /* Color Gain B Pixel 5 a */ |
323 | {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */ | 359 | { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 }, |
324 | {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */ | 360 | /* Color Gain G1 Pixel 1 5 */ |
325 | {0x0d, 0x00}, /* Color GainH Pixel */ | 361 | { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 }, |
326 | {0x0e, 0x0e}, /* Global Gain */ | 362 | /* Color Gain G2 Pixel 1 0 5 */ |
327 | {0x0f, 0x00}, /* Contrast */ | 363 | { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 }, |
328 | {0x10, 0x06}, /* H&V synchro polarity */ | 364 | /* Color Gain R Pixel 3 1 */ |
329 | {0x11, 0x06}, /* ?default */ | 365 | { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 }, |
330 | {0x12, 0x06}, /* DAC scale */ | 366 | /* Color GainH Pixel */ |
331 | {0x14, 0x02}, /* ?default */ | 367 | { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 }, |
332 | {0x13, 0x01}, /* Validate Settings */ | 368 | /* Global Gain */ |
369 | { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 }, | ||
370 | /* Contrast */ | ||
371 | { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 }, | ||
372 | /* H&V synchro polarity */ | ||
373 | { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 }, | ||
374 | /* ?default */ | ||
375 | { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 }, | ||
376 | /* DAC scale */ | ||
377 | { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 }, | ||
378 | /* ?default */ | ||
379 | { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 }, | ||
380 | /* Validate Settings */ | ||
381 | { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 }, | ||
333 | }; | 382 | }; |
383 | |||
334 | static const __u8 initPas202[] = { | 384 | static const __u8 initPas202[] = { |
335 | 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, | 385 | 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, |
336 | 0x00, 0x00, | 386 | 0x00, 0x00, |
337 | 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ | 387 | 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ |
338 | 0x28, 0x1e, 0x28, 0x89, 0x30, | 388 | 0x28, 0x1e, 0x28, 0x89, 0x20, |
339 | 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c | 389 | 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c |
340 | }; | 390 | }; |
341 | static const __u8 pas202_sensor_init[][8] = { | 391 | static const __u8 pas202_sensor_init[][8] = { |
@@ -390,6 +440,21 @@ static const __u8 tas5130_sensor_init[][8] = { | |||
390 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, | 440 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, |
391 | }; | 441 | }; |
392 | 442 | ||
443 | struct sensor_data sensor_data[] = { | ||
444 | SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), | ||
445 | SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), | ||
446 | SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, | ||
447 | F_GAIN, 0, 0x21), | ||
448 | SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, | ||
449 | 0), | ||
450 | SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, | ||
451 | NO_EXPO|NO_FREQ, 0), | ||
452 | SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, | ||
453 | NO_BRIGHTNESS|NO_FREQ, 0), | ||
454 | SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, | ||
455 | 0), | ||
456 | }; | ||
457 | |||
393 | /* get one byte in gspca_dev->usb_buf */ | 458 | /* get one byte in gspca_dev->usb_buf */ |
394 | static void reg_r(struct gspca_dev *gspca_dev, | 459 | static void reg_r(struct gspca_dev *gspca_dev, |
395 | __u16 value) | 460 | __u16 value) |
@@ -468,7 +533,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
468 | {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; | 533 | {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; |
469 | 534 | ||
470 | /* change reg 0x06 */ | 535 | /* change reg 0x06 */ |
471 | i2cOV[1] = sd->sensor_addr; | 536 | i2cOV[1] = sensor_data[sd->sensor].sensor_addr; |
472 | i2cOV[3] = sd->brightness; | 537 | i2cOV[3] = sd->brightness; |
473 | if (i2c_w(gspca_dev, i2cOV) < 0) | 538 | if (i2c_w(gspca_dev, i2cOV) < 0) |
474 | goto err; | 539 | goto err; |
@@ -555,7 +620,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev) | |||
555 | case SENSOR_OV7630: { | 620 | case SENSOR_OV7630: { |
556 | __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; | 621 | __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; |
557 | 622 | ||
558 | i2c[1] = sd->sensor_addr; | 623 | i2c[1] = sensor_data[sd->sensor].sensor_addr; |
559 | i2c[3] = gain >> 2; | 624 | i2c[3] = gain >> 2; |
560 | if (i2c_w(gspca_dev, i2c) < 0) | 625 | if (i2c_w(gspca_dev, i2c) < 0) |
561 | goto err; | 626 | goto err; |
@@ -582,7 +647,7 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
582 | rgb_value = gain; | 647 | rgb_value = gain; |
583 | reg_w(gspca_dev, 0x11, &rgb_value, 1); | 648 | reg_w(gspca_dev, 0x11, &rgb_value, 1); |
584 | 649 | ||
585 | if (sd->sensor_has_gain) | 650 | if (sensor_data[sd->sensor].flags & F_GAIN) |
586 | setsensorgain(gspca_dev); | 651 | setsensorgain(gspca_dev); |
587 | } | 652 | } |
588 | 653 | ||
@@ -662,7 +727,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
662 | reg10 = reg10_max; | 727 | reg10 = reg10_max; |
663 | 728 | ||
664 | /* Write reg 10 and reg11 low nibble */ | 729 | /* Write reg 10 and reg11 low nibble */ |
665 | i2c[1] = sd->sensor_addr; | 730 | i2c[1] = sensor_data[sd->sensor].sensor_addr; |
666 | i2c[3] = reg10; | 731 | i2c[3] = reg10; |
667 | i2c[4] |= reg11 - 1; | 732 | i2c[4] |= reg11 - 1; |
668 | 733 | ||
@@ -702,7 +767,7 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
702 | ? 0x4f : 0x8a; | 767 | ? 0x4f : 0x8a; |
703 | break; | 768 | break; |
704 | } | 769 | } |
705 | i2c[1] = sd->sensor_addr; | 770 | i2c[1] = sensor_data[sd->sensor].sensor_addr; |
706 | if (i2c_w(gspca_dev, i2c) < 0) | 771 | if (i2c_w(gspca_dev, i2c) < 0) |
707 | PDEBUG(D_ERR, "i2c error setfreq"); | 772 | PDEBUG(D_ERR, "i2c error setfreq"); |
708 | break; | 773 | break; |
@@ -735,28 +800,19 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
735 | { | 800 | { |
736 | struct sd *sd = (struct sd *) gspca_dev; | 801 | struct sd *sd = (struct sd *) gspca_dev; |
737 | struct cam *cam; | 802 | struct cam *cam; |
738 | int sif = 0; | ||
739 | 803 | ||
740 | reg_r(gspca_dev, 0x00); | 804 | reg_r(gspca_dev, 0x00); |
741 | if (gspca_dev->usb_buf[0] != 0x10) | 805 | if (gspca_dev->usb_buf[0] != 0x10) |
742 | return -ENODEV; | 806 | return -ENODEV; |
743 | 807 | ||
744 | /* copy the webcam info from the device id */ | 808 | /* copy the webcam info from the device id */ |
745 | sd->sensor = (id->driver_info >> 24) & 0xff; | 809 | sd->sensor = id->driver_info >> 8; |
746 | if (id->driver_info & (F_GAIN << 16)) | 810 | sd->bridge = id->driver_info & 0xff; |
747 | sd->sensor_has_gain = 1; | 811 | gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; |
748 | if (id->driver_info & (F_SIF << 16)) | ||
749 | sif = 1; | ||
750 | if (id->driver_info & (F_H18 << 16)) | ||
751 | sd->fr_h_sz = 18; /* size of frame header */ | ||
752 | else | ||
753 | sd->fr_h_sz = 12; | ||
754 | gspca_dev->ctrl_dis = (id->driver_info >> 8) & 0xff; | ||
755 | sd->sensor_addr = id->driver_info & 0xff; | ||
756 | 812 | ||
757 | cam = &gspca_dev->cam; | 813 | cam = &gspca_dev->cam; |
758 | cam->epaddr = 0x01; | 814 | cam->epaddr = 0x01; |
759 | if (!sif) { | 815 | if (!(sensor_data[sd->sensor].flags & F_SIF)) { |
760 | cam->cam_mode = vga_mode; | 816 | cam->cam_mode = vga_mode; |
761 | cam->nmodes = ARRAY_SIZE(vga_mode); | 817 | cam->nmodes = ARRAY_SIZE(vga_mode); |
762 | } else { | 818 | } else { |
@@ -785,78 +841,29 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
785 | return 0; | 841 | return 0; |
786 | } | 842 | } |
787 | 843 | ||
788 | static void pas106_i2cinit(struct gspca_dev *gspca_dev) | ||
789 | { | ||
790 | int i; | ||
791 | const __u8 *data; | ||
792 | __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 }; | ||
793 | |||
794 | i = ARRAY_SIZE(pas106_data); | ||
795 | data = pas106_data[0]; | ||
796 | while (--i >= 0) { | ||
797 | memcpy(&i2c1[2], data, 2); | ||
798 | /* copy 2 bytes from the template */ | ||
799 | if (i2c_w(gspca_dev, i2c1) < 0) | ||
800 | PDEBUG(D_ERR, "i2c error pas106"); | ||
801 | data += 2; | ||
802 | } | ||
803 | } | ||
804 | |||
805 | /* -- start the camera -- */ | 844 | /* -- start the camera -- */ |
806 | static void sd_start(struct gspca_dev *gspca_dev) | 845 | static void sd_start(struct gspca_dev *gspca_dev) |
807 | { | 846 | { |
808 | struct sd *sd = (struct sd *) gspca_dev; | 847 | struct sd *sd = (struct sd *) gspca_dev; |
809 | int mode, l = 0x1f; | 848 | int mode, l; |
810 | const __u8 *sn9c10x; | 849 | const __u8 *sn9c10x; |
811 | __u8 reg17_19[3]; | 850 | __u8 reg17_19[3]; |
812 | 851 | ||
813 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 852 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 0x07; |
853 | sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge]; | ||
854 | l = sensor_data[sd->sensor].bridge_init_size[sd->bridge]; | ||
855 | reg17_19[0] = sn9c10x[0x17 - 1]; | ||
856 | reg17_19[1] = sn9c10x[0x18 - 1] | (mode << 4); | ||
857 | reg17_19[2] = sn9c10x[0x19 - 1]; | ||
858 | /* Special cases where reg 17 and or 19 value depends on mode */ | ||
814 | switch (sd->sensor) { | 859 | switch (sd->sensor) { |
815 | case SENSOR_HV7131R: | ||
816 | sn9c10x = initHv7131; | ||
817 | reg17_19[0] = 0x60; | ||
818 | reg17_19[1] = (mode << 4) | 0x8a; | ||
819 | reg17_19[2] = 0x20; | ||
820 | break; | ||
821 | case SENSOR_OV6650: | ||
822 | sn9c10x = initOv6650; | ||
823 | reg17_19[0] = 0x68; | ||
824 | reg17_19[1] = (mode << 4) | 0x8b; | ||
825 | reg17_19[2] = 0x20; | ||
826 | break; | ||
827 | case SENSOR_OV7630: | ||
828 | if (sd->fr_h_sz == 18) { /* SN9C103 */ | ||
829 | sn9c10x = initOv7630_3; | ||
830 | l = sizeof initOv7630_3; | ||
831 | } else | ||
832 | sn9c10x = initOv7630; | ||
833 | reg17_19[0] = 0x68; | ||
834 | reg17_19[1] = (mode << 4) | COMP2; | ||
835 | reg17_19[2] = MCK_INIT1; | ||
836 | break; | ||
837 | case SENSOR_PAS106: | ||
838 | sn9c10x = initPas106; | ||
839 | reg17_19[0] = 0x24; /* 0x28 */ | ||
840 | reg17_19[1] = (mode << 4) | COMP1; | ||
841 | reg17_19[2] = MCK_INIT1; | ||
842 | break; | ||
843 | case SENSOR_PAS202: | 860 | case SENSOR_PAS202: |
844 | sn9c10x = initPas202; | ||
845 | reg17_19[0] = mode ? 0x24 : 0x20; | 861 | reg17_19[0] = mode ? 0x24 : 0x20; |
846 | reg17_19[1] = (mode << 4) | 0x89; | ||
847 | reg17_19[2] = 0x20; | ||
848 | break; | 862 | break; |
849 | case SENSOR_TAS5110: | 863 | case SENSOR_TAS5130CXX: |
850 | sn9c10x = initTas5110; | 864 | /* probably not mode specific at all most likely the upper |
851 | reg17_19[0] = 0x60; | 865 | nibble of 0x19 is exposure (clock divider) just as with |
852 | reg17_19[1] = (mode << 4) | 0x86; | 866 | the tas5110, we need someone to test this. */ |
853 | reg17_19[2] = 0x2b; /* 0xf3; */ | ||
854 | break; | ||
855 | default: | ||
856 | /* case SENSOR_TAS5130CXX: */ | ||
857 | sn9c10x = initTas5130; | ||
858 | reg17_19[0] = 0x60; | ||
859 | reg17_19[1] = (mode << 4) | COMP; | ||
860 | reg17_19[2] = mode ? 0x23 : 0x43; | 867 | reg17_19[2] = mode ? 0x23 : 0x43; |
861 | break; | 868 | break; |
862 | } | 869 | } |
@@ -867,41 +874,16 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
867 | reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); | 874 | reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); |
868 | /* Set the registers from the template */ | 875 | /* Set the registers from the template */ |
869 | reg_w(gspca_dev, 0x01, sn9c10x, l); | 876 | reg_w(gspca_dev, 0x01, sn9c10x, l); |
870 | switch (sd->sensor) { | 877 | |
871 | case SENSOR_HV7131R: | 878 | /* Init the sensor */ |
872 | i2c_w_vector(gspca_dev, hv7131_sensor_init, | 879 | i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init, |
873 | sizeof hv7131_sensor_init); | 880 | sensor_data[sd->sensor].sensor_init_size); |
874 | break; | 881 | if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge]) |
875 | case SENSOR_OV6650: | 882 | i2c_w_vector(gspca_dev, |
876 | i2c_w_vector(gspca_dev, ov6650_sensor_init, | 883 | sensor_data[sd->sensor].sensor_bridge_init[sd->bridge], |
877 | sizeof ov6650_sensor_init); | 884 | sensor_data[sd->sensor].sensor_bridge_init_size[ |
878 | break; | 885 | sd->bridge]); |
879 | case SENSOR_OV7630: | 886 | |
880 | i2c_w_vector(gspca_dev, ov7630_sensor_init, | ||
881 | sizeof ov7630_sensor_init); | ||
882 | if (sd->fr_h_sz == 18) { /* SN9C103 */ | ||
883 | const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00, | ||
884 | 0x00, 0x00, 0x10 }; | ||
885 | i2c_w(gspca_dev, i2c); | ||
886 | } | ||
887 | break; | ||
888 | case SENSOR_PAS106: | ||
889 | pas106_i2cinit(gspca_dev); | ||
890 | break; | ||
891 | case SENSOR_PAS202: | ||
892 | i2c_w_vector(gspca_dev, pas202_sensor_init, | ||
893 | sizeof pas202_sensor_init); | ||
894 | break; | ||
895 | case SENSOR_TAS5110: | ||
896 | i2c_w_vector(gspca_dev, tas5110_sensor_init, | ||
897 | sizeof tas5110_sensor_init); | ||
898 | break; | ||
899 | default: | ||
900 | /* case SENSOR_TAS5130CXX: */ | ||
901 | i2c_w_vector(gspca_dev, tas5130_sensor_init, | ||
902 | sizeof tas5130_sensor_init); | ||
903 | break; | ||
904 | } | ||
905 | /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ | 887 | /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ |
906 | reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); | 888 | reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); |
907 | /* compression register */ | 889 | /* compression register */ |
@@ -937,10 +919,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
937 | 919 | ||
938 | static void sd_stopN(struct gspca_dev *gspca_dev) | 920 | static void sd_stopN(struct gspca_dev *gspca_dev) |
939 | { | 921 | { |
940 | __u8 ByteSend; | 922 | sd_init(gspca_dev); |
941 | |||
942 | ByteSend = 0x09; /* 0X00 */ | ||
943 | reg_w(gspca_dev, 0x01, &ByteSend, 1); | ||
944 | } | 923 | } |
945 | 924 | ||
946 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 925 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
@@ -970,15 +949,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
970 | && data[5 + i] == 0x96) { /* start of frame */ | 949 | && data[5 + i] == 0x96) { /* start of frame */ |
971 | int lum = -1; | 950 | int lum = -1; |
972 | int pkt_type = LAST_PACKET; | 951 | int pkt_type = LAST_PACKET; |
952 | int fr_h_sz = (sd->bridge == BRIDGE_103) ? | ||
953 | 18 : 12; | ||
973 | 954 | ||
974 | if (len - i < sd->fr_h_sz) { | 955 | if (len - i < fr_h_sz) { |
975 | PDEBUG(D_STREAM, "packet too short to" | 956 | PDEBUG(D_STREAM, "packet too short to" |
976 | " get avg brightness"); | 957 | " get avg brightness"); |
977 | } else if (sd->fr_h_sz == 12) { | 958 | } else if (sd->bridge == BRIDGE_103) { |
978 | lum = data[i + 8] + (data[i + 9] << 8); | ||
979 | } else { | ||
980 | lum = data[i + 9] + | 959 | lum = data[i + 9] + |
981 | (data[i + 10] << 8); | 960 | (data[i + 10] << 8); |
961 | } else { | ||
962 | lum = data[i + 8] + (data[i + 9] << 8); | ||
982 | } | 963 | } |
983 | if (lum == 0) { | 964 | if (lum == 0) { |
984 | lum = -1; | 965 | lum = -1; |
@@ -993,8 +974,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
993 | 974 | ||
994 | frame = gspca_frame_add(gspca_dev, pkt_type, | 975 | frame = gspca_frame_add(gspca_dev, pkt_type, |
995 | frame, data, 0); | 976 | frame, data, 0); |
996 | data += i + sd->fr_h_sz; | 977 | data += i + fr_h_sz; |
997 | len -= i + sd->fr_h_sz; | 978 | len -= i + fr_h_sz; |
998 | gspca_frame_add(gspca_dev, FIRST_PACKET, | 979 | gspca_frame_add(gspca_dev, FIRST_PACKET, |
999 | frame, data, len); | 980 | frame, data, len); |
1000 | return; | 981 | return; |
@@ -1143,55 +1124,33 @@ static const struct sd_desc sd_desc = { | |||
1143 | }; | 1124 | }; |
1144 | 1125 | ||
1145 | /* -- module initialisation -- */ | 1126 | /* -- module initialisation -- */ |
1146 | #define SFCI(sensor, flags, disable_ctrls, i2c_addr) \ | 1127 | #define SB(sensor, bridge) \ |
1147 | .driver_info = (SENSOR_ ## sensor << 24) \ | 1128 | .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge |
1148 | | ((flags) << 16) \ | 1129 | |
1149 | | ((disable_ctrls) << 8) \ | ||
1150 | | (i2c_addr) | ||
1151 | #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) | ||
1152 | #define NO_FREQ (1 << FREQ_IDX) | ||
1153 | #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) | ||
1154 | 1130 | ||
1155 | static __devinitdata struct usb_device_id device_table[] = { | 1131 | static __devinitdata struct usb_device_id device_table[] = { |
1156 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 1132 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
1157 | {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */ | 1133 | {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, |
1158 | SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, | 1134 | {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, |
1159 | {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */ | 1135 | {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, |
1160 | SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, | 1136 | {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, |
1161 | {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */ | 1137 | {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, |
1162 | SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, | ||
1163 | {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */ | ||
1164 | SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, | ||
1165 | {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */ | ||
1166 | SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, | ||
1167 | #endif | 1138 | #endif |
1168 | {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */ | 1139 | {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, |
1169 | SFCI(OV6650, F_GAIN|F_SIF, 0, 0x60)}, | ||
1170 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 1140 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
1171 | {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ | 1141 | {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, |
1172 | SFCI(OV7630, F_GAIN, 0, 0x21)}, | 1142 | {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, |
1173 | {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ | 1143 | {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, |
1174 | SFCI(TAS5130CXX, 0, NO_EXPO|NO_FREQ, 0)}, | 1144 | {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, |
1175 | {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */ | 1145 | {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, |
1176 | SFCI(TAS5130CXX, 0, NO_EXPO|NO_FREQ, 0)}, | 1146 | {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, |
1177 | {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */ | ||
1178 | SFCI(PAS202, 0, NO_EXPO|NO_FREQ, 0)}, | ||
1179 | {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */ | ||
1180 | SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, | ||
1181 | {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */ | ||
1182 | SFCI(OV7630, F_GAIN, 0, 0x21)}, | ||
1183 | #endif | 1147 | #endif |
1184 | {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */ | 1148 | {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, |
1185 | SFCI(HV7131R, 0, NO_EXPO|NO_FREQ, 0)}, | ||
1186 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 1149 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
1187 | {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */ | 1150 | {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, |
1188 | SFCI(OV7630, F_GAIN, 0, 0x21)}, | 1151 | {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, |
1189 | {USB_DEVICE(0x0c45, 0x608f), /* SN9C103 */ | 1152 | {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, |
1190 | SFCI(OV7630, F_GAIN|F_H18, 0, 0x21)}, | 1153 | {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, |
1191 | {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */ | ||
1192 | SFCI(PAS202, F_H18, NO_EXPO|NO_FREQ, 0)}, | ||
1193 | {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */ | ||
1194 | SFCI(OV7630, F_GAIN|F_H18, 0, 0x21)}, | ||
1195 | #endif | 1154 | #endif |
1196 | {} | 1155 | {} |
1197 | }; | 1156 | }; |