^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * C-Media CMI8788 driver for Asus Xonar cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xonar.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) MODULE_DESCRIPTION("Asus Virtuoso driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) MODULE_SUPPORTED_DEVICE("{{Asus,AV66},{Asus,AV100},{Asus,AV200}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) MODULE_PARM_DESC(index, "card index");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) MODULE_PARM_DESC(id, "ID string");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) MODULE_PARM_DESC(enable, "enable card");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static const struct pci_device_id xonar_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) { OXYGEN_PCI_SUBID(0x1043, 0x8269) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) { OXYGEN_PCI_SUBID(0x1043, 0x8275) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) { OXYGEN_PCI_SUBID(0x1043, 0x82b7) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) { OXYGEN_PCI_SUBID(0x1043, 0x8314) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) { OXYGEN_PCI_SUBID(0x1043, 0x8327) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) { OXYGEN_PCI_SUBID(0x1043, 0x834f) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) { OXYGEN_PCI_SUBID(0x1043, 0x835c) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) { OXYGEN_PCI_SUBID(0x1043, 0x835d) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) { OXYGEN_PCI_SUBID(0x1043, 0x835e) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) { OXYGEN_PCI_SUBID(0x1043, 0x838e) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) { OXYGEN_PCI_SUBID(0x1043, 0x8428) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) { OXYGEN_PCI_SUBID(0x1043, 0x8522) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) { OXYGEN_PCI_SUBID(0x1043, 0x85f4) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) MODULE_DEVICE_TABLE(pci, xonar_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int get_xonar_model(struct oxygen *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (get_xonar_pcm179x_model(chip, id) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (get_xonar_cs43xx_model(chip, id) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (get_xonar_wm87x6_model(chip, id) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int xonar_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ++dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) xonar_ids, get_xonar_model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ++dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static struct pci_driver xonar_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .id_table = xonar_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .probe = xonar_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .remove = oxygen_pci_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .pm = &oxygen_pci_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .shutdown = oxygen_pci_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) module_pci_driver(xonar_driver);