1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "au88x0.h"
19#include <linux/init.h>
20#include <linux/pci.h>
21#include <linux/slab.h>
22#include <linux/interrupt.h>
23#include <linux/module.h>
24#include <linux/dma-mapping.h>
25#include <sound/initval.h>
26
27
28static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
29static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
30static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
31static int pcifix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 255 };
32
33module_param_array(index, int, NULL, 0444);
34MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
35module_param_array(id, charp, NULL, 0444);
36MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
37module_param_array(enable, bool, NULL, 0444);
38MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
39module_param_array(pcifix, int, NULL, 0444);
40MODULE_PARM_DESC(pcifix, "Enable VIA-workaround for " CARD_NAME " soundcard.");
41
42MODULE_DESCRIPTION("Aureal vortex");
43MODULE_LICENSE("GPL");
44MODULE_DEVICE_TABLE(pci, snd_vortex_ids);
45
46static void vortex_fix_latency(struct pci_dev *vortex)
47{
48 int rc;
49 rc = pci_write_config_byte(vortex, 0x40, 0xff);
50 if (!rc) {
51 dev_info(&vortex->dev, "vortex latency is 0xff\n");
52 } else {
53 dev_warn(&vortex->dev,
54 "could not set vortex latency: pci error 0x%x\n", rc);
55 }
56}
57
58static void vortex_fix_agp_bridge(struct pci_dev *via)
59{
60 int rc;
61 u8 value;
62
63
64
65
66
67
68
69 rc = pci_read_config_byte(via, 0x42, &value);
70 if (!rc) {
71 if (!(value & 0x10))
72 rc = pci_write_config_byte(via, 0x42, value | 0x10);
73 }
74 if (!rc) {
75 dev_info(&via->dev, "bridge config is 0x%x\n", value | 0x10);
76 } else {
77 dev_warn(&via->dev,
78 "could not set vortex latency: pci error 0x%x\n", rc);
79 }
80}
81
82static void snd_vortex_workaround(struct pci_dev *vortex, int fix)
83{
84 struct pci_dev *via = NULL;
85
86
87 if (fix == 255) {
88
89 via = pci_get_device(PCI_VENDOR_ID_VIA,
90 PCI_DEVICE_ID_VIA_8365_1, NULL);
91
92 if (via == NULL) {
93 via = pci_get_device(PCI_VENDOR_ID_VIA,
94 PCI_DEVICE_ID_VIA_82C598_1, NULL);
95
96 if (via == NULL)
97 via = pci_get_device(PCI_VENDOR_ID_AMD,
98 PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
99 }
100 if (via) {
101 dev_info(&vortex->dev,
102 "Activating latency workaround...\n");
103 vortex_fix_latency(vortex);
104 vortex_fix_agp_bridge(via);
105 }
106 } else {
107 if (fix & 0x1)
108 vortex_fix_latency(vortex);
109 if (fix & 0x2)
110 via = pci_get_device(PCI_VENDOR_ID_VIA,
111 PCI_DEVICE_ID_VIA_8365_1, NULL);
112 else if (fix & 0x4)
113 via = pci_get_device(PCI_VENDOR_ID_VIA,
114 PCI_DEVICE_ID_VIA_82C598_1, NULL);
115 else if (fix & 0x8)
116 via = pci_get_device(PCI_VENDOR_ID_AMD,
117 PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
118 if (via)
119 vortex_fix_agp_bridge(via);
120 }
121 pci_dev_put(via);
122}
123
124
125
126static int snd_vortex_dev_free(struct snd_device *device)
127{
128 vortex_t *vortex = device->device_data;
129
130 vortex_gameport_unregister(vortex);
131 vortex_core_shutdown(vortex);
132
133 free_irq(vortex->irq, vortex);
134 iounmap(vortex->mmio);
135 pci_release_regions(vortex->pci_dev);
136 pci_disable_device(vortex->pci_dev);
137 kfree(vortex);
138
139 return 0;
140}
141
142
143
144static int
145snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
146{
147 vortex_t *chip;
148 int err;
149 static const struct snd_device_ops ops = {
150 .dev_free = snd_vortex_dev_free,
151 };
152
153 *rchip = NULL;
154
155
156 err = pci_enable_device(pci);
157 if (err < 0)
158 return err;
159 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) {
160 dev_err(card->dev, "error to set DMA mask\n");
161 pci_disable_device(pci);
162 return -ENXIO;
163 }
164
165 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
166 if (chip == NULL) {
167 pci_disable_device(pci);
168 return -ENOMEM;
169 }
170
171 chip->card = card;
172
173
174 chip->pci_dev = pci;
175 chip->io = pci_resource_start(pci, 0);
176 chip->vendor = pci->vendor;
177 chip->device = pci->device;
178 chip->card = card;
179 chip->irq = -1;
180
181
182
183
184 err = pci_request_regions(pci, CARD_NAME_SHORT);
185 if (err)
186 goto regions_out;
187
188 chip->mmio = pci_ioremap_bar(pci, 0);
189 if (!chip->mmio) {
190 dev_err(card->dev, "MMIO area remap failed.\n");
191 err = -ENOMEM;
192 goto ioremap_out;
193 }
194
195
196
197
198 err = vortex_core_init(chip);
199 if (err) {
200 dev_err(card->dev, "hw core init failed\n");
201 goto core_out;
202 }
203
204 err = request_irq(pci->irq, vortex_interrupt,
205 IRQF_SHARED, KBUILD_MODNAME, chip);
206 if (err) {
207 dev_err(card->dev, "cannot grab irq\n");
208 goto irq_out;
209 }
210 chip->irq = pci->irq;
211 card->sync_irq = chip->irq;
212
213 pci_set_master(pci);
214
215
216
217 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
218 if (err < 0)
219 goto alloc_out;
220
221 *rchip = chip;
222
223 return 0;
224
225 alloc_out:
226 free_irq(chip->irq, chip);
227 irq_out:
228 vortex_core_shutdown(chip);
229 core_out:
230 iounmap(chip->mmio);
231 ioremap_out:
232 pci_release_regions(chip->pci_dev);
233 regions_out:
234 pci_disable_device(chip->pci_dev);
235
236 vortex_gameport_unregister(chip);
237 kfree(chip);
238 return err;
239}
240
241
242static int
243snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
244{
245 static int dev;
246 struct snd_card *card;
247 vortex_t *chip;
248 int err;
249
250
251 if (dev >= SNDRV_CARDS)
252 return -ENODEV;
253 if (!enable[dev]) {
254 dev++;
255 return -ENOENT;
256 }
257
258 err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
259 0, &card);
260 if (err < 0)
261 return err;
262
263
264 err = snd_vortex_create(card, pci, &chip);
265 if (err < 0) {
266 snd_card_free(card);
267 return err;
268 }
269 snd_vortex_workaround(pci, pcifix[dev]);
270
271
272 strcpy(card->driver, CARD_NAME_SHORT);
273 sprintf(card->shortname, "Aureal Vortex %s", CARD_NAME_SHORT);
274 sprintf(card->longname, "%s at 0x%lx irq %i",
275 card->shortname, chip->io, chip->irq);
276
277
278 err = snd_vortex_mixer(chip);
279 if (err < 0) {
280 snd_card_free(card);
281 return err;
282 }
283
284 err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_PCM);
285 if (err < 0) {
286 snd_card_free(card);
287 return err;
288 }
289#ifndef CHIP_AU8820
290
291 err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1);
292 if (err < 0) {
293 snd_card_free(card);
294 return err;
295 }
296
297 err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D);
298 if (err < 0) {
299 snd_card_free(card);
300 return err;
301 }
302#endif
303
304
305
306
307
308
309
310#ifndef CHIP_AU8810
311
312 err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT);
313 if (err < 0) {
314 snd_card_free(card);
315 return err;
316 }
317#endif
318 err = snd_vortex_midi(chip);
319 if (err < 0) {
320 snd_card_free(card);
321 return err;
322 }
323
324 vortex_gameport_register(chip);
325
326#if 0
327 if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH,
328 sizeof(snd_vortex_synth_arg_t), &wave) < 0
329 || wave == NULL) {
330 dev_err(card->dev, "Can't initialize Aureal wavetable synth\n");
331 } else {
332 snd_vortex_synth_arg_t *arg;
333
334 arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
335 strcpy(wave->name, "Aureal Synth");
336 arg->hwptr = vortex;
337 arg->index = 1;
338 arg->seq_ports = seq_ports[dev];
339 arg->max_voices = max_synth_voices[dev];
340 }
341#endif
342
343
344 err = pci_read_config_word(pci, PCI_DEVICE_ID, &chip->device);
345 if (err < 0) {
346 snd_card_free(card);
347 return err;
348 }
349 err = pci_read_config_word(pci, PCI_VENDOR_ID, &chip->vendor);
350 if (err < 0) {
351 snd_card_free(card);
352 return err;
353 }
354 chip->rev = pci->revision;
355#ifdef CHIP_AU8830
356 if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) {
357 dev_alert(card->dev,
358 "The revision (%x) of your card has not been seen before.\n",
359 chip->rev);
360 dev_alert(card->dev,
361 "Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n");
362 snd_card_free(card);
363 err = -ENODEV;
364 return err;
365 }
366#endif
367
368
369 err = snd_card_register(card);
370 if (err < 0) {
371 snd_card_free(card);
372 return err;
373 }
374
375 pci_set_drvdata(pci, card);
376 dev++;
377 vortex_connect_default(chip, 1);
378 vortex_enable_int(chip);
379 return 0;
380}
381
382
383static void snd_vortex_remove(struct pci_dev *pci)
384{
385 snd_card_free(pci_get_drvdata(pci));
386}
387
388
389static struct pci_driver vortex_driver = {
390 .name = KBUILD_MODNAME,
391 .id_table = snd_vortex_ids,
392 .probe = snd_vortex_probe,
393 .remove = snd_vortex_remove,
394};
395
396module_pci_driver(vortex_driver);
397