diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2009-01-29 02:59:45 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:36 -0400 |
commit | 3ef2c5be9c79ce668e3e58d323379be24e39e20c (patch) | |
tree | b085b91bea697d8fc1df4523235d9c17e0c614db /drivers/media/video/gspca | |
parent | 50b1a9fc259042666605ff65acd572eaa656ab0b (diff) |
V4L/DVB (10419): gspca - sonixj: Sensor mt9v111 added.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r-- | drivers/media/video/gspca/sonixj.c | 206 |
1 files changed, 180 insertions, 26 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 59363e077bbf..74d2aca390b3 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -46,7 +46,7 @@ struct sd { | |||
46 | u8 red; | 46 | u8 red; |
47 | u8 gamma; | 47 | u8 gamma; |
48 | u8 vflip; /* ov7630 only */ | 48 | u8 vflip; /* ov7630 only */ |
49 | u8 infrared; /* mi0360 only */ | 49 | u8 infrared; /* mt9v111 only */ |
50 | 50 | ||
51 | s8 ag_cnt; | 51 | s8 ag_cnt; |
52 | #define AG_CNT_START 13 | 52 | #define AG_CNT_START 13 |
@@ -61,10 +61,11 @@ struct sd { | |||
61 | #define SENSOR_HV7131R 0 | 61 | #define SENSOR_HV7131R 0 |
62 | #define SENSOR_MI0360 1 | 62 | #define SENSOR_MI0360 1 |
63 | #define SENSOR_MO4000 2 | 63 | #define SENSOR_MO4000 2 |
64 | #define SENSOR_OM6802 3 | 64 | #define SENSOR_MT9V111 3 |
65 | #define SENSOR_OV7630 4 | 65 | #define SENSOR_OM6802 4 |
66 | #define SENSOR_OV7648 5 | 66 | #define SENSOR_OV7630 5 |
67 | #define SENSOR_OV7660 6 | 67 | #define SENSOR_OV7648 6 |
68 | #define SENSOR_OV7660 7 | ||
68 | u8 i2c_base; | 69 | u8 i2c_base; |
69 | }; | 70 | }; |
70 | 71 | ||
@@ -206,7 +207,7 @@ static struct ctrl sd_ctrls[] = { | |||
206 | .set = sd_setvflip, | 207 | .set = sd_setvflip, |
207 | .get = sd_getvflip, | 208 | .get = sd_getvflip, |
208 | }, | 209 | }, |
209 | /* mi0360 only */ | 210 | /* mt9v111 only */ |
210 | #define INFRARED_IDX 7 | 211 | #define INFRARED_IDX 7 |
211 | { | 212 | { |
212 | { | 213 | { |
@@ -228,18 +229,20 @@ static struct ctrl sd_ctrls[] = { | |||
228 | static __u32 ctrl_dis[] = { | 229 | static __u32 ctrl_dis[] = { |
229 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), | 230 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), |
230 | /* SENSOR_HV7131R 0 */ | 231 | /* SENSOR_HV7131R 0 */ |
231 | (1 << VFLIP_IDX), | 232 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), |
232 | /* SENSOR_MI0360 1 */ | 233 | /* SENSOR_MI0360 1 */ |
233 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), | 234 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), |
234 | /* SENSOR_MO4000 2 */ | 235 | /* SENSOR_MO4000 2 */ |
236 | (1 << AUTOGAIN_IDX), | ||
237 | /* SENSOR_MT9V111 3 */ | ||
235 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), | 238 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), |
236 | /* SENSOR_OM6802 3 */ | 239 | /* SENSOR_OM6802 4 */ |
237 | (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX), | 240 | (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX), |
238 | /* SENSOR_OV7630 4 */ | 241 | /* SENSOR_OV7630 5 */ |
239 | (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), | 242 | (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), |
240 | /* SENSOR_OV7648 5 */ | 243 | /* SENSOR_OV7648 6 */ |
241 | (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), | 244 | (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), |
242 | /* SENSOR_OV7660 6 */ | 245 | /* SENSOR_OV7660 7 */ |
243 | }; | 246 | }; |
244 | 247 | ||
245 | static const struct v4l2_pix_format vga_mode[] = { | 248 | static const struct v4l2_pix_format vga_mode[] = { |
@@ -294,6 +297,17 @@ static const u8 sn_mo4000[0x1c] = { | |||
294 | 0x08, 0x00, 0x00, 0x00 | 297 | 0x08, 0x00, 0x00, 0x00 |
295 | }; | 298 | }; |
296 | 299 | ||
300 | static const u8 sn_mt9v111[0x1c] = { | ||
301 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | ||
302 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, | ||
303 | /* reg8 reg9 rega regb regc regd rege regf */ | ||
304 | 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
305 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | ||
306 | 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40, | ||
307 | /* reg18 reg19 reg1a reg1b */ | ||
308 | 0x06, 0x00, 0x00, 0x00 | ||
309 | }; | ||
310 | |||
297 | static const u8 sn_om6802[0x1c] = { | 311 | static const u8 sn_om6802[0x1c] = { |
298 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | 312 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
299 | 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, | 313 | 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, |
@@ -343,6 +357,7 @@ static const u8 *sn_tb[] = { | |||
343 | sn_hv7131, | 357 | sn_hv7131, |
344 | sn_mi0360, | 358 | sn_mi0360, |
345 | sn_mo4000, | 359 | sn_mo4000, |
360 | sn_mt9v111, | ||
346 | sn_om6802, | 361 | sn_om6802, |
347 | sn_ov7630, | 362 | sn_ov7630, |
348 | sn_ov7648, | 363 | sn_ov7648, |
@@ -396,7 +411,7 @@ static const u8 hv7131r_sensor_init[][8] = { | |||
396 | static const u8 mi0360_sensor_init[][8] = { | 411 | static const u8 mi0360_sensor_init[][8] = { |
397 | {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, | 412 | {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, |
398 | {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, | 413 | {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, |
399 | {0xb1, 0x5d, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, | 414 | {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, |
400 | {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, | 415 | {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, |
401 | {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10}, | 416 | {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10}, |
402 | {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, | 417 | {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, |
@@ -470,6 +485,38 @@ static const u8 mo4000_sensor_init[][8] = { | |||
470 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, | 485 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, |
471 | {} | 486 | {} |
472 | }; | 487 | }; |
488 | static const u8 mt9v111_sensor_init[][8] = { | ||
489 | {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */ | ||
490 | /* delay 20 ms */ | ||
491 | {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
492 | {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ | ||
493 | {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ | ||
494 | {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */ | ||
495 | {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */ | ||
496 | {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */ | ||
497 | {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */ | ||
498 | {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */ | ||
499 | {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */ | ||
500 | {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */ | ||
501 | {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */ | ||
502 | {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */ | ||
503 | {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */ | ||
504 | {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */ | ||
505 | {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */ | ||
506 | {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
507 | /*******/ | ||
508 | {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
509 | {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
510 | {0xb1, 0x5c, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, /* shutter width */ | ||
511 | {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */ | ||
512 | {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */ | ||
513 | /*******/ | ||
514 | {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */ | ||
515 | {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */ | ||
516 | {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */ | ||
517 | {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ | ||
518 | {} | ||
519 | }; | ||
473 | static const u8 om6802_sensor_init[][8] = { | 520 | static const u8 om6802_sensor_init[][8] = { |
474 | {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10}, | 521 | {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10}, |
475 | {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10}, | 522 | {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10}, |
@@ -736,7 +783,7 @@ static void reg_w1(struct gspca_dev *gspca_dev, | |||
736 | u16 value, | 783 | u16 value, |
737 | u8 data) | 784 | u8 data) |
738 | { | 785 | { |
739 | PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data); | 786 | PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data); |
740 | gspca_dev->usb_buf[0] = data; | 787 | gspca_dev->usb_buf[0] = data; |
741 | usb_control_msg(gspca_dev->dev, | 788 | usb_control_msg(gspca_dev->dev, |
742 | usb_sndctrlpipe(gspca_dev->dev, 0), | 789 | usb_sndctrlpipe(gspca_dev->dev, 0), |
@@ -752,7 +799,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
752 | const u8 *buffer, | 799 | const u8 *buffer, |
753 | int len) | 800 | int len) |
754 | { | 801 | { |
755 | PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..", | 802 | PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..", |
756 | value, buffer[0], buffer[1]); | 803 | value, buffer[0], buffer[1]); |
757 | #ifdef GSPCA_DEBUG | 804 | #ifdef GSPCA_DEBUG |
758 | if (len > USB_BUF_SZ) { | 805 | if (len > USB_BUF_SZ) { |
@@ -832,7 +879,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) | |||
832 | reg_r(gspca_dev, 0x0a, 5); | 879 | reg_r(gspca_dev, 0x0a, 5); |
833 | } | 880 | } |
834 | 881 | ||
835 | static int probesensor(struct gspca_dev *gspca_dev) | 882 | static int hv7131r_probe(struct gspca_dev *gspca_dev) |
836 | { | 883 | { |
837 | i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ | 884 | i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ |
838 | msleep(10); | 885 | msleep(10); |
@@ -854,6 +901,52 @@ static int probesensor(struct gspca_dev *gspca_dev) | |||
854 | return -ENODEV; | 901 | return -ENODEV; |
855 | } | 902 | } |
856 | 903 | ||
904 | static int mi0360_probe(struct gspca_dev *gspca_dev) | ||
905 | { | ||
906 | int i, j; | ||
907 | u16 val; | ||
908 | static const u8 probe_tb[][4][8] = { | ||
909 | { | ||
910 | {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, | ||
911 | {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
912 | {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
913 | {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10} | ||
914 | }, | ||
915 | { | ||
916 | {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, | ||
917 | {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
918 | {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
919 | {} | ||
920 | }, | ||
921 | }; | ||
922 | |||
923 | for (i = 0; i < ARRAY_SIZE(probe_tb); i++) { | ||
924 | reg_w1(gspca_dev, 0x17, 0x62); | ||
925 | reg_w1(gspca_dev, 0x01, 0x08); | ||
926 | for (j = 0; j < 3; j++) | ||
927 | i2c_w8(gspca_dev, probe_tb[i][j]); | ||
928 | msleep(2); | ||
929 | reg_r(gspca_dev, 0x0a, 5); | ||
930 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; | ||
931 | if (probe_tb[i][3][0] != 0) | ||
932 | i2c_w8(gspca_dev, probe_tb[i][3]); | ||
933 | reg_w1(gspca_dev, 0x01, 0x29); | ||
934 | reg_w1(gspca_dev, 0x17, 0x42); | ||
935 | if (val != 0xffff) | ||
936 | break; | ||
937 | } | ||
938 | switch (val) { | ||
939 | case 0x823a: | ||
940 | PDEBUG(D_PROBE, "Sensor mt9v111"); | ||
941 | return SENSOR_MT9V111; | ||
942 | case 0x8243: | ||
943 | PDEBUG(D_PROBE, "Sensor mi0360"); | ||
944 | return SENSOR_MI0360; | ||
945 | } | ||
946 | PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val); | ||
947 | return SENSOR_MI0360; | ||
948 | } | ||
949 | |||
857 | static int configure_gpio(struct gspca_dev *gspca_dev, | 950 | static int configure_gpio(struct gspca_dev *gspca_dev, |
858 | const u8 *sn9c1xx) | 951 | const u8 *sn9c1xx) |
859 | { | 952 | { |
@@ -887,6 +980,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
887 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | 980 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); |
888 | 981 | ||
889 | switch (sd->sensor) { | 982 | switch (sd->sensor) { |
983 | case SENSOR_MT9V111: | ||
984 | reg_w1(gspca_dev, 0x01, 0x61); | ||
985 | reg_w1(gspca_dev, 0x17, 0x61); | ||
986 | reg_w1(gspca_dev, 0x01, 0x60); | ||
987 | reg_w1(gspca_dev, 0x01, 0x40); | ||
988 | break; | ||
890 | case SENSOR_OM6802: | 989 | case SENSOR_OM6802: |
891 | reg_w1(gspca_dev, 0x02, 0x71); | 990 | reg_w1(gspca_dev, 0x02, 0x71); |
892 | reg_w1(gspca_dev, 0x01, 0x42); | 991 | reg_w1(gspca_dev, 0x01, 0x42); |
@@ -920,7 +1019,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
920 | reg_w1(gspca_dev, 0x17, 0x61); | 1019 | reg_w1(gspca_dev, 0x17, 0x61); |
921 | reg_w1(gspca_dev, 0x01, 0x42); | 1020 | reg_w1(gspca_dev, 0x01, 0x42); |
922 | if (sd->sensor == SENSOR_HV7131R) { | 1021 | if (sd->sensor == SENSOR_HV7131R) { |
923 | if (probesensor(gspca_dev) < 0) | 1022 | if (hv7131r_probe(gspca_dev) < 0) |
924 | return -ENODEV; | 1023 | return -ENODEV; |
925 | } | 1024 | } |
926 | break; | 1025 | break; |
@@ -961,6 +1060,19 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev) | |||
961 | } | 1060 | } |
962 | } | 1061 | } |
963 | 1062 | ||
1063 | static void mt9v111_InitSensor(struct gspca_dev *gspca_dev) | ||
1064 | { | ||
1065 | int i = 0; | ||
1066 | |||
1067 | i2c_w8(gspca_dev, mt9v111_sensor_init[i]); | ||
1068 | i++; | ||
1069 | msleep(20); | ||
1070 | while (mt9v111_sensor_init[i][0]) { | ||
1071 | i2c_w8(gspca_dev, mt9v111_sensor_init[i]); | ||
1072 | i++; | ||
1073 | } | ||
1074 | } | ||
1075 | |||
964 | static void om6802_InitSensor(struct gspca_dev *gspca_dev) | 1076 | static void om6802_InitSensor(struct gspca_dev *gspca_dev) |
965 | { | 1077 | { |
966 | int i = 0; | 1078 | int i = 0; |
@@ -1078,11 +1190,21 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1078 | case BRIDGE_SN9C105: | 1190 | case BRIDGE_SN9C105: |
1079 | if (regF1 != 0x11) | 1191 | if (regF1 != 0x11) |
1080 | return -ENODEV; | 1192 | return -ENODEV; |
1193 | if (sd->sensor == SENSOR_MI0360) { | ||
1194 | sd->sensor = mi0360_probe(gspca_dev); | ||
1195 | if (sd->sensor == SENSOR_MT9V111) | ||
1196 | sd->i2c_base = 0x5c; | ||
1197 | } | ||
1081 | reg_w(gspca_dev, 0x01, regGpio, 2); | 1198 | reg_w(gspca_dev, 0x01, regGpio, 2); |
1082 | break; | 1199 | break; |
1083 | case BRIDGE_SN9C120: | 1200 | case BRIDGE_SN9C120: |
1084 | if (regF1 != 0x12) | 1201 | if (regF1 != 0x12) |
1085 | return -ENODEV; | 1202 | return -ENODEV; |
1203 | if (sd->sensor == SENSOR_MI0360) { | ||
1204 | sd->sensor = mi0360_probe(gspca_dev); | ||
1205 | if (sd->sensor == SENSOR_MT9V111) | ||
1206 | sd->i2c_base = 0x5c; | ||
1207 | } | ||
1086 | regGpio[1] = 0x70; | 1208 | regGpio[1] = 0x70; |
1087 | reg_w(gspca_dev, 0x01, regGpio, 2); | 1209 | reg_w(gspca_dev, 0x01, regGpio, 2); |
1088 | break; | 1210 | break; |
@@ -1117,7 +1239,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev, | |||
1117 | break; | 1239 | break; |
1118 | } | 1240 | } |
1119 | case SENSOR_MI0360: { | 1241 | case SENSOR_MI0360: { |
1120 | u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ | 1242 | u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ |
1121 | { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; | 1243 | { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; |
1122 | static const u8 doit[] = /* update sensor */ | 1244 | static const u8 doit[] = /* update sensor */ |
1123 | { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; | 1245 | { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; |
@@ -1153,12 +1275,25 @@ static u32 setexposure(struct gspca_dev *gspca_dev, | |||
1153 | | ((expo & 0x0003) << 4); | 1275 | | ((expo & 0x0003) << 4); |
1154 | i2c_w8(gspca_dev, expoMo10); | 1276 | i2c_w8(gspca_dev, expoMo10); |
1155 | i2c_w8(gspca_dev, gainMo); | 1277 | i2c_w8(gspca_dev, gainMo); |
1156 | PDEBUG(D_CONF, "set exposure %d", | 1278 | PDEBUG(D_FRAM, "set exposure %d", |
1157 | ((expoMo10[3] & 0x07) << 10) | 1279 | ((expoMo10[3] & 0x07) << 10) |
1158 | | (expoMof[3] << 2) | 1280 | | (expoMof[3] << 2) |
1159 | | ((expoMo10[3] & 0x30) >> 4)); | 1281 | | ((expoMo10[3] & 0x30) >> 4)); |
1160 | break; | 1282 | break; |
1161 | } | 1283 | } |
1284 | case SENSOR_MT9V111: { | ||
1285 | u8 expo_c1[] = | ||
1286 | { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 }; | ||
1287 | |||
1288 | if (expo > 0x0280) | ||
1289 | expo = 0x0280; | ||
1290 | else if (expo < 0x0040) | ||
1291 | expo = 0x0040; | ||
1292 | expo_c1[3] = expo >> 8; | ||
1293 | expo_c1[4] = expo; | ||
1294 | i2c_w8(gspca_dev, expo_c1); | ||
1295 | break; | ||
1296 | } | ||
1162 | case SENSOR_OM6802: { | 1297 | case SENSOR_OM6802: { |
1163 | u8 gainOm[] = | 1298 | u8 gainOm[] = |
1164 | { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; | 1299 | { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; |
@@ -1170,7 +1305,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev, | |||
1170 | gainOm[3] = expo >> 2; | 1305 | gainOm[3] = expo >> 2; |
1171 | i2c_w8(gspca_dev, gainOm); | 1306 | i2c_w8(gspca_dev, gainOm); |
1172 | reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f); | 1307 | reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f); |
1173 | PDEBUG(D_CONF, "set exposure %d", gainOm[3]); | 1308 | PDEBUG(D_FRAM, "set exposure %d", gainOm[3]); |
1174 | break; | 1309 | break; |
1175 | } | 1310 | } |
1176 | } | 1311 | } |
@@ -1198,6 +1333,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1198 | expo = sd->brightness >> 4; | 1333 | expo = sd->brightness >> 4; |
1199 | sd->exposure = setexposure(gspca_dev, expo); | 1334 | sd->exposure = setexposure(gspca_dev, expo); |
1200 | break; | 1335 | break; |
1336 | case SENSOR_MT9V111: | ||
1337 | expo = sd->brightness >> 8; | ||
1338 | sd->exposure = setexposure(gspca_dev, expo); | ||
1339 | break; | ||
1201 | case SENSOR_OM6802: | 1340 | case SENSOR_OM6802: |
1202 | expo = sd->brightness >> 6; | 1341 | expo = sd->brightness >> 6; |
1203 | sd->exposure = setexposure(gspca_dev, expo); | 1342 | sd->exposure = setexposure(gspca_dev, expo); |
@@ -1205,7 +1344,8 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1205 | break; | 1344 | break; |
1206 | } | 1345 | } |
1207 | 1346 | ||
1208 | reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */ | 1347 | if (sd->sensor != SENSOR_MT9V111) |
1348 | reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */ | ||
1209 | } | 1349 | } |
1210 | 1350 | ||
1211 | static void setcontrast(struct gspca_dev *gspca_dev) | 1351 | static void setcontrast(struct gspca_dev *gspca_dev) |
@@ -1322,6 +1462,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1322 | reg_w1(gspca_dev, 0xc9, 0x3c); | 1462 | reg_w1(gspca_dev, 0xc9, 0x3c); |
1323 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); | 1463 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); |
1324 | switch (sd->sensor) { | 1464 | switch (sd->sensor) { |
1465 | case SENSOR_MT9V111: | ||
1466 | reg17 = 0xe0; | ||
1467 | break; | ||
1325 | case SENSOR_OV7630: | 1468 | case SENSOR_OV7630: |
1326 | reg17 = 0xe2; | 1469 | reg17 = 0xe2; |
1327 | break; | 1470 | break; |
@@ -1349,6 +1492,10 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1349 | for (i = 0; i < 8; i++) | 1492 | for (i = 0; i < 8; i++) |
1350 | reg_w(gspca_dev, 0x84, reg84, sizeof reg84); | 1493 | reg_w(gspca_dev, 0x84, reg84, sizeof reg84); |
1351 | switch (sd->sensor) { | 1494 | switch (sd->sensor) { |
1495 | case SENSOR_MT9V111: | ||
1496 | reg_w1(gspca_dev, 0x9a, 0x07); | ||
1497 | reg_w1(gspca_dev, 0x99, 0x59); | ||
1498 | break; | ||
1352 | case SENSOR_OV7648: | 1499 | case SENSOR_OV7648: |
1353 | reg_w1(gspca_dev, 0x9a, 0x0a); | 1500 | reg_w1(gspca_dev, 0x9a, 0x0a); |
1354 | reg_w1(gspca_dev, 0x99, 0x60); | 1501 | reg_w1(gspca_dev, 0x99, 0x60); |
@@ -1388,6 +1535,14 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1388 | /* reg1 = 0x06; * 640 clk 24Mz (done) */ | 1535 | /* reg1 = 0x06; * 640 clk 24Mz (done) */ |
1389 | } | 1536 | } |
1390 | break; | 1537 | break; |
1538 | case SENSOR_MT9V111: | ||
1539 | mt9v111_InitSensor(gspca_dev); | ||
1540 | if (mode) { | ||
1541 | reg1 = 0x04; /* 320 clk 48Mhz */ | ||
1542 | } else { | ||
1543 | /* reg1 = 0x06; * 640 clk 24Mz (done) */ | ||
1544 | reg17 = 0xe2; | ||
1545 | } | ||
1391 | case SENSOR_OM6802: | 1546 | case SENSOR_OM6802: |
1392 | om6802_InitSensor(gspca_dev); | 1547 | om6802_InitSensor(gspca_dev); |
1393 | reg17 = 0x64; /* 640 MCKSIZE */ | 1548 | reg17 = 0x64; /* 640 MCKSIZE */ |
@@ -1436,17 +1591,14 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1436 | reg18 = sn9c1xx[0x18] | (mode << 4); | 1591 | reg18 = sn9c1xx[0x18] | (mode << 4); |
1437 | reg_w1(gspca_dev, 0x18, reg18 | 0x40); | 1592 | reg_w1(gspca_dev, 0x18, reg18 | 0x40); |
1438 | 1593 | ||
1439 | reg_w(gspca_dev, 0x100, qtable4, 0x40); | 1594 | reg_w(gspca_dev, 0x0100, qtable4, 0x40); |
1440 | reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); | 1595 | reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40); |
1441 | 1596 | ||
1442 | reg_w1(gspca_dev, 0x18, reg18); | 1597 | reg_w1(gspca_dev, 0x18, reg18); |
1443 | 1598 | ||
1444 | reg_w1(gspca_dev, 0x17, reg17); | 1599 | reg_w1(gspca_dev, 0x17, reg17); |
1445 | reg_w1(gspca_dev, 0x01, reg1); | 1600 | reg_w1(gspca_dev, 0x01, reg1); |
1446 | switch (sd->sensor) { | 1601 | switch (sd->sensor) { |
1447 | case SENSOR_MI0360: | ||
1448 | setinfrared(sd); | ||
1449 | break; | ||
1450 | case SENSOR_OV7630: | 1602 | case SENSOR_OV7630: |
1451 | setvflip(sd); | 1603 | setvflip(sd); |
1452 | break; | 1604 | break; |
@@ -1482,6 +1634,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1482 | case SENSOR_OV7648: | 1634 | case SENSOR_OV7648: |
1483 | i2c_w8(gspca_dev, stopov7648); | 1635 | i2c_w8(gspca_dev, stopov7648); |
1484 | /* fall thru */ | 1636 | /* fall thru */ |
1637 | case SENSOR_MT9V111: | ||
1485 | case SENSOR_OV7630: | 1638 | case SENSOR_OV7630: |
1486 | data = 0x29; | 1639 | data = 0x29; |
1487 | break; | 1640 | break; |
@@ -1529,6 +1682,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
1529 | default: | 1682 | default: |
1530 | /* case SENSOR_MO4000: */ | 1683 | /* case SENSOR_MO4000: */ |
1531 | /* case SENSOR_MI0360: */ | 1684 | /* case SENSOR_MI0360: */ |
1685 | /* case SENSOR_MT9V111: */ | ||
1532 | /* case SENSOR_OM6802: */ | 1686 | /* case SENSOR_OM6802: */ |
1533 | expotimes = sd->exposure; | 1687 | expotimes = sd->exposure; |
1534 | expotimes += (luma_mean - delta) >> 6; | 1688 | expotimes += (luma_mean - delta) >> 6; |
@@ -1785,7 +1939,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
1785 | /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */ | 1939 | /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */ |
1786 | {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, | 1940 | {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, |
1787 | /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ | 1941 | /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ |
1788 | {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, | 1942 | {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MT9V111, 0x5c)}, |
1789 | /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */ | 1943 | /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */ |
1790 | /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ | 1944 | /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ |
1791 | {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, | 1945 | {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, |