2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-17 17:53:56 +08:00

ALSA: hda - Improve auto-cfg mixer name for ALC262

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>
This commit is contained in:
Takashi Iwai 2009-08-25 16:08:47 +02:00
parent 23112d6d2d
commit c3fc1f502a

View File

@ -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;
}