Skip to content

Commit

Permalink
ALSA: hda - Improve auto-cfg mixer name for ALC262
Browse files Browse the repository at this point in the history
Similar improvements for ALC262 codec like previous two commits:
assign a better name, either Master or Speaker, for the primary output
controls.

However, in the case of ALC262 codec, the necessary changes are larger
than others because we need to check the possibility of different mixer
amps depending on the pins.  The pin 0x16 is mono, and bound with the
dedicated mixer 0x0e while other pins are bound with 0x0c.  Thus, there
are two possible volumes.

When only one of them is used, we can name it as "Master".  OTOH, when
both are used at the same time, they have to be named uniquely.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Aug 25, 2009
1 parent 23112d6 commit c3fc1f5
Showing 1 changed file with 89 additions and 63 deletions.
152 changes: 89 additions & 63 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -10790,80 +10790,106 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
{ } /* end */
};

/* We use two mixers depending on the output pin; 0x16 is a mono output
* and thus it's bound with a different mixer.
* This function returns which mixer amp should be used.
*/
static int alc262_check_volbit(hda_nid_t nid)
{
if (!nid)
return 0;
else if (nid == 0x16)
return 2;
else
return 1;
}

static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
const char *pfx, int *vbits)
{
char name[32];
unsigned long val;
int vbit;

vbit = alc262_check_volbit(nid);
if (!vbit)
return 0;
if (*vbits & vbit) /* a volume control for this mixer already there */
return 0;
*vbits |= vbit;
snprintf(name, sizeof(name), "%s Playback Volume", pfx);
if (vbit == 2)
val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
else
val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
return add_control(spec, ALC_CTL_WIDGET_VOL, name, val);
}

static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
const char *pfx)
{
char name[32];
unsigned long val;

if (!nid)
return 0;
snprintf(name, sizeof(name), "%s Playback Switch", pfx);
if (nid == 0x16)
val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
else
val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
return add_control(spec, ALC_CTL_WIDGET_MUTE, name, val);
}

/* add playback controls from the parsed DAC table */
static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
const struct auto_pin_cfg *cfg)
{
hda_nid_t nid;
const char *pfx;
int vbits;
int err;

spec->multiout.num_dacs = 1; /* only use one dac */
spec->multiout.dac_nids = spec->private_dac_nids;
spec->multiout.dac_nids[0] = 2;

nid = cfg->line_out_pins[0];
if (nid) {
err = add_control(spec, ALC_CTL_WIDGET_VOL,
"Front Playback Volume",
HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
if (err < 0)
return err;
err = add_control(spec, ALC_CTL_WIDGET_MUTE,
"Front Playback Switch",
HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
if (err < 0)
return err;
}
if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
pfx = "Master";
else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
pfx = "Speaker";
else
pfx = "Front";
err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
if (err < 0)
return err;
err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
if (err < 0)
return err;
err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
if (err < 0)
return err;

nid = cfg->speaker_pins[0];
if (nid) {
if (nid == 0x16) {
err = add_control(spec, ALC_CTL_WIDGET_VOL,
"Speaker Playback Volume",
HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
HDA_OUTPUT));
if (err < 0)
return err;
err = add_control(spec, ALC_CTL_WIDGET_MUTE,
"Speaker Playback Switch",
HDA_COMPOSE_AMP_VAL(nid, 2, 0,
HDA_OUTPUT));
if (err < 0)
return err;
} else {
err = add_control(spec, ALC_CTL_WIDGET_MUTE,
"Speaker Playback Switch",
HDA_COMPOSE_AMP_VAL(nid, 3, 0,
HDA_OUTPUT));
if (err < 0)
return err;
}
}
nid = cfg->hp_pins[0];
if (nid) {
/* spec->multiout.hp_nid = 2; */
if (nid == 0x16) {
err = add_control(spec, ALC_CTL_WIDGET_VOL,
"Headphone Playback Volume",
HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
HDA_OUTPUT));
if (err < 0)
return err;
err = add_control(spec, ALC_CTL_WIDGET_MUTE,
"Headphone Playback Switch",
HDA_COMPOSE_AMP_VAL(nid, 2, 0,
HDA_OUTPUT));
if (err < 0)
return err;
} else {
err = add_control(spec, ALC_CTL_WIDGET_MUTE,
"Headphone Playback Switch",
HDA_COMPOSE_AMP_VAL(nid, 3, 0,
HDA_OUTPUT));
if (err < 0)
return err;
}
}
vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
alc262_check_volbit(cfg->speaker_pins[0]) |
alc262_check_volbit(cfg->hp_pins[0]);
if (vbits == 1 || vbits == 2)
pfx = "Master"; /* only one mixer is used */
else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
pfx = "Speaker";
else
pfx = "Front";
vbits = 0;
err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
if (err < 0)
return err;
err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
&vbits);
if (err < 0)
return err;
err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
&vbits);
if (err < 0)
return err;
return 0;
}

Expand Down

0 comments on commit c3fc1f5

Please sign in to comment.