xref: /linux/sound/soc/intel/avs/pcm.c (revision 9f2c9170934eace462499ba0bfe042cc72900173)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
4 //
5 // Authors: Cezary Rojewski <cezary.rojewski@intel.com>
6 //          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
7 //
8 
9 #include <linux/debugfs.h>
10 #include <linux/device.h>
11 #include <sound/hda_register.h>
12 #include <sound/hdaudio_ext.h>
13 #include <sound/pcm_params.h>
14 #include <sound/soc-acpi.h>
15 #include <sound/soc-acpi-intel-match.h>
16 #include <sound/soc-component.h>
17 #include "avs.h"
18 #include "path.h"
19 #include "topology.h"
20 
21 struct avs_dma_data {
22 	struct avs_tplg_path_template *template;
23 	struct avs_path *path;
24 	/*
25 	 * link stream is stored within substream's runtime
26 	 * private_data to fulfill the needs of codec BE path
27 	 *
28 	 * host stream assigned
29 	 */
30 	struct hdac_ext_stream *host_stream;
31 
32 	struct snd_pcm_substream *substream;
33 };
34 
35 static struct avs_tplg_path_template *
36 avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
37 {
38 	struct snd_soc_dapm_widget *dw;
39 	struct snd_soc_dapm_path *dp;
40 	enum snd_soc_dapm_direction dir;
41 
42 	if (direction == SNDRV_PCM_STREAM_CAPTURE) {
43 		dw = dai->capture_widget;
44 		dir = is_fe ? SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN;
45 	} else {
46 		dw = dai->playback_widget;
47 		dir = is_fe ? SND_SOC_DAPM_DIR_IN : SND_SOC_DAPM_DIR_OUT;
48 	}
49 
50 	dp = list_first_entry_or_null(&dw->edges[dir], typeof(*dp), list_node[dir]);
51 	if (!dp)
52 		return NULL;
53 
54 	/* Get the other widget, with actual path template data */
55 	dw = (dp->source == dw) ? dp->sink : dp->source;
56 
57 	return dw->priv;
58 }
59 
60 static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe,
61 			   const struct snd_soc_dai_ops *ops)
62 {
63 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
64 	struct avs_dev *adev = to_avs_dev(dai->dev);
65 	struct avs_tplg_path_template *template;
66 	struct avs_dma_data *data;
67 
68 	template = avs_dai_find_path_template(dai, is_fe, substream->stream);
69 	if (!template) {
70 		dev_err(dai->dev, "no %s path for dai %s, invalid tplg?\n",
71 			snd_pcm_stream_str(substream), dai->name);
72 		return -EINVAL;
73 	}
74 
75 	data = kzalloc(sizeof(*data), GFP_KERNEL);
76 	if (!data)
77 		return -ENOMEM;
78 
79 	data->substream = substream;
80 	data->template = template;
81 	snd_soc_dai_set_dma_data(dai, substream, data);
82 
83 	if (rtd->dai_link->ignore_suspend)
84 		adev->num_lp_paths++;
85 
86 	return 0;
87 }
88 
89 static int avs_dai_hw_params(struct snd_pcm_substream *substream,
90 			     struct snd_pcm_hw_params *fe_hw_params,
91 			     struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
92 			     int dma_id)
93 {
94 	struct avs_dma_data *data;
95 	struct avs_path *path;
96 	struct avs_dev *adev = to_avs_dev(dai->dev);
97 	int ret;
98 
99 	data = snd_soc_dai_get_dma_data(dai, substream);
100 
101 	dev_dbg(dai->dev, "%s FE hw_params str %p rtd %p",
102 		__func__, substream, substream->runtime);
103 	dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
104 		params_rate(fe_hw_params), params_channels(fe_hw_params),
105 		params_width(fe_hw_params), params_physical_width(fe_hw_params));
106 
107 	dev_dbg(dai->dev, "%s BE hw_params str %p rtd %p",
108 		__func__, substream, substream->runtime);
109 	dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
110 		params_rate(be_hw_params), params_channels(be_hw_params),
111 		params_width(be_hw_params), params_physical_width(be_hw_params));
112 
113 	path = avs_path_create(adev, dma_id, data->template, fe_hw_params, be_hw_params);
114 	if (IS_ERR(path)) {
115 		ret = PTR_ERR(path);
116 		dev_err(dai->dev, "create path failed: %d\n", ret);
117 		return ret;
118 	}
119 
120 	data->path = path;
121 	return 0;
122 }
123 
124 static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
125 				struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
126 				int dma_id)
127 {
128 	struct snd_pcm_hw_params *fe_hw_params = NULL;
129 	struct snd_soc_pcm_runtime *fe, *be;
130 	struct snd_soc_dpcm *dpcm;
131 
132 	be = asoc_substream_to_rtd(substream);
133 	for_each_dpcm_fe(be, substream->stream, dpcm) {
134 		fe = dpcm->fe;
135 		fe_hw_params = &fe->dpcm[substream->stream].hw_params;
136 	}
137 
138 	return avs_dai_hw_params(substream, fe_hw_params, be_hw_params, dai, dma_id);
139 }
140 
141 static int avs_dai_prepare(struct avs_dev *adev, struct snd_pcm_substream *substream,
142 			   struct snd_soc_dai *dai)
143 {
144 	struct avs_dma_data *data;
145 	int ret;
146 
147 	data = snd_soc_dai_get_dma_data(dai, substream);
148 	if (!data->path)
149 		return 0;
150 
151 	ret = avs_path_reset(data->path);
152 	if (ret < 0) {
153 		dev_err(dai->dev, "reset path failed: %d\n", ret);
154 		return ret;
155 	}
156 
157 	ret = avs_path_pause(data->path);
158 	if (ret < 0)
159 		dev_err(dai->dev, "pause path failed: %d\n", ret);
160 	return ret;
161 }
162 
163 static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops;
164 
165 static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
166 {
167 	return avs_dai_startup(substream, dai, false, &avs_dai_nonhda_be_ops);
168 }
169 
170 static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
171 {
172 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
173 	struct avs_dev *adev = to_avs_dev(dai->dev);
174 	struct avs_dma_data *data;
175 
176 	if (rtd->dai_link->ignore_suspend)
177 		adev->num_lp_paths--;
178 
179 	data = snd_soc_dai_get_dma_data(dai, substream);
180 
181 	snd_soc_dai_set_dma_data(dai, substream, NULL);
182 	kfree(data);
183 }
184 
185 static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
186 				       struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
187 {
188 	struct avs_dma_data *data;
189 
190 	data = snd_soc_dai_get_dma_data(dai, substream);
191 	if (data->path)
192 		return 0;
193 
194 	/* Actual port-id comes from topology. */
195 	return avs_dai_be_hw_params(substream, hw_params, dai, 0);
196 }
197 
198 static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
199 {
200 	struct avs_dma_data *data;
201 
202 	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
203 
204 	data = snd_soc_dai_get_dma_data(dai, substream);
205 	if (data->path) {
206 		avs_path_free(data->path);
207 		data->path = NULL;
208 	}
209 
210 	return 0;
211 }
212 
213 static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
214 {
215 	return avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
216 }
217 
218 static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
219 				     struct snd_soc_dai *dai)
220 {
221 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
222 	struct avs_dma_data *data;
223 	int ret = 0;
224 
225 	data = snd_soc_dai_get_dma_data(dai, substream);
226 
227 	switch (cmd) {
228 	case SNDRV_PCM_TRIGGER_RESUME:
229 		if (rtd->dai_link->ignore_suspend)
230 			break;
231 		fallthrough;
232 	case SNDRV_PCM_TRIGGER_START:
233 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
234 		ret = avs_path_pause(data->path);
235 		if (ret < 0) {
236 			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
237 			break;
238 		}
239 
240 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
241 		if (ret < 0)
242 			dev_err(dai->dev, "run BE path failed: %d\n", ret);
243 		break;
244 
245 	case SNDRV_PCM_TRIGGER_SUSPEND:
246 		if (rtd->dai_link->ignore_suspend)
247 			break;
248 		fallthrough;
249 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
250 	case SNDRV_PCM_TRIGGER_STOP:
251 		ret = avs_path_pause(data->path);
252 		if (ret < 0)
253 			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
254 
255 		ret = avs_path_reset(data->path);
256 		if (ret < 0)
257 			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
258 		break;
259 
260 	default:
261 		ret = -EINVAL;
262 		break;
263 	}
264 
265 	return ret;
266 }
267 
268 static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
269 	.startup = avs_dai_nonhda_be_startup,
270 	.shutdown = avs_dai_nonhda_be_shutdown,
271 	.hw_params = avs_dai_nonhda_be_hw_params,
272 	.hw_free = avs_dai_nonhda_be_hw_free,
273 	.prepare = avs_dai_nonhda_be_prepare,
274 	.trigger = avs_dai_nonhda_be_trigger,
275 };
276 
277 static const struct snd_soc_dai_ops avs_dai_hda_be_ops;
278 
279 static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
280 {
281 	return avs_dai_startup(substream, dai, false, &avs_dai_hda_be_ops);
282 }
283 
284 static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
285 {
286 	return avs_dai_nonhda_be_shutdown(substream, dai);
287 }
288 
289 static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
290 				    struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
291 {
292 	struct avs_dma_data *data;
293 	struct hdac_ext_stream *link_stream;
294 
295 	data = snd_soc_dai_get_dma_data(dai, substream);
296 	if (data->path)
297 		return 0;
298 
299 	link_stream = substream->runtime->private_data;
300 
301 	return avs_dai_be_hw_params(substream, hw_params, dai,
302 				    hdac_stream(link_stream)->stream_tag - 1);
303 }
304 
305 static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
306 {
307 	struct avs_dma_data *data;
308 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
309 	struct hdac_ext_stream *link_stream;
310 	struct hdac_ext_link *link;
311 	struct hda_codec *codec;
312 
313 	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
314 
315 	data = snd_soc_dai_get_dma_data(dai, substream);
316 	if (!data->path)
317 		return 0;
318 
319 	link_stream = substream->runtime->private_data;
320 	link_stream->link_prepared = false;
321 	avs_path_free(data->path);
322 	data->path = NULL;
323 
324 	/* clear link <-> stream mapping */
325 	codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
326 	link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
327 	if (!link)
328 		return -EINVAL;
329 
330 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
331 		snd_hdac_ext_bus_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag);
332 
333 	return 0;
334 }
335 
336 static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
337 {
338 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
339 	struct snd_pcm_runtime *runtime = substream->runtime;
340 	struct hdac_ext_stream *link_stream = runtime->private_data;
341 	struct hdac_ext_link *link;
342 	struct hda_codec *codec;
343 	struct hdac_bus *bus;
344 	unsigned int format_val;
345 	int ret;
346 
347 	if (link_stream->link_prepared)
348 		return 0;
349 
350 	codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
351 	bus = &codec->bus->core;
352 	format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
353 						 runtime->sample_bits, 0);
354 
355 	snd_hdac_ext_stream_decouple(bus, link_stream, true);
356 	snd_hdac_ext_stream_reset(link_stream);
357 	snd_hdac_ext_stream_setup(link_stream, format_val);
358 
359 	link = snd_hdac_ext_bus_get_hlink_by_addr(bus, codec->core.addr);
360 	if (!link)
361 		return -EINVAL;
362 
363 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
364 		snd_hdac_ext_bus_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag);
365 
366 	ret = avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
367 	if (ret)
368 		return ret;
369 
370 	link_stream->link_prepared = true;
371 	return 0;
372 }
373 
374 static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
375 				  struct snd_soc_dai *dai)
376 {
377 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
378 	struct hdac_ext_stream *link_stream;
379 	struct avs_dma_data *data;
380 	int ret = 0;
381 
382 	dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd);
383 
384 	data = snd_soc_dai_get_dma_data(dai, substream);
385 	link_stream = substream->runtime->private_data;
386 
387 	switch (cmd) {
388 	case SNDRV_PCM_TRIGGER_RESUME:
389 		if (rtd->dai_link->ignore_suspend)
390 			break;
391 		fallthrough;
392 	case SNDRV_PCM_TRIGGER_START:
393 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
394 		snd_hdac_ext_stream_start(link_stream);
395 
396 		ret = avs_path_pause(data->path);
397 		if (ret < 0) {
398 			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
399 			break;
400 		}
401 
402 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
403 		if (ret < 0)
404 			dev_err(dai->dev, "run BE path failed: %d\n", ret);
405 		break;
406 
407 	case SNDRV_PCM_TRIGGER_SUSPEND:
408 		if (rtd->dai_link->ignore_suspend)
409 			break;
410 		fallthrough;
411 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
412 	case SNDRV_PCM_TRIGGER_STOP:
413 		ret = avs_path_pause(data->path);
414 		if (ret < 0)
415 			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
416 
417 		snd_hdac_ext_stream_clear(link_stream);
418 
419 		ret = avs_path_reset(data->path);
420 		if (ret < 0)
421 			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
422 		break;
423 
424 	default:
425 		ret = -EINVAL;
426 		break;
427 	}
428 
429 	return ret;
430 }
431 
432 static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
433 	.startup = avs_dai_hda_be_startup,
434 	.shutdown = avs_dai_hda_be_shutdown,
435 	.hw_params = avs_dai_hda_be_hw_params,
436 	.hw_free = avs_dai_hda_be_hw_free,
437 	.prepare = avs_dai_hda_be_prepare,
438 	.trigger = avs_dai_hda_be_trigger,
439 };
440 
441 static const unsigned int rates[] = {
442 	8000, 11025, 12000, 16000,
443 	22050, 24000, 32000, 44100,
444 	48000, 64000, 88200, 96000,
445 	128000, 176400, 192000,
446 };
447 
448 static const struct snd_pcm_hw_constraint_list hw_rates = {
449 	.count = ARRAY_SIZE(rates),
450 	.list = rates,
451 	.mask = 0,
452 };
453 
454 const struct snd_soc_dai_ops avs_dai_fe_ops;
455 
456 static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
457 {
458 	struct snd_pcm_runtime *runtime = substream->runtime;
459 	struct avs_dma_data *data;
460 	struct avs_dev *adev = to_avs_dev(dai->dev);
461 	struct hdac_bus *bus = &adev->base.core;
462 	struct hdac_ext_stream *host_stream;
463 	int ret;
464 
465 	ret = avs_dai_startup(substream, dai, true, &avs_dai_fe_ops);
466 	if (ret)
467 		return ret;
468 
469 	data = snd_soc_dai_get_dma_data(dai, substream);
470 
471 	host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST);
472 	if (!host_stream) {
473 		kfree(data);
474 		return -EBUSY;
475 	}
476 
477 	data->host_stream = host_stream;
478 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
479 	/* avoid wrap-around with wall-clock */
480 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
481 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_rates);
482 	snd_pcm_set_sync(substream);
483 
484 	dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p",
485 		__func__, hdac_stream(host_stream)->stream_tag, substream);
486 
487 	return 0;
488 }
489 
490 static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
491 {
492 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
493 	struct avs_dev *adev = to_avs_dev(dai->dev);
494 	struct avs_dma_data *data;
495 
496 	if (rtd->dai_link->ignore_suspend)
497 		adev->num_lp_paths--;
498 
499 	data = snd_soc_dai_get_dma_data(dai, substream);
500 
501 	snd_soc_dai_set_dma_data(dai, substream, NULL);
502 	snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
503 	kfree(data);
504 }
505 
506 static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
507 				struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
508 {
509 	struct snd_pcm_hw_params *be_hw_params = NULL;
510 	struct snd_soc_pcm_runtime *fe, *be;
511 	struct snd_soc_dpcm *dpcm;
512 	struct avs_dma_data *data;
513 	struct hdac_ext_stream *host_stream;
514 	int ret;
515 
516 	data = snd_soc_dai_get_dma_data(dai, substream);
517 	if (data->path)
518 		return 0;
519 
520 	host_stream = data->host_stream;
521 
522 	hdac_stream(host_stream)->bufsize = 0;
523 	hdac_stream(host_stream)->period_bytes = 0;
524 	hdac_stream(host_stream)->format_val = 0;
525 
526 	fe = asoc_substream_to_rtd(substream);
527 	for_each_dpcm_be(fe, substream->stream, dpcm) {
528 		be = dpcm->be;
529 		be_hw_params = &be->dpcm[substream->stream].hw_params;
530 	}
531 
532 	ret = avs_dai_hw_params(substream, hw_params, be_hw_params, dai,
533 				hdac_stream(host_stream)->stream_tag - 1);
534 	if (ret)
535 		goto create_err;
536 
537 	ret = avs_path_bind(data->path);
538 	if (ret < 0) {
539 		dev_err(dai->dev, "bind FE <-> BE failed: %d\n", ret);
540 		goto bind_err;
541 	}
542 
543 	return 0;
544 
545 bind_err:
546 	avs_path_free(data->path);
547 	data->path = NULL;
548 create_err:
549 	snd_pcm_lib_free_pages(substream);
550 	return ret;
551 }
552 
553 static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
554 {
555 	struct avs_dma_data *data;
556 	struct hdac_ext_stream *host_stream;
557 	int ret;
558 
559 	dev_dbg(dai->dev, "%s fe HW_FREE str %p rtd %p",
560 		__func__, substream, substream->runtime);
561 
562 	data = snd_soc_dai_get_dma_data(dai, substream);
563 	if (!data->path)
564 		return 0;
565 
566 	host_stream = data->host_stream;
567 
568 	ret = avs_path_unbind(data->path);
569 	if (ret < 0)
570 		dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
571 
572 	avs_path_free(data->path);
573 	data->path = NULL;
574 	snd_hdac_stream_cleanup(hdac_stream(host_stream));
575 	hdac_stream(host_stream)->prepared = false;
576 
577 	return ret;
578 }
579 
580 static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
581 {
582 	int ret;
583 
584 	ret = __avs_dai_fe_hw_free(substream, dai);
585 	snd_pcm_lib_free_pages(substream);
586 
587 	return ret;
588 }
589 
590 static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
591 {
592 	struct snd_pcm_runtime *runtime = substream->runtime;
593 	struct avs_dma_data *data;
594 	struct avs_dev *adev = to_avs_dev(dai->dev);
595 	struct hdac_ext_stream *host_stream;
596 	struct hdac_bus *bus;
597 	unsigned int format_val;
598 	int ret;
599 
600 	data = snd_soc_dai_get_dma_data(dai, substream);
601 	host_stream = data->host_stream;
602 
603 	if (hdac_stream(host_stream)->prepared)
604 		return 0;
605 
606 	bus = hdac_stream(host_stream)->bus;
607 	snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
608 	snd_hdac_stream_reset(hdac_stream(host_stream));
609 
610 	format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
611 						 runtime->sample_bits, 0);
612 
613 	ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
614 	if (ret < 0)
615 		return ret;
616 
617 	ret = snd_hdac_stream_setup(hdac_stream(host_stream));
618 	if (ret < 0)
619 		return ret;
620 
621 	ret = avs_dai_prepare(adev, substream, dai);
622 	if (ret)
623 		return ret;
624 
625 	hdac_stream(host_stream)->prepared = true;
626 	return 0;
627 }
628 
629 static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
630 {
631 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
632 	struct avs_dma_data *data;
633 	struct hdac_ext_stream *host_stream;
634 	struct hdac_bus *bus;
635 	unsigned long flags;
636 	int ret = 0;
637 
638 	data = snd_soc_dai_get_dma_data(dai, substream);
639 	host_stream = data->host_stream;
640 	bus = hdac_stream(host_stream)->bus;
641 
642 	switch (cmd) {
643 	case SNDRV_PCM_TRIGGER_RESUME:
644 		if (rtd->dai_link->ignore_suspend)
645 			break;
646 		fallthrough;
647 	case SNDRV_PCM_TRIGGER_START:
648 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
649 		spin_lock_irqsave(&bus->reg_lock, flags);
650 		snd_hdac_stream_start(hdac_stream(host_stream), true);
651 		spin_unlock_irqrestore(&bus->reg_lock, flags);
652 
653 		/* Timeout on DRSM poll shall not stop the resume so ignore the result. */
654 		if (cmd == SNDRV_PCM_TRIGGER_RESUME)
655 			snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
656 
657 		ret = avs_path_pause(data->path);
658 		if (ret < 0) {
659 			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
660 			break;
661 		}
662 
663 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
664 		if (ret < 0)
665 			dev_err(dai->dev, "run FE path failed: %d\n", ret);
666 
667 		break;
668 
669 	case SNDRV_PCM_TRIGGER_SUSPEND:
670 		if (rtd->dai_link->ignore_suspend)
671 			break;
672 		fallthrough;
673 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
674 	case SNDRV_PCM_TRIGGER_STOP:
675 		ret = avs_path_pause(data->path);
676 		if (ret < 0)
677 			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
678 
679 		spin_lock_irqsave(&bus->reg_lock, flags);
680 		snd_hdac_stream_stop(hdac_stream(host_stream));
681 		spin_unlock_irqrestore(&bus->reg_lock, flags);
682 
683 		ret = avs_path_reset(data->path);
684 		if (ret < 0)
685 			dev_err(dai->dev, "reset FE path failed: %d\n", ret);
686 		break;
687 
688 	default:
689 		ret = -EINVAL;
690 		break;
691 	}
692 
693 	return ret;
694 }
695 
696 const struct snd_soc_dai_ops avs_dai_fe_ops = {
697 	.startup = avs_dai_fe_startup,
698 	.shutdown = avs_dai_fe_shutdown,
699 	.hw_params = avs_dai_fe_hw_params,
700 	.hw_free = avs_dai_fe_hw_free,
701 	.prepare = avs_dai_fe_prepare,
702 	.trigger = avs_dai_fe_trigger,
703 };
704 
705 static ssize_t topology_name_read(struct file *file, char __user *user_buf, size_t count,
706 				  loff_t *ppos)
707 {
708 	struct snd_soc_component *component = file->private_data;
709 	struct snd_soc_card *card = component->card;
710 	struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
711 	char buf[64];
712 	size_t len;
713 
714 	len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
715 			mach->tplg_filename);
716 
717 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
718 }
719 
720 static const struct file_operations topology_name_fops = {
721 	.open = simple_open,
722 	.read = topology_name_read,
723 	.llseek = default_llseek,
724 };
725 
726 static int avs_component_load_libraries(struct avs_soc_component *acomp)
727 {
728 	struct avs_tplg *tplg = acomp->tplg;
729 	struct avs_dev *adev = to_avs_dev(acomp->base.dev);
730 	int ret;
731 
732 	if (!tplg->num_libs)
733 		return 0;
734 
735 	/* Parent device may be asleep and library loading involves IPCs. */
736 	ret = pm_runtime_resume_and_get(adev->dev);
737 	if (ret < 0)
738 		return ret;
739 
740 	avs_hda_power_gating_enable(adev, false);
741 	avs_hda_clock_gating_enable(adev, false);
742 	avs_hda_l1sen_enable(adev, false);
743 
744 	ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
745 
746 	avs_hda_l1sen_enable(adev, true);
747 	avs_hda_clock_gating_enable(adev, true);
748 	avs_hda_power_gating_enable(adev, true);
749 
750 	if (!ret)
751 		ret = avs_module_info_init(adev, false);
752 
753 	pm_runtime_mark_last_busy(adev->dev);
754 	pm_runtime_put_autosuspend(adev->dev);
755 
756 	return ret;
757 }
758 
759 static int avs_component_probe(struct snd_soc_component *component)
760 {
761 	struct snd_soc_card *card = component->card;
762 	struct snd_soc_acpi_mach *mach;
763 	struct avs_soc_component *acomp;
764 	struct avs_dev *adev;
765 	char *filename;
766 	int ret;
767 
768 	dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
769 	mach = dev_get_platdata(card->dev);
770 	acomp = to_avs_soc_component(component);
771 	adev = to_avs_dev(component->dev);
772 
773 	acomp->tplg = avs_tplg_new(component);
774 	if (!acomp->tplg)
775 		return -ENOMEM;
776 
777 	if (!mach->tplg_filename)
778 		goto finalize;
779 
780 	/* Load specified topology and create debugfs for it. */
781 	filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
782 			     mach->tplg_filename);
783 	if (!filename)
784 		return -ENOMEM;
785 
786 	ret = avs_load_topology(component, filename);
787 	kfree(filename);
788 	if (ret < 0)
789 		return ret;
790 
791 	ret = avs_component_load_libraries(acomp);
792 	if (ret < 0) {
793 		dev_err(card->dev, "libraries loading failed: %d\n", ret);
794 		goto err_load_libs;
795 	}
796 
797 finalize:
798 	debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
799 			    &topology_name_fops);
800 
801 	mutex_lock(&adev->comp_list_mutex);
802 	list_add_tail(&acomp->node, &adev->comp_list);
803 	mutex_unlock(&adev->comp_list_mutex);
804 
805 	return 0;
806 
807 err_load_libs:
808 	avs_remove_topology(component);
809 	return ret;
810 }
811 
812 static void avs_component_remove(struct snd_soc_component *component)
813 {
814 	struct avs_soc_component *acomp = to_avs_soc_component(component);
815 	struct snd_soc_acpi_mach *mach;
816 	struct avs_dev *adev = to_avs_dev(component->dev);
817 	int ret;
818 
819 	mach = dev_get_platdata(component->card->dev);
820 
821 	mutex_lock(&adev->comp_list_mutex);
822 	list_del(&acomp->node);
823 	mutex_unlock(&adev->comp_list_mutex);
824 
825 	if (mach->tplg_filename) {
826 		ret = avs_remove_topology(component);
827 		if (ret < 0)
828 			dev_err(component->dev, "unload topology failed: %d\n", ret);
829 	}
830 }
831 
832 static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data)
833 {
834 	struct snd_pcm_substream *substream;
835 	struct snd_soc_pcm_runtime *rtd;
836 	int ret;
837 
838 	substream = data->substream;
839 	rtd = snd_pcm_substream_chip(substream);
840 
841 	ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai);
842 	if (ret)
843 		dev_err(dai->dev, "hw_params on resume failed: %d\n", ret);
844 
845 	return ret;
846 }
847 
848 static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
849 {
850 	struct hdac_ext_stream *host_stream;
851 	struct hdac_stream *hstream;
852 	struct hdac_bus *bus;
853 	int ret;
854 
855 	host_stream = data->host_stream;
856 	hstream = hdac_stream(host_stream);
857 	bus = hdac_stream(host_stream)->bus;
858 
859 	/* Set DRSM before programming stream and position registers. */
860 	snd_hdac_stream_drsm_enable(bus, true, hstream->index);
861 
862 	ret = dai->driver->ops->prepare(data->substream, dai);
863 	if (ret) {
864 		dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret);
865 		return ret;
866 	}
867 
868 	writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL);
869 	writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU);
870 	writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL);
871 	writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU);
872 
873 	/* As per HW spec recommendation, program LPIB and DPIB to the same value. */
874 	snd_hdac_stream_set_lpib(hstream, hstream->lpib);
875 	snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
876 
877 	return 0;
878 }
879 
880 static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
881 {
882 	int ret;
883 
884 	ret = dai->driver->ops->prepare(data->substream, dai);
885 	if (ret)
886 		dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret);
887 
888 	return ret;
889 }
890 
891 static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
892 {
893 	struct hdac_ext_stream *host_stream;
894 	int ret;
895 
896 	host_stream = data->host_stream;
897 
898 	/* Store position addresses so we can resume from them later on. */
899 	hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream));
900 	host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL);
901 	host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU);
902 	host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL);
903 	host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU);
904 
905 	ret = __avs_dai_fe_hw_free(data->substream, dai);
906 	if (ret < 0)
907 		dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret);
908 
909 	return ret;
910 }
911 
912 static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
913 {
914 	int ret;
915 
916 	ret = dai->driver->ops->hw_free(data->substream, dai);
917 	if (ret < 0)
918 		dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret);
919 
920 	return ret;
921 }
922 
923 static int avs_component_pm_op(struct snd_soc_component *component, bool be,
924 			       int (*op)(struct snd_soc_dai *, struct avs_dma_data *))
925 {
926 	struct snd_soc_pcm_runtime *rtd;
927 	struct avs_dma_data *data;
928 	struct snd_soc_dai *dai;
929 	int ret;
930 
931 	for_each_component_dais(component, dai) {
932 		data = dai->playback_dma_data;
933 		if (data) {
934 			rtd = snd_pcm_substream_chip(data->substream);
935 			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
936 				ret = op(dai, data);
937 				if (ret < 0) {
938 					__snd_pcm_set_state(data->substream->runtime,
939 							    SNDRV_PCM_STATE_DISCONNECTED);
940 					return ret;
941 				}
942 			}
943 		}
944 
945 		data = dai->capture_dma_data;
946 		if (data) {
947 			rtd = snd_pcm_substream_chip(data->substream);
948 			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
949 				ret = op(dai, data);
950 				if (ret < 0) {
951 					__snd_pcm_set_state(data->substream->runtime,
952 							    SNDRV_PCM_STATE_DISCONNECTED);
953 					return ret;
954 				}
955 			}
956 		}
957 	}
958 
959 	return 0;
960 }
961 
962 static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be)
963 {
964 	return avs_component_pm_op(component, be, &avs_dai_resume_hw_params);
965 }
966 
967 static int avs_component_resume_prepare(struct snd_soc_component *component, bool be)
968 {
969 	int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
970 
971 	if (be)
972 		prepare_cb = &avs_dai_resume_be_prepare;
973 	else
974 		prepare_cb = &avs_dai_resume_fe_prepare;
975 
976 	return avs_component_pm_op(component, be, prepare_cb);
977 }
978 
979 static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be)
980 {
981 	int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
982 
983 	if (be)
984 		hw_free_cb = &avs_dai_suspend_be_hw_free;
985 	else
986 		hw_free_cb = &avs_dai_suspend_fe_hw_free;
987 
988 	return avs_component_pm_op(component, be, hw_free_cb);
989 }
990 
991 static int avs_component_suspend(struct snd_soc_component *component)
992 {
993 	int ret;
994 
995 	/*
996 	 * When freeing paths, FEs need to be first as they perform
997 	 * path unbinding.
998 	 */
999 	ret = avs_component_suspend_hw_free(component, false);
1000 	if (ret)
1001 		return ret;
1002 
1003 	return avs_component_suspend_hw_free(component, true);
1004 }
1005 
1006 static int avs_component_resume(struct snd_soc_component *component)
1007 {
1008 	int ret;
1009 
1010 	/*
1011 	 * When creating paths, FEs need to be last as they perform
1012 	 * path binding.
1013 	 */
1014 	ret = avs_component_resume_hw_params(component, true);
1015 	if (ret)
1016 		return ret;
1017 
1018 	ret = avs_component_resume_hw_params(component, false);
1019 	if (ret)
1020 		return ret;
1021 
1022 	/* It is expected that the LINK stream is prepared first. */
1023 	ret = avs_component_resume_prepare(component, true);
1024 	if (ret)
1025 		return ret;
1026 
1027 	return avs_component_resume_prepare(component, false);
1028 }
1029 
1030 static const struct snd_pcm_hardware avs_pcm_hardware = {
1031 	.info			= SNDRV_PCM_INFO_MMAP |
1032 				  SNDRV_PCM_INFO_MMAP_VALID |
1033 				  SNDRV_PCM_INFO_INTERLEAVED |
1034 				  SNDRV_PCM_INFO_PAUSE |
1035 				  SNDRV_PCM_INFO_RESUME |
1036 				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
1037 	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
1038 				  SNDRV_PCM_FMTBIT_S24_LE |
1039 				  SNDRV_PCM_FMTBIT_S32_LE,
1040 	.buffer_bytes_max	= AZX_MAX_BUF_SIZE,
1041 	.period_bytes_min	= 128,
1042 	.period_bytes_max	= AZX_MAX_BUF_SIZE / 2,
1043 	.periods_min		= 2,
1044 	.periods_max		= AZX_MAX_FRAG,
1045 	.fifo_size		= 0,
1046 };
1047 
1048 static int avs_component_open(struct snd_soc_component *component,
1049 			      struct snd_pcm_substream *substream)
1050 {
1051 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1052 
1053 	/* only FE DAI links are handled here */
1054 	if (rtd->dai_link->no_pcm)
1055 		return 0;
1056 
1057 	return snd_soc_set_runtime_hwparams(substream, &avs_pcm_hardware);
1058 }
1059 
1060 static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
1061 {
1062 	return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1063 		     (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
1064 }
1065 
1066 static snd_pcm_uframes_t
1067 avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
1068 {
1069 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1070 	struct avs_dma_data *data;
1071 	struct hdac_ext_stream *host_stream;
1072 	unsigned int pos;
1073 
1074 	data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
1075 	if (!data->host_stream)
1076 		return 0;
1077 
1078 	host_stream = data->host_stream;
1079 	pos = avs_hda_stream_dpib_read(host_stream);
1080 
1081 	if (pos >= hdac_stream(host_stream)->bufsize)
1082 		pos = 0;
1083 
1084 	return bytes_to_frames(substream->runtime, pos);
1085 }
1086 
1087 static int avs_component_mmap(struct snd_soc_component *component,
1088 			      struct snd_pcm_substream *substream,
1089 			      struct vm_area_struct *vma)
1090 {
1091 	return snd_pcm_lib_default_mmap(substream, vma);
1092 }
1093 
1094 #define MAX_PREALLOC_SIZE	(32 * 1024 * 1024)
1095 
1096 static int avs_component_construct(struct snd_soc_component *component,
1097 				   struct snd_soc_pcm_runtime *rtd)
1098 {
1099 	struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
1100 	struct snd_pcm *pcm = rtd->pcm;
1101 
1102 	if (dai->driver->playback.channels_min)
1103 		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
1104 					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1105 					   MAX_PREALLOC_SIZE);
1106 
1107 	if (dai->driver->capture.channels_min)
1108 		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
1109 					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1110 					   MAX_PREALLOC_SIZE);
1111 
1112 	return 0;
1113 }
1114 
1115 static const struct snd_soc_component_driver avs_component_driver = {
1116 	.name			= "avs-pcm",
1117 	.probe			= avs_component_probe,
1118 	.remove			= avs_component_remove,
1119 	.suspend		= avs_component_suspend,
1120 	.resume			= avs_component_resume,
1121 	.open			= avs_component_open,
1122 	.pointer		= avs_component_pointer,
1123 	.mmap			= avs_component_mmap,
1124 	.pcm_construct		= avs_component_construct,
1125 	.module_get_upon_open	= 1, /* increment refcount when a pcm is opened */
1126 	.topology_name_prefix	= "intel/avs",
1127 };
1128 
1129 int avs_soc_component_register(struct device *dev, const char *name,
1130 			       const struct snd_soc_component_driver *drv,
1131 			       struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
1132 {
1133 	struct avs_soc_component *acomp;
1134 	int ret;
1135 
1136 	acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
1137 	if (!acomp)
1138 		return -ENOMEM;
1139 
1140 	ret = snd_soc_component_initialize(&acomp->base, drv, dev);
1141 	if (ret < 0)
1142 		return ret;
1143 
1144 	/* force name change after ASoC is done with its init */
1145 	acomp->base.name = name;
1146 	INIT_LIST_HEAD(&acomp->node);
1147 
1148 	return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
1149 }
1150 
1151 static struct snd_soc_dai_driver dmic_cpu_dais[] = {
1152 {
1153 	.name = "DMIC Pin",
1154 	.ops = &avs_dai_nonhda_be_ops,
1155 	.capture = {
1156 		.stream_name	= "DMIC Rx",
1157 		.channels_min	= 1,
1158 		.channels_max	= 4,
1159 		.rates		= SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
1160 		.formats	= SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
1161 	},
1162 },
1163 {
1164 	.name = "DMIC WoV Pin",
1165 	.ops = &avs_dai_nonhda_be_ops,
1166 	.capture = {
1167 		.stream_name	= "DMIC WoV Rx",
1168 		.channels_min	= 1,
1169 		.channels_max	= 4,
1170 		.rates		= SNDRV_PCM_RATE_16000,
1171 		.formats	= SNDRV_PCM_FMTBIT_S16_LE,
1172 	},
1173 },
1174 };
1175 
1176 int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
1177 {
1178 	return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
1179 					  ARRAY_SIZE(dmic_cpu_dais));
1180 }
1181 
1182 static const struct snd_soc_dai_driver i2s_dai_template = {
1183 	.ops = &avs_dai_nonhda_be_ops,
1184 	.playback = {
1185 		.channels_min	= 1,
1186 		.channels_max	= 8,
1187 		.rates		= SNDRV_PCM_RATE_8000_192000 |
1188 				  SNDRV_PCM_RATE_KNOT,
1189 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1190 				  SNDRV_PCM_FMTBIT_S24_LE |
1191 				  SNDRV_PCM_FMTBIT_S32_LE,
1192 	},
1193 	.capture = {
1194 		.channels_min	= 1,
1195 		.channels_max	= 8,
1196 		.rates		= SNDRV_PCM_RATE_8000_192000 |
1197 				  SNDRV_PCM_RATE_KNOT,
1198 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1199 				  SNDRV_PCM_FMTBIT_S24_LE |
1200 				  SNDRV_PCM_FMTBIT_S32_LE,
1201 	},
1202 };
1203 
1204 int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
1205 			      unsigned long *tdms)
1206 {
1207 	struct snd_soc_dai_driver *cpus, *dai;
1208 	size_t ssp_count, cpu_count;
1209 	int i, j;
1210 
1211 	ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
1212 	cpu_count = hweight_long(port_mask);
1213 	if (tdms)
1214 		for_each_set_bit(i, &port_mask, ssp_count)
1215 			cpu_count += hweight_long(tdms[i]);
1216 
1217 	cpus = devm_kzalloc(adev->dev, sizeof(*cpus) * cpu_count, GFP_KERNEL);
1218 	if (!cpus)
1219 		return -ENOMEM;
1220 
1221 	dai = cpus;
1222 	for_each_set_bit(i, &port_mask, ssp_count) {
1223 		memcpy(dai, &i2s_dai_template, sizeof(*dai));
1224 
1225 		dai->name =
1226 			devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
1227 		dai->playback.stream_name =
1228 			devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
1229 		dai->capture.stream_name =
1230 			devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
1231 
1232 		if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1233 			return -ENOMEM;
1234 		dai++;
1235 	}
1236 
1237 	if (!tdms)
1238 		goto plat_register;
1239 
1240 	for_each_set_bit(i, &port_mask, ssp_count) {
1241 		for_each_set_bit(j, &tdms[i], ssp_count) {
1242 			memcpy(dai, &i2s_dai_template, sizeof(*dai));
1243 
1244 			dai->name =
1245 				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
1246 			dai->playback.stream_name =
1247 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
1248 			dai->capture.stream_name =
1249 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
1250 
1251 			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1252 				return -ENOMEM;
1253 			dai++;
1254 		}
1255 	}
1256 
1257 plat_register:
1258 	return avs_soc_component_register(adev->dev, name, &avs_component_driver, cpus, cpu_count);
1259 }
1260 
1261 /* HD-Audio CPU DAI template */
1262 static const struct snd_soc_dai_driver hda_cpu_dai = {
1263 	.ops = &avs_dai_hda_be_ops,
1264 	.playback = {
1265 		.channels_min	= 1,
1266 		.channels_max	= 8,
1267 		.rates		= SNDRV_PCM_RATE_8000_192000,
1268 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1269 				  SNDRV_PCM_FMTBIT_S24_LE |
1270 				  SNDRV_PCM_FMTBIT_S32_LE,
1271 	},
1272 	.capture = {
1273 		.channels_min	= 1,
1274 		.channels_max	= 8,
1275 		.rates		= SNDRV_PCM_RATE_8000_192000,
1276 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1277 				  SNDRV_PCM_FMTBIT_S24_LE |
1278 				  SNDRV_PCM_FMTBIT_S32_LE,
1279 	},
1280 };
1281 
1282 static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1283 {
1284 	struct snd_soc_acpi_mach *mach;
1285 	struct snd_soc_dai *dai, *save;
1286 	struct hda_codec *codec;
1287 	char name[32];
1288 
1289 	mach = dev_get_platdata(component->card->dev);
1290 	codec = mach->pdata;
1291 	sprintf(name, "%s-cpu", dev_name(&codec->core.dev));
1292 
1293 	for_each_component_dais_safe(component, dai, save) {
1294 		if (!strstr(dai->driver->name, name))
1295 			continue;
1296 
1297 		snd_soc_dapm_free_widget(dai->playback_widget);
1298 		snd_soc_dapm_free_widget(dai->capture_widget);
1299 		snd_soc_unregister_dai(dai);
1300 	}
1301 }
1302 
1303 static int avs_component_hda_probe(struct snd_soc_component *component)
1304 {
1305 	struct snd_soc_dapm_context *dapm;
1306 	struct snd_soc_dai_driver *dais;
1307 	struct snd_soc_acpi_mach *mach;
1308 	struct hda_codec *codec;
1309 	struct hda_pcm *pcm;
1310 	const char *cname;
1311 	int pcm_count = 0, ret, i;
1312 
1313 	mach = dev_get_platdata(component->card->dev);
1314 	if (!mach)
1315 		return -EINVAL;
1316 
1317 	codec = mach->pdata;
1318 	if (list_empty(&codec->pcm_list_head))
1319 		return -EINVAL;
1320 	list_for_each_entry(pcm, &codec->pcm_list_head, list)
1321 		pcm_count++;
1322 
1323 	dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1324 			    GFP_KERNEL);
1325 	if (!dais)
1326 		return -ENOMEM;
1327 
1328 	cname = dev_name(&codec->core.dev);
1329 	dapm = snd_soc_component_get_dapm(component);
1330 	pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1331 
1332 	for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1333 		struct snd_soc_dai *dai;
1334 
1335 		memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1336 		dais[i].id = i;
1337 		dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1338 					      "%s-cpu%d", cname, i);
1339 		if (!dais[i].name) {
1340 			ret = -ENOMEM;
1341 			goto exit;
1342 		}
1343 
1344 		if (pcm->stream[0].substreams) {
1345 			dais[i].playback.stream_name =
1346 				devm_kasprintf(component->dev, GFP_KERNEL,
1347 					       "%s-cpu%d Tx", cname, i);
1348 			if (!dais[i].playback.stream_name) {
1349 				ret = -ENOMEM;
1350 				goto exit;
1351 			}
1352 		}
1353 
1354 		if (pcm->stream[1].substreams) {
1355 			dais[i].capture.stream_name =
1356 				devm_kasprintf(component->dev, GFP_KERNEL,
1357 					       "%s-cpu%d Rx", cname, i);
1358 			if (!dais[i].capture.stream_name) {
1359 				ret = -ENOMEM;
1360 				goto exit;
1361 			}
1362 		}
1363 
1364 		dai = snd_soc_register_dai(component, &dais[i], false);
1365 		if (!dai) {
1366 			dev_err(component->dev, "register dai for %s failed\n",
1367 				pcm->name);
1368 			ret = -EINVAL;
1369 			goto exit;
1370 		}
1371 
1372 		ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1373 		if (ret < 0) {
1374 			dev_err(component->dev, "create widgets failed: %d\n",
1375 				ret);
1376 			goto exit;
1377 		}
1378 	}
1379 
1380 	ret = avs_component_probe(component);
1381 exit:
1382 	if (ret)
1383 		avs_component_hda_unregister_dais(component);
1384 
1385 	return ret;
1386 }
1387 
1388 static void avs_component_hda_remove(struct snd_soc_component *component)
1389 {
1390 	avs_component_hda_unregister_dais(component);
1391 	avs_component_remove(component);
1392 }
1393 
1394 static int avs_component_hda_open(struct snd_soc_component *component,
1395 				  struct snd_pcm_substream *substream)
1396 {
1397 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1398 	struct hdac_ext_stream *link_stream;
1399 	struct hda_codec *codec;
1400 
1401 	if (!rtd->dai_link->no_pcm) {
1402 		struct snd_pcm_hardware hwparams = avs_pcm_hardware;
1403 		struct snd_soc_pcm_runtime *be;
1404 		struct snd_soc_dpcm *dpcm;
1405 		int dir = substream->stream;
1406 
1407 		/*
1408 		 * Support the DPCM reparenting while still fulfilling expectations of HDAudio
1409 		 * common code - a valid stream pointer at substream->runtime->private_data -
1410 		 * by having all FEs point to the same private data.
1411 		 */
1412 		for_each_dpcm_be(rtd, dir, dpcm) {
1413 			struct snd_pcm_substream *be_substream;
1414 
1415 			be = dpcm->be;
1416 			if (be->dpcm[dir].users == 1)
1417 				break;
1418 
1419 			be_substream = snd_soc_dpcm_get_substream(be, dir);
1420 			substream->runtime->private_data = be_substream->runtime->private_data;
1421 			break;
1422 		}
1423 
1424 		/* RESUME unsupported for de-coupled HD-Audio capture. */
1425 		if (dir == SNDRV_PCM_STREAM_CAPTURE)
1426 			hwparams.info &= ~SNDRV_PCM_INFO_RESUME;
1427 
1428 		return snd_soc_set_runtime_hwparams(substream, &hwparams);
1429 	}
1430 
1431 	codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
1432 	link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
1433 					     HDAC_EXT_STREAM_TYPE_LINK);
1434 	if (!link_stream)
1435 		return -EBUSY;
1436 
1437 	substream->runtime->private_data = link_stream;
1438 	return 0;
1439 }
1440 
1441 static int avs_component_hda_close(struct snd_soc_component *component,
1442 				   struct snd_pcm_substream *substream)
1443 {
1444 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1445 	struct hdac_ext_stream *link_stream;
1446 
1447 	/* only BE DAI links are handled here */
1448 	if (!rtd->dai_link->no_pcm)
1449 		return 0;
1450 
1451 	link_stream = substream->runtime->private_data;
1452 	snd_hdac_ext_stream_release(link_stream, HDAC_EXT_STREAM_TYPE_LINK);
1453 	substream->runtime->private_data = NULL;
1454 
1455 	return 0;
1456 }
1457 
1458 static const struct snd_soc_component_driver avs_hda_component_driver = {
1459 	.name			= "avs-hda-pcm",
1460 	.probe			= avs_component_hda_probe,
1461 	.remove			= avs_component_hda_remove,
1462 	.suspend		= avs_component_suspend,
1463 	.resume			= avs_component_resume,
1464 	.open			= avs_component_hda_open,
1465 	.close			= avs_component_hda_close,
1466 	.pointer		= avs_component_pointer,
1467 	.mmap			= avs_component_mmap,
1468 	.pcm_construct		= avs_component_construct,
1469 	/*
1470 	 * hda platform component's probe() is dependent on
1471 	 * codec->pcm_list_head, it needs to be initialized after codec
1472 	 * component. remove_order is here for completeness sake
1473 	 */
1474 	.probe_order		= SND_SOC_COMP_ORDER_LATE,
1475 	.remove_order		= SND_SOC_COMP_ORDER_EARLY,
1476 	.module_get_upon_open	= 1,
1477 	.topology_name_prefix	= "intel/avs",
1478 };
1479 
1480 int avs_hda_platform_register(struct avs_dev *adev, const char *name)
1481 {
1482 	return avs_soc_component_register(adev->dev, name,
1483 					  &avs_hda_component_driver, NULL, 0);
1484 }
1485