Skip to content

Commit

Permalink
ALSA: hda - Improve naming rule for primary output
Browse files Browse the repository at this point in the history
When the volume or mute control of the primary output is shared with
other (headphone or speaker) outputs, we shouldn't name it as a
specific output type but rather name it with the channel name or a
generic name like "PCM".

Also, this check should be performed individually for the volume and
the mute controls because some codecs may have shared volumes but
separate mute controls.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Jan 17, 2013
1 parent ac2e873 commit 247d85e
Showing 1 changed file with 42 additions and 17 deletions.
59 changes: 42 additions & 17 deletions sound/pci/hda/hda_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,19 +825,27 @@ static int add_stereo_sw(struct hda_codec *codec, const char *pfx,
return add_sw_ctl(codec, pfx, cidx, chs, path);
}

/* any ctl assigned to the path with the given index? */
static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type)
{
struct nid_path *path = snd_hda_get_path_from_idx(codec, path_idx);
return path && path->ctls[ctl_type];
}

static const char * const channel_name[4] = {
"Front", "Surround", "CLFE", "Side"
};

/* give some appropriate ctl name prefix for the given line out channel */
static const char *get_line_out_pfx(struct hda_gen_spec *spec, int ch,
bool can_be_master, int *index)
static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
int *index, int ctl_type)
{
struct hda_gen_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;

*index = 0;
if (cfg->line_outs == 1 && !spec->multi_ios &&
!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
!cfg->hp_outs && !cfg->speaker_outs)
return spec->vmaster_mute.hook ? "PCM" : "Master";

/* if there is really a single DAC used in the whole output paths,
Expand All @@ -847,24 +855,41 @@ static const char *get_line_out_pfx(struct hda_gen_spec *spec, int ch,
!spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
return spec->vmaster_mute.hook ? "PCM" : "Master";

/* multi-io channels */
if (ch >= cfg->line_outs)
return channel_name[ch];

switch (cfg->line_out_type) {
case AUTO_PIN_SPEAKER_OUT:
/* if the primary channel vol/mute is shared with HP volume,
* don't name it as Speaker
*/
if (!ch && cfg->hp_outs &&
!path_has_mixer(codec, spec->hp_paths[0], ctl_type))
break;
if (cfg->line_outs == 1)
return "Speaker";
if (cfg->line_outs == 2)
return ch ? "Bass Speaker" : "Speaker";
break;
case AUTO_PIN_HP_OUT:
/* if the primary channel vol/mute is shared with spk volume,
* don't name it as Headphone
*/
if (!ch && cfg->speaker_outs &&
!path_has_mixer(codec, spec->speaker_paths[0], ctl_type))
break;
/* for multi-io case, only the primary out */
if (ch && spec->multi_ios)
break;
*index = ch;
return "Headphone";
default:
if (cfg->line_outs == 1 && !spec->multi_ios)
return "PCM";
break;
}

/* for a single channel output, we don't have to name the channel */
if (cfg->line_outs == 1 && !spec->multi_ios)
return "PCM";

if (ch >= ARRAY_SIZE(channel_name)) {
snd_BUG();
return "PCM";
Expand Down Expand Up @@ -1626,16 +1651,11 @@ static int create_multi_out_ctls(struct hda_codec *codec,
int index;
struct nid_path *path;

if (i >= cfg->line_outs) {
index = 0;
name = channel_name[i];
} else {
name = get_line_out_pfx(spec, i, true, &index);
}

path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]);
if (!path)
continue;

name = get_line_out_pfx(codec, i, &index, NID_PATH_VOL_CTL);
if (!name || !strcmp(name, "CLFE")) {
/* Center/LFE */
err = add_vol_ctl(codec, "Center", 0, 1, path);
Expand All @@ -1644,16 +1664,21 @@ static int create_multi_out_ctls(struct hda_codec *codec,
err = add_vol_ctl(codec, "LFE", 0, 2, path);
if (err < 0)
return err;
} else {
err = add_stereo_vol(codec, name, index, path);
if (err < 0)
return err;
}

name = get_line_out_pfx(codec, i, &index, NID_PATH_MUTE_CTL);
if (!name || !strcmp(name, "CLFE")) {
err = add_sw_ctl(codec, "Center", 0, 1, path);
if (err < 0)
return err;
err = add_sw_ctl(codec, "LFE", 0, 2, path);
if (err < 0)
return err;
} else {
err = add_stereo_vol(codec, name, index, path);
if (err < 0)
return err;
err = add_stereo_sw(codec, name, index, path);
if (err < 0)
return err;
Expand Down

0 comments on commit 247d85e

Please sign in to comment.