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