Skip to content

Commit 4825dba

Browse files
committed
audio: mic_privacy: Fix pricacy feature not working after D3 resume
When resuming from D3 state, the microphone privacy feature wasn't being properly restored. This led to failures in privacy tests, as the system didn't respond to privacy button inputs after a D3 transition. This patch fixes the issue by implementing proper state restoration in resume_dais(): - Re-initialize mic_privacy_manager when exiting D3 - Restore privacy settings based on saved state before D3 - Re-enable DMIC IRQ handlers to catch further privacy state changes - Add additional validation and logging to track D3 transition behavior The fix improves the mic_privacy_enable_dmic_irq function to handle D3 state transitions more robustly by immediately checking the IRQ status after re-enabling handlers to catch any events that may have occurred during D3. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
1 parent 9eed235 commit 4825dba

2 files changed

Lines changed: 62 additions & 2 deletions

File tree

src/audio/mic_privacy_manager/mic_privacy_manager_intel.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,29 @@ static void enable_fw_managed_irq(bool enable_irq)
6262

6363
void mic_privacy_enable_dmic_irq(bool enable_irq)
6464
{
65+
/* Only proceed if we have a valid device and API */
66+
if (!mic_priv_dev || !mic_privacy_api) {
67+
LOG_ERR("mic_privacy device or API not initialized");
68+
return;
69+
}
70+
6571
if (mic_privacy_api->get_policy() == MIC_PRIVACY_HW_MANAGED) {
66-
if (enable_irq)
72+
if (enable_irq) {
6773
mic_privacy_api->enable_dmic_irq(true, handle_dmic_irq);
68-
else
74+
75+
/* Check current status immediately to handle any transitions during D3 */
76+
if (mic_privacy_api->get_dmic_irq_status()) {
77+
struct mic_privacy_settings settings;
78+
uint32_t mic_disable_status =
79+
mic_privacy_api->get_dmic_mic_disable_status();
80+
81+
mic_privacy_fill_settings(&settings, mic_disable_status);
82+
mic_privacy_propagate_settings(&settings);
83+
mic_privacy_api->clear_dmic_irq_status();
84+
}
85+
} else {
6986
mic_privacy_api->enable_dmic_irq(false, NULL);
87+
}
7088
}
7189
}
7290

@@ -84,6 +102,9 @@ int mic_privacy_manager_init(void)
84102
LOG_INF("mic_privacy init FW_MANAGED mode");
85103
mic_privacy_api->set_fw_managed_mode(true);
86104
enable_fw_managed_irq(true);
105+
} else if (mic_privacy_policy == MIC_PRIVACY_HW_MANAGED) {
106+
LOG_INF("mic_privacy init HW_MANAGED mode");
107+
mic_privacy_api->enable_dmic_irq(true, handle_dmic_irq);
87108
}
88109

89110
return 0;

zephyr/lib/cpu.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
*/
1212

1313
#include <sof/audio/component.h>
14+
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
15+
#include <sof/audio/mic_privacy_manager.h>
16+
#ifdef CONFIG_ADSP_IMR_CONTEXT_SAVE
17+
static bool mic_privacy_enabled;
18+
#endif /* CONFIG_ADSP_IMR_CONTEXT_SAVE */
19+
#endif /* CONFIG_INTEL_ADSP_MIC_PRIVACY */
1420
#include <sof/init.h>
1521
#include <sof/lib/cpu.h>
1622
#include <sof/lib/pm_runtime.h>
@@ -64,6 +70,7 @@ extern void *global_imr_ram_storage;
6470
* data integrity across D3 transitions, which is critical for SOF's operation
6571
* and currently outside the scope of Zephyr's device-level PM capabilities.
6672
*/
73+
6774
static void suspend_dais(void)
6875
{
6976
struct ipc_comp_dev *icd;
@@ -79,6 +86,14 @@ static void suspend_dais(void)
7986

8087
mod = comp_mod(icd->cd);
8188
cd = module_get_private_data(mod);
89+
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
90+
if (cd->mic_priv) {
91+
if (mic_privacy_manager_get_policy() == MIC_PRIVACY_FW_MANAGED)
92+
mic_privacy_enabled = true;
93+
else
94+
mic_privacy_enabled = false;
95+
}
96+
#endif
8297
dd = cd->dd[0];
8398
if (dai_remove(dd->dai->dev) < 0) {
8499
tr_err(&zephyr_tr, "DAI suspend failed, type %d index %d",
@@ -95,6 +110,13 @@ static void resume_dais(void)
95110
struct copier_data *cd;
96111
struct dai_data *dd;
97112

113+
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
114+
/* Re-initialize mic privacy manager first to ensure proper state
115+
* before DAI resume
116+
*/
117+
mic_privacy_manager_init();
118+
#endif
119+
98120
list_for_item(clist, &ipc_get()->comp_list) {
99121
icd = container_of(clist, struct ipc_comp_dev, list);
100122
if (icd->type != COMP_TYPE_COMPONENT || dev_comp_type(icd->cd) != SOF_COMP_DAI)
@@ -107,6 +129,23 @@ static void resume_dais(void)
107129
tr_err(&zephyr_tr, "DAI resume failed, type %d index %d",
108130
dd->dai->type, dd->dai->index);
109131
}
132+
133+
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
134+
if (cd->mic_priv) {
135+
if (mic_privacy_enabled) {
136+
/* Need to restore MIC privacy settings */
137+
struct mic_privacy_settings settings;
138+
139+
/* Update privacy settings based on saved state */
140+
mic_privacy_fill_settings(&settings, MIC_PRIV_MUTED);
141+
mic_privacy_propagate_settings(&settings);
142+
/* Re-enable DMIC IRQ to handle further privacy state changes */
143+
mic_privacy_enable_dmic_irq(true);
144+
mic_privacy_enabled = false;
145+
tr_dbg(&zephyr_tr, "DMIC privacy settings restored after D3");
146+
}
147+
}
148+
#endif
110149
}
111150
}
112151
#endif /* CONFIG_ADSP_IMR_CONTEXT_SAVE */

0 commit comments

Comments
 (0)