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 hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); 220 if (!hlink) 221 return -EINVAL; 222 223 hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream); 224 if (!hext_stream) { 225 hext_stream = hda_link_stream_assign(bus, substream); 226 if (!hext_stream) 227 return -EBUSY; 228 229 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)hext_stream); 230 } 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_sof_widget *pipe_widget; 454 struct sof_ipc4_pipeline *pipeline; 455 struct snd_soc_pcm_runtime *rtd; 456 struct snd_sof_widget *swidget; 457 struct snd_soc_dapm_widget *w; 458 struct snd_soc_dai *codec_dai; 459 struct snd_soc_dai *cpu_dai; 460 int ret; 461 462 dev_dbg(dai->dev, "cmd=%d dai %s direction %d\n", cmd, 463 dai->name, substream->stream); 464 465 rtd = asoc_substream_to_rtd(substream); 466 cpu_dai = asoc_rtd_to_cpu(rtd, 0); 467 codec_dai = asoc_rtd_to_codec(rtd, 0); 468 469 w = snd_soc_dai_get_widget(dai, substream->stream); 470 swidget = w->dobj.private; 471 pipe_widget = swidget->spipe->pipe_widget; 472 pipeline = pipe_widget->private; 473 474 switch (cmd) { 475 case SNDRV_PCM_TRIGGER_START: 476 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 477 snd_hdac_ext_stream_start(hext_stream); 478 if (pipeline->state != SOF_IPC4_PIPE_PAUSED) { 479 ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 480 SOF_IPC4_PIPE_PAUSED); 481 if (ret < 0) 482 return ret; 483 pipeline->state = SOF_IPC4_PIPE_PAUSED; 484 } 485 486 ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 487 SOF_IPC4_PIPE_RUNNING); 488 if (ret < 0) 489 return ret; 490 pipeline->state = SOF_IPC4_PIPE_RUNNING; 491 break; 492 case SNDRV_PCM_TRIGGER_SUSPEND: 493 case SNDRV_PCM_TRIGGER_STOP: 494 { 495 ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 496 SOF_IPC4_PIPE_PAUSED); 497 if (ret < 0) 498 return ret; 499 500 pipeline->state = SOF_IPC4_PIPE_PAUSED; 501 502 snd_hdac_ext_stream_clear(hext_stream); 503 504 ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 505 SOF_IPC4_PIPE_RESET); 506 if (ret < 0) 507 return ret; 508 509 pipeline->state = SOF_IPC4_PIPE_RESET; 510 511 ret = hda_link_dma_cleanup(substream, hext_stream, cpu_dai, codec_dai, false); 512 if (ret < 0) { 513 dev_err(sdev->dev, "%s: failed to clean up link DMA\n", __func__); 514 return ret; 515 } 516 break; 517 } 518 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 519 { 520 ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 521 SOF_IPC4_PIPE_PAUSED); 522 if (ret < 0) 523 return ret; 524 525 pipeline->state = SOF_IPC4_PIPE_PAUSED; 526 527 snd_hdac_ext_stream_clear(hext_stream); 528 break; 529 } 530 default: 531 dev_err(sdev->dev, "%s: unknown trigger command %d\n", __func__, cmd); 532 return -EINVAL; 533 } 534 535 return 0; 536 } 537 538 static int hda_dai_hw_free(struct snd_pcm_substream *substream, 539 struct snd_soc_dai *dai) 540 { 541 int ret; 542 543 ret = hda_link_dma_hw_free(substream); 544 if (ret < 0) 545 return ret; 546 547 return hda_dai_hw_free_ipc(substream->stream, dai); 548 } 549 550 static const struct snd_soc_dai_ops ipc3_hda_dai_ops = { 551 .hw_params = hda_dai_hw_params, 552 .hw_free = hda_dai_hw_free, 553 .trigger = ipc3_hda_dai_trigger, 554 .prepare = hda_dai_prepare, 555 }; 556 557 static int hda_dai_suspend(struct hdac_bus *bus) 558 { 559 struct snd_soc_pcm_runtime *rtd; 560 struct hdac_ext_stream *hext_stream; 561 struct hdac_stream *s; 562 int ret; 563 564 /* set internal flag for BE */ 565 list_for_each_entry(s, &bus->stream_list, list) { 566 567 hext_stream = stream_to_hdac_ext_stream(s); 568 569 /* 570 * clear stream. This should already be taken care for running 571 * streams when the SUSPEND trigger is called. But paused 572 * streams do not get suspended, so this needs to be done 573 * explicitly during suspend. 574 */ 575 if (hext_stream->link_substream) { 576 struct snd_soc_dai *cpu_dai; 577 struct snd_soc_dai *codec_dai; 578 579 rtd = asoc_substream_to_rtd(hext_stream->link_substream); 580 cpu_dai = asoc_rtd_to_cpu(rtd, 0); 581 codec_dai = asoc_rtd_to_codec(rtd, 0); 582 583 ret = hda_link_dma_cleanup(hext_stream->link_substream, 584 hext_stream, 585 cpu_dai, codec_dai, false); 586 if (ret < 0) 587 return ret; 588 589 /* for consistency with TRIGGER_SUSPEND we free DAI resources */ 590 ret = hda_dai_hw_free_ipc(hdac_stream(hext_stream)->direction, cpu_dai); 591 if (ret < 0) 592 return ret; 593 } 594 } 595 596 return 0; 597 } 598 599 static const struct snd_soc_dai_ops ipc4_hda_dai_ops = { 600 .hw_params = hda_dai_hw_params, 601 .hw_free = hda_dai_hw_free, 602 .trigger = ipc4_hda_dai_trigger, 603 .prepare = hda_dai_prepare, 604 }; 605 606 #endif 607 608 /* only one flag used so far to harden hw_params/hw_free/trigger/prepare */ 609 struct ssp_dai_dma_data { 610 bool setup; 611 }; 612 613 static int ssp_dai_setup_or_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, 614 bool setup) 615 { 616 struct snd_soc_dapm_widget *w; 617 618 w = snd_soc_dai_get_widget(dai, substream->stream); 619 620 if (setup) 621 return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE, NULL); 622 623 return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE, NULL); 624 } 625 626 static int ssp_dai_startup(struct snd_pcm_substream *substream, 627 struct snd_soc_dai *dai) 628 { 629 struct ssp_dai_dma_data *dma_data; 630 631 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); 632 if (!dma_data) 633 return -ENOMEM; 634 635 snd_soc_dai_set_dma_data(dai, substream, dma_data); 636 637 return 0; 638 } 639 640 static int ssp_dai_setup(struct snd_pcm_substream *substream, 641 struct snd_soc_dai *dai, 642 bool setup) 643 { 644 struct ssp_dai_dma_data *dma_data; 645 int ret = 0; 646 647 dma_data = snd_soc_dai_get_dma_data(dai, substream); 648 if (!dma_data) { 649 dev_err(dai->dev, "%s: failed to get dma_data\n", __func__); 650 return -EIO; 651 } 652 653 if (dma_data->setup != setup) { 654 ret = ssp_dai_setup_or_free(substream, dai, setup); 655 if (!ret) 656 dma_data->setup = setup; 657 } 658 return ret; 659 } 660 661 static int ssp_dai_hw_params(struct snd_pcm_substream *substream, 662 struct snd_pcm_hw_params *params, 663 struct snd_soc_dai *dai) 664 { 665 /* params are ignored for now */ 666 return ssp_dai_setup(substream, dai, true); 667 } 668 669 static int ssp_dai_prepare(struct snd_pcm_substream *substream, 670 struct snd_soc_dai *dai) 671 { 672 /* 673 * the SSP will only be reconfigured during resume operations and 674 * not in case of xruns 675 */ 676 return ssp_dai_setup(substream, dai, true); 677 } 678 679 static int ipc3_ssp_dai_trigger(struct snd_pcm_substream *substream, 680 int cmd, struct snd_soc_dai *dai) 681 { 682 if (cmd != SNDRV_PCM_TRIGGER_SUSPEND) 683 return 0; 684 685 return ssp_dai_setup(substream, dai, false); 686 } 687 688 static int ssp_dai_hw_free(struct snd_pcm_substream *substream, 689 struct snd_soc_dai *dai) 690 { 691 return ssp_dai_setup(substream, dai, false); 692 } 693 694 static void ssp_dai_shutdown(struct snd_pcm_substream *substream, 695 struct snd_soc_dai *dai) 696 { 697 struct ssp_dai_dma_data *dma_data; 698 699 dma_data = snd_soc_dai_get_dma_data(dai, substream); 700 if (!dma_data) { 701 dev_err(dai->dev, "%s: failed to get dma_data\n", __func__); 702 return; 703 } 704 snd_soc_dai_set_dma_data(dai, substream, NULL); 705 kfree(dma_data); 706 } 707 708 static const struct snd_soc_dai_ops ipc3_ssp_dai_ops = { 709 .startup = ssp_dai_startup, 710 .hw_params = ssp_dai_hw_params, 711 .prepare = ssp_dai_prepare, 712 .trigger = ipc3_ssp_dai_trigger, 713 .hw_free = ssp_dai_hw_free, 714 .shutdown = ssp_dai_shutdown, 715 }; 716 717 void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) 718 { 719 int i; 720 721 switch (sdev->pdata->ipc_type) { 722 case SOF_IPC: 723 for (i = 0; i < ops->num_drv; i++) { 724 if (strstr(ops->drv[i].name, "SSP")) { 725 ops->drv[i].ops = &ipc3_ssp_dai_ops; 726 continue; 727 } 728 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 729 if (strstr(ops->drv[i].name, "iDisp") || 730 strstr(ops->drv[i].name, "Analog") || 731 strstr(ops->drv[i].name, "Digital")) 732 ops->drv[i].ops = &ipc3_hda_dai_ops; 733 #endif 734 } 735 break; 736 case SOF_INTEL_IPC4: 737 { 738 struct sof_ipc4_fw_data *ipc4_data = sdev->private; 739 740 for (i = 0; i < ops->num_drv; i++) { 741 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 742 if (strstr(ops->drv[i].name, "iDisp") || 743 strstr(ops->drv[i].name, "Analog") || 744 strstr(ops->drv[i].name, "Digital")) 745 ops->drv[i].ops = &ipc4_hda_dai_ops; 746 #endif 747 } 748 749 if (!hda_use_tplg_nhlt) 750 ipc4_data->nhlt = intel_nhlt_init(sdev->dev); 751 752 break; 753 } 754 default: 755 break; 756 } 757 } 758 759 void hda_ops_free(struct snd_sof_dev *sdev) 760 { 761 if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) { 762 struct sof_ipc4_fw_data *ipc4_data = sdev->private; 763 764 if (!hda_use_tplg_nhlt) 765 intel_nhlt_free(ipc4_data->nhlt); 766 } 767 } 768 EXPORT_SYMBOL_NS(hda_ops_free, SND_SOC_SOF_INTEL_HDA_COMMON); 769 770 /* 771 * common dai driver for skl+ platforms. 772 * some products who use this DAI array only physically have a subset of 773 * the DAIs, but no harm is done here by adding the whole set. 774 */ 775 struct snd_soc_dai_driver skl_dai[] = { 776 { 777 .name = "SSP0 Pin", 778 .playback = { 779 .channels_min = 1, 780 .channels_max = 8, 781 }, 782 .capture = { 783 .channels_min = 1, 784 .channels_max = 8, 785 }, 786 }, 787 { 788 .name = "SSP1 Pin", 789 .playback = { 790 .channels_min = 1, 791 .channels_max = 8, 792 }, 793 .capture = { 794 .channels_min = 1, 795 .channels_max = 8, 796 }, 797 }, 798 { 799 .name = "SSP2 Pin", 800 .playback = { 801 .channels_min = 1, 802 .channels_max = 8, 803 }, 804 .capture = { 805 .channels_min = 1, 806 .channels_max = 8, 807 }, 808 }, 809 { 810 .name = "SSP3 Pin", 811 .playback = { 812 .channels_min = 1, 813 .channels_max = 8, 814 }, 815 .capture = { 816 .channels_min = 1, 817 .channels_max = 8, 818 }, 819 }, 820 { 821 .name = "SSP4 Pin", 822 .playback = { 823 .channels_min = 1, 824 .channels_max = 8, 825 }, 826 .capture = { 827 .channels_min = 1, 828 .channels_max = 8, 829 }, 830 }, 831 { 832 .name = "SSP5 Pin", 833 .playback = { 834 .channels_min = 1, 835 .channels_max = 8, 836 }, 837 .capture = { 838 .channels_min = 1, 839 .channels_max = 8, 840 }, 841 }, 842 { 843 .name = "DMIC01 Pin", 844 .capture = { 845 .channels_min = 1, 846 .channels_max = 4, 847 }, 848 }, 849 { 850 .name = "DMIC16k Pin", 851 .capture = { 852 .channels_min = 1, 853 .channels_max = 4, 854 }, 855 }, 856 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 857 { 858 .name = "iDisp1 Pin", 859 .playback = { 860 .channels_min = 1, 861 .channels_max = 8, 862 }, 863 }, 864 { 865 .name = "iDisp2 Pin", 866 .playback = { 867 .channels_min = 1, 868 .channels_max = 8, 869 }, 870 }, 871 { 872 .name = "iDisp3 Pin", 873 .playback = { 874 .channels_min = 1, 875 .channels_max = 8, 876 }, 877 }, 878 { 879 .name = "iDisp4 Pin", 880 .playback = { 881 .channels_min = 1, 882 .channels_max = 8, 883 }, 884 }, 885 { 886 .name = "Analog CPU DAI", 887 .playback = { 888 .channels_min = 1, 889 .channels_max = 16, 890 }, 891 .capture = { 892 .channels_min = 1, 893 .channels_max = 16, 894 }, 895 }, 896 { 897 .name = "Digital CPU DAI", 898 .playback = { 899 .channels_min = 1, 900 .channels_max = 16, 901 }, 902 .capture = { 903 .channels_min = 1, 904 .channels_max = 16, 905 }, 906 }, 907 { 908 .name = "Alt Analog CPU DAI", 909 .playback = { 910 .channels_min = 1, 911 .channels_max = 16, 912 }, 913 .capture = { 914 .channels_min = 1, 915 .channels_max = 16, 916 }, 917 }, 918 #endif 919 }; 920 921 int hda_dsp_dais_suspend(struct snd_sof_dev *sdev) 922 { 923 /* 924 * In the corner case where a SUSPEND happens during a PAUSE, the ALSA core 925 * does not throw the TRIGGER_SUSPEND. This leaves the DAIs in an unbalanced state. 926 * Since the component suspend is called last, we can trap this corner case 927 * and force the DAIs to release their resources. 928 */ 929 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 930 int ret; 931 932 ret = hda_dai_suspend(sof_to_bus(sdev)); 933 if (ret < 0) 934 return ret; 935 #endif 936 937 return 0; 938 } 939