aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-01-29 02:59:45 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:36 -0400
commit3ef2c5be9c79ce668e3e58d323379be24e39e20c (patch)
treeb085b91bea697d8fc1df4523235d9c17e0c614db
parent50b1a9fc259042666605ff65acd572eaa656ab0b (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>
-rw-r--r--drivers/media/video/gspca/sonixj.c206
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[] = {
228static __u32 ctrl_dis[] = { 229static __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
245static const struct v4l2_pix_format vga_mode[] = { 248static 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
300static 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
297static const u8 sn_om6802[0x1c] = { 311static 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] = {
396static const u8 mi0360_sensor_init[][8] = { 411static 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};
488static 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};
473static const u8 om6802_sensor_init[][8] = { 520static 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
835static int probesensor(struct gspca_dev *gspca_dev) 882static 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
904static 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
857static int configure_gpio(struct gspca_dev *gspca_dev, 950static 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
1063static 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
964static void om6802_InitSensor(struct gspca_dev *gspca_dev) 1076static 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
1211static void setcontrast(struct gspca_dev *gspca_dev) 1351static 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)},