diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-cards.c | 238 |
1 files changed, 134 insertions, 104 deletions
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 387cb2122d4f..f6715007d409 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/vmalloc.h> | 34 | #include <linux/vmalloc.h> |
35 | #include <linux/firmware.h> | 35 | #include <linux/firmware.h> |
36 | #include <net/checksum.h> | ||
36 | 37 | ||
37 | #include <asm/io.h> | 38 | #include <asm/io.h> |
38 | 39 | ||
@@ -45,7 +46,7 @@ static void boot_msp34xx(struct bttv *btv, int pin); | |||
45 | static void boot_bt832(struct bttv *btv); | 46 | static void boot_bt832(struct bttv *btv); |
46 | static void hauppauge_eeprom(struct bttv *btv); | 47 | static void hauppauge_eeprom(struct bttv *btv); |
47 | static void avermedia_eeprom(struct bttv *btv); | 48 | static void avermedia_eeprom(struct bttv *btv); |
48 | static void osprey_eeprom(struct bttv *btv); | 49 | static void osprey_eeprom(struct bttv *btv, const u8 ee[256]); |
49 | static void modtec_eeprom(struct bttv *btv); | 50 | static void modtec_eeprom(struct bttv *btv); |
50 | static void init_PXC200(struct bttv *btv); | 51 | static void init_PXC200(struct bttv *btv); |
51 | static void init_RTV24(struct bttv *btv); | 52 | static void init_RTV24(struct bttv *btv); |
@@ -2843,13 +2844,28 @@ struct tvcard bttv_tvcards[] = { | |||
2843 | .has_remote = 1, | 2844 | .has_remote = 1, |
2844 | }, | 2845 | }, |
2845 | /* ---- card 0x8c ---------------------------------- */ | 2846 | /* ---- card 0x8c ---------------------------------- */ |
2847 | /* Has four Bt878 chips behind a PCI bridge, each chip has: | ||
2848 | one external BNC composite input (mux 2) | ||
2849 | three internal composite inputs (unknown muxes) | ||
2850 | an 18-bit stereo A/D (CS5331A), which has: | ||
2851 | one external stereo unblanced (RCA) audio connection | ||
2852 | one (or 3?) internal stereo balanced (XLR) audio connection | ||
2853 | input is selected via gpio to a 14052B mux | ||
2854 | (mask=0x300, unbal=0x000, bal=0x100, ??=0x200,0x300) | ||
2855 | gain is controlled via an X9221A chip on the I2C bus @0x28 | ||
2856 | sample rate is controlled via gpio to an MK1413S | ||
2857 | (mask=0x3, 32kHz=0x0, 44.1kHz=0x1, 48kHz=0x2, ??=0x3) | ||
2858 | There is neither a tuner nor an svideo input. */ | ||
2846 | [BTTV_BOARD_OSPREY440] = { | 2859 | [BTTV_BOARD_OSPREY440] = { |
2847 | .name = "Osprey 440", | 2860 | .name = "Osprey 440", |
2848 | .video_inputs = 1, | 2861 | .video_inputs = 4, |
2849 | .audio_inputs = 1, | 2862 | .audio_inputs = 2, /* this is meaningless */ |
2850 | .tuner = UNSET, | 2863 | .tuner = UNSET, |
2851 | .svhs = 1, | 2864 | .svhs = UNSET, |
2852 | .muxsel = { 2 }, | 2865 | .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */ |
2866 | .gpiomask = 0x303, | ||
2867 | .gpiomute = 0x000, /* int + 32kHz */ | ||
2868 | .gpiomux = { 0, 0, 0x000, 0x100}, | ||
2853 | .pll = PLL_28, | 2869 | .pll = PLL_28, |
2854 | .tuner_type = UNSET, | 2870 | .tuner_type = UNSET, |
2855 | .tuner_addr = ADDR_UNSET, | 2871 | .tuner_addr = ADDR_UNSET, |
@@ -3453,11 +3469,12 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3453 | case BTTV_BOARD_OSPREY2xx: | 3469 | case BTTV_BOARD_OSPREY2xx: |
3454 | case BTTV_BOARD_OSPREY2x0_SVID: | 3470 | case BTTV_BOARD_OSPREY2x0_SVID: |
3455 | case BTTV_BOARD_OSPREY2x0: | 3471 | case BTTV_BOARD_OSPREY2x0: |
3472 | case BTTV_BOARD_OSPREY440: | ||
3456 | case BTTV_BOARD_OSPREY500: | 3473 | case BTTV_BOARD_OSPREY500: |
3457 | case BTTV_BOARD_OSPREY540: | 3474 | case BTTV_BOARD_OSPREY540: |
3458 | case BTTV_BOARD_OSPREY2000: | 3475 | case BTTV_BOARD_OSPREY2000: |
3459 | bttv_readee(btv,eeprom_data,0xa0); | 3476 | bttv_readee(btv,eeprom_data,0xa0); |
3460 | osprey_eeprom(btv); | 3477 | osprey_eeprom(btv, eeprom_data); |
3461 | break; | 3478 | break; |
3462 | case BTTV_BOARD_IDS_EAGLE: | 3479 | case BTTV_BOARD_IDS_EAGLE: |
3463 | init_ids_eagle(btv); | 3480 | init_ids_eagle(btv); |
@@ -3748,106 +3765,119 @@ static int __devinit pvr_boot(struct bttv *btv) | |||
3748 | /* ----------------------------------------------------------------------- */ | 3765 | /* ----------------------------------------------------------------------- */ |
3749 | /* some osprey specific stuff */ | 3766 | /* some osprey specific stuff */ |
3750 | 3767 | ||
3751 | static void __devinit osprey_eeprom(struct bttv *btv) | 3768 | static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256]) |
3752 | { | 3769 | { |
3753 | int i = 0; | 3770 | int i; |
3754 | unsigned char *ee = eeprom_data; | 3771 | u32 serial = 0; |
3755 | unsigned long serial = 0; | 3772 | int cardid = -1; |
3756 | 3773 | ||
3757 | if (btv->c.type == 0) { | 3774 | /* This code will nevery actually get called in this case.... */ |
3758 | /* this might be an antique... check for MMAC label in eeprom */ | 3775 | if (btv->c.type == BTTV_BOARD_UNKNOWN) { |
3759 | if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { | 3776 | /* this might be an antique... check for MMAC label in eeprom */ |
3760 | unsigned char checksum = 0; | 3777 | if (!strncmp(ee, "MMAC", 4)) { |
3761 | for (i = 0; i < 21; i++) | 3778 | u8 checksum = 0; |
3762 | checksum += ee[i]; | 3779 | for (i = 0; i < 21; i++) |
3763 | if (checksum != ee[21]) | 3780 | checksum += ee[i]; |
3764 | return; | 3781 | if (checksum != ee[21]) |
3765 | btv->c.type = BTTV_BOARD_OSPREY1x0_848; | 3782 | return; |
3766 | for (i = 12; i < 21; i++) | 3783 | cardid = BTTV_BOARD_OSPREY1x0_848; |
3767 | serial *= 10, serial += ee[i] - '0'; | 3784 | for (i = 12; i < 21; i++) |
3768 | } | 3785 | serial *= 10, serial += ee[i] - '0'; |
3786 | } | ||
3769 | } else { | 3787 | } else { |
3770 | unsigned short type; | 3788 | unsigned short type; |
3771 | int offset = 4*16; | 3789 | |
3772 | 3790 | for (i = 4*16; i < 8*16; i += 16) { | |
3773 | for (; offset < 8*16; offset += 16) { | 3791 | u16 checksum = ip_compute_csum(ee + i, 16); |
3774 | unsigned short checksum = 0; | 3792 | |
3775 | /* verify the checksum */ | 3793 | if ((checksum&0xff) + (checksum>>8) == 0xff) |
3776 | for (i = 0; i < 14; i++) | 3794 | break; |
3777 | checksum += ee[i+offset]; | 3795 | } |
3778 | checksum = ~checksum; /* no idea why */ | 3796 | if (i >= 8*16) |
3779 | if ((((checksum>>8)&0x0FF) == ee[offset+14]) && | 3797 | return; |
3780 | ((checksum & 0x0FF) == ee[offset+15])) { | 3798 | ee += i; |
3781 | break; | 3799 | |
3782 | } | 3800 | /* found a valid descriptor */ |
3783 | } | 3801 | type = be16_to_cpup((u16*)(ee+4)); |
3784 | 3802 | ||
3785 | if (offset >= 8*16) | 3803 | switch(type) { |
3786 | return; | 3804 | /* 848 based */ |
3787 | 3805 | case 0x0004: | |
3788 | /* found a valid descriptor */ | 3806 | cardid = BTTV_BOARD_OSPREY1x0_848; |
3789 | type = (ee[offset+4]<<8) | (ee[offset+5]); | 3807 | break; |
3790 | 3808 | case 0x0005: | |
3791 | switch(type) { | 3809 | cardid = BTTV_BOARD_OSPREY101_848; |
3792 | /* 848 based */ | 3810 | break; |
3793 | case 0x0004: | 3811 | |
3794 | btv->c.type = BTTV_BOARD_OSPREY1x0_848; | 3812 | /* 878 based */ |
3795 | break; | 3813 | case 0x0012: |
3796 | case 0x0005: | 3814 | case 0x0013: |
3797 | btv->c.type = BTTV_BOARD_OSPREY101_848; | 3815 | cardid = BTTV_BOARD_OSPREY1x0; |
3798 | break; | 3816 | break; |
3799 | 3817 | case 0x0014: | |
3800 | /* 878 based */ | 3818 | case 0x0015: |
3801 | case 0x0012: | 3819 | cardid = BTTV_BOARD_OSPREY1x1; |
3802 | case 0x0013: | 3820 | break; |
3803 | btv->c.type = BTTV_BOARD_OSPREY1x0; | 3821 | case 0x0016: |
3804 | break; | 3822 | case 0x0017: |
3805 | case 0x0014: | 3823 | case 0x0020: |
3806 | case 0x0015: | 3824 | cardid = BTTV_BOARD_OSPREY1x1_SVID; |
3807 | btv->c.type = BTTV_BOARD_OSPREY1x1; | 3825 | break; |
3808 | break; | 3826 | case 0x0018: |
3809 | case 0x0016: | 3827 | case 0x0019: |
3810 | case 0x0017: | 3828 | case 0x001E: |
3811 | case 0x0020: | 3829 | case 0x001F: |
3812 | btv->c.type = BTTV_BOARD_OSPREY1x1_SVID; | 3830 | cardid = BTTV_BOARD_OSPREY2xx; |
3813 | break; | 3831 | break; |
3814 | case 0x0018: | 3832 | case 0x001A: |
3815 | case 0x0019: | 3833 | case 0x001B: |
3816 | case 0x001E: | 3834 | cardid = BTTV_BOARD_OSPREY2x0_SVID; |
3817 | case 0x001F: | 3835 | break; |
3818 | btv->c.type = BTTV_BOARD_OSPREY2xx; | 3836 | case 0x0040: |
3819 | break; | 3837 | cardid = BTTV_BOARD_OSPREY500; |
3820 | case 0x001A: | 3838 | break; |
3821 | case 0x001B: | 3839 | case 0x0050: |
3822 | btv->c.type = BTTV_BOARD_OSPREY2x0_SVID; | 3840 | case 0x0056: |
3823 | break; | 3841 | cardid = BTTV_BOARD_OSPREY540; |
3824 | case 0x0040: | 3842 | /* bttv_osprey_540_init(btv); */ |
3825 | btv->c.type = BTTV_BOARD_OSPREY500; | 3843 | break; |
3826 | break; | 3844 | case 0x0060: |
3827 | case 0x0050: | 3845 | case 0x0070: |
3828 | case 0x0056: | 3846 | case 0x00A0: |
3829 | btv->c.type = BTTV_BOARD_OSPREY540; | 3847 | cardid = BTTV_BOARD_OSPREY2x0; |
3830 | /* bttv_osprey_540_init(btv); */ | 3848 | /* enable output on select control lines */ |
3831 | break; | 3849 | gpio_inout(0xffffff,0x000303); |
3832 | case 0x0060: | 3850 | break; |
3833 | case 0x0070: | 3851 | case 0x00D8: |
3834 | case 0x00A0: | 3852 | cardid = BTTV_BOARD_OSPREY440; |
3835 | btv->c.type = BTTV_BOARD_OSPREY2x0; | 3853 | break; |
3836 | /* enable output on select control lines */ | 3854 | default: |
3837 | gpio_inout(0xffffff,0x000303); | 3855 | /* unknown...leave generic, but get serial # */ |
3838 | break; | 3856 | printk(KERN_INFO "bttv%d: " |
3839 | default: | 3857 | "osprey eeprom: unknown card type 0x%04x\n", |
3840 | /* unknown...leave generic, but get serial # */ | 3858 | btv->c.nr, type); |
3841 | break; | 3859 | break; |
3842 | } | 3860 | } |
3843 | serial = (ee[offset+6] << 24) | 3861 | serial = be32_to_cpup((u32*)(ee+6)); |
3844 | | (ee[offset+7] << 16) | 3862 | } |
3845 | | (ee[offset+8] << 8) | 3863 | |
3846 | | (ee[offset+9]); | 3864 | printk(KERN_INFO "bttv%d: osprey eeprom: card=%d '%s' serial=%u\n", |
3847 | } | 3865 | btv->c.nr, cardid, |
3848 | 3866 | cardid>0 ? bttv_tvcards[cardid].name : "Unknown", serial); | |
3849 | printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n", | 3867 | |
3850 | btv->c.nr, btv->c.type, bttv_tvcards[btv->c.type].name,serial); | 3868 | if (cardid<0 || btv->c.type == cardid) |
3869 | return; | ||
3870 | |||
3871 | /* card type isn't set correctly */ | ||
3872 | if (card[btv->c.nr] < bttv_num_tvcards) { | ||
3873 | printk(KERN_WARNING "bttv%d: osprey eeprom: " | ||
3874 | "Not overriding user specified card type\n", btv->c.nr); | ||
3875 | } else { | ||
3876 | printk(KERN_INFO "bttv%d: osprey eeprom: " | ||
3877 | "Changing card type from %d to %d\n", btv->c.nr, | ||
3878 | btv->c.type, cardid); | ||
3879 | btv->c.type = cardid; | ||
3880 | } | ||
3851 | } | 3881 | } |
3852 | 3882 | ||
3853 | /* ----------------------------------------------------------------------- */ | 3883 | /* ----------------------------------------------------------------------- */ |