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