Skip to content

Commit

Permalink
copier: gain: add dma control ipc handling
Browse files Browse the repository at this point in the history
Add methods to update gain coefficients in runtime by handling
DMA CONTROL IPC message being sent to specific dai device based
on provided node id.
Check for unity gain flag.

Signed-off-by: Ievgen Ganakov <ievgen.ganakov@intel.com>
  • Loading branch information
iganakov committed Sep 5, 2024
1 parent 706bfd6 commit eb8625c
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/audio/copier/copier_gain.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,79 @@ 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,
size_t config_size, enum sof_ipc_dai_type dai_type)
{
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;

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

if (!icd || icd->type != COMP_TYPE_COMPONENT)
continue;

dev = icd->cd;

if (!dev || dev->ipc_config.type != SOF_COMP_DAI)
continue;

struct processing_module *mod = comp_mod(dev);
struct copier_data *cd = module_get_private_data(mod);

ret = copier_set_gain(dev, cd->dd[0], gain_data);
if (ret)
comp_err(dev, "Gain DMA control: failed to set gain");
return ret;
}

return -ENODEV;
}

int copier_set_gain(struct comp_dev *dev, struct dai_data *dd,
struct gain_dma_control_data *gain_data)
{
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;

if (!gain_data) {
comp_err(dev, "Gain data is NULL");
return -EINVAL;
}

/* Set gain coefficients */
comp_info(dev, "Update gain coefficients from DMA_CONTROL ipc");

size_t gain_coef_size = channels * sizeof(uint16_t);

ret = memcpy_s(static_gain, gain_coef_size, gain_data->gain_coeffs,
gain_coef_size);
if (ret) {
comp_err(dev, "memcpy_s failed with error %d", ret);
return ret;
}

for (int i = channels; i < MAX_GAIN_COEFFS_CNT; i++)
static_gain[i] = static_gain[i % channels];

ret = memcpy_s(gain_params->gain_coeffs, sizeof(static_gain),
static_gain, sizeof(static_gain));
if (ret) {
comp_err(dev, "memcpy_s failed with error %d", ret);
return ret;
}

gain_params->unity_gain = copier_is_unity_gain(gain_params);

return 0;
}
43 changes: 43 additions & 0 deletions src/audio/copier/copier_gain.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ struct copier_gain_params {
uint16_t channels_count; /**< Number of channels */
};

/** Gain Coefficients IO Control
*
* This parameter is sent by the driver to add/modify a static gain.
* Coefficients are encoded in Q10 format.
*/
struct gain_dma_control_data {
uint16_t gain_coeffs[MAX_GAIN_COEFFS_CNT];
} __packed __aligned(4);

/**
* @brief Sets gain parameters.
*
Expand Down Expand Up @@ -196,4 +205,38 @@ int copier_gain_input(struct comp_dev *dev, struct comp_buffer *buff,
*/
enum copier_gain_state copier_gain_eval_state(struct copier_gain_params *gain_params);

/**
* Sets/modify gain for a copier module in runtime.
*
* @param dev The copier device structure.
* @param dd The DAI data structure.
* @param gain_data The gain control data structure.
* @return 0 on success, otherwise a negative error code.
*/
int copier_set_gain(struct comp_dev *dev, struct dai_data *dd,
struct gain_dma_control_data *gain_data);

/**
* Checks for unity gain mode.
*
* @param gain_params The copier gain parameters structure.
* @return true if the gain is set to unity gain, false otherwise.
*/
bool copier_is_unity_gain(struct copier_gain_params *gain_params);

/**
* Controls the gain for a copier device using DMA Control IPC message.
*
* 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 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,
size_t config_size, enum sof_ipc_dai_type dai_type);

#endif /* __SOF_COPIER_GAIN_H__ */
10 changes: 10 additions & 0 deletions src/audio/copier/copier_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,16 @@ int copier_gain_input32(struct comp_buffer *buff, enum copier_gain_state state,
return 0;
}

bool copier_is_unity_gain(struct copier_gain_params *gain_params)
{
/* Set unity gain flag */
for (int i = 0; i < MAX_GAIN_COEFFS_CNT; i++) {
if (gain_params->gain_coeffs[i] != UNITY_GAIN_GENERIC)
return false;
}
return true;
}

#endif

void copier_update_params(struct copier_data *cd, struct comp_dev *dev,
Expand Down
8 changes: 8 additions & 0 deletions src/audio/copier/copier_hifi.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,4 +415,12 @@ int copier_gain_input32(struct comp_buffer *buff, enum copier_gain_state state,
return 0;
}

bool copier_is_unity_gain(struct copier_gain_params *gain_params)
{
ae_int16x4 gain_coeffs = AE_MOVF16X4_FROMINT64(UNITY_GAIN_4X_Q10);
xtbool4 unity_gain_check = AE_EQ16(gain_params->gain_coeffs[0], gain_coeffs);

return XT_ALL4(unity_gain_check) ? true : false;
}

#endif

0 comments on commit eb8625c

Please sign in to comment.