imx-audmix.c (6f47c7ae8c7afaf9ad291d39f0d3974f191a7946) imx-audmix.c (05d996e113481fdd9ac40ccf5cadabd1e73f2404)
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 *

--- 126 unchanged lines hidden (view full) ---

135 .startup = imx_audmix_fe_startup,
136 .hw_params = imx_audmix_fe_hw_params,
137};
138
139static const struct snd_soc_ops imx_audmix_be_ops = {
140 .hw_params = imx_audmix_be_hw_params,
141};
142
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 *

--- 126 unchanged lines hidden (view full) ---

135 .startup = imx_audmix_fe_startup,
136 .hw_params = imx_audmix_fe_hw_params,
137};
138
139static const struct snd_soc_ops imx_audmix_be_ops = {
140 .hw_params = imx_audmix_be_hw_params,
141};
142
143static const char *name[][3] = {
144 {"HiFi-AUDMIX-FE-0", "HiFi-AUDMIX-FE-1", "HiFi-AUDMIX-FE-2"},
145 {"sai-tx", "sai-tx", "sai-rx"},
146 {"AUDMIX-Playback-0", "AUDMIX-Playback-1", "CPU-Capture"},
147 {"CPU-Playback", "CPU-Playback", "AUDMIX-Capture-0"},
148};
149
143static int imx_audmix_probe(struct platform_device *pdev)
144{
145 struct device_node *np = pdev->dev.of_node;
146 struct device_node *audmix_np = NULL, *out_cpu_np = NULL;
147 struct platform_device *audmix_pdev = NULL;
148 struct platform_device *cpu_pdev;
149 struct of_phandle_args args;
150 struct imx_audmix *priv;
151 int i, num_dai, ret;
152 const char *fe_name_pref = "HiFi-AUDMIX-FE-";
150static int imx_audmix_probe(struct platform_device *pdev)
151{
152 struct device_node *np = pdev->dev.of_node;
153 struct device_node *audmix_np = NULL, *out_cpu_np = NULL;
154 struct platform_device *audmix_pdev = NULL;
155 struct platform_device *cpu_pdev;
156 struct of_phandle_args args;
157 struct imx_audmix *priv;
158 int i, num_dai, ret;
159 const char *fe_name_pref = "HiFi-AUDMIX-FE-";
153 char *be_name, *be_pb, *be_cp, *dai_name, *capture_dai_name;
160 char *be_name, *dai_name;
154
155 if (pdev->dev.parent) {
156 audmix_np = pdev->dev.parent->of_node;
157 } else {
158 dev_err(&pdev->dev, "Missing parent device.\n");
159 return -EINVAL;
160 }
161

--- 16 unchanged lines hidden (view full) ---

178 audmix_np->full_name);
179 return -EINVAL;
180 }
181
182 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
183 if (!priv)
184 return -ENOMEM;
185
161
162 if (pdev->dev.parent) {
163 audmix_np = pdev->dev.parent->of_node;
164 } else {
165 dev_err(&pdev->dev, "Missing parent device.\n");
166 return -EINVAL;
167 }
168

--- 16 unchanged lines hidden (view full) ---

185 audmix_np->full_name);
186 return -EINVAL;
187 }
188
189 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
190 if (!priv)
191 return -ENOMEM;
192
193 num_dai += 1;
186 priv->num_dai = 2 * num_dai;
187 priv->dai = devm_kcalloc(&pdev->dev, priv->num_dai,
188 sizeof(struct snd_soc_dai_link), GFP_KERNEL);
189 if (!priv->dai)
190 return -ENOMEM;
191
192 priv->num_dai_conf = num_dai;
193 priv->dai_conf = devm_kcalloc(&pdev->dev, priv->num_dai_conf,
194 sizeof(struct snd_soc_codec_conf),
195 GFP_KERNEL);
196 if (!priv->dai_conf)
197 return -ENOMEM;
198
194 priv->num_dai = 2 * num_dai;
195 priv->dai = devm_kcalloc(&pdev->dev, priv->num_dai,
196 sizeof(struct snd_soc_dai_link), GFP_KERNEL);
197 if (!priv->dai)
198 return -ENOMEM;
199
200 priv->num_dai_conf = num_dai;
201 priv->dai_conf = devm_kcalloc(&pdev->dev, priv->num_dai_conf,
202 sizeof(struct snd_soc_codec_conf),
203 GFP_KERNEL);
204 if (!priv->dai_conf)
205 return -ENOMEM;
206
199 priv->num_dapm_routes = 3 * num_dai;
207 priv->num_dapm_routes = num_dai;
200 priv->dapm_routes = devm_kcalloc(&pdev->dev, priv->num_dapm_routes,
201 sizeof(struct snd_soc_dapm_route),
202 GFP_KERNEL);
203 if (!priv->dapm_routes)
204 return -ENOMEM;
205
206 for (i = 0; i < num_dai; i++) {
207 struct snd_soc_dai_link_component *dlc;
208
209 /* for CPU x 2 */
210 dlc = devm_kcalloc(&pdev->dev, 2, sizeof(*dlc), GFP_KERNEL);
211 if (!dlc)
212 return -ENOMEM;
213
208 priv->dapm_routes = devm_kcalloc(&pdev->dev, priv->num_dapm_routes,
209 sizeof(struct snd_soc_dapm_route),
210 GFP_KERNEL);
211 if (!priv->dapm_routes)
212 return -ENOMEM;
213
214 for (i = 0; i < num_dai; i++) {
215 struct snd_soc_dai_link_component *dlc;
216
217 /* for CPU x 2 */
218 dlc = devm_kcalloc(&pdev->dev, 2, sizeof(*dlc), GFP_KERNEL);
219 if (!dlc)
220 return -ENOMEM;
221
214 ret = of_parse_phandle_with_args(audmix_np, "dais", NULL, i,
215 &args);
222 if (i == num_dai - 1)
223 ret = of_parse_phandle_with_args(audmix_np, "dais", NULL, 0,
224 &args);
225 else
226 ret = of_parse_phandle_with_args(audmix_np, "dais", NULL, i,
227 &args);
216 if (ret < 0) {
217 dev_err(&pdev->dev, "of_parse_phandle_with_args failed\n");
218 return ret;
219 }
220
221 cpu_pdev = of_find_device_by_node(args.np);
222 if (!cpu_pdev) {
223 dev_err(&pdev->dev, "failed to find SAI platform device\n");
224 return -EINVAL;
225 }
226 put_device(&cpu_pdev->dev);
227
228 dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s",
228 if (ret < 0) {
229 dev_err(&pdev->dev, "of_parse_phandle_with_args failed\n");
230 return ret;
231 }
232
233 cpu_pdev = of_find_device_by_node(args.np);
234 if (!cpu_pdev) {
235 dev_err(&pdev->dev, "failed to find SAI platform device\n");
236 return -EINVAL;
237 }
238 put_device(&cpu_pdev->dev);
239
240 dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s",
229 fe_name_pref, args.np->full_name + 1);
241 fe_name_pref, args.np->full_name);
230 if (!dai_name)
231 return -ENOMEM;
232
233 dev_info(pdev->dev.parent, "DAI FE name:%s\n", dai_name);
234
242 if (!dai_name)
243 return -ENOMEM;
244
245 dev_info(pdev->dev.parent, "DAI FE name:%s\n", dai_name);
246
235 if (i == 0) {
247 if (i == num_dai - 1)
236 out_cpu_np = args.np;
248 out_cpu_np = args.np;
237 capture_dai_name =
238 devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
239 dai_name, "CPU-Capture");
240 if (!capture_dai_name)
241 return -ENOMEM;
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 = &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;
249
250 /*
251 * CPU == Platform
252 * platform is using soc-generic-dmaengine-pcm
253 */
254 priv->dai[i].cpus =
255 priv->dai[i].platforms = &dlc[0];
256 priv->dai[i].codecs = &snd_soc_dummy_dlc;
257
258 priv->dai[i].num_cpus = 1;
259 priv->dai[i].num_codecs = 1;
260 priv->dai[i].num_platforms = 1;
255
256 priv->dai[i].name = dai_name;
261 priv->dai[i].name = name[0][i];
257 priv->dai[i].stream_name = "HiFi-AUDMIX-FE";
258 priv->dai[i].cpus->of_node = args.np;
262 priv->dai[i].stream_name = "HiFi-AUDMIX-FE";
263 priv->dai[i].cpus->of_node = args.np;
259 priv->dai[i].cpus->dai_name = dev_name(&cpu_pdev->dev);
264 priv->dai[i].cpus->dai_name = name[1][i];
265
260 priv->dai[i].dynamic = 1;
261 priv->dai[i].dpcm_playback = 1;
266 priv->dai[i].dynamic = 1;
267 priv->dai[i].dpcm_playback = 1;
262 priv->dai[i].dpcm_capture = (i == 0 ? 1 : 0);
268 if (i == num_dai - 1) {
269 priv->dai[i].dpcm_capture = 1;
270 priv->dai[i].dpcm_playback = 0;
271 }
263 priv->dai[i].ignore_pmdown_time = 1;
264 priv->dai[i].ops = &imx_audmix_fe_ops;
265
266 /* Add AUDMIX Backend */
267 be_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
268 "audmix-%d", i);
272 priv->dai[i].ignore_pmdown_time = 1;
273 priv->dai[i].ops = &imx_audmix_fe_ops;
274
275 /* Add AUDMIX Backend */
276 be_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
277 "audmix-%d", i);
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 = &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;
286 priv->dai[num_dai + i].dpcm_playback = 1;
278 priv->dai[num_dai + i].cpus = &dlc[1];
279 priv->dai[num_dai + i].codecs = &snd_soc_dummy_dlc;
280
281 priv->dai[num_dai + i].num_cpus = 1;
282 priv->dai[num_dai + i].num_codecs = 1;
283
284 priv->dai[num_dai + i].name = be_name;
285 priv->dai[num_dai + i].cpus->of_node = audmix_np;
286 priv->dai[num_dai + i].cpus->dai_name = be_name;
287 priv->dai[num_dai + i].no_pcm = 1;
288 priv->dai[num_dai + i].dpcm_playback = 1;
287 priv->dai[num_dai + i].dpcm_capture = 1;
289 if (i == num_dai - 1) {
290 priv->dai[num_dai + i].dpcm_capture = 1;
291 priv->dai[num_dai + i].dpcm_playback = 0;
292 }
288 priv->dai[num_dai + i].ignore_pmdown_time = 1;
289 priv->dai[num_dai + i].ops = &imx_audmix_be_ops;
290
291 priv->dai_conf[i].dlc.of_node = args.np;
292 priv->dai_conf[i].name_prefix = dai_name;
293
293 priv->dai[num_dai + i].ignore_pmdown_time = 1;
294 priv->dai[num_dai + i].ops = &imx_audmix_be_ops;
295
296 priv->dai_conf[i].dlc.of_node = args.np;
297 priv->dai_conf[i].name_prefix = dai_name;
298
294 priv->dapm_routes[i].source =
295 devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
296 dai_name, "CPU-Playback");
297 if (!priv->dapm_routes[i].source)
298 return -ENOMEM;
299 if (i == num_dai - 1) {
300 priv->dapm_routes[i].sink =
301 devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
302 dai_name, name[2][i]);
303 if (!priv->dapm_routes[i].sink)
304 return -ENOMEM;
299
305
300 priv->dapm_routes[i].sink = be_pb;
301 priv->dapm_routes[num_dai + i].source = be_pb;
302 priv->dapm_routes[num_dai + i].sink = be_cp;
303 priv->dapm_routes[2 * num_dai + i].source = be_cp;
304 priv->dapm_routes[2 * num_dai + i].sink = capture_dai_name;
306 priv->dapm_routes[i].source = name[3][i];
307 } else {
308 priv->dapm_routes[i].source =
309 devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
310 dai_name, name[3][i]);
311 if (!priv->dapm_routes[i].source)
312 return -ENOMEM;
313
314 priv->dapm_routes[i].sink = name[2][i];
315 }
305 }
306
307 cpu_pdev = of_find_device_by_node(out_cpu_np);
308 if (!cpu_pdev) {
309 dev_err(&pdev->dev, "failed to find SAI platform device\n");
310 return -EINVAL;
311 }
312 put_device(&cpu_pdev->dev);

--- 46 unchanged lines hidden ---
316 }
317
318 cpu_pdev = of_find_device_by_node(out_cpu_np);
319 if (!cpu_pdev) {
320 dev_err(&pdev->dev, "failed to find SAI platform device\n");
321 return -EINVAL;
322 }
323 put_device(&cpu_pdev->dev);

--- 46 unchanged lines hidden ---