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

Commit f3268512 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Refactor input-pin parser for VIA codecs



patch_via.c has redundant codes for parsing the input-pins.  Although
they are pretty similar, but all implemented in different functions
just because of hard-coded ids and slight incompatibilities.
This patch refactors the codes to use the common helper function,
resulting in the reduction of many lines.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 73413b12
Loading
Loading
Loading
Loading
+60 −330
Original line number Original line Diff line number Diff line
@@ -2413,51 +2413,53 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
}
}


/* create playback/capture controls for input pins */
/* create playback/capture controls for input pins */
static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
static int vt_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
					    const struct auto_pin_cfg *cfg,
					    hda_nid_t cap_nid,
					    hda_nid_t pin_idxs[], int num_idxs)
{
{
	static char *labels[] = {
		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
	};
	struct hda_input_mux *imux = &spec->private_imux[0];
	struct hda_input_mux *imux = &spec->private_imux[0];
	int i, err, idx = 0;
	int i, err, idx;


	/* for internal loopback recording select */
	/* for internal loopback recording select */
	for (idx = 0; idx < num_idxs; idx++) {
		if (pin_idxs[idx] == 0xff) {
			imux->items[imux->num_items].label = "Stereo Mixer";
			imux->items[imux->num_items].label = "Stereo Mixer";
			imux->items[imux->num_items].index = idx;
			imux->items[imux->num_items].index = idx;
			imux->num_items++;
			imux->num_items++;
			break;
		}
	}


	for (i = 0; i < AUTO_PIN_LAST; i++) {
	for (i = 0; i < AUTO_PIN_LAST; i++) {
		if (!cfg->input_pins[i])
		if (!cfg->input_pins[i])
			continue;
			continue;


		switch (cfg->input_pins[i]) {
		for (idx = 0; idx < num_idxs; idx++)
		case 0x1d: /* Mic */
			if (pin_idxs[idx] == cfg->input_pins[i])
			idx = 2;
				break;
				break;

		if (idx >= num_idxs)
		case 0x1e: /* Line In */
			continue;
			idx = 3;
		err = via_new_analog_input(spec, auto_pin_cfg_labels[i],
			break;
					   idx, cap_nid);

		case 0x21: /* Front Mic */
			idx = 4;
			break;

		case 0x24: /* CD */
			idx = 1;
			break;
		}
		err = via_new_analog_input(spec, labels[i], idx, 0x17);
		if (err < 0)
		if (err < 0)
			return err;
			return err;
		imux->items[imux->num_items].label = labels[i];
		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
		imux->items[imux->num_items].index = idx;
		imux->items[imux->num_items].index = idx;
		imux->num_items++;
		imux->num_items++;
	}
	}
	return 0;
	return 0;
}
}


/* create playback/capture controls for input pins */
static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
{
	static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
	return vt_auto_create_analog_input_ctls(spec, cfg, 0x17, pin_idxs,
						ARRAY_SIZE(pin_idxs));
}

#ifdef CONFIG_SND_HDA_POWER_SAVE
#ifdef CONFIG_SND_HDA_POWER_SAVE
static struct hda_amp_list vt1708_loopbacks[] = {
static struct hda_amp_list vt1708_loopbacks[] = {
	{ 0x17, HDA_INPUT, 1 },
	{ 0x17, HDA_INPUT, 1 },
@@ -3024,46 +3026,9 @@ static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
						const struct auto_pin_cfg *cfg)
{
{
	static char *labels[] = {
	static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
	return vt_auto_create_analog_input_ctls(spec, cfg, 0x18, pin_idxs,
	};
						ARRAY_SIZE(pin_idxs));
	struct hda_input_mux *imux = &spec->private_imux[0];
	int i, err, idx = 0;

	/* for internal loopback recording select */
	imux->items[imux->num_items].label = "Stereo Mixer";
	imux->items[imux->num_items].index = idx;
	imux->num_items++;

	for (i = 0; i < AUTO_PIN_LAST; i++) {
		if (!cfg->input_pins[i])
			continue;

		switch (cfg->input_pins[i]) {
		case 0x1d: /* Mic */
			idx = 2;
			break;

		case 0x1e: /* Line In */
			idx = 3;
			break;

		case 0x21: /* Front Mic */
			idx = 4;
			break;

		case 0x23: /* CD */
			idx = 1;
			break;
		}
		err = via_new_analog_input(spec, labels[i], idx, 0x18);
		if (err < 0)
			return err;
		imux->items[imux->num_items].label = labels[i];
		imux->items[imux->num_items].index = idx;
		imux->num_items++;
	}
	return 0;
}
}


static int vt1709_parse_auto_config(struct hda_codec *codec)
static int vt1709_parse_auto_config(struct hda_codec *codec)
@@ -3591,46 +3556,9 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
						const struct auto_pin_cfg *cfg)
{
{
	static char *labels[] = {
	static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
	return vt_auto_create_analog_input_ctls(spec, cfg, 0x16, pin_idxs,
	};
						ARRAY_SIZE(pin_idxs));
	struct hda_input_mux *imux = &spec->private_imux[0];
	int i, err, idx = 0;

	/* for internal loopback recording select */
	imux->items[imux->num_items].label = "Stereo Mixer";
	imux->items[imux->num_items].index = idx;
	imux->num_items++;

	for (i = 0; i < AUTO_PIN_LAST; i++) {
		if (!cfg->input_pins[i])
			continue;

		switch (cfg->input_pins[i]) {
		case 0x1a: /* Mic */
			idx = 2;
			break;

		case 0x1b: /* Line In */
			idx = 3;
			break;

		case 0x1e: /* Front Mic */
			idx = 4;
			break;

		case 0x1f: /* CD */
			idx = 1;
			break;
		}
		err = via_new_analog_input(spec, labels[i], idx, 0x16);
		if (err < 0)
			return err;
		imux->items[imux->num_items].label = labels[i];
		imux->items[imux->num_items].index = idx;
		imux->num_items++;
	}
	return 0;
}
}


static int vt1708B_parse_auto_config(struct hda_codec *codec)
static int vt1708B_parse_auto_config(struct hda_codec *codec)
@@ -4064,46 +3992,9 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
						const struct auto_pin_cfg *cfg)
{
{
	static char *labels[] = {
	static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
	return vt_auto_create_analog_input_ctls(spec, cfg, 0x16, pin_idxs,
	};
						ARRAY_SIZE(pin_idxs));
	struct hda_input_mux *imux = &spec->private_imux[0];
	int i, err, idx = 0;

	/* for internal loopback recording select */
	imux->items[imux->num_items].label = "Stereo Mixer";
	imux->items[imux->num_items].index = 5;
	imux->num_items++;

	for (i = 0; i < AUTO_PIN_LAST; i++) {
		if (!cfg->input_pins[i])
			continue;

		switch (cfg->input_pins[i]) {
		case 0x1a: /* Mic */
			idx = 2;
			break;

		case 0x1b: /* Line In */
			idx = 3;
			break;

		case 0x1e: /* Front Mic */
			idx = 4;
			break;

		case 0x1f: /* CD */
			idx = 1;
			break;
		}
		err = via_new_analog_input(spec, labels[i], idx, 0x16);
		if (err < 0)
			return err;
		imux->items[imux->num_items].label = labels[i];
		imux->items[imux->num_items].index = idx-1;
		imux->num_items++;
	}
	return 0;
}
}


/* fill out digital output widgets; one for master and one for slave outputs */
/* fill out digital output widgets; one for master and one for slave outputs */
@@ -4457,42 +4348,9 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
						const struct auto_pin_cfg *cfg)
{
{
	static char *labels[] = {
	static hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
	return vt_auto_create_analog_input_ctls(spec, cfg, 0x1a, pin_idxs,
	};
						ARRAY_SIZE(pin_idxs));
	struct hda_input_mux *imux = &spec->private_imux[0];
	int i, err, idx = 0;

	/* for internal loopback recording select */
	imux->items[imux->num_items].label = "Stereo Mixer";
	imux->items[imux->num_items].index = 3;
	imux->num_items++;

	for (i = 0; i < AUTO_PIN_LAST; i++) {
		if (!cfg->input_pins[i])
			continue;

		switch (cfg->input_pins[i]) {
		case 0x14: /* Mic */
			idx = 1;
			break;

		case 0x15: /* Line In */
			idx = 2;
			break;

		case 0x18: /* Front Mic */
			idx = 3;
			break;
		}
		err = via_new_analog_input(spec, labels[i], idx, 0x1A);
		if (err < 0)
			return err;
		imux->items[imux->num_items].label = labels[i];
		imux->items[imux->num_items].index = idx-1;
		imux->num_items++;
	}
	return 0;
}
}


static int vt1702_parse_auto_config(struct hda_codec *codec)
static int vt1702_parse_auto_config(struct hda_codec *codec)
@@ -4875,46 +4733,9 @@ static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1718S_auto_create_analog_input_ctls(struct via_spec *spec,
static int vt1718S_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
						const struct auto_pin_cfg *cfg)
{
{
	static char *labels[] = {
	static hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
	return vt_auto_create_analog_input_ctls(spec, cfg, 0x21, pin_idxs,
	};
						ARRAY_SIZE(pin_idxs));
	struct hda_input_mux *imux = &spec->private_imux[0];
	int i, err, idx = 0;

	/* for internal loopback recording select */
	imux->items[imux->num_items].label = "Stereo Mixer";
	imux->items[imux->num_items].index = 5;
	imux->num_items++;

	for (i = 0; i < AUTO_PIN_LAST; i++) {
		if (!cfg->input_pins[i])
			continue;

		switch (cfg->input_pins[i]) {
		case 0x2b: /* Mic */
			idx = 1;
			break;

		case 0x2a: /* Line In */
			idx = 2;
			break;

		case 0x29: /* Front Mic */
			idx = 3;
			break;

		case 0x2c: /* CD */
			idx = 0;
			break;
		}
		err = via_new_analog_input(spec, labels[i], idx, 0x21);
		if (err < 0)
			return err;
		imux->items[imux->num_items].label = labels[i];
		imux->items[imux->num_items].index = idx;
		imux->num_items++;
	}
	return 0;
}
}


static int vt1718S_parse_auto_config(struct hda_codec *codec)
static int vt1718S_parse_auto_config(struct hda_codec *codec)
@@ -5374,46 +5195,9 @@ static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1716S_auto_create_analog_input_ctls(struct via_spec *spec,
static int vt1716S_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
						const struct auto_pin_cfg *cfg)
{
{
	static char *labels[] = {
	static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
	return vt_auto_create_analog_input_ctls(spec, cfg, 0x16, pin_idxs,
	};
						ARRAY_SIZE(pin_idxs));
	struct hda_input_mux *imux = &spec->private_imux[0];
	int i, err, idx = 0;

	/* for internal loopback recording select */
	imux->items[imux->num_items].label = "Stereo Mixer";
	imux->items[imux->num_items].index = 5;
	imux->num_items++;

	for (i = 0; i < AUTO_PIN_LAST; i++) {
		if (!cfg->input_pins[i])
			continue;

		switch (cfg->input_pins[i]) {
		case 0x1a: /* Mic */
			idx = 2;
			break;

		case 0x1b: /* Line In */
			idx = 3;
			break;

		case 0x1e: /* Front Mic */
			idx = 4;
			break;

		case 0x1f: /* CD */
			idx = 1;
			break;
		}
		err = via_new_analog_input(spec, labels[i], idx, 0x16);
		if (err < 0)
			return err;
		imux->items[imux->num_items].label = labels[i];
		imux->items[imux->num_items].index = idx-1;
		imux->num_items++;
	}
	return 0;
}
}


static int vt1716S_parse_auto_config(struct hda_codec *codec)
static int vt1716S_parse_auto_config(struct hda_codec *codec)
@@ -5720,47 +5504,19 @@ static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec,
static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
						const struct auto_pin_cfg *cfg)
{
{
	static char *labels[] = {
		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
	};
	struct hda_input_mux *imux = &spec->private_imux[0];
	struct hda_input_mux *imux = &spec->private_imux[0];
	int i, err, idx = 0;
	static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };

	int err;
	for (i = 0; i < AUTO_PIN_LAST; i++) {
		if (!cfg->input_pins[i])
			continue;

		switch (cfg->input_pins[i]) {
		case 0x2b: /* Mic */
			idx = 0;
			break;

		case 0x2a: /* Line In */
			idx = 1;
			break;


		case 0x29: /* Front Mic */
	err = vt_auto_create_analog_input_ctls(spec, cfg, 0x21, pin_idxs,
			idx = 2;
					       ARRAY_SIZE(pin_idxs));
			break;
		}
		err = via_new_analog_input(spec, labels[i], idx, 0x21);
	if (err < 0)
	if (err < 0)
		return err;
		return err;
		imux->items[imux->num_items].label = labels[i];
		imux->items[imux->num_items].index = idx;
		imux->num_items++;
	}

	/* build volume/mute control of loopback */
	/* build volume/mute control of loopback */
	err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21);
	err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21);
	if (err < 0)
	if (err < 0)
		return err;
		return err;


	/* for internal loopback recording select */
	imux->items[imux->num_items].label = "Stereo Mixer";
	imux->items[imux->num_items].index = 3;
	imux->num_items++;

	/* for digital mic select */
	/* for digital mic select */
	imux->items[imux->num_items].label = "Digital Mic";
	imux->items[imux->num_items].label = "Digital Mic";
	imux->items[imux->num_items].index = 4;
	imux->items[imux->num_items].index = 4;
@@ -6070,46 +5826,20 @@ static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec,
static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec,
						const struct auto_pin_cfg *cfg)
						const struct auto_pin_cfg *cfg)
{
{
	static char *labels[] = {
		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
	};
	struct hda_input_mux *imux = &spec->private_imux[0];
	struct hda_input_mux *imux = &spec->private_imux[0];
	int i, err, idx = 0;
	static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };

	int err;
	for (i = 0; i < AUTO_PIN_LAST; i++) {
		if (!cfg->input_pins[i])
			continue;

		switch (cfg->input_pins[i]) {
		case 0x2b: /* Mic */
			idx = 0;
			break;

		case 0x2a: /* Line In */
			idx = 1;
			break;


		case 0x29: /* Front Mic */
	err = vt_auto_create_analog_input_ctls(spec, cfg, 0x21, pin_idxs,
			idx = 2;
					       ARRAY_SIZE(pin_idxs));
			break;
		}
		err = via_new_analog_input(spec, labels[i], idx, 0x21);
	if (err < 0)
	if (err < 0)
		return err;
		return err;
		imux->items[imux->num_items].label = labels[i];

		imux->items[imux->num_items].index = idx;
		imux->num_items++;
	}
	/* build volume/mute control of loopback */
	/* build volume/mute control of loopback */
	err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21);
	err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21);
	if (err < 0)
	if (err < 0)
		return err;
		return err;


	/* for internal loopback recording select */
	imux->items[imux->num_items].label = "Stereo Mixer";
	imux->items[imux->num_items].index = 5;
	imux->num_items++;

	/* for digital mic select */
	/* for digital mic select */
	imux->items[imux->num_items].label = "Digital Mic";
	imux->items[imux->num_items].label = "Digital Mic";
	imux->items[imux->num_items].index = 6;
	imux->items[imux->num_items].index = 6;