Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=dcfb4140328eed2d73797f278786eb99efd9f41c
Commit:     dcfb4140328eed2d73797f278786eb99efd9f41c
Parent:     6c041b5eae5a3e5c950c1d99f59d907c680922d2
Author:     Trent Piepho <[EMAIL PROTECTED]>
AuthorDate: Thu Sep 6 15:06:44 2007 +0200
Committer:  Jaroslav Kysela <[EMAIL PROTECTED]>
CommitDate: Tue Oct 16 16:49:11 2007 +0200

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: Takashi Iwai <[EMAIL PROTECTED]>
    Signed-off-by: Jaroslav Kysela <[EMAIL PROTECTED]>
---
 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 d87d6a3..10c8af1 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");
 /* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */
 #define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 
+ 1) * 8)
 
+/* Cards with configuration information */
+enum snd_bt87x_boardid {
+       SND_BT87X_BOARD_GENERIC,        /* both an & dig interfaces, 32kHz */
+       SND_BT87X_BOARD_ANALOG,         /* board with no external A/D */
+       SND_BT87X_BOARD_OSPREY2x0,
+       SND_BT87X_BOARD_OSPREY440,
+       SND_BT87X_BOARD_AVPHONE98,
+};
+
+/* Card configuration */
+struct snd_bt87x_board {
+       int dig_rate;           /* Digital input sampling rate */
+       u32 digital_fmt;        /* Register settings for digital input */
+       unsigned no_analog:1;   /* No analog input */
+       unsigned no_digital:1;  /* No digital input */
+};
+
+static const __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = {
+       [SND_BT87X_BOARD_GENERIC] = {
+               .dig_rate = 32000,
+       },
+       [SND_BT87X_BOARD_ANALOG] = {
+               .no_digital = 1,
+       },
+       [SND_BT87X_BOARD_OSPREY2x0] = {
+               .dig_rate = 44100,
+               .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT),
+       },
+       [SND_BT87X_BOARD_OSPREY440] = {
+               .dig_rate = 32000,
+               .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT),
+               .no_analog = 1,
+       },
+       [SND_BT87X_BOARD_AVPHONE98] = {
+               .dig_rate = 48000,
+       },
+};
+
 struct snd_bt87x {
        struct snd_card *card;
        struct pci_dev *pci;
+       struct snd_bt87x_board board;
 
        void __iomem *mmio;
        int irq;
 
-       int dig_rate;
-
        spinlock_t reg_lock;
        unsigned long opened;
        struct snd_pcm_substream *substream;
@@ -342,9 +379,9 @@ static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, 
struct snd_pcm_runti
 {
        chip->reg_control |= CTL_DA_IOM_DA;
        runtime->hw = snd_bt87x_digital_hw;
-       runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->dig_rate);
-       runtime->hw.rate_min = chip->dig_rate;
-       runtime->hw.rate_max = chip->dig_rate;
+       runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->board.dig_rate);
+       runtime->hw.rate_min = chip->board.dig_rate;
+       runtime->hw.rate_max = chip->board.dig_rate;
        return 0;
 }
 
@@ -709,9 +746,9 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
        chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
                                     pci_resource_len(pci, 0));
        if (!chip->mmio) {
-               snd_bt87x_free(chip);
                snd_printk(KERN_ERR "cannot remap io memory\n");
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto fail;
        }
 
        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,
        snd_bt87x_writel(chip, REG_INT_MASK, 0);
        snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
 
-       if (request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
-                       "Bt87x audio", chip)) {
-               snd_bt87x_free(chip);
-               snd_printk(KERN_ERR "cannot grab irq\n");
-               return -EBUSY;
+       err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
+                         "Bt87x audio", chip);
+       if (err < 0) {
+               snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
+               goto fail;
        }
        chip->irq = pci->irq;
        pci_set_master(pci);
        synchronize_irq(chip->irq);
 
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
-       if (err < 0) {
-               snd_bt87x_free(chip);
-               return err;
-       }
+       if (err < 0)
+               goto fail;
+
        snd_card_set_dev(card, &pci->dev);
        *rchip = chip;
        return 0;
+
+fail:
+       snd_bt87x_free(chip);
+       return err;
 }
 
-#define BT_DEVICE(chip, subvend, subdev, rate) \
+#define BT_DEVICE(chip, subvend, subdev, id) \
        { .vendor = PCI_VENDOR_ID_BROOKTREE, \
          .device = chip, \
          .subvendor = subvend, .subdevice = subdev, \
-         .driver_data = rate }
+         .driver_data = SND_BT87X_BOARD_ ## id }
+/* driver_data is the card id for that device */
 
-/* driver_data is the default digital_rate value for that device */
 static struct pci_device_id snd_bt87x_ids[] = {
        /* Hauppauge WinTV series */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC),
        /* Hauppauge WinTV series */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, GENERIC),
        /* Viewcast Osprey 200 */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, OSPREY2x0),
        /* Viewcast Osprey 440 (rate is configurable via gpio) */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, 32000),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, OSPREY440),
        /* ATI TV-Wonder */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, GENERIC),
        /* Leadtek Winfast tv 2000xp delux */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC),
        /* Voodoo TV 200 */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, 32000),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC),
        /* AVerMedia Studio No. 103, 203, ...? */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, AVPHONE98),
        /* Prolink PixelView PV-M4900 */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1554, 0x4011, 32000),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1554, 0x4011, GENERIC),
        /* Pinnacle  Studio PCTV rave */
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0xbd11, 0x1200, 32000),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0xbd11, 0x1200, GENERIC),
        { }
 };
 MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
@@ -792,7 +832,7 @@ static struct {
 
 static struct pci_driver driver;
 
-/* return the rate of the card, or a negative value if it's blacklisted */
+/* return the id of the card, or a negative value if it's blacklisted */
 static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
 {
        int i;
@@ -810,12 +850,12 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev 
*pci)
                        return -EBUSY;
                }
 
-       snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x, using default 
rate 32000\n",
-                  pci->device, pci->subsystem_vendor, pci->subsystem_device);
+       snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x\n",
+                  pci->device, pci->subsystem_vendor, pci->subsystem_device);
        snd_printk(KERN_DEBUG "please mail id, board name, and, "
                   "if it works, the correct digital_rate option to "
                   "<[EMAIL PROTECTED]>\n");
-       return 32000; /* default rate */
+       return SND_BT87X_BOARD_GENERIC;
 }
 
 static int __devinit snd_bt87x_probe(struct pci_dev *pci,
@@ -824,12 +864,16 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci,
        static int dev;
        struct snd_card *card;
        struct snd_bt87x *chip;
-       int err, rate;
+       int err;
+       enum snd_bt87x_boardid boardid;
 
-       rate = pci_id->driver_data;
-       if (! rate)
-               if ((rate = snd_bt87x_detect_card(pci)) <= 0)
+       if (!pci_id->driver_data) {
+               err = snd_bt87x_detect_card(pci);
+               if (err < 0)
                        return -ENODEV;
+               boardid = err;
+       } else
+               boardid = pci_id->driver_data;
 
        if (dev >= SNDRV_CARDS)
                return -ENODEV;
@@ -846,27 +890,39 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci,
        if (err < 0)
                goto _error;
 
-       if (digital_rate[dev] > 0)
-               chip->dig_rate = digital_rate[dev];
-       else
-               chip->dig_rate = rate;
+       memcpy(&chip->board, &snd_bt87x_boards[boardid], sizeof(chip->board));
 
-       err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
-       if (err < 0)
-               goto _error;
-       err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
-       if (err < 0)
-               goto _error;
+       if (!chip->board.no_digital) {
+               if (digital_rate[dev] > 0)
+                       chip->board.dig_rate = digital_rate[dev];
 
-       err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_volume, chip));
-       if (err < 0)
-               goto _error;
-       err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_boost, chip));
-       if (err < 0)
-               goto _error;
-       err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_source, chip));
-       if (err < 0)
-               goto _error;
+               chip->reg_control |= chip->board.digital_fmt;
+
+               err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
+               if (err < 0)
+                       goto _error;
+       }
+       if (!chip->board.no_analog) {
+               err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
+               if (err < 0)
+                       goto _error;
+               err = snd_ctl_add(card, snd_ctl_new1(
+                                 &snd_bt87x_capture_volume, chip));
+               if (err < 0)
+                       goto _error;
+               err = snd_ctl_add(card, snd_ctl_new1(
+                                 &snd_bt87x_capture_boost, chip));
+               if (err < 0)
+                       goto _error;
+               err = snd_ctl_add(card, snd_ctl_new1(
+                                 &snd_bt87x_capture_source, chip));
+               if (err < 0)
+                       goto _error;
+       }
+       snd_printk(KERN_INFO "bt87x%d: Using board %d, %sanalog, %sdigital "
+                  "(rate %d Hz)\n", dev, boardid,
+                  chip->board.no_analog ? "no " : "",
+                  chip->board.no_digital ? "no " : "", chip->board.dig_rate);
 
        strcpy(card->driver, "Bt87x");
        sprintf(card->shortname, "Brooktree Bt%x", pci->device);
@@ -897,8 +953,8 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci)
 /* default entries for all Bt87x cards - it's not exported */
 /* driver_data is set to 0 to call detection */
 static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = {
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, 0),
-       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, 0),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, GENERIC),
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, GENERIC),
        { }
 };
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to