aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_generic.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2020-06-18 13:08:37 +0200
committerTakashi Iwai <tiwai@suse.de>2020-06-18 13:23:38 +0200
commit15509b6344726de22bdbfff88b65341dd0dd33af (patch)
tree52106f9e882474becd5c0f5ecdcf6ed46d3a6f8f /sound/pci/hda/hda_generic.c
parentALSA: hda: generic: Drop the old mic-mute LED hook (diff)
downloadlinux-dev-15509b6344726de22bdbfff88b65341dd0dd33af.tar.xz
linux-dev-15509b6344726de22bdbfff88b65341dd0dd33af.zip
ALSA: hda: generic: Add vmaster mute LED helper
Like mic-mute LED handling, add a new helper to deal with the master mute LED with LED classdev. Unlike the mic-mute case, the playback master mute is hooked on vmaster, and we suppose no nested hooks allowed there. The classdev creation code is factored out to a common function that is called from both mute and mic-mute LED helpers. Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com> Link: https://lore.kernel.org/r/20200618110842.27238-9-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
-rw-r--r--sound/pci/hda/hda_generic.c71
1 files changed, 59 insertions, 12 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index c97a1404af6b..c74519d7096b 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -3889,6 +3889,64 @@ static int parse_mic_boost(struct hda_codec *codec)
#ifdef CONFIG_SND_HDA_GENERIC_LEDS
/*
+ * vmaster mute LED hook helpers
+ */
+
+static int create_mute_led_cdev(struct hda_codec *codec,
+ int (*callback)(struct led_classdev *,
+ enum led_brightness),
+ bool micmute)
+{
+ struct led_classdev *cdev;
+
+ cdev = devm_kzalloc(&codec->core.dev, sizeof(*cdev), GFP_KERNEL);
+ if (!cdev)
+ return -ENOMEM;
+
+ cdev->name = micmute ? "hda::micmute" : "hda::mute";
+ cdev->max_brightness = 1;
+ cdev->default_trigger = micmute ? "audio-micmute" : "audio-mute";
+ cdev->brightness_set_blocking = callback;
+ cdev->brightness = ledtrig_audio_get(micmute ? LED_AUDIO_MICMUTE : LED_AUDIO_MUTE);
+
+ return devm_led_classdev_register(&codec->core.dev, cdev);
+}
+
+static void vmaster_update_mute_led(void *private_data, int enabled)
+{
+ ledtrig_audio_set(LED_AUDIO_MUTE, enabled ? LED_OFF : LED_ON);
+}
+
+/**
+ * snd_dha_gen_add_mute_led_cdev - Create a LED classdev and enable as vmaster mute LED
+ * @codec: the HDA codec
+ * @callback: the callback for LED classdev brightness_set_blocking
+ */
+int snd_hda_gen_add_mute_led_cdev(struct hda_codec *codec,
+ int (*callback)(struct led_classdev *,
+ enum led_brightness))
+{
+ struct hda_gen_spec *spec = codec->spec;
+ int err;
+
+ if (callback) {
+ err = create_mute_led_cdev(codec, callback, false);
+ if (err) {
+ codec_warn(codec, "failed to create a mute LED cdev\n");
+ return err;
+ }
+ }
+
+ if (spec->vmaster_mute.hook)
+ codec_err(codec, "vmaster hook already present before cdev!\n");
+
+ spec->vmaster_mute.hook = vmaster_update_mute_led;
+ spec->vmaster_mute_enum = 1;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_hda_gen_add_mute_led_cdev);
+
+/*
* mic mute LED hook helpers
*/
enum {
@@ -4029,20 +4087,9 @@ int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec,
enum led_brightness))
{
int err;
- struct led_classdev *cdev;
if (callback) {
- cdev = devm_kzalloc(&codec->core.dev, sizeof(*cdev), GFP_KERNEL);
- if (!cdev)
- return -ENOMEM;
-
- cdev->name = "hda::micmute";
- cdev->max_brightness = 1;
- cdev->default_trigger = "audio-micmute";
- cdev->brightness_set_blocking = callback;
- cdev->brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
-
- err = devm_led_classdev_register(&codec->core.dev, cdev);
+ err = create_mute_led_cdev(codec, callback, true);
if (err) {
codec_warn(codec, "failed to create a mic-mute LED cdev\n");
return err;