diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2009-01-22 06:25:16 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:33 -0400 |
commit | 2d56f3bbe795b72207ec127cb3dc3b08bb4b8775 (patch) | |
tree | 8294109b89dacf831d55a5ad10a8d245e228ff03 /drivers/media/video/gspca/t613.c | |
parent | 82e2549102a11c6ffc09f960e2325fd092c002a3 (diff) |
V4L/DVB (10381): gspca - t613: New unknown sensor 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/t613.c')
-rw-r--r-- | drivers/media/video/gspca/t613.c | 178 |
1 files changed, 120 insertions, 58 deletions
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 8e89024b9135..a97920eb03f9 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c | |||
@@ -49,8 +49,9 @@ struct sd { | |||
49 | u8 effect; | 49 | u8 effect; |
50 | 50 | ||
51 | u8 sensor; | 51 | u8 sensor; |
52 | #define SENSOR_TAS5130A 0 | 52 | #define SENSOR_OM6802 0 |
53 | #define SENSOR_OM6802 1 | 53 | #define SENSOR_OTHER 1 |
54 | #define SENSOR_TAS5130A 2 | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | /* V4L2 controls supported by the driver */ | 57 | /* V4L2 controls supported by the driver */ |
@@ -272,6 +273,34 @@ struct additional_sensor_data { | |||
272 | }; | 273 | }; |
273 | 274 | ||
274 | const static struct additional_sensor_data sensor_data[] = { | 275 | const static struct additional_sensor_data sensor_data[] = { |
276 | { /* OM6802 */ | ||
277 | .data1 = | ||
278 | {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, | ||
279 | 0xb3, 0xfc}, | ||
280 | .data2 = | ||
281 | {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, | ||
282 | 0xff}, | ||
283 | .data4 = /*Freq (50/60Hz). Splitted for test purpose */ | ||
284 | {0x66, 0xca, 0xa8, 0xf0}, | ||
285 | .data5 = /* this could be removed later */ | ||
286 | {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, | ||
287 | .stream = | ||
288 | {0x0b, 0x04, 0x0a, 0x78}, | ||
289 | }, | ||
290 | { /* OTHER */ | ||
291 | .data1 = | ||
292 | {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a, | ||
293 | 0xe8, 0xfc}, | ||
294 | .data2 = | ||
295 | {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, | ||
296 | 0xd9}, | ||
297 | .data4 = | ||
298 | {0x66, 0x00, 0xa8, 0xa8}, | ||
299 | .data5 = | ||
300 | {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69}, | ||
301 | .stream = | ||
302 | {0x0b, 0x04, 0x0a, 0x00}, | ||
303 | }, | ||
275 | { /* TAS5130A */ | 304 | { /* TAS5130A */ |
276 | .data1 = | 305 | .data1 = |
277 | {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27, | 306 | {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27, |
@@ -286,20 +315,6 @@ const static struct additional_sensor_data sensor_data[] = { | |||
286 | .stream = | 315 | .stream = |
287 | {0x0b, 0x04, 0x0a, 0x40}, | 316 | {0x0b, 0x04, 0x0a, 0x40}, |
288 | }, | 317 | }, |
289 | { /* OM6802 */ | ||
290 | .data1 = | ||
291 | {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, | ||
292 | 0xb3, 0xfc}, | ||
293 | .data2 = | ||
294 | {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, | ||
295 | 0xff}, | ||
296 | .data4 = /*Freq (50/60Hz). Splitted for test purpose */ | ||
297 | {0x66, 0xca, 0xa8, 0xf0 }, | ||
298 | .data5 = /* this could be removed later */ | ||
299 | {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, | ||
300 | .stream = | ||
301 | {0x0b, 0x04, 0x0a, 0x78}, | ||
302 | } | ||
303 | }; | 318 | }; |
304 | 319 | ||
305 | #define MAX_EFFECTS 7 | 320 | #define MAX_EFFECTS 7 |
@@ -619,7 +634,9 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
619 | * to see the initial parameters.*/ | 634 | * to see the initial parameters.*/ |
620 | struct sd *sd = (struct sd *) gspca_dev; | 635 | struct sd *sd = (struct sd *) gspca_dev; |
621 | int i; | 636 | int i; |
622 | u8 byte, test_byte; | 637 | u16 sensor_id; |
638 | u8 test_byte; | ||
639 | u16 reg80, reg8e; | ||
623 | 640 | ||
624 | static const u8 read_indexs[] = | 641 | static const u8 read_indexs[] = |
625 | { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, | 642 | { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, |
@@ -628,8 +645,10 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
628 | {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; | 645 | {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; |
629 | static const u8 n2[] = | 646 | static const u8 n2[] = |
630 | {0x08, 0x00}; | 647 | {0x08, 0x00}; |
631 | static const u8 n3[] = | 648 | static const u8 n3[6] = |
632 | {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; | 649 | {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; |
650 | static const u8 n3_other[6] = | ||
651 | {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00}; | ||
633 | static const u8 n4[] = | 652 | static const u8 n4[] = |
634 | {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, | 653 | {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, |
635 | 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, | 654 | 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, |
@@ -640,40 +659,61 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
640 | 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, | 659 | 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, |
641 | 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, | 660 | 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, |
642 | 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; | 661 | 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; |
662 | static const u8 n4_other[] = | ||
663 | {0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69, | ||
664 | 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68, | ||
665 | 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8, | ||
666 | 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8, | ||
667 | 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56, | ||
668 | 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5, | ||
669 | 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0, | ||
670 | 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00}; | ||
643 | static const u8 nset8[6] = | 671 | static const u8 nset8[6] = |
644 | { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; | 672 | { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; |
673 | static const u8 nset8_other[6] = | ||
674 | { 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 }; | ||
645 | static const u8 nset9[4] = | 675 | static const u8 nset9[4] = |
646 | { 0x0b, 0x04, 0x0a, 0x78 }; | 676 | { 0x0b, 0x04, 0x0a, 0x78 }; |
677 | static const u8 nset9_other[4] = | ||
678 | { 0x0b, 0x04, 0x0a, 0x00 }; | ||
647 | 679 | ||
648 | byte = reg_r(gspca_dev, 0x06); | 680 | sensor_id = (reg_r(gspca_dev, 0x06) << 8) |
649 | test_byte = reg_r(gspca_dev, 0x07); | 681 | | reg_r(gspca_dev, 0x07); |
650 | if (byte == 0x08 && test_byte == 0x07) { | 682 | switch (sensor_id) { |
651 | PDEBUG(D_CONF, "sensor om6802"); | 683 | case 0x0801: |
652 | sd->sensor = SENSOR_OM6802; | ||
653 | } else if (byte == 0x08 && test_byte == 0x01) { | ||
654 | PDEBUG(D_CONF, "sensor tas5130a"); | 684 | PDEBUG(D_CONF, "sensor tas5130a"); |
655 | sd->sensor = SENSOR_TAS5130A; | 685 | sd->sensor = SENSOR_TAS5130A; |
656 | } else { | 686 | break; |
657 | PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte); | 687 | case 0x0803: |
658 | sd->sensor = SENSOR_TAS5130A; | 688 | PDEBUG(D_CONF, "sensor om6802"); |
689 | sd->sensor = SENSOR_OTHER; | ||
690 | break; | ||
691 | case 0x0807: | ||
692 | PDEBUG(D_CONF, "sensor om6802"); | ||
693 | sd->sensor = SENSOR_OM6802; | ||
694 | break; | ||
695 | default: | ||
696 | PDEBUG(D_CONF, "unknown sensor %04x", sensor_id); | ||
697 | return -1; | ||
659 | } | 698 | } |
660 | 699 | ||
661 | reg_w_buf(gspca_dev, n1, sizeof n1); | 700 | if (sd->sensor != SENSOR_OTHER) { |
662 | test_byte = 0; | 701 | reg_w_buf(gspca_dev, n1, sizeof n1); |
663 | i = 5; | 702 | i = 5; |
664 | while (--i >= 0) { | 703 | while (--i >= 0) { |
665 | reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); | 704 | reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); |
666 | test_byte = reg_r(gspca_dev, 0x0063); | 705 | test_byte = reg_r(gspca_dev, 0x0063); |
667 | msleep(100); | 706 | msleep(100); |
668 | if (test_byte == 0x17) | 707 | if (test_byte == 0x17) |
669 | break; /* OK */ | 708 | break; /* OK */ |
670 | } | 709 | } |
671 | if (i < 0) { | 710 | if (i < 0) { |
672 | err("Bad sensor reset %02x", test_byte); | 711 | err("Bad sensor reset %02x", test_byte); |
673 | /* return -EIO; */ | 712 | /* return -EIO; */ |
674 | /*fixme: test - continue */ | 713 | /*fixme: test - continue */ |
714 | } | ||
715 | reg_w_buf(gspca_dev, n2, sizeof n2); | ||
675 | } | 716 | } |
676 | reg_w_buf(gspca_dev, n2, sizeof n2); | ||
677 | 717 | ||
678 | i = 0; | 718 | i = 0; |
679 | while (read_indexs[i] != 0x00) { | 719 | while (read_indexs[i] != 0x00) { |
@@ -683,10 +723,20 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
683 | i++; | 723 | i++; |
684 | } | 724 | } |
685 | 725 | ||
686 | reg_w_buf(gspca_dev, n3, sizeof n3); | 726 | if (sd->sensor != SENSOR_OTHER) { |
687 | reg_w_buf(gspca_dev, n4, sizeof n4); | 727 | reg_w_buf(gspca_dev, n3, sizeof n3); |
688 | reg_r(gspca_dev, 0x0080); | 728 | reg_w_buf(gspca_dev, n4, sizeof n4); |
689 | reg_w(gspca_dev, 0x2c80); | 729 | reg_r(gspca_dev, 0x0080); |
730 | reg_w(gspca_dev, 0x2c80); | ||
731 | reg80 = 0x3880; | ||
732 | reg8e = 0x338e; | ||
733 | } else { | ||
734 | reg_w_buf(gspca_dev, n3_other, sizeof n3_other); | ||
735 | reg_w_buf(gspca_dev, n4_other, sizeof n4_other); | ||
736 | sd->gamma = 5; | ||
737 | reg80 = 0xac80; | ||
738 | reg8e = 0xb88e; | ||
739 | } | ||
690 | 740 | ||
691 | reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, | 741 | reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, |
692 | sizeof sensor_data[sd->sensor].data1); | 742 | sizeof sensor_data[sd->sensor].data1); |
@@ -695,9 +745,9 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
695 | reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2, | 745 | reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2, |
696 | sizeof sensor_data[sd->sensor].data2); | 746 | sizeof sensor_data[sd->sensor].data2); |
697 | 747 | ||
698 | reg_w(gspca_dev, 0x3880); | 748 | reg_w(gspca_dev, reg80); |
699 | reg_w(gspca_dev, 0x3880); | 749 | reg_w(gspca_dev, reg80); |
700 | reg_w(gspca_dev, 0x338e); | 750 | reg_w(gspca_dev, reg8e); |
701 | 751 | ||
702 | setbrightness(gspca_dev); | 752 | setbrightness(gspca_dev); |
703 | setcontrast(gspca_dev); | 753 | setcontrast(gspca_dev); |
@@ -714,10 +764,14 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
714 | sizeof sensor_data[sd->sensor].data4); | 764 | sizeof sensor_data[sd->sensor].data4); |
715 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5, | 765 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5, |
716 | sizeof sensor_data[sd->sensor].data5); | 766 | sizeof sensor_data[sd->sensor].data5); |
717 | reg_w_buf(gspca_dev, nset8, sizeof nset8); | 767 | if (sd->sensor != SENSOR_OTHER) { |
718 | reg_w_buf(gspca_dev, nset9, sizeof nset9); | 768 | reg_w_buf(gspca_dev, nset8, sizeof nset8); |
719 | 769 | reg_w_buf(gspca_dev, nset9, sizeof nset9); | |
720 | reg_w(gspca_dev, 0x2880); | 770 | reg_w(gspca_dev, 0x2880); |
771 | } else { | ||
772 | reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other); | ||
773 | reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other); | ||
774 | } | ||
721 | 775 | ||
722 | reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, | 776 | reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, |
723 | sizeof sensor_data[sd->sensor].data1); | 777 | sizeof sensor_data[sd->sensor].data1); |
@@ -790,7 +844,7 @@ static void poll_sensor(struct gspca_dev *gspca_dev) | |||
790 | 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, | 844 | 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, |
791 | 0xc2, 0x80, 0xc3, 0x10}; | 845 | 0xc2, 0x80, 0xc3, 0x10}; |
792 | 846 | ||
793 | if (sd->sensor != SENSOR_TAS5130A) { | 847 | if (sd->sensor == SENSOR_OM6802) { |
794 | PDEBUG(D_STREAM, "[Sensor requires polling]"); | 848 | PDEBUG(D_STREAM, "[Sensor requires polling]"); |
795 | reg_w_buf(gspca_dev, poll1, sizeof poll1); | 849 | reg_w_buf(gspca_dev, poll1, sizeof poll1); |
796 | reg_w_buf(gspca_dev, poll2, sizeof poll2); | 850 | reg_w_buf(gspca_dev, poll2, sizeof poll2); |
@@ -826,7 +880,14 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
826 | break; | 880 | break; |
827 | } | 881 | } |
828 | 882 | ||
829 | if (sd->sensor == SENSOR_TAS5130A) { | 883 | switch (sd->sensor) { |
884 | case SENSOR_OM6802: | ||
885 | om6802_sensor_init(gspca_dev); | ||
886 | break; | ||
887 | case SENSOR_OTHER: | ||
888 | break; | ||
889 | default: | ||
890 | /* case SENSOR_TAS5130A: */ | ||
830 | i = 0; | 891 | i = 0; |
831 | while (tas5130a_sensor_init[i][0] != 0) { | 892 | while (tas5130a_sensor_init[i][0] != 0) { |
832 | reg_w_buf(gspca_dev, tas5130a_sensor_init[i], | 893 | reg_w_buf(gspca_dev, tas5130a_sensor_init[i], |
@@ -838,8 +899,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
838 | reg_w_buf(gspca_dev, tas5130a_sensor_init[3], | 899 | reg_w_buf(gspca_dev, tas5130a_sensor_init[3], |
839 | sizeof tas5130a_sensor_init[0]); | 900 | sizeof tas5130a_sensor_init[0]); |
840 | reg_w(gspca_dev, 0x3c80); | 901 | reg_w(gspca_dev, 0x3c80); |
841 | } else { | 902 | break; |
842 | om6802_sensor_init(gspca_dev); | ||
843 | } | 903 | } |
844 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, | 904 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, |
845 | sizeof sensor_data[sd->sensor].data4); | 905 | sizeof sensor_data[sd->sensor].data4); |
@@ -869,8 +929,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
869 | msleep(20); | 929 | msleep(20); |
870 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, | 930 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, |
871 | sizeof sensor_data[sd->sensor].stream); | 931 | sizeof sensor_data[sd->sensor].stream); |
872 | msleep(20); | 932 | if (sd->sensor != SENSOR_OTHER) { |
873 | reg_w(gspca_dev, 0x0309); | 933 | msleep(20); |
934 | reg_w(gspca_dev, 0x0309); | ||
935 | } | ||
874 | } | 936 | } |
875 | 937 | ||
876 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 938 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |