ALSA: hda - Add a new function to seek for a codec ID

Gateway notebooks have their ID inside codec vendor ID, not at PCI ID. Due to
that, model auto-detection were not possible with the standard seek method.

This is what is found at lspci -vnn:

00:14.2 Audio device [0403]: ATI Technologies Inc SB450 HDA Audio [1002:437b] (rev 01)
        Subsystem: ATI Technologies Inc SB450 HDA Audio [1002:437b]

Yet, autodetection is possible, since the codec properly reflects the vendor at
the Subsystem ID:

$ cat /proc/asound/card0/codec#0 |head -4

Codec: SigmaTel STAC9250
Address: 0
Vendor Id: 0x83847634
Subsystem Id: 0x107b0367

This patch adds a new autodetection function that seeks for codec subsystem ID.

Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Mauro Carvalho Chehab 2008-08-11 10:18:39 +02:00 committed by Takashi Iwai
parent ff7a326736
commit 2eda344546
2 changed files with 64 additions and 0 deletions

View file

@ -2704,6 +2704,67 @@ int snd_hda_check_board_config(struct hda_codec *codec,
}
EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
/**
* snd_hda_check_board_codec_sid_config - compare the current codec
subsystem ID with the
config table
This is important for Gateway notebooks with SB450 HDA Audio
where the vendor ID of the PCI device is:
ATI Technologies Inc SB450 HDA Audio [1002:437b]
and the vendor/subvendor are found only at the codec.
* @codec: the HDA codec
* @num_configs: number of config enums
* @models: array of model name strings
* @tbl: configuration table, terminated by null entries
*
* Compares the modelname or PCI subsystem id of the current codec with the
* given configuration table. If a matching entry is found, returns its
* config value (supposed to be 0 or positive).
*
* If no entries are matching, the function returns a negative value.
*/
int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
int num_configs, const char **models,
const struct snd_pci_quirk *tbl)
{
const struct snd_pci_quirk *q;
/* Search for codec ID */
for (q = tbl; q->subvendor; q++) {
unsigned long vendorid = (q->subdevice) | (q->subvendor << 16);
if (vendorid == codec->subsystem_id)
break;
}
if (!q->subvendor)
return -1;
tbl = q;
if (tbl->value >= 0 && tbl->value < num_configs) {
#ifdef CONFIG_SND_DEBUG_DETECT
char tmp[10];
const char *model = NULL;
if (models)
model = models[tbl->value];
if (!model) {
sprintf(tmp, "#%d", tbl->value);
model = tmp;
}
snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
"for config %x:%x (%s)\n",
model, tbl->subvendor, tbl->subdevice,
(tbl->name ? tbl->name : "Unknown device"));
#endif
return tbl->value;
}
return -1;
}
EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config);
/**
* snd_hda_add_new_ctls - create controls from the array
* @codec: the HDA codec

View file

@ -296,6 +296,9 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen);
int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
const char **modelnames,
const struct snd_pci_quirk *pci_list);
int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
int num_configs, const char **models,
const struct snd_pci_quirk *tbl);
int snd_hda_add_new_ctls(struct hda_codec *codec,
struct snd_kcontrol_new *knew);