Skip to content

Commit e65bf99

Browse files
perexgtiwai
authored andcommitted
ALSA: HDA - remove the custom implementation for the audio LED trigger
With the new snd-ctl-led module, we have a generic way to trigger audio LEDs based on the sound control changes. Remove the custom implementation from the HDA driver. Move the LED initialization before snd_hda_gen_parse_auto_config() call in all drivers to create marked controls there. Signed-off-by: Jaroslav Kysela <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 22d8de6 commit e65bf99

File tree

9 files changed

+45
-235
lines changed

9 files changed

+45
-235
lines changed

sound/pci/hda/Kconfig

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,8 @@ comment "Set to Y if you want auto-loading the codec driver"
221221

222222
config SND_HDA_GENERIC
223223
tristate "Enable generic HD-audio codec parser"
224-
select NEW_LEDS if SND_HDA_GENERIC_LEDS
224+
select SND_CTL_LED if SND_HDA_GENERIC_LEDS
225225
select LEDS_CLASS if SND_HDA_GENERIC_LEDS
226-
select LEDS_TRIGGERS if SND_HDA_GENERIC_LEDS
227-
select LEDS_TRIGGER_AUDIO if SND_HDA_GENERIC_LEDS
228226
help
229227
Say Y or M here to enable the generic HD-audio codec parser
230228
in snd-hda-intel driver.

sound/pci/hda/hda_codec.c

Lines changed: 6 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,7 +1952,7 @@ static int add_follower(struct hda_codec *codec,
19521952
int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
19531953
unsigned int *tlv, const char * const *followers,
19541954
const char *suffix, bool init_follower_vol,
1955-
struct snd_kcontrol **ctl_ret)
1955+
unsigned int access, struct snd_kcontrol **ctl_ret)
19561956
{
19571957
struct snd_kcontrol *kctl;
19581958
int err;
@@ -1968,6 +1968,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
19681968
kctl = snd_ctl_make_virtual_master(name, tlv);
19691969
if (!kctl)
19701970
return -ENOMEM;
1971+
kctl->vd[0].access |= access;
19711972
err = snd_hda_ctl_add(codec, 0, kctl);
19721973
if (err < 0)
19731974
return err;
@@ -1994,87 +1995,29 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
19941995
}
19951996
EXPORT_SYMBOL_GPL(__snd_hda_add_vmaster);
19961997

1997-
/*
1998-
* mute-LED control using vmaster
1999-
*/
2000-
static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol,
2001-
struct snd_ctl_elem_info *uinfo)
2002-
{
2003-
static const char * const texts[] = {
2004-
"On", "Off", "Follow Master"
2005-
};
2006-
2007-
return snd_ctl_enum_info(uinfo, 1, 3, texts);
2008-
}
2009-
2010-
static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol,
2011-
struct snd_ctl_elem_value *ucontrol)
2012-
{
2013-
struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2014-
ucontrol->value.enumerated.item[0] = hook->mute_mode;
2015-
return 0;
2016-
}
2017-
2018-
static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
2019-
struct snd_ctl_elem_value *ucontrol)
2020-
{
2021-
struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2022-
unsigned int old_mode = hook->mute_mode;
2023-
2024-
hook->mute_mode = ucontrol->value.enumerated.item[0];
2025-
if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER)
2026-
hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
2027-
if (old_mode == hook->mute_mode)
2028-
return 0;
2029-
snd_hda_sync_vmaster_hook(hook);
2030-
return 1;
2031-
}
2032-
2033-
static const struct snd_kcontrol_new vmaster_mute_mode = {
2034-
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2035-
.name = "Mute-LED Mode",
2036-
.info = vmaster_mute_mode_info,
2037-
.get = vmaster_mute_mode_get,
2038-
.put = vmaster_mute_mode_put,
2039-
};
2040-
20411998
/* meta hook to call each driver's vmaster hook */
20421999
static void vmaster_hook(void *private_data, int enabled)
20432000
{
20442001
struct hda_vmaster_mute_hook *hook = private_data;
20452002

2046-
if (hook->mute_mode != HDA_VMUTE_FOLLOW_MASTER)
2047-
enabled = hook->mute_mode;
20482003
hook->hook(hook->codec, enabled);
20492004
}
20502005

20512006
/**
2052-
* snd_hda_add_vmaster_hook - Add a vmaster hook for mute-LED
2007+
* snd_hda_add_vmaster_hook - Add a vmaster hw specific hook
20532008
* @codec: the HDA codec
20542009
* @hook: the vmaster hook object
2055-
* @expose_enum_ctl: flag to create an enum ctl
20562010
*
2057-
* Add a mute-LED hook with the given vmaster switch kctl.
2058-
* When @expose_enum_ctl is set, "Mute-LED Mode" control is automatically
2059-
* created and associated with the given hook.
2011+
* Add a hw specific hook (like EAPD) with the given vmaster switch kctl.
20602012
*/
20612013
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
2062-
struct hda_vmaster_mute_hook *hook,
2063-
bool expose_enum_ctl)
2014+
struct hda_vmaster_mute_hook *hook)
20642015
{
2065-
struct snd_kcontrol *kctl;
2066-
20672016
if (!hook->hook || !hook->sw_kctl)
20682017
return 0;
20692018
hook->codec = codec;
2070-
hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
20712019
snd_ctl_add_vmaster_hook(hook->sw_kctl, vmaster_hook, hook);
2072-
if (!expose_enum_ctl)
2073-
return 0;
2074-
kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
2075-
if (!kctl)
2076-
return -ENOMEM;
2077-
return snd_hda_ctl_add(codec, 0, kctl);
2020+
return 0;
20782021
}
20792022
EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook);
20802023

sound/pci/hda/hda_generic.c

Lines changed: 25 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,8 @@ add_control(struct hda_gen_spec *spec, int type, const char *name,
981981
knew->index = cidx;
982982
if (get_amp_nid_(val))
983983
knew->subdevice = HDA_SUBDEV_AMP_FLAG;
984+
if (knew->access == 0)
985+
knew->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
984986
knew->private_value = val;
985987
return knew;
986988
}
@@ -3618,8 +3620,11 @@ static int add_single_cap_ctl(struct hda_codec *codec, const char *label,
36183620
amp_val_replace_channels(ctl, chs));
36193621
if (!knew)
36203622
return -ENOMEM;
3621-
if (is_switch)
3623+
if (is_switch) {
36223624
knew->put = cap_single_sw_put;
3625+
if (spec->mic_mute_led)
3626+
knew->access |= SNDRV_CTL_ELEM_ACCESS_MIC_LED;
3627+
}
36233628
if (!inv_dmic)
36243629
return 0;
36253630

@@ -3634,8 +3639,11 @@ static int add_single_cap_ctl(struct hda_codec *codec, const char *label,
36343639
amp_val_replace_channels(ctl, 2));
36353640
if (!knew)
36363641
return -ENOMEM;
3637-
if (is_switch)
3642+
if (is_switch) {
36383643
knew->put = cap_single_sw_put;
3644+
if (spec->mic_mute_led)
3645+
knew->access |= SNDRV_CTL_ELEM_ACCESS_MIC_LED;
3646+
}
36393647
return 0;
36403648
}
36413649

@@ -3676,6 +3684,8 @@ static int create_bind_cap_vol_ctl(struct hda_codec *codec, int idx,
36763684
knew->index = idx;
36773685
knew->private_value = sw_ctl;
36783686
knew->subdevice = HDA_SUBDEV_AMP_FLAG;
3687+
if (spec->mic_mute_led)
3688+
knew->access |= SNDRV_CTL_ELEM_ACCESS_MIC_LED;
36793689
}
36803690
return 0;
36813691
}
@@ -3917,11 +3927,6 @@ static int create_mute_led_cdev(struct hda_codec *codec,
39173927
return devm_led_classdev_register(&codec->core.dev, cdev);
39183928
}
39193929

3920-
static void vmaster_update_mute_led(void *private_data, int enabled)
3921-
{
3922-
ledtrig_audio_set(LED_AUDIO_MUTE, enabled ? LED_OFF : LED_ON);
3923-
}
3924-
39253930
/**
39263931
* snd_hda_gen_add_mute_led_cdev - Create a LED classdev and enable as vmaster mute LED
39273932
* @codec: the HDA codec
@@ -3945,134 +3950,11 @@ int snd_hda_gen_add_mute_led_cdev(struct hda_codec *codec,
39453950
if (spec->vmaster_mute.hook)
39463951
codec_err(codec, "vmaster hook already present before cdev!\n");
39473952

3948-
spec->vmaster_mute.hook = vmaster_update_mute_led;
3949-
spec->vmaster_mute_enum = 1;
3953+
spec->vmaster_mute_led = 1;
39503954
return 0;
39513955
}
39523956
EXPORT_SYMBOL_GPL(snd_hda_gen_add_mute_led_cdev);
39533957

3954-
/*
3955-
* mic mute LED hook helpers
3956-
*/
3957-
enum {
3958-
MICMUTE_LED_ON,
3959-
MICMUTE_LED_OFF,
3960-
MICMUTE_LED_FOLLOW_CAPTURE,
3961-
MICMUTE_LED_FOLLOW_MUTE,
3962-
};
3963-
3964-
static void call_micmute_led_update(struct hda_codec *codec)
3965-
{
3966-
struct hda_gen_spec *spec = codec->spec;
3967-
unsigned int val;
3968-
3969-
switch (spec->micmute_led.led_mode) {
3970-
case MICMUTE_LED_ON:
3971-
val = 1;
3972-
break;
3973-
case MICMUTE_LED_OFF:
3974-
val = 0;
3975-
break;
3976-
case MICMUTE_LED_FOLLOW_CAPTURE:
3977-
val = !!spec->micmute_led.capture;
3978-
break;
3979-
case MICMUTE_LED_FOLLOW_MUTE:
3980-
default:
3981-
val = !spec->micmute_led.capture;
3982-
break;
3983-
}
3984-
3985-
if (val == spec->micmute_led.led_value)
3986-
return;
3987-
spec->micmute_led.led_value = val;
3988-
ledtrig_audio_set(LED_AUDIO_MICMUTE,
3989-
spec->micmute_led.led_value ? LED_ON : LED_OFF);
3990-
}
3991-
3992-
static void update_micmute_led(struct hda_codec *codec,
3993-
struct snd_kcontrol *kcontrol,
3994-
struct snd_ctl_elem_value *ucontrol)
3995-
{
3996-
struct hda_gen_spec *spec = codec->spec;
3997-
unsigned int mask;
3998-
3999-
if (spec->micmute_led.old_hook)
4000-
spec->micmute_led.old_hook(codec, kcontrol, ucontrol);
4001-
4002-
if (!ucontrol)
4003-
return;
4004-
mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4005-
if (!strcmp("Capture Switch", ucontrol->id.name)) {
4006-
/* TODO: How do I verify if it's a mono or stereo here? */
4007-
if (ucontrol->value.integer.value[0] ||
4008-
ucontrol->value.integer.value[1])
4009-
spec->micmute_led.capture |= mask;
4010-
else
4011-
spec->micmute_led.capture &= ~mask;
4012-
call_micmute_led_update(codec);
4013-
}
4014-
}
4015-
4016-
static int micmute_led_mode_info(struct snd_kcontrol *kcontrol,
4017-
struct snd_ctl_elem_info *uinfo)
4018-
{
4019-
static const char * const texts[] = {
4020-
"On", "Off", "Follow Capture", "Follow Mute",
4021-
};
4022-
4023-
return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
4024-
}
4025-
4026-
static int micmute_led_mode_get(struct snd_kcontrol *kcontrol,
4027-
struct snd_ctl_elem_value *ucontrol)
4028-
{
4029-
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4030-
struct hda_gen_spec *spec = codec->spec;
4031-
4032-
ucontrol->value.enumerated.item[0] = spec->micmute_led.led_mode;
4033-
return 0;
4034-
}
4035-
4036-
static int micmute_led_mode_put(struct snd_kcontrol *kcontrol,
4037-
struct snd_ctl_elem_value *ucontrol)
4038-
{
4039-
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4040-
struct hda_gen_spec *spec = codec->spec;
4041-
unsigned int mode;
4042-
4043-
mode = ucontrol->value.enumerated.item[0];
4044-
if (mode > MICMUTE_LED_FOLLOW_MUTE)
4045-
mode = MICMUTE_LED_FOLLOW_MUTE;
4046-
if (mode == spec->micmute_led.led_mode)
4047-
return 0;
4048-
spec->micmute_led.led_mode = mode;
4049-
call_micmute_led_update(codec);
4050-
return 1;
4051-
}
4052-
4053-
static const struct snd_kcontrol_new micmute_led_mode_ctl = {
4054-
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4055-
.name = "Mic Mute-LED Mode",
4056-
.info = micmute_led_mode_info,
4057-
.get = micmute_led_mode_get,
4058-
.put = micmute_led_mode_put,
4059-
};
4060-
4061-
/* Set up the capture sync hook for controlling the mic-mute LED */
4062-
static int add_micmute_led_hook(struct hda_codec *codec)
4063-
{
4064-
struct hda_gen_spec *spec = codec->spec;
4065-
4066-
spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE;
4067-
spec->micmute_led.capture = 0;
4068-
spec->micmute_led.led_value = -1;
4069-
spec->micmute_led.old_hook = spec->cap_sync_hook;
4070-
spec->cap_sync_hook = update_micmute_led;
4071-
if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl))
4072-
return -ENOMEM;
4073-
return 0;
4074-
}
4075-
40763958
/**
40773959
* snd_hda_gen_add_micmute_led_cdev - Create a LED classdev and enable as mic-mute LED
40783960
* @codec: the HDA codec
@@ -4091,6 +3973,7 @@ int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec,
40913973
int (*callback)(struct led_classdev *,
40923974
enum led_brightness))
40933975
{
3976+
struct hda_gen_spec *spec = codec->spec;
40943977
int err;
40953978

40963979
if (callback) {
@@ -4101,7 +3984,8 @@ int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec,
41013984
}
41023985
}
41033986

4104-
return add_micmute_led_hook(codec);
3987+
spec->mic_mute_led = 1;
3988+
return 0;
41053989
}
41063990
EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led_cdev);
41073991
#endif /* CONFIG_SND_HDA_GENERIC_LEDS */
@@ -5060,6 +4944,9 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
50604944

50614945
parse_user_hints(codec);
50624946

4947+
if (spec->vmaster_mute_led || spec->mic_mute_led)
4948+
snd_ctl_led_request();
4949+
50634950
if (spec->mixer_nid && !spec->mixer_merge_nid)
50644951
spec->mixer_merge_nid = spec->mixer_nid;
50654952

@@ -5291,21 +5178,22 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
52915178
!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
52925179
err = snd_hda_add_vmaster(codec, "Master Playback Volume",
52935180
spec->vmaster_tlv, follower_pfxs,
5294-
"Playback Volume");
5181+
"Playback Volume", 0);
52955182
if (err < 0)
52965183
return err;
52975184
}
52985185
if (!spec->no_analog && !spec->suppress_vmaster &&
52995186
!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
53005187
err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
53015188
NULL, follower_pfxs,
5302-
"Playback Switch",
5303-
true, &spec->vmaster_mute.sw_kctl);
5189+
"Playback Switch", true,
5190+
spec->vmaster_mute_led ?
5191+
SNDRV_CTL_ELEM_ACCESS_SPK_LED : 0,
5192+
&spec->vmaster_mute.sw_kctl);
53045193
if (err < 0)
53055194
return err;
53065195
if (spec->vmaster_mute.hook) {
5307-
snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
5308-
spec->vmaster_mute_enum);
5196+
snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute);
53095197
snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
53105198
}
53115199
}

0 commit comments

Comments
 (0)