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 communicate. 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 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 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 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 82 static void snd_vortex_workaround(struct pci_dev *vortex, int fix) 83 { 84 struct pci_dev *via = NULL; 85 86 /* autodetect if workarounds are required */ 87 if (fix == 255) { 88 /* VIA KT133 */ 89 via = pci_get_device(PCI_VENDOR_ID_VIA, 90 PCI_DEVICE_ID_VIA_8365_1, NULL); 91 /* VIA Apollo */ 92 if (via == NULL) { 93 via = pci_get_device(PCI_VENDOR_ID_VIA, 94 PCI_DEVICE_ID_VIA_82C598_1, NULL); 95 /* AMD Irongate */ 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 // component-destructor 125 // (see "Management of Cards and Components") 126 static void snd_vortex_free(struct snd_card *card) 127 { 128 vortex_t *vortex = card->private_data; 129 130 vortex_gameport_unregister(vortex); 131 vortex_core_shutdown(vortex); 132 } 133 134 // chip-specific constructor 135 // (see "Management of Cards and Components") 136 static int 137 snd_vortex_create(struct snd_card *card, struct pci_dev *pci) 138 { 139 vortex_t *chip = card->private_data; 140 int err; 141 142 // check PCI availability (DMA). 143 err = pcim_enable_device(pci); 144 if (err < 0) 145 return err; 146 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { 147 dev_err(card->dev, "error to set DMA mask\n"); 148 return -ENXIO; 149 } 150 151 chip->card = card; 152 153 // initialize the stuff 154 chip->pci_dev = pci; 155 chip->vendor = pci->vendor; 156 chip->device = pci->device; 157 chip->card = card; 158 chip->irq = -1; 159 160 // (1) PCI resource allocation 161 // Get MMIO area 162 // 163 chip->mmio = pcim_iomap_region(pci, 0, KBUILD_MODNAME); 164 if (IS_ERR(chip->mmio)) 165 return PTR_ERR(chip->mmio); 166 167 chip->io = pci_resource_start(pci, 0); 168 169 /* Init audio core. 170 * This must be done before we do request_irq otherwise we can get spurious 171 * interrupts that we do not handle properly and make a mess of things */ 172 err = vortex_core_init(chip); 173 if (err) { 174 dev_err(card->dev, "hw core init failed\n"); 175 return err; 176 } 177 178 err = devm_request_irq(&pci->dev, pci->irq, vortex_interrupt, 179 IRQF_SHARED, KBUILD_MODNAME, chip); 180 if (err) { 181 dev_err(card->dev, "cannot grab irq\n"); 182 return err; 183 } 184 chip->irq = pci->irq; 185 card->sync_irq = chip->irq; 186 card->private_free = snd_vortex_free; 187 188 pci_set_master(pci); 189 // End of PCI setup. 190 return 0; 191 } 192 193 // constructor -- see "Constructor" sub-section 194 static int 195 __snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) 196 { 197 static int dev; 198 struct snd_card *card; 199 vortex_t *chip; 200 int err; 201 202 // (1) 203 if (dev >= SNDRV_CARDS) 204 return -ENODEV; 205 if (!enable[dev]) { 206 dev++; 207 return -ENOENT; 208 } 209 // (2) 210 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, 211 sizeof(*chip), &card); 212 if (err < 0) 213 return err; 214 chip = card->private_data; 215 216 // (3) 217 err = snd_vortex_create(card, pci); 218 if (err < 0) 219 return err; 220 snd_vortex_workaround(pci, pcifix[dev]); 221 222 // Card details needed in snd_vortex_midi 223 strcpy(card->driver, CARD_NAME_SHORT); 224 sprintf(card->shortname, "Aureal Vortex %s", CARD_NAME_SHORT); 225 sprintf(card->longname, "%s at 0x%lx irq %i", 226 card->shortname, chip->io, chip->irq); 227 228 // (4) Alloc components. 229 err = snd_vortex_mixer(chip); 230 if (err < 0) 231 return err; 232 // ADB pcm. 233 err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_PCM); 234 if (err < 0) 235 return err; 236 #ifndef CHIP_AU8820 237 // ADB SPDIF 238 err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1); 239 if (err < 0) 240 return err; 241 // A3D 242 err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D); 243 if (err < 0) 244 return err; 245 #endif 246 /* 247 // ADB I2S 248 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_I2S, 1)) < 0) { 249 return err; 250 } 251 */ 252 #ifndef CHIP_AU8810 253 // WT pcm. 254 err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT); 255 if (err < 0) 256 return err; 257 #endif 258 err = snd_vortex_midi(chip); 259 if (err < 0) 260 return err; 261 262 vortex_gameport_register(chip); 263 264 #if 0 265 if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH, 266 sizeof(snd_vortex_synth_arg_t), &wave) < 0 267 || wave == NULL) { 268 dev_err(card->dev, "Can't initialize Aureal wavetable synth\n"); 269 } else { 270 snd_vortex_synth_arg_t *arg; 271 272 arg = SNDRV_SEQ_DEVICE_ARGPTR(wave); 273 strcpy(wave->name, "Aureal Synth"); 274 arg->hwptr = vortex; 275 arg->index = 1; 276 arg->seq_ports = seq_ports[dev]; 277 arg->max_voices = max_synth_voices[dev]; 278 } 279 #endif 280 281 // (5) 282 err = pci_read_config_word(pci, PCI_DEVICE_ID, &chip->device); 283 if (err < 0) 284 return err; 285 err = pci_read_config_word(pci, PCI_VENDOR_ID, &chip->vendor); 286 if (err < 0) 287 return err; 288 chip->rev = pci->revision; 289 #ifdef CHIP_AU8830 290 if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) { 291 dev_alert(card->dev, 292 "The revision (%x) of your card has not been seen before.\n", 293 chip->rev); 294 dev_alert(card->dev, 295 "Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n"); 296 return -ENODEV; 297 } 298 #endif 299 300 // (6) 301 err = snd_card_register(card); 302 if (err < 0) 303 return err; 304 // (7) 305 pci_set_drvdata(pci, card); 306 dev++; 307 vortex_connect_default(chip, 1); 308 vortex_enable_int(chip); 309 return 0; 310 } 311 312 static int 313 snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) 314 { 315 return snd_card_free_on_error(&pci->dev, __snd_vortex_probe(pci, pci_id)); 316 } 317 318 // pci_driver definition 319 static struct pci_driver vortex_driver = { 320 .name = KBUILD_MODNAME, 321 .id_table = snd_vortex_ids, 322 .probe = snd_vortex_probe, 323 }; 324 325 module_pci_driver(vortex_driver); 326