1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
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.
6 // Copyright(c) 2018 Intel Corporation. All rights reserved.
8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
10 // PCM Layer, interface between ALSA and IPC.
13 #include <linux/pm_runtime.h>
14 #include <sound/pcm_params.h>
15 #include <sound/sof.h>
17 #include "sof-audio.h"
19 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
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
)
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
;
33 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
37 return snd_sof_create_page_table(component
->dev
, dmab
,
38 spcm
->stream
[stream
].page_table
.area
, size
);
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
)
44 struct snd_soc_component
*scomp
= spcm
->scomp
;
45 struct snd_sof_dev
*sdev
= snd_soc_component_get_drvdata(scomp
);
48 int ret
= snd_sof_ipc_pcm_params(sdev
, substream
, reply
);
51 dev_err(scomp
->dev
, "error: got wrong reply for PCM %d\n",
58 * sof pcm period elapse work
60 void snd_sof_pcm_period_elapsed_work(struct work_struct
*work
)
62 struct snd_sof_pcm_stream
*sps
=
63 container_of(work
, struct snd_sof_pcm_stream
,
66 snd_pcm_period_elapsed(sps
->substream
);
70 * sof pcm period elapse, this could be called at irq thread context.
72 void snd_sof_pcm_period_elapsed(struct snd_pcm_substream
*substream
)
74 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
75 struct snd_soc_component
*component
=
76 snd_soc_rtdcom_lookup(rtd
, SOF_AUDIO_PCM_DRV_NAME
);
77 struct snd_sof_pcm
*spcm
;
79 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
81 dev_err(component
->dev
,
82 "error: period elapsed for unknown stream!\n");
87 * snd_pcm_period_elapsed() can be called in interrupt context
88 * before IRQ_HANDLED is returned. Inside snd_pcm_period_elapsed(),
89 * when the PCM is done draining or xrun happened, a STOP IPC will
90 * then be sent and this IPC will hit IPC timeout.
91 * To avoid sending IPC before the previous IPC is handled, we
92 * schedule delayed work here to call the snd_pcm_period_elapsed().
94 schedule_work(&spcm
->stream
[substream
->stream
].period_elapsed_work
);
96 EXPORT_SYMBOL(snd_sof_pcm_period_elapsed
);
98 static int sof_pcm_dsp_pcm_free(struct snd_pcm_substream
*substream
,
99 struct snd_sof_dev
*sdev
,
100 struct snd_sof_pcm
*spcm
)
102 struct sof_ipc_stream stream
;
103 struct sof_ipc_reply reply
;
106 stream
.hdr
.size
= sizeof(stream
);
107 stream
.hdr
.cmd
= SOF_IPC_GLB_STREAM_MSG
| SOF_IPC_STREAM_PCM_FREE
;
108 stream
.comp_id
= spcm
->stream
[substream
->stream
].comp_id
;
110 /* send IPC to the DSP */
111 ret
= sof_ipc_tx_message(sdev
->ipc
, stream
.hdr
.cmd
, &stream
,
112 sizeof(stream
), &reply
, sizeof(reply
));
114 spcm
->prepared
[substream
->stream
] = false;
119 static int sof_pcm_hw_params(struct snd_soc_component
*component
,
120 struct snd_pcm_substream
*substream
,
121 struct snd_pcm_hw_params
*params
)
123 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
124 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
125 struct snd_sof_dev
*sdev
= snd_soc_component_get_drvdata(component
);
126 struct snd_sof_pcm
*spcm
;
127 struct sof_ipc_pcm_params pcm
;
128 struct sof_ipc_pcm_params_reply ipc_params_reply
;
131 /* nothing to do for BE */
132 if (rtd
->dai_link
->no_pcm
)
135 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
140 * Handle repeated calls to hw_params() without free_pcm() in
141 * between. At least ALSA OSS emulation depends on this.
143 if (spcm
->prepared
[substream
->stream
]) {
144 ret
= sof_pcm_dsp_pcm_free(substream
, sdev
, spcm
);
149 dev_dbg(component
->dev
, "pcm: hw params stream %d dir %d\n",
150 spcm
->pcm
.pcm_id
, substream
->stream
);
152 memset(&pcm
, 0, sizeof(pcm
));
154 /* create compressed page table for audio firmware */
155 if (runtime
->buffer_changed
) {
156 ret
= create_page_table(component
, substream
, runtime
->dma_area
,
162 /* number of pages should be rounded up */
163 pcm
.params
.buffer
.pages
= PFN_UP(runtime
->dma_bytes
);
165 /* set IPC PCM parameters */
166 pcm
.hdr
.size
= sizeof(pcm
);
167 pcm
.hdr
.cmd
= SOF_IPC_GLB_STREAM_MSG
| SOF_IPC_STREAM_PCM_PARAMS
;
168 pcm
.comp_id
= spcm
->stream
[substream
->stream
].comp_id
;
169 pcm
.params
.hdr
.size
= sizeof(pcm
.params
);
170 pcm
.params
.buffer
.phy_addr
=
171 spcm
->stream
[substream
->stream
].page_table
.addr
;
172 pcm
.params
.buffer
.size
= runtime
->dma_bytes
;
173 pcm
.params
.direction
= substream
->stream
;
174 pcm
.params
.sample_valid_bytes
= params_width(params
) >> 3;
175 pcm
.params
.buffer_fmt
= SOF_IPC_BUFFER_INTERLEAVED
;
176 pcm
.params
.rate
= params_rate(params
);
177 pcm
.params
.channels
= params_channels(params
);
178 pcm
.params
.host_period_bytes
= params_period_bytes(params
);
181 ret
= snd_pcm_format_physical_width(params_format(params
));
184 pcm
.params
.sample_container_bytes
= ret
>> 3;
187 switch (params_format(params
)) {
188 case SNDRV_PCM_FORMAT_S16
:
189 pcm
.params
.frame_fmt
= SOF_IPC_FRAME_S16_LE
;
191 case SNDRV_PCM_FORMAT_S24
:
192 pcm
.params
.frame_fmt
= SOF_IPC_FRAME_S24_4LE
;
194 case SNDRV_PCM_FORMAT_S32
:
195 pcm
.params
.frame_fmt
= SOF_IPC_FRAME_S32_LE
;
197 case SNDRV_PCM_FORMAT_FLOAT
:
198 pcm
.params
.frame_fmt
= SOF_IPC_FRAME_FLOAT
;
204 /* firmware already configured host stream */
205 ret
= snd_sof_pcm_platform_hw_params(sdev
,
210 dev_err(component
->dev
, "error: platform hw params failed\n");
214 dev_dbg(component
->dev
, "stream_tag %d", pcm
.params
.stream_tag
);
216 /* send IPC to the DSP */
217 ret
= sof_ipc_tx_message(sdev
->ipc
, pcm
.hdr
.cmd
, &pcm
, sizeof(pcm
),
218 &ipc_params_reply
, sizeof(ipc_params_reply
));
220 dev_err(component
->dev
, "error: hw params ipc failed for stream %d\n",
221 pcm
.params
.stream_tag
);
225 ret
= sof_pcm_dsp_params(spcm
, substream
, &ipc_params_reply
);
229 spcm
->prepared
[substream
->stream
] = true;
231 /* save pcm hw_params */
232 memcpy(&spcm
->params
[substream
->stream
], params
, sizeof(*params
));
237 static int sof_pcm_hw_free(struct snd_soc_component
*component
,
238 struct snd_pcm_substream
*substream
)
240 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
241 struct snd_sof_dev
*sdev
= snd_soc_component_get_drvdata(component
);
242 struct snd_sof_pcm
*spcm
;
245 /* nothing to do for BE */
246 if (rtd
->dai_link
->no_pcm
)
249 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
253 dev_dbg(component
->dev
, "pcm: free stream %d dir %d\n",
254 spcm
->pcm
.pcm_id
, substream
->stream
);
256 if (spcm
->prepared
[substream
->stream
]) {
257 ret
= sof_pcm_dsp_pcm_free(substream
, sdev
, spcm
);
262 cancel_work_sync(&spcm
->stream
[substream
->stream
].period_elapsed_work
);
264 ret
= snd_sof_pcm_platform_hw_free(sdev
, substream
);
266 dev_err(component
->dev
, "error: platform hw free failed\n");
273 static int sof_pcm_prepare(struct snd_soc_component
*component
,
274 struct snd_pcm_substream
*substream
)
276 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
277 struct snd_sof_pcm
*spcm
;
280 /* nothing to do for BE */
281 if (rtd
->dai_link
->no_pcm
)
284 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
288 if (spcm
->prepared
[substream
->stream
])
291 dev_dbg(component
->dev
, "pcm: prepare stream %d dir %d\n",
292 spcm
->pcm
.pcm_id
, substream
->stream
);
295 ret
= sof_pcm_hw_params(component
,
296 substream
, &spcm
->params
[substream
->stream
]);
298 dev_err(component
->dev
,
299 "error: set pcm hw_params after resume\n");
307 * FE dai link trigger actions are always executed in non-atomic context because
308 * they involve IPC's.
310 static int sof_pcm_trigger(struct snd_soc_component
*component
,
311 struct snd_pcm_substream
*substream
, int cmd
)
313 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
314 struct snd_sof_dev
*sdev
= snd_soc_component_get_drvdata(component
);
315 struct snd_sof_pcm
*spcm
;
316 struct sof_ipc_stream stream
;
317 struct sof_ipc_reply reply
;
318 bool reset_hw_params
= false;
319 bool ipc_first
= false;
322 /* nothing to do for BE */
323 if (rtd
->dai_link
->no_pcm
)
326 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
330 dev_dbg(component
->dev
, "pcm: trigger stream %d dir %d cmd %d\n",
331 spcm
->pcm
.pcm_id
, substream
->stream
, cmd
);
333 stream
.hdr
.size
= sizeof(stream
);
334 stream
.hdr
.cmd
= SOF_IPC_GLB_STREAM_MSG
;
335 stream
.comp_id
= spcm
->stream
[substream
->stream
].comp_id
;
338 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
339 stream
.hdr
.cmd
|= SOF_IPC_STREAM_TRIG_PAUSE
;
342 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
343 stream
.hdr
.cmd
|= SOF_IPC_STREAM_TRIG_RELEASE
;
345 case SNDRV_PCM_TRIGGER_RESUME
:
346 if (spcm
->stream
[substream
->stream
].suspend_ignored
) {
348 * this case will be triggered when INFO_RESUME is
349 * supported, no need to resume streams that remained
352 spcm
->stream
[substream
->stream
].suspend_ignored
= false;
356 /* set up hw_params */
357 ret
= sof_pcm_prepare(component
, substream
);
359 dev_err(component
->dev
,
360 "error: failed to set up hw_params upon resume\n");
365 case SNDRV_PCM_TRIGGER_START
:
366 if (spcm
->stream
[substream
->stream
].suspend_ignored
) {
368 * This case will be triggered when INFO_RESUME is
369 * not supported, no need to re-start streams that
370 * remained enabled in D0ix.
372 spcm
->stream
[substream
->stream
].suspend_ignored
= false;
375 stream
.hdr
.cmd
|= SOF_IPC_STREAM_TRIG_START
;
377 case SNDRV_PCM_TRIGGER_SUSPEND
:
378 if (sdev
->system_suspend_target
== SOF_SUSPEND_S0IX
&&
379 spcm
->stream
[substream
->stream
].d0i3_compatible
) {
381 * trap the event, not sending trigger stop to
382 * prevent the FW pipelines from being stopped,
383 * and mark the flag to ignore the upcoming DAPM
386 spcm
->stream
[substream
->stream
].suspend_ignored
= true;
390 case SNDRV_PCM_TRIGGER_STOP
:
391 stream
.hdr
.cmd
|= SOF_IPC_STREAM_TRIG_STOP
;
393 reset_hw_params
= true;
396 dev_err(component
->dev
, "error: unhandled trigger cmd %d\n",
402 * DMA and IPC sequence is different for start and stop. Need to send
403 * STOP IPC before stop DMA
406 snd_sof_pcm_platform_trigger(sdev
, substream
, cmd
);
408 /* send IPC to the DSP */
409 ret
= sof_ipc_tx_message(sdev
->ipc
, stream
.hdr
.cmd
, &stream
,
410 sizeof(stream
), &reply
, sizeof(reply
));
412 /* need to STOP DMA even if STOP IPC failed */
414 snd_sof_pcm_platform_trigger(sdev
, substream
, cmd
);
416 /* free PCM if reset_hw_params is set and the STOP IPC is successful */
417 if (!ret
&& reset_hw_params
)
418 ret
= sof_pcm_dsp_pcm_free(substream
, sdev
, spcm
);
423 static snd_pcm_uframes_t
sof_pcm_pointer(struct snd_soc_component
*component
,
424 struct snd_pcm_substream
*substream
)
426 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
427 struct snd_sof_dev
*sdev
= snd_soc_component_get_drvdata(component
);
428 struct snd_sof_pcm
*spcm
;
429 snd_pcm_uframes_t host
, dai
;
431 /* nothing to do for BE */
432 if (rtd
->dai_link
->no_pcm
)
435 /* use dsp ops pointer callback directly if set */
436 if (sof_ops(sdev
)->pcm_pointer
)
437 return sof_ops(sdev
)->pcm_pointer(sdev
, substream
);
439 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
443 /* read position from DSP */
444 host
= bytes_to_frames(substream
->runtime
,
445 spcm
->stream
[substream
->stream
].posn
.host_posn
);
446 dai
= bytes_to_frames(substream
->runtime
,
447 spcm
->stream
[substream
->stream
].posn
.dai_posn
);
449 dev_vdbg(component
->dev
,
450 "PCM: stream %d dir %d DMA position %lu DAI position %lu\n",
451 spcm
->pcm
.pcm_id
, substream
->stream
, host
, dai
);
456 static int sof_pcm_open(struct snd_soc_component
*component
,
457 struct snd_pcm_substream
*substream
)
459 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
460 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
461 struct snd_sof_dev
*sdev
= snd_soc_component_get_drvdata(component
);
462 const struct snd_sof_dsp_ops
*ops
= sof_ops(sdev
);
463 struct snd_sof_pcm
*spcm
;
464 struct snd_soc_tplg_stream_caps
*caps
;
467 /* nothing to do for BE */
468 if (rtd
->dai_link
->no_pcm
)
471 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
475 dev_dbg(component
->dev
, "pcm: open stream %d dir %d\n",
476 spcm
->pcm
.pcm_id
, substream
->stream
);
479 caps
= &spcm
->pcm
.caps
[substream
->stream
];
481 /* set runtime config */
482 runtime
->hw
.info
= ops
->hw_info
; /* platform-specific */
484 /* set any runtime constraints based on topology */
485 runtime
->hw
.formats
= le64_to_cpu(caps
->formats
);
486 runtime
->hw
.period_bytes_min
= le32_to_cpu(caps
->period_size_min
);
487 runtime
->hw
.period_bytes_max
= le32_to_cpu(caps
->period_size_max
);
488 runtime
->hw
.periods_min
= le32_to_cpu(caps
->periods_min
);
489 runtime
->hw
.periods_max
= le32_to_cpu(caps
->periods_max
);
492 * caps->buffer_size_min is not used since the
493 * snd_pcm_hardware structure only defines buffer_bytes_max
495 runtime
->hw
.buffer_bytes_max
= le32_to_cpu(caps
->buffer_size_max
);
497 dev_dbg(component
->dev
, "period min %zd max %zd bytes\n",
498 runtime
->hw
.period_bytes_min
,
499 runtime
->hw
.period_bytes_max
);
500 dev_dbg(component
->dev
, "period count %d max %d\n",
501 runtime
->hw
.periods_min
,
502 runtime
->hw
.periods_max
);
503 dev_dbg(component
->dev
, "buffer max %zd bytes\n",
504 runtime
->hw
.buffer_bytes_max
);
506 /* set wait time - TODO: come from topology */
507 substream
->wait_time
= 500;
509 spcm
->stream
[substream
->stream
].posn
.host_posn
= 0;
510 spcm
->stream
[substream
->stream
].posn
.dai_posn
= 0;
511 spcm
->stream
[substream
->stream
].substream
= substream
;
512 spcm
->prepared
[substream
->stream
] = false;
514 ret
= snd_sof_pcm_platform_open(sdev
, substream
);
516 dev_err(component
->dev
, "error: pcm open failed %d\n", ret
);
521 static int sof_pcm_close(struct snd_soc_component
*component
,
522 struct snd_pcm_substream
*substream
)
524 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
525 struct snd_sof_dev
*sdev
= snd_soc_component_get_drvdata(component
);
526 struct snd_sof_pcm
*spcm
;
529 /* nothing to do for BE */
530 if (rtd
->dai_link
->no_pcm
)
533 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
537 dev_dbg(component
->dev
, "pcm: close stream %d dir %d\n",
538 spcm
->pcm
.pcm_id
, substream
->stream
);
540 err
= snd_sof_pcm_platform_close(sdev
, substream
);
542 dev_err(component
->dev
, "error: pcm close failed %d\n",
545 * keep going, no point in preventing the close
554 * Pre-allocate playback/capture audio buffer pages.
555 * no need to explicitly release memory preallocated by sof_pcm_new in pcm_free
556 * snd_pcm_lib_preallocate_free_for_all() is called by the core.
558 static int sof_pcm_new(struct snd_soc_component
*component
,
559 struct snd_soc_pcm_runtime
*rtd
)
561 struct snd_sof_dev
*sdev
= snd_soc_component_get_drvdata(component
);
562 struct snd_sof_pcm
*spcm
;
563 struct snd_pcm
*pcm
= rtd
->pcm
;
564 struct snd_soc_tplg_stream_caps
*caps
;
565 int stream
= SNDRV_PCM_STREAM_PLAYBACK
;
567 /* find SOF PCM for this RTD */
568 spcm
= snd_sof_find_spcm_dai(component
, rtd
);
570 dev_warn(component
->dev
, "warn: can't find PCM with DAI ID %d\n",
575 dev_dbg(component
->dev
, "creating new PCM %s\n", spcm
->pcm
.pcm_name
);
577 /* do we need to pre-allocate playback audio buffer pages */
578 if (!spcm
->pcm
.playback
)
581 caps
= &spcm
->pcm
.caps
[stream
];
583 /* pre-allocate playback audio buffer pages */
584 dev_dbg(component
->dev
,
585 "spcm: allocate %s playback DMA buffer size 0x%x max 0x%x\n",
586 caps
->name
, caps
->buffer_size_min
, caps
->buffer_size_max
);
588 if (!pcm
->streams
[stream
].substream
) {
589 dev_err(component
->dev
, "error: NULL playback substream!\n");
593 snd_pcm_set_managed_buffer(pcm
->streams
[stream
].substream
,
594 SNDRV_DMA_TYPE_DEV_SG
, sdev
->dev
,
595 0, le32_to_cpu(caps
->buffer_size_max
));
597 stream
= SNDRV_PCM_STREAM_CAPTURE
;
599 /* do we need to pre-allocate capture audio buffer pages */
600 if (!spcm
->pcm
.capture
)
603 caps
= &spcm
->pcm
.caps
[stream
];
605 /* pre-allocate capture audio buffer pages */
606 dev_dbg(component
->dev
,
607 "spcm: allocate %s capture DMA buffer size 0x%x max 0x%x\n",
608 caps
->name
, caps
->buffer_size_min
, caps
->buffer_size_max
);
610 if (!pcm
->streams
[stream
].substream
) {
611 dev_err(component
->dev
, "error: NULL capture substream!\n");
615 snd_pcm_set_managed_buffer(pcm
->streams
[stream
].substream
,
616 SNDRV_DMA_TYPE_DEV_SG
, sdev
->dev
,
617 0, le32_to_cpu(caps
->buffer_size_max
));
622 /* fixup the BE DAI link to match any values from topology */
623 int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime
*rtd
, struct snd_pcm_hw_params
*params
)
625 struct snd_interval
*rate
= hw_param_interval(params
,
626 SNDRV_PCM_HW_PARAM_RATE
);
627 struct snd_interval
*channels
= hw_param_interval(params
,
628 SNDRV_PCM_HW_PARAM_CHANNELS
);
629 struct snd_mask
*fmt
= hw_param_mask(params
, SNDRV_PCM_HW_PARAM_FORMAT
);
630 struct snd_soc_component
*component
=
631 snd_soc_rtdcom_lookup(rtd
, SOF_AUDIO_PCM_DRV_NAME
);
632 struct snd_sof_dai
*dai
=
633 snd_sof_find_dai(component
, (char *)rtd
->dai_link
->name
);
634 struct snd_soc_dpcm
*dpcm
;
636 /* no topology exists for this BE, try a common configuration */
638 dev_warn(component
->dev
,
639 "warning: no topology found for BE DAI %s config\n",
640 rtd
->dai_link
->name
);
642 /* set 48k, stereo, 16bits by default */
650 snd_mask_set_format(fmt
, SNDRV_PCM_FORMAT_S16_LE
);
655 /* read format from topology */
658 switch (dai
->comp_dai
.config
.frame_fmt
) {
659 case SOF_IPC_FRAME_S16_LE
:
660 snd_mask_set_format(fmt
, SNDRV_PCM_FORMAT_S16_LE
);
662 case SOF_IPC_FRAME_S24_4LE
:
663 snd_mask_set_format(fmt
, SNDRV_PCM_FORMAT_S24_LE
);
665 case SOF_IPC_FRAME_S32_LE
:
666 snd_mask_set_format(fmt
, SNDRV_PCM_FORMAT_S32_LE
);
669 dev_err(component
->dev
, "error: No available DAI format!\n");
673 /* read rate and channels from topology */
674 switch (dai
->dai_config
->type
) {
675 case SOF_DAI_INTEL_SSP
:
676 rate
->min
= dai
->dai_config
->ssp
.fsync_rate
;
677 rate
->max
= dai
->dai_config
->ssp
.fsync_rate
;
678 channels
->min
= dai
->dai_config
->ssp
.tdm_slots
;
679 channels
->max
= dai
->dai_config
->ssp
.tdm_slots
;
681 dev_dbg(component
->dev
,
682 "rate_min: %d rate_max: %d\n", rate
->min
, rate
->max
);
683 dev_dbg(component
->dev
,
684 "channels_min: %d channels_max: %d\n",
685 channels
->min
, channels
->max
);
688 case SOF_DAI_INTEL_DMIC
:
689 /* DMIC only supports 16 or 32 bit formats */
690 if (dai
->comp_dai
.config
.frame_fmt
== SOF_IPC_FRAME_S24_4LE
) {
691 dev_err(component
->dev
,
692 "error: invalid fmt %d for DAI type %d\n",
693 dai
->comp_dai
.config
.frame_fmt
,
694 dai
->dai_config
->type
);
697 case SOF_DAI_INTEL_HDA
:
699 * HDAudio does not follow the default trigger
700 * sequence due to firmware implementation
702 for_each_dpcm_fe(rtd
, SNDRV_PCM_STREAM_PLAYBACK
, dpcm
) {
703 struct snd_soc_pcm_runtime
*fe
= dpcm
->fe
;
705 fe
->dai_link
->trigger
[SNDRV_PCM_STREAM_PLAYBACK
] =
706 SND_SOC_DPCM_TRIGGER_POST
;
709 case SOF_DAI_INTEL_ALH
:
710 /* do nothing for ALH dai_link */
712 case SOF_DAI_IMX_ESAI
:
713 rate
->min
= dai
->dai_config
->esai
.fsync_rate
;
714 rate
->max
= dai
->dai_config
->esai
.fsync_rate
;
715 channels
->min
= dai
->dai_config
->esai
.tdm_slots
;
716 channels
->max
= dai
->dai_config
->esai
.tdm_slots
;
718 dev_dbg(component
->dev
,
719 "rate_min: %d rate_max: %d\n", rate
->min
, rate
->max
);
720 dev_dbg(component
->dev
,
721 "channels_min: %d channels_max: %d\n",
722 channels
->min
, channels
->max
);
724 case SOF_DAI_IMX_SAI
:
725 rate
->min
= dai
->dai_config
->sai
.fsync_rate
;
726 rate
->max
= dai
->dai_config
->sai
.fsync_rate
;
727 channels
->min
= dai
->dai_config
->sai
.tdm_slots
;
728 channels
->max
= dai
->dai_config
->sai
.tdm_slots
;
730 dev_dbg(component
->dev
,
731 "rate_min: %d rate_max: %d\n", rate
->min
, rate
->max
);
732 dev_dbg(component
->dev
,
733 "channels_min: %d channels_max: %d\n",
734 channels
->min
, channels
->max
);
737 dev_err(component
->dev
, "error: invalid DAI type %d\n",
738 dai
->dai_config
->type
);
745 static int sof_pcm_probe(struct snd_soc_component
*component
)
747 struct snd_sof_dev
*sdev
= snd_soc_component_get_drvdata(component
);
748 struct snd_sof_pdata
*plat_data
= sdev
->pdata
;
749 const char *tplg_filename
;
752 /* load the default topology */
753 sdev
->component
= component
;
755 tplg_filename
= devm_kasprintf(sdev
->dev
, GFP_KERNEL
,
757 plat_data
->tplg_filename_prefix
,
758 plat_data
->tplg_filename
);
762 ret
= snd_sof_load_topology(component
, tplg_filename
);
764 dev_err(component
->dev
, "error: failed to load DSP topology %d\n",
772 static void sof_pcm_remove(struct snd_soc_component
*component
)
774 /* remove topology */
775 snd_soc_tplg_component_remove(component
);
778 void snd_sof_new_platform_drv(struct snd_sof_dev
*sdev
)
780 struct snd_soc_component_driver
*pd
= &sdev
->plat_drv
;
781 struct snd_sof_pdata
*plat_data
= sdev
->pdata
;
782 const char *drv_name
;
784 drv_name
= plat_data
->machine
->drv_name
;
786 pd
->name
= "sof-audio-component";
787 pd
->probe
= sof_pcm_probe
;
788 pd
->remove
= sof_pcm_remove
;
789 pd
->open
= sof_pcm_open
;
790 pd
->close
= sof_pcm_close
;
791 pd
->hw_params
= sof_pcm_hw_params
;
792 pd
->prepare
= sof_pcm_prepare
;
793 pd
->hw_free
= sof_pcm_hw_free
;
794 pd
->trigger
= sof_pcm_trigger
;
795 pd
->pointer
= sof_pcm_pointer
;
797 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS)
798 pd
->compress_ops
= &sof_compressed_ops
;
800 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
801 /* override cops when probe support is enabled */
802 pd
->compress_ops
= &sof_probe_compressed_ops
;
804 pd
->pcm_construct
= sof_pcm_new
;
805 pd
->ignore_machine
= drv_name
;
806 pd
->be_hw_params_fixup
= sof_pcm_dai_link_fixup
;
807 pd
->be_pcm_base
= SOF_BE_PCM_BASE
;
808 pd
->use_dai_pcm_id
= true;
809 pd
->topology_name_prefix
= "sof";
811 /* increment module refcount when a pcm is opened */
812 pd
->module_get_upon_open
= 1;