// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) // // This file is provided under a dual BSD/GPLv2 license. When using or // redistributing this file, you may do so under either license. // // Copyright(c) 2021 Intel Corporation // //
/* container size */
ret = snd_pcm_format_physical_width(params_format(params)); if (ret < 0) return ret;
pcm.params.sample_container_bytes = ret >> 3;
/* format */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16:
pcm.params.frame_fmt = SOF_IPC_FRAME_S16_LE; break; case SNDRV_PCM_FORMAT_S24:
pcm.params.frame_fmt = SOF_IPC_FRAME_S24_4LE; break; case SNDRV_PCM_FORMAT_S32:
pcm.params.frame_fmt = SOF_IPC_FRAME_S32_LE; break; case SNDRV_PCM_FORMAT_FLOAT:
pcm.params.frame_fmt = SOF_IPC_FRAME_FLOAT; break; default: return -EINVAL;
}
/* Update the IPC message with information from the platform */
pcm.params.stream_tag = platform_params->stream_tag;
if (platform_params->use_phy_address)
pcm.params.buffer.phy_addr = platform_params->phy_addr;
if (platform_params->no_ipc_position) { /* For older ABIs set host_period_bytes to zero to inform * FW we don't want position updates. Newer versions use * no_stream_position for this purpose.
*/ if (v->abi_version < SOF_ABI_VER(3, 10, 0))
pcm.params.host_period_bytes = 0; else
pcm.params.no_stream_position = 1;
}
if (platform_params->cont_update_posn)
pcm.params.cont_update_posn = 1;
/* * Search for all matching DAIs as we can have both playback and capture DAI * associated with the same link.
*/
list_for_each_entry(dai, &sdev->dai_list, list) { if (!dai->name || strcmp(link_name, dai->name)) continue; for (i = 0; i < dai->number_configs; i++) { struct sof_dai_private_data *private = dai->private;
if (!dai) {
dev_err(component->dev, "%s: No DAI found with name %s\n", __func__,
rtd->dai_link->name); return -EINVAL;
}
private = dai->private; if (!private) {
dev_err(component->dev, "%s: No private data found for DAI %s\n", __func__,
rtd->dai_link->name); return -EINVAL;
}
/* read format from topology */
snd_mask_none(fmt);
switch (private->comp_dai->config.frame_fmt) { case SOF_IPC_FRAME_S16_LE:
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); break; case SOF_IPC_FRAME_S24_4LE:
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); break; case SOF_IPC_FRAME_S32_LE:
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE); break; default:
dev_err(component->dev, "No available DAI format!\n"); return -EINVAL;
}
/* read rate and channels from topology */ switch (private->dai_config->type) { case SOF_DAI_INTEL_SSP: /* search for config to pcm params match, if not found use default */
ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params);
break; case SOF_DAI_INTEL_DMIC: /* DMIC only supports 16 or 32 bit formats */ if (private->comp_dai->config.frame_fmt == SOF_IPC_FRAME_S24_4LE) {
dev_err(component->dev, "Invalid fmt %d for DAI type %d\n",
private->comp_dai->config.frame_fmt,
private->dai_config->type);
} break; case SOF_DAI_INTEL_HDA: /* * HDAudio does not follow the default trigger * sequence due to firmware implementation
*/
for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) { struct snd_soc_pcm_runtime *fe = dpcm->fe;
fe->dai_link->trigger[SNDRV_PCM_STREAM_PLAYBACK] =
SND_SOC_DPCM_TRIGGER_POST;
} break; case SOF_DAI_INTEL_ALH: /* * Dai could run with different channel count compared with * front end, so get dai channel count from topology
*/
channels->min = private->dai_config->alh.channels;
channels->max = private->dai_config->alh.channels; break; case SOF_DAI_IMX_ESAI:
rate->min = private->dai_config->esai.fsync_rate;
rate->max = private->dai_config->esai.fsync_rate;
channels->min = private->dai_config->esai.tdm_slots;
channels->max = private->dai_config->esai.tdm_slots;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.