History

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.

Chancel Liu committed 7 months ago

Commit ccd7e531 parent ba2a0e81 file · +48 −0Browse files

Unified · Split

sound/soc/fsl/imx-rpmsg.c+48−0
@@ -30,6 +30,53 @@ static const struct snd_soc_dapm_widget imx_rpmsg_dapm_widgets[] = { · 29 unmodified lines
3030 SND_SOC_DAPM_MIC("Main MIC", NULL),
3131 };
3232
33+static int imx_rpmsg_hw_params(struct snd_pcm_substream *substream,
34+ struct snd_pcm_hw_params *params)
35+{
36+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
37+ struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
38+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
39+ snd_pcm_format_t format = params_format(params);
40+ struct device *dev = rtd->card->dev;
41+ unsigned int fmt = rtd->dai_link->dai_fmt;
42+ bool format_is_dsd = false;
43+ int ret;
44+
45+ switch (format) {
46+ case SNDRV_PCM_FORMAT_DSD_U8:
47+ case SNDRV_PCM_FORMAT_DSD_U16_LE:
48+ case SNDRV_PCM_FORMAT_DSD_U16_BE:
49+ case SNDRV_PCM_FORMAT_DSD_U32_LE:
50+ case SNDRV_PCM_FORMAT_DSD_U32_BE:
51+ format_is_dsd = true;
52+ break;
53+ default:
54+ format_is_dsd = false;
55+ break;
56+ }
57+
58+ if (format_is_dsd)
59+ fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
60+ SND_SOC_DAIFMT_PDM;
61+
62+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
63+ if (ret && ret != -ENOTSUPP) {
64+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
65+ return ret;
66+ }
67+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
68+ if (ret && ret != -ENOTSUPP) {
69+ dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
70+ return ret;
71+ }
72+
73+ return 0;
74+}
75+
76+static const struct snd_soc_ops imx_rpmsg_ops = {
77+ .hw_params = imx_rpmsg_hw_params,
78+};
79+
3380 static int imx_rpmsg_late_probe(struct snd_soc_card *card)
3481 {
3582 struct imx_rpmsg *data = snd_soc_card_get_drvdata(card);
@@ -135,6 +182,7 @@ static int imx_rpmsg_probe(struct platform_device *pdev) · 99 unmodified lines
135182 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S |
136183 SND_SOC_DAIFMT_NB_NF |
137184 SND_SOC_DAIFMT_CBC_CFC;
185+ data->dai.ops = &imx_rpmsg_ops;
138186
139187 /*
140188 * i.MX rpmsg sound cards work on codec slave mode. MCLK will be