Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2eda3445 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab Committed by Takashi Iwai
Browse files

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: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent ff7a3267
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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);