Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: SOF: Copy compress parameters into extended data

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@nxp.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20220712141531.14599-3-daniel.baluta@oss.nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Daniel Baluta and committed by
Mark Brown
3f70c360 d5770dae

+17 -6
+4 -2
include/sound/sof/stream.h
··· 86 86 uint32_t host_period_bytes; 87 87 uint16_t no_stream_position; /**< 1 means don't send stream position */ 88 88 uint8_t cont_update_posn; /**< 1 means continuous update stream position */ 89 - 90 - uint8_t reserved[5]; 89 + uint8_t reserved0; 90 + int16_t ext_data_length; /**< 0, means no extended data */ 91 + uint8_t reserved[2]; 91 92 uint16_t chmap[SOF_IPC_MAX_CHANNELS]; /**< channel map - SOF_CHMAP_ */ 93 + uint8_t ext_data[]; /**< extended data */ 92 94 } __packed; 93 95 94 96 /* PCM params info - SOF_IPC_STREAM_PCM_PARAMS */
+13 -4
sound/soc/sof/compress.c
··· 170 170 struct snd_compr_tstamp *tstamp; 171 171 struct sof_ipc_pcm_params *pcm; 172 172 struct snd_sof_pcm *spcm; 173 + size_t ext_data_size; 173 174 int ret; 174 175 175 176 tstamp = crtd->private_data; ··· 180 179 if (!spcm) 181 180 return -EINVAL; 182 181 183 - pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); 182 + ext_data_size = sizeof(params->codec); 183 + 184 + if (sizeof(*pcm) + ext_data_size > sdev->ipc->max_payload_size) 185 + return -EINVAL; 186 + 187 + pcm = kzalloc(sizeof(*pcm) + ext_data_size, GFP_KERNEL); 184 188 if (!pcm) 185 189 return -ENOMEM; 186 190 ··· 200 194 goto out; 201 195 202 196 pcm->params.buffer.pages = PFN_UP(crtd->dma_bytes); 203 - pcm->hdr.size = sizeof(*pcm); 197 + pcm->hdr.size = sizeof(*pcm) + ext_data_size; 204 198 pcm->hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS; 205 199 206 200 pcm->comp_id = spcm->stream[cstream->direction].comp_id; 207 - pcm->params.hdr.size = sizeof(pcm->params); 201 + pcm->params.hdr.size = sizeof(pcm->params) + ext_data_size; 208 202 pcm->params.buffer.phy_addr = spcm->stream[cstream->direction].page_table.addr; 209 203 pcm->params.buffer.size = crtd->dma_bytes; 210 204 pcm->params.direction = cstream->direction; ··· 215 209 pcm->params.sample_container_bytes = 216 210 snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32) >> 3; 217 211 pcm->params.host_period_bytes = params->buffer.fragment_size; 212 + pcm->params.ext_data_length = ext_data_size; 218 213 219 - ret = sof_ipc_tx_message(sdev->ipc, pcm, sizeof(*pcm), 214 + memcpy((u8 *)pcm->params.ext_data, &params->codec, ext_data_size); 215 + 216 + ret = sof_ipc_tx_message(sdev->ipc, pcm, sizeof(*pcm) + ext_data_size, 220 217 &ipc_params_reply, sizeof(ipc_params_reply)); 221 218 if (ret < 0) { 222 219 dev_err(component->dev, "error ipc failed\n");