]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
ALSA: hda: cs35l41: Add read-only ALSA control for forced mute
authorStefan Binding <sbinding@opensource.cirrus.com>
Thu, 21 Sep 2023 16:28:49 +0000 (17:28 +0100)
committerTakashi Iwai <tiwai@suse.de>
Fri, 22 Sep 2023 08:47:50 +0000 (10:47 +0200)
When the CS35L41 amp is requested to mute using the ACPI
notification mechanism, userspace is not notified that the amp
is muted. To allow userspace to know about the mute, add an
ALSA control which tracks the forced mute override.
This control does not track the overall mute state of the amp,
since the amp is only unmuted during playback anyway, instead
it tracks the mute override request from the ACPI notification.

Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230921162849.1988124-5-sbinding@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/cs35l41_hda.c

index 18ca00c0a8cd1e3c48118c1bb89e0afab9d0d67b..92b815ce193b8bdb2bcfa2bd31a77d0040e187ec 100644 (file)
@@ -972,6 +972,15 @@ static int cs35l41_fw_load_ctl_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+static int cs35l41_mute_override_ctl_get(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_value *ucontrol)
+{
+       struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol);
+
+       ucontrol->value.integer.value[0] = cs35l41->mute_override;
+       return 0;
+}
+
 static void cs35l41_fw_load_work(struct work_struct *work)
 {
        struct cs35l41_hda *cs35l41 = container_of(work, struct cs35l41_hda, fw_load_work);
@@ -1055,6 +1064,7 @@ static int cs35l41_create_controls(struct cs35l41_hda *cs35l41)
 {
        char fw_type_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
        char fw_load_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+       char mute_override_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
        struct snd_kcontrol_new fw_type_ctl = {
                .name = fw_type_ctl_name,
                .iface = SNDRV_CTL_ELEM_IFACE_CARD,
@@ -1069,12 +1079,21 @@ static int cs35l41_create_controls(struct cs35l41_hda *cs35l41)
                .get = cs35l41_fw_load_ctl_get,
                .put = cs35l41_fw_load_ctl_put,
        };
+       struct snd_kcontrol_new mute_override_ctl = {
+               .name = mute_override_ctl_name,
+               .iface = SNDRV_CTL_ELEM_IFACE_CARD,
+               .info = snd_ctl_boolean_mono_info,
+               .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+               .get = cs35l41_mute_override_ctl_get,
+       };
        int ret;
 
        scnprintf(fw_type_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s DSP1 Firmware Type",
                  cs35l41->amp_name);
        scnprintf(fw_load_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s DSP1 Firmware Load",
                  cs35l41->amp_name);
+       scnprintf(mute_override_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s Forced Mute Status",
+                 cs35l41->amp_name);
 
        ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_type_ctl, cs35l41));
        if (ret) {
@@ -1092,6 +1111,15 @@ static int cs35l41_create_controls(struct cs35l41_hda *cs35l41)
 
        dev_dbg(cs35l41->dev, "Added Control %s\n", fw_load_ctl.name);
 
+       ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&mute_override_ctl, cs35l41));
+       if (ret) {
+               dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", mute_override_ctl.name,
+                       ret);
+               return ret;
+       }
+
+       dev_dbg(cs35l41->dev, "Added Control %s\n", mute_override_ctl.name);
+
        return 0;
 }