Commit 14e1d357 authored by Dan Carpenter's avatar Dan Carpenter Committed by Jaroslav Kysela
Browse files

[ALSA] atiixp - Add a parameter ac97_quirk



Add an option to specify the AC'97 codec instead of
probing.  This is a fix for bugzilla #7467.

Signed-off-by: default avatarDan Carpenter <error27@gmail.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent ddc2cec4
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -242,6 +242,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
    ac97_clock		- AC'97 clock (default = 48000)
    ac97_quirk		- AC'97 workaround for strange hardware
			  See "AC97 Quirk Option" section below.
    ac97_codec		- Workaround to specify which AC'97 codec 
			  instead of probing.  If this works for you
			  file a bug with your `lspci -vn` output.
			  -2  -- Force probing.
			  -1  -- Default behavior.
			  0-2 -- Use the specified codec.
    spdif_aclink	- S/PDIF transfer over AC-link (default = 1)

    This module supports one card and autoprobe.
+45 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static int ac97_clock = 48000;
static char *ac97_quirk;
static int spdif_aclink = 1;
static int ac97_codec = -1;

module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
@@ -54,6 +55,8 @@ module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
module_param(ac97_codec, int, 0444);
MODULE_PARM_DESC(ac97_codec, "Specify codec instead of probing.");
module_param(spdif_aclink, bool, 0444);
MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");

@@ -293,6 +296,22 @@ static struct pci_device_id snd_atiixp_ids[] = {

MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);

struct atiixp_quirk {
	unsigned short  subvendor;
	unsigned short  subdevice;
	const char *name;
	int ac97_codec;
};

static struct atiixp_quirk atiixp_quirks[] __devinitdata = {
	{
		.subvendor = 0x15bd,
		.subdevice = 0x3100,
		.name = "DFI RS482",
		.ac97_codec = 0,
	},
	{ .subvendor = 0 } /* terminator */
};

/*
 * lowlevel functions
@@ -553,11 +572,37 @@ static int snd_atiixp_aclink_down(struct atiixp *chip)
	     ATI_REG_ISR_CODEC2_NOT_READY)
#define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)

static int ac97_probing_bugs(struct pci_dev *pci)
{
	int i = 0;

	while (atiixp_quirks[i].subvendor) {
		if (pci->subsystem_vendor == atiixp_quirks[i].subvendor  &&
		    pci->subsystem_device == atiixp_quirks[i].subdevice) {
			printk(KERN_INFO "Atiixp quirk for %s.  "
			       "Forcing codec %d\n", atiixp_quirks[i].name, 
			       atiixp_quirks[i].ac97_codec);
			return atiixp_quirks[i].ac97_codec;
		}
		i++;
	}
	/* this hardware doesn't need workarounds.  Probe for codec */
	return -1;
}

static int snd_atiixp_codec_detect(struct atiixp *chip)
{
	int timeout;

	chip->codec_not_ready_bits = 0;
	if (ac97_codec == -1)
		ac97_codec = ac97_probing_bugs(chip->pci);
	if (ac97_codec >= 0) {
		chip->codec_not_ready_bits |= 
			CODEC_CHECK_BITS ^ (1 << (ac97_codec + 10));
		return 0;
	}

	atiixp_write(chip, IER, CODEC_CHECK_BITS);
	/* wait for the interrupts */
	timeout = 50;