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