summaryrefslogtreecommitdiff
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorStefan Binding <sbinding@opensource.cirrus.com>2023-09-21 19:28:49 +0300
committerTakashi Iwai <tiwai@suse.de>2023-09-22 11:47:50 +0300
commit4c870513fbb02b842408b840cf68ea8fe09ed82e (patch)
treec8249cdab307c4eb0294b3b3dae62c41c27f10ad /sound/pci/hda
parent447106e92a0c86c332d40710436f38f64c322cd6 (diff)
downloadlinux-4c870513fbb02b842408b840cf68ea8fe09ed82e.tar.xz
ALSA: hda: cs35l41: Add read-only ALSA control for forced mute
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>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/cs35l41_hda.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index 18ca00c0a8cd..92b815ce193b 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -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;
}