1 /* 2 * ALSA driver for the Aureal Vortex family of soundprocessors. 3 * Author: Manuel Jander (mjander@embedded.cl) 4 * 5 * This driver is the result of the OpenVortex Project from Savannah 6 * (savannah.nongnu.org/projects/openvortex). I would like to thank 7 * the developers of OpenVortex, Jeff Muizelaar and Kester Maddock, from 8 * whom i got plenty of help, and their codebase was invaluable. 9 * Thanks to the ALSA developers, they helped a lot working out 10 * the ALSA part. 11 * Thanks also to Sourceforge for maintaining the old binary drivers, 12 * and the forum, where developers could comunicate. 13 * 14 * Now at least i can play Legacy DOOM with MIDI music :-) 15 */ 16 17 #include "au88x0.h" 18 #include <linux/init.h> 19 #include <linux/pci.h> 20 #include <linux/slab.h> 21 #include <linux/interrupt.h> 22 #include <linux/moduleparam.h> 23 #include <sound/initval.h> 24 25 // module parameters (see "Module Parameters") 26 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 27 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 28 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 29 static int pcifix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 255 }; 30 31 module_param_array(index, int, NULL, 0444); 32 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); 33 module_param_array(id, charp, NULL, 0444); 34 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); 35 module_param_array(enable, bool, NULL, 0444); 36 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); 37 module_param_array(pcifix, int, NULL, 0444); 38 MODULE_PARM_DESC(pcifix, "Enable VIA-workaround for " CARD_NAME " soundcard."); 39 40 MODULE_DESCRIPTION("Aureal vortex"); 41 MODULE_LICENSE("GPL"); 42 MODULE_SUPPORTED_DEVICE("{{Aureal Semiconductor Inc., Aureal Vortex Sound Processor}}"); 43 44 MODULE_DEVICE_TABLE(pci, snd_vortex_ids); 45 46 static void vortex_fix_latency(struct pci_dev *vortex) 47 { 48 int rc; 49 if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) { 50 printk(KERN_INFO CARD_NAME 51 ": vortex latency is 0xff\n"); 52 } else { 53 printk(KERN_WARNING CARD_NAME 54 ": could not set vortex latency: pci error 0x%x\n", rc); 55 } 56 } 57 58 static void vortex_fix_agp_bridge(struct pci_dev *via) 59 { 60 int rc; 61 u8 value; 62 63 /* 64 * only set the bit (Extend PCI#2 Internal Master for 65 * Efficient Handling of Dummy Requests) if the can 66 * read the config and it is not already set 67 */ 68 69 if (!(rc = pci_read_config_byte(via, 0x42, &value)) 70 && ((value & 0x10) 71 || !(rc = pci_write_config_byte(via, 0x42, value | 0x10)))) { 72 printk(KERN_INFO CARD_NAME 73 ": bridge config is 0x%x\n", value | 0x10); 74 } else { 75 printk(KERN_WARNING CARD_NAME 76 ": could not set vortex latency: pci error 0x%x\n", rc); 77 } 78 } 79 80 static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix) 81 { 82 struct pci_dev *via; 83 84 /* autodetect if workarounds are required */ 85 if (fix == 255) { 86 /* VIA KT133 */ 87 via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL); 88 /* VIA Apollo */ 89 if (via == NULL) { 90 via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL); 91 } 92 /* AMD Irongate */ 93 if (via == NULL) { 94 via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL); 95 } 96 if (via) { 97 printk(KERN_INFO CARD_NAME ": Activating latency workaround...\n"); 98 vortex_fix_latency(vortex); 99 vortex_fix_agp_bridge(via); 100 } 101 } else { 102 if (fix & 0x1) 103 vortex_fix_latency(vortex); 104 if ((fix & 0x2) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL))) 105 vortex_fix_agp_bridge(via); 106 if ((fix & 0x4) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL))) 107 vortex_fix_agp_bridge(via); 108 if ((fix & 0x8) && (via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL))) 109 vortex_fix_agp_bridge(via); 110 } 111 } 112 113 // component-destructor 114 // (see "Management of Cards and Components") 115 static int snd_vortex_dev_free(snd_device_t * device) 116 { 117 vortex_t *vortex = device->device_data; 118 119 vortex_gameport_unregister(vortex); 120 vortex_core_shutdown(vortex); 121 // Take down PCI interface. 122 synchronize_irq(vortex->irq); 123 free_irq(vortex->irq, vortex); 124 pci_release_regions(vortex->pci_dev); 125 pci_disable_device(vortex->pci_dev); 126 kfree(vortex); 127 128 return 0; 129 } 130 131 // chip-specific constructor 132 // (see "Management of Cards and Components") 133 static int __devinit 134 snd_vortex_create(snd_card_t * card, struct pci_dev *pci, vortex_t ** rchip) 135 { 136 vortex_t *chip; 137 int err; 138 static snd_device_ops_t ops = { 139 .dev_free = snd_vortex_dev_free, 140 }; 141 142 *rchip = NULL; 143 144 // check PCI availability (DMA). 145 if ((err = pci_enable_device(pci)) < 0) 146 return err; 147 if (!pci_dma_supported(pci, VORTEX_DMA_MASK)) { 148 printk(KERN_ERR "error to set DMA mask\n"); 149 return -ENXIO; 150 } 151 pci_set_dma_mask(pci, VORTEX_DMA_MASK); 152 153 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); 154 if (chip == NULL) 155 return -ENOMEM; 156 157 chip->card = card; 158 159 // initialize the stuff 160 chip->pci_dev = pci; 161 chip->io = pci_resource_start(pci, 0); 162 chip->vendor = pci->vendor; 163 chip->device = pci->device; 164 chip->card = card; 165 chip->irq = -1; 166 167 // (1) PCI resource allocation 168 // Get MMIO area 169 // 170 if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0) 171 goto regions_out; 172 173 chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), 174 pci_resource_len(pci, 0)); 175 if (!chip->mmio) { 176 printk(KERN_ERR "MMIO area remap failed.\n"); 177 err = -ENOMEM; 178 goto ioremap_out; 179 } 180 181 /* Init audio core. 182 * This must be done before we do request_irq otherwise we can get spurious 183 * interupts that we do not handle properly and make a mess of things */ 184 if ((err = vortex_core_init(chip)) != 0) { 185 printk(KERN_ERR "hw core init failed\n"); 186 goto core_out; 187 } 188 189 if ((err = request_irq(pci->irq, vortex_interrupt, 190 SA_INTERRUPT | SA_SHIRQ, CARD_NAME_SHORT, 191 chip)) != 0) { 192 printk(KERN_ERR "cannot grab irq\n"); 193 goto irq_out; 194 } 195 chip->irq = pci->irq; 196 197 pci_set_master(pci); 198 // End of PCI setup. 199 200 // Register alsa root device. 201 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 202 goto alloc_out; 203 } 204 205 *rchip = chip; 206 207 return 0; 208 209 alloc_out: 210 synchronize_irq(chip->irq); 211 free_irq(chip->irq, chip); 212 irq_out: 213 vortex_core_shutdown(chip); 214 core_out: 215 iounmap(chip->mmio); 216 ioremap_out: 217 pci_release_regions(chip->pci_dev); 218 regions_out: 219 pci_disable_device(chip->pci_dev); 220 //FIXME: this not the right place to unregister the gameport 221 vortex_gameport_unregister(chip); 222 return err; 223 } 224 225 // constructor -- see "Constructor" sub-section 226 static int __devinit 227 snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) 228 { 229 static int dev; 230 snd_card_t *card; 231 vortex_t *chip; 232 int err; 233 234 // (1) 235 if (dev >= SNDRV_CARDS) 236 return -ENODEV; 237 if (!enable[dev]) { 238 dev++; 239 return -ENOENT; 240 } 241 // (2) 242 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); 243 if (card == NULL) 244 return -ENOMEM; 245 246 // (3) 247 if ((err = snd_vortex_create(card, pci, &chip)) < 0) { 248 snd_card_free(card); 249 return err; 250 } 251 snd_vortex_workaround(pci, pcifix[dev]); 252 // (4) Alloc components. 253 // ADB pcm. 254 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_ADB)) < 0) { 255 snd_card_free(card); 256 return err; 257 } 258 #ifndef CHIP_AU8820 259 // ADB SPDIF 260 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1)) < 0) { 261 snd_card_free(card); 262 return err; 263 } 264 // A3D 265 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D)) < 0) { 266 snd_card_free(card); 267 return err; 268 } 269 #endif 270 /* 271 // ADB I2S 272 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_I2S, 1)) < 0) { 273 snd_card_free(card); 274 return err; 275 } 276 */ 277 #ifndef CHIP_AU8810 278 // WT pcm. 279 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT)) < 0) { 280 snd_card_free(card); 281 return err; 282 } 283 #endif 284 // snd_ac97_mixer and Vortex mixer. 285 if ((err = snd_vortex_mixer(chip)) < 0) { 286 snd_card_free(card); 287 return err; 288 } 289 if ((err = snd_vortex_midi(chip)) < 0) { 290 snd_card_free(card); 291 return err; 292 } 293 294 vortex_gameport_register(chip); 295 296 #if 0 297 if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH, 298 sizeof(snd_vortex_synth_arg_t), &wave) < 0 299 || wave == NULL) { 300 snd_printk("Can't initialize Aureal wavetable synth\n"); 301 } else { 302 snd_vortex_synth_arg_t *arg; 303 304 arg = SNDRV_SEQ_DEVICE_ARGPTR(wave); 305 strcpy(wave->name, "Aureal Synth"); 306 arg->hwptr = vortex; 307 arg->index = 1; 308 arg->seq_ports = seq_ports[dev]; 309 arg->max_voices = max_synth_voices[dev]; 310 } 311 #endif 312 313 // (5) 314 strcpy(card->driver, CARD_NAME_SHORT); 315 strcpy(card->shortname, CARD_NAME_SHORT); 316 sprintf(card->longname, "%s at 0x%lx irq %i", 317 card->shortname, chip->io, chip->irq); 318 319 if ((err = pci_read_config_word(pci, PCI_DEVICE_ID, 320 &(chip->device))) < 0) { 321 snd_card_free(card); 322 return err; 323 } 324 if ((err = pci_read_config_word(pci, PCI_VENDOR_ID, 325 &(chip->vendor))) < 0) { 326 snd_card_free(card); 327 return err; 328 } 329 if ((err = pci_read_config_byte(pci, PCI_REVISION_ID, 330 &(chip->rev))) < 0) { 331 snd_card_free(card); 332 return err; 333 } 334 #ifdef CHIP_AU8830 335 if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) { 336 printk(KERN_ALERT 337 "vortex: The revision (%x) of your card has not been seen before.\n", 338 chip->rev); 339 printk(KERN_ALERT 340 "vortex: Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n"); 341 snd_card_free(card); 342 err = -ENODEV; 343 return err; 344 } 345 #endif 346 347 // (6) 348 if ((err = snd_card_register(card)) < 0) { 349 snd_card_free(card); 350 return err; 351 } 352 // (7) 353 pci_set_drvdata(pci, card); 354 dev++; 355 vortex_connect_default(chip, 1); 356 vortex_enable_int(chip); 357 return 0; 358 } 359 360 // destructor -- see "Destructor" sub-section 361 static void __devexit snd_vortex_remove(struct pci_dev *pci) 362 { 363 snd_card_free(pci_get_drvdata(pci)); 364 pci_set_drvdata(pci, NULL); 365 } 366 367 // pci_driver definition 368 static struct pci_driver driver = { 369 .name = CARD_NAME_SHORT, 370 .id_table = snd_vortex_ids, 371 .probe = snd_vortex_probe, 372 .remove = __devexit_p(snd_vortex_remove), 373 }; 374 375 // initialization of the module 376 static int __init alsa_card_vortex_init(void) 377 { 378 return pci_module_init(&driver); 379 } 380 381 // clean up the module 382 static void __exit alsa_card_vortex_exit(void) 383 { 384 pci_unregister_driver(&driver); 385 } 386 387 module_init(alsa_card_vortex_init) 388 module_exit(alsa_card_vortex_exit) 389