mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
ASoC: imx-rpmsg: Add DSD format support with dynamic DAI format switching
Add hw_params callback to dynamically switch DAI format between I2S and PDM based on audio stream format. When DSD formats are detected, the DAI format is switched to PDM mode. Signed-off-by: Chancel Liu <chancel.liu@nxp.com> Link: https://patch.msgid.link/20260326055614.3614104-1-chancel.liu@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
ba2a0e81d4
commit
ccd7e53b7d
|
|
@ -30,6 +30,53 @@ static const struct snd_soc_dapm_widget imx_rpmsg_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_MIC("Main MIC", NULL),
|
||||
};
|
||||
|
||||
static int imx_rpmsg_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
|
||||
snd_pcm_format_t format = params_format(params);
|
||||
struct device *dev = rtd->card->dev;
|
||||
unsigned int fmt = rtd->dai_link->dai_fmt;
|
||||
bool format_is_dsd = false;
|
||||
int ret;
|
||||
|
||||
switch (format) {
|
||||
case SNDRV_PCM_FORMAT_DSD_U8:
|
||||
case SNDRV_PCM_FORMAT_DSD_U16_LE:
|
||||
case SNDRV_PCM_FORMAT_DSD_U16_BE:
|
||||
case SNDRV_PCM_FORMAT_DSD_U32_LE:
|
||||
case SNDRV_PCM_FORMAT_DSD_U32_BE:
|
||||
format_is_dsd = true;
|
||||
break;
|
||||
default:
|
||||
format_is_dsd = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (format_is_dsd)
|
||||
fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
|
||||
SND_SOC_DAIFMT_PDM;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops imx_rpmsg_ops = {
|
||||
.hw_params = imx_rpmsg_hw_params,
|
||||
};
|
||||
|
||||
static int imx_rpmsg_late_probe(struct snd_soc_card *card)
|
||||
{
|
||||
struct imx_rpmsg *data = snd_soc_card_get_drvdata(card);
|
||||
|
|
@ -135,6 +182,7 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
|
|||
data->dai.dai_fmt = SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBC_CFC;
|
||||
data->dai.ops = &imx_rpmsg_ops;
|
||||
|
||||
/*
|
||||
* i.MX rpmsg sound cards work on codec slave mode. MCLK will be
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user