summaryrefslogtreecommitdiff
path: root/sound/soc/sof/control.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/control.c')
-rw-r--r--sound/soc/sof/control.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c
index 2b8711eda362..7baf7f1507c3 100644
--- a/sound/soc/sof/control.c
+++ b/sound/soc/sof/control.c
@@ -11,8 +11,39 @@
/* Mixer Controls */
#include <linux/pm_runtime.h>
+#include <linux/leds.h>
#include "sof-priv.h"
+static void update_mute_led(struct snd_sof_control *scontrol,
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ unsigned int temp = 0;
+ unsigned int mask;
+ int i;
+
+ mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+ for (i = 0; i < scontrol->num_channels; i++) {
+ if (ucontrol->value.integer.value[i]) {
+ temp |= mask;
+ break;
+ }
+ }
+
+ if (temp == scontrol->led_ctl.led_value)
+ return;
+
+ scontrol->led_ctl.led_value = temp;
+
+#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
+ if (!scontrol->led_ctl.direction)
+ ledtrig_audio_set(LED_AUDIO_MUTE, temp ? LED_OFF : LED_ON);
+ else
+ ledtrig_audio_set(LED_AUDIO_MICMUTE, temp ? LED_OFF : LED_ON);
+#endif
+}
+
static inline u32 mixer_to_ipc(unsigned int value, u32 *volume_map, int size)
{
if (value >= size)
@@ -118,6 +149,9 @@ int snd_sof_switch_put(struct snd_kcontrol *kcontrol,
cdata->chanv[i].value = value;
}
+ if (scontrol->led_ctl.use_led)
+ update_mute_led(scontrol, kcontrol, ucontrol);
+
/* notify DSP of mixer updates */
if (pm_runtime_active(sdev->dev))
snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,