Skip to content

Commit

Permalink
copier: dmic: enable gain for dmic dai
Browse files Browse the repository at this point in the history
Enable gain for DMIC interface. Configure gain feature with
parameters received in DMIC BLOB.

Add support for runtime DMIC gain parameters update using
DMA Control IPC.

Signed-off-by: Ievgen Ganakov <[email protected]>
  • Loading branch information
iganakov authored and mwasko committed Oct 4, 2024
1 parent 8dda5ac commit 9cdef9f
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/audio/base_fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ static int basefw_dma_control(bool first_block,
}

dma_control = (struct ipc4_dma_control *)data;
data_size = data_offset - (sizeof(struct ipc4_dma_control) - sizeof(uint32_t));
data_size = data_offset - sizeof(struct ipc4_dma_control);

if (data_size < (dma_control->config_length * sizeof(uint32_t))) {
tr_err(&ipc_tr, "DMA Control data too short: got %u, expected %u",
Expand Down
13 changes: 13 additions & 0 deletions src/audio/base_fw_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <rtos/string.h>
#include <sof/tlv.h>
#include <sof/lib/dai.h>
#include <ipc/dai.h>

#if defined(CONFIG_SOC_SERIES_INTEL_ADSP_ACE)
#include <intel_adsp_hda.h>
Expand All @@ -24,6 +25,7 @@

#include <ipc4/base_fw.h>
#include <rimage/sof/user/manifest.h>
#include "copier/copier_gain.h"

struct ipc4_modules_info {
uint32_t modules_count;
Expand Down Expand Up @@ -353,7 +355,18 @@ int basefw_vendor_dma_control(uint32_t node_id, const char *config_data, size_t

tr_info(&basefw_comp_tr, "node_id 0x%x, config_data 0x%x, data_size %u",
node_id, (uint32_t)config_data, data_size);

switch (node.f.dma_type) {
case ipc4_dmic_link_input_class:
/* In DMIC case we don't need to update zephyr dai params */
ret = copier_gain_dma_control(node, config_data, data_size,
SOF_DAI_INTEL_DMIC);
if (ret) {
tr_err(&basefw_comp_tr,
"Failed to update copier gain coefs, error: %d", ret);
return IPC4_INVALID_REQUEST;
}
return IPC4_SUCCESS;
case ipc4_i2s_link_output_class:
case ipc4_i2s_link_input_class:
type = DAI_INTEL_SSP;
Expand Down
3 changes: 3 additions & 0 deletions src/audio/copier/copier_dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,9 @@ int copier_dai_create(struct comp_dev *dev, struct copier_data *cd,
return -EINVAL;
}
dai.out_fmt = &copier->out_fmt;
#if CONFIG_COPIER_GAIN
dai.apply_gain = true;
#endif
break;
default:
return -EINVAL;
Expand Down
55 changes: 53 additions & 2 deletions src/audio/copier/copier_gain.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <ipc4/base-config.h>
#include <sof/audio/component_ext.h>
#include <module/module/base.h>
#include <sof/tlv.h>
#include <ipc4/dmic.h>
#include "copier.h"
#include "copier_gain.h"

Expand All @@ -26,6 +28,31 @@ int copier_gain_set_params(struct comp_dev *dev, struct dai_data *dd)
/* Set basic gain parameters */
copier_gain_set_basic_params(dev, dd, ipc4_cfg);

switch (dd->dai->type) {
case SOF_DAI_INTEL_DMIC:
{
struct dmic_config_data *dmic_cfg = cd->gtw_cfg;

if (!dmic_cfg) {
comp_err(dev, "No dmic config found");
return -EINVAL;
}

union dmic_global_cfg *dmic_glb_cfg = &dmic_cfg->dmic_blob.global_cfg;

/* 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 =
frames * dmic_glb_cfg->ext_global_cfg.silence_period;
dd->gain_data->fade_sg_length = frames * fade_period;
}
break;
default:
comp_info(dev, "Apply default fade period for dai type %d", dd->dai->type);
break;
}

/* Set fade parameters */
ret = copier_gain_set_fade_params(dev, dd, ipc4_cfg, fade_period, frames);
if (ret)
Expand Down Expand Up @@ -73,18 +100,19 @@ enum copier_gain_state copier_gain_eval_state(struct copier_gain_params *gain_pa
return state;
}

int copier_gain_dma_control(uint32_t node_id, const uint32_t *config_data,
int copier_gain_dma_control(union ipc4_connector_node_id node, const char *config_data,
size_t config_size, enum sof_ipc_dai_type dai_type)
{
struct sof_tlv *tlv = (struct sof_tlv *)config_data;
struct ipc *ipc = ipc_get();
struct ipc_comp_dev *icd;
struct comp_dev *dev;
struct list_item *clist;

int ret;

list_for_item(clist, &ipc->comp_list) {
struct gain_dma_control_data *gain_data = NULL;
void *tlv_val = NULL;

icd = container_of(clist, struct ipc_comp_dev, list);

Expand All @@ -99,6 +127,29 @@ int copier_gain_dma_control(uint32_t node_id, const uint32_t *config_data,
struct processing_module *mod = comp_mod(dev);
struct copier_data *cd = module_get_private_data(mod);

switch (dai_type) {
case SOF_DAI_INTEL_DMIC:
if (cd->dd[0]->dai->index != node.f.v_index)
continue;

if (!config_size) {
comp_err(dev, "Config length for DMIC couldn't be zero");
return -EINVAL;
}

/* Gain coefficients for DMIC */
tlv_val = tlv_value_ptr_get(tlv, DMIC_SET_GAIN_COEFFICIENTS);
if (!tlv_val) {
comp_err(dev, "No gain coefficients in DMA_CONTROL ipc");
return -EINVAL;
}
gain_data = tlv_val;
break;
default:
comp_warn(dev, "Gain DMA control: no dai type=%d found", dai_type);
break;
}

ret = copier_set_gain(dev, cd->dd[0], gain_data);
if (ret)
comp_err(dev, "Gain DMA control: failed to set gain");
Expand Down
4 changes: 2 additions & 2 deletions src/audio/copier/copier_gain.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,13 @@ bool copier_is_unity_gain(struct copier_gain_params *gain_params);
* This function retrieves gain data from the DMA Control IPC message and updates
* corresponding dai device gain params structure.
*
* @param node_id Gateway node id.
* @param node Gateway node id.
* @param config_data The gain configuration data.
* @param config_size The size of the gain configuration data.
* @param dai_type The type of the DAI device.
* @return 0 on success, otherwise a negative error code.
*/
int copier_gain_dma_control(uint32_t node_id, const uint32_t *config_data,
int copier_gain_dma_control(union ipc4_connector_node_id node, const char *config_data,
size_t config_size, enum sof_ipc_dai_type dai_type);

#endif /* __SOF_COPIER_GAIN_H__ */
2 changes: 1 addition & 1 deletion src/include/ipc4/base_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ struct ipc4_astate_table {
struct ipc4_dma_control {
uint32_t node_id;
uint32_t config_length;
uint32_t config_data[1];
uint32_t config_data[0];
} __attribute__((packed, aligned(4)));

enum ipc4_perf_measurements_state_set {
Expand Down

0 comments on commit 9cdef9f

Please sign in to comment.