1
// SPDX-License-Identifier: (GPL-2.0 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 <dkms/sound/pcm_params.h>
15
#include <dkms/sound/sof.h>
19
#define DRV_NAME "sof-audio-component"
21
/* Create DMA buffer page table for DSP */
22
static int create_page_table(struct snd_soc_component *component,
23
struct snd_pcm_substream *substream,
24
unsigned char *dma_area, size_t size)
26
struct snd_soc_pcm_runtime *rtd = substream->private_data;
27
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
28
struct snd_sof_pcm *spcm;
29
struct snd_dma_buffer *dmab = snd_pcm_get_dma_buf(substream);
30
int stream = substream->stream;
32
spcm = snd_sof_find_spcm_dai(sdev, rtd);
36
return snd_sof_create_page_table(sdev, dmab,
37
spcm->stream[stream].page_table.area, size);
40
static int sof_pcm_dsp_params(struct snd_sof_pcm *spcm, struct snd_pcm_substream *substream,
41
const struct sof_ipc_pcm_params_reply *reply)
43
struct snd_sof_dev *sdev = spcm->sdev;
45
int ret = snd_sof_ipc_pcm_params(sdev, substream, reply);
48
dev_err(sdev->dev, "error: got wrong reply for PCM %d\n",
55
* sof pcm period elapse work
57
static void sof_pcm_period_elapsed_work(struct work_struct *work)
59
struct snd_sof_pcm_stream *sps =
60
container_of(work, struct snd_sof_pcm_stream,
63
snd_pcm_period_elapsed(sps->substream);
67
* sof pcm period elapse, this could be called at irq thread context.
69
void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream)
71
struct snd_soc_pcm_runtime *rtd = substream->private_data;
72
struct snd_soc_component *component =
73
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
74
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
75
struct snd_sof_pcm *spcm;
77
spcm = snd_sof_find_spcm_dai(sdev, rtd);
80
"error: period elapsed for unknown stream!\n");
85
* snd_pcm_period_elapsed() can be called in interrupt context
86
* before IRQ_HANDLED is returned. Inside snd_pcm_period_elapsed(),
87
* when the PCM is done draining or xrun happened, a STOP IPC will
88
* then be sent and this IPC will hit IPC timeout.
89
* To avoid sending IPC before the previous IPC is handled, we
90
* schedule delayed work here to call the snd_pcm_period_elapsed().
92
schedule_work(&spcm->stream[substream->stream].period_elapsed_work);
94
EXPORT_SYMBOL(snd_sof_pcm_period_elapsed);
96
/* this may get called several times by oss emulation */
97
static int sof_pcm_hw_params(struct snd_soc_component *component,
98
struct snd_pcm_substream *substream,
99
struct snd_pcm_hw_params *params)
101
struct snd_soc_pcm_runtime *rtd = substream->private_data;
102
struct snd_pcm_runtime *runtime = substream->runtime;
103
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
104
struct snd_sof_pcm *spcm;
105
struct sof_ipc_pcm_params pcm;
106
struct sof_ipc_pcm_params_reply ipc_params_reply;
109
/* nothing to do for BE */
110
if (rtd->dai_link->no_pcm)
113
spcm = snd_sof_find_spcm_dai(sdev, rtd);
117
dev_dbg(sdev->dev, "pcm: hw params stream %d dir %d\n",
118
spcm->pcm.pcm_id, substream->stream);
120
memset(&pcm, 0, sizeof(pcm));
122
/* allocate audio buffer pages */
123
ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
125
dev_err(sdev->dev, "error: could not allocate %d bytes for PCM %d\n",
126
params_buffer_bytes(params), spcm->pcm.pcm_id);
131
* ret == 1 means the buffer is changed
132
* create compressed page table for audio firmware
133
* ret == 0 means the buffer is not changed
134
* so no need to regenerate the page table
136
ret = create_page_table(component, substream, runtime->dma_area,
142
/* number of pages should be rounded up */
143
pcm.params.buffer.pages = PFN_UP(runtime->dma_bytes);
145
/* set IPC PCM parameters */
146
pcm.hdr.size = sizeof(pcm);
147
pcm.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS;
148
pcm.comp_id = spcm->stream[substream->stream].comp_id;
149
pcm.params.hdr.size = sizeof(pcm.params);
150
pcm.params.buffer.phy_addr =
151
spcm->stream[substream->stream].page_table.addr;
152
pcm.params.buffer.size = runtime->dma_bytes;
153
pcm.params.direction = substream->stream;
154
pcm.params.sample_valid_bytes = params_width(params) >> 3;
155
pcm.params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
156
pcm.params.rate = params_rate(params);
157
pcm.params.channels = params_channels(params);
158
pcm.params.host_period_bytes = params_period_bytes(params);
161
ret = snd_pcm_format_physical_width(params_format(params));
164
pcm.params.sample_container_bytes = ret >> 3;
167
switch (params_format(params)) {
168
case SNDRV_PCM_FORMAT_S16:
169
pcm.params.frame_fmt = SOF_IPC_FRAME_S16_LE;
171
case SNDRV_PCM_FORMAT_S24:
172
pcm.params.frame_fmt = SOF_IPC_FRAME_S24_4LE;
174
case SNDRV_PCM_FORMAT_S32:
175
pcm.params.frame_fmt = SOF_IPC_FRAME_S32_LE;
177
case SNDRV_PCM_FORMAT_FLOAT:
178
pcm.params.frame_fmt = SOF_IPC_FRAME_FLOAT;
184
/* firmware already configured host stream */
185
ret = snd_sof_pcm_platform_hw_params(sdev,
190
dev_err(sdev->dev, "error: platform hw params failed\n");
194
dev_dbg(sdev->dev, "stream_tag %d", pcm.params.stream_tag);
196
/* send IPC to the DSP */
197
ret = sof_ipc_tx_message(sdev->ipc, pcm.hdr.cmd, &pcm, sizeof(pcm),
198
&ipc_params_reply, sizeof(ipc_params_reply));
200
dev_err(sdev->dev, "error: hw params ipc failed for stream %d\n",
201
pcm.params.stream_tag);
205
ret = sof_pcm_dsp_params(spcm, substream, &ipc_params_reply);
209
spcm->prepared[substream->stream] = true;
211
/* save pcm hw_params */
212
memcpy(&spcm->params[substream->stream], params, sizeof(*params));
217
static int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream,
218
struct snd_sof_dev *sdev,
219
struct snd_sof_pcm *spcm)
221
struct sof_ipc_stream stream;
222
struct sof_ipc_reply reply;
225
stream.hdr.size = sizeof(stream);
226
stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
227
stream.comp_id = spcm->stream[substream->stream].comp_id;
229
/* send IPC to the DSP */
230
ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
231
sizeof(stream), &reply, sizeof(reply));
233
spcm->prepared[substream->stream] = false;
238
static int sof_pcm_hw_free(struct snd_soc_component *component,
239
struct snd_pcm_substream *substream)
241
struct snd_soc_pcm_runtime *rtd = substream->private_data;
242
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
243
struct snd_sof_pcm *spcm;
246
/* nothing to do for BE */
247
if (rtd->dai_link->no_pcm)
250
spcm = snd_sof_find_spcm_dai(sdev, rtd);
254
dev_dbg(sdev->dev, "pcm: free stream %d dir %d\n", spcm->pcm.pcm_id,
257
if (spcm->prepared[substream->stream]) {
258
ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
263
snd_pcm_lib_free_pages(substream);
265
cancel_work_sync(&spcm->stream[substream->stream].period_elapsed_work);
267
ret = snd_sof_pcm_platform_hw_free(sdev, substream);
269
dev_err(sdev->dev, "error: platform hw free failed\n");
276
static int sof_pcm_prepare(struct snd_soc_component *component,
277
struct snd_pcm_substream *substream)
279
struct snd_soc_pcm_runtime *rtd = substream->private_data;
280
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
281
struct snd_sof_pcm *spcm;
284
/* nothing to do for BE */
285
if (rtd->dai_link->no_pcm)
288
spcm = snd_sof_find_spcm_dai(sdev, rtd);
292
if (spcm->prepared[substream->stream])
295
dev_dbg(sdev->dev, "pcm: prepare stream %d dir %d\n", spcm->pcm.pcm_id,
299
ret = sof_pcm_hw_params(component,
300
substream, &spcm->params[substream->stream]);
302
dev_err(sdev->dev, "error: set pcm hw_params after resume\n");
310
* FE dai link trigger actions are always executed in non-atomic context because
311
* they involve IPC's.
313
static int sof_pcm_trigger(struct snd_soc_component *component,
314
struct snd_pcm_substream *substream, int cmd)
316
struct snd_soc_pcm_runtime *rtd = substream->private_data;
317
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
318
struct snd_sof_pcm *spcm;
319
struct sof_ipc_stream stream;
320
struct sof_ipc_reply reply;
321
bool reset_hw_params = false;
322
bool ipc_first = false;
325
/* nothing to do for BE */
326
if (rtd->dai_link->no_pcm)
329
spcm = snd_sof_find_spcm_dai(sdev, rtd);
333
dev_dbg(sdev->dev, "pcm: trigger stream %d dir %d cmd %d\n",
334
spcm->pcm.pcm_id, substream->stream, cmd);
336
stream.hdr.size = sizeof(stream);
337
stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG;
338
stream.comp_id = spcm->stream[substream->stream].comp_id;
341
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
342
stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_PAUSE;
345
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
346
stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE;
348
case SNDRV_PCM_TRIGGER_RESUME:
349
if (spcm->stream[substream->stream].suspend_ignored) {
351
* this case will be triggered when INFO_RESUME is
352
* supported, no need to resume streams that remained
355
spcm->stream[substream->stream].suspend_ignored = false;
359
dev_dbg(sdev->dev, "pcm: trigger resume stream %d dir %d cmd %d\n",
360
spcm->pcm.pcm_id, substream->stream, cmd);
362
/* set up hw_params */
363
ret = sof_pcm_prepare(component, substream);
366
"error: failed to set up hw_params upon resume\n");
371
case SNDRV_PCM_TRIGGER_START:
372
if (spcm->stream[substream->stream].suspend_ignored) {
374
* This case will be triggered when INFO_RESUME is
375
* not supported, no need to re-start streams that
376
* remained enabled in D0ix.
378
spcm->stream[substream->stream].suspend_ignored = false;
381
stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_START;
383
case SNDRV_PCM_TRIGGER_SUSPEND:
384
if (sdev->s0_suspend &&
385
spcm->stream[substream->stream].d0i3_compatible) {
387
* trap the event, not sending trigger stop to
388
* prevent the FW pipelines from being stopped,
389
* and mark the flag to ignore the upcoming DAPM
392
spcm->stream[substream->stream].suspend_ignored = true;
396
dev_dbg(sdev->dev, "pcm: trigger suspend stream %d dir %d cmd %d\n",
397
spcm->pcm.pcm_id, substream->stream, cmd);
400
case SNDRV_PCM_TRIGGER_STOP:
401
stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP;
403
reset_hw_params = true;
406
dev_err(sdev->dev, "error: unhandled trigger cmd %d\n", cmd);
411
* DMA and IPC sequence is different for start and stop. Need to send
412
* STOP IPC before stop DMA
415
snd_sof_pcm_platform_trigger(sdev, substream, cmd);
417
/* send IPC to the DSP */
418
ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
419
sizeof(stream), &reply, sizeof(reply));
421
/* need to STOP DMA even if STOP IPC failed */
423
snd_sof_pcm_platform_trigger(sdev, substream, cmd);
425
/* free PCM if reset_hw_params is set and the STOP IPC is successful */
426
if (!ret && reset_hw_params)
427
ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
432
static snd_pcm_uframes_t sof_pcm_pointer(struct snd_soc_component *component,
433
struct snd_pcm_substream *substream)
435
struct snd_soc_pcm_runtime *rtd = substream->private_data;
436
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
437
struct snd_sof_pcm *spcm;
438
snd_pcm_uframes_t host, dai;
440
/* nothing to do for BE */
441
if (rtd->dai_link->no_pcm)
444
/* use dsp ops pointer callback directly if set */
445
if (sof_ops(sdev)->pcm_pointer)
446
return sof_ops(sdev)->pcm_pointer(sdev, substream);
448
spcm = snd_sof_find_spcm_dai(sdev, rtd);
452
/* read position from DSP */
453
host = bytes_to_frames(substream->runtime,
454
spcm->stream[substream->stream].posn.host_posn);
455
dai = bytes_to_frames(substream->runtime,
456
spcm->stream[substream->stream].posn.dai_posn);
458
dev_dbg(sdev->dev, "PCM: stream %d dir %d DMA position %lu DAI position %lu\n",
459
spcm->pcm.pcm_id, substream->stream, host, dai);
464
static int sof_pcm_open(struct snd_soc_component *component,
465
struct snd_pcm_substream *substream)
467
struct snd_soc_pcm_runtime *rtd = substream->private_data;
468
struct snd_pcm_runtime *runtime = substream->runtime;
469
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
470
const struct snd_sof_dsp_ops *ops = sof_ops(sdev);
471
struct snd_sof_pcm *spcm;
472
struct snd_soc_tplg_stream_caps *caps;
475
/* nothing to do for BE */
476
if (rtd->dai_link->no_pcm)
479
spcm = snd_sof_find_spcm_dai(sdev, rtd);
483
dev_dbg(sdev->dev, "pcm: open stream %d dir %d\n", spcm->pcm.pcm_id,
486
INIT_WORK(&spcm->stream[substream->stream].period_elapsed_work,
487
sof_pcm_period_elapsed_work);
489
caps = &spcm->pcm.caps[substream->stream];
491
/* set any runtime constraints based on topology */
492
snd_pcm_hw_constraint_step(substream->runtime, 0,
493
SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
494
le32_to_cpu(caps->period_size_min));
495
snd_pcm_hw_constraint_step(substream->runtime, 0,
496
SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
497
le32_to_cpu(caps->period_size_min));
499
/* set runtime config */
500
runtime->hw.info = ops->hw_info; /* platform-specific */
502
runtime->hw.formats = le64_to_cpu(caps->formats);
503
runtime->hw.period_bytes_min = le32_to_cpu(caps->period_size_min);
504
runtime->hw.period_bytes_max = le32_to_cpu(caps->period_size_max);
505
runtime->hw.periods_min = le32_to_cpu(caps->periods_min);
506
runtime->hw.periods_max = le32_to_cpu(caps->periods_max);
509
* caps->buffer_size_min is not used since the
510
* snd_pcm_hardware structure only defines buffer_bytes_max
512
runtime->hw.buffer_bytes_max = le32_to_cpu(caps->buffer_size_max);
514
dev_dbg(sdev->dev, "period min %zd max %zd bytes\n",
515
runtime->hw.period_bytes_min,
516
runtime->hw.period_bytes_max);
517
dev_dbg(sdev->dev, "period count %d max %d\n",
518
runtime->hw.periods_min,
519
runtime->hw.periods_max);
520
dev_dbg(sdev->dev, "buffer max %zd bytes\n",
521
runtime->hw.buffer_bytes_max);
523
/* set wait time - TODO: come from topology */
524
substream->wait_time = 500;
526
spcm->stream[substream->stream].posn.host_posn = 0;
527
spcm->stream[substream->stream].posn.dai_posn = 0;
528
spcm->stream[substream->stream].substream = substream;
529
spcm->prepared[substream->stream] = false;
531
ret = snd_sof_pcm_platform_open(sdev, substream);
533
dev_err(sdev->dev, "error: pcm open failed %d\n", ret);
538
static int sof_pcm_close(struct snd_soc_component *component,
539
struct snd_pcm_substream *substream)
541
struct snd_soc_pcm_runtime *rtd = substream->private_data;
542
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
543
struct snd_sof_pcm *spcm;
546
/* nothing to do for BE */
547
if (rtd->dai_link->no_pcm)
550
spcm = snd_sof_find_spcm_dai(sdev, rtd);
554
dev_dbg(sdev->dev, "pcm: close stream %d dir %d\n", spcm->pcm.pcm_id,
557
err = snd_sof_pcm_platform_close(sdev, substream);
559
dev_err(sdev->dev, "error: pcm close failed %d\n",
562
* keep going, no point in preventing the close
571
* Pre-allocate playback/capture audio buffer pages.
572
* no need to explicitly release memory preallocated by sof_pcm_new in pcm_free
573
* snd_pcm_lib_preallocate_free_for_all() is called by the core.
575
static int sof_pcm_new(struct snd_soc_component *component,
576
struct snd_soc_pcm_runtime *rtd)
578
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
579
struct snd_sof_pcm *spcm;
580
struct snd_pcm *pcm = rtd->pcm;
581
struct snd_soc_tplg_stream_caps *caps;
582
int stream = SNDRV_PCM_STREAM_PLAYBACK;
584
/* find SOF PCM for this RTD */
585
spcm = snd_sof_find_spcm_dai(sdev, rtd);
587
dev_warn(sdev->dev, "warn: can't find PCM with DAI ID %d\n",
592
dev_dbg(sdev->dev, "creating new PCM %s\n", spcm->pcm.pcm_name);
594
/* do we need to pre-allocate playback audio buffer pages */
595
if (!spcm->pcm.playback)
598
caps = &spcm->pcm.caps[stream];
600
/* pre-allocate playback audio buffer pages */
601
dev_dbg(sdev->dev, "spcm: allocate %s playback DMA buffer size 0x%x max 0x%x\n",
602
caps->name, caps->buffer_size_min, caps->buffer_size_max);
604
snd_pcm_lib_preallocate_pages(pcm->streams[stream].substream,
605
SNDRV_DMA_TYPE_DEV_SG, sdev->dev,
606
le32_to_cpu(caps->buffer_size_min),
607
le32_to_cpu(caps->buffer_size_max));
609
stream = SNDRV_PCM_STREAM_CAPTURE;
611
/* do we need to pre-allocate capture audio buffer pages */
612
if (!spcm->pcm.capture)
615
caps = &spcm->pcm.caps[stream];
617
/* pre-allocate capture audio buffer pages */
618
dev_dbg(sdev->dev, "spcm: allocate %s capture DMA buffer size 0x%x max 0x%x\n",
619
caps->name, caps->buffer_size_min, caps->buffer_size_max);
621
snd_pcm_lib_preallocate_pages(pcm->streams[stream].substream,
622
SNDRV_DMA_TYPE_DEV_SG, sdev->dev,
623
le32_to_cpu(caps->buffer_size_min),
624
le32_to_cpu(caps->buffer_size_max));
629
/* fixup the BE DAI link to match any values from topology */
630
static int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
631
struct snd_pcm_hw_params *params)
633
struct snd_interval *rate = hw_param_interval(params,
634
SNDRV_PCM_HW_PARAM_RATE);
635
struct snd_interval *channels = hw_param_interval(params,
636
SNDRV_PCM_HW_PARAM_CHANNELS);
637
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
638
struct snd_soc_component *component =
639
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
640
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
641
struct snd_sof_dai *dai =
642
snd_sof_find_dai(sdev, (char *)rtd->dai_link->name);
644
/* no topology exists for this BE, try a common configuration */
646
dev_warn(sdev->dev, "warning: no topology found for BE DAI %s config\n",
647
rtd->dai_link->name);
649
/* set 48k, stereo, 16bits by default */
657
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
662
/* read format from topology */
665
switch (dai->comp_dai.config.frame_fmt) {
666
case SOF_IPC_FRAME_S16_LE:
667
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
669
case SOF_IPC_FRAME_S24_4LE:
670
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
672
case SOF_IPC_FRAME_S32_LE:
673
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE);
676
dev_err(sdev->dev, "error: No available DAI format!\n");
680
/* read rate and channels from topology */
681
switch (dai->dai_config->type) {
682
case SOF_DAI_INTEL_SSP:
683
rate->min = dai->dai_config->ssp.fsync_rate;
684
rate->max = dai->dai_config->ssp.fsync_rate;
685
channels->min = dai->dai_config->ssp.tdm_slots;
686
channels->max = dai->dai_config->ssp.tdm_slots;
689
"rate_min: %d rate_max: %d\n", rate->min, rate->max);
691
"channels_min: %d channels_max: %d\n",
692
channels->min, channels->max);
695
case SOF_DAI_INTEL_DMIC:
696
/* DMIC only supports 16 or 32 bit formats */
697
if (dai->comp_dai.config.frame_fmt == SOF_IPC_FRAME_S24_4LE) {
699
"error: invalid fmt %d for DAI type %d\n",
700
dai->comp_dai.config.frame_fmt,
701
dai->dai_config->type);
704
case SOF_DAI_INTEL_HDA:
705
/* do nothing for HDA dai_link */
707
case SOF_DAI_INTEL_ALH:
708
/* do nothing for ALH dai_link */
710
case SOF_DAI_IMX_ESAI:
711
channels->min = dai->dai_config->esai.tdm_slots;
712
channels->max = dai->dai_config->esai.tdm_slots;
715
"channels_min: %d channels_max: %d\n",
716
channels->min, channels->max);
719
dev_err(sdev->dev, "error: invalid DAI type %d\n",
720
dai->dai_config->type);
727
static int sof_pcm_probe(struct snd_soc_component *component)
729
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
730
struct snd_sof_pdata *plat_data = sdev->pdata;
731
const char *tplg_filename;
734
/* load the default topology */
735
sdev->component = component;
737
tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
739
plat_data->tplg_filename_prefix,
740
plat_data->tplg_filename);
744
ret = snd_sof_load_topology(sdev, tplg_filename);
746
dev_err(sdev->dev, "error: failed to load DSP topology %d\n",
752
* Some platforms in SOF, ex: BYT, may not have their platform PM
753
* callbacks set. Increment the usage count so as to
754
* prevent the device from entering runtime suspend.
756
if (!sof_ops(sdev)->runtime_suspend || !sof_ops(sdev)->runtime_resume)
757
pm_runtime_get_noresume(sdev->dev);
762
static void sof_pcm_remove(struct snd_soc_component *component)
764
/* remove topology */
765
snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL);
768
void snd_sof_new_platform_drv(struct snd_sof_dev *sdev)
770
struct snd_soc_component_driver *pd = &sdev->plat_drv;
771
struct snd_sof_pdata *plat_data = sdev->pdata;
772
const char *drv_name;
774
drv_name = plat_data->machine->drv_name;
776
pd->name = "sof-audio-component";
777
pd->probe = sof_pcm_probe;
778
pd->remove = sof_pcm_remove;
779
pd->open = sof_pcm_open;
780
pd->close = sof_pcm_close;
781
pd->ioctl = snd_soc_pcm_lib_ioctl;
782
pd->hw_params = sof_pcm_hw_params;
783
pd->prepare = sof_pcm_prepare;
784
pd->hw_free = sof_pcm_hw_free;
785
pd->trigger = sof_pcm_trigger;
786
pd->pointer = sof_pcm_pointer;
788
#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS)
789
pd->compr_ops = &sof_compressed_ops;
791
pd->pcm_construct = sof_pcm_new;
792
pd->ignore_machine = drv_name;
793
pd->be_hw_params_fixup = sof_pcm_dai_link_fixup;
794
pd->be_pcm_base = SOF_BE_PCM_BASE;
795
pd->use_dai_pcm_id = true;
796
pd->topology_name_prefix = "sof";
798
/* increment module refcount when a pcm is opened */
799
pd->module_get_upon_open = 1;