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