Skip to content

Commit

Permalink
ALSA: hda/realtek - Use path-based parser for digital outputs
Browse files Browse the repository at this point in the history
Similar like analog output paths, use the path list for parsing and
initializing digital outputs as well.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Jan 12, 2013
1 parent c9967f1 commit fef7fbb
Showing 1 changed file with 22 additions and 20 deletions.
42 changes: 22 additions & 20 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,14 @@ static unsigned int alc_get_coef0(struct hda_codec *codec)
return spec->coef0;
}

static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
hda_nid_t pin, int pin_type,
hda_nid_t dac);
static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin,
bool is_digital);
static bool add_new_out_path(struct hda_codec *codec, hda_nid_t pin,
hda_nid_t dac);

/*
* Digital I/O handling
*/
Expand All @@ -1433,22 +1441,13 @@ static void alc_auto_init_digital(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
int i;
hda_nid_t pin, dac;
hda_nid_t pin;

for (i = 0; i < spec->autocfg.dig_outs; i++) {
pin = spec->autocfg.dig_out_pins[i];
if (!pin)
continue;
snd_hda_set_pin_ctl(codec, pin, PIN_OUT);
if (!i)
dac = spec->multiout.dig_out_nid;
else
dac = spec->slave_dig_outs[i - 1];
if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
continue;
snd_hda_codec_write(codec, dac, 0,
AC_VERB_SET_AMP_GAIN_MUTE,
AMP_OUT_UNMUTE);
alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
}
pin = spec->autocfg.dig_in_pin;
if (pin)
Expand All @@ -1465,13 +1464,10 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
/* support multiple SPDIFs; the secondary is set up as a slave */
nums = 0;
for (i = 0; i < spec->autocfg.dig_outs; i++) {
hda_nid_t conn[4];
err = snd_hda_get_connections(codec,
spec->autocfg.dig_out_pins[i],
conn, ARRAY_SIZE(conn));
if (err <= 0)
hda_nid_t pin = spec->autocfg.dig_out_pins[i];
dig_nid = alc_auto_look_for_dac(codec, pin, true);
if (!dig_nid)
continue;
dig_nid = conn[0]; /* assume the first element is audio-out */
if (!nums) {
spec->multiout.dig_out_nid = dig_nid;
spec->dig_out_type = spec->autocfg.dig_out_type[0];
Expand All @@ -1481,6 +1477,7 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
break;
spec->slave_dig_outs[nums - 1] = dig_nid;
}
add_new_out_path(codec, pin, dig_nid);
nums++;
}

Expand Down Expand Up @@ -2895,15 +2892,20 @@ static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
}

/* look for an empty DAC slot */
static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin,
bool is_digital)
{
struct alc_spec *spec = codec->spec;
bool cap_digital;
int i;

for (i = 0; i < spec->num_all_dacs; i++) {
hda_nid_t nid = spec->all_dacs[i];
if (!nid || alc_is_dac_already_used(codec, nid))
continue;
cap_digital = !!(get_wcaps(codec, nid) & AC_WCAP_DIGITAL);
if (is_digital != cap_digital)
continue;
if (is_reachable_path(codec, nid, pin))
return nid;
}
Expand Down Expand Up @@ -3169,7 +3171,7 @@ static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
for (i = 0; i < num_outs; i++) {
hda_nid_t pin = pins[i];
if (!dacs[i])
dacs[i] = alc_auto_look_for_dac(codec, pin);
dacs[i] = alc_auto_look_for_dac(codec, pin, false);
if (!dacs[i] && !i) {
for (j = 1; j < num_outs; j++) {
if (is_reachable_path(codec, dacs[j], pin)) {
Expand Down Expand Up @@ -4110,7 +4112,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec,
if (hardwired)
dac = get_dac_if_single(codec, nid);
else if (!dac)
dac = alc_auto_look_for_dac(codec, nid);
dac = alc_auto_look_for_dac(codec, nid, false);
if (!dac) {
badness++;
continue;
Expand Down

0 comments on commit fef7fbb

Please sign in to comment.