diff options
author | Jean-François Moine <moinejf@free.fr> | 2010-04-25 13:45:43 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:58:15 -0400 |
commit | 03ed2a11eac62c15be28f58b182003fc56ca4f82 (patch) | |
tree | 325eefbc96b54bf4e853f864ac2712e97f4c0bf5 | |
parent | e3302cad9bc111e158e03eff763dff36bce02fe6 (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>
-rw-r--r-- | drivers/media/video/gspca/sonixj.c | 95 |
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 | ||
503 | static 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 | |||
498 | static const u8 sn_sp80708[0x1c] = { | 514 | static 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 | ||
1193 | static 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 | }; | ||
1202 | static 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 | |||
1176 | static const u8 sp80708_sensor_init[][8] = { | 1224 | static 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 | ||
1547 | static 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 | |||
1498 | static void ov7648_probe(struct gspca_dev *gspca_dev) | 1571 | static 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]); |