Commit f1eaaeec authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Allow fixed codec-probe mask

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: default avatarTakashi Iwai <tiwai@suse.de>
parent c98041f7
...@@ -381,6 +381,7 @@ struct azx { ...@@ -381,6 +381,7 @@ struct azx {
/* HD codec */ /* HD codec */
unsigned short codec_mask; unsigned short codec_mask;
int codec_probe_mask; /* copied from probe_mask option */
struct hda_bus *bus; struct hda_bus *bus;
/* CORB/RIRB */ /* CORB/RIRB */
...@@ -1228,7 +1229,6 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = { ...@@ -1228,7 +1229,6 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
}; };
static int __devinit azx_codec_create(struct azx *chip, const char *model, static int __devinit azx_codec_create(struct azx *chip, const char *model,
unsigned int codec_probe_mask,
int no_init) int no_init)
{ {
struct hda_bus_template bus_temp; struct hda_bus_template bus_temp;
...@@ -1261,7 +1261,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, ...@@ -1261,7 +1261,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
/* First try to probe all given codec slots */ /* First try to probe all given codec slots */
for (c = 0; c < max_slots; c++) { 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) { if (probe_codec(chip, c) < 0) {
/* Some BIOSen give you wrong codec addresses /* Some BIOSen give you wrong codec addresses
* that don't exist * that don't exist
...@@ -1285,7 +1285,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, ...@@ -1285,7 +1285,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
/* Then create codec instances */ /* Then create codec instances */
for (c = 0; c < max_slots; c++) { 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; struct hda_codec *codec;
err = snd_hda_codec_new(chip->bus, c, !no_init, &codec); err = snd_hda_codec_new(chip->bus, c, !no_init, &codec);
if (err < 0) if (err < 0)
...@@ -2101,20 +2101,31 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = { ...@@ -2101,20 +2101,31 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
{} {}
}; };
#define AZX_FORCE_CODEC_MASK 0x100
static void __devinit check_probe_mask(struct azx *chip, int dev) static void __devinit check_probe_mask(struct azx *chip, int dev)
{ {
const struct snd_pci_quirk *q; 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); q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
if (q) { if (q) {
printk(KERN_INFO printk(KERN_INFO
"hda_intel: probe_mask set to 0x%x " "hda_intel: probe_mask set to 0x%x "
"for device %04x:%04x\n", "for device %04x:%04x\n",
q->value, q->subvendor, q->subdevice); 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);
}
} }
...@@ -2347,8 +2358,7 @@ static int __devinit azx_probe(struct pci_dev *pci, ...@@ -2347,8 +2358,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
card->private_data = chip; card->private_data = chip;
/* create codec instances */ /* create codec instances */
err = azx_codec_create(chip, model[dev], probe_mask[dev], err = azx_codec_create(chip, model[dev], probe_only[dev]);
probe_only[dev]);
if (err < 0) if (err < 0)
goto out_free; goto out_free;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment