+#define BT_DEVICE(chip, subvend, subdev, rate) \
+ { .vendor = PCI_VENDOR_ID_BROOKTREE, \
+ .device = PCI_DEVICE_ID_BROOKTREE_##chip, \
+ .subvendor = subvend, .subdevice = subdev, \
+ .driver_data = rate }
+
+/* driver_data is the default digital_rate value for that device */
+static struct pci_device_id snd_bt87x_ids[] = {
+ BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
+ BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
+ BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */
+ { }
+};
+MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
+
+/* cards known not to have audio
+ * (DVB cards use the audio function to transfer MPEG data) */
+static struct {
+ unsigned short subvendor, subdevice;
+} blacklist[] __devinitdata = {
+ {0x0071, 0x0101}, /* Nebula Electronics DigiTV */
+ {0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */
+ {0x1461, 0x0761}, /* AVermedia AverTV DVB-T */
+ {0x1461, 0x0771}, /* AVermedia DVB-T 771 */
+ {0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */
+ {0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */
+ {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */
+};
+
+/* return the rate of the card, or a negative value if it's blacklisted */
+static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
+{
+ int i;
+ const struct pci_device_id *supported;
+
+ supported = pci_match_device(snd_bt87x_ids, pci);
+ if (supported)
+ return supported->driver_data;
+
+ for (i = 0; i < ARRAY_SIZE(blacklist); ++i)
+ if (blacklist[i].subvendor == pci->subsystem_vendor &&
+ blacklist[i].subdevice == pci->subsystem_device) {
+ snd_printdd(KERN_INFO "card %#04x:%#04x has no audio\n",
+ pci->subsystem_vendor, pci->subsystem_device);
+ return -EBUSY;
+ }
+
+ snd_printk(KERN_INFO "unknown card %#04x:%#04x, using default rate 32000\n",
+ 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@lists.sf.net>\n");
+ return 32000; /* default rate */
+}
+