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

Commit 5b0cb1d8 authored by Jaroslav Kysela's avatar Jaroslav Kysela
Browse files

ALSA: hda - add more NID->Control mapping



This set of changes add missing NID values to some static control
elemenents. Also, it handles all "Capture Source" or "Input Source"
controls.

Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent f4054253
Loading
Loading
Loading
Loading
+62 −2
Original line number Diff line number Diff line
@@ -931,6 +931,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
#endif
	list_del(&codec->list);
	snd_array_free(&codec->mixers);
	snd_array_free(&codec->nids);
	codec->bus->caddr_tbl[codec->addr] = NULL;
	if (codec->patch_ops.free)
		codec->patch_ops.free(codec);
@@ -985,7 +986,8 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
	mutex_init(&codec->control_mutex);
	init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
	init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
	snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60);
	snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
	snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
	snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
	snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
	if (codec->bus->modelname) {
@@ -1706,7 +1708,7 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);

/**
 * snd_hda_ctl-add - Add a control element and assign to the codec
 * snd_hda_ctl_add - Add a control element and assign to the codec
 * @codec: HD-audio codec
 * @nid: corresponding NID (optional)
 * @kctl: the control element to assign
@@ -1746,6 +1748,35 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
}
EXPORT_SYMBOL_HDA(snd_hda_ctl_add);

/**
 * snd_hda_add_nid - Assign a NID to a control element
 * @codec: HD-audio codec
 * @nid: corresponding NID (optional)
 * @kctl: the control element to assign
 * @index: index to kctl
 *
 * Add the given control element to an array inside the codec instance.
 * This function is used when #snd_hda_ctl_add cannot be used for 1:1
 * NID:KCTL mapping - for example "Capture Source" selector.
 */
int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
		    unsigned int index, hda_nid_t nid)
{
	struct hda_nid_item *item;

	if (nid > 0) {
		item = snd_array_new(&codec->nids);
		if (!item)
			return -ENOMEM;
		item->kctl = kctl;
		item->index = index;
		item->nid = nid;
		return 0;
	}
	return -EINVAL;
}
EXPORT_SYMBOL_HDA(snd_hda_add_nid);

/**
 * snd_hda_ctls_clear - Clear all controls assigned to the given codec
 * @codec: HD-audio codec
@@ -1757,6 +1788,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
	for (i = 0; i < codec->mixers.used; i++)
		snd_ctl_remove(codec->bus->card, items[i].kctl);
	snd_array_free(&codec->mixers);
	snd_array_free(&codec->nids);
}

/* pseudo device locking
@@ -3476,6 +3508,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)

	for (; knew->name; knew++) {
		struct snd_kcontrol *kctl;
		if (knew->iface == -1)	/* skip this codec private value */
			continue;
		kctl = snd_ctl_new1(knew, codec);
		if (!kctl)
			return -ENOMEM;
@@ -3496,6 +3530,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
}
EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);

/**
 * snd_hda_add_nids - assign nids to controls from the array
 * @codec: the HDA codec
 * @kctl: struct snd_kcontrol
 * @index: index to kctl
 * @nids: the array of hda_nid_t
 * @size: count of hda_nid_t items
 *
 * This helper function assigns NIDs in the given array to a control element.
 *
 * Returns 0 if successful, or a negative error code.
 */
int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
		     unsigned int index, hda_nid_t *nids, unsigned int size)
{
	int err;

	for ( ; size > 0; size--, nids++) {
		err = snd_hda_add_nid(codec, kctl, index, *nids);
		if (err < 0)
			return err;
	}
	return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_add_nids);

#ifdef CONFIG_SND_HDA_POWER_SAVE
static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
				unsigned int power_state);
+1 −0
Original line number Diff line number Diff line
@@ -789,6 +789,7 @@ struct hda_codec {
	u32 *wcaps;

	struct snd_array mixers;	/* list of assigned mixer elements */
	struct snd_array nids;		/* list of mapped mixer elements */

	struct hda_cache_rec amp_cache;	/* cache for amp access */
	struct hda_cache_rec cmd_cache;	/* cache for other commands */
+2 −1
Original line number Diff line number Diff line
@@ -861,7 +861,8 @@ static int build_input_controls(struct hda_codec *codec)
	}

	/* create input MUX if multiple sources are available */
	err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&cap_sel, codec));
	err = snd_hda_ctl_add(codec, spec->adc_node->nid,
			      snd_ctl_new1(&cap_sel, codec));
	if (err < 0)
		return err;

+5 −0
Original line number Diff line number Diff line
@@ -342,6 +342,8 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
                               const struct snd_pci_quirk *tbl);
int snd_hda_add_new_ctls(struct hda_codec *codec,
			 struct snd_kcontrol_new *knew);
int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
		     unsigned int index, hda_nid_t *nids, unsigned int size);

/*
 * unsolicited event handler
@@ -466,11 +468,14 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);

struct hda_nid_item {
	struct snd_kcontrol *kctl;
	unsigned int index;
	hda_nid_t nid;
};

int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
		    struct snd_kcontrol *kctl);
int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
		    unsigned int index, hda_nid_t nid);
void snd_hda_ctls_clear(struct hda_codec *codec);

/*
+14 −9
Original line number Diff line number Diff line
@@ -61,18 +61,21 @@ static const char *get_wid_type_name(unsigned int wid_value)
		return "UNKNOWN Widget";
}

static void print_nid_mixers(struct snd_info_buffer *buffer,
			     struct hda_codec *codec, hda_nid_t nid)
static void print_nid_array(struct snd_info_buffer *buffer,
			    struct hda_codec *codec, hda_nid_t nid,
			    struct snd_array *array)
{
	int i;
	struct hda_nid_item *items = codec->mixers.list;
	struct hda_nid_item *items = array->list, *item;
	struct snd_kcontrol *kctl;
	for (i = 0; i < codec->mixers.used; i++) {
		if (items[i].nid == nid) {
			kctl = items[i].kctl;
	for (i = 0; i < array->used; i++) {
		item = &items[i];
		if (item->nid == nid) {
			kctl = item->kctl;
			snd_iprintf(buffer,
			  "  Control: name=\"%s\", index=%i, device=%i\n",
			  kctl->id.name, kctl->id.index, kctl->id.device);
			  kctl->id.name, kctl->id.index + item->index,
			  kctl->id.device);
		}
	}
}
@@ -528,7 +531,8 @@ static void print_gpio(struct snd_info_buffer *buffer,
			    (data & (1<<i)) ? 1 : 0,
			    (unsol & (1<<i)) ? 1 : 0);
	/* FIXME: add GPO and GPI pin information */
	print_nid_mixers(buffer, codec, nid);
	print_nid_array(buffer, codec, nid, &codec->mixers);
	print_nid_array(buffer, codec, nid, &codec->nids);
}

static void print_codec_info(struct snd_info_entry *entry,
@@ -608,7 +612,8 @@ static void print_codec_info(struct snd_info_entry *entry,
			snd_iprintf(buffer, " CP");
		snd_iprintf(buffer, "\n");

		print_nid_mixers(buffer, codec, nid);
		print_nid_array(buffer, codec, nid, &codec->mixers);
		print_nid_array(buffer, codec, nid, &codec->nids);
		print_nid_pcms(buffer, codec, nid);

		/* volume knob is a special widget that always have connection
Loading