imx-audmix.c (e9cbc89067cce78211c8629c78e931c0fe64e29d) | imx-audmix.c (14ec63f678e8beaaa1005ccae6c112bf672ba2b3) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright 2017 NXP 4 * 5 * The code contained herein is licensed under the GNU General Public 6 * License. You may obtain a copy of the GNU General Public License 7 * Version 2 or later at the following locations: 8 * --- 29 unchanged lines hidden (view full) --- 38 39static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = { 40 .count = ARRAY_SIZE(imx_audmix_rates), 41 .list = imx_audmix_rates, 42}; 43 44static int imx_audmix_fe_startup(struct snd_pcm_substream *substream) 45{ | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright 2017 NXP 4 * 5 * The code contained herein is licensed under the GNU General Public 6 * License. You may obtain a copy of the GNU General Public License 7 * Version 2 or later at the following locations: 8 * --- 29 unchanged lines hidden (view full) --- 38 39static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = { 40 .count = ARRAY_SIZE(imx_audmix_rates), 41 .list = imx_audmix_rates, 42}; 43 44static int imx_audmix_fe_startup(struct snd_pcm_substream *substream) 45{ |
46 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | 46 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); |
47 struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card); 48 struct snd_pcm_runtime *runtime = substream->runtime; 49 struct device *dev = rtd->card->dev; 50 unsigned long clk_rate = clk_get_rate(priv->cpu_mclk); 51 int ret; 52 53 if (clk_rate % 24576000 == 0) { 54 ret = snd_pcm_hw_constraint_list(runtime, 0, --- 12 unchanged lines hidden (view full) --- 67 68 return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, 69 FSL_AUDMIX_FORMATS); 70} 71 72static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream, 73 struct snd_pcm_hw_params *params) 74{ | 47 struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card); 48 struct snd_pcm_runtime *runtime = substream->runtime; 49 struct device *dev = rtd->card->dev; 50 unsigned long clk_rate = clk_get_rate(priv->cpu_mclk); 51 int ret; 52 53 if (clk_rate % 24576000 == 0) { 54 ret = snd_pcm_hw_constraint_list(runtime, 0, --- 12 unchanged lines hidden (view full) --- 67 68 return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, 69 FSL_AUDMIX_FORMATS); 70} 71 72static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream, 73 struct snd_pcm_hw_params *params) 74{ |
75 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | 75 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); |
76 struct device *dev = rtd->card->dev; 77 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 78 unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF; 79 u32 channels = params_channels(params); 80 int ret, dir; 81 82 /* For playback the AUDMIX is consumer, and for record is provider */ 83 fmt |= tx ? SND_SOC_DAIFMT_BP_FP : SND_SOC_DAIFMT_BC_FC; 84 dir = tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN; 85 86 /* set DAI configuration */ | 76 struct device *dev = rtd->card->dev; 77 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 78 unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF; 79 u32 channels = params_channels(params); 80 int ret, dir; 81 82 /* For playback the AUDMIX is consumer, and for record is provider */ 83 fmt |= tx ? SND_SOC_DAIFMT_BP_FP : SND_SOC_DAIFMT_BC_FC; 84 dir = tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN; 85 86 /* set DAI configuration */ |
87 ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), fmt); | 87 ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), fmt); |
88 if (ret) { 89 dev_err(dev, "failed to set cpu dai fmt: %d\n", ret); 90 return ret; 91 } 92 | 88 if (ret) { 89 dev_err(dev, "failed to set cpu dai fmt: %d\n", ret); 90 return ret; 91 } 92 |
93 ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), FSL_SAI_CLK_MAST1, 0, dir); | 93 ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_cpu(rtd, 0), FSL_SAI_CLK_MAST1, 0, dir); |
94 if (ret) { 95 dev_err(dev, "failed to set cpu sysclk: %d\n", ret); 96 return ret; 97 } 98 99 /* 100 * Per datasheet, AUDMIX expects 8 slots and 32 bits 101 * for every slot in TDM mode. 102 */ | 94 if (ret) { 95 dev_err(dev, "failed to set cpu sysclk: %d\n", ret); 96 return ret; 97 } 98 99 /* 100 * Per datasheet, AUDMIX expects 8 slots and 32 bits 101 * for every slot in TDM mode. 102 */ |
103 ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), BIT(channels) - 1, | 103 ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), BIT(channels) - 1, |
104 BIT(channels) - 1, 8, 32); 105 if (ret) 106 dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret); 107 108 return ret; 109} 110 111static int imx_audmix_be_hw_params(struct snd_pcm_substream *substream, 112 struct snd_pcm_hw_params *params) 113{ | 104 BIT(channels) - 1, 8, 32); 105 if (ret) 106 dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret); 107 108 return ret; 109} 110 111static int imx_audmix_be_hw_params(struct snd_pcm_substream *substream, 112 struct snd_pcm_hw_params *params) 113{ |
114 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | 114 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); |
115 struct device *dev = rtd->card->dev; 116 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 117 unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF; 118 int ret; 119 120 if (!tx) 121 return 0; 122 123 /* For playback the AUDMIX is consumer */ 124 fmt |= SND_SOC_DAIFMT_BC_FC; 125 126 /* set AUDMIX DAI configuration */ | 115 struct device *dev = rtd->card->dev; 116 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 117 unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF; 118 int ret; 119 120 if (!tx) 121 return 0; 122 123 /* For playback the AUDMIX is consumer */ 124 fmt |= SND_SOC_DAIFMT_BC_FC; 125 126 /* set AUDMIX DAI configuration */ |
127 ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), fmt); | 127 ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), fmt); |
128 if (ret) 129 dev_err(dev, "failed to set AUDMIX DAI fmt: %d\n", ret); 130 131 return ret; 132} 133 134static const struct snd_soc_ops imx_audmix_fe_ops = { 135 .startup = imx_audmix_fe_startup, --- 106 unchanged lines hidden (view full) --- 242 } 243 244 /* 245 * CPU == Platform 246 * platform is using soc-generic-dmaengine-pcm 247 */ 248 priv->dai[i].cpus = 249 priv->dai[i].platforms = &dlc[0]; | 128 if (ret) 129 dev_err(dev, "failed to set AUDMIX DAI fmt: %d\n", ret); 130 131 return ret; 132} 133 134static const struct snd_soc_ops imx_audmix_fe_ops = { 135 .startup = imx_audmix_fe_startup, --- 106 unchanged lines hidden (view full) --- 242 } 243 244 /* 245 * CPU == Platform 246 * platform is using soc-generic-dmaengine-pcm 247 */ 248 priv->dai[i].cpus = 249 priv->dai[i].platforms = &dlc[0]; |
250 priv->dai[i].codecs = &asoc_dummy_dlc; | 250 priv->dai[i].codecs = &snd_soc_dummy_dlc; |
251 252 priv->dai[i].num_cpus = 1; 253 priv->dai[i].num_codecs = 1; 254 priv->dai[i].num_platforms = 1; 255 256 priv->dai[i].name = dai_name; 257 priv->dai[i].stream_name = "HiFi-AUDMIX-FE"; 258 priv->dai[i].cpus->of_node = args.np; --- 10 unchanged lines hidden (view full) --- 269 be_pb = devm_kasprintf(&pdev->dev, GFP_KERNEL, 270 "AUDMIX-Playback-%d", i); 271 be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL, 272 "AUDMIX-Capture-%d", i); 273 if (!be_name || !be_pb || !be_cp) 274 return -ENOMEM; 275 276 priv->dai[num_dai + i].cpus = &dlc[1]; | 251 252 priv->dai[i].num_cpus = 1; 253 priv->dai[i].num_codecs = 1; 254 priv->dai[i].num_platforms = 1; 255 256 priv->dai[i].name = dai_name; 257 priv->dai[i].stream_name = "HiFi-AUDMIX-FE"; 258 priv->dai[i].cpus->of_node = args.np; --- 10 unchanged lines hidden (view full) --- 269 be_pb = devm_kasprintf(&pdev->dev, GFP_KERNEL, 270 "AUDMIX-Playback-%d", i); 271 be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL, 272 "AUDMIX-Capture-%d", i); 273 if (!be_name || !be_pb || !be_cp) 274 return -ENOMEM; 275 276 priv->dai[num_dai + i].cpus = &dlc[1]; |
277 priv->dai[num_dai + i].codecs = &asoc_dummy_dlc; | 277 priv->dai[num_dai + i].codecs = &snd_soc_dummy_dlc; |
278 279 priv->dai[num_dai + i].num_cpus = 1; 280 priv->dai[num_dai + i].num_codecs = 1; 281 282 priv->dai[num_dai + i].name = be_name; 283 priv->dai[num_dai + i].cpus->of_node = audmix_np; 284 priv->dai[num_dai + i].cpus->dai_name = be_name; 285 priv->dai[num_dai + i].no_pcm = 1; --- 24 unchanged lines hidden (view full) --- 310 return -EINVAL; 311 } 312 put_device(&cpu_pdev->dev); 313 314 priv->cpu_mclk = devm_clk_get(&cpu_pdev->dev, "mclk1"); 315 if (IS_ERR(priv->cpu_mclk)) { 316 ret = PTR_ERR(priv->cpu_mclk); 317 dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret); | 278 279 priv->dai[num_dai + i].num_cpus = 1; 280 priv->dai[num_dai + i].num_codecs = 1; 281 282 priv->dai[num_dai + i].name = be_name; 283 priv->dai[num_dai + i].cpus->of_node = audmix_np; 284 priv->dai[num_dai + i].cpus->dai_name = be_name; 285 priv->dai[num_dai + i].no_pcm = 1; --- 24 unchanged lines hidden (view full) --- 310 return -EINVAL; 311 } 312 put_device(&cpu_pdev->dev); 313 314 priv->cpu_mclk = devm_clk_get(&cpu_pdev->dev, "mclk1"); 315 if (IS_ERR(priv->cpu_mclk)) { 316 ret = PTR_ERR(priv->cpu_mclk); 317 dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret); |
318 return ret; | 318 return -EINVAL; |
319 } 320 321 priv->audmix_pdev = audmix_pdev; 322 priv->out_pdev = cpu_pdev; 323 324 priv->card.dai_link = priv->dai; 325 priv->card.num_links = priv->num_dai; 326 priv->card.codec_conf = priv->dai_conf; --- 32 unchanged lines hidden --- | 319 } 320 321 priv->audmix_pdev = audmix_pdev; 322 priv->out_pdev = cpu_pdev; 323 324 priv->card.dai_link = priv->dai; 325 priv->card.num_links = priv->num_dai; 326 priv->card.codec_conf = priv->dai_conf; --- 32 unchanged lines hidden --- |