~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/intel/skylake/skl-pcm.c

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 <linux/delay.h>
 25 #include <sound/pcm_params.h>
 26 #include <sound/soc.h>
 27 #include "skl.h"
 28 #include "skl-topology.h"
 29 #include "skl-sst-dsp.h"
 30 #include "skl-sst-ipc.h"
 31 
 32 #define HDA_MONO 1
 33 #define HDA_STEREO 2
 34 #define HDA_QUAD 4
 35 #define HDA_MAX 8
 36 
 37 static const struct snd_pcm_hardware azx_pcm_hw = {
 38         .info =                 (SNDRV_PCM_INFO_MMAP |
 39                                  SNDRV_PCM_INFO_INTERLEAVED |
 40                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
 41                                  SNDRV_PCM_INFO_MMAP_VALID |
 42                                  SNDRV_PCM_INFO_PAUSE |
 43                                  SNDRV_PCM_INFO_RESUME |
 44                                  SNDRV_PCM_INFO_SYNC_START |
 45                                  SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */
 46                                  SNDRV_PCM_INFO_HAS_LINK_ATIME |
 47                                  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
 48         .formats =              SNDRV_PCM_FMTBIT_S16_LE |
 49                                 SNDRV_PCM_FMTBIT_S32_LE |
 50                                 SNDRV_PCM_FMTBIT_S24_LE,
 51         .rates =                SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
 52                                 SNDRV_PCM_RATE_8000,
 53         .rate_min =             8000,
 54         .rate_max =             48000,
 55         .channels_min =         1,
 56         .channels_max =         8,
 57         .buffer_bytes_max =     AZX_MAX_BUF_SIZE,
 58         .period_bytes_min =     128,
 59         .period_bytes_max =     AZX_MAX_BUF_SIZE / 2,
 60         .periods_min =          2,
 61         .periods_max =          AZX_MAX_FRAG,
 62         .fifo_size =            0,
 63 };
 64 
 65 static inline
 66 struct hdac_ext_stream *get_hdac_ext_stream(struct snd_pcm_substream *substream)
 67 {
 68         return substream->runtime->private_data;
 69 }
 70 
 71 static struct hdac_bus *get_bus_ctx(struct snd_pcm_substream *substream)
 72 {
 73         struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
 74         struct hdac_stream *hstream = hdac_stream(stream);
 75         struct hdac_bus *bus = hstream->bus;
 76         return bus;
 77 }
 78 
 79 static int skl_substream_alloc_pages(struct hdac_bus *bus,
 80                                  struct snd_pcm_substream *substream,
 81                                  size_t size)
 82 {
 83         struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
 84 
 85         hdac_stream(stream)->bufsize = 0;
 86         hdac_stream(stream)->period_bytes = 0;
 87         hdac_stream(stream)->format_val = 0;
 88 
 89         return snd_pcm_lib_malloc_pages(substream, size);
 90 }
 91 
 92 static int skl_substream_free_pages(struct hdac_bus *bus,
 93                                 struct snd_pcm_substream *substream)
 94 {
 95         return snd_pcm_lib_free_pages(substream);
 96 }
 97 
 98 static void skl_set_pcm_constrains(struct hdac_bus *bus,
 99                                  struct snd_pcm_runtime *runtime)
100 {
101         snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
102 
103         /* avoid wrap-around with wall-clock */
104         snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME,
105                                      20, 178000000);
106 }
107 
108 static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_bus *bus)
109 {
110         if (bus->ppcap)
111                 return HDAC_EXT_STREAM_TYPE_HOST;
112         else
113                 return HDAC_EXT_STREAM_TYPE_COUPLED;
114 }
115 
116 /*
117  * check if the stream opened is marked as ignore_suspend by machine, if so
118  * then enable suspend_active refcount
119  *
120  * The count supend_active does not need lock as it is used in open/close
121  * and suspend context
122  */
123 static void skl_set_suspend_active(struct snd_pcm_substream *substream,
124                                          struct snd_soc_dai *dai, bool enable)
125 {
126         struct hdac_bus *bus = dev_get_drvdata(dai->dev);
127         struct snd_soc_dapm_widget *w;
128         struct skl *skl = bus_to_skl(bus);
129 
130         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
131                 w = dai->playback_widget;
132         else
133                 w = dai->capture_widget;
134 
135         if (w->ignore_suspend && enable)
136                 skl->supend_active++;
137         else if (w->ignore_suspend && !enable)
138                 skl->supend_active--;
139 }
140 
141 int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
142 {
143         struct hdac_bus *bus = dev_get_drvdata(dev);
144         unsigned int format_val;
145         struct hdac_stream *hstream;
146         struct hdac_ext_stream *stream;
147         int err;
148 
149         hstream = snd_hdac_get_stream(bus, params->stream,
150                                         params->host_dma_id + 1);
151         if (!hstream)
152                 return -EINVAL;
153 
154         stream = stream_to_hdac_ext_stream(hstream);
155         snd_hdac_ext_stream_decouple(bus, stream, true);
156 
157         format_val = snd_hdac_calc_stream_format(params->s_freq,
158                         params->ch, params->format, params->host_bps, 0);
159 
160         dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
161                 format_val, params->s_freq, params->ch, params->format);
162 
163         snd_hdac_stream_reset(hdac_stream(stream));
164         err = snd_hdac_stream_set_params(hdac_stream(stream), format_val);
165         if (err < 0)
166                 return err;
167 
168         err = snd_hdac_stream_setup(hdac_stream(stream));
169         if (err < 0)
170                 return err;
171 
172         hdac_stream(stream)->prepared = 1;
173 
174         return 0;
175 }
176 
177 int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
178 {
179         struct hdac_bus *bus = dev_get_drvdata(dev);
180         unsigned int format_val;
181         struct hdac_stream *hstream;
182         struct hdac_ext_stream *stream;
183         struct hdac_ext_link *link;
184         unsigned char stream_tag;
185 
186         hstream = snd_hdac_get_stream(bus, params->stream,
187                                         params->link_dma_id + 1);
188         if (!hstream)
189                 return -EINVAL;
190 
191         stream = stream_to_hdac_ext_stream(hstream);
192         snd_hdac_ext_stream_decouple(bus, stream, true);
193         format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch,
194                                         params->format, params->link_bps, 0);
195 
196         dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
197                 format_val, params->s_freq, params->ch, params->format);
198 
199         snd_hdac_ext_link_stream_reset(stream);
200 
201         snd_hdac_ext_link_stream_setup(stream, format_val);
202 
203         stream_tag = hstream->stream_tag;
204         if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) {
205                 list_for_each_entry(link, &bus->hlink_list, list) {
206                         if (link->index == params->link_index)
207                                 snd_hdac_ext_link_set_stream_id(link,
208                                                                 stream_tag);
209                 }
210         }
211 
212         stream->link_prepared = 1;
213 
214         return 0;
215 }
216 
217 static int skl_pcm_open(struct snd_pcm_substream *substream,
218                 struct snd_soc_dai *dai)
219 {
220         struct hdac_bus *bus = dev_get_drvdata(dai->dev);
221         struct hdac_ext_stream *stream;
222         struct snd_pcm_runtime *runtime = substream->runtime;
223         struct skl_dma_params *dma_params;
224         struct skl *skl = get_skl_ctx(dai->dev);
225         struct skl_module_cfg *mconfig;
226 
227         dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
228 
229         stream = snd_hdac_ext_stream_assign(bus, substream,
230                                         skl_get_host_stream_type(bus));
231         if (stream == NULL)
232                 return -EBUSY;
233 
234         skl_set_pcm_constrains(bus, runtime);
235 
236         /*
237          * disable WALLCLOCK timestamps for capture streams
238          * until we figure out how to handle digital inputs
239          */
240         if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
241                 runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */
242                 runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME;
243         }
244 
245         runtime->private_data = stream;
246 
247         dma_params = kzalloc(sizeof(*dma_params), GFP_KERNEL);
248         if (!dma_params)
249                 return -ENOMEM;
250 
251         dma_params->stream_tag = hdac_stream(stream)->stream_tag;
252         snd_soc_dai_set_dma_data(dai, substream, dma_params);
253 
254         dev_dbg(dai->dev, "stream tag set in dma params=%d\n",
255                                  dma_params->stream_tag);
256         skl_set_suspend_active(substream, dai, true);
257         snd_pcm_set_sync(substream);
258 
259         mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
260         if (!mconfig)
261                 return -EINVAL;
262 
263         skl_tplg_d0i3_get(skl, mconfig->d0i3_caps);
264 
265         return 0;
266 }
267 
268 static int skl_pcm_prepare(struct snd_pcm_substream *substream,
269                 struct snd_soc_dai *dai)
270 {
271         struct skl *skl = get_skl_ctx(dai->dev);
272         struct skl_module_cfg *mconfig;
273         int ret;
274 
275         dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
276 
277         mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
278 
279         /*
280          * In case of XRUN recovery or in the case when the application
281          * calls prepare another time, reset the FW pipe to clean state
282          */
283         if (mconfig &&
284                 (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN ||
285                  mconfig->pipe->state == SKL_PIPE_CREATED ||
286                  mconfig->pipe->state == SKL_PIPE_PAUSED)) {
287 
288                 ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe);
289 
290                 if (ret < 0)
291                         return ret;
292 
293                 ret = skl_pcm_host_dma_prepare(dai->dev,
294                                         mconfig->pipe->p_params);
295                 if (ret < 0)
296                         return ret;
297         }
298 
299         return 0;
300 }
301 
302 static int skl_pcm_hw_params(struct snd_pcm_substream *substream,
303                                 struct snd_pcm_hw_params *params,
304                                 struct snd_soc_dai *dai)
305 {
306         struct hdac_bus *bus = dev_get_drvdata(dai->dev);
307         struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
308         struct snd_pcm_runtime *runtime = substream->runtime;
309         struct skl_pipe_params p_params = {0};
310         struct skl_module_cfg *m_cfg;
311         int ret, dma_id;
312 
313         dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
314         ret = skl_substream_alloc_pages(bus, substream,
315                                           params_buffer_bytes(params));
316         if (ret < 0)
317                 return ret;
318 
319         dev_dbg(dai->dev, "format_val, rate=%d, ch=%d, format=%d\n",
320                         runtime->rate, runtime->channels, runtime->format);
321 
322         dma_id = hdac_stream(stream)->stream_tag - 1;
323         dev_dbg(dai->dev, "dma_id=%d\n", dma_id);
324 
325         p_params.s_fmt = snd_pcm_format_width(params_format(params));
326         p_params.ch = params_channels(params);
327         p_params.s_freq = params_rate(params);
328         p_params.host_dma_id = dma_id;
329         p_params.stream = substream->stream;
330         p_params.format = params_format(params);
331         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
332                 p_params.host_bps = dai->driver->playback.sig_bits;
333         else
334                 p_params.host_bps = dai->driver->capture.sig_bits;
335 
336 
337         m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream);
338         if (m_cfg)
339                 skl_tplg_update_pipe_params(dai->dev, m_cfg, &p_params);
340 
341         return 0;
342 }
343 
344 static void skl_pcm_close(struct snd_pcm_substream *substream,
345                 struct snd_soc_dai *dai)
346 {
347         struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
348         struct hdac_bus *bus = dev_get_drvdata(dai->dev);
349         struct skl_dma_params *dma_params = NULL;
350         struct skl *skl = bus_to_skl(bus);
351         struct skl_module_cfg *mconfig;
352 
353         dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
354 
355         snd_hdac_ext_stream_release(stream, skl_get_host_stream_type(bus));
356 
357         dma_params = snd_soc_dai_get_dma_data(dai, substream);
358         /*
359          * now we should set this to NULL as we are freeing by the
360          * dma_params
361          */
362         snd_soc_dai_set_dma_data(dai, substream, NULL);
363         skl_set_suspend_active(substream, dai, false);
364 
365         /*
366          * check if close is for "Reference Pin" and set back the
367          * CGCTL.MISCBDCGE if disabled by driver
368          */
369         if (!strncmp(dai->name, "Reference Pin", 13) &&
370                         skl->skl_sst->miscbdcg_disabled) {
371                 skl->skl_sst->enable_miscbdcge(dai->dev, true);
372                 skl->skl_sst->miscbdcg_disabled = false;
373         }
374 
375         mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
376         if (mconfig)
377                 skl_tplg_d0i3_put(skl, mconfig->d0i3_caps);
378 
379         kfree(dma_params);
380 }
381 
382 static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
383                 struct snd_soc_dai *dai)
384 {
385         struct hdac_bus *bus = dev_get_drvdata(dai->dev);
386         struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
387         struct skl *skl = get_skl_ctx(dai->dev);
388         struct skl_module_cfg *mconfig;
389         int ret;
390 
391         dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
392 
393         mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
394 
395         if (mconfig) {
396                 ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe);
397                 if (ret < 0)
398                         dev_err(dai->dev, "%s:Reset failed ret =%d",
399                                                 __func__, ret);
400         }
401 
402         snd_hdac_stream_cleanup(hdac_stream(stream));
403         hdac_stream(stream)->prepared = 0;
404 
405         return skl_substream_free_pages(bus, substream);
406 }
407 
408 static int skl_be_hw_params(struct snd_pcm_substream *substream,
409                                 struct snd_pcm_hw_params *params,
410                                 struct snd_soc_dai *dai)
411 {
412         struct skl_pipe_params p_params = {0};
413 
414         p_params.s_fmt = snd_pcm_format_width(params_format(params));
415         p_params.ch = params_channels(params);
416         p_params.s_freq = params_rate(params);
417         p_params.stream = substream->stream;
418 
419         return skl_tplg_be_update_params(dai, &p_params);
420 }
421 
422 static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
423                 int cmd)
424 {
425         struct hdac_bus *bus = get_bus_ctx(substream);
426         struct hdac_ext_stream *stream;
427         int start;
428         unsigned long cookie;
429         struct hdac_stream *hstr;
430 
431         stream = get_hdac_ext_stream(substream);
432         hstr = hdac_stream(stream);
433 
434         if (!hstr->prepared)
435                 return -EPIPE;
436 
437         switch (cmd) {
438         case SNDRV_PCM_TRIGGER_START:
439         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
440         case SNDRV_PCM_TRIGGER_RESUME:
441                 start = 1;
442                 break;
443 
444         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
445         case SNDRV_PCM_TRIGGER_SUSPEND:
446         case SNDRV_PCM_TRIGGER_STOP:
447                 start = 0;
448                 break;
449 
450         default:
451                 return -EINVAL;
452         }
453 
454         spin_lock_irqsave(&bus->reg_lock, cookie);
455 
456         if (start) {
457                 snd_hdac_stream_start(hdac_stream(stream), true);
458                 snd_hdac_stream_timecounter_init(hstr, 0);
459         } else {
460                 snd_hdac_stream_stop(hdac_stream(stream));
461         }
462 
463         spin_unlock_irqrestore(&bus->reg_lock, cookie);
464 
465         return 0;
466 }
467 
468 static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
469                 struct snd_soc_dai *dai)
470 {
471         struct skl *skl = get_skl_ctx(dai->dev);
472         struct skl_sst *ctx = skl->skl_sst;
473         struct skl_module_cfg *mconfig;
474         struct hdac_bus *bus = get_bus_ctx(substream);
475         struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
476         struct snd_soc_dapm_widget *w;
477         int ret;
478 
479         mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
480         if (!mconfig)
481                 return -EIO;
482 
483         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
484                 w = dai->playback_widget;
485         else
486                 w = dai->capture_widget;
487 
488         switch (cmd) {
489         case SNDRV_PCM_TRIGGER_RESUME:
490                 if (!w->ignore_suspend) {
491                         /*
492                          * enable DMA Resume enable bit for the stream, set the
493                          * dpib & lpib position to resume before starting the
494                          * DMA
495                          */
496                         snd_hdac_ext_stream_drsm_enable(bus, true,
497                                                 hdac_stream(stream)->index);
498                         snd_hdac_ext_stream_set_dpibr(bus, stream,
499                                                         stream->lpib);
500                         snd_hdac_ext_stream_set_lpib(stream, stream->lpib);
501                 }
502                 /* fall through */
503 
504         case SNDRV_PCM_TRIGGER_START:
505         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
506                 /*
507                  * Start HOST DMA and Start FE Pipe.This is to make sure that
508                  * there are no underrun/overrun in the case when the FE
509                  * pipeline is started but there is a delay in starting the
510                  * DMA channel on the host.
511                  */
512                 ret = skl_decoupled_trigger(substream, cmd);
513                 if (ret < 0)
514                         return ret;
515                 return skl_run_pipe(ctx, mconfig->pipe);
516                 break;
517 
518         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
519         case SNDRV_PCM_TRIGGER_SUSPEND:
520         case SNDRV_PCM_TRIGGER_STOP:
521                 /*
522                  * Stop FE Pipe first and stop DMA. This is to make sure that
523                  * there are no underrun/overrun in the case if there is a delay
524                  * between the two operations.
525                  */
526                 ret = skl_stop_pipe(ctx, mconfig->pipe);
527                 if (ret < 0)
528                         return ret;
529 
530                 ret = skl_decoupled_trigger(substream, cmd);
531                 if ((cmd == SNDRV_PCM_TRIGGER_SUSPEND) && !w->ignore_suspend) {
532                         /* save the dpib and lpib positions */
533                         stream->dpib = readl(bus->remap_addr +
534                                         AZX_REG_VS_SDXDPIB_XBASE +
535                                         (AZX_REG_VS_SDXDPIB_XINTERVAL *
536                                         hdac_stream(stream)->index));
537 
538                         stream->lpib = snd_hdac_stream_get_pos_lpib(
539                                                         hdac_stream(stream));
540                         snd_hdac_ext_stream_decouple(bus, stream, false);
541                 }
542                 break;
543 
544         default:
545                 return -EINVAL;
546         }
547 
548         return 0;
549 }
550 
551 
552 static int skl_link_hw_params(struct snd_pcm_substream *substream,
553                                 struct snd_pcm_hw_params *params,
554                                 struct snd_soc_dai *dai)
555 {
556         struct hdac_bus *bus = dev_get_drvdata(dai->dev);
557         struct hdac_ext_stream *link_dev;
558         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
559         struct snd_soc_dai *codec_dai = rtd->codec_dai;
560         struct skl_pipe_params p_params = {0};
561         struct hdac_ext_link *link;
562         int stream_tag;
563 
564         link_dev = snd_hdac_ext_stream_assign(bus, substream,
565                                         HDAC_EXT_STREAM_TYPE_LINK);
566         if (!link_dev)
567                 return -EBUSY;
568 
569         snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
570 
571         link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name);
572         if (!link)
573                 return -EINVAL;
574 
575         stream_tag = hdac_stream(link_dev)->stream_tag;
576 
577         /* set the stream tag in the codec dai dma params  */
578         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
579                 snd_soc_dai_set_tdm_slot(codec_dai, stream_tag, 0, 0, 0);
580         else
581                 snd_soc_dai_set_tdm_slot(codec_dai, 0, stream_tag, 0, 0);
582 
583         p_params.s_fmt = snd_pcm_format_width(params_format(params));
584         p_params.ch = params_channels(params);
585         p_params.s_freq = params_rate(params);
586         p_params.stream = substream->stream;
587         p_params.link_dma_id = stream_tag - 1;
588         p_params.link_index = link->index;
589         p_params.format = params_format(params);
590 
591         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
592                 p_params.link_bps = codec_dai->driver->playback.sig_bits;
593         else
594                 p_params.link_bps = codec_dai->driver->capture.sig_bits;
595 
596         return skl_tplg_be_update_params(dai, &p_params);
597 }
598 
599 static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
600                 struct snd_soc_dai *dai)
601 {
602         struct skl *skl = get_skl_ctx(dai->dev);
603         struct skl_module_cfg *mconfig = NULL;
604 
605         /* In case of XRUN recovery, reset the FW pipe to clean state */
606         mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
607         if (mconfig && !mconfig->pipe->passthru &&
608                 (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN))
609                 skl_reset_pipe(skl->skl_sst, mconfig->pipe);
610 
611         return 0;
612 }
613 
614 static int skl_link_pcm_trigger(struct snd_pcm_substream *substream,
615         int cmd, struct snd_soc_dai *dai)
616 {
617         struct hdac_ext_stream *link_dev =
618                                 snd_soc_dai_get_dma_data(dai, substream);
619         struct hdac_bus *bus = get_bus_ctx(substream);
620         struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
621 
622         dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd);
623         switch (cmd) {
624         case SNDRV_PCM_TRIGGER_RESUME:
625         case SNDRV_PCM_TRIGGER_START:
626         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
627                 snd_hdac_ext_link_stream_start(link_dev);
628                 break;
629 
630         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
631         case SNDRV_PCM_TRIGGER_SUSPEND:
632         case SNDRV_PCM_TRIGGER_STOP:
633                 snd_hdac_ext_link_stream_clear(link_dev);
634                 if (cmd == SNDRV_PCM_TRIGGER_SUSPEND)
635                         snd_hdac_ext_stream_decouple(bus, stream, false);
636                 break;
637 
638         default:
639                 return -EINVAL;
640         }
641         return 0;
642 }
643 
644 static int skl_link_hw_free(struct snd_pcm_substream *substream,
645                 struct snd_soc_dai *dai)
646 {
647         struct hdac_bus *bus = dev_get_drvdata(dai->dev);
648         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
649         struct hdac_ext_stream *link_dev =
650                                 snd_soc_dai_get_dma_data(dai, substream);
651         struct hdac_ext_link *link;
652         unsigned char stream_tag;
653 
654         dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
655 
656         link_dev->link_prepared = 0;
657 
658         link = snd_hdac_ext_bus_get_link(bus, rtd->codec_dai->component->name);
659         if (!link)
660                 return -EINVAL;
661 
662         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
663                 stream_tag = hdac_stream(link_dev)->stream_tag;
664                 snd_hdac_ext_link_clear_stream_id(link, stream_tag);
665         }
666 
667         snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK);
668         return 0;
669 }
670 
671 static const struct snd_soc_dai_ops skl_pcm_dai_ops = {
672         .startup = skl_pcm_open,
673         .shutdown = skl_pcm_close,
674         .prepare = skl_pcm_prepare,
675         .hw_params = skl_pcm_hw_params,
676         .hw_free = skl_pcm_hw_free,
677         .trigger = skl_pcm_trigger,
678 };
679 
680 static const struct snd_soc_dai_ops skl_dmic_dai_ops = {
681         .hw_params = skl_be_hw_params,
682 };
683 
684 static const struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
685         .hw_params = skl_be_hw_params,
686 };
687 
688 static const struct snd_soc_dai_ops skl_link_dai_ops = {
689         .prepare = skl_link_pcm_prepare,
690         .hw_params = skl_link_hw_params,
691         .hw_free = skl_link_hw_free,
692         .trigger = skl_link_pcm_trigger,
693 };
694 
695 static struct snd_soc_dai_driver skl_fe_dai[] = {
696 {
697         .name = "System Pin",
698         .ops = &skl_pcm_dai_ops,
699         .playback = {
700                 .stream_name = "System Playback",
701                 .channels_min = HDA_MONO,
702                 .channels_max = HDA_STEREO,
703                 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000,
704                 .formats = SNDRV_PCM_FMTBIT_S16_LE |
705                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
706                 .sig_bits = 32,
707         },
708         .capture = {
709                 .stream_name = "System Capture",
710                 .channels_min = HDA_MONO,
711                 .channels_max = HDA_STEREO,
712                 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
713                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
714                 .sig_bits = 32,
715         },
716 },
717 {
718         .name = "System Pin2",
719         .ops = &skl_pcm_dai_ops,
720         .playback = {
721                 .stream_name = "Headset Playback",
722                 .channels_min = HDA_MONO,
723                 .channels_max = HDA_STEREO,
724                 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
725                         SNDRV_PCM_RATE_8000,
726                 .formats = SNDRV_PCM_FMTBIT_S16_LE |
727                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
728         },
729 },
730 {
731         .name = "Echoref Pin",
732         .ops = &skl_pcm_dai_ops,
733         .capture = {
734                 .stream_name = "Echoreference Capture",
735                 .channels_min = HDA_STEREO,
736                 .channels_max = HDA_STEREO,
737                 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
738                         SNDRV_PCM_RATE_8000,
739                 .formats = SNDRV_PCM_FMTBIT_S16_LE |
740                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
741         },
742 },
743 {
744         .name = "Reference Pin",
745         .ops = &skl_pcm_dai_ops,
746         .capture = {
747                 .stream_name = "Reference Capture",
748                 .channels_min = HDA_MONO,
749                 .channels_max = HDA_QUAD,
750                 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
751                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
752                 .sig_bits = 32,
753         },
754 },
755 {
756         .name = "Deepbuffer Pin",
757         .ops = &skl_pcm_dai_ops,
758         .playback = {
759                 .stream_name = "Deepbuffer Playback",
760                 .channels_min = HDA_STEREO,
761                 .channels_max = HDA_STEREO,
762                 .rates = SNDRV_PCM_RATE_48000,
763                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
764                 .sig_bits = 32,
765         },
766 },
767 {
768         .name = "LowLatency Pin",
769         .ops = &skl_pcm_dai_ops,
770         .playback = {
771                 .stream_name = "Low Latency Playback",
772                 .channels_min = HDA_STEREO,
773                 .channels_max = HDA_STEREO,
774                 .rates = SNDRV_PCM_RATE_48000,
775                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
776                 .sig_bits = 32,
777         },
778 },
779 {
780         .name = "DMIC Pin",
781         .ops = &skl_pcm_dai_ops,
782         .capture = {
783                 .stream_name = "DMIC Capture",
784                 .channels_min = HDA_MONO,
785                 .channels_max = HDA_QUAD,
786                 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
787                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
788                 .sig_bits = 32,
789         },
790 },
791 {
792         .name = "HDMI1 Pin",
793         .ops = &skl_pcm_dai_ops,
794         .playback = {
795                 .stream_name = "HDMI1 Playback",
796                 .channels_min = HDA_STEREO,
797                 .channels_max = 8,
798                 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
799                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
800                         SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
801                         SNDRV_PCM_RATE_192000,
802                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
803                         SNDRV_PCM_FMTBIT_S32_LE,
804                 .sig_bits = 32,
805         },
806 },
807 {
808         .name = "HDMI2 Pin",
809         .ops = &skl_pcm_dai_ops,
810         .playback = {
811                 .stream_name = "HDMI2 Playback",
812                 .channels_min = HDA_STEREO,
813                 .channels_max = 8,
814                 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
815                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
816                         SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
817                         SNDRV_PCM_RATE_192000,
818                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
819                         SNDRV_PCM_FMTBIT_S32_LE,
820                 .sig_bits = 32,
821         },
822 },
823 {
824         .name = "HDMI3 Pin",
825         .ops = &skl_pcm_dai_ops,
826         .playback = {
827                 .stream_name = "HDMI3 Playback",
828                 .channels_min = HDA_STEREO,
829                 .channels_max = 8,
830                 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
831                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
832                         SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
833                         SNDRV_PCM_RATE_192000,
834                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
835                         SNDRV_PCM_FMTBIT_S32_LE,
836                 .sig_bits = 32,
837         },
838 },
839 };
840 
841 /* BE CPU  Dais */
842 static struct snd_soc_dai_driver skl_platform_dai[] = {
843 {
844         .name = "SSP0 Pin",
845         .ops = &skl_be_ssp_dai_ops,
846         .playback = {
847                 .stream_name = "ssp0 Tx",
848                 .channels_min = HDA_STEREO,
849                 .channels_max = HDA_STEREO,
850                 .rates = SNDRV_PCM_RATE_48000,
851                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
852         },
853         .capture = {
854                 .stream_name = "ssp0 Rx",
855                 .channels_min = HDA_STEREO,
856                 .channels_max = HDA_STEREO,
857                 .rates = SNDRV_PCM_RATE_48000,
858                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
859         },
860 },
861 {
862         .name = "SSP1 Pin",
863         .ops = &skl_be_ssp_dai_ops,
864         .playback = {
865                 .stream_name = "ssp1 Tx",
866                 .channels_min = HDA_STEREO,
867                 .channels_max = HDA_STEREO,
868                 .rates = SNDRV_PCM_RATE_48000,
869                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
870         },
871         .capture = {
872                 .stream_name = "ssp1 Rx",
873                 .channels_min = HDA_STEREO,
874                 .channels_max = HDA_STEREO,
875                 .rates = SNDRV_PCM_RATE_48000,
876                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
877         },
878 },
879 {
880         .name = "SSP2 Pin",
881         .ops = &skl_be_ssp_dai_ops,
882         .playback = {
883                 .stream_name = "ssp2 Tx",
884                 .channels_min = HDA_STEREO,
885                 .channels_max = HDA_STEREO,
886                 .rates = SNDRV_PCM_RATE_48000,
887                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
888         },
889         .capture = {
890                 .stream_name = "ssp2 Rx",
891                 .channels_min = HDA_STEREO,
892                 .channels_max = HDA_STEREO,
893                 .rates = SNDRV_PCM_RATE_48000,
894                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
895         },
896 },
897 {
898         .name = "SSP3 Pin",
899         .ops = &skl_be_ssp_dai_ops,
900         .playback = {
901                 .stream_name = "ssp3 Tx",
902                 .channels_min = HDA_STEREO,
903                 .channels_max = HDA_STEREO,
904                 .rates = SNDRV_PCM_RATE_48000,
905                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
906         },
907         .capture = {
908                 .stream_name = "ssp3 Rx",
909                 .channels_min = HDA_STEREO,
910                 .channels_max = HDA_STEREO,
911                 .rates = SNDRV_PCM_RATE_48000,
912                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
913         },
914 },
915 {
916         .name = "SSP4 Pin",
917         .ops = &skl_be_ssp_dai_ops,
918         .playback = {
919                 .stream_name = "ssp4 Tx",
920                 .channels_min = HDA_STEREO,
921                 .channels_max = HDA_STEREO,
922                 .rates = SNDRV_PCM_RATE_48000,
923                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
924         },
925         .capture = {
926                 .stream_name = "ssp4 Rx",
927                 .channels_min = HDA_STEREO,
928                 .channels_max = HDA_STEREO,
929                 .rates = SNDRV_PCM_RATE_48000,
930                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
931         },
932 },
933 {
934         .name = "SSP5 Pin",
935         .ops = &skl_be_ssp_dai_ops,
936         .playback = {
937                 .stream_name = "ssp5 Tx",
938                 .channels_min = HDA_STEREO,
939                 .channels_max = HDA_STEREO,
940                 .rates = SNDRV_PCM_RATE_48000,
941                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
942         },
943         .capture = {
944                 .stream_name = "ssp5 Rx",
945                 .channels_min = HDA_STEREO,
946                 .channels_max = HDA_STEREO,
947                 .rates = SNDRV_PCM_RATE_48000,
948                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
949         },
950 },
951 {
952         .name = "iDisp1 Pin",
953         .ops = &skl_link_dai_ops,
954         .playback = {
955                 .stream_name = "iDisp1 Tx",
956                 .channels_min = HDA_STEREO,
957                 .channels_max = 8,
958                 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000,
959                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
960                         SNDRV_PCM_FMTBIT_S24_LE,
961         },
962 },
963 {
964         .name = "iDisp2 Pin",
965         .ops = &skl_link_dai_ops,
966         .playback = {
967                 .stream_name = "iDisp2 Tx",
968                 .channels_min = HDA_STEREO,
969                 .channels_max = 8,
970                 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
971                         SNDRV_PCM_RATE_48000,
972                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
973                         SNDRV_PCM_FMTBIT_S24_LE,
974         },
975 },
976 {
977         .name = "iDisp3 Pin",
978         .ops = &skl_link_dai_ops,
979         .playback = {
980                 .stream_name = "iDisp3 Tx",
981                 .channels_min = HDA_STEREO,
982                 .channels_max = 8,
983                 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
984                         SNDRV_PCM_RATE_48000,
985                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
986                         SNDRV_PCM_FMTBIT_S24_LE,
987         },
988 },
989 {
990         .name = "DMIC01 Pin",
991         .ops = &skl_dmic_dai_ops,
992         .capture = {
993                 .stream_name = "DMIC01 Rx",
994                 .channels_min = HDA_MONO,
995                 .channels_max = HDA_QUAD,
996                 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
997                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
998         },
999 },
1000 {
1001         .name = "DMIC16k Pin",
1002         .ops = &skl_dmic_dai_ops,
1003         .capture = {
1004                 .stream_name = "DMIC16k Rx",
1005                 .channels_min = HDA_MONO,
1006                 .channels_max = HDA_QUAD,
1007                 .rates = SNDRV_PCM_RATE_16000,
1008                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1009         },
1010 },
1011 {
1012         .name = "Analog CPU DAI",
1013         .ops = &skl_link_dai_ops,
1014         .playback = {
1015                 .stream_name = "Analog CPU Playback",
1016                 .channels_min = HDA_MONO,
1017                 .channels_max = HDA_MAX,
1018                 .rates = SNDRV_PCM_RATE_8000_192000,
1019                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
1020                         SNDRV_PCM_FMTBIT_S32_LE,
1021         },
1022         .capture = {
1023                 .stream_name = "Analog CPU Capture",
1024                 .channels_min = HDA_MONO,
1025                 .channels_max = HDA_MAX,
1026                 .rates = SNDRV_PCM_RATE_8000_192000,
1027                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
1028                         SNDRV_PCM_FMTBIT_S32_LE,
1029         },
1030 },
1031 {
1032         .name = "Alt Analog CPU DAI",
1033         .ops = &skl_link_dai_ops,
1034         .playback = {
1035                 .stream_name = "Alt Analog CPU Playback",
1036                 .channels_min = HDA_MONO,
1037                 .channels_max = HDA_MAX,
1038                 .rates = SNDRV_PCM_RATE_8000_192000,
1039                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
1040                         SNDRV_PCM_FMTBIT_S32_LE,
1041         },
1042         .capture = {
1043                 .stream_name = "Alt Analog CPU Capture",
1044                 .channels_min = HDA_MONO,
1045                 .channels_max = HDA_MAX,
1046                 .rates = SNDRV_PCM_RATE_8000_192000,
1047                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
1048                         SNDRV_PCM_FMTBIT_S32_LE,
1049         },
1050 },
1051 {
1052         .name = "Digital CPU DAI",
1053         .ops = &skl_link_dai_ops,
1054         .playback = {
1055                 .stream_name = "Digital CPU Playback",
1056                 .channels_min = HDA_MONO,
1057                 .channels_max = HDA_MAX,
1058                 .rates = SNDRV_PCM_RATE_8000_192000,
1059                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
1060                         SNDRV_PCM_FMTBIT_S32_LE,
1061         },
1062         .capture = {
1063                 .stream_name = "Digital CPU Capture",
1064                 .channels_min = HDA_MONO,
1065                 .channels_max = HDA_MAX,
1066                 .rates = SNDRV_PCM_RATE_8000_192000,
1067                 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
1068                         SNDRV_PCM_FMTBIT_S32_LE,
1069         },
1070 },
1071 };
1072 
1073 int skl_dai_load(struct snd_soc_component *cmp, int index,
1074                         struct snd_soc_dai_driver *dai_drv,
1075                         struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai)
1076 {
1077         dai_drv->ops = &skl_pcm_dai_ops;
1078 
1079         return 0;
1080 }
1081 
1082 static int skl_platform_open(struct snd_pcm_substream *substream)
1083 {
1084         struct snd_soc_pcm_runtime *rtd = substream->private_data;
1085         struct snd_soc_dai_link *dai_link = rtd->dai_link;
1086 
1087         dev_dbg(rtd->cpu_dai->dev, "In %s:%s\n", __func__,
1088                                         dai_link->cpu_dai_name);
1089 
1090         snd_soc_set_runtime_hwparams(substream, &azx_pcm_hw);
1091 
1092         return 0;
1093 }
1094 
1095 static int skl_coupled_trigger(struct snd_pcm_substream *substream,
1096                                         int cmd)
1097 {
1098         struct hdac_bus *bus = get_bus_ctx(substream);
1099         struct hdac_ext_stream *stream;
1100         struct snd_pcm_substream *s;
1101         bool start;
1102         int sbits = 0;
1103         unsigned long cookie;
1104         struct hdac_stream *hstr;
1105 
1106         stream = get_hdac_ext_stream(substream);
1107         hstr = hdac_stream(stream);
1108 
1109         dev_dbg(bus->dev, "In %s cmd=%d\n", __func__, cmd);
1110 
1111         if (!hstr->prepared)
1112                 return -EPIPE;
1113 
1114         switch (cmd) {
1115         case SNDRV_PCM_TRIGGER_START:
1116         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1117         case SNDRV_PCM_TRIGGER_RESUME:
1118                 start = true;
1119                 break;
1120 
1121         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1122         case SNDRV_PCM_TRIGGER_SUSPEND:
1123         case SNDRV_PCM_TRIGGER_STOP:
1124                 start = false;
1125                 break;
1126 
1127         default:
1128                 return -EINVAL;
1129         }
1130 
1131         snd_pcm_group_for_each_entry(s, substream) {
1132                 if (s->pcm->card != substream->pcm->card)
1133                         continue;
1134                 stream = get_hdac_ext_stream(s);
1135                 sbits |= 1 << hdac_stream(stream)->index;
1136                 snd_pcm_trigger_done(s, substream);
1137         }
1138 
1139         spin_lock_irqsave(&bus->reg_lock, cookie);
1140 
1141         /* first, set SYNC bits of corresponding streams */
1142         snd_hdac_stream_sync_trigger(hstr, true, sbits, AZX_REG_SSYNC);
1143 
1144         snd_pcm_group_for_each_entry(s, substream) {
1145                 if (s->pcm->card != substream->pcm->card)
1146                         continue;
1147                 stream = get_hdac_ext_stream(s);
1148                 if (start)
1149                         snd_hdac_stream_start(hdac_stream(stream), true);
1150                 else
1151                         snd_hdac_stream_stop(hdac_stream(stream));
1152         }
1153         spin_unlock_irqrestore(&bus->reg_lock, cookie);
1154 
1155         snd_hdac_stream_sync(hstr, start, sbits);
1156 
1157         spin_lock_irqsave(&bus->reg_lock, cookie);
1158 
1159         /* reset SYNC bits */
1160         snd_hdac_stream_sync_trigger(hstr, false, sbits, AZX_REG_SSYNC);
1161         if (start)
1162                 snd_hdac_stream_timecounter_init(hstr, sbits);
1163         spin_unlock_irqrestore(&bus->reg_lock, cookie);
1164 
1165         return 0;
1166 }
1167 
1168 static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
1169                                         int cmd)
1170 {
1171         struct hdac_bus *bus = get_bus_ctx(substream);
1172 
1173         if (!bus->ppcap)
1174                 return skl_coupled_trigger(substream, cmd);
1175 
1176         return 0;
1177 }
1178 
1179 static snd_pcm_uframes_t skl_platform_pcm_pointer
1180                         (struct snd_pcm_substream *substream)
1181 {
1182         struct hdac_ext_stream *hstream = get_hdac_ext_stream(substream);
1183         struct hdac_bus *bus = get_bus_ctx(substream);
1184         unsigned int pos;
1185 
1186         /*
1187          * Use DPIB for Playback stream as the periodic DMA Position-in-
1188          * Buffer Writes may be scheduled at the same time or later than
1189          * the MSI and does not guarantee to reflect the Position of the
1190          * last buffer that was transferred. Whereas DPIB register in
1191          * HAD space reflects the actual data that is transferred.
1192          * Use the position buffer for capture, as DPIB write gets
1193          * completed earlier than the actual data written to the DDR.
1194          *
1195          * For capture stream following workaround is required to fix the
1196          * incorrect position reporting.
1197          *
1198          * 1. Wait for 20us before reading the DMA position in buffer once
1199          * the interrupt is generated for stream completion as update happens
1200          * on the HDA frame boundary i.e. 20.833uSec.
1201          * 2. Read DPIB register to flush the DMA position value. This dummy
1202          * read is required to flush DMA position value.
1203          * 3. Read the DMA Position-in-Buffer. This value now will be equal to
1204          * or greater than period boundary.
1205          */
1206 
1207         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1208                 pos = readl(bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1209                                 (AZX_REG_VS_SDXDPIB_XINTERVAL *
1210                                 hdac_stream(hstream)->index));
1211         } else {
1212                 udelay(20);
1213                 readl(bus->remap_addr +
1214                                 AZX_REG_VS_SDXDPIB_XBASE +
1215                                 (AZX_REG_VS_SDXDPIB_XINTERVAL *
1216                                  hdac_stream(hstream)->index));
1217                 pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream));
1218         }
1219 
1220         if (pos >= hdac_stream(hstream)->bufsize)
1221                 pos = 0;
1222 
1223         return bytes_to_frames(substream->runtime, pos);
1224 }
1225 
1226 static u64 skl_adjust_codec_delay(struct snd_pcm_substream *substream,
1227                                 u64 nsec)
1228 {
1229         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1230         struct snd_soc_dai *codec_dai = rtd->codec_dai;
1231         u64 codec_frames, codec_nsecs;
1232 
1233         if (!codec_dai->driver->ops->delay)
1234                 return nsec;
1235 
1236         codec_frames = codec_dai->driver->ops->delay(substream, codec_dai);
1237         codec_nsecs = div_u64(codec_frames * 1000000000LL,
1238                               substream->runtime->rate);
1239 
1240         if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
1241                 return nsec + codec_nsecs;
1242 
1243         return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0;
1244 }
1245 
1246 static int skl_get_time_info(struct snd_pcm_substream *substream,
1247                         struct timespec *system_ts, struct timespec *audio_ts,
1248                         struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
1249                         struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
1250 {
1251         struct hdac_ext_stream *sstream = get_hdac_ext_stream(substream);
1252         struct hdac_stream *hstr = hdac_stream(sstream);
1253         u64 nsec;
1254 
1255         if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) &&
1256                 (audio_tstamp_config->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK)) {
1257 
1258                 snd_pcm_gettime(substream->runtime, system_ts);
1259 
1260                 nsec = timecounter_read(&hstr->tc);
1261                 nsec = div_u64(nsec, 3); /* can be optimized */
1262                 if (audio_tstamp_config->report_delay)
1263                         nsec = skl_adjust_codec_delay(substream, nsec);
1264 
1265                 *audio_ts = ns_to_timespec(nsec);
1266 
1267                 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK;
1268                 audio_tstamp_report->accuracy_report = 1; /* rest of struct is valid */
1269                 audio_tstamp_report->accuracy = 42; /* 24MHzWallClk == 42ns resolution */
1270 
1271         } else {
1272                 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
1273         }
1274 
1275         return 0;
1276 }
1277 
1278 static const struct snd_pcm_ops skl_platform_ops = {
1279         .open = skl_platform_open,
1280         .ioctl = snd_pcm_lib_ioctl,
1281         .trigger = skl_platform_pcm_trigger,
1282         .pointer = skl_platform_pcm_pointer,
1283         .get_time_info =  skl_get_time_info,
1284         .mmap = snd_pcm_lib_default_mmap,
1285         .page = snd_pcm_sgbuf_ops_page,
1286 };
1287 
1288 static void skl_pcm_free(struct snd_pcm *pcm)
1289 {
1290         snd_pcm_lib_preallocate_free_for_all(pcm);
1291 }
1292 
1293 #define MAX_PREALLOC_SIZE       (32 * 1024 * 1024)
1294 
1295 static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1296 {
1297         struct snd_soc_dai *dai = rtd->cpu_dai;
1298         struct hdac_bus *bus = dev_get_drvdata(dai->dev);
1299         struct snd_pcm *pcm = rtd->pcm;
1300         unsigned int size;
1301         struct skl *skl = bus_to_skl(bus);
1302 
1303         if (dai->driver->playback.channels_min ||
1304                 dai->driver->capture.channels_min) {
1305                 /* buffer pre-allocation */
1306                 size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
1307                 if (size > MAX_PREALLOC_SIZE)
1308                         size = MAX_PREALLOC_SIZE;
1309                 snd_pcm_lib_preallocate_pages_for_all(pcm,
1310                                                 SNDRV_DMA_TYPE_DEV_SG,
1311                                                 snd_dma_pci_data(skl->pci),
1312                                                 size, MAX_PREALLOC_SIZE);
1313         }
1314 
1315         return 0;
1316 }
1317 
1318 static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
1319 {
1320         struct skl_sst *ctx = skl->skl_sst;
1321         struct skl_module_inst_id *pin_id;
1322         uuid_le *uuid_mod, *uuid_tplg;
1323         struct skl_module *skl_module;
1324         struct uuid_module *module;
1325         int i, ret = -EIO;
1326 
1327         uuid_mod = (uuid_le *)mconfig->guid;
1328 
1329         if (list_empty(&ctx->uuid_list)) {
1330                 dev_err(ctx->dev, "Module list is empty\n");
1331                 return -EIO;
1332         }
1333 
1334         list_for_each_entry(module, &ctx->uuid_list, list) {
1335                 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
1336                         mconfig->id.module_id = module->id;
1337                         if (mconfig->module)
1338                                 mconfig->module->loadable = module->is_loadable;
1339                         ret = 0;
1340                         break;
1341                 }
1342         }
1343 
1344         if (ret)
1345                 return ret;
1346 
1347         uuid_mod = &module->uuid;
1348         ret = -EIO;
1349         for (i = 0; i < skl->nr_modules; i++) {
1350                 skl_module = skl->modules[i];
1351                 uuid_tplg = &skl_module->uuid;
1352                 if (!uuid_le_cmp(*uuid_mod, *uuid_tplg)) {
1353                         mconfig->module = skl_module;
1354                         ret = 0;
1355                         break;
1356                 }
1357         }
1358         if (skl->nr_modules && ret)
1359                 return ret;
1360 
1361         list_for_each_entry(module, &ctx->uuid_list, list) {
1362                 for (i = 0; i < MAX_IN_QUEUE; i++) {
1363                         pin_id = &mconfig->m_in_pin[i].id;
1364                         if (!uuid_le_cmp(pin_id->mod_uuid, module->uuid))
1365                                 pin_id->module_id = module->id;
1366                 }
1367 
1368                 for (i = 0; i < MAX_OUT_QUEUE; i++) {
1369                         pin_id = &mconfig->m_out_pin[i].id;
1370                         if (!uuid_le_cmp(pin_id->mod_uuid, module->uuid))
1371                                 pin_id->module_id = module->id;
1372                 }
1373         }
1374 
1375         return 0;
1376 }
1377 
1378 static int skl_populate_modules(struct skl *skl)
1379 {
1380         struct skl_pipeline *p;
1381         struct skl_pipe_module *m;
1382         struct snd_soc_dapm_widget *w;
1383         struct skl_module_cfg *mconfig;
1384         int ret = 0;
1385 
1386         list_for_each_entry(p, &skl->ppl_list, node) {
1387                 list_for_each_entry(m, &p->pipe->w_list, node) {
1388                         w = m->w;
1389                         mconfig = w->priv;
1390 
1391                         ret = skl_get_module_info(skl, mconfig);
1392                         if (ret < 0) {
1393                                 dev_err(skl->skl_sst->dev,
1394                                         "query module info failed\n");
1395                                 return ret;
1396                         }
1397 
1398                         skl_tplg_add_moduleid_in_bind_params(skl, w);
1399                 }
1400         }
1401 
1402         return ret;
1403 }
1404 
1405 static int skl_platform_soc_probe(struct snd_soc_component *component)
1406 {
1407         struct hdac_bus *bus = dev_get_drvdata(component->dev);
1408         struct skl *skl = bus_to_skl(bus);
1409         const struct skl_dsp_ops *ops;
1410         int ret;
1411 
1412         pm_runtime_get_sync(component->dev);
1413         if (bus->ppcap) {
1414                 skl->component = component;
1415 
1416                 /* init debugfs */
1417                 skl->debugfs = skl_debugfs_init(skl);
1418 
1419                 ret = skl_tplg_init(component, bus);
1420                 if (ret < 0) {
1421                         dev_err(component->dev, "Failed to init topology!\n");
1422                         return ret;
1423                 }
1424 
1425                 /* load the firmwares, since all is set */
1426                 ops = skl_get_dsp_ops(skl->pci->device);
1427                 if (!ops)
1428                         return -EIO;
1429 
1430                 if (!skl->skl_sst->is_first_boot) {
1431                         dev_err(component->dev, "DSP reports first boot done!!!\n");
1432                         return -EIO;
1433                 }
1434 
1435                 /*
1436                  * Disable dynamic clock and power gating during firmware
1437                  * and library download
1438                  */
1439                 skl->skl_sst->enable_miscbdcge(component->dev, false);
1440                 skl->skl_sst->clock_power_gating(component->dev, false);
1441 
1442                 ret = ops->init_fw(component->dev, skl->skl_sst);
1443                 skl->skl_sst->enable_miscbdcge(component->dev, true);
1444                 skl->skl_sst->clock_power_gating(component->dev, true);
1445                 if (ret < 0) {
1446                         dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
1447                         return ret;
1448                 }
1449                 skl_populate_modules(skl);
1450                 skl->skl_sst->update_d0i3c = skl_update_d0i3c;
1451                 skl_dsp_enable_notification(skl->skl_sst, false);
1452 
1453                 if (skl->cfg.astate_cfg != NULL) {
1454                         skl_dsp_set_astate_cfg(skl->skl_sst,
1455                                         skl->cfg.astate_cfg->count,
1456                                         skl->cfg.astate_cfg);
1457                 }
1458         }
1459         pm_runtime_mark_last_busy(component->dev);
1460         pm_runtime_put_autosuspend(component->dev);
1461 
1462         return 0;
1463 }
1464 
1465 static void skl_pcm_remove(struct snd_soc_component *component)
1466 {
1467         /* remove topology */
1468         snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL);
1469 }
1470 
1471 static const struct snd_soc_component_driver skl_component  = {
1472         .name           = "pcm",
1473         .probe          = skl_platform_soc_probe,
1474         .remove         = skl_pcm_remove,
1475         .ops            = &skl_platform_ops,
1476         .pcm_new        = skl_pcm_new,
1477         .pcm_free       = skl_pcm_free,
1478         .module_get_upon_open = 1, /* increment refcount when a pcm is opened */
1479 };
1480 
1481 int skl_platform_register(struct device *dev)
1482 {
1483         int ret;
1484         struct snd_soc_dai_driver *dais;
1485         int num_dais = ARRAY_SIZE(skl_platform_dai);
1486         struct hdac_bus *bus = dev_get_drvdata(dev);
1487         struct skl *skl = bus_to_skl(bus);
1488 
1489         INIT_LIST_HEAD(&skl->ppl_list);
1490         INIT_LIST_HEAD(&skl->bind_list);
1491 
1492         skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
1493                             GFP_KERNEL);
1494         if (!skl->dais) {
1495                 ret = -ENOMEM;
1496                 goto err;
1497         }
1498 
1499         if (!skl->use_tplg_pcm) {
1500                 dais = krealloc(skl->dais, sizeof(skl_fe_dai) +
1501                                 sizeof(skl_platform_dai), GFP_KERNEL);
1502                 if (!dais) {
1503                         ret = -ENOMEM;
1504                         goto err;
1505                 }
1506 
1507                 skl->dais = dais;
1508                 memcpy(&skl->dais[ARRAY_SIZE(skl_platform_dai)], skl_fe_dai,
1509                        sizeof(skl_fe_dai));
1510                 num_dais += ARRAY_SIZE(skl_fe_dai);
1511         }
1512 
1513         ret = devm_snd_soc_register_component(dev, &skl_component,
1514                                          skl->dais, num_dais);
1515         if (ret)
1516                 dev_err(dev, "soc component registration failed %d\n", ret);
1517 err:
1518         return ret;
1519 }
1520 
1521 int skl_platform_unregister(struct device *dev)
1522 {
1523         struct hdac_bus *bus = dev_get_drvdata(dev);
1524         struct skl *skl = bus_to_skl(bus);
1525         struct skl_module_deferred_bind *modules, *tmp;
1526 
1527         if (!list_empty(&skl->bind_list)) {
1528                 list_for_each_entry_safe(modules, tmp, &skl->bind_list, node) {
1529                         list_del(&modules->node);
1530                         kfree(modules);
1531                 }
1532         }
1533 
1534         kfree(skl->dais);
1535 
1536         return 0;
1537 }
1538 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp