From: Takashi Iwai Subject: ALSA: hda - Allow fixed codec-probe mask Patch-mainline: 2.6.30-rc1 References: bnc#502733 Some devices have broken BIOS and they don't set the codec probe-bit properly after cleared by the driver. This makes the driver skipping the necessary codec slots. Since BIOS update isn't always easy, now the semantics of probe_mask option is changed a bit. When it contains the bit 8 (0x100), the lower bits are used to probe that slots regardless of codec-probe bits returned by the hardware. For example, probe_mask=0x103 will force to probe the codec slot #0 and #1. Signed-off-by: Takashi Iwai Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -373,6 +373,7 @@ struct azx { /* HD codec */ unsigned short codec_mask; + int codec_probe_mask; /* copied from probe_mask option */ struct hda_bus *bus; /* CORB/RIRB */ @@ -1222,8 +1223,7 @@ static unsigned int azx_max_codecs[AZX_N [AZX_DRIVER_TERA] = 1, }; -static int __devinit azx_codec_create(struct azx *chip, const char *model, - unsigned int codec_probe_mask) +static int __devinit azx_codec_create(struct azx *chip, const char *model) { struct hda_bus_template bus_temp; int c, codecs, err; @@ -1253,7 +1253,7 @@ static int __devinit azx_codec_create(st /* First try to probe all given codec slots */ for (c = 0; c < max_slots; c++) { - if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { + if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { if (probe_codec(chip, c) < 0) { /* Some BIOSen give you wrong codec addresses * that don't exist @@ -1277,7 +1277,7 @@ static int __devinit azx_codec_create(st /* Then create codec instances */ for (c = 0; c < max_slots; c++) { - if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { + if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { struct hda_codec *codec; err = snd_hda_codec_new(chip->bus, c, &codec); if (err < 0) @@ -2153,23 +2153,38 @@ static struct snd_pci_quirk probe_mask_l SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01), /* broken BIOS */ SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01), + /* including bogus ALC268 in slot#2 that conflicts with ALC888 */ + SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01), + /* forced codec slots */ + SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103), {} }; +#define AZX_FORCE_CODEC_MASK 0x100 + static void __devinit check_probe_mask(struct azx *chip, int dev) { const struct snd_pci_quirk *q; - if (probe_mask[dev] == -1) { + chip->codec_probe_mask = probe_mask[dev]; + if (chip->codec_probe_mask == -1) { q = snd_pci_quirk_lookup(chip->pci, probe_mask_list); if (q) { printk(KERN_INFO "hda_intel: probe_mask set to 0x%x " "for device %04x:%04x\n", q->value, q->subvendor, q->subdevice); - probe_mask[dev] = q->value; + chip->codec_probe_mask = q->value; } } + + /* check forced option */ + if (chip->codec_probe_mask != -1 && + (chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) { + chip->codec_mask = chip->codec_probe_mask & 0xff; + printk(KERN_INFO "hda_intel: codec_mask forced to 0x%x\n", + chip->codec_mask); + } } @@ -2407,7 +2422,7 @@ static int __devinit azx_probe(struct pc card->private_data = chip; /* create codec instances */ - err = azx_codec_create(chip, model[dev], probe_mask[dev]); + err = azx_codec_create(chip, model[dev]); if (err < 0) goto out_free;