@@ -651,7 +651,11 @@ sof_ipc4_volsw_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
651651
652652struct sof_ipc4_kcontrol_global_priv {
653653 struct snd_card * snd_card ;
654- struct snd_kcontrol * capture_hw_mute ;
654+ struct sof_ipc4_kcontrol_global_capture_hw_mute {
655+ struct snd_kcontrol * kctl ;
656+ bool force_muted ; /* If true mute state indicator forced to muted */
657+ bool last_reported ; /* The latest mute state received from FW */
658+ } capture_hw_mute ;
655659};
656660
657661static int sof_ipc4_capture_hw_mute_get (struct snd_kcontrol * kcontrol ,
@@ -717,10 +721,13 @@ static int sof_ipc4_create_non_topology_controls(struct snd_sof_dev *sdev,
717721 kctl -> private_value = 0 ;
718722
719723 ret = snd_ctl_add (snd_card , kctl );
720- if (ret < 0 )
724+ if (ret >= 0 ) {
725+ priv -> capture_hw_mute .kctl = kctl ;
726+ priv -> capture_hw_mute .force_muted = false;
727+ priv -> capture_hw_mute .last_reported = false;
728+ } else {
721729 dev_err (dev , "%s: snd_ctl_add(): failed" , __func__ );
722- else
723- priv -> capture_hw_mute = kctl ;
730+ }
724731 }
725732
726733 ipc4_data -> global_kcontrol_priv = priv ;
@@ -736,13 +743,19 @@ static void snd_ipc4_global_capture_hw_mute_report(struct snd_sof_dev *sdev,
736743 struct device * dev = sdev -> dev ;
737744 struct snd_kcontrol * kctl ;
738745
739- if (!priv || !priv -> capture_hw_mute )
746+ if (!priv || !priv -> capture_hw_mute . kctl )
740747 return ;
741748
742- kctl = priv -> capture_hw_mute ;
749+ kctl = priv -> capture_hw_mute . kctl ;
743750
744- dev_dbg (dev , "%s: reporting %u, old %lu" , __func__ ,
745- status , kctl -> private_value );
751+ dev_dbg (dev , "%s: new %u, old %lu, last %u force %u" , __func__ ,
752+ status , kctl -> private_value , priv -> capture_hw_mute .last_reported ,
753+ priv -> capture_hw_mute .force_muted );
754+
755+ priv -> capture_hw_mute .last_reported = status ;
756+
757+ if (priv -> capture_hw_mute .force_muted )
758+ status = false;
746759
747760 if (kctl -> private_value == status )
748761 return ;
@@ -751,6 +764,19 @@ static void snd_ipc4_global_capture_hw_mute_report(struct snd_sof_dev *sdev,
751764 snd_ctl_notify (priv -> snd_card , SNDRV_CTL_EVENT_MASK_VALUE , & kctl -> id );
752765}
753766
767+ void snd_ipc4_global_capture_hw_mute_force (struct snd_sof_dev * sdev , bool force )
768+ {
769+ struct sof_ipc4_fw_data * ipc4_data = sdev -> private ;
770+ struct sof_ipc4_kcontrol_global_priv * priv = ipc4_data -> global_kcontrol_priv ;
771+
772+ if (!priv )
773+ return ;
774+
775+ priv -> capture_hw_mute .force_muted = force ;
776+
777+ snd_ipc4_global_capture_hw_mute_report (sdev , priv -> capture_hw_mute .last_reported );
778+ }
779+
754780static void snd_ipc4_handle_global_event (struct snd_sof_dev * sdev ,
755781 struct sof_ipc4_control_msg_payload * msg_data )
756782{
0 commit comments