diff options
Diffstat (limited to 'sound/pci/ctxfi/xfi.c')
-rw-r--r-- | sound/pci/ctxfi/xfi.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c new file mode 100644 index 000000000000..76541748e7bc --- /dev/null +++ b/sound/pci/ctxfi/xfi.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * xfi linux driver. | ||
3 | * | ||
4 | * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. | ||
5 | * | ||
6 | * This source file is released under GPL v2 license (no other versions). | ||
7 | * See the COPYING file included in the main directory of this source | ||
8 | * distribution for the license terms and conditions. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/pci.h> | ||
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/pci_ids.h> | ||
15 | #include <sound/core.h> | ||
16 | #include <sound/initval.h> | ||
17 | #include "ctatc.h" | ||
18 | #include "cthardware.h" | ||
19 | |||
20 | MODULE_AUTHOR("Creative Technology Ltd"); | ||
21 | MODULE_DESCRIPTION("X-Fi driver version 1.03"); | ||
22 | MODULE_LICENSE("GPL v2"); | ||
23 | MODULE_SUPPORTED_DEVICE("{{Creative Labs, Sound Blaster X-Fi}"); | ||
24 | |||
25 | static unsigned int reference_rate = 48000; | ||
26 | static unsigned int multiple = 2; | ||
27 | MODULE_PARM_DESC(reference_rate, "Reference rate (default=48000)"); | ||
28 | module_param(reference_rate, uint, S_IRUGO); | ||
29 | MODULE_PARM_DESC(multiple, "Rate multiplier (default=2)"); | ||
30 | module_param(multiple, uint, S_IRUGO); | ||
31 | |||
32 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
33 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
34 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
35 | |||
36 | module_param_array(index, int, NULL, 0444); | ||
37 | MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver"); | ||
38 | module_param_array(id, charp, NULL, 0444); | ||
39 | MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver"); | ||
40 | module_param_array(enable, bool, NULL, 0444); | ||
41 | MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver"); | ||
42 | |||
43 | static struct pci_device_id ct_pci_dev_ids[] = { | ||
44 | /* only X-Fi is supported, so... */ | ||
45 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1), | ||
46 | .driver_data = ATC20K1, | ||
47 | }, | ||
48 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K2), | ||
49 | .driver_data = ATC20K2, | ||
50 | }, | ||
51 | { 0, } | ||
52 | }; | ||
53 | MODULE_DEVICE_TABLE(pci, ct_pci_dev_ids); | ||
54 | |||
55 | static int __devinit | ||
56 | ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | ||
57 | { | ||
58 | static int dev; | ||
59 | struct snd_card *card; | ||
60 | struct ct_atc *atc; | ||
61 | int err; | ||
62 | |||
63 | if (dev >= SNDRV_CARDS) | ||
64 | return -ENODEV; | ||
65 | |||
66 | if (!enable[dev]) { | ||
67 | dev++; | ||
68 | return -ENOENT; | ||
69 | } | ||
70 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); | ||
71 | if (err) | ||
72 | return err; | ||
73 | if ((reference_rate != 48000) && (reference_rate != 44100)) { | ||
74 | printk(KERN_ERR "ctxfi: Invalid reference_rate value %u!!!\n", | ||
75 | reference_rate); | ||
76 | printk(KERN_ERR "ctxfi: The valid values for reference_rate " | ||
77 | "are 48000 and 44100, Value 48000 is assumed.\n"); | ||
78 | reference_rate = 48000; | ||
79 | } | ||
80 | if ((multiple != 1) && (multiple != 2)) { | ||
81 | printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n", | ||
82 | multiple); | ||
83 | printk(KERN_ERR "ctxfi: The valid values for multiple are " | ||
84 | "1 and 2, Value 2 is assumed.\n"); | ||
85 | multiple = 2; | ||
86 | } | ||
87 | err = ct_atc_create(card, pci, reference_rate, multiple, | ||
88 | pci_id->driver_data, &atc); | ||
89 | if (err < 0) | ||
90 | goto error; | ||
91 | |||
92 | card->private_data = atc; | ||
93 | |||
94 | /* Create alsa devices supported by this card */ | ||
95 | err = ct_atc_create_alsa_devs(atc); | ||
96 | if (err < 0) | ||
97 | goto error; | ||
98 | |||
99 | strcpy(card->driver, "SB-XFi"); | ||
100 | strcpy(card->shortname, "Creative X-Fi"); | ||
101 | snprintf(card->longname, sizeof(card->longname), "%s %s %s", | ||
102 | card->shortname, atc->chip_name, atc->model_name); | ||
103 | |||
104 | err = snd_card_register(card); | ||
105 | if (err < 0) | ||
106 | goto error; | ||
107 | |||
108 | pci_set_drvdata(pci, card); | ||
109 | dev++; | ||
110 | |||
111 | return 0; | ||
112 | |||
113 | error: | ||
114 | snd_card_free(card); | ||
115 | return err; | ||
116 | } | ||
117 | |||
118 | static void __devexit ct_card_remove(struct pci_dev *pci) | ||
119 | { | ||
120 | snd_card_free(pci_get_drvdata(pci)); | ||
121 | pci_set_drvdata(pci, NULL); | ||
122 | } | ||
123 | |||
124 | #ifdef CONFIG_PM | ||
125 | static int ct_card_suspend(struct pci_dev *pci, pm_message_t state) | ||
126 | { | ||
127 | struct snd_card *card = pci_get_drvdata(pci); | ||
128 | struct ct_atc *atc = card->private_data; | ||
129 | |||
130 | return atc->suspend(atc, state); | ||
131 | } | ||
132 | |||
133 | static int ct_card_resume(struct pci_dev *pci) | ||
134 | { | ||
135 | struct snd_card *card = pci_get_drvdata(pci); | ||
136 | struct ct_atc *atc = card->private_data; | ||
137 | |||
138 | return atc->resume(atc); | ||
139 | } | ||
140 | #endif | ||
141 | |||
142 | static struct pci_driver ct_driver = { | ||
143 | .name = "SB-XFi", | ||
144 | .id_table = ct_pci_dev_ids, | ||
145 | .probe = ct_card_probe, | ||
146 | .remove = __devexit_p(ct_card_remove), | ||
147 | #ifdef CONFIG_PM | ||
148 | .suspend = ct_card_suspend, | ||
149 | .resume = ct_card_resume, | ||
150 | #endif | ||
151 | }; | ||
152 | |||
153 | static int __init ct_card_init(void) | ||
154 | { | ||
155 | return pci_register_driver(&ct_driver); | ||
156 | } | ||
157 | |||
158 | static void __exit ct_card_exit(void) | ||
159 | { | ||
160 | pci_unregister_driver(&ct_driver); | ||
161 | } | ||
162 | |||
163 | module_init(ct_card_init) | ||
164 | module_exit(ct_card_exit) | ||