diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-09-03 15:47:23 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-09-03 17:36:28 -0400 |
commit | d2d16e9084ee44088974c3312b803d54dd9b46d7 (patch) | |
tree | aef9da5c8de12332ca2994f8e5210c2fa4d35394 /drivers | |
parent | 23d9e4776b426d1f8a602e0e8d868154847f0dd4 (diff) |
V4L/DVB (8663): gspca: Webcam 0c45:6128 added in sonixj.
Patch adapted from a patch to gspcav1 made by the google microdia group.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/gspca/sonixj.c | 128 |
1 files changed, 111 insertions, 17 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 245a30ec5fb1..151e1b625b0d 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -54,8 +54,9 @@ struct sd { | |||
54 | #define SENSOR_HV7131R 0 | 54 | #define SENSOR_HV7131R 0 |
55 | #define SENSOR_MI0360 1 | 55 | #define SENSOR_MI0360 1 |
56 | #define SENSOR_MO4000 2 | 56 | #define SENSOR_MO4000 2 |
57 | #define SENSOR_OV7648 3 | 57 | #define SENSOR_OM6802 3 |
58 | #define SENSOR_OV7660 4 | 58 | #define SENSOR_OV7648 4 |
59 | #define SENSOR_OV7660 5 | ||
59 | unsigned char i2c_base; | 60 | unsigned char i2c_base; |
60 | }; | 61 | }; |
61 | 62 | ||
@@ -180,6 +181,20 @@ static const __u8 sn_mo4000[] = { | |||
180 | 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 181 | 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
181 | }; | 182 | }; |
182 | 183 | ||
184 | static const __u8 sn_om6802[] = { | ||
185 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | ||
186 | 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, | ||
187 | /* reg8 reg9 rega regb regc regd rege regf */ | ||
188 | 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
189 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | ||
190 | 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40, | ||
191 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ | ||
192 | 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
193 | 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf, | ||
194 | 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef, | ||
195 | 0xf7 | ||
196 | }; | ||
197 | |||
183 | static const __u8 sn_ov7648[] = { | 198 | static const __u8 sn_ov7648[] = { |
184 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | 199 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
185 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, | 200 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, |
@@ -207,6 +222,7 @@ static const __u8 *sn_tb[] = { | |||
207 | sn_hv7131, | 222 | sn_hv7131, |
208 | sn_mi0360, | 223 | sn_mi0360, |
209 | sn_mo4000, | 224 | sn_mo4000, |
225 | sn_om6802, | ||
210 | sn_ov7648, | 226 | sn_ov7648, |
211 | sn_ov7660 | 227 | sn_ov7660 |
212 | }; | 228 | }; |
@@ -340,6 +356,40 @@ static const __u8 mo4000_sensor_init[][8] = { | |||
340 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, | 356 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, |
341 | {} | 357 | {} |
342 | }; | 358 | }; |
359 | static __u8 om6802_sensor_init[][8] = { | ||
360 | {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10}, | ||
361 | {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10}, | ||
362 | {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10}, | ||
363 | {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10}, | ||
364 | /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */ | ||
365 | {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10}, | ||
366 | /* white balance & auto-exposure */ | ||
367 | /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
368 | * set color mode */ | ||
369 | /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10}, | ||
370 | * max AGC value in AE */ | ||
371 | /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
372 | * preset AGC */ | ||
373 | /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
374 | * preset brightness */ | ||
375 | /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
376 | * preset contrast */ | ||
377 | /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10}, | ||
378 | * preset gamma */ | ||
379 | {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10}, | ||
380 | /* luminance mode (0x4f = AE) */ | ||
381 | {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10}, | ||
382 | /* preset shutter */ | ||
383 | /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
384 | * auto frame rate */ | ||
385 | /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */ | ||
386 | |||
387 | /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */ | ||
388 | /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */ | ||
389 | /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */ | ||
390 | /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */ | ||
391 | {} | ||
392 | }; | ||
343 | static const __u8 ov7660_sensor_init[][8] = { | 393 | static const __u8 ov7660_sensor_init[][8] = { |
344 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ | 394 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ |
345 | /* (delay 20ms) */ | 395 | /* (delay 20ms) */ |
@@ -685,8 +735,14 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
685 | 735 | ||
686 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | 736 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); |
687 | 737 | ||
688 | switch (sd->bridge) { | 738 | switch (sd->sensor) { |
689 | case BRIDGE_SN9C325: | 739 | case SENSOR_OM6802: |
740 | reg_w1(gspca_dev, 0x02, 0x71); | ||
741 | reg_w1(gspca_dev, 0x01, 0x42); | ||
742 | reg_w1(gspca_dev, 0x17, 0x64); | ||
743 | reg_w1(gspca_dev, 0x01, 0x42); | ||
744 | break; | ||
745 | case SENSOR_OV7648: | ||
690 | reg_w1(gspca_dev, 0x01, 0x43); | 746 | reg_w1(gspca_dev, 0x01, 0x43); |
691 | reg_w1(gspca_dev, 0x17, 0xae); | 747 | reg_w1(gspca_dev, 0x17, 0xae); |
692 | reg_w1(gspca_dev, 0x01, 0x42); | 748 | reg_w1(gspca_dev, 0x01, 0x42); |
@@ -695,11 +751,11 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
695 | reg_w1(gspca_dev, 0x01, 0x43); | 751 | reg_w1(gspca_dev, 0x01, 0x43); |
696 | reg_w1(gspca_dev, 0x17, 0x61); | 752 | reg_w1(gspca_dev, 0x17, 0x61); |
697 | reg_w1(gspca_dev, 0x01, 0x42); | 753 | reg_w1(gspca_dev, 0x01, 0x42); |
698 | } | 754 | if (sd->sensor == SENSOR_HV7131R) { |
699 | 755 | if (probesensor(gspca_dev) < 0) | |
700 | if (sd->sensor == SENSOR_HV7131R) { | 756 | return -ENODEV; |
701 | if (probesensor(gspca_dev) < 0) | 757 | } |
702 | return -ENODEV; | 758 | break; |
703 | } | 759 | } |
704 | return 0; | 760 | return 0; |
705 | } | 761 | } |
@@ -737,6 +793,16 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev) | |||
737 | } | 793 | } |
738 | } | 794 | } |
739 | 795 | ||
796 | static void om6802_InitSensor(struct gspca_dev *gspca_dev) | ||
797 | { | ||
798 | int i = 0; | ||
799 | |||
800 | while (om6802_sensor_init[i][0]) { | ||
801 | i2c_w8(gspca_dev, om6802_sensor_init[i]); | ||
802 | i++; | ||
803 | } | ||
804 | } | ||
805 | |||
740 | static void ov7648_InitSensor(struct gspca_dev *gspca_dev) | 806 | static void ov7648_InitSensor(struct gspca_dev *gspca_dev) |
741 | { | 807 | { |
742 | int i = 0; | 808 | int i = 0; |
@@ -891,6 +957,20 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, | |||
891 | | ((expoMo10[3] & 0x30) >> 4)); | 957 | | ((expoMo10[3] & 0x30) >> 4)); |
892 | break; | 958 | break; |
893 | } | 959 | } |
960 | case SENSOR_OM6802: { | ||
961 | __u8 gainOm[] = | ||
962 | { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; | ||
963 | |||
964 | if (expo > 0x03ff) | ||
965 | expo = 0x03ff; | ||
966 | if (expo < 0x0001) | ||
967 | expo = 0x0001; | ||
968 | gainOm[3] = expo >> 2; | ||
969 | i2c_w8(gspca_dev, gainOm); | ||
970 | reg_w1(gspca_dev, 0x96, expo >> 5); | ||
971 | PDEBUG(D_CONF, "set exposure %d", gainOm[3]); | ||
972 | break; | ||
973 | } | ||
894 | } | 974 | } |
895 | return expo; | 975 | return expo; |
896 | } | 976 | } |
@@ -901,6 +981,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
901 | unsigned int expo; | 981 | unsigned int expo; |
902 | __u8 k2; | 982 | __u8 k2; |
903 | 983 | ||
984 | k2 = sd->brightness >> 10; | ||
904 | switch (sd->sensor) { | 985 | switch (sd->sensor) { |
905 | case SENSOR_HV7131R: | 986 | case SENSOR_HV7131R: |
906 | expo = sd->brightness << 4; | 987 | expo = sd->brightness << 4; |
@@ -915,9 +996,13 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
915 | expo = sd->brightness >> 4; | 996 | expo = sd->brightness >> 4; |
916 | sd->exposure = setexposure(gspca_dev, expo); | 997 | sd->exposure = setexposure(gspca_dev, expo); |
917 | break; | 998 | break; |
999 | case SENSOR_OM6802: | ||
1000 | expo = sd->brightness >> 6; | ||
1001 | sd->exposure = setexposure(gspca_dev, expo); | ||
1002 | k2 = sd->brightness >> 11; | ||
1003 | break; | ||
918 | } | 1004 | } |
919 | 1005 | ||
920 | k2 = sd->brightness >> 10; | ||
921 | reg_w1(gspca_dev, 0x96, k2); | 1006 | reg_w1(gspca_dev, 0x96, k2); |
922 | } | 1007 | } |
923 | 1008 | ||
@@ -1049,6 +1134,11 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1049 | /* reg1 = 0x06; * 640 clk 24Mz (done) */ | 1134 | /* reg1 = 0x06; * 640 clk 24Mz (done) */ |
1050 | } | 1135 | } |
1051 | break; | 1136 | break; |
1137 | case SENSOR_OM6802: | ||
1138 | om6802_InitSensor(gspca_dev); | ||
1139 | reg1 = 0x46; /* 640 clk 24Mz */ | ||
1140 | reg17 = 0x64; /* 640 MCKSIZE */ | ||
1141 | break; | ||
1052 | case SENSOR_OV7648: | 1142 | case SENSOR_OV7648: |
1053 | ov7648_InitSensor(gspca_dev); | 1143 | ov7648_InitSensor(gspca_dev); |
1054 | reg17 = 0xa2; | 1144 | reg17 = 0xa2; |
@@ -1174,6 +1264,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
1174 | default: | 1264 | default: |
1175 | /* case SENSOR_MO4000: */ | 1265 | /* case SENSOR_MO4000: */ |
1176 | /* case SENSOR_MI0360: */ | 1266 | /* case SENSOR_MI0360: */ |
1267 | /* case SENSOR_OM6802: */ | ||
1177 | expotimes = sd->exposure; | 1268 | expotimes = sd->exposure; |
1178 | expotimes += (luma_mean - delta) >> 6; | 1269 | expotimes += (luma_mean - delta) >> 6; |
1179 | if (expotimes < 0) | 1270 | if (expotimes < 0) |
@@ -1246,7 +1337,8 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) | |||
1246 | i2c_r5(gspca_dev, 0x09); | 1337 | i2c_r5(gspca_dev, 0x09); |
1247 | return (gspca_dev->usb_buf[0] << 8) | 1338 | return (gspca_dev->usb_buf[0] << 8) |
1248 | | gspca_dev->usb_buf[1]; | 1339 | | gspca_dev->usb_buf[1]; |
1249 | case SENSOR_MO4000: | 1340 | default: |
1341 | /* case SENSOR_MO4000: */ | ||
1250 | i2c_r5(gspca_dev, 0x0e); | 1342 | i2c_r5(gspca_dev, 0x0e); |
1251 | hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */ | 1343 | hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */ |
1252 | mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */ | 1344 | mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */ |
@@ -1254,7 +1346,8 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) | |||
1254 | PDEBUG(D_CONF, "exposure %d", | 1346 | PDEBUG(D_CONF, "exposure %d", |
1255 | (hexpo << 10) | (mexpo << 2) | lexpo); | 1347 | (hexpo << 10) | (mexpo << 2) | lexpo); |
1256 | return (hexpo << 10) | (mexpo << 2) | lexpo; | 1348 | return (hexpo << 10) | (mexpo << 2) | lexpo; |
1257 | default: | 1349 | #if 0 |
1350 | /*jfm: not called*/ | ||
1258 | /* case SENSOR_OV7648: * jfm: is it ok for 7648? */ | 1351 | /* case SENSOR_OV7648: * jfm: is it ok for 7648? */ |
1259 | /* case SENSOR_OV7660: */ | 1352 | /* case SENSOR_OV7660: */ |
1260 | /* read sensor exposure */ | 1353 | /* read sensor exposure */ |
@@ -1264,7 +1357,9 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) | |||
1264 | i2c_r5(gspca_dev, 0x08); | 1357 | i2c_r5(gspca_dev, 0x08); |
1265 | mexpo = gspca_dev->usb_buf[2]; | 1358 | mexpo = gspca_dev->usb_buf[2]; |
1266 | return (hexpo << 10) | (mexpo << 2) | lexpo; | 1359 | return (hexpo << 10) | (mexpo << 2) | lexpo; |
1360 | #endif | ||
1267 | } | 1361 | } |
1362 | /* not reached */ | ||
1268 | } | 1363 | } |
1269 | 1364 | ||
1270 | static void getbrightness(struct gspca_dev *gspca_dev) | 1365 | static void getbrightness(struct gspca_dev *gspca_dev) |
@@ -1277,9 +1372,8 @@ static void getbrightness(struct gspca_dev *gspca_dev) | |||
1277 | sd->brightness = getexposure(gspca_dev) >> 4; | 1372 | sd->brightness = getexposure(gspca_dev) >> 4; |
1278 | break; | 1373 | break; |
1279 | case SENSOR_MI0360: | 1374 | case SENSOR_MI0360: |
1280 | sd->brightness = getexposure(gspca_dev) << 4; | ||
1281 | break; | ||
1282 | case SENSOR_MO4000: | 1375 | case SENSOR_MO4000: |
1376 | case SENSOR_OM6802: | ||
1283 | sd->brightness = getexposure(gspca_dev) << 4; | 1377 | sd->brightness = getexposure(gspca_dev) << 4; |
1284 | break; | 1378 | break; |
1285 | } | 1379 | } |
@@ -1406,9 +1500,9 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
1406 | /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ | 1500 | /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ |
1407 | /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ | 1501 | /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ |
1408 | /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ | 1502 | /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ |
1409 | {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)}, | 1503 | {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ |
1410 | /* bw600.inf: | 1504 | /*bw600.inf:*/ |
1411 | {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */ | 1505 | {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/ |
1412 | {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, | 1506 | {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, |
1413 | /* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */ | 1507 | /* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */ |
1414 | /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ | 1508 | /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ |