[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