[alsa-devel] [PATCH] cs4236: detect cs4236+ chip in one pass

Ville Syrjälä syrjala at sci.fi
Sun Nov 1 12:47:37 CET 2009


On Sun, Nov 01, 2009 at 12:47:38PM +0100, Krzysztof Helt wrote:
> From: Krzysztof Helt <krzysztof.h1 at wp.pl>
> 
> The cs4236 was two step detection with call to the snd_wss_free()
> between two steps. The snd_wss_free() did not free a sound device
> created in the snd_wss_create(). This caused an OOPS during module
> removal as the same sound device was released twice. The same OOPS
> happened if the cs4236 module loading failed.
> 
> Fix this by adapting the snd_cs4236_create() to correctly work with
> chips less capable then cs4236. The snd_cs4236_create() behaves the
> same as the snd_wss_create() if the chip is less capable than the cs4236.
> 
> Signed-off-by: Krzysztof Helt <krzysztof.h1 at wp.pl>
> ---
<snip>
> @@ -281,83 +285,88 @@ int snd_cs4236_create(struct snd_card *card,
>  	*rchip = NULL;
>  	if (hardware == WSS_HW_DETECT)
>  		hardware = WSS_HW_DETECT3;
> -	if (cport < 0x100) {
> -		snd_printk(KERN_ERR "please, specify control port "
> -			   "for CS4236+ chips\n");
> -		return -ENODEV;
> -	}
> +
>  	err = snd_wss_create(card, port, cport,
>  			     irq, dma1, dma2, hardware, hwshare, &chip);
>  	if (err < 0)
>  		return err;
>  
> -	if (!(chip->hardware & WSS_HW_CS4236B_MASK)) {
> -		snd_printk(KERN_ERR "CS4236+: MODE3 and extended registers "
> -			   "not available, hardware=0x%x\n", chip->hardware);
> -		snd_device_free(card, chip);
> -		return -ENODEV;
> -	}
> +	if (chip->hardware & WSS_HW_CS4236B_MASK) {
>  #if 0
> -	{
> -		int idx;
> -		for (idx = 0; idx < 8; idx++)
> -			snd_printk(KERN_DEBUG "CD%i = 0x%x\n",
> -				   idx, inb(chip->cport + idx));
> -		for (idx = 0; idx < 9; idx++)
> -			snd_printk(KERN_DEBUG "C%i = 0x%x\n",
> -				   idx, snd_cs4236_ctrl_in(chip, idx));
> -	}
> +		{
> +			int idx;
> +			for (idx = 0; idx < 8; idx++)
> +				snd_printk(KERN_DEBUG "CD%i = 0x%x\n",
> +					   idx, inb(chip->cport + idx));
> +			for (idx = 0; idx < 9; idx++)
> +				snd_printk(KERN_DEBUG "C%i = 0x%x\n",
> +					   idx, snd_cs4236_ctrl_in(chip, idx));
> +		}
>  #endif
> -	ver1 = snd_cs4236_ctrl_in(chip, 1);
> -	ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
> -	snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2);
> -	if (ver1 != ver2) {
> -		snd_printk(KERN_ERR "CS4236+ chip detected, but "
> -			   "control port 0x%lx is not valid\n", cport);
> -		snd_device_free(card, chip);
> -		return -ENODEV;
> -	}
> -	snd_cs4236_ctrl_out(chip, 0, 0x00);
> -	snd_cs4236_ctrl_out(chip, 2, 0xff);
> -	snd_cs4236_ctrl_out(chip, 3, 0x00);
> -	snd_cs4236_ctrl_out(chip, 4, 0x80);
> -	snd_cs4236_ctrl_out(chip, 5, ((IEC958_AES1_CON_PCM_CODER & 3) << 6) | IEC958_AES0_CON_EMPHASIS_NONE);
> -	snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
> -	snd_cs4236_ctrl_out(chip, 7, 0x00);
> -	/* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958 output */
> -	/* is working with this setup, other hardware should have */
> -	/* different signal paths and this value should be selectable */
> -	/* in the future */
> -	snd_cs4236_ctrl_out(chip, 8, 0x8c);
> -	chip->rate_constraint = snd_cs4236_xrate;
> -	chip->set_playback_format = snd_cs4236_playback_format;
> -	chip->set_capture_format = snd_cs4236_capture_format;
> +		if (cport < 0x100 || cport == SNDRV_AUTO_PORT) {
> +			snd_printk(KERN_ERR "please, specify control port "
> +				   "for CS4236+ chips\n");

Missing a call to snd_device_free() here.

> +			return -ENODEV;
> +		}

-- 
Ville Syrjälä
syrjala at sci.fi
http://www.sci.fi/~syrjala/


More information about the Alsa-devel mailing list