aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sonixj.c
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2010-04-25 13:45:43 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-19 11:58:15 -0400
commit03ed2a11eac62c15be28f58b182003fc56ca4f82 (patch)
tree325eefbc96b54bf4e853f864ac2712e97f4c0bf5 /drivers/media/video/gspca/sonixj.c
parente3302cad9bc111e158e03eff763dff36bce02fe6 (diff)
V4L/DVB: gspca - sonixj: Add sensor soi768
The webcams 0c45:613e may contain the sensors ov7630 or soi768. A sensor probe is done at init time when the sensor is declared ov7630. Signed-off-by: Jean-François 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.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 19ae4f5ca73c..bb923efb75bd 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -80,6 +80,7 @@ enum {
80 SENSOR_OV7660, 80 SENSOR_OV7660,
81 SENSOR_PO1030, 81 SENSOR_PO1030,
82 SENSOR_PO2030N, 82 SENSOR_PO2030N,
83 SENSOR_SOI768,
83 SENSOR_SP80708, 84 SENSOR_SP80708,
84} sensors; 85} sensors;
85 u8 i2c_addr; 86 u8 i2c_addr;
@@ -330,6 +331,10 @@ static const __u32 ctrl_dis[] = {
330 (1 << INFRARED_IDX) | 331 (1 << INFRARED_IDX) |
331 (1 << VFLIP_IDX) | 332 (1 << VFLIP_IDX) |
332 (1 << FREQ_IDX), 333 (1 << FREQ_IDX),
334[SENSOR_SOI768] = (1 << AUTOGAIN_IDX) |
335 (1 << INFRARED_IDX) |
336 (1 << VFLIP_IDX) |
337 (1 << FREQ_IDX),
333 338
334[SENSOR_SP80708] = (1 << AUTOGAIN_IDX) | 339[SENSOR_SP80708] = (1 << AUTOGAIN_IDX) |
335 (1 << INFRARED_IDX) | 340 (1 << INFRARED_IDX) |
@@ -495,6 +500,17 @@ static const u8 sn_po2030n[0x1c] = {
495 0x07, 0x00, 0x00, 0x00 500 0x07, 0x00, 0x00, 0x00
496}; 501};
497 502
503static const u8 sn_soi768[0x1c] = {
504/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
505 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
506/* reg8 reg9 rega regb regc regd rege regf */
507 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
509 0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00,
510/* reg18 reg19 reg1a reg1b */
511 0x07, 0x00, 0x00, 0x00
512};
513
498static const u8 sn_sp80708[0x1c] = { 514static const u8 sn_sp80708[0x1c] = {
499/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 515/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
500 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, 516 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
@@ -520,7 +536,8 @@ static const u8 *sn_tb[] = {
520[SENSOR_OV7660] = sn_ov7660, 536[SENSOR_OV7660] = sn_ov7660,
521[SENSOR_PO1030] = sn_po1030, 537[SENSOR_PO1030] = sn_po1030,
522[SENSOR_PO2030N] = sn_po2030n, 538[SENSOR_PO2030N] = sn_po2030n,
523[SENSOR_SP80708] = sn_sp80708 539[SENSOR_SOI768] = sn_soi768,
540[SENSOR_SP80708] = sn_sp80708,
524}; 541};
525 542
526/* default gamma table */ 543/* default gamma table */
@@ -1173,6 +1190,37 @@ static const u8 po2030n_sensor_param1[][8] = {
1173 {} 1190 {}
1174}; 1191};
1175 1192
1193static const u8 soi768_sensor_init[][8] = {
1194 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1195 {0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
1196 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1197 {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1198 {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1199 {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1200 {}
1201};
1202static const u8 soi768_sensor_param1[][8] = {
1203 {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1204 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1205 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1206 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1207 {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1208/* */
1209/* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1210/* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1211 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1212/* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1213 {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1214/* the next sequence should be used for auto gain */
1215 {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1216 /* global gain ? : 07 - change with 0x15 at the end */
1217 {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1218 {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1219 {0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10},
1220 /* exposure ? : 0200 - change with 0x1e at the end */
1221 {}
1222};
1223
1176static const u8 sp80708_sensor_init[][8] = { 1224static const u8 sp80708_sensor_init[][8] = {
1177 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, 1225 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1178 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, 1226 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
@@ -1271,6 +1319,7 @@ static const u8 (*sensor_init[])[8] = {
1271[SENSOR_OV7660] = ov7660_sensor_init, 1319[SENSOR_OV7660] = ov7660_sensor_init,
1272[SENSOR_PO1030] = po1030_sensor_init, 1320[SENSOR_PO1030] = po1030_sensor_init,
1273[SENSOR_PO2030N] = po2030n_sensor_init, 1321[SENSOR_PO2030N] = po2030n_sensor_init,
1322[SENSOR_SOI768] = soi768_sensor_init,
1274[SENSOR_SP80708] = sp80708_sensor_init, 1323[SENSOR_SP80708] = sp80708_sensor_init,
1275}; 1324};
1276 1325
@@ -1495,6 +1544,30 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
1495 } 1544 }
1496} 1545}
1497 1546
1547static void ov7630_probe(struct gspca_dev *gspca_dev)
1548{
1549 struct sd *sd = (struct sd *) gspca_dev;
1550 u16 val;
1551
1552 /* check ov76xx */
1553 reg_w1(gspca_dev, 0x17, 0x62);
1554 reg_w1(gspca_dev, 0x01, 0x08);
1555 sd->i2c_addr = 0x21;
1556 i2c_r(gspca_dev, 0x0a, 2);
1557 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1558 reg_w1(gspca_dev, 0x01, 0x29);
1559 reg_w1(gspca_dev, 0x17, 0x42);
1560 if (val == 0x7628) { /* soi768 */
1561 sd->sensor = SENSOR_SOI768;
1562/*fixme: only valid for 0c45:613e?*/
1563 gspca_dev->cam.input_flags =
1564 V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1565 PDEBUG(D_PROBE, "Sensor soi768");
1566 return;
1567 }
1568 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1569}
1570
1498static void ov7648_probe(struct gspca_dev *gspca_dev) 1571static void ov7648_probe(struct gspca_dev *gspca_dev)
1499{ 1572{
1500 struct sd *sd = (struct sd *) gspca_dev; 1573 struct sd *sd = (struct sd *) gspca_dev;
@@ -1591,6 +1664,7 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1591 case SENSOR_OV7660: 1664 case SENSOR_OV7660:
1592 case SENSOR_PO1030: 1665 case SENSOR_PO1030:
1593 case SENSOR_PO2030N: 1666 case SENSOR_PO2030N:
1667 case SENSOR_SOI768:
1594 case SENSOR_SP80708: 1668 case SENSOR_SP80708:
1595 reg9a = reg9a_spec; 1669 reg9a = reg9a_spec;
1596 break; 1670 break;
@@ -1656,6 +1730,7 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1656 reg_w1(gspca_dev, 0x01, 0x42); 1730 reg_w1(gspca_dev, 0x01, 0x42);
1657 break; 1731 break;
1658 case SENSOR_PO1030: 1732 case SENSOR_PO1030:
1733 case SENSOR_SOI768:
1659 reg_w1(gspca_dev, 0x01, 0x61); 1734 reg_w1(gspca_dev, 0x01, 0x61);
1660 reg_w1(gspca_dev, 0x17, 0x20); 1735 reg_w1(gspca_dev, 0x17, 0x20);
1661 reg_w1(gspca_dev, 0x01, 0x60); 1736 reg_w1(gspca_dev, 0x01, 0x60);
@@ -1771,6 +1846,9 @@ static int sd_init(struct gspca_dev *gspca_dev)
1771 case SENSOR_MI0360: 1846 case SENSOR_MI0360:
1772 mi0360_probe(gspca_dev); 1847 mi0360_probe(gspca_dev);
1773 break; 1848 break;
1849 case SENSOR_OV7630:
1850 ov7630_probe(gspca_dev);
1851 break;
1774 case SENSOR_OV7648: 1852 case SENSOR_OV7648:
1775 ov7648_probe(gspca_dev); 1853 ov7648_probe(gspca_dev);
1776 break; 1854 break;
@@ -2280,6 +2358,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2280 reg17 = 0x20; 2358 reg17 = 0x20;
2281 break; 2359 break;
2282 case SENSOR_OV7660: 2360 case SENSOR_OV7660:
2361 case SENSOR_SOI768:
2283 reg17 = 0xa0; 2362 reg17 = 0xa0;
2284 break; 2363 break;
2285 case SENSOR_PO1030: 2364 case SENSOR_PO1030:
@@ -2317,6 +2396,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2317 reg_w1(gspca_dev, 0x9a, 0x0a); 2396 reg_w1(gspca_dev, 0x9a, 0x0a);
2318 break; 2397 break;
2319 case SENSOR_PO2030N: 2398 case SENSOR_PO2030N:
2399 case SENSOR_SOI768:
2320 reg_w1(gspca_dev, 0x9a, 0x06); 2400 reg_w1(gspca_dev, 0x9a, 0x06);
2321 break; 2401 break;
2322 default: 2402 default:
@@ -2403,6 +2483,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
2403 reg1 = 0x46; 2483 reg1 = 0x46;
2404 reg17 = 0xa2; 2484 reg17 = 0xa2;
2405 break; 2485 break;
2486 case SENSOR_SOI768:
2487 init = soi768_sensor_param1;
2488 reg1 = 0x44;
2489 reg17 = 0xa2;
2490 break;
2406 default: 2491 default:
2407/* case SENSOR_SP80708: */ 2492/* case SENSOR_SP80708: */
2408 init = sp80708_sensor_param1; 2493 init = sp80708_sensor_param1;
@@ -2425,6 +2510,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2425 switch (sd->sensor) { 2510 switch (sd->sensor) {
2426 case SENSOR_ADCM1700: 2511 case SENSOR_ADCM1700:
2427 case SENSOR_GC0307: 2512 case SENSOR_GC0307:
2513 case SENSOR_SOI768:
2428 reg_w(gspca_dev, 0xca, CA_adcm1700, 4); 2514 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2429 break; 2515 break;
2430 case SENSOR_PO2030N: 2516 case SENSOR_PO2030N:
@@ -2439,6 +2525,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2439 case SENSOR_OV7630: 2525 case SENSOR_OV7630:
2440 case SENSOR_OV7648: 2526 case SENSOR_OV7648:
2441 case SENSOR_OV7660: 2527 case SENSOR_OV7660:
2528 case SENSOR_SOI768:
2442 reg_w(gspca_dev, 0xce, CE_ov76xx, 4); 2529 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
2443 break; 2530 break;
2444 case SENSOR_GC0307: 2531 case SENSOR_GC0307:
@@ -2480,6 +2567,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2480 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; 2567 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
2481 static const u8 stopov7648[] = 2568 static const u8 stopov7648[] =
2482 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; 2569 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
2570 static const u8 stopsoi768[] =
2571 { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
2483 u8 data; 2572 u8 data;
2484 const u8 *sn9c1xx; 2573 const u8 *sn9c1xx;
2485 2574
@@ -2504,6 +2593,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2504 case SENSOR_PO1030: 2593 case SENSOR_PO1030:
2505 data = 0x29; 2594 data = 0x29;
2506 break; 2595 break;
2596 case SENSOR_SOI768:
2597 i2c_w8(gspca_dev, stopsoi768);
2598 data = 0x29;
2599 break;
2507 } 2600 }
2508 sn9c1xx = sn_tb[sd->sensor]; 2601 sn9c1xx = sn_tb[sd->sensor];
2509 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 2602 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);