2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-11-20 00:26:39 +08:00

cmi8330: Add basic CMI8329 support

Add basic support for CMI8329 cards. Makes PCM and OPL3 work.
Does not break CMI8330 (tested).

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Ondrej Zary 2009-07-04 22:25:44 +02:00 committed by Takashi Iwai
parent 74a0094cd9
commit 69eb88825a

View File

@ -1,5 +1,5 @@
/* /*
* Driver for C-Media's CMI8330 soundcards. * Driver for C-Media's CMI8330 and CMI8329 soundcards.
* Copyright (c) by George Talusan <gstalusan@uwaterloo.ca> * Copyright (c) by George Talusan <gstalusan@uwaterloo.ca>
* http://www.undergrad.math.uwaterloo.ca/~gstalusa * http://www.undergrad.math.uwaterloo.ca/~gstalusa
* *
@ -64,7 +64,7 @@
/* /*
*/ */
MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>"); MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>");
MODULE_DESCRIPTION("C-Media CMI8330"); MODULE_DESCRIPTION("C-Media CMI8330/CMI8329");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001,@X@0001}}}"); MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001,@X@0001}}}");
@ -86,38 +86,38 @@ static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
module_param_array(index, int, NULL, 0444); module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for CMI8330 soundcard."); MODULE_PARM_DESC(index, "Index value for CMI8330/CMI8329 soundcard.");
module_param_array(id, charp, NULL, 0444); module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for CMI8330 soundcard."); MODULE_PARM_DESC(id, "ID string for CMI8330/CMI8329 soundcard.");
module_param_array(enable, bool, NULL, 0444); module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable CMI8330 soundcard."); MODULE_PARM_DESC(enable, "Enable CMI8330/CMI8329 soundcard.");
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
module_param_array(isapnp, bool, NULL, 0444); module_param_array(isapnp, bool, NULL, 0444);
MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard."); MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
#endif #endif
module_param_array(sbport, long, NULL, 0444); module_param_array(sbport, long, NULL, 0444);
MODULE_PARM_DESC(sbport, "Port # for CMI8330 SB driver."); MODULE_PARM_DESC(sbport, "Port # for CMI8330/CMI8329 SB driver.");
module_param_array(sbirq, int, NULL, 0444); module_param_array(sbirq, int, NULL, 0444);
MODULE_PARM_DESC(sbirq, "IRQ # for CMI8330 SB driver."); MODULE_PARM_DESC(sbirq, "IRQ # for CMI8330/CMI8329 SB driver.");
module_param_array(sbdma8, int, NULL, 0444); module_param_array(sbdma8, int, NULL, 0444);
MODULE_PARM_DESC(sbdma8, "DMA8 for CMI8330 SB driver."); MODULE_PARM_DESC(sbdma8, "DMA8 for CMI8330/CMI8329 SB driver.");
module_param_array(sbdma16, int, NULL, 0444); module_param_array(sbdma16, int, NULL, 0444);
MODULE_PARM_DESC(sbdma16, "DMA16 for CMI8330 SB driver."); MODULE_PARM_DESC(sbdma16, "DMA16 for CMI8330/CMI8329 SB driver.");
module_param_array(wssport, long, NULL, 0444); module_param_array(wssport, long, NULL, 0444);
MODULE_PARM_DESC(wssport, "Port # for CMI8330 WSS driver."); MODULE_PARM_DESC(wssport, "Port # for CMI8330/CMI8329 WSS driver.");
module_param_array(wssirq, int, NULL, 0444); module_param_array(wssirq, int, NULL, 0444);
MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver."); MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330/CMI8329 WSS driver.");
module_param_array(wssdma, int, NULL, 0444); module_param_array(wssdma, int, NULL, 0444);
MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); MODULE_PARM_DESC(wssdma, "DMA for CMI8330/CMI8329 WSS driver.");
module_param_array(fmport, long, NULL, 0444); module_param_array(fmport, long, NULL, 0444);
MODULE_PARM_DESC(fmport, "FM port # for CMI8330 driver."); MODULE_PARM_DESC(fmport, "FM port # for CMI8330/CMI8329 driver.");
module_param_array(mpuport, long, NULL, 0444); module_param_array(mpuport, long, NULL, 0444);
MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330 driver."); MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330/CMI8329 driver.");
module_param_array(mpuirq, int, NULL, 0444); module_param_array(mpuirq, int, NULL, 0444);
MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330 MPU-401 port."); MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330/CMI8329 MPU-401 port.");
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static int isa_registered; static int isa_registered;
static int pnp_registered; static int pnp_registered;
@ -156,6 +156,11 @@ static unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] =
typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *); typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *);
enum card_type {
CMI8330,
CMI8329
};
struct snd_cmi8330 { struct snd_cmi8330 {
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
struct pnp_dev *cap; struct pnp_dev *cap;
@ -172,11 +177,14 @@ struct snd_cmi8330 {
snd_pcm_open_callback_t open; snd_pcm_open_callback_t open;
void *private_data; /* sb or wss */ void *private_data; /* sb or wss */
} streams[2]; } streams[2];
enum card_type type;
}; };
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static struct pnp_card_device_id snd_cmi8330_pnpids[] = { static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
{ .id = "CMI0001", .devs = { { "@X@0001" }, { "@@@0001" }, { "@H@0001" }, { "A@@0001" } } },
{ .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } },
{ .id = "" } { .id = "" }
}; };
@ -304,7 +312,7 @@ static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330
unsigned int idx; unsigned int idx;
int err; int err;
strcpy(card->mixername, "CMI8330/C3D"); strcpy(card->mixername, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) { for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) {
err = snd_ctl_add(card, err = snd_ctl_add(card,
@ -329,6 +337,9 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
struct pnp_dev *pdev; struct pnp_dev *pdev;
int err; int err;
/* CMI8329 has a device with ID A@@0001, CMI8330 does not */
acard->type = (id->devs[3].id[0]) ? CMI8329 : CMI8330;
acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL); acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL);
if (acard->cap == NULL) if (acard->cap == NULL)
return -EBUSY; return -EBUSY;
@ -345,34 +356,36 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
err = pnp_activate_dev(pdev); err = pnp_activate_dev(pdev);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR "CMI8330/C3D (AD1848) PnP configure failure\n"); snd_printk(KERN_ERR "AD1848 PnP configure failure\n");
return -EBUSY; return -EBUSY;
} }
wssport[dev] = pnp_port_start(pdev, 0); wssport[dev] = pnp_port_start(pdev, 0);
wssdma[dev] = pnp_dma(pdev, 0); wssdma[dev] = pnp_dma(pdev, 0);
wssirq[dev] = pnp_irq(pdev, 0); wssirq[dev] = pnp_irq(pdev, 0);
fmport[dev] = pnp_port_start(pdev, 1); if (acard->type == CMI8330)
fmport[dev] = pnp_port_start(pdev, 1);
/* allocate SB16 resources */ /* allocate SB16 resources */
pdev = acard->play; pdev = acard->play;
err = pnp_activate_dev(pdev); err = pnp_activate_dev(pdev);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR "CMI8330/C3D (SB16) PnP configure failure\n"); snd_printk(KERN_ERR "SB16 PnP configure failure\n");
return -EBUSY; return -EBUSY;
} }
sbport[dev] = pnp_port_start(pdev, 0); sbport[dev] = pnp_port_start(pdev, 0);
sbdma8[dev] = pnp_dma(pdev, 0); sbdma8[dev] = pnp_dma(pdev, 0);
sbdma16[dev] = pnp_dma(pdev, 1); sbdma16[dev] = pnp_dma(pdev, 1);
sbirq[dev] = pnp_irq(pdev, 0); sbirq[dev] = pnp_irq(pdev, 0);
if (acard->type == CMI8329)
fmport[dev] = pnp_port_start(pdev, 1);
/* allocate MPU-401 resources */ /* allocate MPU-401 resources */
pdev = acard->mpu; pdev = acard->mpu;
err = pnp_activate_dev(pdev); err = pnp_activate_dev(pdev);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR snd_printk(KERN_ERR "MPU-401 PnP configure failure\n");
"CMI8330/C3D (MPU-401) PnP configure failure\n");
return -EBUSY; return -EBUSY;
} }
mpuport[dev] = pnp_port_start(pdev, 0); mpuport[dev] = pnp_port_start(pdev, 0);
@ -430,9 +443,9 @@ static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *
snd_cmi8330_capture_open snd_cmi8330_capture_open
}; };
if ((err = snd_pcm_new(card, "CMI8330", 0, 1, 1, &pcm)) < 0) if ((err = snd_pcm_new(card, (chip->type == CMI8329) ? "CMI8329" : "CMI8330", 0, 1, 1, &pcm)) < 0)
return err; return err;
strcpy(pcm->name, "CMI8330"); strcpy(pcm->name, (chip->type == CMI8329) ? "CMI8329" : "CMI8330");
pcm->private_data = chip; pcm->private_data = chip;
/* SB16 */ /* SB16 */
@ -527,11 +540,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
wssdma[dev], -1, wssdma[dev], -1,
WSS_HW_DETECT, 0, &acard->wss); WSS_HW_DETECT, 0, &acard->wss);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR PFX "(AD1848) device busy??\n"); snd_printk(KERN_ERR PFX "AD1848 device busy??\n");
return err; return err;
} }
if (acard->wss->hardware != WSS_HW_CMI8330) { if (acard->wss->hardware != WSS_HW_CMI8330) {
snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n"); snd_printk(KERN_ERR PFX "AD1848 not found during probe\n");
return -ENODEV; return -ENODEV;
} }
@ -541,11 +554,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
sbdma8[dev], sbdma8[dev],
sbdma16[dev], sbdma16[dev],
SB_HW_AUTO, &acard->sb)) < 0) { SB_HW_AUTO, &acard->sb)) < 0) {
snd_printk(KERN_ERR PFX "(SB16) device busy??\n"); snd_printk(KERN_ERR PFX "SB16 device busy??\n");
return err; return err;
} }
if (acard->sb->hardware != SB_HW_16) { if (acard->sb->hardware != SB_HW_16) {
snd_printk(KERN_ERR PFX "(SB16) not found during probe\n"); snd_printk(KERN_ERR PFX "SB16 not found during probe\n");
return err; return err;
} }
@ -585,8 +598,8 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
mpuport[dev]); mpuport[dev]);
} }
strcpy(card->driver, "CMI8330/C3D"); strcpy(card->driver, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
strcpy(card->shortname, "C-Media CMI8330/C3D"); strcpy(card->shortname, (acard->type == CMI8329) ? "C-Media CMI8329" : "C-Media CMI8330/C3D");
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
card->shortname, card->shortname,
acard->wss->port, acard->wss->port,