xref: /openbmc/linux/sound/soc/sof/pcm.c (revision 5c816641)
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 //
3 // This file is provided under a dual BSD/GPLv2 license.  When using or
4 // redistributing this file, you may do so under either license.
5 //
6 // Copyright(c) 2018 Intel Corporation. All rights reserved.
7 //
8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9 //
10 // PCM Layer, interface between ALSA and IPC.
11 //
12 
13 #include <linux/pm_runtime.h>
14 #include <sound/pcm_params.h>
15 #include <sound/sof.h>
16 #include "sof-priv.h"
17 #include "sof-audio.h"
18 #include "ops.h"
19 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
20 #include "sof-probes.h"
21 #endif
22 
23 /* Create DMA buffer page table for DSP */
24 static int create_page_table(struct snd_soc_component *component,
25 			     struct snd_pcm_substream *substream,
26 			     unsigned char *dma_area, size_t size)
27 {
28 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
29 	struct snd_sof_pcm *spcm;
30 	struct snd_dma_buffer *dmab = snd_pcm_get_dma_buf(substream);
31 	int stream = substream->stream;
32 
33 	spcm = snd_sof_find_spcm_dai(component, rtd);
34 	if (!spcm)
35 		return -EINVAL;
36 
37 	return snd_sof_create_page_table(component->dev, dmab,
38 		spcm->stream[stream].page_table.area, size);
39 }
40 
41 static int sof_pcm_dsp_params(struct snd_sof_pcm *spcm, struct snd_pcm_substream *substream,
42 			      const struct sof_ipc_pcm_params_reply *reply)
43 {
44 	struct snd_soc_component *scomp = spcm->scomp;
45 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
46 
47 	/* validate offset */
48 	int ret = snd_sof_ipc_pcm_params(sdev, substream, reply);
49 
50 	if (ret < 0)
51 		dev_err(scomp->dev, "error: got wrong reply for PCM %d\n",
52 			spcm->pcm.pcm_id);
53 
54 	return ret;
55 }
56 
57 /*
58  * sof pcm period elapse work
59  */
60 static void snd_sof_pcm_period_elapsed_work(struct work_struct *work)
61 {
62 	struct snd_sof_pcm_stream *sps =
63 		container_of(work, struct snd_sof_pcm_stream,
64 			     period_elapsed_work);
65 
66 	snd_pcm_period_elapsed(sps->substream);
67 }
68 
69 void snd_sof_pcm_init_elapsed_work(struct work_struct *work)
70 {
71 	 INIT_WORK(work, snd_sof_pcm_period_elapsed_work);
72 }
73 
74 /*
75  * sof pcm period elapse, this could be called at irq thread context.
76  */
77 void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream)
78 {
79 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
80 	struct snd_soc_component *component =
81 		snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
82 	struct snd_sof_pcm *spcm;
83 
84 	spcm = snd_sof_find_spcm_dai(component, rtd);
85 	if (!spcm) {
86 		dev_err(component->dev,
87 			"error: period elapsed for unknown stream!\n");
88 		return;
89 	}
90 
91 	/*
92 	 * snd_pcm_period_elapsed() can be called in interrupt context
93 	 * before IRQ_HANDLED is returned. Inside snd_pcm_period_elapsed(),
94 	 * when the PCM is done draining or xrun happened, a STOP IPC will
95 	 * then be sent and this IPC will hit IPC timeout.
96 	 * To avoid sending IPC before the previous IPC is handled, we
97 	 * schedule delayed work here to call the snd_pcm_period_elapsed().
98 	 */
99 	schedule_work(&spcm->stream[substream->stream].period_elapsed_work);
100 }
101 EXPORT_SYMBOL(snd_sof_pcm_period_elapsed);
102 
103 int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream, struct snd_sof_dev *sdev,
104 			 struct snd_sof_pcm *spcm)
105 {
106 	struct sof_ipc_stream stream;
107 	struct sof_ipc_reply reply;
108 	int ret;
109 
110 	if (!spcm->prepared[substream->stream])
111 		return 0;
112 
113 	stream.hdr.size = sizeof(stream);
114 	stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
115 	stream.comp_id = spcm->stream[substream->stream].comp_id;
116 
117 	/* send IPC to the DSP */
118 	ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
119 				 sizeof(stream), &reply, sizeof(reply));
120 	if (!ret)
121 		spcm->prepared[substream->stream] = false;
122 
123 	return ret;
124 }
125 
126 static int sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev,
127 					   struct snd_soc_pcm_runtime *rtd,
128 					   struct snd_sof_pcm *spcm, int dir)
129 {
130 	struct snd_soc_dai *dai;
131 	int ret, j;
132 
133 	/* query DAPM for list of connected widgets and set them up */
134 	for_each_rtd_cpu_dais(rtd, j, dai) {
135 		struct snd_soc_dapm_widget_list *list;
136 
137 		ret = snd_soc_dapm_dai_get_connected_widgets(dai, dir, &list,
138 							     dpcm_end_walk_at_be);
139 		if (ret < 0) {
140 			dev_err(sdev->dev, "error: dai %s has no valid %s path\n", dai->name,
141 				dir == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture");
142 			return ret;
143 		}
144 
145 		spcm->stream[dir].list = list;
146 
147 		ret = sof_widget_list_setup(sdev, spcm, dir);
148 		if (ret < 0) {
149 			dev_err(sdev->dev, "error: failed widget list set up for pcm %d dir %d\n",
150 				spcm->pcm.pcm_id, dir);
151 			spcm->stream[dir].list = NULL;
152 			snd_soc_dapm_dai_free_widgets(&list);
153 			return ret;
154 		}
155 	}
156 
157 	return 0;
158 }
159 
160 static int sof_pcm_hw_params(struct snd_soc_component *component,
161 			     struct snd_pcm_substream *substream,
162 			     struct snd_pcm_hw_params *params)
163 {
164 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
165 	struct snd_pcm_runtime *runtime = substream->runtime;
166 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
167 	struct snd_sof_pcm *spcm;
168 	struct sof_ipc_pcm_params pcm;
169 	struct sof_ipc_pcm_params_reply ipc_params_reply;
170 	int ret;
171 
172 	/* nothing to do for BE */
173 	if (rtd->dai_link->no_pcm)
174 		return 0;
175 
176 	spcm = snd_sof_find_spcm_dai(component, rtd);
177 	if (!spcm)
178 		return -EINVAL;
179 
180 	/*
181 	 * Handle repeated calls to hw_params() without free_pcm() in
182 	 * between. At least ALSA OSS emulation depends on this.
183 	 */
184 	ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
185 	if (ret < 0)
186 		return ret;
187 
188 	dev_dbg(component->dev, "pcm: hw params stream %d dir %d\n",
189 		spcm->pcm.pcm_id, substream->stream);
190 
191 	memset(&pcm, 0, sizeof(pcm));
192 
193 	/* create compressed page table for audio firmware */
194 	if (runtime->buffer_changed) {
195 		ret = create_page_table(component, substream, runtime->dma_area,
196 					runtime->dma_bytes);
197 		if (ret < 0)
198 			return ret;
199 	}
200 
201 	/* number of pages should be rounded up */
202 	pcm.params.buffer.pages = PFN_UP(runtime->dma_bytes);
203 
204 	/* set IPC PCM parameters */
205 	pcm.hdr.size = sizeof(pcm);
206 	pcm.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS;
207 	pcm.comp_id = spcm->stream[substream->stream].comp_id;
208 	pcm.params.hdr.size = sizeof(pcm.params);
209 	pcm.params.buffer.phy_addr =
210 		spcm->stream[substream->stream].page_table.addr;
211 	pcm.params.buffer.size = runtime->dma_bytes;
212 	pcm.params.direction = substream->stream;
213 	pcm.params.sample_valid_bytes = params_width(params) >> 3;
214 	pcm.params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
215 	pcm.params.rate = params_rate(params);
216 	pcm.params.channels = params_channels(params);
217 	pcm.params.host_period_bytes = params_period_bytes(params);
218 
219 	/* container size */
220 	ret = snd_pcm_format_physical_width(params_format(params));
221 	if (ret < 0)
222 		return ret;
223 	pcm.params.sample_container_bytes = ret >> 3;
224 
225 	/* format */
226 	switch (params_format(params)) {
227 	case SNDRV_PCM_FORMAT_S16:
228 		pcm.params.frame_fmt = SOF_IPC_FRAME_S16_LE;
229 		break;
230 	case SNDRV_PCM_FORMAT_S24:
231 		pcm.params.frame_fmt = SOF_IPC_FRAME_S24_4LE;
232 		break;
233 	case SNDRV_PCM_FORMAT_S32:
234 		pcm.params.frame_fmt = SOF_IPC_FRAME_S32_LE;
235 		break;
236 	case SNDRV_PCM_FORMAT_FLOAT:
237 		pcm.params.frame_fmt = SOF_IPC_FRAME_FLOAT;
238 		break;
239 	default:
240 		return -EINVAL;
241 	}
242 
243 	/* firmware already configured host stream */
244 	ret = snd_sof_pcm_platform_hw_params(sdev,
245 					     substream,
246 					     params,
247 					     &pcm.params);
248 	if (ret < 0) {
249 		dev_err(component->dev, "error: platform hw params failed\n");
250 		return ret;
251 	}
252 
253 	dev_dbg(component->dev, "stream_tag %d", pcm.params.stream_tag);
254 
255 	/* if this is a repeated hw_params without hw_free, skip setting up widgets */
256 	if (!spcm->stream[substream->stream].list) {
257 		ret = sof_pcm_setup_connected_widgets(sdev, rtd, spcm, substream->stream);
258 		if (ret < 0)
259 			return ret;
260 	}
261 
262 	/* send hw_params IPC to the DSP */
263 	ret = sof_ipc_tx_message(sdev->ipc, pcm.hdr.cmd, &pcm, sizeof(pcm),
264 				 &ipc_params_reply, sizeof(ipc_params_reply));
265 	if (ret < 0) {
266 		dev_err(component->dev, "error: hw params ipc failed for stream %d\n",
267 			pcm.params.stream_tag);
268 		return ret;
269 	}
270 
271 	ret = sof_pcm_dsp_params(spcm, substream, &ipc_params_reply);
272 	if (ret < 0)
273 		return ret;
274 
275 	spcm->prepared[substream->stream] = true;
276 
277 	/* save pcm hw_params */
278 	memcpy(&spcm->params[substream->stream], params, sizeof(*params));
279 
280 	return ret;
281 }
282 
283 static int sof_pcm_hw_free(struct snd_soc_component *component,
284 			   struct snd_pcm_substream *substream)
285 {
286 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
287 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
288 	struct snd_sof_pcm *spcm;
289 	int ret, err = 0;
290 
291 	/* nothing to do for BE */
292 	if (rtd->dai_link->no_pcm)
293 		return 0;
294 
295 	spcm = snd_sof_find_spcm_dai(component, rtd);
296 	if (!spcm)
297 		return -EINVAL;
298 
299 	dev_dbg(component->dev, "pcm: free stream %d dir %d\n",
300 		spcm->pcm.pcm_id, substream->stream);
301 
302 	/* free PCM in the DSP */
303 	ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
304 	if (ret < 0)
305 		err = ret;
306 
307 
308 	/* stop DMA */
309 	ret = snd_sof_pcm_platform_hw_free(sdev, substream);
310 	if (ret < 0) {
311 		dev_err(component->dev, "error: platform hw free failed\n");
312 		err = ret;
313 	}
314 
315 	/* free the DAPM widget list */
316 	ret = sof_widget_list_free(sdev, spcm, substream->stream);
317 	if (ret < 0)
318 		err = ret;
319 
320 	cancel_work_sync(&spcm->stream[substream->stream].period_elapsed_work);
321 
322 	return err;
323 }
324 
325 static int sof_pcm_prepare(struct snd_soc_component *component,
326 			   struct snd_pcm_substream *substream)
327 {
328 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
329 	struct snd_sof_pcm *spcm;
330 	int ret;
331 
332 	/* nothing to do for BE */
333 	if (rtd->dai_link->no_pcm)
334 		return 0;
335 
336 	spcm = snd_sof_find_spcm_dai(component, rtd);
337 	if (!spcm)
338 		return -EINVAL;
339 
340 	if (spcm->prepared[substream->stream])
341 		return 0;
342 
343 	dev_dbg(component->dev, "pcm: prepare stream %d dir %d\n",
344 		spcm->pcm.pcm_id, substream->stream);
345 
346 	/* set hw_params */
347 	ret = sof_pcm_hw_params(component,
348 				substream, &spcm->params[substream->stream]);
349 	if (ret < 0) {
350 		dev_err(component->dev,
351 			"error: set pcm hw_params after resume\n");
352 		return ret;
353 	}
354 
355 	return 0;
356 }
357 
358 /*
359  * FE dai link trigger actions are always executed in non-atomic context because
360  * they involve IPC's.
361  */
362 static int sof_pcm_trigger(struct snd_soc_component *component,
363 			   struct snd_pcm_substream *substream, int cmd)
364 {
365 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
366 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
367 	struct snd_sof_pcm *spcm;
368 	struct sof_ipc_stream stream;
369 	struct sof_ipc_reply reply;
370 	bool reset_hw_params = false;
371 	bool free_widget_list = false;
372 	bool ipc_first = false;
373 	int ret;
374 
375 	/* nothing to do for BE */
376 	if (rtd->dai_link->no_pcm)
377 		return 0;
378 
379 	spcm = snd_sof_find_spcm_dai(component, rtd);
380 	if (!spcm)
381 		return -EINVAL;
382 
383 	dev_dbg(component->dev, "pcm: trigger stream %d dir %d cmd %d\n",
384 		spcm->pcm.pcm_id, substream->stream, cmd);
385 
386 	stream.hdr.size = sizeof(stream);
387 	stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG;
388 	stream.comp_id = spcm->stream[substream->stream].comp_id;
389 
390 	switch (cmd) {
391 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
392 		stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_PAUSE;
393 		ipc_first = true;
394 		break;
395 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
396 		stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE;
397 		break;
398 	case SNDRV_PCM_TRIGGER_START:
399 		if (spcm->stream[substream->stream].suspend_ignored) {
400 			/*
401 			 * This case will be triggered when INFO_RESUME is
402 			 * not supported, no need to re-start streams that
403 			 * remained enabled in D0ix.
404 			 */
405 			spcm->stream[substream->stream].suspend_ignored = false;
406 			return 0;
407 		}
408 		stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_START;
409 		break;
410 	case SNDRV_PCM_TRIGGER_SUSPEND:
411 		if (sdev->system_suspend_target == SOF_SUSPEND_S0IX &&
412 		    spcm->stream[substream->stream].d0i3_compatible) {
413 			/*
414 			 * trap the event, not sending trigger stop to
415 			 * prevent the FW pipelines from being stopped,
416 			 * and mark the flag to ignore the upcoming DAPM
417 			 * PM events.
418 			 */
419 			spcm->stream[substream->stream].suspend_ignored = true;
420 			return 0;
421 		}
422 		free_widget_list = true;
423 		fallthrough;
424 	case SNDRV_PCM_TRIGGER_STOP:
425 		stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP;
426 		ipc_first = true;
427 		reset_hw_params = true;
428 		break;
429 	default:
430 		dev_err(component->dev, "error: unhandled trigger cmd %d\n",
431 			cmd);
432 		return -EINVAL;
433 	}
434 
435 	/*
436 	 * DMA and IPC sequence is different for start and stop. Need to send
437 	 * STOP IPC before stop DMA
438 	 */
439 	if (!ipc_first)
440 		snd_sof_pcm_platform_trigger(sdev, substream, cmd);
441 
442 	/* send IPC to the DSP */
443 	ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
444 				 sizeof(stream), &reply, sizeof(reply));
445 
446 	/* need to STOP DMA even if STOP IPC failed */
447 	if (ipc_first)
448 		snd_sof_pcm_platform_trigger(sdev, substream, cmd);
449 
450 	/* free PCM if reset_hw_params is set and the STOP IPC is successful */
451 	if (!ret && reset_hw_params) {
452 		ret = sof_pcm_stream_free(sdev, substream, spcm, substream->stream,
453 					  free_widget_list);
454 		if (ret < 0)
455 			return ret;
456 	}
457 
458 	return ret;
459 }
460 
461 static snd_pcm_uframes_t sof_pcm_pointer(struct snd_soc_component *component,
462 					 struct snd_pcm_substream *substream)
463 {
464 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
465 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
466 	struct snd_sof_pcm *spcm;
467 	snd_pcm_uframes_t host, dai;
468 
469 	/* nothing to do for BE */
470 	if (rtd->dai_link->no_pcm)
471 		return 0;
472 
473 	/* use dsp ops pointer callback directly if set */
474 	if (sof_ops(sdev)->pcm_pointer)
475 		return sof_ops(sdev)->pcm_pointer(sdev, substream);
476 
477 	spcm = snd_sof_find_spcm_dai(component, rtd);
478 	if (!spcm)
479 		return -EINVAL;
480 
481 	/* read position from DSP */
482 	host = bytes_to_frames(substream->runtime,
483 			       spcm->stream[substream->stream].posn.host_posn);
484 	dai = bytes_to_frames(substream->runtime,
485 			      spcm->stream[substream->stream].posn.dai_posn);
486 
487 	dev_vdbg(component->dev,
488 		 "PCM: stream %d dir %d DMA position %lu DAI position %lu\n",
489 		 spcm->pcm.pcm_id, substream->stream, host, dai);
490 
491 	return host;
492 }
493 
494 static int sof_pcm_open(struct snd_soc_component *component,
495 			struct snd_pcm_substream *substream)
496 {
497 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
498 	struct snd_pcm_runtime *runtime = substream->runtime;
499 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
500 	const struct snd_sof_dsp_ops *ops = sof_ops(sdev);
501 	struct snd_sof_pcm *spcm;
502 	struct snd_soc_tplg_stream_caps *caps;
503 	int ret;
504 
505 	/* nothing to do for BE */
506 	if (rtd->dai_link->no_pcm)
507 		return 0;
508 
509 	spcm = snd_sof_find_spcm_dai(component, rtd);
510 	if (!spcm)
511 		return -EINVAL;
512 
513 	dev_dbg(component->dev, "pcm: open stream %d dir %d\n",
514 		spcm->pcm.pcm_id, substream->stream);
515 
516 
517 	caps = &spcm->pcm.caps[substream->stream];
518 
519 	/* set runtime config */
520 	runtime->hw.info = ops->hw_info; /* platform-specific */
521 
522 	/* set any runtime constraints based on topology */
523 	runtime->hw.formats = le64_to_cpu(caps->formats);
524 	runtime->hw.period_bytes_min = le32_to_cpu(caps->period_size_min);
525 	runtime->hw.period_bytes_max = le32_to_cpu(caps->period_size_max);
526 	runtime->hw.periods_min = le32_to_cpu(caps->periods_min);
527 	runtime->hw.periods_max = le32_to_cpu(caps->periods_max);
528 
529 	/*
530 	 * caps->buffer_size_min is not used since the
531 	 * snd_pcm_hardware structure only defines buffer_bytes_max
532 	 */
533 	runtime->hw.buffer_bytes_max = le32_to_cpu(caps->buffer_size_max);
534 
535 	dev_dbg(component->dev, "period min %zd max %zd bytes\n",
536 		runtime->hw.period_bytes_min,
537 		runtime->hw.period_bytes_max);
538 	dev_dbg(component->dev, "period count %d max %d\n",
539 		runtime->hw.periods_min,
540 		runtime->hw.periods_max);
541 	dev_dbg(component->dev, "buffer max %zd bytes\n",
542 		runtime->hw.buffer_bytes_max);
543 
544 	/* set wait time - TODO: come from topology */
545 	substream->wait_time = 500;
546 
547 	spcm->stream[substream->stream].posn.host_posn = 0;
548 	spcm->stream[substream->stream].posn.dai_posn = 0;
549 	spcm->stream[substream->stream].substream = substream;
550 	spcm->prepared[substream->stream] = false;
551 
552 	ret = snd_sof_pcm_platform_open(sdev, substream);
553 	if (ret < 0)
554 		dev_err(component->dev, "error: pcm open failed %d\n", ret);
555 
556 	return ret;
557 }
558 
559 static int sof_pcm_close(struct snd_soc_component *component,
560 			 struct snd_pcm_substream *substream)
561 {
562 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
563 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
564 	struct snd_sof_pcm *spcm;
565 	int err;
566 
567 	/* nothing to do for BE */
568 	if (rtd->dai_link->no_pcm)
569 		return 0;
570 
571 	spcm = snd_sof_find_spcm_dai(component, rtd);
572 	if (!spcm)
573 		return -EINVAL;
574 
575 	dev_dbg(component->dev, "pcm: close stream %d dir %d\n",
576 		spcm->pcm.pcm_id, substream->stream);
577 
578 	err = snd_sof_pcm_platform_close(sdev, substream);
579 	if (err < 0) {
580 		dev_err(component->dev, "error: pcm close failed %d\n",
581 			err);
582 		/*
583 		 * keep going, no point in preventing the close
584 		 * from happening
585 		 */
586 	}
587 
588 	return 0;
589 }
590 
591 /*
592  * Pre-allocate playback/capture audio buffer pages.
593  * no need to explicitly release memory preallocated by sof_pcm_new in pcm_free
594  * snd_pcm_lib_preallocate_free_for_all() is called by the core.
595  */
596 static int sof_pcm_new(struct snd_soc_component *component,
597 		       struct snd_soc_pcm_runtime *rtd)
598 {
599 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
600 	struct snd_sof_pcm *spcm;
601 	struct snd_pcm *pcm = rtd->pcm;
602 	struct snd_soc_tplg_stream_caps *caps;
603 	int stream = SNDRV_PCM_STREAM_PLAYBACK;
604 
605 	/* find SOF PCM for this RTD */
606 	spcm = snd_sof_find_spcm_dai(component, rtd);
607 	if (!spcm) {
608 		dev_warn(component->dev, "warn: can't find PCM with DAI ID %d\n",
609 			 rtd->dai_link->id);
610 		return 0;
611 	}
612 
613 	dev_dbg(component->dev, "creating new PCM %s\n", spcm->pcm.pcm_name);
614 
615 	/* do we need to pre-allocate playback audio buffer pages */
616 	if (!spcm->pcm.playback)
617 		goto capture;
618 
619 	caps = &spcm->pcm.caps[stream];
620 
621 	/* pre-allocate playback audio buffer pages */
622 	dev_dbg(component->dev,
623 		"spcm: allocate %s playback DMA buffer size 0x%x max 0x%x\n",
624 		caps->name, caps->buffer_size_min, caps->buffer_size_max);
625 
626 	if (!pcm->streams[stream].substream) {
627 		dev_err(component->dev, "error: NULL playback substream!\n");
628 		return -EINVAL;
629 	}
630 
631 	snd_pcm_set_managed_buffer(pcm->streams[stream].substream,
632 				   SNDRV_DMA_TYPE_DEV_SG, sdev->dev,
633 				   0, le32_to_cpu(caps->buffer_size_max));
634 capture:
635 	stream = SNDRV_PCM_STREAM_CAPTURE;
636 
637 	/* do we need to pre-allocate capture audio buffer pages */
638 	if (!spcm->pcm.capture)
639 		return 0;
640 
641 	caps = &spcm->pcm.caps[stream];
642 
643 	/* pre-allocate capture audio buffer pages */
644 	dev_dbg(component->dev,
645 		"spcm: allocate %s capture DMA buffer size 0x%x max 0x%x\n",
646 		caps->name, caps->buffer_size_min, caps->buffer_size_max);
647 
648 	if (!pcm->streams[stream].substream) {
649 		dev_err(component->dev, "error: NULL capture substream!\n");
650 		return -EINVAL;
651 	}
652 
653 	snd_pcm_set_managed_buffer(pcm->streams[stream].substream,
654 				   SNDRV_DMA_TYPE_DEV_SG, sdev->dev,
655 				   0, le32_to_cpu(caps->buffer_size_max));
656 
657 	return 0;
658 }
659 
660 static void ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char *link_name,
661 					    struct snd_pcm_hw_params *params)
662 {
663 	struct sof_ipc_dai_config *config;
664 	struct snd_sof_dai *dai;
665 	int i;
666 
667 	/*
668 	 * Search for all matching DAIs as we can have both playback and capture DAI
669 	 * associated with the same link.
670 	 */
671 	list_for_each_entry(dai, &sdev->dai_list, list) {
672 		if (!dai->name || strcmp(link_name, dai->name))
673 			continue;
674 		for (i = 0; i < dai->number_configs; i++) {
675 			config = &dai->dai_config[i];
676 			if (config->ssp.fsync_rate == params_rate(params)) {
677 				dev_dbg(sdev->dev, "DAI config %d matches pcm hw params\n", i);
678 				dai->current_config = i;
679 				break;
680 			}
681 		}
682 	}
683 }
684 
685 /* fixup the BE DAI link to match any values from topology */
686 int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params)
687 {
688 	struct snd_interval *rate = hw_param_interval(params,
689 			SNDRV_PCM_HW_PARAM_RATE);
690 	struct snd_interval *channels = hw_param_interval(params,
691 						SNDRV_PCM_HW_PARAM_CHANNELS);
692 	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
693 	struct snd_soc_component *component =
694 		snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
695 	struct snd_sof_dai *dai =
696 		snd_sof_find_dai(component, (char *)rtd->dai_link->name);
697 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
698 	struct snd_soc_dpcm *dpcm;
699 
700 	/* no topology exists for this BE, try a common configuration */
701 	if (!dai) {
702 		dev_warn(component->dev,
703 			 "warning: no topology found for BE DAI %s config\n",
704 			 rtd->dai_link->name);
705 
706 		/*  set 48k, stereo, 16bits by default */
707 		rate->min = 48000;
708 		rate->max = 48000;
709 
710 		channels->min = 2;
711 		channels->max = 2;
712 
713 		snd_mask_none(fmt);
714 		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
715 
716 		return 0;
717 	}
718 
719 	/* read format from topology */
720 	snd_mask_none(fmt);
721 
722 	switch (dai->comp_dai.config.frame_fmt) {
723 	case SOF_IPC_FRAME_S16_LE:
724 		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
725 		break;
726 	case SOF_IPC_FRAME_S24_4LE:
727 		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
728 		break;
729 	case SOF_IPC_FRAME_S32_LE:
730 		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE);
731 		break;
732 	default:
733 		dev_err(component->dev, "error: No available DAI format!\n");
734 		return -EINVAL;
735 	}
736 
737 	/* read rate and channels from topology */
738 	switch (dai->dai_config->type) {
739 	case SOF_DAI_INTEL_SSP:
740 		/* search for config to pcm params match, if not found use default */
741 		ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params);
742 
743 		rate->min = dai->dai_config[dai->current_config].ssp.fsync_rate;
744 		rate->max = dai->dai_config[dai->current_config].ssp.fsync_rate;
745 		channels->min = dai->dai_config[dai->current_config].ssp.tdm_slots;
746 		channels->max = dai->dai_config[dai->current_config].ssp.tdm_slots;
747 
748 		dev_dbg(component->dev,
749 			"rate_min: %d rate_max: %d\n", rate->min, rate->max);
750 		dev_dbg(component->dev,
751 			"channels_min: %d channels_max: %d\n",
752 			channels->min, channels->max);
753 
754 		break;
755 	case SOF_DAI_INTEL_DMIC:
756 		/* DMIC only supports 16 or 32 bit formats */
757 		if (dai->comp_dai.config.frame_fmt == SOF_IPC_FRAME_S24_4LE) {
758 			dev_err(component->dev,
759 				"error: invalid fmt %d for DAI type %d\n",
760 				dai->comp_dai.config.frame_fmt,
761 				dai->dai_config->type);
762 		}
763 		break;
764 	case SOF_DAI_INTEL_HDA:
765 		/*
766 		 * HDAudio does not follow the default trigger
767 		 * sequence due to firmware implementation
768 		 */
769 		for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) {
770 			struct snd_soc_pcm_runtime *fe = dpcm->fe;
771 
772 			fe->dai_link->trigger[SNDRV_PCM_STREAM_PLAYBACK] =
773 				SND_SOC_DPCM_TRIGGER_POST;
774 		}
775 		break;
776 	case SOF_DAI_INTEL_ALH:
777 		/*
778 		 * Dai could run with different channel count compared with
779 		 * front end, so get dai channel count from topology
780 		 */
781 		channels->min = dai->dai_config->alh.channels;
782 		channels->max = dai->dai_config->alh.channels;
783 		break;
784 	case SOF_DAI_IMX_ESAI:
785 		rate->min = dai->dai_config->esai.fsync_rate;
786 		rate->max = dai->dai_config->esai.fsync_rate;
787 		channels->min = dai->dai_config->esai.tdm_slots;
788 		channels->max = dai->dai_config->esai.tdm_slots;
789 
790 		dev_dbg(component->dev,
791 			"rate_min: %d rate_max: %d\n", rate->min, rate->max);
792 		dev_dbg(component->dev,
793 			"channels_min: %d channels_max: %d\n",
794 			channels->min, channels->max);
795 		break;
796 	case SOF_DAI_MEDIATEK_AFE:
797 		rate->min = dai->dai_config->afe.rate;
798 		rate->max = dai->dai_config->afe.rate;
799 		channels->min = dai->dai_config->afe.channels;
800 		channels->max = dai->dai_config->afe.channels;
801 
802 		dev_dbg(component->dev,
803 			"rate_min: %d rate_max: %d\n", rate->min, rate->max);
804 		dev_dbg(component->dev,
805 			"channels_min: %d channels_max: %d\n",
806 			channels->min, channels->max);
807 		break;
808 	case SOF_DAI_IMX_SAI:
809 		rate->min = dai->dai_config->sai.fsync_rate;
810 		rate->max = dai->dai_config->sai.fsync_rate;
811 		channels->min = dai->dai_config->sai.tdm_slots;
812 		channels->max = dai->dai_config->sai.tdm_slots;
813 
814 		dev_dbg(component->dev,
815 			"rate_min: %d rate_max: %d\n", rate->min, rate->max);
816 		dev_dbg(component->dev,
817 			"channels_min: %d channels_max: %d\n",
818 			channels->min, channels->max);
819 		break;
820 	case SOF_DAI_AMD_BT:
821 		rate->min = dai->dai_config->acpbt.fsync_rate;
822 		rate->max = dai->dai_config->acpbt.fsync_rate;
823 		channels->min = dai->dai_config->acpbt.tdm_slots;
824 		channels->max = dai->dai_config->acpbt.tdm_slots;
825 
826 		dev_dbg(component->dev,
827 			"AMD_BT rate_min: %d rate_max: %d\n", rate->min, rate->max);
828 		dev_dbg(component->dev,
829 			"AMD_BT channels_min: %d channels_max: %d\n",
830 			channels->min, channels->max);
831 		break;
832 	case SOF_DAI_AMD_SP:
833 		rate->min = dai->dai_config->acpsp.fsync_rate;
834 		rate->max = dai->dai_config->acpsp.fsync_rate;
835 		channels->min = dai->dai_config->acpsp.tdm_slots;
836 		channels->max = dai->dai_config->acpsp.tdm_slots;
837 
838 		dev_dbg(component->dev,
839 			"AMD_SP rate_min: %d rate_max: %d\n", rate->min, rate->max);
840 		dev_dbg(component->dev,
841 			"AMD_SP channels_min: %d channels_max: %d\n",
842 			channels->min, channels->max);
843 		break;
844 	case SOF_DAI_AMD_DMIC:
845 		rate->min = dai->dai_config->acpdmic.fsync_rate;
846 		rate->max = dai->dai_config->acpdmic.fsync_rate;
847 		channels->min = dai->dai_config->acpdmic.tdm_slots;
848 		channels->max = dai->dai_config->acpdmic.tdm_slots;
849 
850 		dev_dbg(component->dev,
851 			"AMD_DMIC rate_min: %d rate_max: %d\n", rate->min, rate->max);
852 		dev_dbg(component->dev,
853 			"AMD_DMIC channels_min: %d channels_max: %d\n",
854 			channels->min, channels->max);
855 		break;
856 	default:
857 		dev_err(component->dev, "error: invalid DAI type %d\n",
858 			dai->dai_config->type);
859 		break;
860 	}
861 
862 	return 0;
863 }
864 EXPORT_SYMBOL(sof_pcm_dai_link_fixup);
865 
866 static int sof_pcm_probe(struct snd_soc_component *component)
867 {
868 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
869 	struct snd_sof_pdata *plat_data = sdev->pdata;
870 	const char *tplg_filename;
871 	int ret;
872 
873 	/* load the default topology */
874 	sdev->component = component;
875 
876 	tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
877 				       "%s/%s",
878 				       plat_data->tplg_filename_prefix,
879 				       plat_data->tplg_filename);
880 	if (!tplg_filename)
881 		return -ENOMEM;
882 
883 	ret = snd_sof_load_topology(component, tplg_filename);
884 	if (ret < 0) {
885 		dev_err(component->dev, "error: failed to load DSP topology %d\n",
886 			ret);
887 		return ret;
888 	}
889 
890 	return ret;
891 }
892 
893 static void sof_pcm_remove(struct snd_soc_component *component)
894 {
895 	/* remove topology */
896 	snd_soc_tplg_component_remove(component);
897 }
898 
899 static int sof_pcm_ack(struct snd_soc_component *component,
900 		       struct snd_pcm_substream *substream)
901 {
902 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
903 
904 	return snd_sof_pcm_platform_ack(sdev, substream);
905 }
906 
907 void snd_sof_new_platform_drv(struct snd_sof_dev *sdev)
908 {
909 	struct snd_soc_component_driver *pd = &sdev->plat_drv;
910 	struct snd_sof_pdata *plat_data = sdev->pdata;
911 	const char *drv_name;
912 
913 	drv_name = plat_data->machine->drv_name;
914 
915 	pd->name = "sof-audio-component";
916 	pd->probe = sof_pcm_probe;
917 	pd->remove = sof_pcm_remove;
918 	pd->open = sof_pcm_open;
919 	pd->close = sof_pcm_close;
920 	pd->hw_params = sof_pcm_hw_params;
921 	pd->prepare = sof_pcm_prepare;
922 	pd->hw_free = sof_pcm_hw_free;
923 	pd->trigger = sof_pcm_trigger;
924 	pd->pointer = sof_pcm_pointer;
925 	pd->ack = sof_pcm_ack;
926 
927 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
928 	pd->compress_ops = &sof_probe_compressed_ops;
929 #endif
930 	pd->pcm_construct = sof_pcm_new;
931 	pd->ignore_machine = drv_name;
932 	pd->be_hw_params_fixup = sof_pcm_dai_link_fixup;
933 	pd->be_pcm_base = SOF_BE_PCM_BASE;
934 	pd->use_dai_pcm_id = true;
935 	pd->topology_name_prefix = "sof";
936 
937 	 /* increment module refcount when a pcm is opened */
938 	pd->module_get_upon_open = 1;
939 }
940