linux/sound/soc/intel/skylake/skl-pcm.c
<<
>>
Prefs
   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
  35static 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
  63static inline
  64struct hdac_ext_stream *get_hdac_ext_stream(struct snd_pcm_substream *substream)
  65{
  66        return substream->runtime->private_data;
  67}
  68
  69static 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
  78static 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
  91static 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
  97static 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
 107static 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 */
 122static 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
 140static 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
 183static 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
 209static 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
 226static 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
 253static 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
 289static 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
 322static 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
 336static 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
 350static 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
 397static 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
 481static 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
 513static 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
 546static 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
 578static 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
 600static 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
 609static struct snd_soc_dai_ops skl_dmic_dai_ops = {
 610        .hw_params = skl_be_hw_params,
 611};
 612
 613static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
 614        .hw_params = skl_be_hw_params,
 615        .prepare = skl_be_prepare,
 616};
 617
 618static 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
 625static 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
 912static 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
 927static 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
1001static 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 */
1013static 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
1049static 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
1074static 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
1083static 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
1103static 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
1135static 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
1145static 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
1152static 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
1180static 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}
1189static 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
1196static const struct snd_soc_component_driver skl_component = {
1197        .name           = "pcm",
1198};
1199
1200int 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
1225int skl_platform_unregister(struct device *dev)
1226{
1227        snd_soc_unregister_component(dev);
1228        snd_soc_unregister_platform(dev);
1229        return 0;
1230}
1231