aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa')
-rw-r--r--sound/isa/Kconfig1
-rw-r--r--sound/isa/cmi8330.c42
2 files changed, 37 insertions, 6 deletions
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index be2d377ff90a..5915dc41c0ee 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -95,6 +95,7 @@ config SND_CMI8330
95 select SND_WSS_LIB 95 select SND_WSS_LIB
96 select SND_SB16_DSP 96 select SND_SB16_DSP
97 select SND_OPL3_LIB 97 select SND_OPL3_LIB
98 select SND_MPU401_UART
98 help 99 help
99 Say Y here to include support for soundcards based on the 100 Say Y here to include support for soundcards based on the
100 C-Media CMI8330 chip. 101 C-Media CMI8330 chip.
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 115437957413..9ca8122f7ba2 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -31,11 +31,11 @@
31 * To quickly load the module, 31 * To quickly load the module,
32 * 32 *
33 * modprobe -a snd-cmi8330 sbport=0x220 sbirq=5 sbdma8=1 33 * modprobe -a snd-cmi8330 sbport=0x220 sbirq=5 sbdma8=1
34 * sbdma16=5 wssport=0x530 wssirq=11 wssdma=0 34 * sbdma16=5 wssport=0x530 wssirq=11 wssdma=0 fmport=0x388
35 * 35 *
36 * This card has two mixers and two PCM devices. I've cheesed it such 36 * This card has two mixers and two PCM devices. I've cheesed it such
37 * that recording and playback can be done through the same device. 37 * that recording and playback can be done through the same device.
38 * The driver "magically" routes the capturing to the AD1848 codec, 38 * The driver "magically" routes the capturing to the CMI8330 codec,
39 * and playback to the SB16 codec. This allows for full-duplex mode 39 * and playback to the SB16 codec. This allows for full-duplex mode
40 * to some extent. 40 * to some extent.
41 * The utilities in alsa-utils are aware of both devices, so passing 41 * The utilities in alsa-utils are aware of both devices, so passing
@@ -52,6 +52,7 @@
52#include <sound/core.h> 52#include <sound/core.h>
53#include <sound/wss.h> 53#include <sound/wss.h>
54#include <sound/opl3.h> 54#include <sound/opl3.h>
55#include <sound/mpu401.h>
55#include <sound/sb.h> 56#include <sound/sb.h>
56#include <sound/initval.h> 57#include <sound/initval.h>
57 58
@@ -81,6 +82,8 @@ static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
81static int wssirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; 82static int wssirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
82static int wssdma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; 83static int wssdma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
83static long fmport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; 84static long fmport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
85static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
86static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
84 87
85module_param_array(index, int, NULL, 0444); 88module_param_array(index, int, NULL, 0444);
86MODULE_PARM_DESC(index, "Index value for CMI8330 soundcard."); 89MODULE_PARM_DESC(index, "Index value for CMI8330 soundcard.");
@@ -111,6 +114,10 @@ MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
111 114
112module_param_array(fmport, long, NULL, 0444); 115module_param_array(fmport, long, NULL, 0444);
113MODULE_PARM_DESC(fmport, "FM port # for CMI8330 driver."); 116MODULE_PARM_DESC(fmport, "FM port # for CMI8330 driver.");
117module_param_array(mpuport, long, NULL, 0444);
118MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330 driver.");
119module_param_array(mpuirq, int, NULL, 0444);
120MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330 MPU-401 port.");
114#ifdef CONFIG_PNP 121#ifdef CONFIG_PNP
115static int isa_registered; 122static int isa_registered;
116static int pnp_registered; 123static int pnp_registered;
@@ -153,6 +160,7 @@ struct snd_cmi8330 {
153#ifdef CONFIG_PNP 160#ifdef CONFIG_PNP
154 struct pnp_dev *cap; 161 struct pnp_dev *cap;
155 struct pnp_dev *play; 162 struct pnp_dev *play;
163 struct pnp_dev *mpu;
156#endif 164#endif
157 struct snd_card *card; 165 struct snd_card *card;
158 struct snd_wss *wss; 166 struct snd_wss *wss;
@@ -169,7 +177,7 @@ struct snd_cmi8330 {
169#ifdef CONFIG_PNP 177#ifdef CONFIG_PNP
170 178
171static struct pnp_card_device_id snd_cmi8330_pnpids[] = { 179static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
172 { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" } } }, 180 { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } },
173 { .id = "" } 181 { .id = "" }
174}; 182};
175 183
@@ -329,11 +337,15 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
329 if (acard->play == NULL) 337 if (acard->play == NULL)
330 return -EBUSY; 338 return -EBUSY;
331 339
340 acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
341 if (acard->play == NULL)
342 return -EBUSY;
343
332 pdev = acard->cap; 344 pdev = acard->cap;
333 345
334 err = pnp_activate_dev(pdev); 346 err = pnp_activate_dev(pdev);
335 if (err < 0) { 347 if (err < 0) {
336 snd_printk(KERN_ERR "CMI8330/C3D (AD1848) PnP configure failure\n"); 348 snd_printk(KERN_ERR "CMI8330/C3D PnP configure failure\n");
337 return -EBUSY; 349 return -EBUSY;
338 } 350 }
339 wssport[dev] = pnp_port_start(pdev, 0); 351 wssport[dev] = pnp_port_start(pdev, 0);
@@ -354,6 +366,17 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
354 sbdma16[dev] = pnp_dma(pdev, 1); 366 sbdma16[dev] = pnp_dma(pdev, 1);
355 sbirq[dev] = pnp_irq(pdev, 0); 367 sbirq[dev] = pnp_irq(pdev, 0);
356 368
369 /* allocate MPU-401 resources */
370 pdev = acard->mpu;
371
372 err = pnp_activate_dev(pdev);
373 if (err < 0) {
374 snd_printk(KERN_ERR
375 "CMI8330/C3D (MPU-401) PnP configure failure\n");
376 return -EBUSY;
377 }
378 mpuport[dev] = pnp_port_start(pdev, 0);
379 mpuirq[dev] = pnp_irq(pdev, 0);
357 return 0; 380 return 0;
358} 381}
359#endif 382#endif
@@ -502,11 +525,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
502 wssdma[dev], -1, 525 wssdma[dev], -1,
503 WSS_HW_DETECT, 0, &acard->wss); 526 WSS_HW_DETECT, 0, &acard->wss);
504 if (err < 0) { 527 if (err < 0) {
505 snd_printk(KERN_ERR PFX "(AD1848) device busy??\n"); 528 snd_printk(KERN_ERR PFX "(CMI8330) device busy??\n");
506 return err; 529 return err;
507 } 530 }
508 if (acard->wss->hardware != WSS_HW_CMI8330) { 531 if (acard->wss->hardware != WSS_HW_CMI8330) {
509 snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n"); 532 snd_printk(KERN_ERR PFX "(CMI8330) not found during probe\n");
510 return -ENODEV; 533 return -ENODEV;
511 } 534 }
512 535
@@ -552,6 +575,13 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
552 } 575 }
553 } 576 }
554 577
578 if (mpuport[dev] != SNDRV_AUTO_PORT) {
579 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
580 mpuport[dev], 0, mpuirq[dev],
581 IRQF_DISABLED, NULL) < 0)
582 printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n",
583 mpuport[dev]);
584 }
555 585
556 strcpy(card->driver, "CMI8330/C3D"); 586 strcpy(card->driver, "CMI8330/C3D");
557 strcpy(card->shortname, "C-Media CMI8330/C3D"); 587 strcpy(card->shortname, "C-Media CMI8330/C3D");