Skip to content

Commit 9f9d3a8

Browse files
ujfalusiranj063
authored andcommitted
ASoC: SOF: ipc4: Add support for Intel HW managed mic privacy messaging
ACE3 (Panther Lake) introduced support for microphone privacy feature which can - in hardware - mute incoming audio data based on a state of a physical switch. The change in the privacy state is delivered through interface IP blocks and can only be handled by the link owner. In Intel platforms Soundwire is for example host owned, so the interrupt can only be handled by the host. Since the input stream is going to be muted by hardware, the host needs to send a message to firmware about the change in privacy so it can execute a fade out/in to enhance user experience. The support for microphone privacy can be queried from the HW_CONFIG data under the INTEL_MIC_PRIVACY_CAP tuple. This is Intel specific data, the core will pass it to platform code if the intel_configure_mic_privacy() callback is provided. Platform code can call sof_ipc4_mic_privacy_state_change() to send the IPC message to the firmware on state change. Signed-off-by: Peter Ujfalusi <[email protected]>
1 parent c5310ac commit 9f9d3a8

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

include/sound/sof/ipc4/header.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ enum sof_ipc4_base_fw_params {
400400
SOF_IPC4_FW_PARAM_MODULES_INFO_GET,
401401
SOF_IPC4_FW_PARAM_LIBRARIES_INFO_GET = 16,
402402
SOF_IPC4_FW_PARAM_SYSTEM_TIME = 20,
403+
SOF_IPC4_FW_PARAM_MIC_PRIVACY_STATE_CHANGE = 35,
403404
};
404405

405406
enum sof_ipc4_fw_config_params {
@@ -450,6 +451,18 @@ struct sof_ipc4_dx_state_info {
450451
uint32_t dx_mask;
451452
} __packed __aligned(4);
452453

454+
enum sof_ipc4_hw_config_params {
455+
SOF_IPC4_HW_CFG_INTEL_MIC_PRIVACY_CAPS = 11,
456+
};
457+
458+
#define SOF_IPC_INTEL_MIC_PRIVACY_VERSION_PTL 1
459+
460+
struct sof_ipc4_intel_mic_privacy_cap {
461+
uint32_t version;
462+
uint32_t capabilities_length;
463+
uint32_t capabilities[];
464+
} __packed;
465+
453466
/* Reply messages */
454467

455468
/*

sound/soc/sof/ipc4-loader.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,39 @@ int sof_ipc4_query_fw_configuration(struct snd_sof_dev *sdev)
511511
offset += sizeof(*tuple) + tuple->size;
512512
}
513513

514+
/* Get the hardware configuration */
515+
msg.primary = SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
516+
msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
517+
msg.primary |= SOF_IPC4_MOD_ID(SOF_IPC4_MOD_INIT_BASEFW_MOD_ID);
518+
msg.primary |= SOF_IPC4_MOD_INSTANCE(SOF_IPC4_MOD_INIT_BASEFW_INSTANCE_ID);
519+
msg.extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_FW_PARAM_HW_CONFIG_GET);
520+
521+
msg.data_size = sdev->ipc->max_payload_size;
522+
523+
ret = iops->set_get_data(sdev, &msg, msg.data_size, false);
524+
if (ret)
525+
goto out;
526+
527+
offset = 0;
528+
while (offset < msg.data_size) {
529+
tuple = (struct sof_ipc4_tuple *)((u8 *)msg.data_ptr + offset);
530+
531+
switch (tuple->type) {
532+
case SOF_IPC4_HW_CFG_INTEL_MIC_PRIVACY_CAPS:
533+
if (ipc4_data->intel_configure_mic_privacy) {
534+
struct sof_ipc4_intel_mic_privacy_cap *caps;
535+
536+
caps = (struct sof_ipc4_intel_mic_privacy_cap *)tuple->value;
537+
ipc4_data->intel_configure_mic_privacy(sdev, caps);
538+
}
539+
break;
540+
default:
541+
break;
542+
}
543+
544+
offset += sizeof(*tuple) + tuple->size;
545+
}
546+
514547
out:
515548
kfree(msg.data_ptr);
516549

sound/soc/sof/ipc4-priv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <linux/idr.h>
1313
#include <sound/sof/ext_manifest4.h>
14+
#include <sound/sof/ipc4/header.h>
1415
#include "sof-priv.h"
1516

1617
/* The DSP window indices are fixed */
@@ -89,6 +90,8 @@ struct sof_ipc4_fw_data {
8990

9091
int (*load_library)(struct snd_sof_dev *sdev,
9192
struct sof_ipc4_fw_library *fw_lib, bool reload);
93+
void (*intel_configure_mic_privacy)(struct snd_sof_dev *sdev,
94+
struct sof_ipc4_intel_mic_privacy_cap *caps);
9295
struct mutex pipeline_state_mutex; /* protect pipeline triggers, ref counts and states */
9396
};
9497

@@ -118,4 +121,6 @@ void sof_ipc4_update_cpc_from_manifest(struct snd_sof_dev *sdev,
118121
size_t sof_ipc4_find_debug_slot_offset_by_type(struct snd_sof_dev *sdev,
119122
u32 slot_type);
120123

124+
void sof_ipc4_mic_privacy_state_change(struct snd_sof_dev *sdev, bool state);
125+
121126
#endif

sound/soc/sof/ipc4.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,3 +851,21 @@ const struct sof_ipc_ops ipc4_ops = {
851851
.pcm = &ipc4_pcm_ops,
852852
.fw_tracing = &ipc4_mtrace_ops,
853853
};
854+
855+
void sof_ipc4_mic_privacy_state_change(struct snd_sof_dev *sdev, bool state)
856+
{
857+
struct sof_ipc4_msg msg;
858+
u32 data = state;
859+
860+
msg.primary = SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
861+
msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
862+
msg.primary |= SOF_IPC4_MOD_ID(SOF_IPC4_MOD_INIT_BASEFW_MOD_ID);
863+
msg.primary |= SOF_IPC4_MOD_INSTANCE(SOF_IPC4_MOD_INIT_BASEFW_INSTANCE_ID);
864+
msg.extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_FW_PARAM_MIC_PRIVACY_STATE_CHANGE);
865+
866+
msg.data_size = sizeof(data);
867+
msg.data_ptr = &data;
868+
869+
sof_ipc4_set_get_data(sdev, &msg, msg.data_size, true);
870+
}
871+
EXPORT_SYMBOL(sof_ipc4_mic_privacy_state_change);

0 commit comments

Comments
 (0)