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
30 SND_SOC_DAPM_MIC("Main MIC", NULL),30 SND_SOC_DAPM_MIC("Main MIC", NULL),
31};31};
32 32
33static 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
76static const struct snd_soc_ops imx_rpmsg_ops = {
77 .hw_params = imx_rpmsg_hw_params,
78};
79
33static int imx_rpmsg_late_probe(struct snd_soc_card *card)80static int imx_rpmsg_late_probe(struct snd_soc_card *card)
34{81{
35 struct imx_rpmsg *data = snd_soc_card_get_drvdata(card);82 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
135 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S |182 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S |
136 SND_SOC_DAIFMT_NB_NF |183 SND_SOC_DAIFMT_NB_NF |
137 SND_SOC_DAIFMT_CBC_CFC;184 SND_SOC_DAIFMT_CBC_CFC;
185 data->dai.ops = &imx_rpmsg_ops;
138 186
139 /*187 /*
140 * i.MX rpmsg sound cards work on codec slave mode. MCLK will be188 * i.MX rpmsg sound cards work on codec slave mode. MCLK will be