[alsa-devel] [RFC] cmi8330: Add basic CMI8329 support

Takashi Iwai tiwai at suse.de
Sun Jul 5 11:51:42 CEST 2009


At Sat, 4 Jul 2009 22:25:44 +0200,
Ondrej Zary wrote:
> 
> On Monday 29 June 2009 08:25:05 Takashi Iwai wrote:
> > At Sat, 27 Jun 2009 17:07:31 +0200,
> >
> > Ondrej Zary wrote:
> > > Add basic support for CMI8329 cards. It seems to be very similar to
> > > CMI8330, but the PnP devices are different:
> > >  - AD1848 (WSS) and SB16 device IDs are swapped
> > >  - the OPL3 port is contained in SB16 device, not AD1848 (WSS)
> > >  - there is A@@0001 device (looks like some control interface - it has
> > > only one 8-bit I/O address)
> >
> > Does CMI8329 have the very same device ids?
> > If "A@@00" is 8329-specific, you can prepend an entry like
> >
> > 	{.id = "CMI0001", .devs = {{"@X at 0001"}, {"@@@0001"}, {"@H at 0001"},
> > {"A@@001"}},
> >
> > (Note the first two are swapped.)
> 
> Yes, A@@0001 is 8329-specific. Thanks for suggestion, it works.
> 
> > > Is my detection code correct, shouldn't the struct pnp_dev returned
> > > pnp_request_card_device() be released somehow?
> >
> > I guess so.  But looks like a non-critical issue.
> 
> With additional entry, the detection code can be simplified (see patch).
> 
> > > Also the mixer seems to be a bit different - master volume does not work
> > > currently.
> >
> > This is a problem...  Does "SB Master" play any role?
> 
> Unfortunately not. Mixer elements enabled by defining ENABLE_SB_MIXER do not 
> work. I don't know anything about mixer element arrangement in the I/O space.
> The 3D and loudness switches have no effect as they're probably supported 
> only on CMI8330 (that's why it's called CMI8330/C3D).

OK, then there must be something else...

> Add basic support for CMI8329 cards. Makes PCM and OPL3 work.
> Does not break CMI8330 (tested).
> 
> Signed-off-by: Ondrej Zary <linux at rainbow-software.org>

Thanks, applied now.


Takashi
> 
> --- linux-test/sound/isa/cmi8330.c	2009-06-27 16:32:13.000000000 +0200
> +++ linux-2.6.30-pentium/sound/isa/cmi8330.c	2009-07-04 21:58:35.000000000 +0200
> @@ -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 at uwaterloo.ca>

>   *    http://www.undergrad.math.uwaterloo.ca/~gstalusa
>   *
> @@ -64,7 +64,7 @@
>  /*
>   */
>  MODULE_AUTHOR("George Talusan <gstalusan at uwaterloo.ca>");
> -MODULE_DESCRIPTION("C-Media CMI8330");
> +MODULE_DESCRIPTION("C-Media CMI8330/CMI8329");
>  MODULE_LICENSE("GPL");
>  MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001, at X@0001}}}");
>  
> @@ -86,38 +86,38 @@
>  static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
>  
>  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_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_PARM_DESC(enable, "Enable CMI8330 soundcard.");
> +MODULE_PARM_DESC(enable, "Enable CMI8330/CMI8329 soundcard.");
>  #ifdef CONFIG_PNP
>  module_param_array(isapnp, bool, NULL, 0444);
>  MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
>  #endif
>  
>  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_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_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_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_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_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_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_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_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_PARM_DESC(mpuirq, "IRQ # for CMI8330 MPU-401 port.");
> +MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330/CMI8329 MPU-401 port.");
>  #ifdef CONFIG_PNP
>  static int isa_registered;
>  static int pnp_registered;
> @@ -156,6 +156,11 @@
>  
>  typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *);
>  
> +enum card_type {
> +	CMI8330,
> +	CMI8329
> +};
> +
>  struct snd_cmi8330 {
>  #ifdef CONFIG_PNP
>  	struct pnp_dev *cap;
> @@ -172,11 +177,14 @@
>  		snd_pcm_open_callback_t open;
>  		void *private_data; /* sb or wss */
>  	} streams[2];
> +
> +	enum card_type type;
>  };
>  
>  #ifdef CONFIG_PNP
>  
>  static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
> +	{ .id = "CMI0001", .devs = { { "@X at 0001" }, { "@@@0001" }, { "@H at 0001" }, { "A@@0001" } } },
>  	{ .id = "CMI0001", .devs = { { "@@@0001" }, { "@X at 0001" }, { "@H at 0001" } } },
>  	{ .id = "" }
>  };
> @@ -304,7 +312,7 @@
>  	unsigned int idx;
>  	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++) {
>  		err = snd_ctl_add(card,
> @@ -329,6 +337,9 @@
>  	struct pnp_dev *pdev;
>  	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);
>  	if (acard->cap == NULL)
>  		return -EBUSY;
> @@ -345,34 +356,36 @@
>  
>  	err = pnp_activate_dev(pdev);
>  	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;
>  	}
>  	wssport[dev] = pnp_port_start(pdev, 0);
>  	wssdma[dev] = pnp_dma(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 */
>  	pdev = acard->play;
>  
>  	err = pnp_activate_dev(pdev);
>  	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;
>  	}
>  	sbport[dev] = pnp_port_start(pdev, 0);
>  	sbdma8[dev] = pnp_dma(pdev, 0);
>  	sbdma16[dev] = pnp_dma(pdev, 1);
>  	sbirq[dev] = pnp_irq(pdev, 0);
> +	if (acard->type == CMI8329)
> +		fmport[dev] = pnp_port_start(pdev, 1);
>  
>  	/* allocate MPU-401 resources */
>  	pdev = acard->mpu;
>  
>  	err = pnp_activate_dev(pdev);
>  	if (err < 0) {
> -		snd_printk(KERN_ERR
> -			   "CMI8330/C3D (MPU-401) PnP configure failure\n");
> +		snd_printk(KERN_ERR "MPU-401 PnP configure failure\n");
>  		return -EBUSY;
>  	}
>  	mpuport[dev] = pnp_port_start(pdev, 0);
> @@ -430,9 +443,9 @@
>  		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;
> -	strcpy(pcm->name, "CMI8330");
> +	strcpy(pcm->name, (chip->type == CMI8329) ? "CMI8329" : "CMI8330");
>  	pcm->private_data = chip;
>  	
>  	/* SB16 */
> @@ -527,11 +540,11 @@
>  			     wssdma[dev], -1,
>  			     WSS_HW_DETECT, 0, &acard->wss);
>  	if (err < 0) {
> -		snd_printk(KERN_ERR PFX "(AD1848) device busy??\n");
> +		snd_printk(KERN_ERR PFX "AD1848 device busy??\n");
>  		return err;
>  	}
>  	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;
>  	}
>  
> @@ -541,11 +554,11 @@
>  				    sbdma8[dev],
>  				    sbdma16[dev],
>  				    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;
>  	}
>  	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;
>  	}
>  
> @@ -585,8 +598,8 @@
>  				mpuport[dev]);
>  	}
>  
> -	strcpy(card->driver, "CMI8330/C3D");
> -	strcpy(card->shortname, "C-Media CMI8330/C3D");
> +	strcpy(card->driver, (acard->type == CMI8329) ? "CMI8329" : "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",
>  		card->shortname,
>  		acard->wss->port,
> 
> 
> -- 
> Ondrej Zary
> 


More information about the Alsa-devel mailing list