aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrent Piepho <xyzzy@speakeasy.org>2007-09-06 09:06:44 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 10:49:11 -0400
commitdcfb4140328eed2d73797f278786eb99efd9f41c (patch)
treee2642e1fa7ebfb2cd31cae174182d77526f74973
parent6c041b5eae5a3e5c950c1d99f59d907c680922d2 (diff)
[ALSA] snd-bt87x: Improve support for different board types
Different cards have different audio configurations, but the driver didn't support this. The only setting it had was the digital rate. This patch adds a board configuration list. Currently, configurable items are the digital rate and the digital data format (for cards with an external ADC), a flag for the absence of an external ADC, and a flag for no connection to the Bt87x internal ADC. This allows cards that don't use the internal ADC to omit the ALSA 'Bt87x analog' device and related controls. Cards without an external ADC can omit the 'Bt87x digital' device. In order to support the CS5331A ADC used on the Osprey 440 and 2x0 cards, the digital format needs to be different than the default. Support could be added for defining: The connections or lack of them to the Bt87x's internal ADC mux Multiple sample rates for an external ADC (e.g. Osprey) Control of an external mux for an external ADC (e.g. Osprey) The card definitions for cards other than the Ospreys are kept equivalent to their old values. This is likely inaccurate for most cards, as it is doubtful that both an external and the internal ADC would be used. Lacking information on those cards, the behavior is left unchanged. Signed-off-by: Trent Piepho <xyzzy@speakeasy.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r--sound/pci/bt87x.c172
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 */
151enum 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 */
160struct 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
167static 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
150struct snd_bt87x { 188struct 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
778fail:
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 */
750static struct pci_device_id snd_bt87x_ids[] = { 790static 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};
773MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); 813MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
@@ -792,7 +832,7 @@ static struct {
792 832
793static struct pci_driver driver; 833static 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 */
796static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) 836static 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
821static int __devinit snd_bt87x_probe(struct pci_dev *pci, 861static 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 */
899static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = { 955static 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