diff options
-rw-r--r-- | sound/pci/bt87x.c | 172 |
1 files changed, 114 insertions, 58 deletions
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index d87d6a3298ae..10c8af1b736b 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -147,15 +147,52 @@ MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards"); | |||
147 | /* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */ | 147 | /* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */ |
148 | #define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 + 1) * 8) | 148 | #define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 + 1) * 8) |
149 | 149 | ||
150 | /* Cards with configuration information */ | ||
151 | enum snd_bt87x_boardid { | ||
152 | SND_BT87X_BOARD_GENERIC, /* both an & dig interfaces, 32kHz */ | ||
153 | SND_BT87X_BOARD_ANALOG, /* board with no external A/D */ | ||
154 | SND_BT87X_BOARD_OSPREY2x0, | ||
155 | SND_BT87X_BOARD_OSPREY440, | ||
156 | SND_BT87X_BOARD_AVPHONE98, | ||
157 | }; | ||
158 | |||
159 | /* Card configuration */ | ||
160 | struct snd_bt87x_board { | ||
161 | int dig_rate; /* Digital input sampling rate */ | ||
162 | u32 digital_fmt; /* Register settings for digital input */ | ||
163 | unsigned no_analog:1; /* No analog input */ | ||
164 | unsigned no_digital:1; /* No digital input */ | ||
165 | }; | ||
166 | |||
167 | static const __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = { | ||
168 | [SND_BT87X_BOARD_GENERIC] = { | ||
169 | .dig_rate = 32000, | ||
170 | }, | ||
171 | [SND_BT87X_BOARD_ANALOG] = { | ||
172 | .no_digital = 1, | ||
173 | }, | ||
174 | [SND_BT87X_BOARD_OSPREY2x0] = { | ||
175 | .dig_rate = 44100, | ||
176 | .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT), | ||
177 | }, | ||
178 | [SND_BT87X_BOARD_OSPREY440] = { | ||
179 | .dig_rate = 32000, | ||
180 | .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT), | ||
181 | .no_analog = 1, | ||
182 | }, | ||
183 | [SND_BT87X_BOARD_AVPHONE98] = { | ||
184 | .dig_rate = 48000, | ||
185 | }, | ||
186 | }; | ||
187 | |||
150 | struct snd_bt87x { | 188 | struct snd_bt87x { |
151 | struct snd_card *card; | 189 | struct snd_card *card; |
152 | struct pci_dev *pci; | 190 | struct pci_dev *pci; |
191 | struct snd_bt87x_board board; | ||
153 | 192 | ||
154 | void __iomem *mmio; | 193 | void __iomem *mmio; |
155 | int irq; | 194 | int irq; |
156 | 195 | ||
157 | int dig_rate; | ||
158 | |||
159 | spinlock_t reg_lock; | 196 | spinlock_t reg_lock; |
160 | unsigned long opened; | 197 | unsigned long opened; |
161 | struct snd_pcm_substream *substream; | 198 | struct snd_pcm_substream *substream; |
@@ -342,9 +379,9 @@ static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runti | |||
342 | { | 379 | { |
343 | chip->reg_control |= CTL_DA_IOM_DA; | 380 | chip->reg_control |= CTL_DA_IOM_DA; |
344 | runtime->hw = snd_bt87x_digital_hw; | 381 | runtime->hw = snd_bt87x_digital_hw; |
345 | runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->dig_rate); | 382 | runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->board.dig_rate); |
346 | runtime->hw.rate_min = chip->dig_rate; | 383 | runtime->hw.rate_min = chip->board.dig_rate; |
347 | runtime->hw.rate_max = chip->dig_rate; | 384 | runtime->hw.rate_max = chip->board.dig_rate; |
348 | return 0; | 385 | return 0; |
349 | } | 386 | } |
350 | 387 | ||
@@ -709,9 +746,9 @@ static int __devinit snd_bt87x_create(struct snd_card *card, | |||
709 | chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), | 746 | chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), |
710 | pci_resource_len(pci, 0)); | 747 | pci_resource_len(pci, 0)); |
711 | if (!chip->mmio) { | 748 | if (!chip->mmio) { |
712 | snd_bt87x_free(chip); | ||
713 | snd_printk(KERN_ERR "cannot remap io memory\n"); | 749 | snd_printk(KERN_ERR "cannot remap io memory\n"); |
714 | return -ENOMEM; | 750 | err = -ENOMEM; |
751 | goto fail; | ||
715 | } | 752 | } |
716 | 753 | ||
717 | chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT); | 754 | chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT); |
@@ -720,54 +757,57 @@ static int __devinit snd_bt87x_create(struct snd_card *card, | |||
720 | snd_bt87x_writel(chip, REG_INT_MASK, 0); | 757 | snd_bt87x_writel(chip, REG_INT_MASK, 0); |
721 | snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS); | 758 | snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS); |
722 | 759 | ||
723 | if (request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED, | 760 | err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED, |
724 | "Bt87x audio", chip)) { | 761 | "Bt87x audio", chip); |
725 | snd_bt87x_free(chip); | 762 | if (err < 0) { |
726 | snd_printk(KERN_ERR "cannot grab irq\n"); | 763 | snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq); |
727 | return -EBUSY; | 764 | goto fail; |
728 | } | 765 | } |
729 | chip->irq = pci->irq; | 766 | chip->irq = pci->irq; |
730 | pci_set_master(pci); | 767 | pci_set_master(pci); |
731 | synchronize_irq(chip->irq); | 768 | synchronize_irq(chip->irq); |
732 | 769 | ||
733 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); | 770 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); |
734 | if (err < 0) { | 771 | if (err < 0) |
735 | snd_bt87x_free(chip); | 772 | goto fail; |
736 | return err; | 773 | |
737 | } | ||
738 | snd_card_set_dev(card, &pci->dev); | 774 | snd_card_set_dev(card, &pci->dev); |
739 | *rchip = chip; | 775 | *rchip = chip; |
740 | return 0; | 776 | return 0; |
777 | |||
778 | fail: | ||
779 | snd_bt87x_free(chip); | ||
780 | return err; | ||
741 | } | 781 | } |
742 | 782 | ||
743 | #define BT_DEVICE(chip, subvend, subdev, rate) \ | 783 | #define BT_DEVICE(chip, subvend, subdev, id) \ |
744 | { .vendor = PCI_VENDOR_ID_BROOKTREE, \ | 784 | { .vendor = PCI_VENDOR_ID_BROOKTREE, \ |
745 | .device = chip, \ | 785 | .device = chip, \ |
746 | .subvendor = subvend, .subdevice = subdev, \ | 786 | .subvendor = subvend, .subdevice = subdev, \ |
747 | .driver_data = rate } | 787 | .driver_data = SND_BT87X_BOARD_ ## id } |
788 | /* driver_data is the card id for that device */ | ||
748 | 789 | ||
749 | /* driver_data is the default digital_rate value for that device */ | ||
750 | static struct pci_device_id snd_bt87x_ids[] = { | 790 | static struct pci_device_id snd_bt87x_ids[] = { |
751 | /* Hauppauge WinTV series */ | 791 | /* Hauppauge WinTV series */ |
752 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000), | 792 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC), |
753 | /* Hauppauge WinTV series */ | 793 | /* Hauppauge WinTV series */ |
754 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), | 794 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, GENERIC), |
755 | /* Viewcast Osprey 200 */ | 795 | /* Viewcast Osprey 200 */ |
756 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), | 796 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, OSPREY2x0), |
757 | /* Viewcast Osprey 440 (rate is configurable via gpio) */ | 797 | /* Viewcast Osprey 440 (rate is configurable via gpio) */ |
758 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, 32000), | 798 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, OSPREY440), |
759 | /* ATI TV-Wonder */ | 799 | /* ATI TV-Wonder */ |
760 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000), | 800 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, GENERIC), |
761 | /* Leadtek Winfast tv 2000xp delux */ | 801 | /* Leadtek Winfast tv 2000xp delux */ |
762 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), | 802 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC), |
763 | /* Voodoo TV 200 */ | 803 | /* Voodoo TV 200 */ |
764 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, 32000), | 804 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC), |
765 | /* AVerMedia Studio No. 103, 203, ...? */ | 805 | /* AVerMedia Studio No. 103, 203, ...? */ |
766 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000), | 806 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, AVPHONE98), |
767 | /* Prolink PixelView PV-M4900 */ | 807 | /* Prolink PixelView PV-M4900 */ |
768 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1554, 0x4011, 32000), | 808 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1554, 0x4011, GENERIC), |
769 | /* Pinnacle Studio PCTV rave */ | 809 | /* Pinnacle Studio PCTV rave */ |
770 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0xbd11, 0x1200, 32000), | 810 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0xbd11, 0x1200, GENERIC), |
771 | { } | 811 | { } |
772 | }; | 812 | }; |
773 | MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); | 813 | MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); |
@@ -792,7 +832,7 @@ static struct { | |||
792 | 832 | ||
793 | static struct pci_driver driver; | 833 | static struct pci_driver driver; |
794 | 834 | ||
795 | /* return the rate of the card, or a negative value if it's blacklisted */ | 835 | /* return the id of the card, or a negative value if it's blacklisted */ |
796 | static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) | 836 | static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) |
797 | { | 837 | { |
798 | int i; | 838 | int i; |
@@ -810,12 +850,12 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) | |||
810 | return -EBUSY; | 850 | return -EBUSY; |
811 | } | 851 | } |
812 | 852 | ||
813 | snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x, using default rate 32000\n", | 853 | snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x\n", |
814 | pci->device, pci->subsystem_vendor, pci->subsystem_device); | 854 | pci->device, pci->subsystem_vendor, pci->subsystem_device); |
815 | snd_printk(KERN_DEBUG "please mail id, board name, and, " | 855 | snd_printk(KERN_DEBUG "please mail id, board name, and, " |
816 | "if it works, the correct digital_rate option to " | 856 | "if it works, the correct digital_rate option to " |
817 | "<alsa-devel@alsa-project.org>\n"); | 857 | "<alsa-devel@alsa-project.org>\n"); |
818 | return 32000; /* default rate */ | 858 | return SND_BT87X_BOARD_GENERIC; |
819 | } | 859 | } |
820 | 860 | ||
821 | static int __devinit snd_bt87x_probe(struct pci_dev *pci, | 861 | static int __devinit snd_bt87x_probe(struct pci_dev *pci, |
@@ -824,12 +864,16 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci, | |||
824 | static int dev; | 864 | static int dev; |
825 | struct snd_card *card; | 865 | struct snd_card *card; |
826 | struct snd_bt87x *chip; | 866 | struct snd_bt87x *chip; |
827 | int err, rate; | 867 | int err; |
868 | enum snd_bt87x_boardid boardid; | ||
828 | 869 | ||
829 | rate = pci_id->driver_data; | 870 | if (!pci_id->driver_data) { |
830 | if (! rate) | 871 | err = snd_bt87x_detect_card(pci); |
831 | if ((rate = snd_bt87x_detect_card(pci)) <= 0) | 872 | if (err < 0) |
832 | return -ENODEV; | 873 | return -ENODEV; |
874 | boardid = err; | ||
875 | } else | ||
876 | boardid = pci_id->driver_data; | ||
833 | 877 | ||
834 | if (dev >= SNDRV_CARDS) | 878 | if (dev >= SNDRV_CARDS) |
835 | return -ENODEV; | 879 | return -ENODEV; |
@@ -846,27 +890,39 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci, | |||
846 | if (err < 0) | 890 | if (err < 0) |
847 | goto _error; | 891 | goto _error; |
848 | 892 | ||
849 | if (digital_rate[dev] > 0) | 893 | memcpy(&chip->board, &snd_bt87x_boards[boardid], sizeof(chip->board)); |
850 | chip->dig_rate = digital_rate[dev]; | ||
851 | else | ||
852 | chip->dig_rate = rate; | ||
853 | 894 | ||
854 | err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital"); | 895 | if (!chip->board.no_digital) { |
855 | if (err < 0) | 896 | if (digital_rate[dev] > 0) |
856 | goto _error; | 897 | chip->board.dig_rate = digital_rate[dev]; |
857 | err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog"); | ||
858 | if (err < 0) | ||
859 | goto _error; | ||
860 | 898 | ||
861 | err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_volume, chip)); | 899 | chip->reg_control |= chip->board.digital_fmt; |
862 | if (err < 0) | 900 | |
863 | goto _error; | 901 | err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital"); |
864 | err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_boost, chip)); | 902 | if (err < 0) |
865 | if (err < 0) | 903 | goto _error; |
866 | goto _error; | 904 | } |
867 | err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_source, chip)); | 905 | if (!chip->board.no_analog) { |
868 | if (err < 0) | 906 | err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog"); |
869 | goto _error; | 907 | if (err < 0) |
908 | goto _error; | ||
909 | err = snd_ctl_add(card, snd_ctl_new1( | ||
910 | &snd_bt87x_capture_volume, chip)); | ||
911 | if (err < 0) | ||
912 | goto _error; | ||
913 | err = snd_ctl_add(card, snd_ctl_new1( | ||
914 | &snd_bt87x_capture_boost, chip)); | ||
915 | if (err < 0) | ||
916 | goto _error; | ||
917 | err = snd_ctl_add(card, snd_ctl_new1( | ||
918 | &snd_bt87x_capture_source, chip)); | ||
919 | if (err < 0) | ||
920 | goto _error; | ||
921 | } | ||
922 | snd_printk(KERN_INFO "bt87x%d: Using board %d, %sanalog, %sdigital " | ||
923 | "(rate %d Hz)\n", dev, boardid, | ||
924 | chip->board.no_analog ? "no " : "", | ||
925 | chip->board.no_digital ? "no " : "", chip->board.dig_rate); | ||
870 | 926 | ||
871 | strcpy(card->driver, "Bt87x"); | 927 | strcpy(card->driver, "Bt87x"); |
872 | sprintf(card->shortname, "Brooktree Bt%x", pci->device); | 928 | sprintf(card->shortname, "Brooktree Bt%x", pci->device); |
@@ -897,8 +953,8 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci) | |||
897 | /* default entries for all Bt87x cards - it's not exported */ | 953 | /* default entries for all Bt87x cards - it's not exported */ |
898 | /* driver_data is set to 0 to call detection */ | 954 | /* driver_data is set to 0 to call detection */ |
899 | static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = { | 955 | static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = { |
900 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, 0), | 956 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, GENERIC), |
901 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, 0), | 957 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, GENERIC), |
902 | { } | 958 | { } |
903 | }; | 959 | }; |
904 | 960 | ||