1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 // 3 // This file is provided under a dual BSD/GPLv2 license. When using or 4 // redistributing this file, you may do so under either license. 5 // 6 // Copyright(c) 2018 Intel Corporation. All rights reserved. 7 // 8 // Authors: Keyon Jie <yang.jie@linux.intel.com> 9 // 10 11 #include <sound/pcm_params.h> 12 #include <sound/hdaudio_ext.h> 13 #include <sound/intel-nhlt.h> 14 #include <sound/sof/ipc4/header.h> 15 #include <uapi/sound/sof/header.h> 16 #include "../ipc4-priv.h" 17 #include "../ipc4-topology.h" 18 #include "../sof-priv.h" 19 #include "../sof-audio.h" 20 #include "hda.h" 21 22 /* 23 * The default method is to fetch NHLT from BIOS. With this parameter set 24 * it is possible to override that with NHLT in the SOF topology manifest. 25 */ 26 static bool hda_use_tplg_nhlt; 27 module_param_named(sof_use_tplg_nhlt, hda_use_tplg_nhlt, bool, 0444); 28 MODULE_PARM_DESC(sof_use_tplg_nhlt, "SOF topology nhlt override"); 29 30 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 31 32 struct hda_pipe_params { 33 u32 ch; 34 u32 s_freq; 35 u32 s_fmt; 36 u8 linktype; 37 snd_pcm_format_t format; 38 int link_index; 39 int stream; 40 unsigned int link_bps; 41 }; 42 43 /* 44 * This function checks if the host dma channel corresponding 45 * to the link DMA stream_tag argument is assigned to one 46 * of the FEs connected to the BE DAI. 47 */ 48 static bool hda_check_fes(struct snd_soc_pcm_runtime *rtd, 49 int dir, int stream_tag) 50 { 51 struct snd_pcm_substream *fe_substream; 52 struct hdac_stream *fe_hstream; 53 struct snd_soc_dpcm *dpcm; 54 55 for_each_dpcm_fe(rtd, dir, dpcm) { 56 fe_substream = snd_soc_dpcm_get_substream(dpcm->fe, dir); 57 fe_hstream = fe_substream->runtime->private_data; 58 if (fe_hstream->stream_tag == stream_tag) 59 return true; 60 } 61 62 return false; 63 } 64 65 static struct hdac_ext_stream * 66 hda_link_stream_assign(struct hdac_bus *bus, 67 struct snd_pcm_substream *substream) 68 { 69 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 70 struct sof_intel_hda_stream *hda_stream; 71 const struct sof_intel_dsp_desc *chip; 72 struct snd_sof_dev *sdev; 73 struct hdac_ext_stream *res = NULL; 74 struct hdac_stream *hstream = NULL; 75 76 int stream_dir = substream->stream; 77 78 if (!bus->ppcap) { 79 dev_err(bus->dev, "stream type not supported\n"); 80 return NULL; 81 } 82 83 spin_lock_irq(&bus->reg_lock); 84 list_for_each_entry(hstream, &bus->stream_list, list) { 85 struct hdac_ext_stream *hext_stream = 86 stream_to_hdac_ext_stream(hstream); 87 if (hstream->direction != substream->stream) 88 continue; 89 90 hda_stream = hstream_to_sof_hda_stream(hext_stream); 91 sdev = hda_stream->sdev; 92 chip = get_chip_info(sdev->pdata); 93 94 /* check if link is available */ 95 if (!hext_stream->link_locked) { 96 /* 97 * choose the first available link for platforms that do not have the 98 * PROCEN_FMT_QUIRK set. 99 */ 100 if (!(chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK)) { 101 res = hext_stream; 102 break; 103 } 104 105 if (hstream->opened) { 106 /* 107 * check if the stream tag matches the stream 108 * tag of one of the connected FEs 109 */ 110 if (hda_check_fes(rtd, stream_dir, 111 hstream->stream_tag)) { 112 res = hext_stream; 113 break; 114 } 115 } else { 116 res = hext_stream; 117 118 /* 119 * This must be a hostless stream. 120 * So reserve the host DMA channel. 121 */ 122 hda_stream->host_reserved = 1; 123 break; 124 } 125 } 126 } 127 128 if (res) { 129 /* Make sure that host and link DMA is decoupled. */ 130 snd_hdac_ext_stream_decouple_locked(bus, res, true); 131 132 res->link_locked = 1; 133 res->link_substream = substream; 134 } 135 spin_unlock_irq(&bus->reg_lock); 136 137 return res; 138 } 139 140 static int hda_link_dma_cleanup(struct snd_pcm_substream *substream, 141 struct hdac_stream *hstream, 142 struct snd_soc_dai *cpu_dai, 143 struct snd_soc_dai *codec_dai, 144 bool trigger_suspend_stop) 145 { 146 struct hdac_ext_stream *hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream); 147 struct hdac_bus *bus = hstream->bus; 148 struct sof_intel_hda_stream *hda_stream; 149 struct hdac_ext_link *link; 150 int stream_tag; 151 152 link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); 153 if (!link) 154 return -EINVAL; 155 156 if (trigger_suspend_stop) 157 snd_hdac_ext_link_stream_clear(hext_stream); 158 159 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 160 stream_tag = hdac_stream(hext_stream)->stream_tag; 161 snd_hdac_ext_link_clear_stream_id(link, stream_tag); 162 } 163 snd_soc_dai_set_dma_data(cpu_dai, substream, NULL); 164 snd_hdac_ext_stream_release(hext_stream, HDAC_EXT_STREAM_TYPE_LINK); 165 hext_stream->link_prepared = 0; 166 167 /* free the host DMA channel reserved by hostless streams */ 168 hda_stream = hstream_to_sof_hda_stream(hext_stream); 169 hda_stream->host_reserved = 0; 170 171 return 0; 172 } 173 174 static int hda_link_dma_params(struct hdac_ext_stream *hext_stream, 175 struct hda_pipe_params *params) 176 { 177 struct hdac_stream *hstream = &hext_stream->hstream; 178 unsigned char stream_tag = hstream->stream_tag; 179 struct hdac_bus *bus = hstream->bus; 180 struct hdac_ext_link *link; 181 unsigned int format_val; 182 183 snd_hdac_ext_link_stream_reset(hext_stream); 184 185 format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch, 186 params->format, 187 params->link_bps, 0); 188 189 dev_dbg(bus->dev, "format_val=%d, rate=%d, ch=%d, format=%d\n", 190 format_val, params->s_freq, params->ch, params->format); 191 192 snd_hdac_ext_link_stream_setup(hext_stream, format_val); 193 194 if (hext_stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { 195 list_for_each_entry(link, &bus->hlink_list, list) { 196 if (link->index == params->link_index) 197 snd_hdac_ext_link_set_stream_id(link, 198 stream_tag); 199 } 200 } 201 202 hext_stream->link_prepared = 1; 203 204 return 0; 205 } 206 207 static int hda_link_dma_hw_params(struct snd_pcm_substream *substream, 208 struct snd_pcm_hw_params *params) 209 { 210 struct hdac_stream *hstream = substream->runtime->private_data; 211 struct hdac_ext_stream *hext_stream; 212 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 213 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 214 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 215 struct hda_pipe_params p_params = {0}; 216 struct hdac_bus *bus = hstream->bus; 217 struct hdac_ext_link *link; 218 219 hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream); 220 if (!hext_stream) { 221 hext_stream = hda_link_stream_assign(bus, substream); 222 if (!hext_stream) 223 return -EBUSY; 224 225 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)hext_stream); 226 } 227 228 link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); 229 if (!link) 230 return -EINVAL; 231 232 /* set the hdac_stream in the codec dai */ 233 snd_soc_dai_set_stream(codec_dai, hdac_stream(hext_stream), substream->stream); 234 235 p_params.s_fmt = snd_pcm_format_width(params_format(params)); 236 p_params.ch = params_channels(params); 237 p_params.s_freq = params_rate(params); 238 p_params.stream = substream->stream; 239 p_params.link_index = link->index; 240 p_params.format = params_format(params); 241 242 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 243 p_params.link_bps = codec_dai->driver->playback.sig_bits; 244 else 245 p_params.link_bps = codec_dai->driver->capture.sig_bits; 246 247 return hda_link_dma_params(hext_stream, &p_params); 248 } 249 250 static int hda_link_dma_prepare(struct snd_pcm_substream *substream) 251 { 252 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 253 int stream = substream->stream; 254 255 return hda_link_dma_hw_params(substream, &rtd->dpcm[stream].hw_params); 256 } 257 258 static int hda_link_dma_trigger(struct snd_pcm_substream *substream, int cmd) 259 { 260 struct hdac_stream *hstream = substream->runtime->private_data; 261 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 262 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 263 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 264 struct hdac_ext_stream *hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream); 265 int ret; 266 267 if (!hext_stream) 268 return 0; 269 270 switch (cmd) { 271 case SNDRV_PCM_TRIGGER_START: 272 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 273 snd_hdac_ext_link_stream_start(hext_stream); 274 break; 275 case SNDRV_PCM_TRIGGER_SUSPEND: 276 case SNDRV_PCM_TRIGGER_STOP: 277 ret = hda_link_dma_cleanup(substream, hstream, cpu_dai, codec_dai, true); 278 if (ret < 0) 279 return ret; 280 281 break; 282 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 283 snd_hdac_ext_link_stream_clear(hext_stream); 284 285 break; 286 default: 287 return -EINVAL; 288 } 289 return 0; 290 } 291 292 static int hda_link_dma_hw_free(struct snd_pcm_substream *substream) 293 { 294 struct hdac_stream *hstream = substream->runtime->private_data; 295 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 296 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 297 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 298 struct hdac_ext_stream *hext_stream; 299 300 hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream); 301 if (!hext_stream) 302 return 0; 303 304 return hda_link_dma_cleanup(substream, hstream, cpu_dai, codec_dai, false); 305 } 306 307 static int hda_dai_widget_update(struct snd_soc_dapm_widget *w, 308 int channel, bool widget_setup) 309 { 310 struct snd_sof_dai_config_data data; 311 312 data.dai_data = channel; 313 314 /* set up/free DAI widget and send DAI_CONFIG IPC */ 315 if (widget_setup) 316 return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_2_STEP_STOP, &data); 317 318 return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE, &data); 319 } 320 321 static int hda_dai_hw_params_update(struct snd_pcm_substream *substream, 322 struct snd_pcm_hw_params *params, 323 struct snd_soc_dai *dai) 324 { 325 struct hdac_ext_stream *hext_stream; 326 struct snd_soc_dapm_widget *w; 327 int stream_tag; 328 329 hext_stream = snd_soc_dai_get_dma_data(dai, substream); 330 if (!hext_stream) 331 return -EINVAL; 332 333 stream_tag = hdac_stream(hext_stream)->stream_tag; 334 335 w = snd_soc_dai_get_widget(dai, substream->stream); 336 337 /* set up the DAI widget and send the DAI_CONFIG with the new tag */ 338 return hda_dai_widget_update(w, stream_tag - 1, true); 339 } 340 341 static int hda_dai_hw_params(struct snd_pcm_substream *substream, 342 struct snd_pcm_hw_params *params, 343 struct snd_soc_dai *dai) 344 { 345 struct hdac_ext_stream *hext_stream = 346 snd_soc_dai_get_dma_data(dai, substream); 347 int ret; 348 349 if (hext_stream && hext_stream->link_prepared) 350 return 0; 351 352 ret = hda_link_dma_hw_params(substream, params); 353 if (ret < 0) 354 return ret; 355 356 return hda_dai_hw_params_update(substream, params, dai); 357 } 358 359 360 static int hda_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w) 361 { 362 struct snd_sof_widget *swidget = w->dobj.private; 363 struct snd_soc_component *component = swidget->scomp; 364 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 365 const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; 366 int ret = 0; 367 368 if (tplg_ops->dai_config) { 369 ret = tplg_ops->dai_config(sdev, swidget, SOF_DAI_CONFIG_FLAGS_PAUSE, NULL); 370 if (ret < 0) 371 dev_err(sdev->dev, "%s: DAI config failed for widget %s\n", __func__, 372 w->name); 373 } 374 375 return ret; 376 } 377 378 static int hda_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) 379 { 380 struct hdac_ext_stream *hext_stream = 381 snd_soc_dai_get_dma_data(dai, substream); 382 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); 383 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 384 int stream = substream->stream; 385 int ret; 386 387 if (hext_stream && hext_stream->link_prepared) 388 return 0; 389 390 dev_dbg(sdev->dev, "prepare stream dir %d\n", substream->stream); 391 392 ret = hda_link_dma_prepare(substream); 393 if (ret < 0) 394 return ret; 395 396 return hda_dai_hw_params_update(substream, &rtd->dpcm[stream].hw_params, dai); 397 } 398 399 static int hda_dai_hw_free_ipc(int stream, /* direction */ 400 struct snd_soc_dai *dai) 401 { 402 struct snd_soc_dapm_widget *w; 403 404 w = snd_soc_dai_get_widget(dai, stream); 405 406 /* free the link DMA channel in the FW and the DAI widget */ 407 return hda_dai_widget_update(w, DMA_CHAN_INVALID, false); 408 } 409 410 static int ipc3_hda_dai_trigger(struct snd_pcm_substream *substream, 411 int cmd, struct snd_soc_dai *dai) 412 { 413 struct snd_soc_dapm_widget *w; 414 int ret; 415 416 dev_dbg(dai->dev, "cmd=%d dai %s direction %d\n", cmd, 417 dai->name, substream->stream); 418 419 ret = hda_link_dma_trigger(substream, cmd); 420 if (ret < 0) 421 return ret; 422 423 w = snd_soc_dai_get_widget(dai, substream->stream); 424 425 switch (cmd) { 426 case SNDRV_PCM_TRIGGER_SUSPEND: 427 case SNDRV_PCM_TRIGGER_STOP: 428 /* 429 * free DAI widget during stop/suspend to keep widget use_count's balanced. 430 */ 431 ret = hda_dai_hw_free_ipc(substream->stream, dai); 432 if (ret < 0) 433 return ret; 434 435 break; 436 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 437 ret = hda_dai_config_pause_push_ipc(w); 438 if (ret < 0) 439 return ret; 440 break; 441 442 default: 443 break; 444 } 445 return 0; 446 } 447 448 /* 449 * In contrast to IPC3, the dai trigger in IPC4 mixes pipeline state changes 450 * (over IPC channel) and DMA state change (direct host register changes). 451 */ 452 static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, 453 int cmd, struct snd_soc_dai *dai) 454 { 455 struct hdac_ext_stream *hext_stream = snd_soc_dai_get_dma_data(dai, substream); 456 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); 457 struct snd_soc_pcm_runtime *rtd; 458 struct snd_sof_widget *swidget; 459 struct snd_soc_dapm_widget *w; 460 struct snd_soc_dai *codec_dai; 461 struct hdac_stream *hstream; 462 struct snd_soc_dai *cpu_dai; 463 int ret; 464 465 dev_dbg(dai->dev, "cmd=%d dai %s direction %d\n", cmd, 466 dai->name, substream->stream); 467 468 hstream = substream->runtime->private_data; 469 rtd = asoc_substream_to_rtd(substream); 470 cpu_dai = asoc_rtd_to_cpu(rtd, 0); 471 codec_dai = asoc_rtd_to_codec(rtd, 0); 472 473 w = snd_soc_dai_get_widget(dai, substream->stream); 474 swidget = w->dobj.private; 475 476 switch (cmd) { 477 case SNDRV_PCM_TRIGGER_START: 478 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 479 snd_hdac_ext_link_stream_start(hext_stream); 480 break; 481 case SNDRV_PCM_TRIGGER_SUSPEND: 482 case SNDRV_PCM_TRIGGER_STOP: 483 { 484 struct snd_sof_widget *pipe_widget = swidget->pipe_widget; 485 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 486 487 ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, 488 SOF_IPC4_PIPE_PAUSED); 489 if (ret < 0) 490 return ret; 491 492 pipeline->state = SOF_IPC4_PIPE_PAUSED; 493 494 snd_hdac_ext_link_stream_clear(hext_stream); 495 496 ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, 497 SOF_IPC4_PIPE_RESET); 498 if (ret < 0) 499 return ret; 500 501 pipeline->state = SOF_IPC4_PIPE_RESET; 502 503 ret = hda_link_dma_cleanup(substream, hstream, cpu_dai, codec_dai, false); 504 if (ret < 0) { 505 dev_err(sdev->dev, "%s: failed to clean up link DMA\n", __func__); 506 return ret; 507 } 508 break; 509 } 510 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 511 { 512 struct snd_sof_widget *pipe_widget = swidget->pipe_widget; 513 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 514 515 ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, 516 SOF_IPC4_PIPE_PAUSED); 517 if (ret < 0) 518 return ret; 519 520 pipeline->state = SOF_IPC4_PIPE_PAUSED; 521 522 snd_hdac_ext_link_stream_clear(hext_stream); 523 break; 524 } 525 default: 526 dev_err(sdev->dev, "%s: unknown trigger command %d\n", __func__, cmd); 527 return -EINVAL; 528 } 529 530 return 0; 531 } 532 533 static int hda_dai_hw_free(struct snd_pcm_substream *substream, 534 struct snd_soc_dai *dai) 535 { 536 int ret; 537 538 ret = hda_link_dma_hw_free(substream); 539 if (ret < 0) 540 return ret; 541 542 return hda_dai_hw_free_ipc(substream->stream, dai); 543 } 544 545 static const struct snd_soc_dai_ops ipc3_hda_dai_ops = { 546 .hw_params = hda_dai_hw_params, 547 .hw_free = hda_dai_hw_free, 548 .trigger = ipc3_hda_dai_trigger, 549 .prepare = hda_dai_prepare, 550 }; 551 552 static int hda_dai_suspend(struct hdac_bus *bus) 553 { 554 struct snd_soc_pcm_runtime *rtd; 555 struct hdac_ext_stream *hext_stream; 556 struct hdac_stream *s; 557 int ret; 558 559 /* set internal flag for BE */ 560 list_for_each_entry(s, &bus->stream_list, list) { 561 562 hext_stream = stream_to_hdac_ext_stream(s); 563 564 /* 565 * clear stream. This should already be taken care for running 566 * streams when the SUSPEND trigger is called. But paused 567 * streams do not get suspended, so this needs to be done 568 * explicitly during suspend. 569 */ 570 if (hext_stream->link_substream) { 571 struct snd_soc_dai *cpu_dai; 572 struct snd_soc_dai *codec_dai; 573 574 rtd = asoc_substream_to_rtd(hext_stream->link_substream); 575 cpu_dai = asoc_rtd_to_cpu(rtd, 0); 576 codec_dai = asoc_rtd_to_codec(rtd, 0); 577 578 ret = hda_link_dma_cleanup(hext_stream->link_substream, s, 579 cpu_dai, codec_dai, false); 580 if (ret < 0) 581 return ret; 582 583 /* for consistency with TRIGGER_SUSPEND we free DAI resources */ 584 ret = hda_dai_hw_free_ipc(hdac_stream(hext_stream)->direction, cpu_dai); 585 if (ret < 0) 586 return ret; 587 } 588 } 589 590 return 0; 591 } 592 593 static const struct snd_soc_dai_ops ipc4_hda_dai_ops = { 594 .hw_params = hda_dai_hw_params, 595 .hw_free = hda_dai_hw_free, 596 .trigger = ipc4_hda_dai_trigger, 597 .prepare = hda_dai_prepare, 598 }; 599 600 #endif 601 602 /* only one flag used so far to harden hw_params/hw_free/trigger/prepare */ 603 struct ssp_dai_dma_data { 604 bool setup; 605 }; 606 607 static int ssp_dai_setup_or_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, 608 bool setup) 609 { 610 struct snd_soc_dapm_widget *w; 611 612 w = snd_soc_dai_get_widget(dai, substream->stream); 613 614 if (setup) 615 return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE, NULL); 616 617 return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE, NULL); 618 } 619 620 static int ssp_dai_startup(struct snd_pcm_substream *substream, 621 struct snd_soc_dai *dai) 622 { 623 struct ssp_dai_dma_data *dma_data; 624 625 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); 626 if (!dma_data) 627 return -ENOMEM; 628 629 snd_soc_dai_set_dma_data(dai, substream, dma_data); 630 631 return 0; 632 } 633 634 static int ssp_dai_setup(struct snd_pcm_substream *substream, 635 struct snd_soc_dai *dai, 636 bool setup) 637 { 638 struct ssp_dai_dma_data *dma_data; 639 int ret = 0; 640 641 dma_data = snd_soc_dai_get_dma_data(dai, substream); 642 if (!dma_data) { 643 dev_err(dai->dev, "%s: failed to get dma_data\n", __func__); 644 return -EIO; 645 } 646 647 if (dma_data->setup != setup) { 648 ret = ssp_dai_setup_or_free(substream, dai, setup); 649 if (!ret) 650 dma_data->setup = setup; 651 } 652 return ret; 653 } 654 655 static int ssp_dai_hw_params(struct snd_pcm_substream *substream, 656 struct snd_pcm_hw_params *params, 657 struct snd_soc_dai *dai) 658 { 659 /* params are ignored for now */ 660 return ssp_dai_setup(substream, dai, true); 661 } 662 663 static int ssp_dai_prepare(struct snd_pcm_substream *substream, 664 struct snd_soc_dai *dai) 665 { 666 /* 667 * the SSP will only be reconfigured during resume operations and 668 * not in case of xruns 669 */ 670 return ssp_dai_setup(substream, dai, true); 671 } 672 673 static int ipc3_ssp_dai_trigger(struct snd_pcm_substream *substream, 674 int cmd, struct snd_soc_dai *dai) 675 { 676 if (cmd != SNDRV_PCM_TRIGGER_SUSPEND) 677 return 0; 678 679 return ssp_dai_setup(substream, dai, false); 680 } 681 682 static int ssp_dai_hw_free(struct snd_pcm_substream *substream, 683 struct snd_soc_dai *dai) 684 { 685 return ssp_dai_setup(substream, dai, false); 686 } 687 688 static void ssp_dai_shutdown(struct snd_pcm_substream *substream, 689 struct snd_soc_dai *dai) 690 { 691 struct ssp_dai_dma_data *dma_data; 692 693 dma_data = snd_soc_dai_get_dma_data(dai, substream); 694 if (!dma_data) { 695 dev_err(dai->dev, "%s: failed to get dma_data\n", __func__); 696 return; 697 } 698 snd_soc_dai_set_dma_data(dai, substream, NULL); 699 kfree(dma_data); 700 } 701 702 static const struct snd_soc_dai_ops ipc3_ssp_dai_ops = { 703 .startup = ssp_dai_startup, 704 .hw_params = ssp_dai_hw_params, 705 .prepare = ssp_dai_prepare, 706 .trigger = ipc3_ssp_dai_trigger, 707 .hw_free = ssp_dai_hw_free, 708 .shutdown = ssp_dai_shutdown, 709 }; 710 711 static int ipc4_be_dai_common_trigger(struct snd_soc_dai *dai, int cmd, int stream) 712 { 713 struct snd_sof_widget *pipe_widget; 714 struct sof_ipc4_pipeline *pipeline; 715 struct snd_sof_widget *swidget; 716 struct snd_soc_dapm_widget *w; 717 struct snd_sof_dev *sdev; 718 int ret; 719 720 w = snd_soc_dai_get_widget(dai, stream); 721 swidget = w->dobj.private; 722 pipe_widget = swidget->pipe_widget; 723 pipeline = pipe_widget->private; 724 sdev = snd_soc_component_get_drvdata(swidget->scomp); 725 726 switch (cmd) { 727 case SNDRV_PCM_TRIGGER_SUSPEND: 728 case SNDRV_PCM_TRIGGER_STOP: 729 ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, 730 SOF_IPC4_PIPE_PAUSED); 731 if (ret < 0) 732 return ret; 733 pipeline->state = SOF_IPC4_PIPE_PAUSED; 734 735 ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, 736 SOF_IPC4_PIPE_RESET); 737 if (ret < 0) 738 return ret; 739 pipeline->state = SOF_IPC4_PIPE_RESET; 740 break; 741 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 742 ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, 743 SOF_IPC4_PIPE_PAUSED); 744 if (ret < 0) 745 return ret; 746 pipeline->state = SOF_IPC4_PIPE_PAUSED; 747 break; 748 default: 749 break; 750 } 751 752 return 0; 753 } 754 755 static int ipc4_be_dai_trigger(struct snd_pcm_substream *substream, 756 int cmd, struct snd_soc_dai *dai) 757 { 758 return ipc4_be_dai_common_trigger(dai, cmd, substream->stream); 759 } 760 761 static const struct snd_soc_dai_ops ipc4_dmic_dai_ops = { 762 .trigger = ipc4_be_dai_trigger, 763 }; 764 765 static const struct snd_soc_dai_ops ipc4_ssp_dai_ops = { 766 .trigger = ipc4_be_dai_trigger, 767 }; 768 769 void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) 770 { 771 int i; 772 773 switch (sdev->pdata->ipc_type) { 774 case SOF_IPC: 775 for (i = 0; i < ops->num_drv; i++) { 776 if (strstr(ops->drv[i].name, "SSP")) { 777 ops->drv[i].ops = &ipc3_ssp_dai_ops; 778 continue; 779 } 780 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 781 if (strstr(ops->drv[i].name, "iDisp") || 782 strstr(ops->drv[i].name, "Analog") || 783 strstr(ops->drv[i].name, "Digital")) 784 ops->drv[i].ops = &ipc3_hda_dai_ops; 785 #endif 786 } 787 break; 788 case SOF_INTEL_IPC4: 789 { 790 struct sof_ipc4_fw_data *ipc4_data = sdev->private; 791 792 for (i = 0; i < ops->num_drv; i++) { 793 if (strstr(ops->drv[i].name, "DMIC")) { 794 ops->drv[i].ops = &ipc4_dmic_dai_ops; 795 continue; 796 } 797 if (strstr(ops->drv[i].name, "SSP")) { 798 ops->drv[i].ops = &ipc4_ssp_dai_ops; 799 continue; 800 } 801 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 802 if (strstr(ops->drv[i].name, "iDisp") || 803 strstr(ops->drv[i].name, "Analog") || 804 strstr(ops->drv[i].name, "Digital")) 805 ops->drv[i].ops = &ipc4_hda_dai_ops; 806 #endif 807 } 808 809 if (!hda_use_tplg_nhlt) 810 ipc4_data->nhlt = intel_nhlt_init(sdev->dev); 811 812 if (IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)) 813 sdw_callback.trigger = ipc4_be_dai_common_trigger; 814 815 break; 816 } 817 default: 818 break; 819 } 820 } 821 822 void hda_ops_free(struct snd_sof_dev *sdev) 823 { 824 if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) { 825 struct sof_ipc4_fw_data *ipc4_data = sdev->private; 826 827 if (!hda_use_tplg_nhlt) 828 intel_nhlt_free(ipc4_data->nhlt); 829 } 830 } 831 EXPORT_SYMBOL_NS(hda_ops_free, SND_SOC_SOF_INTEL_HDA_COMMON); 832 833 /* 834 * common dai driver for skl+ platforms. 835 * some products who use this DAI array only physically have a subset of 836 * the DAIs, but no harm is done here by adding the whole set. 837 */ 838 struct snd_soc_dai_driver skl_dai[] = { 839 { 840 .name = "SSP0 Pin", 841 .playback = { 842 .channels_min = 1, 843 .channels_max = 8, 844 }, 845 .capture = { 846 .channels_min = 1, 847 .channels_max = 8, 848 }, 849 }, 850 { 851 .name = "SSP1 Pin", 852 .playback = { 853 .channels_min = 1, 854 .channels_max = 8, 855 }, 856 .capture = { 857 .channels_min = 1, 858 .channels_max = 8, 859 }, 860 }, 861 { 862 .name = "SSP2 Pin", 863 .playback = { 864 .channels_min = 1, 865 .channels_max = 8, 866 }, 867 .capture = { 868 .channels_min = 1, 869 .channels_max = 8, 870 }, 871 }, 872 { 873 .name = "SSP3 Pin", 874 .playback = { 875 .channels_min = 1, 876 .channels_max = 8, 877 }, 878 .capture = { 879 .channels_min = 1, 880 .channels_max = 8, 881 }, 882 }, 883 { 884 .name = "SSP4 Pin", 885 .playback = { 886 .channels_min = 1, 887 .channels_max = 8, 888 }, 889 .capture = { 890 .channels_min = 1, 891 .channels_max = 8, 892 }, 893 }, 894 { 895 .name = "SSP5 Pin", 896 .playback = { 897 .channels_min = 1, 898 .channels_max = 8, 899 }, 900 .capture = { 901 .channels_min = 1, 902 .channels_max = 8, 903 }, 904 }, 905 { 906 .name = "DMIC01 Pin", 907 .capture = { 908 .channels_min = 1, 909 .channels_max = 4, 910 }, 911 }, 912 { 913 .name = "DMIC16k Pin", 914 .capture = { 915 .channels_min = 1, 916 .channels_max = 4, 917 }, 918 }, 919 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 920 { 921 .name = "iDisp1 Pin", 922 .playback = { 923 .channels_min = 1, 924 .channels_max = 8, 925 }, 926 }, 927 { 928 .name = "iDisp2 Pin", 929 .playback = { 930 .channels_min = 1, 931 .channels_max = 8, 932 }, 933 }, 934 { 935 .name = "iDisp3 Pin", 936 .playback = { 937 .channels_min = 1, 938 .channels_max = 8, 939 }, 940 }, 941 { 942 .name = "iDisp4 Pin", 943 .playback = { 944 .channels_min = 1, 945 .channels_max = 8, 946 }, 947 }, 948 { 949 .name = "Analog CPU DAI", 950 .playback = { 951 .channels_min = 1, 952 .channels_max = 16, 953 }, 954 .capture = { 955 .channels_min = 1, 956 .channels_max = 16, 957 }, 958 }, 959 { 960 .name = "Digital CPU DAI", 961 .playback = { 962 .channels_min = 1, 963 .channels_max = 16, 964 }, 965 .capture = { 966 .channels_min = 1, 967 .channels_max = 16, 968 }, 969 }, 970 { 971 .name = "Alt Analog CPU DAI", 972 .playback = { 973 .channels_min = 1, 974 .channels_max = 16, 975 }, 976 .capture = { 977 .channels_min = 1, 978 .channels_max = 16, 979 }, 980 }, 981 #endif 982 }; 983 984 int hda_dsp_dais_suspend(struct snd_sof_dev *sdev) 985 { 986 /* 987 * In the corner case where a SUSPEND happens during a PAUSE, the ALSA core 988 * does not throw the TRIGGER_SUSPEND. This leaves the DAIs in an unbalanced state. 989 * Since the component suspend is called last, we can trap this corner case 990 * and force the DAIs to release their resources. 991 */ 992 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 993 int ret; 994 995 ret = hda_dai_suspend(sof_to_bus(sdev)); 996 if (ret < 0) 997 return ret; 998 #endif 999 1000 return 0; 1001 } 1002