aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sonixj.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-11-23 04:46:35 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:42:07 -0500
commitb8c8a5bf833db5ad80266a6a9e5ad496ab01d434 (patch)
tree7456580eda398445daa8886d7521ca6bb03b3ecd /drivers/media/video/gspca/sonixj.c
parent4e5cf58ecf98f7cce8033d5b8249c3e9d7ada3f0 (diff)
V4L/DVB (13489): gspca - sonixj: Add the sensor po1030.
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/sonixj.c')
-rw-r--r--drivers/media/video/gspca/sonixj.c153
1 files changed, 141 insertions, 12 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 282c707e5e81..0bd36a00dd2a 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -72,7 +72,8 @@ struct sd {
72#define SENSOR_OV7630 5 72#define SENSOR_OV7630 5
73#define SENSOR_OV7648 6 73#define SENSOR_OV7648 6
74#define SENSOR_OV7660 7 74#define SENSOR_OV7660 7
75#define SENSOR_SP80708 8 75#define SENSOR_PO1030 8
76#define SENSOR_SP80708 9
76 u8 i2c_addr; 77 u8 i2c_addr;
77 78
78 u8 *jpeg_hdr; 79 u8 *jpeg_hdr;
@@ -250,7 +251,7 @@ static struct ctrl sd_ctrls[] = {
250 .minimum = 0, 251 .minimum = 0,
251 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ 252 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
252 .step = 1, 253 .step = 1,
253#define FREQ_DEF 2 254#define FREQ_DEF 1
254 .default_value = FREQ_DEF, 255 .default_value = FREQ_DEF,
255 }, 256 },
256 .set = sd_setfreq, 257 .set = sd_setfreq,
@@ -277,7 +278,9 @@ static __u32 ctrl_dis[] = {
277 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 278 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
278 /* SENSOR_OV7660 7 */ 279 /* SENSOR_OV7660 7 */
279 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | 280 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
280 (1 << FREQ_IDX), /* SENSOR_SP80708 8 */ 281 (1 << FREQ_IDX), /* SENSOR_PO1030 8 */
282 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
283 (1 << FREQ_IDX), /* SENSOR_SP80708 9 */
281}; 284};
282 285
283static const struct v4l2_pix_format vga_mode[] = { 286static const struct v4l2_pix_format vga_mode[] = {
@@ -388,6 +391,17 @@ static const u8 sn_ov7660[0x1c] = {
388 0x07, 0x00, 0x00, 0x00 391 0x07, 0x00, 0x00, 0x00
389}; 392};
390 393
394static const u8 sn_po1030[0x1c] = {
395/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
396 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
397/* reg8 reg9 rega regb regc regd rege regf */
398 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
400 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
401/* reg18 reg19 reg1a reg1b */
402 0x07, 0x00, 0x00, 0x00
403};
404
391static const u8 sn_sp80708[0x1c] = { 405static const u8 sn_sp80708[0x1c] = {
392/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 406/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
393 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, 407 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
@@ -409,6 +423,7 @@ static const u8 *sn_tb[] = {
409 sn_ov7630, 423 sn_ov7630,
410 sn_ov7648, 424 sn_ov7648,
411 sn_ov7660, 425 sn_ov7660,
426 sn_po1030,
412 sn_sp80708 427 sn_sp80708
413}; 428};
414 429
@@ -832,6 +847,60 @@ static const u8 ov7660_sensor_param1[][8] = {
832 {} 847 {}
833}; 848};
834 849
850static const u8 po1030_sensor_init[][8] = {
851/* the sensor registers are described in m5602/m5602_po1030.h */
852 {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
853 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
854 {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
855 {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
856 {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
857 {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
858 {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
859 {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
860 {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
861 {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
862 {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
863 {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
864 {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
865 {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
866 {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
867 {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
868 {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
869 {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
870 {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
871 {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
872 {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
873 {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
874 {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
875 {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
876 {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
877 {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
878 {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
879 {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
880
881 {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
882 {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
883 {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
884 {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
885 {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
886 {}
887};
888static const u8 po1030_sensor_param1[][8] = {
889/* from ms-win traces - these values change with auto gain/expo/wb.. */
890 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
891 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
892/* mean values */
893 {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
894 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
895 {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
896
897 {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
898 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
899 {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
900/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
901 {}
902};
903
835static const u8 sp80708_sensor_init[][8] = { 904static const u8 sp80708_sensor_init[][8] = {
836 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, 905 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, 906 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
@@ -917,7 +986,7 @@ static const u8 sp80708_sensor_param1[][8] = {
917 {} 986 {}
918}; 987};
919 988
920static const u8 (*sensor_init[9])[8] = { 989static const u8 (*sensor_init[10])[8] = {
921 hv7131r_sensor_init, /* HV7131R 0 */ 990 hv7131r_sensor_init, /* HV7131R 0 */
922 mi0360_sensor_init, /* MI0360 1 */ 991 mi0360_sensor_init, /* MI0360 1 */
923 mo4000_sensor_init, /* MO4000 2 */ 992 mo4000_sensor_init, /* MO4000 2 */
@@ -926,7 +995,8 @@ static const u8 (*sensor_init[9])[8] = {
926 ov7630_sensor_init, /* OV7630 5 */ 995 ov7630_sensor_init, /* OV7630 5 */
927 ov7648_sensor_init, /* OV7648 6 */ 996 ov7648_sensor_init, /* OV7648 6 */
928 ov7660_sensor_init, /* OV7660 7 */ 997 ov7660_sensor_init, /* OV7660 7 */
929 sp80708_sensor_init, /* SP80708 8 */ 998 po1030_sensor_init, /* PO1030 8 */
999 sp80708_sensor_init, /* SP80708 9 */
930}; 1000};
931 1001
932/* read <len> bytes to gspca_dev->usb_buf */ 1002/* read <len> bytes to gspca_dev->usb_buf */
@@ -1033,8 +1103,8 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
1033 msleep(2); 1103 msleep(2);
1034} 1104}
1035 1105
1036/* read 5 bytes in gspca_dev->usb_buf */ 1106/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1037static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) 1107static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1038{ 1108{
1039 struct sd *sd = (struct sd *) gspca_dev; 1109 struct sd *sd = (struct sd *) gspca_dev;
1040 u8 mode[8]; 1110 u8 mode[8];
@@ -1056,7 +1126,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
1056 mode[7] = 0x10; 1126 mode[7] = 0x10;
1057 i2c_w8(gspca_dev, mode); 1127 i2c_w8(gspca_dev, mode);
1058 msleep(2); 1128 msleep(2);
1059 mode[0] = (mode[0] & 0x81) | (5 << 4) | 0x02; 1129 mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
1060 mode[2] = 0; 1130 mode[2] = 0;
1061 i2c_w8(gspca_dev, mode); 1131 i2c_w8(gspca_dev, mode);
1062 msleep(2); 1132 msleep(2);
@@ -1081,7 +1151,7 @@ static void hv7131r_probe(struct gspca_dev *gspca_dev)
1081 msleep(10); 1151 msleep(10);
1082 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ 1152 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
1083 msleep(10); 1153 msleep(10);
1084 i2c_r5(gspca_dev, 0); /* read sensor id */ 1154 i2c_r(gspca_dev, 0, 5); /* read sensor id */
1085 if (gspca_dev->usb_buf[0] == 0x02 1155 if (gspca_dev->usb_buf[0] == 0x02
1086 && gspca_dev->usb_buf[1] == 0x09 1156 && gspca_dev->usb_buf[1] == 0x09
1087 && gspca_dev->usb_buf[2] == 0x01 1157 && gspca_dev->usb_buf[2] == 0x01
@@ -1144,6 +1214,41 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
1144 } 1214 }
1145} 1215}
1146 1216
1217static void ov7648_probe(struct gspca_dev *gspca_dev)
1218{
1219 struct sd *sd = (struct sd *) gspca_dev;
1220
1221 /* check ov76xx */
1222 reg_w1(gspca_dev, 0x17, 0x62);
1223 reg_w1(gspca_dev, 0x01, 0x08);
1224 sd->i2c_addr = 0x21;
1225 i2c_r(gspca_dev, 0x0a, 2);
1226 if (gspca_dev->usb_buf[3] == 0x76) { /* ov76xx */
1227 PDEBUG(D_PROBE, "Sensor ov%02x%02x",
1228 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1229 return;
1230 }
1231
1232 /* reset */
1233 reg_w1(gspca_dev, 0x01, 0x29);
1234 reg_w1(gspca_dev, 0x17, 0x42);
1235
1236 /* check po1030 */
1237 reg_w1(gspca_dev, 0x17, 0x62);
1238 reg_w1(gspca_dev, 0x01, 0x08);
1239 sd->i2c_addr = 0x6e;
1240 i2c_r(gspca_dev, 0x00, 2);
1241 if (gspca_dev->usb_buf[3] == 0x10 /* po1030 */
1242 && gspca_dev->usb_buf[4] == 0x30) {
1243 PDEBUG(D_PROBE, "Sensor po1030");
1244 sd->sensor = SENSOR_PO1030;
1245 return;
1246 }
1247
1248 PDEBUG(D_PROBE, "Unknown sensor %02x%02x",
1249 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1250}
1251
1147static void bridge_init(struct gspca_dev *gspca_dev, 1252static void bridge_init(struct gspca_dev *gspca_dev,
1148 const u8 *sn9c1xx) 1253 const u8 *sn9c1xx)
1149{ 1254{
@@ -1164,6 +1269,7 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1164 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); 1269 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
1165 switch (sd->sensor) { 1270 switch (sd->sensor) {
1166 case SENSOR_OV7660: 1271 case SENSOR_OV7660:
1272 case SENSOR_PO1030:
1167 case SENSOR_SP80708: 1273 case SENSOR_SP80708:
1168 reg9a = reg9a_spec; 1274 reg9a = reg9a_spec;
1169 break; 1275 break;
@@ -1214,7 +1320,14 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1214 reg_w1(gspca_dev, 0x01, 0x62); 1320 reg_w1(gspca_dev, 0x01, 0x62);
1215 reg_w1(gspca_dev, 0x01, 0x42); 1321 reg_w1(gspca_dev, 0x01, 0x42);
1216 break; 1322 break;
1323 case SENSOR_PO1030:
1324 reg_w1(gspca_dev, 0x01, 0x61);
1325 reg_w1(gspca_dev, 0x17, 0x20);
1326 reg_w1(gspca_dev, 0x01, 0x60);
1327 reg_w1(gspca_dev, 0x01, 0x40);
1328 break;
1217 case SENSOR_OV7660: 1329 case SENSOR_OV7660:
1330 /* fall thru */
1218 case SENSOR_SP80708: 1331 case SENSOR_SP80708:
1219 reg_w1(gspca_dev, 0x01, 0x63); 1332 reg_w1(gspca_dev, 0x01, 0x63);
1220 reg_w1(gspca_dev, 0x17, 0x20); 1333 reg_w1(gspca_dev, 0x17, 0x20);
@@ -1266,7 +1379,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1266 sd->quality = QUALITY_DEF; 1379 sd->quality = QUALITY_DEF;
1267 sd->jpegqual = 80; 1380 sd->jpegqual = 80;
1268 1381
1269 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1270 return 0; 1382 return 0;
1271} 1383}
1272 1384
@@ -1301,8 +1413,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
1301 case BRIDGE_SN9C120: 1413 case BRIDGE_SN9C120:
1302 if (regF1 != 0x12) 1414 if (regF1 != 0x12)
1303 return -ENODEV; 1415 return -ENODEV;
1304 if (sd->sensor == SENSOR_MI0360) 1416 switch (sd->sensor) {
1417 case SENSOR_MI0360:
1305 mi0360_probe(gspca_dev); 1418 mi0360_probe(gspca_dev);
1419 break;
1420 case SENSOR_OV7648:
1421 ov7648_probe(gspca_dev);
1422 break;
1423 }
1306 regGpio[1] = 0x70; 1424 regGpio[1] = 0x70;
1307 reg_w(gspca_dev, 0x01, regGpio, 2); 1425 reg_w(gspca_dev, 0x01, regGpio, 2);
1308 break; 1426 break;
@@ -1321,6 +1439,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
1321 sn9c1xx = sn_tb[sd->sensor]; 1439 sn9c1xx = sn_tb[sd->sensor];
1322 sd->i2c_addr = sn9c1xx[9]; 1440 sd->i2c_addr = sn9c1xx[9];
1323 1441
1442 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1443
1324 return 0; 1444 return 0;
1325} 1445}
1326 1446
@@ -1742,6 +1862,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1742 case SENSOR_OV7660: 1862 case SENSOR_OV7660:
1743 reg17 = 0xa0; 1863 reg17 = 0xa0;
1744 break; 1864 break;
1865 case SENSOR_PO1030:
1866 reg17 = 0xa0;
1867 break;
1745 default: 1868 default:
1746 reg17 = 0x60; 1869 reg17 = 0x60;
1747 break; 1870 break;
@@ -1839,6 +1962,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
1839 * inverse power down */ 1962 * inverse power down */
1840 } 1963 }
1841 break; 1964 break;
1965 case SENSOR_PO1030:
1966 init = po1030_sensor_param1;
1967 reg17 = 0xa2;
1968 reg1 = 0x44;
1969 break;
1842 default: 1970 default:
1843/* case SENSOR_SP80708: */ 1971/* case SENSOR_SP80708: */
1844 init = sp80708_sensor_param1; 1972 init = sp80708_sensor_param1;
@@ -1919,6 +2047,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1919 /* fall thru */ 2047 /* fall thru */
1920 case SENSOR_MT9V111: 2048 case SENSOR_MT9V111:
1921 case SENSOR_OV7630: 2049 case SENSOR_OV7630:
2050 case SENSOR_PO1030:
1922 data = 0x29; 2051 data = 0x29;
1923 break; 2052 break;
1924 } 2053 }
@@ -2325,7 +2454,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2325/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */ 2454/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
2326 {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/ 2455 {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
2327/*bw600.inf:*/ 2456/*bw600.inf:*/
2328 {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c110?*/ 2457 {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
2329 {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)}, 2458 {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
2330 {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)}, 2459 {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
2331/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */ 2460/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */