Merge branch 'for-linus' into for-next
[platform/kernel/linux-starfive.git] / sound / pci / hda / patch_realtek.c
index e62d588..0aa778f 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/dmi.h>
 #include <linux/module.h>
 #include <linux/input.h>
+#include <linux/leds.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include <sound/hda_codec.h>
@@ -81,6 +82,7 @@ struct alc_spec {
 
        /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
        int mute_led_polarity;
+       int micmute_led_polarity;
        hda_nid_t mute_led_nid;
        hda_nid_t cap_mute_led_nid;
 
@@ -4080,11 +4082,9 @@ static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
 
 /* update LED status via GPIO */
 static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
-                               bool enabled)
+                               int polarity, bool enabled)
 {
-       struct alc_spec *spec = codec->spec;
-
-       if (spec->mute_led_polarity)
+       if (polarity)
                enabled = !enabled;
        alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
 }
@@ -4095,7 +4095,8 @@ static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
        struct hda_codec *codec = private_data;
        struct alc_spec *spec = codec->spec;
 
-       alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
+       alc_update_gpio_led(codec, spec->gpio_mute_led_mask,
+                           spec->mute_led_polarity, enabled);
 }
 
 /* turn on/off mic-mute LED via GPIO per capture hook */
@@ -4104,9 +4105,30 @@ static void alc_gpio_micmute_update(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
 
        alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
+                           spec->micmute_led_polarity,
                            spec->gen.micmute_led.led_value);
 }
 
+#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
+static int micmute_led_set(struct led_classdev *led_cdev,
+                          enum led_brightness brightness)
+{
+       struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
+       struct alc_spec *spec = codec->spec;
+
+       alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
+                           spec->micmute_led_polarity, !!brightness);
+       return 0;
+}
+
+static struct led_classdev micmute_led_cdev = {
+       .name = "hda::micmute",
+       .max_brightness = 1,
+       .brightness_set_blocking = micmute_led_set,
+       .default_trigger = "audio-micmute",
+};
+#endif
+
 /* setup mute and mic-mute GPIO bits, add hooks appropriately */
 static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
                                  int action,
@@ -4114,6 +4136,9 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
                                  unsigned int micmute_mask)
 {
        struct alc_spec *spec = codec->spec;
+#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
+       int err;
+#endif
 
        alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
 
@@ -4126,6 +4151,13 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
        if (micmute_mask) {
                spec->gpio_mic_led_mask = micmute_mask;
                snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
+
+#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
+               micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
+               err = devm_led_classdev_register(&codec->core.dev, &micmute_led_cdev);
+               if (err)
+                       codec_warn(codec, "failed to register micmute LED\n");
+#endif
        }
 }
 
@@ -4138,7 +4170,11 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
 static void alc285_fixup_hp_gpio_led(struct hda_codec *codec,
                                const struct hda_fixup *fix, int action)
 {
-       alc_fixup_hp_gpio_led(codec, action, 0x04, 0x00);
+       struct alc_spec *spec = codec->spec;
+
+       spec->micmute_led_polarity = 1;
+
+       alc_fixup_hp_gpio_led(codec, action, 0x04, 0x01);
 }
 
 static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
@@ -5808,7 +5844,8 @@ static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
 
        snd_hda_gen_hp_automute(codec, jack);
        /* mute_led_polarity is set to 0, so we pass inverted value here */
-       alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
+       alc_update_gpio_led(codec, 0x10, spec->mute_led_polarity,
+                           !spec->gen.hp_jack_present);
 }
 
 /* Manage GPIOs for HP EliteBook Folio 9480m.