From: Daniel Baluta <daniel.baluta@xxxxxxx> Allocate memory at the end of sof_ipc_stream_params to store snd_compr_params in order to be sent them to SOF firmware. This will help firmware correctly configure codecs parameters. Notice, that we use 2 bytes from the reserved pool in order to store the extended data length. This is compatible with older FWs where there was no extended data. Signed-off-by: Daniel Baluta <daniel.baluta@xxxxxxx> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx> --- include/sound/sof/stream.h | 6 ++++-- sound/soc/sof/compress.c | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/include/sound/sof/stream.h b/include/sound/sof/stream.h index 1db3bbc3e65d..9377113f13e4 100644 --- a/include/sound/sof/stream.h +++ b/include/sound/sof/stream.h @@ -86,9 +86,11 @@ struct sof_ipc_stream_params { uint32_t host_period_bytes; uint16_t no_stream_position; /**< 1 means don't send stream position */ uint8_t cont_update_posn; /**< 1 means continuous update stream position */ - - uint8_t reserved[5]; + uint8_t reserved0; + int16_t ext_data_length; /**< 0, means no extended data */ + uint8_t reserved[2]; uint16_t chmap[SOF_IPC_MAX_CHANNELS]; /**< channel map - SOF_CHMAP_ */ + uint8_t ext_data[]; /**< extended data */ } __packed; /* PCM params info - SOF_IPC_STREAM_PCM_PARAMS */ diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 45c2ff61ee4d..1204dce29ef9 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -170,6 +170,7 @@ static int sof_compr_set_params(struct snd_soc_component *component, struct snd_compr_tstamp *tstamp; struct sof_ipc_pcm_params *pcm; struct snd_sof_pcm *spcm; + size_t ext_data_size; int ret; tstamp = crtd->private_data; @@ -179,7 +180,12 @@ static int sof_compr_set_params(struct snd_soc_component *component, if (!spcm) return -EINVAL; - pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); + ext_data_size = sizeof(params->codec); + + if (sizeof(*pcm) + ext_data_size > sdev->ipc->max_payload_size) + return -EINVAL; + + pcm = kzalloc(sizeof(*pcm) + ext_data_size, GFP_KERNEL); if (!pcm) return -ENOMEM; @@ -194,11 +200,11 @@ static int sof_compr_set_params(struct snd_soc_component *component, goto out; pcm->params.buffer.pages = PFN_UP(crtd->dma_bytes); - pcm->hdr.size = sizeof(*pcm); + pcm->hdr.size = sizeof(*pcm) + ext_data_size; pcm->hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS; pcm->comp_id = spcm->stream[cstream->direction].comp_id; - pcm->params.hdr.size = sizeof(pcm->params); + pcm->params.hdr.size = sizeof(pcm->params) + ext_data_size; pcm->params.buffer.phy_addr = spcm->stream[cstream->direction].page_table.addr; pcm->params.buffer.size = crtd->dma_bytes; pcm->params.direction = cstream->direction; @@ -209,8 +215,11 @@ static int sof_compr_set_params(struct snd_soc_component *component, pcm->params.sample_container_bytes = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32) >> 3; pcm->params.host_period_bytes = params->buffer.fragment_size; + pcm->params.ext_data_length = ext_data_size; + + memcpy((u8 *)pcm->params.ext_data, ¶ms->codec, ext_data_size); - ret = sof_ipc_tx_message(sdev->ipc, pcm, sizeof(*pcm), + ret = sof_ipc_tx_message(sdev->ipc, pcm, sizeof(*pcm) + ext_data_size, &ipc_params_reply, sizeof(ipc_params_reply)); if (ret < 0) { dev_err(component->dev, "error ipc failed\n"); -- 2.27.0