Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mic_privacy: initial implementation #9788

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion posix/include/sof/lib/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#endif

struct comp_buffer;
struct comp_dev;

/** \addtogroup sof_dma_drivers DMA Drivers
* DMA Drivers API specification.
Expand Down Expand Up @@ -550,7 +551,8 @@ int dma_buffer_copy_to(struct comp_buffer __sparse_cache *source,
* conversion function. DMA buffer consume should be performed after the data has been copied
* to all sinks.
*/
int stream_copy_from_no_consume(struct comp_buffer __sparse_cache *source,
int stream_copy_from_no_consume(struct comp_dev *dev,
struct comp_buffer __sparse_cache *source,
struct comp_buffer __sparse_cache *sink,
dma_process_func process,
uint32_t source_bytes, uint32_t chmap);
Expand Down
3 changes: 3 additions & 0 deletions src/audio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD)
if(CONFIG_COMP_VOLUME)
add_subdirectory(volume)
endif()
if(CONFIG_INTEL_ADSP_MIC_PRIVACY)
add_subdirectory(mic_privacy_manager)
endif()
subdirs(pipeline)
add_subdirectory(google)
if(CONFIG_COMP_CHAIN_DMA)
Expand Down
52 changes: 52 additions & 0 deletions src/audio/base_fw_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
#include <rimage/sof/user/manifest.h>
#include "copier/copier_gain.h"

#if CONFIG_INTEL_ADSP_MIC_PRIVACY
#include <sof/audio/mic_privacy_manager.h>
#endif

struct ipc4_modules_info {
uint32_t modules_count;
struct sof_man_module modules[0];
Expand Down Expand Up @@ -100,6 +104,18 @@ int basefw_vendor_hw_config(uint32_t *data_offset, char *data)
tlv_value_uint32_set(tuple, IPC4_I2S_CAPS_HW_CFG, I2S_VER_30_PTL);
#endif

#if CONFIG_INTEL_ADSP_MIC_PRIVACY
struct privacy_capabilities priv_caps;

tuple = tlv_next(tuple);

priv_caps.privacy_version = 1;
priv_caps.capabilities_length = 1;
priv_caps.capabilities[0] = mic_privacy_get_policy_register();

tlv_value_set(tuple, IPC4_INTEL_MIC_PRIVACY_CAPS_HW_CFG, sizeof(priv_caps), &priv_caps);
#endif

tuple = tlv_next(tuple);
*data_offset = (int)((char *)tuple - data);

Expand Down Expand Up @@ -335,6 +351,38 @@ static int basefw_set_fw_config(bool first_block,
return 0;
}

static int basefw_set_mic_priv_policy(bool first_block,
bool last_block,
uint32_t data_offset_or_size,
const char *data)
{
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
return 0;
#else
return IPC4_UNAVAILABLE;
#endif
}

static int basefw_mic_priv_state_changed(bool first_block,
bool last_block,
uint32_t data_offset_or_size,
const char *data)
{
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
tr_info(&basefw_comp_tr, "state changed to %d", *data);

uint32_t mic_disable_status = (uint32_t)(*data);
struct mic_privacy_settings settings;

mic_privacy_fill_settings(&settings, mic_disable_status);
mic_privacy_propagate_settings(&settings);

return 0;
#else
return IPC4_UNAVAILABLE;
#endif
}

int basefw_vendor_set_large_config(struct comp_dev *dev,
uint32_t param_id,
bool first_block,
Expand All @@ -345,6 +393,10 @@ int basefw_vendor_set_large_config(struct comp_dev *dev,
switch (param_id) {
case IPC4_FW_CONFIG:
return basefw_set_fw_config(first_block, last_block, data_offset, data);
case IPC4_SET_MIC_PRIVACY_FW_MANAGED_POLICY_MASK:
return basefw_set_mic_priv_policy(first_block, last_block, data_offset, data);
case IPC4_MIC_PRIVACY_HW_MANAGED_STATE_CHANGE:
return basefw_mic_priv_state_changed(first_block, last_block, data_offset, data);
default:
break;
}
Expand Down
99 changes: 99 additions & 0 deletions src/audio/copier/copier.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
#include "host_copier.h"
#include "dai_copier.h"
#include "ipcgtw_copier.h"
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
#include <zephyr/drivers/mic_privacy/intel/mic_privacy.h>
#endif

#if CONFIG_ZEPHYR_NATIVE_DRIVERS
#include <zephyr/drivers/dai.h>
Expand All @@ -51,6 +54,79 @@ SOF_DEFINE_REG_UUID(copier);

DECLARE_TR_CTX(copier_comp_tr, SOF_UUID(copier_uuid), LOG_LEVEL_INFO);

#if CONFIG_INTEL_ADSP_MIC_PRIVACY
static void mic_privacy_event(void *arg, enum notify_id type, void *data)
{
struct mic_privacy_data *mic_priv_data = arg;
struct mic_privacy_settings *mic_privacy_settings = data;

if (type == NOTIFIER_ID_MIC_PRIVACY_STATE_CHANGE) {
LOG_INF("mic_privacy_event, state1 = %d, state2 = %d ",
mic_privacy_settings->mic_privacy_state, mic_priv_data->mic_privacy_state);

if (mic_privacy_settings->mic_privacy_state == MIC_PRIV_UNMUTED) {
if (mic_priv_data->mic_privacy_state == MIC_PRIV_MUTED) {
mic_priv_data->mic_privacy_state = MIC_PRIV_FADE_IN;
LOG_INF("mic_privacy_event switch to FADE_IN");
}
} else {
/* In case when mute would be triggered before copier instantiation. */
if (mic_priv_data->mic_privacy_state != MIC_PRIV_MUTED) {
mic_priv_data->mic_privacy_state = MIC_PRIV_FADE_OUT;
LOG_INF("mic_privacy_event switch to FADE_OUT");
}
}
mic_priv_data->max_ramp_time_in_ms = (mic_privacy_settings->max_ramp_time * 1000) /
ADSP_RTC_FREQUENCY;
}
}

static int mic_privacy_configure(struct comp_dev *dev, struct copier_data *cd)
{
struct mic_privacy_data *mic_priv_data;
int ret;

mic_priv_data = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM,
sizeof(struct mic_privacy_data));
if (!mic_priv_data)
return -ENOMEM;

if (cd->gtw_type == ipc4_gtw_dmic)
mic_privacy_enable_dmic_irq(true);

mic_priv_data->audio_freq = cd->config.base.audio_fmt.sampling_frequency;

uint32_t zeroing_wait_time = (mic_privacy_get_dma_zeroing_wait_time() * 1000) /
ADSP_RTC_FREQUENCY;

ret = copier_gain_set_params(dev, &mic_priv_data->mic_priv_gain_params,
zeroing_wait_time, SOF_DAI_INTEL_NONE);
if (ret != 0) {
rfree(mic_priv_data);
return ret;
}

cd->mic_priv = mic_priv_data;

ret = notifier_register(cd->mic_priv, NULL, NOTIFIER_ID_MIC_PRIVACY_STATE_CHANGE,
mic_privacy_event, 0);
if (ret != 0)
rfree(mic_priv_data);

return ret;
}

static void mic_privacy_free(struct copier_data *cd)
{
if (cd->gtw_type == ipc4_gtw_dmic)
mic_privacy_enable_dmic_irq(false);

notifier_unregister(cd->mic_priv, NULL, NOTIFIER_ID_MIC_PRIVACY_STATE_CHANGE);

rfree(cd->mic_priv);
}
#endif

static int copier_init(struct processing_module *mod)
{
union ipc4_connector_node_id node_id;
Expand Down Expand Up @@ -131,6 +207,16 @@ static int copier_init(struct processing_module *mod)
comp_err(dev, "unable to create host");
goto error;
}
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
if (cd->direction == SOF_IPC_STREAM_CAPTURE &&
node_id.f.dma_type == ipc4_hda_host_output_class) {
ret = mic_privacy_configure(dev, cd);
if (ret < 0) {
comp_err(dev, "unable to configure mic privacy");
goto error;
}
}
#endif
break;
case ipc4_hda_link_output_class:
case ipc4_hda_link_input_class:
Expand All @@ -144,6 +230,15 @@ static int copier_init(struct processing_module *mod)
comp_err(dev, "unable to create dai");
goto error;
}
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
if (cd->direction == SOF_IPC_STREAM_CAPTURE) {
ret = mic_privacy_configure(dev, cd);
if (ret < 0) {
comp_err(dev, "unable to configure mic privacy");
goto error;
}
}
#endif
break;
#if CONFIG_IPC4_GATEWAY
case ipc4_ipc_output_class:
Expand Down Expand Up @@ -184,6 +279,10 @@ static int copier_free(struct processing_module *mod)
struct copier_data *cd = module_get_private_data(mod);
struct comp_dev *dev = mod->dev;

#if CONFIG_INTEL_ADSP_MIC_PRIVACY
mic_privacy_free(cd);
#endif

switch (dev->ipc_config.type) {
case SOF_COMP_HOST:
if (!cd->ipc_gtw)
Expand Down
7 changes: 7 additions & 0 deletions src/audio/copier/copier.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
#include <sof/compiler_attributes.h>
#include <sof/audio/buffer.h>
#include <sof/audio/pcm_converter.h>
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
#include <sof/lib/notifier.h>
#include <sof/audio/mic_privacy_manager.h>
#endif

static const uint32_t INVALID_QUEUE_ID = 0xFFFFFFFF;

Expand Down Expand Up @@ -270,6 +274,9 @@ struct copier_data {
uint32_t channels[IPC4_ALH_MAX_NUMBER_OF_GTW];
uint32_t chan_map[IPC4_ALH_MAX_NUMBER_OF_GTW];
struct ipcgtw_data *ipcgtw_data;
#if CONFIG_INTEL_ADSP_MIC_PRIVACY
struct mic_privacy_data *mic_priv;
#endif
};

int apply_attenuation(struct comp_dev *dev, struct copier_data *cd,
Expand Down
4 changes: 3 additions & 1 deletion src/audio/copier/copier_dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,9 @@ static int copier_dai_init(struct comp_dev *dev,
}
cd->dd[index]->gain_data = gain_data;

ret = copier_gain_set_params(dev, cd->dd[index]);
ret = copier_gain_set_params(dev, cd->dd[index]->gain_data,
GAIN_DEFAULT_FADE_PERIOD,
cd->dd[index]->dai->type);
if (ret < 0) {
comp_err(dev, "Failed to set gain params!");
goto gain_free;
Expand Down
30 changes: 16 additions & 14 deletions src/audio/copier/copier_gain.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,22 @@

LOG_MODULE_DECLARE(copier, CONFIG_SOF_LOG_LEVEL);

int copier_gain_set_params(struct comp_dev *dev, struct dai_data *dd)
int copier_gain_set_params(struct comp_dev *dev,
struct copier_gain_params *gain_params,
uint32_t fade_period,
enum sof_ipc_dai_type dai_type)
{
struct processing_module *mod = comp_mod(dev);
struct copier_data *cd = module_get_private_data(mod);
struct ipc4_base_module_cfg *ipc4_cfg = &cd->config.base;
uint32_t sampling_freq = ipc4_cfg->audio_fmt.sampling_frequency;
uint32_t frames = sampling_freq / dev->pipeline->period;
uint32_t fade_period = GAIN_DEFAULT_FADE_PERIOD;
int ret;

/* Set basic gain parameters */
copier_gain_set_basic_params(dev, dd, ipc4_cfg);
copier_gain_set_basic_params(dev, gain_params, ipc4_cfg);

switch (dd->dai->type) {
switch (dai_type) {
case SOF_DAI_INTEL_DMIC:
{
struct dmic_config_data *dmic_cfg = cd->gtw_cfg;
Expand All @@ -43,18 +45,18 @@ int copier_gain_set_params(struct comp_dev *dev, struct dai_data *dd)
/* Get fade period from DMIC blob */
fade_period = dmic_glb_cfg->ext_global_cfg.fade_in_period;
/* Convert and assign silence and fade length values */
dd->gain_data->silence_sg_length =
gain_params->silence_sg_length =
frames * dmic_glb_cfg->ext_global_cfg.silence_period;
dd->gain_data->fade_sg_length = frames * fade_period;
gain_params->fade_sg_length = frames * fade_period;
}
break;
default:
comp_info(dev, "Apply default fade period for dai type %d", dd->dai->type);
comp_info(dev, "Apply default fade period for dai type %d", dai_type);
break;
}

/* Set fade parameters */
ret = copier_gain_set_fade_params(dev, dd, ipc4_cfg, fade_period, frames);
ret = copier_gain_set_fade_params(dev, gain_params, ipc4_cfg, fade_period, frames);
if (ret)
comp_err(dev, "Failed to set fade params");

Expand Down Expand Up @@ -150,7 +152,10 @@ int copier_gain_dma_control(union ipc4_connector_node_id node, const char *confi
break;
}

ret = copier_set_gain(dev, cd->dd[0], gain_data);
struct ipc4_copier_module_cfg *copier_cfg = cd->dd[0]->dai_spec_config;
const int channels = copier_cfg->base.audio_fmt.channels_count;

ret = copier_set_gain(dev, cd->dd[0]->gain_data, gain_data, channels);
if (ret)
comp_err(dev, "Gain DMA control: failed to set gain");
return ret;
Expand All @@ -159,12 +164,9 @@ int copier_gain_dma_control(union ipc4_connector_node_id node, const char *confi
return -ENODEV;
}

int copier_set_gain(struct comp_dev *dev, struct dai_data *dd,
struct gain_dma_control_data *gain_data)
int copier_set_gain(struct comp_dev *dev, struct copier_gain_params *gain_params,
struct gain_dma_control_data *gain_data, int channels)
{
struct copier_gain_params *gain_params = dd->gain_data;
struct ipc4_copier_module_cfg *copier_cfg = dd->dai_spec_config;
const int channels = copier_cfg->base.audio_fmt.channels_count;
uint16_t static_gain[MAX_GAIN_COEFFS_CNT];
int ret;

Expand Down
Loading
Loading