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 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 <trace/events/sof.h> 17 #include "sof-of-dev.h" 18 #include "sof-priv.h" 19 #include "sof-audio.h" 20 #include "sof-utils.h" 21 #include "ops.h" 22 23 /* 24 * sof pcm period elapse work 25 */ 26 static void snd_sof_pcm_period_elapsed_work(struct work_struct *work) 27 { 28 struct snd_sof_pcm_stream *sps = 29 container_of(work, struct snd_sof_pcm_stream, 30 period_elapsed_work); 31 32 snd_pcm_period_elapsed(sps->substream); 33 } 34 35 void snd_sof_pcm_init_elapsed_work(struct work_struct *work) 36 { 37 INIT_WORK(work, snd_sof_pcm_period_elapsed_work); 38 } 39 40 /* 41 * sof pcm period elapse, this could be called at irq thread context. 42 */ 43 void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream) 44 { 45 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 46 struct snd_soc_component *component = 47 snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME); 48 struct snd_sof_pcm *spcm; 49 50 spcm = snd_sof_find_spcm_dai(component, rtd); 51 if (!spcm) { 52 dev_err(component->dev, 53 "error: period elapsed for unknown stream!\n"); 54 return; 55 } 56 57 /* 58 * snd_pcm_period_elapsed() can be called in interrupt context 59 * before IRQ_HANDLED is returned. Inside snd_pcm_period_elapsed(), 60 * when the PCM is done draining or xrun happened, a STOP IPC will 61 * then be sent and this IPC will hit IPC timeout. 62 * To avoid sending IPC before the previous IPC is handled, we 63 * schedule delayed work here to call the snd_pcm_period_elapsed(). 64 */ 65 schedule_work(&spcm->stream[substream->stream].period_elapsed_work); 66 } 67 EXPORT_SYMBOL(snd_sof_pcm_period_elapsed); 68 69 static int 70 sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_runtime *rtd, 71 struct snd_sof_pcm *spcm, struct snd_pcm_hw_params *params, 72 struct snd_sof_platform_stream_params *platform_params, int dir) 73 { 74 struct snd_soc_dai *dai; 75 int ret, j; 76 77 /* query DAPM for list of connected widgets and set them up */ 78 for_each_rtd_cpu_dais(rtd, j, dai) { 79 struct snd_soc_dapm_widget_list *list; 80 81 ret = snd_soc_dapm_dai_get_connected_widgets(dai, dir, &list, 82 dpcm_end_walk_at_be); 83 if (ret < 0) { 84 spcm_err(spcm, dir, "dai %s has no valid %s path\n", 85 dai->name, snd_pcm_direction_name(dir)); 86 return ret; 87 } 88 89 spcm->stream[dir].list = list; 90 91 ret = sof_widget_list_setup(sdev, spcm, params, platform_params, dir); 92 if (ret < 0) { 93 spcm_err(spcm, dir, "Widget list set up failed\n"); 94 spcm->stream[dir].list = NULL; 95 snd_soc_dapm_dai_free_widgets(&list); 96 return ret; 97 } 98 } 99 100 return 0; 101 } 102 103 static int sof_pcm_hw_params(struct snd_soc_component *component, 104 struct snd_pcm_substream *substream, 105 struct snd_pcm_hw_params *params) 106 { 107 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 108 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 109 const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm); 110 struct snd_sof_platform_stream_params platform_params = { 0 }; 111 struct snd_pcm_runtime *runtime = substream->runtime; 112 struct snd_sof_pcm *spcm; 113 int ret; 114 115 /* nothing to do for BE */ 116 if (rtd->dai_link->no_pcm) 117 return 0; 118 119 spcm = snd_sof_find_spcm_dai(component, rtd); 120 if (!spcm) 121 return -EINVAL; 122 123 spcm_dbg(spcm, substream->stream, "Entry: hw_params\n"); 124 125 /* 126 * Handle repeated calls to hw_params() without free_pcm() in 127 * between. At least ALSA OSS emulation depends on this. 128 */ 129 if (spcm->prepared[substream->stream] && pcm_ops && pcm_ops->hw_free) { 130 ret = pcm_ops->hw_free(component, substream); 131 if (ret < 0) 132 return ret; 133 134 spcm->prepared[substream->stream] = false; 135 } 136 137 ret = snd_sof_pcm_platform_hw_params(sdev, substream, params, &platform_params); 138 if (ret < 0) { 139 spcm_err(spcm, substream->stream, "platform hw params failed\n"); 140 return ret; 141 } 142 143 /* if this is a repeated hw_params without hw_free, skip setting up widgets */ 144 if (!spcm->stream[substream->stream].list) { 145 ret = sof_pcm_setup_connected_widgets(sdev, rtd, spcm, params, &platform_params, 146 substream->stream); 147 if (ret < 0) 148 return ret; 149 } 150 151 /* create compressed page table for audio firmware */ 152 if (runtime->buffer_changed) { 153 struct snd_dma_buffer *dmab = snd_pcm_get_dma_buf(substream); 154 155 ret = snd_sof_create_page_table(component->dev, dmab, 156 spcm->stream[substream->stream].page_table.area, 157 runtime->dma_bytes); 158 if (ret < 0) 159 return ret; 160 } 161 162 if (pcm_ops && pcm_ops->hw_params) { 163 ret = pcm_ops->hw_params(component, substream, params, &platform_params); 164 if (ret < 0) 165 return ret; 166 } 167 168 spcm->prepared[substream->stream] = true; 169 170 /* save pcm hw_params */ 171 memcpy(&spcm->params[substream->stream], params, sizeof(*params)); 172 173 return 0; 174 } 175 176 static int sof_pcm_stream_free(struct snd_sof_dev *sdev, 177 struct snd_pcm_substream *substream, 178 struct snd_sof_pcm *spcm, int dir, 179 bool free_widget_list) 180 { 181 const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm); 182 int ret; 183 int err = 0; 184 185 if (spcm->prepared[substream->stream]) { 186 /* stop DMA first if needed */ 187 if (pcm_ops && pcm_ops->platform_stop_during_hw_free) 188 snd_sof_pcm_platform_trigger(sdev, substream, 189 SNDRV_PCM_TRIGGER_STOP); 190 191 /* free PCM in the DSP */ 192 if (pcm_ops && pcm_ops->hw_free) { 193 ret = pcm_ops->hw_free(sdev->component, substream); 194 if (ret < 0) { 195 spcm_err(spcm, substream->stream, 196 "pcm_ops->hw_free failed %d\n", ret); 197 err = ret; 198 } 199 } 200 201 spcm->prepared[substream->stream] = false; 202 spcm->pending_stop[substream->stream] = false; 203 } 204 205 /* reset the DMA */ 206 ret = snd_sof_pcm_platform_hw_free(sdev, substream); 207 if (ret < 0) { 208 spcm_err(spcm, substream->stream, 209 "platform hw free failed %d\n", ret); 210 if (!err) 211 err = ret; 212 } 213 214 /* free widget list */ 215 if (free_widget_list) { 216 ret = sof_widget_list_free(sdev, spcm, dir); 217 if (ret < 0) { 218 spcm_err(spcm, substream->stream, 219 "sof_widget_list_free failed %d\n", ret); 220 if (!err) 221 err = ret; 222 } 223 } 224 225 return err; 226 } 227 228 int sof_pcm_free_all_streams(struct snd_sof_dev *sdev) 229 { 230 struct snd_pcm_substream *substream; 231 struct snd_sof_pcm *spcm; 232 int dir, ret; 233 234 list_for_each_entry(spcm, &sdev->pcm_list, list) { 235 for_each_pcm_streams(dir) { 236 substream = spcm->stream[dir].substream; 237 238 if (!substream || !substream->runtime || 239 spcm->stream[dir].suspend_ignored) 240 continue; 241 242 if (spcm->stream[dir].list) { 243 ret = sof_pcm_stream_free(sdev, substream, spcm, 244 dir, true); 245 if (ret < 0) 246 return ret; 247 } 248 } 249 } 250 251 return 0; 252 } 253 254 static int sof_pcm_hw_free(struct snd_soc_component *component, 255 struct snd_pcm_substream *substream) 256 { 257 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 258 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 259 struct snd_sof_pcm *spcm; 260 int ret; 261 262 /* nothing to do for BE */ 263 if (rtd->dai_link->no_pcm) 264 return 0; 265 266 spcm = snd_sof_find_spcm_dai(component, rtd); 267 if (!spcm) 268 return -EINVAL; 269 270 spcm_dbg(spcm, substream->stream, "Entry: hw_free\n"); 271 272 ret = sof_pcm_stream_free(sdev, substream, spcm, substream->stream, true); 273 274 cancel_work_sync(&spcm->stream[substream->stream].period_elapsed_work); 275 276 return ret; 277 } 278 279 static int sof_pcm_prepare(struct snd_soc_component *component, 280 struct snd_pcm_substream *substream) 281 { 282 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 283 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 284 struct snd_sof_pcm *spcm; 285 int ret; 286 287 /* nothing to do for BE */ 288 if (rtd->dai_link->no_pcm) 289 return 0; 290 291 spcm = snd_sof_find_spcm_dai(component, rtd); 292 if (!spcm) 293 return -EINVAL; 294 295 spcm_dbg(spcm, substream->stream, "Entry: prepare\n"); 296 297 if (spcm->prepared[substream->stream]) { 298 if (!spcm->pending_stop[substream->stream]) 299 return 0; 300 301 /* 302 * this case should be reached in case of xruns where we absolutely 303 * want to free-up and reset all PCM/DMA resources 304 */ 305 ret = sof_pcm_stream_free(sdev, substream, spcm, substream->stream, true); 306 if (ret < 0) 307 return ret; 308 } 309 310 /* set hw_params */ 311 ret = sof_pcm_hw_params(component, 312 substream, &spcm->params[substream->stream]); 313 if (ret < 0) { 314 spcm_err(spcm, substream->stream, 315 "failed to set hw_params after resume\n"); 316 return ret; 317 } 318 319 return 0; 320 } 321 322 /* 323 * FE dai link trigger actions are always executed in non-atomic context because 324 * they involve IPC's. 325 */ 326 static int sof_pcm_trigger(struct snd_soc_component *component, 327 struct snd_pcm_substream *substream, int cmd) 328 { 329 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 330 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 331 const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm); 332 struct snd_sof_pcm *spcm; 333 bool reset_hw_params = false; 334 bool ipc_first = false; 335 int ret = 0; 336 337 /* nothing to do for BE */ 338 if (rtd->dai_link->no_pcm) 339 return 0; 340 341 spcm = snd_sof_find_spcm_dai(component, rtd); 342 if (!spcm) 343 return -EINVAL; 344 345 spcm_dbg(spcm, substream->stream, "Entry: trigger (cmd: %d)\n", cmd); 346 347 spcm->pending_stop[substream->stream] = false; 348 349 switch (cmd) { 350 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 351 ipc_first = true; 352 break; 353 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 354 if (pcm_ops && pcm_ops->ipc_first_on_start) 355 ipc_first = true; 356 break; 357 case SNDRV_PCM_TRIGGER_START: 358 if (spcm->stream[substream->stream].suspend_ignored) { 359 /* 360 * This case will be triggered when INFO_RESUME is 361 * not supported, no need to re-start streams that 362 * remained enabled in D0ix. 363 */ 364 spcm->stream[substream->stream].suspend_ignored = false; 365 return 0; 366 } 367 368 if (pcm_ops && pcm_ops->ipc_first_on_start) 369 ipc_first = true; 370 break; 371 case SNDRV_PCM_TRIGGER_SUSPEND: 372 /* 373 * If DSP D0I3 is allowed during S0iX, set the suspend_ignored flag for 374 * D0I3-compatible streams to keep the firmware pipeline running 375 */ 376 if (pcm_ops && pcm_ops->d0i3_supported_in_s0ix && 377 sdev->system_suspend_target == SOF_SUSPEND_S0IX && 378 spcm->stream[substream->stream].d0i3_compatible) { 379 spcm->stream[substream->stream].suspend_ignored = true; 380 return 0; 381 } 382 383 /* On suspend the DMA must be stopped in DSPless mode */ 384 if (sdev->dspless_mode_selected) 385 reset_hw_params = true; 386 387 fallthrough; 388 case SNDRV_PCM_TRIGGER_STOP: 389 ipc_first = true; 390 if (pcm_ops && pcm_ops->reset_hw_params_during_stop) 391 reset_hw_params = true; 392 break; 393 default: 394 spcm_err(spcm, substream->stream, "Unhandled trigger cmd %d\n", cmd); 395 return -EINVAL; 396 } 397 398 if (!ipc_first) 399 snd_sof_pcm_platform_trigger(sdev, substream, cmd); 400 401 if (pcm_ops && pcm_ops->trigger) 402 ret = pcm_ops->trigger(component, substream, cmd); 403 404 switch (cmd) { 405 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 406 case SNDRV_PCM_TRIGGER_START: 407 /* invoke platform trigger to start DMA only if pcm_ops is successful */ 408 if (ipc_first && !ret) 409 snd_sof_pcm_platform_trigger(sdev, substream, cmd); 410 break; 411 case SNDRV_PCM_TRIGGER_SUSPEND: 412 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 413 case SNDRV_PCM_TRIGGER_STOP: 414 /* invoke platform trigger to stop DMA even if pcm_ops isn't set or if it failed */ 415 if (!pcm_ops || !pcm_ops->platform_stop_during_hw_free) 416 snd_sof_pcm_platform_trigger(sdev, substream, cmd); 417 418 /* 419 * set the pending_stop flag to indicate that pipeline stop has been delayed. 420 * This will be used later to stop the pipelines during prepare when recovering 421 * from xruns. 422 */ 423 if (pcm_ops && pcm_ops->platform_stop_during_hw_free && 424 cmd == SNDRV_PCM_TRIGGER_STOP) 425 spcm->pending_stop[substream->stream] = true; 426 break; 427 default: 428 break; 429 } 430 431 /* free PCM if reset_hw_params is set and the STOP IPC is successful */ 432 if (!ret && reset_hw_params) 433 ret = sof_pcm_stream_free(sdev, substream, spcm, substream->stream, false); 434 435 return ret; 436 } 437 438 static snd_pcm_uframes_t sof_pcm_pointer(struct snd_soc_component *component, 439 struct snd_pcm_substream *substream) 440 { 441 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 442 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 443 const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm); 444 struct snd_sof_pcm *spcm; 445 snd_pcm_uframes_t host, dai; 446 int ret = -EOPNOTSUPP; 447 448 /* nothing to do for BE */ 449 if (rtd->dai_link->no_pcm) 450 return 0; 451 452 if (pcm_ops && pcm_ops->pointer) 453 ret = pcm_ops->pointer(component, substream, &host); 454 455 if (ret != -EOPNOTSUPP) 456 return ret ? ret : host; 457 458 /* use dsp ops pointer callback directly if set */ 459 if (sof_ops(sdev)->pcm_pointer) 460 return sof_ops(sdev)->pcm_pointer(sdev, substream); 461 462 spcm = snd_sof_find_spcm_dai(component, rtd); 463 if (!spcm) 464 return -EINVAL; 465 466 /* read position from DSP */ 467 host = bytes_to_frames(substream->runtime, 468 spcm->stream[substream->stream].posn.host_posn); 469 dai = bytes_to_frames(substream->runtime, 470 spcm->stream[substream->stream].posn.dai_posn); 471 472 trace_sof_pcm_pointer_position(sdev, spcm, substream, host, dai); 473 474 return host; 475 } 476 477 static int sof_pcm_open(struct snd_soc_component *component, 478 struct snd_pcm_substream *substream) 479 { 480 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 481 struct snd_pcm_runtime *runtime = substream->runtime; 482 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 483 const struct snd_sof_dsp_ops *ops = sof_ops(sdev); 484 struct snd_sof_pcm *spcm; 485 struct snd_soc_tplg_stream_caps *caps; 486 int ret; 487 488 /* nothing to do for BE */ 489 if (rtd->dai_link->no_pcm) 490 return 0; 491 492 spcm = snd_sof_find_spcm_dai(component, rtd); 493 if (!spcm) 494 return -EINVAL; 495 496 spcm_dbg(spcm, substream->stream, "Entry: open\n"); 497 498 caps = &spcm->pcm.caps[substream->stream]; 499 500 /* set runtime config */ 501 runtime->hw.info = ops->hw_info; /* platform-specific */ 502 503 /* set any runtime constraints based on topology */ 504 runtime->hw.formats = le64_to_cpu(caps->formats); 505 runtime->hw.period_bytes_min = le32_to_cpu(caps->period_size_min); 506 runtime->hw.period_bytes_max = le32_to_cpu(caps->period_size_max); 507 runtime->hw.periods_min = le32_to_cpu(caps->periods_min); 508 runtime->hw.periods_max = le32_to_cpu(caps->periods_max); 509 510 /* 511 * caps->buffer_size_min is not used since the 512 * snd_pcm_hardware structure only defines buffer_bytes_max 513 */ 514 runtime->hw.buffer_bytes_max = le32_to_cpu(caps->buffer_size_max); 515 516 /* set wait time - TODO: come from topology */ 517 substream->wait_time = 500; 518 519 spcm->stream[substream->stream].posn.host_posn = 0; 520 spcm->stream[substream->stream].posn.dai_posn = 0; 521 spcm->stream[substream->stream].substream = substream; 522 spcm->prepared[substream->stream] = false; 523 524 ret = snd_sof_pcm_platform_open(sdev, substream); 525 if (ret < 0) { 526 spcm_err(spcm, substream->stream, 527 "platform pcm open failed %d\n", ret); 528 return ret; 529 } 530 531 spcm_dbg(spcm, substream->stream, "period bytes min %zd, max %zd\n", 532 runtime->hw.period_bytes_min, runtime->hw.period_bytes_max); 533 spcm_dbg(spcm, substream->stream, "period count min %d, max %d\n", 534 runtime->hw.periods_min, runtime->hw.periods_max); 535 spcm_dbg(spcm, substream->stream, "buffer bytes max %zd\n", runtime->hw.buffer_bytes_max); 536 537 return 0; 538 } 539 540 static int sof_pcm_close(struct snd_soc_component *component, 541 struct snd_pcm_substream *substream) 542 { 543 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 544 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 545 struct snd_sof_pcm *spcm; 546 int err; 547 548 /* nothing to do for BE */ 549 if (rtd->dai_link->no_pcm) 550 return 0; 551 552 spcm = snd_sof_find_spcm_dai(component, rtd); 553 if (!spcm) 554 return -EINVAL; 555 556 spcm_dbg(spcm, substream->stream, "Entry: close\n"); 557 558 err = snd_sof_pcm_platform_close(sdev, substream); 559 if (err < 0) { 560 spcm_err(spcm, substream->stream, 561 "platform pcm close failed %d\n", err); 562 /* 563 * keep going, no point in preventing the close 564 * from happening 565 */ 566 } 567 568 spcm->stream[substream->stream].substream = NULL; 569 570 return 0; 571 } 572 573 /* 574 * Pre-allocate playback/capture audio buffer pages. 575 * no need to explicitly release memory preallocated by sof_pcm_new in pcm_free 576 * snd_pcm_lib_preallocate_free_for_all() is called by the core. 577 */ 578 static int sof_pcm_new(struct snd_soc_component *component, 579 struct snd_soc_pcm_runtime *rtd) 580 { 581 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 582 struct snd_sof_pcm *spcm; 583 struct snd_pcm *pcm = rtd->pcm; 584 struct snd_soc_tplg_stream_caps *caps; 585 int stream = SNDRV_PCM_STREAM_PLAYBACK; 586 587 /* find SOF PCM for this RTD */ 588 spcm = snd_sof_find_spcm_dai(component, rtd); 589 if (!spcm) { 590 dev_warn(component->dev, "warn: can't find PCM with DAI ID %d\n", 591 rtd->dai_link->id); 592 return 0; 593 } 594 595 dev_dbg(spcm->scomp->dev, "pcm%u (%s): Entry: pcm_construct\n", 596 spcm->pcm.pcm_id, spcm->pcm.pcm_name); 597 598 /* do we need to pre-allocate playback audio buffer pages */ 599 if (!spcm->pcm.playback) 600 goto capture; 601 602 caps = &spcm->pcm.caps[stream]; 603 604 if (!pcm->streams[stream].substream) { 605 spcm_err(spcm, stream, "NULL playback substream!\n"); 606 return -EINVAL; 607 } 608 609 /* pre-allocate playback audio buffer pages */ 610 spcm_dbg(spcm, stream, "allocate %s playback DMA buffer size 0x%x max 0x%x\n", 611 caps->name, caps->buffer_size_min, caps->buffer_size_max); 612 613 snd_pcm_set_managed_buffer(pcm->streams[stream].substream, 614 SNDRV_DMA_TYPE_DEV_SG, sdev->dev, 615 0, le32_to_cpu(caps->buffer_size_max)); 616 capture: 617 stream = SNDRV_PCM_STREAM_CAPTURE; 618 619 /* do we need to pre-allocate capture audio buffer pages */ 620 if (!spcm->pcm.capture) 621 return 0; 622 623 caps = &spcm->pcm.caps[stream]; 624 625 if (!pcm->streams[stream].substream) { 626 spcm_err(spcm, stream, "NULL capture substream!\n"); 627 return -EINVAL; 628 } 629 630 /* pre-allocate capture audio buffer pages */ 631 spcm_dbg(spcm, stream, "allocate %s capture DMA buffer size 0x%x max 0x%x\n", 632 caps->name, caps->buffer_size_min, caps->buffer_size_max); 633 634 snd_pcm_set_managed_buffer(pcm->streams[stream].substream, 635 SNDRV_DMA_TYPE_DEV_SG, sdev->dev, 636 0, le32_to_cpu(caps->buffer_size_max)); 637 638 return 0; 639 } 640 641 /* fixup the BE DAI link to match any values from topology */ 642 int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) 643 { 644 struct snd_interval *rate = hw_param_interval(params, 645 SNDRV_PCM_HW_PARAM_RATE); 646 struct snd_interval *channels = hw_param_interval(params, 647 SNDRV_PCM_HW_PARAM_CHANNELS); 648 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 649 struct snd_soc_component *component = 650 snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME); 651 struct snd_sof_dai *dai = 652 snd_sof_find_dai(component, (char *)rtd->dai_link->name); 653 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 654 const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm); 655 656 /* no topology exists for this BE, try a common configuration */ 657 if (!dai) { 658 dev_warn(component->dev, 659 "warning: no topology found for BE DAI %s config\n", 660 rtd->dai_link->name); 661 662 /* set 48k, stereo, 16bits by default */ 663 rate->min = 48000; 664 rate->max = 48000; 665 666 channels->min = 2; 667 channels->max = 2; 668 669 snd_mask_none(fmt); 670 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); 671 672 return 0; 673 } 674 675 if (pcm_ops && pcm_ops->dai_link_fixup) 676 return pcm_ops->dai_link_fixup(rtd, params); 677 678 return 0; 679 } 680 EXPORT_SYMBOL(sof_pcm_dai_link_fixup); 681 682 static int sof_pcm_probe(struct snd_soc_component *component) 683 { 684 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 685 struct snd_sof_pdata *plat_data = sdev->pdata; 686 const char *tplg_filename; 687 int ret; 688 689 /* 690 * make sure the device is pm_runtime_active before loading the 691 * topology and initiating IPC or bus transactions 692 */ 693 ret = pm_runtime_resume_and_get(component->dev); 694 if (ret < 0 && ret != -EACCES) 695 return ret; 696 697 /* load the default topology */ 698 sdev->component = component; 699 700 tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, 701 "%s/%s", 702 plat_data->tplg_filename_prefix, 703 plat_data->tplg_filename); 704 if (!tplg_filename) { 705 ret = -ENOMEM; 706 goto pm_error; 707 } 708 709 ret = snd_sof_load_topology(component, tplg_filename); 710 if (ret < 0) 711 dev_err(component->dev, "error: failed to load DSP topology %d\n", 712 ret); 713 714 pm_error: 715 pm_runtime_put_autosuspend(component->dev); 716 717 return ret; 718 } 719 720 static void sof_pcm_remove(struct snd_soc_component *component) 721 { 722 /* remove topology */ 723 snd_soc_tplg_component_remove(component); 724 } 725 726 static int sof_pcm_ack(struct snd_soc_component *component, 727 struct snd_pcm_substream *substream) 728 { 729 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 730 731 return snd_sof_pcm_platform_ack(sdev, substream); 732 } 733 734 static snd_pcm_sframes_t sof_pcm_delay(struct snd_soc_component *component, 735 struct snd_pcm_substream *substream) 736 { 737 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 738 const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm); 739 740 if (pcm_ops && pcm_ops->delay) 741 return pcm_ops->delay(component, substream); 742 743 return 0; 744 } 745 746 void snd_sof_new_platform_drv(struct snd_sof_dev *sdev) 747 { 748 struct snd_soc_component_driver *pd = &sdev->plat_drv; 749 struct snd_sof_pdata *plat_data = sdev->pdata; 750 const char *drv_name; 751 752 if (plat_data->machine) 753 drv_name = plat_data->machine->drv_name; 754 else if (plat_data->of_machine) 755 drv_name = plat_data->of_machine->drv_name; 756 else 757 drv_name = NULL; 758 759 pd->name = "sof-audio-component"; 760 pd->probe = sof_pcm_probe; 761 pd->remove = sof_pcm_remove; 762 pd->open = sof_pcm_open; 763 pd->close = sof_pcm_close; 764 pd->hw_params = sof_pcm_hw_params; 765 pd->prepare = sof_pcm_prepare; 766 pd->hw_free = sof_pcm_hw_free; 767 pd->trigger = sof_pcm_trigger; 768 pd->pointer = sof_pcm_pointer; 769 pd->ack = sof_pcm_ack; 770 pd->delay = sof_pcm_delay; 771 772 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS) 773 pd->compress_ops = &sof_compressed_ops; 774 #endif 775 776 pd->pcm_construct = sof_pcm_new; 777 pd->ignore_machine = drv_name; 778 pd->be_pcm_base = SOF_BE_PCM_BASE; 779 pd->use_dai_pcm_id = true; 780 pd->topology_name_prefix = "sof"; 781 782 /* increment module refcount when a pcm is opened */ 783 pd->module_get_upon_open = 1; 784 785 pd->legacy_dai_naming = 1; 786 787 /* 788 * The fixup is only needed when the DSP is in use as with the DSPless 789 * mode we are directly using the audio interface 790 */ 791 if (!sdev->dspless_mode_selected) 792 pd->be_hw_params_fixup = sof_pcm_dai_link_fixup; 793 } 794