1 /* 2 * skl-pcm.c -ASoC HDA Platform driver file implementing PCM functionality 3 * 4 * Copyright (C) 2014-2015 Intel Corp 5 * Author: Jeeja KP <jeeja.kp@intel.com> 6 * 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; version 2 of the License. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 19 * 20 */ 21 22 #include <linux/pci.h> 23 #include <linux/pm_runtime.h> 24 #include <sound/pcm_params.h> 25 #include <sound/soc.h> 26 #include "skl.h" 27 #include "skl-topology.h" 28 #include "skl-sst-dsp.h" 29 #include "skl-sst-ipc.h" 30 31 #define HDA_MONO 1 32 #define HDA_STEREO 2 33 #define HDA_QUAD 4 34 35 static struct snd_pcm_hardware azx_pcm_hw = { 36 .info = (SNDRV_PCM_INFO_MMAP | 37 SNDRV_PCM_INFO_INTERLEAVED | 38 SNDRV_PCM_INFO_BLOCK_TRANSFER | 39 SNDRV_PCM_INFO_MMAP_VALID | 40 SNDRV_PCM_INFO_PAUSE | 41 SNDRV_PCM_INFO_RESUME | 42 SNDRV_PCM_INFO_SYNC_START | 43 SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */ 44 SNDRV_PCM_INFO_HAS_LINK_ATIME | 45 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP), 46 .formats = SNDRV_PCM_FMTBIT_S16_LE | 47 SNDRV_PCM_FMTBIT_S32_LE | 48 SNDRV_PCM_FMTBIT_S24_LE, 49 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | 50 SNDRV_PCM_RATE_8000, 51 .rate_min = 8000, 52 .rate_max = 48000, 53 .channels_min = 1, 54 .channels_max = 8, 55 .buffer_bytes_max = AZX_MAX_BUF_SIZE, 56 .period_bytes_min = 128, 57 .period_bytes_max = AZX_MAX_BUF_SIZE / 2, 58 .periods_min = 2, 59 .periods_max = AZX_MAX_FRAG, 60 .fifo_size = 0, 61 }; 62 63 static inline 64 struct hdac_ext_stream *get_hdac_ext_stream(struct snd_pcm_substream *substream) 65 { 66 return substream->runtime->private_data; 67 } 68 69 static struct hdac_ext_bus *get_bus_ctx(struct snd_pcm_substream *substream) 70 { 71 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 72 struct hdac_stream *hstream = hdac_stream(stream); 73 struct hdac_bus *bus = hstream->bus; 74 75 return hbus_to_ebus(bus); 76 } 77 78 static int skl_substream_alloc_pages(struct hdac_ext_bus *ebus, 79 struct snd_pcm_substream *substream, 80 size_t size) 81 { 82 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 83 84 hdac_stream(stream)->bufsize = 0; 85 hdac_stream(stream)->period_bytes = 0; 86 hdac_stream(stream)->format_val = 0; 87 88 return snd_pcm_lib_malloc_pages(substream, size); 89 } 90 91 static int skl_substream_free_pages(struct hdac_bus *bus, 92 struct snd_pcm_substream *substream) 93 { 94 return snd_pcm_lib_free_pages(substream); 95 } 96 97 static void skl_set_pcm_constrains(struct hdac_ext_bus *ebus, 98 struct snd_pcm_runtime *runtime) 99 { 100 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 101 102 /* avoid wrap-around with wall-clock */ 103 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 104 20, 178000000); 105 } 106 107 static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus) 108 { 109 if (ebus->ppcap) 110 return HDAC_EXT_STREAM_TYPE_HOST; 111 else 112 return HDAC_EXT_STREAM_TYPE_COUPLED; 113 } 114 115 /* 116 * check if the stream opened is marked as ignore_suspend by machine, if so 117 * then enable suspend_active refcount 118 * 119 * The count supend_active does not need lock as it is used in open/close 120 * and suspend context 121 */ 122 static void skl_set_suspend_active(struct snd_pcm_substream *substream, 123 struct snd_soc_dai *dai, bool enable) 124 { 125 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 126 struct snd_soc_dapm_widget *w; 127 struct skl *skl = ebus_to_skl(ebus); 128 129 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 130 w = dai->playback_widget; 131 else 132 w = dai->capture_widget; 133 134 if (w->ignore_suspend && enable) 135 skl->supend_active++; 136 else if (w->ignore_suspend && !enable) 137 skl->supend_active--; 138 } 139 140 static int skl_pcm_open(struct snd_pcm_substream *substream, 141 struct snd_soc_dai *dai) 142 { 143 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 144 struct hdac_ext_stream *stream; 145 struct snd_pcm_runtime *runtime = substream->runtime; 146 struct skl_dma_params *dma_params; 147 148 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 149 150 stream = snd_hdac_ext_stream_assign(ebus, substream, 151 skl_get_host_stream_type(ebus)); 152 if (stream == NULL) 153 return -EBUSY; 154 155 skl_set_pcm_constrains(ebus, runtime); 156 157 /* 158 * disable WALLCLOCK timestamps for capture streams 159 * until we figure out how to handle digital inputs 160 */ 161 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 162 runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */ 163 runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME; 164 } 165 166 runtime->private_data = stream; 167 168 dma_params = kzalloc(sizeof(*dma_params), GFP_KERNEL); 169 if (!dma_params) 170 return -ENOMEM; 171 172 dma_params->stream_tag = hdac_stream(stream)->stream_tag; 173 snd_soc_dai_set_dma_data(dai, substream, dma_params); 174 175 dev_dbg(dai->dev, "stream tag set in dma params=%d\n", 176 dma_params->stream_tag); 177 skl_set_suspend_active(substream, dai, true); 178 snd_pcm_set_sync(substream); 179 180 return 0; 181 } 182 183 static int skl_get_format(struct snd_pcm_substream *substream, 184 struct snd_soc_dai *dai) 185 { 186 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 187 struct skl_dma_params *dma_params; 188 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 189 int format_val = 0; 190 191 if (ebus->ppcap) { 192 struct snd_pcm_runtime *runtime = substream->runtime; 193 194 format_val = snd_hdac_calc_stream_format(runtime->rate, 195 runtime->channels, 196 runtime->format, 197 32, 0); 198 } else { 199 struct snd_soc_dai *codec_dai = rtd->codec_dai; 200 201 dma_params = snd_soc_dai_get_dma_data(codec_dai, substream); 202 if (dma_params) 203 format_val = dma_params->format; 204 } 205 206 return format_val; 207 } 208 209 static int skl_be_prepare(struct snd_pcm_substream *substream, 210 struct snd_soc_dai *dai) 211 { 212 struct skl *skl = get_skl_ctx(dai->dev); 213 struct skl_sst *ctx = skl->skl_sst; 214 struct skl_module_cfg *mconfig; 215 216 if (dai->playback_widget->power || dai->capture_widget->power) 217 return 0; 218 219 mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream); 220 if (mconfig == NULL) 221 return -EINVAL; 222 223 return skl_dsp_set_dma_control(ctx, mconfig); 224 } 225 226 static int skl_pcm_prepare(struct snd_pcm_substream *substream, 227 struct snd_soc_dai *dai) 228 { 229 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 230 unsigned int format_val; 231 int err; 232 233 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 234 235 format_val = skl_get_format(substream, dai); 236 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d\n", 237 hdac_stream(stream)->stream_tag, format_val); 238 snd_hdac_stream_reset(hdac_stream(stream)); 239 240 err = snd_hdac_stream_set_params(hdac_stream(stream), format_val); 241 if (err < 0) 242 return err; 243 244 err = snd_hdac_stream_setup(hdac_stream(stream)); 245 if (err < 0) 246 return err; 247 248 hdac_stream(stream)->prepared = 1; 249 250 return err; 251 } 252 253 static int skl_pcm_hw_params(struct snd_pcm_substream *substream, 254 struct snd_pcm_hw_params *params, 255 struct snd_soc_dai *dai) 256 { 257 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 258 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 259 struct snd_pcm_runtime *runtime = substream->runtime; 260 struct skl_pipe_params p_params = {0}; 261 struct skl_module_cfg *m_cfg; 262 int ret, dma_id; 263 264 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 265 ret = skl_substream_alloc_pages(ebus, substream, 266 params_buffer_bytes(params)); 267 if (ret < 0) 268 return ret; 269 270 dev_dbg(dai->dev, "format_val, rate=%d, ch=%d, format=%d\n", 271 runtime->rate, runtime->channels, runtime->format); 272 273 dma_id = hdac_stream(stream)->stream_tag - 1; 274 dev_dbg(dai->dev, "dma_id=%d\n", dma_id); 275 276 p_params.s_fmt = snd_pcm_format_width(params_format(params)); 277 p_params.ch = params_channels(params); 278 p_params.s_freq = params_rate(params); 279 p_params.host_dma_id = dma_id; 280 p_params.stream = substream->stream; 281 282 m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream); 283 if (m_cfg) 284 skl_tplg_update_pipe_params(dai->dev, m_cfg, &p_params); 285 286 return 0; 287 } 288 289 static void skl_pcm_close(struct snd_pcm_substream *substream, 290 struct snd_soc_dai *dai) 291 { 292 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 293 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 294 struct skl_dma_params *dma_params = NULL; 295 struct skl *skl = ebus_to_skl(ebus); 296 297 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 298 299 snd_hdac_ext_stream_release(stream, skl_get_host_stream_type(ebus)); 300 301 dma_params = snd_soc_dai_get_dma_data(dai, substream); 302 /* 303 * now we should set this to NULL as we are freeing by the 304 * dma_params 305 */ 306 snd_soc_dai_set_dma_data(dai, substream, NULL); 307 skl_set_suspend_active(substream, dai, false); 308 309 /* 310 * check if close is for "Reference Pin" and set back the 311 * CGCTL.MISCBDCGE if disabled by driver 312 */ 313 if (!strncmp(dai->name, "Reference Pin", 13) && 314 skl->skl_sst->miscbdcg_disabled) { 315 skl->skl_sst->enable_miscbdcge(dai->dev, true); 316 skl->skl_sst->miscbdcg_disabled = false; 317 } 318 319 kfree(dma_params); 320 } 321 322 static int skl_pcm_hw_free(struct snd_pcm_substream *substream, 323 struct snd_soc_dai *dai) 324 { 325 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 326 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 327 328 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 329 330 snd_hdac_stream_cleanup(hdac_stream(stream)); 331 hdac_stream(stream)->prepared = 0; 332 333 return skl_substream_free_pages(ebus_to_hbus(ebus), substream); 334 } 335 336 static int skl_be_hw_params(struct snd_pcm_substream *substream, 337 struct snd_pcm_hw_params *params, 338 struct snd_soc_dai *dai) 339 { 340 struct skl_pipe_params p_params = {0}; 341 342 p_params.s_fmt = snd_pcm_format_width(params_format(params)); 343 p_params.ch = params_channels(params); 344 p_params.s_freq = params_rate(params); 345 p_params.stream = substream->stream; 346 347 return skl_tplg_be_update_params(dai, &p_params); 348 } 349 350 static int skl_decoupled_trigger(struct snd_pcm_substream *substream, 351 int cmd) 352 { 353 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 354 struct hdac_bus *bus = ebus_to_hbus(ebus); 355 struct hdac_ext_stream *stream; 356 int start; 357 unsigned long cookie; 358 struct hdac_stream *hstr; 359 360 stream = get_hdac_ext_stream(substream); 361 hstr = hdac_stream(stream); 362 363 if (!hstr->prepared) 364 return -EPIPE; 365 366 switch (cmd) { 367 case SNDRV_PCM_TRIGGER_START: 368 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 369 case SNDRV_PCM_TRIGGER_RESUME: 370 start = 1; 371 break; 372 373 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 374 case SNDRV_PCM_TRIGGER_SUSPEND: 375 case SNDRV_PCM_TRIGGER_STOP: 376 start = 0; 377 break; 378 379 default: 380 return -EINVAL; 381 } 382 383 spin_lock_irqsave(&bus->reg_lock, cookie); 384 385 if (start) { 386 snd_hdac_stream_start(hdac_stream(stream), true); 387 snd_hdac_stream_timecounter_init(hstr, 0); 388 } else { 389 snd_hdac_stream_stop(hdac_stream(stream)); 390 } 391 392 spin_unlock_irqrestore(&bus->reg_lock, cookie); 393 394 return 0; 395 } 396 397 static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, 398 struct snd_soc_dai *dai) 399 { 400 struct skl *skl = get_skl_ctx(dai->dev); 401 struct skl_sst *ctx = skl->skl_sst; 402 struct skl_module_cfg *mconfig; 403 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 404 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 405 struct snd_soc_dapm_widget *w; 406 int ret; 407 408 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); 409 if (!mconfig) 410 return -EIO; 411 412 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 413 w = dai->playback_widget; 414 else 415 w = dai->capture_widget; 416 417 switch (cmd) { 418 case SNDRV_PCM_TRIGGER_RESUME: 419 if (!w->ignore_suspend) { 420 skl_pcm_prepare(substream, dai); 421 /* 422 * enable DMA Resume enable bit for the stream, set the 423 * dpib & lpib position to resume before starting the 424 * DMA 425 */ 426 snd_hdac_ext_stream_drsm_enable(ebus, true, 427 hdac_stream(stream)->index); 428 snd_hdac_ext_stream_set_dpibr(ebus, stream, 429 stream->dpib); 430 snd_hdac_ext_stream_set_lpib(stream, stream->lpib); 431 } 432 433 case SNDRV_PCM_TRIGGER_START: 434 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 435 /* 436 * Start HOST DMA and Start FE Pipe.This is to make sure that 437 * there are no underrun/overrun in the case when the FE 438 * pipeline is started but there is a delay in starting the 439 * DMA channel on the host. 440 */ 441 snd_hdac_ext_stream_decouple(ebus, stream, true); 442 ret = skl_decoupled_trigger(substream, cmd); 443 if (ret < 0) 444 return ret; 445 return skl_run_pipe(ctx, mconfig->pipe); 446 break; 447 448 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 449 case SNDRV_PCM_TRIGGER_SUSPEND: 450 case SNDRV_PCM_TRIGGER_STOP: 451 /* 452 * Stop FE Pipe first and stop DMA. This is to make sure that 453 * there are no underrun/overrun in the case if there is a delay 454 * between the two operations. 455 */ 456 ret = skl_stop_pipe(ctx, mconfig->pipe); 457 if (ret < 0) 458 return ret; 459 460 ret = skl_decoupled_trigger(substream, cmd); 461 if ((cmd == SNDRV_PCM_TRIGGER_SUSPEND) && !w->ignore_suspend) { 462 /* save the dpib and lpib positions */ 463 stream->dpib = readl(ebus->bus.remap_addr + 464 AZX_REG_VS_SDXDPIB_XBASE + 465 (AZX_REG_VS_SDXDPIB_XINTERVAL * 466 hdac_stream(stream)->index)); 467 468 stream->lpib = snd_hdac_stream_get_pos_lpib( 469 hdac_stream(stream)); 470 snd_hdac_ext_stream_decouple(ebus, stream, false); 471 } 472 break; 473 474 default: 475 return -EINVAL; 476 } 477 478 return 0; 479 } 480 481 static int skl_link_hw_params(struct snd_pcm_substream *substream, 482 struct snd_pcm_hw_params *params, 483 struct snd_soc_dai *dai) 484 { 485 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 486 struct hdac_ext_stream *link_dev; 487 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 488 struct hdac_ext_dma_params *dma_params; 489 struct snd_soc_dai *codec_dai = rtd->codec_dai; 490 struct skl_pipe_params p_params = {0}; 491 492 link_dev = snd_hdac_ext_stream_assign(ebus, substream, 493 HDAC_EXT_STREAM_TYPE_LINK); 494 if (!link_dev) 495 return -EBUSY; 496 497 snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); 498 499 /* set the stream tag in the codec dai dma params */ 500 dma_params = snd_soc_dai_get_dma_data(codec_dai, substream); 501 if (dma_params) 502 dma_params->stream_tag = hdac_stream(link_dev)->stream_tag; 503 504 p_params.s_fmt = snd_pcm_format_width(params_format(params)); 505 p_params.ch = params_channels(params); 506 p_params.s_freq = params_rate(params); 507 p_params.stream = substream->stream; 508 p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1; 509 510 return skl_tplg_be_update_params(dai, &p_params); 511 } 512 513 static int skl_link_pcm_prepare(struct snd_pcm_substream *substream, 514 struct snd_soc_dai *dai) 515 { 516 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 517 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 518 struct hdac_ext_stream *link_dev = 519 snd_soc_dai_get_dma_data(dai, substream); 520 unsigned int format_val = 0; 521 struct skl_dma_params *dma_params; 522 struct snd_soc_dai *codec_dai = rtd->codec_dai; 523 struct hdac_ext_link *link; 524 525 dma_params = (struct skl_dma_params *) 526 snd_soc_dai_get_dma_data(codec_dai, substream); 527 if (dma_params) 528 format_val = dma_params->format; 529 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d codec_dai_name=%s\n", 530 hdac_stream(link_dev)->stream_tag, format_val, codec_dai->name); 531 532 link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name); 533 if (!link) 534 return -EINVAL; 535 536 snd_hdac_ext_link_stream_reset(link_dev); 537 538 snd_hdac_ext_link_stream_setup(link_dev, format_val); 539 540 snd_hdac_ext_link_set_stream_id(link, hdac_stream(link_dev)->stream_tag); 541 link_dev->link_prepared = 1; 542 543 return 0; 544 } 545 546 static int skl_link_pcm_trigger(struct snd_pcm_substream *substream, 547 int cmd, struct snd_soc_dai *dai) 548 { 549 struct hdac_ext_stream *link_dev = 550 snd_soc_dai_get_dma_data(dai, substream); 551 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 552 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 553 554 dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd); 555 switch (cmd) { 556 case SNDRV_PCM_TRIGGER_RESUME: 557 skl_link_pcm_prepare(substream, dai); 558 case SNDRV_PCM_TRIGGER_START: 559 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 560 snd_hdac_ext_stream_decouple(ebus, stream, true); 561 snd_hdac_ext_link_stream_start(link_dev); 562 break; 563 564 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 565 case SNDRV_PCM_TRIGGER_SUSPEND: 566 case SNDRV_PCM_TRIGGER_STOP: 567 snd_hdac_ext_link_stream_clear(link_dev); 568 if (cmd == SNDRV_PCM_TRIGGER_SUSPEND) 569 snd_hdac_ext_stream_decouple(ebus, stream, false); 570 break; 571 572 default: 573 return -EINVAL; 574 } 575 return 0; 576 } 577 578 static int skl_link_hw_free(struct snd_pcm_substream *substream, 579 struct snd_soc_dai *dai) 580 { 581 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 582 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 583 struct hdac_ext_stream *link_dev = 584 snd_soc_dai_get_dma_data(dai, substream); 585 struct hdac_ext_link *link; 586 587 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 588 589 link_dev->link_prepared = 0; 590 591 link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name); 592 if (!link) 593 return -EINVAL; 594 595 snd_hdac_ext_link_clear_stream_id(link, hdac_stream(link_dev)->stream_tag); 596 snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK); 597 return 0; 598 } 599 600 static struct snd_soc_dai_ops skl_pcm_dai_ops = { 601 .startup = skl_pcm_open, 602 .shutdown = skl_pcm_close, 603 .prepare = skl_pcm_prepare, 604 .hw_params = skl_pcm_hw_params, 605 .hw_free = skl_pcm_hw_free, 606 .trigger = skl_pcm_trigger, 607 }; 608 609 static struct snd_soc_dai_ops skl_dmic_dai_ops = { 610 .hw_params = skl_be_hw_params, 611 }; 612 613 static struct snd_soc_dai_ops skl_be_ssp_dai_ops = { 614 .hw_params = skl_be_hw_params, 615 .prepare = skl_be_prepare, 616 }; 617 618 static struct snd_soc_dai_ops skl_link_dai_ops = { 619 .prepare = skl_link_pcm_prepare, 620 .hw_params = skl_link_hw_params, 621 .hw_free = skl_link_hw_free, 622 .trigger = skl_link_pcm_trigger, 623 }; 624 625 static struct snd_soc_dai_driver skl_platform_dai[] = { 626 { 627 .name = "System Pin", 628 .ops = &skl_pcm_dai_ops, 629 .playback = { 630 .stream_name = "System Playback", 631 .channels_min = HDA_MONO, 632 .channels_max = HDA_STEREO, 633 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, 634 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 635 }, 636 .capture = { 637 .stream_name = "System Capture", 638 .channels_min = HDA_MONO, 639 .channels_max = HDA_STEREO, 640 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 641 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 642 }, 643 }, 644 { 645 .name = "Reference Pin", 646 .ops = &skl_pcm_dai_ops, 647 .capture = { 648 .stream_name = "Reference Capture", 649 .channels_min = HDA_MONO, 650 .channels_max = HDA_QUAD, 651 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 652 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 653 }, 654 }, 655 { 656 .name = "Deepbuffer Pin", 657 .ops = &skl_pcm_dai_ops, 658 .playback = { 659 .stream_name = "Deepbuffer Playback", 660 .channels_min = HDA_STEREO, 661 .channels_max = HDA_STEREO, 662 .rates = SNDRV_PCM_RATE_48000, 663 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 664 }, 665 }, 666 { 667 .name = "LowLatency Pin", 668 .ops = &skl_pcm_dai_ops, 669 .playback = { 670 .stream_name = "Low Latency Playback", 671 .channels_min = HDA_STEREO, 672 .channels_max = HDA_STEREO, 673 .rates = SNDRV_PCM_RATE_48000, 674 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 675 }, 676 }, 677 { 678 .name = "DMIC Pin", 679 .ops = &skl_pcm_dai_ops, 680 .capture = { 681 .stream_name = "DMIC Capture", 682 .channels_min = HDA_MONO, 683 .channels_max = HDA_QUAD, 684 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 685 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 686 }, 687 }, 688 { 689 .name = "HDMI1 Pin", 690 .ops = &skl_pcm_dai_ops, 691 .playback = { 692 .stream_name = "HDMI1 Playback", 693 .channels_min = HDA_STEREO, 694 .channels_max = 8, 695 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 696 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | 697 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | 698 SNDRV_PCM_RATE_192000, 699 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 700 SNDRV_PCM_FMTBIT_S32_LE, 701 }, 702 }, 703 { 704 .name = "HDMI2 Pin", 705 .ops = &skl_pcm_dai_ops, 706 .playback = { 707 .stream_name = "HDMI2 Playback", 708 .channels_min = HDA_STEREO, 709 .channels_max = 8, 710 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 711 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | 712 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | 713 SNDRV_PCM_RATE_192000, 714 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 715 SNDRV_PCM_FMTBIT_S32_LE, 716 }, 717 }, 718 { 719 .name = "HDMI3 Pin", 720 .ops = &skl_pcm_dai_ops, 721 .playback = { 722 .stream_name = "HDMI3 Playback", 723 .channels_min = HDA_STEREO, 724 .channels_max = 8, 725 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 726 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | 727 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | 728 SNDRV_PCM_RATE_192000, 729 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 730 SNDRV_PCM_FMTBIT_S32_LE, 731 }, 732 }, 733 734 /* BE CPU Dais */ 735 { 736 .name = "SSP0 Pin", 737 .ops = &skl_be_ssp_dai_ops, 738 .playback = { 739 .stream_name = "ssp0 Tx", 740 .channels_min = HDA_STEREO, 741 .channels_max = HDA_STEREO, 742 .rates = SNDRV_PCM_RATE_48000, 743 .formats = SNDRV_PCM_FMTBIT_S16_LE, 744 }, 745 .capture = { 746 .stream_name = "ssp0 Rx", 747 .channels_min = HDA_STEREO, 748 .channels_max = HDA_STEREO, 749 .rates = SNDRV_PCM_RATE_48000, 750 .formats = SNDRV_PCM_FMTBIT_S16_LE, 751 }, 752 }, 753 { 754 .name = "SSP1 Pin", 755 .ops = &skl_be_ssp_dai_ops, 756 .playback = { 757 .stream_name = "ssp1 Tx", 758 .channels_min = HDA_STEREO, 759 .channels_max = HDA_STEREO, 760 .rates = SNDRV_PCM_RATE_48000, 761 .formats = SNDRV_PCM_FMTBIT_S16_LE, 762 }, 763 .capture = { 764 .stream_name = "ssp1 Rx", 765 .channels_min = HDA_STEREO, 766 .channels_max = HDA_STEREO, 767 .rates = SNDRV_PCM_RATE_48000, 768 .formats = SNDRV_PCM_FMTBIT_S16_LE, 769 }, 770 }, 771 { 772 .name = "SSP2 Pin", 773 .ops = &skl_be_ssp_dai_ops, 774 .playback = { 775 .stream_name = "ssp2 Tx", 776 .channels_min = HDA_STEREO, 777 .channels_max = HDA_STEREO, 778 .rates = SNDRV_PCM_RATE_48000, 779 .formats = SNDRV_PCM_FMTBIT_S16_LE, 780 }, 781 .capture = { 782 .stream_name = "ssp2 Rx", 783 .channels_min = HDA_STEREO, 784 .channels_max = HDA_STEREO, 785 .rates = SNDRV_PCM_RATE_48000, 786 .formats = SNDRV_PCM_FMTBIT_S16_LE, 787 }, 788 }, 789 { 790 .name = "SSP3 Pin", 791 .ops = &skl_be_ssp_dai_ops, 792 .playback = { 793 .stream_name = "ssp3 Tx", 794 .channels_min = HDA_STEREO, 795 .channels_max = HDA_STEREO, 796 .rates = SNDRV_PCM_RATE_48000, 797 .formats = SNDRV_PCM_FMTBIT_S16_LE, 798 }, 799 .capture = { 800 .stream_name = "ssp3 Rx", 801 .channels_min = HDA_STEREO, 802 .channels_max = HDA_STEREO, 803 .rates = SNDRV_PCM_RATE_48000, 804 .formats = SNDRV_PCM_FMTBIT_S16_LE, 805 }, 806 }, 807 { 808 .name = "SSP4 Pin", 809 .ops = &skl_be_ssp_dai_ops, 810 .playback = { 811 .stream_name = "ssp4 Tx", 812 .channels_min = HDA_STEREO, 813 .channels_max = HDA_STEREO, 814 .rates = SNDRV_PCM_RATE_48000, 815 .formats = SNDRV_PCM_FMTBIT_S16_LE, 816 }, 817 .capture = { 818 .stream_name = "ssp4 Rx", 819 .channels_min = HDA_STEREO, 820 .channels_max = HDA_STEREO, 821 .rates = SNDRV_PCM_RATE_48000, 822 .formats = SNDRV_PCM_FMTBIT_S16_LE, 823 }, 824 }, 825 { 826 .name = "SSP5 Pin", 827 .ops = &skl_be_ssp_dai_ops, 828 .playback = { 829 .stream_name = "ssp5 Tx", 830 .channels_min = HDA_STEREO, 831 .channels_max = HDA_STEREO, 832 .rates = SNDRV_PCM_RATE_48000, 833 .formats = SNDRV_PCM_FMTBIT_S16_LE, 834 }, 835 .capture = { 836 .stream_name = "ssp5 Rx", 837 .channels_min = HDA_STEREO, 838 .channels_max = HDA_STEREO, 839 .rates = SNDRV_PCM_RATE_48000, 840 .formats = SNDRV_PCM_FMTBIT_S16_LE, 841 }, 842 }, 843 { 844 .name = "iDisp1 Pin", 845 .ops = &skl_link_dai_ops, 846 .playback = { 847 .stream_name = "iDisp1 Tx", 848 .channels_min = HDA_STEREO, 849 .channels_max = 8, 850 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000, 851 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | 852 SNDRV_PCM_FMTBIT_S24_LE, 853 }, 854 }, 855 { 856 .name = "iDisp2 Pin", 857 .ops = &skl_link_dai_ops, 858 .playback = { 859 .stream_name = "iDisp2 Tx", 860 .channels_min = HDA_STEREO, 861 .channels_max = 8, 862 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000| 863 SNDRV_PCM_RATE_48000, 864 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | 865 SNDRV_PCM_FMTBIT_S24_LE, 866 }, 867 }, 868 { 869 .name = "iDisp3 Pin", 870 .ops = &skl_link_dai_ops, 871 .playback = { 872 .stream_name = "iDisp3 Tx", 873 .channels_min = HDA_STEREO, 874 .channels_max = 8, 875 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000| 876 SNDRV_PCM_RATE_48000, 877 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | 878 SNDRV_PCM_FMTBIT_S24_LE, 879 }, 880 }, 881 { 882 .name = "DMIC01 Pin", 883 .ops = &skl_dmic_dai_ops, 884 .capture = { 885 .stream_name = "DMIC01 Rx", 886 .channels_min = HDA_MONO, 887 .channels_max = HDA_QUAD, 888 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 889 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 890 }, 891 }, 892 { 893 .name = "HD-Codec Pin", 894 .ops = &skl_link_dai_ops, 895 .playback = { 896 .stream_name = "HD-Codec Tx", 897 .channels_min = HDA_STEREO, 898 .channels_max = HDA_STEREO, 899 .rates = SNDRV_PCM_RATE_48000, 900 .formats = SNDRV_PCM_FMTBIT_S16_LE, 901 }, 902 .capture = { 903 .stream_name = "HD-Codec Rx", 904 .channels_min = HDA_STEREO, 905 .channels_max = HDA_STEREO, 906 .rates = SNDRV_PCM_RATE_48000, 907 .formats = SNDRV_PCM_FMTBIT_S16_LE, 908 }, 909 }, 910 }; 911 912 static int skl_platform_open(struct snd_pcm_substream *substream) 913 { 914 struct snd_pcm_runtime *runtime; 915 struct snd_soc_pcm_runtime *rtd = substream->private_data; 916 struct snd_soc_dai_link *dai_link = rtd->dai_link; 917 918 dev_dbg(rtd->cpu_dai->dev, "In %s:%s\n", __func__, 919 dai_link->cpu_dai_name); 920 921 runtime = substream->runtime; 922 snd_soc_set_runtime_hwparams(substream, &azx_pcm_hw); 923 924 return 0; 925 } 926 927 static int skl_coupled_trigger(struct snd_pcm_substream *substream, 928 int cmd) 929 { 930 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 931 struct hdac_bus *bus = ebus_to_hbus(ebus); 932 struct hdac_ext_stream *stream; 933 struct snd_pcm_substream *s; 934 bool start; 935 int sbits = 0; 936 unsigned long cookie; 937 struct hdac_stream *hstr; 938 939 stream = get_hdac_ext_stream(substream); 940 hstr = hdac_stream(stream); 941 942 dev_dbg(bus->dev, "In %s cmd=%d\n", __func__, cmd); 943 944 if (!hstr->prepared) 945 return -EPIPE; 946 947 switch (cmd) { 948 case SNDRV_PCM_TRIGGER_START: 949 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 950 case SNDRV_PCM_TRIGGER_RESUME: 951 start = true; 952 break; 953 954 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 955 case SNDRV_PCM_TRIGGER_SUSPEND: 956 case SNDRV_PCM_TRIGGER_STOP: 957 start = false; 958 break; 959 960 default: 961 return -EINVAL; 962 } 963 964 snd_pcm_group_for_each_entry(s, substream) { 965 if (s->pcm->card != substream->pcm->card) 966 continue; 967 stream = get_hdac_ext_stream(s); 968 sbits |= 1 << hdac_stream(stream)->index; 969 snd_pcm_trigger_done(s, substream); 970 } 971 972 spin_lock_irqsave(&bus->reg_lock, cookie); 973 974 /* first, set SYNC bits of corresponding streams */ 975 snd_hdac_stream_sync_trigger(hstr, true, sbits, AZX_REG_SSYNC); 976 977 snd_pcm_group_for_each_entry(s, substream) { 978 if (s->pcm->card != substream->pcm->card) 979 continue; 980 stream = get_hdac_ext_stream(s); 981 if (start) 982 snd_hdac_stream_start(hdac_stream(stream), true); 983 else 984 snd_hdac_stream_stop(hdac_stream(stream)); 985 } 986 spin_unlock_irqrestore(&bus->reg_lock, cookie); 987 988 snd_hdac_stream_sync(hstr, start, sbits); 989 990 spin_lock_irqsave(&bus->reg_lock, cookie); 991 992 /* reset SYNC bits */ 993 snd_hdac_stream_sync_trigger(hstr, false, sbits, AZX_REG_SSYNC); 994 if (start) 995 snd_hdac_stream_timecounter_init(hstr, sbits); 996 spin_unlock_irqrestore(&bus->reg_lock, cookie); 997 998 return 0; 999 } 1000 1001 static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream, 1002 int cmd) 1003 { 1004 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 1005 1006 if (!ebus->ppcap) 1007 return skl_coupled_trigger(substream, cmd); 1008 1009 return 0; 1010 } 1011 1012 /* calculate runtime delay from LPIB */ 1013 static int skl_get_delay_from_lpib(struct hdac_ext_bus *ebus, 1014 struct hdac_ext_stream *sstream, 1015 unsigned int pos) 1016 { 1017 struct hdac_bus *bus = ebus_to_hbus(ebus); 1018 struct hdac_stream *hstream = hdac_stream(sstream); 1019 struct snd_pcm_substream *substream = hstream->substream; 1020 int stream = substream->stream; 1021 unsigned int lpib_pos = snd_hdac_stream_get_pos_lpib(hstream); 1022 int delay; 1023 1024 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1025 delay = pos - lpib_pos; 1026 else 1027 delay = lpib_pos - pos; 1028 1029 if (delay < 0) { 1030 if (delay >= hstream->delay_negative_threshold) 1031 delay = 0; 1032 else 1033 delay += hstream->bufsize; 1034 } 1035 1036 if (hstream->bufsize == delay) 1037 delay = 0; 1038 1039 if (delay >= hstream->period_bytes) { 1040 dev_info(bus->dev, 1041 "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n", 1042 delay, hstream->period_bytes); 1043 delay = 0; 1044 } 1045 1046 return bytes_to_frames(substream->runtime, delay); 1047 } 1048 1049 static unsigned int skl_get_position(struct hdac_ext_stream *hstream, 1050 int codec_delay) 1051 { 1052 struct hdac_stream *hstr = hdac_stream(hstream); 1053 struct snd_pcm_substream *substream = hstr->substream; 1054 struct hdac_ext_bus *ebus; 1055 unsigned int pos; 1056 int delay; 1057 1058 /* use the position buffer as default */ 1059 pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream)); 1060 1061 if (pos >= hdac_stream(hstream)->bufsize) 1062 pos = 0; 1063 1064 if (substream->runtime) { 1065 ebus = get_bus_ctx(substream); 1066 delay = skl_get_delay_from_lpib(ebus, hstream, pos) 1067 + codec_delay; 1068 substream->runtime->delay += delay; 1069 } 1070 1071 return pos; 1072 } 1073 1074 static snd_pcm_uframes_t skl_platform_pcm_pointer 1075 (struct snd_pcm_substream *substream) 1076 { 1077 struct hdac_ext_stream *hstream = get_hdac_ext_stream(substream); 1078 1079 return bytes_to_frames(substream->runtime, 1080 skl_get_position(hstream, 0)); 1081 } 1082 1083 static u64 skl_adjust_codec_delay(struct snd_pcm_substream *substream, 1084 u64 nsec) 1085 { 1086 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 1087 struct snd_soc_dai *codec_dai = rtd->codec_dai; 1088 u64 codec_frames, codec_nsecs; 1089 1090 if (!codec_dai->driver->ops->delay) 1091 return nsec; 1092 1093 codec_frames = codec_dai->driver->ops->delay(substream, codec_dai); 1094 codec_nsecs = div_u64(codec_frames * 1000000000LL, 1095 substream->runtime->rate); 1096 1097 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 1098 return nsec + codec_nsecs; 1099 1100 return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0; 1101 } 1102 1103 static int skl_get_time_info(struct snd_pcm_substream *substream, 1104 struct timespec *system_ts, struct timespec *audio_ts, 1105 struct snd_pcm_audio_tstamp_config *audio_tstamp_config, 1106 struct snd_pcm_audio_tstamp_report *audio_tstamp_report) 1107 { 1108 struct hdac_ext_stream *sstream = get_hdac_ext_stream(substream); 1109 struct hdac_stream *hstr = hdac_stream(sstream); 1110 u64 nsec; 1111 1112 if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) && 1113 (audio_tstamp_config->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK)) { 1114 1115 snd_pcm_gettime(substream->runtime, system_ts); 1116 1117 nsec = timecounter_read(&hstr->tc); 1118 nsec = div_u64(nsec, 3); /* can be optimized */ 1119 if (audio_tstamp_config->report_delay) 1120 nsec = skl_adjust_codec_delay(substream, nsec); 1121 1122 *audio_ts = ns_to_timespec(nsec); 1123 1124 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK; 1125 audio_tstamp_report->accuracy_report = 1; /* rest of struct is valid */ 1126 audio_tstamp_report->accuracy = 42; /* 24MHzWallClk == 42ns resolution */ 1127 1128 } else { 1129 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT; 1130 } 1131 1132 return 0; 1133 } 1134 1135 static struct snd_pcm_ops skl_platform_ops = { 1136 .open = skl_platform_open, 1137 .ioctl = snd_pcm_lib_ioctl, 1138 .trigger = skl_platform_pcm_trigger, 1139 .pointer = skl_platform_pcm_pointer, 1140 .get_time_info = skl_get_time_info, 1141 .mmap = snd_pcm_lib_default_mmap, 1142 .page = snd_pcm_sgbuf_ops_page, 1143 }; 1144 1145 static void skl_pcm_free(struct snd_pcm *pcm) 1146 { 1147 snd_pcm_lib_preallocate_free_for_all(pcm); 1148 } 1149 1150 #define MAX_PREALLOC_SIZE (32 * 1024 * 1024) 1151 1152 static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) 1153 { 1154 struct snd_soc_dai *dai = rtd->cpu_dai; 1155 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 1156 struct snd_pcm *pcm = rtd->pcm; 1157 unsigned int size; 1158 int retval = 0; 1159 struct skl *skl = ebus_to_skl(ebus); 1160 1161 if (dai->driver->playback.channels_min || 1162 dai->driver->capture.channels_min) { 1163 /* buffer pre-allocation */ 1164 size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024; 1165 if (size > MAX_PREALLOC_SIZE) 1166 size = MAX_PREALLOC_SIZE; 1167 retval = snd_pcm_lib_preallocate_pages_for_all(pcm, 1168 SNDRV_DMA_TYPE_DEV_SG, 1169 snd_dma_pci_data(skl->pci), 1170 size, MAX_PREALLOC_SIZE); 1171 if (retval) { 1172 dev_err(dai->dev, "dma buffer allocationf fail\n"); 1173 return retval; 1174 } 1175 } 1176 1177 return retval; 1178 } 1179 1180 static int skl_platform_soc_probe(struct snd_soc_platform *platform) 1181 { 1182 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); 1183 1184 if (ebus->ppcap) 1185 return skl_tplg_init(platform, ebus); 1186 1187 return 0; 1188 } 1189 static struct snd_soc_platform_driver skl_platform_drv = { 1190 .probe = skl_platform_soc_probe, 1191 .ops = &skl_platform_ops, 1192 .pcm_new = skl_pcm_new, 1193 .pcm_free = skl_pcm_free, 1194 }; 1195 1196 static const struct snd_soc_component_driver skl_component = { 1197 .name = "pcm", 1198 }; 1199 1200 int skl_platform_register(struct device *dev) 1201 { 1202 int ret; 1203 struct hdac_ext_bus *ebus = dev_get_drvdata(dev); 1204 struct skl *skl = ebus_to_skl(ebus); 1205 1206 INIT_LIST_HEAD(&skl->ppl_list); 1207 1208 ret = snd_soc_register_platform(dev, &skl_platform_drv); 1209 if (ret) { 1210 dev_err(dev, "soc platform registration failed %d\n", ret); 1211 return ret; 1212 } 1213 ret = snd_soc_register_component(dev, &skl_component, 1214 skl_platform_dai, 1215 ARRAY_SIZE(skl_platform_dai)); 1216 if (ret) { 1217 dev_err(dev, "soc component registration failed %d\n", ret); 1218 snd_soc_unregister_platform(dev); 1219 } 1220 1221 return ret; 1222 1223 } 1224 1225 int skl_platform_unregister(struct device *dev) 1226 { 1227 snd_soc_unregister_component(dev); 1228 snd_soc_unregister_platform(dev); 1229 return 0; 1230 } 1231