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