aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2011-01-05 11:55:43 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-01-19 08:45:03 -0500
commit0a76cb8cefbaf84465e0cd9a6a1da7f54981c8ef (patch)
tree82cdfba640c14626d4c2094cedcd62d4c124268c /drivers/media
parenta24f0c5c47946b1a1999f44808e2219e7758d146 (diff)
[media] gspca_sonixb: Refactor to unify bridge handling
Refactor the code to unify how the sn9c101/102 and the sn9c103 bridge are handled. Also move code which is the same for all sensors from the per sensor init register settings to a central place. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/gspca/sonixb.c206
1 files changed, 116 insertions, 90 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 73504a3f87b7..43784027568f 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -23,8 +23,15 @@
23/* Some documentation on known sonixb registers: 23/* Some documentation on known sonixb registers:
24 24
25Reg Use 25Reg Use
26sn9c101 / sn9c102:
260x10 high nibble red gain low nibble blue gain 270x10 high nibble red gain low nibble blue gain
270x11 low nibble green gain 280x11 low nibble green gain
29sn9c103:
300x05 red gain 0-127
310x06 blue gain 0-127
320x07 green gain 0-127
33all:
340x08-0x0f i2c / 3wire registers
280x12 hstart 350x12 hstart
290x13 vstart 360x13 vstart
300x15 hsize (hsize = register-value * 16) 370x15 hsize (hsize = register-value * 16)
@@ -88,12 +95,9 @@ struct sd {
88typedef const __u8 sensor_init_t[8]; 95typedef const __u8 sensor_init_t[8];
89 96
90struct sensor_data { 97struct sensor_data {
91 const __u8 *bridge_init[2]; 98 const __u8 *bridge_init;
92 int bridge_init_size[2];
93 sensor_init_t *sensor_init; 99 sensor_init_t *sensor_init;
94 int sensor_init_size; 100 int sensor_init_size;
95 sensor_init_t *sensor_bridge_init[2];
96 int sensor_bridge_init_size[2];
97 int flags; 101 int flags;
98 unsigned ctrl_dis; 102 unsigned ctrl_dis;
99 __u8 sensor_addr; 103 __u8 sensor_addr;
@@ -114,7 +118,6 @@ struct sensor_data {
114#define NO_FREQ (1 << FREQ_IDX) 118#define NO_FREQ (1 << FREQ_IDX)
115#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) 119#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
116 120
117#define COMP2 0x8f
118#define COMP 0xc7 /* 0x87 //0x07 */ 121#define COMP 0xc7 /* 0x87 //0x07 */
119#define COMP1 0xc9 /* 0x89 //0x09 */ 122#define COMP1 0xc9 /* 0x89 //0x09 */
120 123
@@ -123,15 +126,11 @@ struct sensor_data {
123 126
124#define SYS_CLK 0x04 127#define SYS_CLK 0x04
125 128
126#define SENS(bridge_1, bridge_3, sensor, sensor_1, \ 129#define SENS(bridge, sensor, _flags, _ctrl_dis, _sensor_addr) \
127 sensor_3, _flags, _ctrl_dis, _sensor_addr) \
128{ \ 130{ \
129 .bridge_init = { bridge_1, bridge_3 }, \ 131 .bridge_init = bridge, \
130 .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
131 .sensor_init = sensor, \ 132 .sensor_init = sensor, \
132 .sensor_init_size = sizeof(sensor), \ 133 .sensor_init_size = sizeof(sensor), \
133 .sensor_bridge_init = { sensor_1, sensor_3,}, \
134 .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
135 .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \ 134 .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
136} 135}
137 136
@@ -311,7 +310,6 @@ static const __u8 initHv7131d[] = {
311 0x00, 0x00, 310 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 311 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
313 0x28, 0x1e, 0x60, 0x8e, 0x42, 312 0x28, 0x1e, 0x60, 0x8e, 0x42,
314 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
315}; 313};
316static const __u8 hv7131d_sensor_init[][8] = { 314static const __u8 hv7131d_sensor_init[][8] = {
317 {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17}, 315 {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
@@ -326,7 +324,6 @@ static const __u8 initHv7131r[] = {
326 0x00, 0x00, 324 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 325 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
328 0x28, 0x1e, 0x60, 0x8a, 0x20, 326 0x28, 0x1e, 0x60, 0x8a, 0x20,
329 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
330}; 327};
331static const __u8 hv7131r_sensor_init[][8] = { 328static const __u8 hv7131r_sensor_init[][8] = {
332 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, 329 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
@@ -339,7 +336,7 @@ static const __u8 initOv6650[] = {
339 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 336 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
340 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 337 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, 338 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
342 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07 339 0x10,
343}; 340};
344static const __u8 ov6650_sensor_init[][8] = { 341static const __u8 ov6650_sensor_init[][8] = {
345 /* Bright, contrast, etc are set through SCBB interface. 342 /* Bright, contrast, etc are set through SCBB interface.
@@ -378,18 +375,7 @@ static const __u8 initOv7630[] = {
378 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ 375 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
379 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ 376 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
380 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 377 0x28, 0x1e, /* H & V sizes r15 .. r16 */
381 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */
382 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
383};
384static const __u8 initOv7630_3[] = {
385 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
386 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
387 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
388 0x28, 0x1e, /* H & V sizes r15 .. r16 */
389 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ 378 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
390 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
391 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
392 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
393}; 379};
394static const __u8 ov7630_sensor_init[][8] = { 380static const __u8 ov7630_sensor_init[][8] = {
395 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, 381 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
@@ -413,16 +399,11 @@ static const __u8 ov7630_sensor_init[][8] = {
413 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, 399 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
414}; 400};
415 401
416static const __u8 ov7630_sensor_init_3[][8] = {
417 {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
418};
419
420static const __u8 initPas106[] = { 402static const __u8 initPas106[] = {
421 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, 403 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
422 0x00, 0x00, 404 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 405 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
424 0x16, 0x12, 0x24, COMP1, MCK_INIT1, 406 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
425 0x18, 0x10, 0x02, 0x02, 0x09, 0x07
426}; 407};
427/* compression 0x86 mckinit1 0x2b */ 408/* compression 0x86 mckinit1 0x2b */
428 409
@@ -496,7 +477,6 @@ static const __u8 initPas202[] = {
496 0x00, 0x00, 477 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, 478 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
498 0x28, 0x1e, 0x20, 0x89, 0x20, 479 0x28, 0x1e, 0x20, 0x89, 0x20,
499 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
500}; 480};
501 481
502/* "Known" PAS202BCB registers: 482/* "Known" PAS202BCB registers:
@@ -537,7 +517,6 @@ static const __u8 initTas5110c[] = {
537 0x00, 0x00, 517 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a, 518 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
539 0x16, 0x12, 0x60, 0x86, 0x2b, 519 0x16, 0x12, 0x60, 0x86, 0x2b,
540 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
541}; 520};
542/* Same as above, except a different hstart */ 521/* Same as above, except a different hstart */
543static const __u8 initTas5110d[] = { 522static const __u8 initTas5110d[] = {
@@ -545,7 +524,6 @@ static const __u8 initTas5110d[] = {
545 0x00, 0x00, 524 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a, 525 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
547 0x16, 0x12, 0x60, 0x86, 0x2b, 526 0x16, 0x12, 0x60, 0x86, 0x2b,
548 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
549}; 527};
550static const __u8 tas5110_sensor_init[][8] = { 528static const __u8 tas5110_sensor_init[][8] = {
551 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10}, 529 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
@@ -558,7 +536,6 @@ static const __u8 initTas5130[] = {
558 0x00, 0x00, 536 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a, 537 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
560 0x28, 0x1e, 0x60, COMP, MCK_INIT, 538 0x28, 0x1e, 0x60, COMP, MCK_INIT,
561 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
562}; 539};
563static const __u8 tas5130_sensor_init[][8] = { 540static const __u8 tas5130_sensor_init[][8] = {
564/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, 541/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
@@ -569,21 +546,17 @@ static const __u8 tas5130_sensor_init[][8] = {
569}; 546};
570 547
571static struct sensor_data sensor_data[] = { 548static struct sensor_data sensor_data[] = {
572SENS(initHv7131d, NULL, hv7131d_sensor_init, NULL, NULL, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), 549SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
573SENS(initHv7131r, NULL, hv7131r_sensor_init, NULL, NULL, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), 550SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
574SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), 551SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60),
575SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, 552SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21),
576 F_GAIN, 0, 0x21), 553SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0),
577SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ, 554SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0),
578 0), 555SENS(initTas5110c, tas5110_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
579SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN, 556 NO_BRIGHTNESS|NO_FREQ, 0),
580 NO_FREQ, 0), 557SENS(initTas5110d, tas5110_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
581SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL, 558 NO_BRIGHTNESS|NO_FREQ, 0),
582 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0), 559SENS(initTas5130, tas5130_sensor_init, 0, NO_EXPO|NO_FREQ, 0),
583SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL,
584 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
585SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
586 0),
587}; 560};
588 561
589/* get one byte in gspca_dev->usb_buf */ 562/* get one byte in gspca_dev->usb_buf */
@@ -796,7 +769,7 @@ static void setgain(struct gspca_dev *gspca_dev)
796{ 769{
797 struct sd *sd = (struct sd *) gspca_dev; 770 struct sd *sd = (struct sd *) gspca_dev;
798 __u8 gain; 771 __u8 gain;
799 __u8 buf[2] = { 0, 0 }; 772 __u8 buf[3] = { 0, 0, 0 };
800 773
801 if (sensor_data[sd->sensor].flags & F_GAIN) { 774 if (sensor_data[sd->sensor].flags & F_GAIN) {
802 /* Use the sensor gain to do the actual gain */ 775 /* Use the sensor gain to do the actual gain */
@@ -804,13 +777,18 @@ static void setgain(struct gspca_dev *gspca_dev)
804 return; 777 return;
805 } 778 }
806 779
807 gain = sd->gain >> 4; 780 if (sd->bridge == BRIDGE_103) {
808 781 gain = sd->gain >> 1;
809 /* red and blue gain */ 782 buf[0] = gain; /* Red */
810 buf[0] = gain << 4 | gain; 783 buf[1] = gain; /* Green */
811 /* green gain */ 784 buf[2] = gain; /* Blue */
812 buf[1] = gain; 785 reg_w(gspca_dev, 0x05, buf, 3);
813 reg_w(gspca_dev, 0x10, buf, 2); 786 } else {
787 gain = sd->gain >> 4;
788 buf[0] = gain << 4 | gain; /* Red and blue */
789 buf[1] = gain; /* Green */
790 reg_w(gspca_dev, 0x10, buf, 2);
791 }
814} 792}
815 793
816static void setexposure(struct gspca_dev *gspca_dev) 794static void setexposure(struct gspca_dev *gspca_dev)
@@ -1127,53 +1105,91 @@ static int sd_start(struct gspca_dev *gspca_dev)
1127{ 1105{
1128 struct sd *sd = (struct sd *) gspca_dev; 1106 struct sd *sd = (struct sd *) gspca_dev;
1129 struct cam *cam = &gspca_dev->cam; 1107 struct cam *cam = &gspca_dev->cam;
1130 int mode, l; 1108 int i, mode;
1131 const __u8 *sn9c10x; 1109 __u8 regs[0x31];
1132 __u8 reg12_19[8];
1133 1110
1134 mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07; 1111 mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
1135 sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge]; 1112 /* Copy registers 0x01 - 0x19 from the template */
1136 l = sensor_data[sd->sensor].bridge_init_size[sd->bridge]; 1113 memcpy(&regs[0x01], sensor_data[sd->sensor].bridge_init, 0x19);
1137 memcpy(reg12_19, &sn9c10x[0x12 - 1], 8); 1114 /* Set the mode */
1138 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4); 1115 regs[0x18] |= mode << 4;
1139 /* Special cases where reg 17 and or 19 value depends on mode */ 1116
1117 /* Set bridge gain to 1.0 */
1118 if (sd->bridge == BRIDGE_103) {
1119 regs[0x05] = 0x20; /* Red */
1120 regs[0x06] = 0x20; /* Green */
1121 regs[0x07] = 0x20; /* Blue */
1122 } else {
1123 regs[0x10] = 0x00; /* Red and blue */
1124 regs[0x11] = 0x00; /* Green */
1125 }
1126
1127 /* Setup pixel numbers and auto exposure window */
1128 if (sensor_data[sd->sensor].flags & F_SIF) {
1129 regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */
1130 regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */
1131 regs[0x1c] = 0x02; /* AE H-start 64 */
1132 regs[0x1d] = 0x02; /* AE V-start 64 */
1133 regs[0x1e] = 0x09; /* AE H-end 288 */
1134 regs[0x1f] = 0x07; /* AE V-end 224 */
1135 } else {
1136 regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */
1137 regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */
1138 regs[0x1c] = 0x02; /* AE H-start 64 */
1139 regs[0x1d] = 0x03; /* AE V-start 96 */
1140 regs[0x1e] = 0x0f; /* AE H-end 480 */
1141 regs[0x1f] = 0x0c; /* AE V-end 384 */
1142 }
1143
1144 /* Setup the gamma table (only used with the sn9c103 bridge) */
1145 for (i = 0; i < 16; i++)
1146 regs[0x20 + i] = i * 16;
1147 regs[0x20 + i] = 255;
1148
1149 /* Special cases where some regs depend on mode or bridge */
1140 switch (sd->sensor) { 1150 switch (sd->sensor) {
1141 case SENSOR_TAS5130CXX: 1151 case SENSOR_TAS5130CXX:
1142 /* probably not mode specific at all most likely the upper 1152 /* FIXME / TESTME
1153 probably not mode specific at all most likely the upper
1143 nibble of 0x19 is exposure (clock divider) just as with 1154 nibble of 0x19 is exposure (clock divider) just as with
1144 the tas5110, we need someone to test this. */ 1155 the tas5110, we need someone to test this. */
1145 reg12_19[7] = mode ? 0x23 : 0x43; 1156 regs[0x19] = mode ? 0x23 : 0x43;
1146 break; 1157 break;
1158 case SENSOR_OV7630:
1159 /* FIXME / TESTME for some reason with the 101/102 bridge the
1160 clock is set to 12 Mhz (reg1 == 0x04), rather then 24.
1161 Also the hstart needs to go from 1 to 2 when using a 103,
1162 which is likely related. This does not seem right. */
1163 if (sd->bridge == BRIDGE_103) {
1164 regs[0x01] = 0x44; /* Select 24 Mhz clock */
1165 regs[0x12] = 0x02; /* Set hstart to 2 */
1166 }
1147 } 1167 }
1148 /* Disable compression when the raw bayer format has been selected */ 1168 /* Disable compression when the raw bayer format has been selected */
1149 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) 1169 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
1150 reg12_19[6] &= ~0x80; 1170 regs[0x18] &= ~0x80;
1151 1171
1152 /* Vga mode emulation on SIF sensor? */ 1172 /* Vga mode emulation on SIF sensor? */
1153 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) { 1173 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
1154 reg12_19[0] += 16; /* 0x12: hstart adjust */ 1174 regs[0x12] += 16; /* hstart adjust */
1155 reg12_19[1] += 24; /* 0x13: vstart adjust */ 1175 regs[0x13] += 24; /* vstart adjust */
1156 reg12_19[3] = 320 / 16; /* 0x15: hsize */ 1176 regs[0x15] = 320 / 16; /* hsize */
1157 reg12_19[4] = 240 / 16; /* 0x16: vsize */ 1177 regs[0x16] = 240 / 16; /* vsize */
1158 } 1178 }
1159 1179
1160 /* reg 0x01 bit 2 video transfert on */ 1180 /* reg 0x01 bit 2 video transfert on */
1161 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); 1181 reg_w(gspca_dev, 0x01, &regs[0x01], 1);
1162 /* reg 0x17 SensorClk enable inv Clk 0x60 */ 1182 /* reg 0x17 SensorClk enable inv Clk 0x60 */
1163 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); 1183 reg_w(gspca_dev, 0x17, &regs[0x17], 1);
1164 /* Set the registers from the template */ 1184 /* Set the registers from the template */
1165 reg_w(gspca_dev, 0x01, sn9c10x, l); 1185 reg_w(gspca_dev, 0x01, &regs[0x01],
1186 (sd->bridge == BRIDGE_103) ? 0x30 : 0x1f);
1166 1187
1167 /* Init the sensor */ 1188 /* Init the sensor */
1168 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init, 1189 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
1169 sensor_data[sd->sensor].sensor_init_size); 1190 sensor_data[sd->sensor].sensor_init_size);
1170 if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
1171 i2c_w_vector(gspca_dev,
1172 sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
1173 sensor_data[sd->sensor].sensor_bridge_init_size[
1174 sd->bridge]);
1175 1191
1176 /* Mode specific sensor setup */ 1192 /* Mode / bridge specific sensor setup */
1177 switch (sd->sensor) { 1193 switch (sd->sensor) {
1178 case SENSOR_PAS202: { 1194 case SENSOR_PAS202: {
1179 const __u8 i2cpclockdiv[] = 1195 const __u8 i2cpclockdiv[] =
@@ -1181,27 +1197,37 @@ static int sd_start(struct gspca_dev *gspca_dev)
1181 /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */ 1197 /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
1182 if (mode) 1198 if (mode)
1183 i2c_w(gspca_dev, i2cpclockdiv); 1199 i2c_w(gspca_dev, i2cpclockdiv);
1200 break;
1184 } 1201 }
1202 case SENSOR_OV7630:
1203 /* FIXME / TESTME We should be able to handle this identical
1204 for the 101/102 and the 103 case */
1205 if (sd->bridge == BRIDGE_103) {
1206 const __u8 i2c[] = { 0xa0, 0x21, 0x13,
1207 0x80, 0x00, 0x00, 0x00, 0x10 };
1208 i2c_w(gspca_dev, i2c);
1209 }
1210 break;
1185 } 1211 }
1186 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ 1212 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
1187 reg_w(gspca_dev, 0x15, &reg12_19[3], 2); 1213 reg_w(gspca_dev, 0x15, &regs[0x15], 2);
1188 /* compression register */ 1214 /* compression register */
1189 reg_w(gspca_dev, 0x18, &reg12_19[6], 1); 1215 reg_w(gspca_dev, 0x18, &regs[0x18], 1);
1190 /* H_start */ 1216 /* H_start */
1191 reg_w(gspca_dev, 0x12, &reg12_19[0], 1); 1217 reg_w(gspca_dev, 0x12, &regs[0x12], 1);
1192 /* V_START */ 1218 /* V_START */
1193 reg_w(gspca_dev, 0x13, &reg12_19[1], 1); 1219 reg_w(gspca_dev, 0x13, &regs[0x13], 1);
1194 /* reset 0x17 SensorClk enable inv Clk 0x60 */ 1220 /* reset 0x17 SensorClk enable inv Clk 0x60 */
1195 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ 1221 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
1196 reg_w(gspca_dev, 0x17, &reg12_19[5], 1); 1222 reg_w(gspca_dev, 0x17, &regs[0x17], 1);
1197 /*MCKSIZE ->3 */ /*fixme: not ov7630*/ 1223 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
1198 reg_w(gspca_dev, 0x19, &reg12_19[7], 1); 1224 reg_w(gspca_dev, 0x19, &regs[0x19], 1);
1199 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ 1225 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
1200 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); 1226 reg_w(gspca_dev, 0x1c, &regs[0x1c], 4);
1201 /* Enable video transfert */ 1227 /* Enable video transfert */
1202 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); 1228 reg_w(gspca_dev, 0x01, &regs[0x01], 1);
1203 /* Compression */ 1229 /* Compression */
1204 reg_w(gspca_dev, 0x18, &reg12_19[6], 2); 1230 reg_w(gspca_dev, 0x18, &regs[0x18], 2);
1205 msleep(20); 1231 msleep(20);
1206 1232
1207 sd->reg11 = -1; 1233 sd->reg11 = -1;