|
@@ -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 "
|
|
|
"<alsa-devel@alsa-project.org>\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),
|
|
|
{ }
|
|
|
};
|
|
|
|