ALSA: hda - Add expose_enum_ctl flag to snd_hda_add_vmaster_hook()
Since it's not always safe to assume that the vmaster hook is purely the mute-LED control, add the flag indicating whether to expose the mute-LED enum control or not. Currently, conexant codec sets this off for non-HP laptops where EAPD may be used really as EAPD. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
d2f344b5e0
commit
f29735cbef
@ -2508,7 +2508,8 @@ static struct snd_kcontrol_new vmaster_mute_mode = {
|
|||||||
* the given hook.
|
* the given hook.
|
||||||
*/
|
*/
|
||||||
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
||||||
struct hda_vmaster_mute_hook *hook)
|
struct hda_vmaster_mute_hook *hook,
|
||||||
|
bool expose_enum_ctl)
|
||||||
{
|
{
|
||||||
struct snd_kcontrol *kctl;
|
struct snd_kcontrol *kctl;
|
||||||
|
|
||||||
@ -2517,6 +2518,8 @@ int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
|||||||
snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
|
snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
|
||||||
hook->codec = codec;
|
hook->codec = codec;
|
||||||
hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
|
hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
|
||||||
|
if (!expose_enum_ctl)
|
||||||
|
return 0;
|
||||||
kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
|
kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
|
||||||
if (!kctl)
|
if (!kctl)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -165,7 +165,8 @@ struct hda_vmaster_mute_hook {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
||||||
struct hda_vmaster_mute_hook *hook);
|
struct hda_vmaster_mute_hook *hook,
|
||||||
|
bool expose_enum_ctl);
|
||||||
void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
|
void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
|
||||||
|
|
||||||
/* amp value bits */
|
/* amp value bits */
|
||||||
|
@ -71,6 +71,7 @@ struct conexant_spec {
|
|||||||
int num_mixers;
|
int num_mixers;
|
||||||
hda_nid_t vmaster_nid;
|
hda_nid_t vmaster_nid;
|
||||||
struct hda_vmaster_mute_hook vmaster_mute;
|
struct hda_vmaster_mute_hook vmaster_mute;
|
||||||
|
bool vmaster_mute_led;
|
||||||
|
|
||||||
const struct hda_verb *init_verbs[5]; /* initialization verbs
|
const struct hda_verb *init_verbs[5]; /* initialization verbs
|
||||||
* don't forget NULL
|
* don't forget NULL
|
||||||
@ -4346,8 +4347,10 @@ static int cx_auto_build_controls(struct hda_codec *codec)
|
|||||||
err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
|
err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (spec->vmaster_mute.hook && spec->vmaster_mute.sw_kctl) {
|
if (spec->vmaster_mute.sw_kctl) {
|
||||||
err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute);
|
spec->vmaster_mute.hook = cx_auto_vmaster_hook;
|
||||||
|
err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
|
||||||
|
spec->vmaster_mute_led);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -4476,11 +4479,17 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
|||||||
|
|
||||||
apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
|
apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
|
||||||
|
|
||||||
/* add EAPD vmaster hook to all HP machines */
|
/* Show mute-led control only on HP laptops
|
||||||
/* NOTE: this should be applied via fixup once when the generic
|
* This is a sort of white-list: on HP laptops, EAPD corresponds
|
||||||
* fixup code is merged to hda_codec.c
|
* only to the mute-LED without actualy amp function. Meanwhile,
|
||||||
|
* others may use EAPD really as an amp switch, so it might be
|
||||||
|
* not good to expose it blindly.
|
||||||
*/
|
*/
|
||||||
spec->vmaster_mute.hook = cx_auto_vmaster_hook;
|
switch (codec->subsystem_id >> 16) {
|
||||||
|
case 0x103c:
|
||||||
|
spec->vmaster_mute_led = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
err = cx_auto_search_adcs(codec);
|
err = cx_auto_search_adcs(codec);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -5895,7 +5895,7 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec,
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
case ALC_FIXUP_ACT_BUILD:
|
case ALC_FIXUP_ACT_BUILD:
|
||||||
spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook;
|
spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook;
|
||||||
snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute);
|
snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
|
||||||
/* fallthru */
|
/* fallthru */
|
||||||
case ALC_FIXUP_ACT_INIT:
|
case ALC_FIXUP_ACT_INIT:
|
||||||
snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
|
snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
|
||||||
|
@ -1166,7 +1166,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
|
|||||||
|
|
||||||
if (spec->gpio_led) {
|
if (spec->gpio_led) {
|
||||||
spec->vmaster_mute.hook = stac92xx_vmaster_hook;
|
spec->vmaster_mute.hook = stac92xx_vmaster_hook;
|
||||||
err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute);
|
err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user