Commit 1f015f5f authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Fix double-headphone/speaker paths for Cxt auto-parser

When multiple headphones or speakers are assigned but no individual
DACs are available, the driver should take the first HP/SPK DAC instead
of another primary output.  The patch adds a bit-flag to dac field of
struct pin_dac_pair indicating that it's a slave DAC.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 3c715a98
...@@ -3348,6 +3348,8 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin, ...@@ -3348,6 +3348,8 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
#define MAX_AUTO_DACS 5 #define MAX_AUTO_DACS 5
#define DAC_SLAVE_FLAG 0x8000 /* filled dac is a slave */
/* fill analog DAC list from the widget tree */ /* fill analog DAC list from the widget tree */
static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs) static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
{ {
...@@ -3379,6 +3381,8 @@ static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins, ...@@ -3379,6 +3381,8 @@ static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
filled[nums].pin = pins[i]; filled[nums].pin = pins[i];
filled[nums].type = type; filled[nums].type = type;
filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest); filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
if (!filled[nums].dac && i > 0 && filled[0].dac)
filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG;
nums++; nums++;
} }
return nums; return nums;
...@@ -3407,7 +3411,7 @@ static void cx_auto_parse_output(struct hda_codec *codec) ...@@ -3407,7 +3411,7 @@ static void cx_auto_parse_output(struct hda_codec *codec)
/* fill multiout struct */ /* fill multiout struct */
for (i = 0; i < nums; i++) { for (i = 0; i < nums; i++) {
hda_nid_t dac = spec->dac_info[i].dac; hda_nid_t dac = spec->dac_info[i].dac;
if (!dac) if (!dac || (dac & DAC_SLAVE_FLAG))
continue; continue;
switch (spec->dac_info[i].type) { switch (spec->dac_info[i].type) {
case AUTO_PIN_LINE_OUT: case AUTO_PIN_LINE_OUT:
...@@ -4035,6 +4039,8 @@ static void cx_auto_init_output(struct hda_codec *codec) ...@@ -4035,6 +4039,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
nid = spec->dac_info[i].dac; nid = spec->dac_info[i].dac;
if (!nid) if (!nid)
nid = spec->multiout.dac_nids[0]; nid = spec->multiout.dac_nids[0];
else if (nid & DAC_SLAVE_FLAG)
nid &= ~DAC_SLAVE_FLAG;
select_connection(codec, spec->dac_info[i].pin, nid); select_connection(codec, spec->dac_info[i].pin, nid);
} }
if (spec->auto_mute) { if (spec->auto_mute) {
...@@ -4191,7 +4197,8 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) ...@@ -4191,7 +4197,8 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
for (i = 0; i < spec->dac_info_filled; i++) { for (i = 0; i < spec->dac_info_filled; i++) {
const char *label; const char *label;
int idx, type; int idx, type;
if (!spec->dac_info[i].dac) hda_nid_t dac = spec->dac_info[i].dac;
if (!dac || (dac & DAC_SLAVE_FLAG))
continue; continue;
type = spec->dac_info[i].type; type = spec->dac_info[i].type;
if (type == AUTO_PIN_LINE_OUT) if (type == AUTO_PIN_LINE_OUT)
...@@ -4211,7 +4218,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) ...@@ -4211,7 +4218,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
idx = num_spk++; idx = num_spk++;
break; break;
} }
err = try_add_pb_volume(codec, spec->dac_info[i].dac, err = try_add_pb_volume(codec, dac,
spec->dac_info[i].pin, spec->dac_info[i].pin,
label, idx); label, idx);
if (err < 0) if (err < 0)
......
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