Lines Matching +full:playback +full:- +full:dma

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for C-Media CMI8328-based soundcards, such as AudioExcel AV500
7 * - CMI8328 - main chip (SB Pro emulation, gameport, OPL3, MPU401, CD-ROM)
8 * - CS4231A - WSS codec
9 * - Dream SAM9233+GMS950400+RAM+ROM: Wavetable MIDI, connected to MPU401
16 #include <asm/dma.h>
26 MODULE_AUTHOR("Ondrej Zary <linux@rainbow-software.org>");
27 MODULE_DESCRIPTION("C-Media CMI8328");
38 static int index[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = -1};
39 static char *id[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = NULL};
40 static long port[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_PORT};
41 static int irq[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_IRQ};
42 static int dma1[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_DMA};
43 static int dma2[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_DMA};
44 static long mpuport[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_PORT};
45 static int mpuirq[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_IRQ};
47 static bool gameport[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = true};
59 module_param_hw_array(dma1, int, dma, NULL, 0444);
61 module_param_hw_array(dma2, int, dma, NULL, 0444);
65 MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8328 driver.");
67 MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8328 MPU-401 port.");
91 * bits 2-4: SB IRQ: 001=3, 010=5, 011=7, 100=9, 101=10, 110=11
92 * bits 5-6: SB DMA: 00=disabled (when SB disabled), 01=DMA0, 10=DMA1, 11=DMA3
98 * bits 0-1: CD-ROM mode: 00=disabled, 01=Panasonic, 10=Sony/Mitsumi/Wearnes,
101 * bits 3-4: MPU401 IRQ: 00=3, 01=5, 10=7, 11=9,
102 * bits 5-7: MPU401 port: 000=0x300, 001=0x310, 010=0x320, 011=0x330, 100=0x332,
107 * bits 0-2: CD-ROM IRQ: 000=disabled, 001=3, 010=5, 011=7, 100=9, 101=10,
109 * bits 3-4: CD-ROM DMA: 00=disabled, 01=DMA0, 10=DMA1, 11=DMA3
110 * bits 5-7: CD-ROM port: 000=0x300, 001=0x310, 010=0x320, 011=0x330, 100=0x340,
152 card = chip->card; in snd_cmi8328_mixer()
158 strcpy(id1.name, "Aux Playback Switch"); in snd_cmi8328_mixer()
159 strcpy(id2.name, "CD Playback Switch"); in snd_cmi8328_mixer()
162 dev_err(card->dev, "error renaming control\n"); in snd_cmi8328_mixer()
166 strcpy(id1.name, "Aux Playback Volume"); in snd_cmi8328_mixer()
167 strcpy(id2.name, "CD Playback Volume"); in snd_cmi8328_mixer()
170 dev_err(card->dev, "error renaming control\n"); in snd_cmi8328_mixer()
174 strcpy(id1.name, "Aux Playback Switch"); in snd_cmi8328_mixer()
176 strcpy(id2.name, "Synth Playback Switch"); in snd_cmi8328_mixer()
179 dev_err(card->dev, "error renaming control\n"); in snd_cmi8328_mixer()
183 strcpy(id1.name, "Aux Playback Volume"); in snd_cmi8328_mixer()
185 strcpy(id2.name, "Synth Playback Volume"); in snd_cmi8328_mixer()
188 dev_err(card->dev, "error renaming control\n"); in snd_cmi8328_mixer()
195 /* find index of an item in "-1"-ended array */
200 for (i = 0; array[i] != -1; i++) in array_find()
204 return -1; in array_find()
211 for (i = 0; array[i] != -1; i++) in array_find_l()
215 return -1; in array_find_l()
228 0x336, -1 }; in snd_cmi8328_probe()
230 static const int mpu_irqs[] = { 9, 7, 5, 3, -1 }; in snd_cmi8328_probe()
232 static const int irqs[] = { 9, 10, 11, 7, -1 }; in snd_cmi8328_probe()
234 static const int dma1s[] = { 3, 1, 0, -1 }; in snd_cmi8328_probe()
236 static const int dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1}, {0, -1} }; in snd_cmi8328_probe()
240 /* 0xff is invalid configuration (but settable - hope it isn't set) */ in snd_cmi8328_probe()
242 return -ENODEV; in snd_cmi8328_probe()
246 return -ENODEV; in snd_cmi8328_probe()
249 snd_cmi8328_cfg_write(port, CFG3, 0); /* disable CDROM IRQ and DMA */ in snd_cmi8328_probe()
255 return -EBUSY; in snd_cmi8328_probe()
262 return -EBUSY; in snd_cmi8328_probe()
268 dev_warn(pdev, "unable to find a free DMA2, full-duplex will not work\n"); in snd_cmi8328_probe()
269 dma2[ndev] = -1; in snd_cmi8328_probe()
276 return -EINVAL; in snd_cmi8328_probe()
279 /* ...and DMA... */ in snd_cmi8328_probe()
283 return -EINVAL; in snd_cmi8328_probe()
291 return -EINVAL; in snd_cmi8328_probe()
293 val |= 0x04; /* enable separate capture DMA */ in snd_cmi8328_probe()
301 cmi = card->private_data; in snd_cmi8328_probe()
302 cmi->card = card; in snd_cmi8328_probe()
303 cmi->port = port; in snd_cmi8328_probe()
304 cmi->wss_cfg = val; in snd_cmi8328_probe()
306 err = snd_wss_create(card, port + 4, -1, irq[ndev], dma1[ndev], in snd_cmi8328_probe()
307 dma2[ndev], WSS_HW_DETECT, 0, &cmi->wss); in snd_cmi8328_probe()
311 err = snd_wss_pcm(cmi->wss, 0); in snd_cmi8328_probe()
315 err = snd_wss_mixer(cmi->wss); in snd_cmi8328_probe()
318 err = snd_cmi8328_mixer(cmi->wss); in snd_cmi8328_probe()
322 if (snd_wss_timer(cmi->wss, 0) < 0) in snd_cmi8328_probe()
365 strcpy(card->driver, "CMI8328"); in snd_cmi8328_probe()
366 strcpy(card->shortname, "C-Media CMI8328"); in snd_cmi8328_probe()
367 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d,%d", in snd_cmi8328_probe()
368 card->shortname, cmi->wss->port, irq[ndev], dma1[ndev], in snd_cmi8328_probe()
383 struct gameport *gp = cmi->gameport = gameport_allocate_port(); in snd_cmi8328_probe()
384 if (cmi->gameport) { in snd_cmi8328_probe()
388 gp->io = 0x200; in snd_cmi8328_probe()
402 struct snd_cmi8328 *cmi = card->private_data; in snd_cmi8328_remove()
405 if (cmi->gameport) in snd_cmi8328_remove()
406 gameport_unregister_port(cmi->gameport); in snd_cmi8328_remove()
409 snd_cmi8328_cfg_write(cmi->port, CFG1, CFG1_SB_DISABLE); in snd_cmi8328_remove()
410 snd_cmi8328_cfg_write(cmi->port, CFG2, 0); in snd_cmi8328_remove()
411 snd_cmi8328_cfg_write(cmi->port, CFG3, 0); in snd_cmi8328_remove()
423 cmi = card->private_data; in snd_cmi8328_suspend()
424 snd_cmi8328_cfg_save(cmi->port, cmi->cfg); in snd_cmi8328_suspend()
426 cmi->wss->suspend(cmi->wss); in snd_cmi8328_suspend()
438 cmi = card->private_data; in snd_cmi8328_resume()
439 snd_cmi8328_cfg_restore(cmi->port, cmi->cfg); in snd_cmi8328_resume()
440 outb(cmi->wss_cfg, cmi->port); in snd_cmi8328_resume()
441 cmi->wss->resume(cmi->wss); in snd_cmi8328_resume()