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 
33 static struct avs_tplg_path_template *
avs_dai_find_path_template(struct snd_soc_dai * dai,bool is_fe,int direction)34 avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
35 {
36 	struct snd_soc_dapm_widget *dw;
37 	struct snd_soc_dapm_path *dp;
38 	enum snd_soc_dapm_direction dir;
39 
40 	if (direction == SNDRV_PCM_STREAM_CAPTURE) {
41 		dw = dai->capture_widget;
42 		dir = is_fe ? SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN;
43 	} else {
44 		dw = dai->playback_widget;
45 		dir = is_fe ? SND_SOC_DAPM_DIR_IN : SND_SOC_DAPM_DIR_OUT;
46 	}
47 
48 	dp = list_first_entry_or_null(&dw->edges[dir], typeof(*dp), list_node[dir]);
49 	if (!dp)
50 		return NULL;
51 
52 	/* Get the other widget, with actual path template data */
53 	dw = (dp->source == dw) ? dp->sink : dp->source;
54 
55 	return dw->priv;
56 }
57 
avs_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai,bool is_fe)58 static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe)
59 {
60 	struct avs_tplg_path_template *template;
61 	struct avs_dma_data *data;
62 
63 	template = avs_dai_find_path_template(dai, is_fe, substream->stream);
64 	if (!template) {
65 		dev_err(dai->dev, "no %s path for dai %s, invalid tplg?\n",
66 			snd_pcm_stream_str(substream), dai->name);
67 		return -EINVAL;
68 	}
69 
70 	data = kzalloc(sizeof(*data), GFP_KERNEL);
71 	if (!data)
72 		return -ENOMEM;
73 
74 	data->template = template;
75 	snd_soc_dai_set_dma_data(dai, substream, data);
76 
77 	return 0;
78 }
79 
avs_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * fe_hw_params,struct snd_pcm_hw_params * be_hw_params,struct snd_soc_dai * dai,int dma_id)80 static int avs_dai_hw_params(struct snd_pcm_substream *substream,
81 			     struct snd_pcm_hw_params *fe_hw_params,
82 			     struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
83 			     int dma_id)
84 {
85 	struct avs_dma_data *data;
86 	struct avs_path *path;
87 	struct avs_dev *adev = to_avs_dev(dai->dev);
88 	int ret;
89 
90 	data = snd_soc_dai_get_dma_data(dai, substream);
91 
92 	dev_dbg(dai->dev, "%s FE hw_params str %p rtd %p",
93 		__func__, substream, substream->runtime);
94 	dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
95 		params_rate(fe_hw_params), params_channels(fe_hw_params),
96 		params_width(fe_hw_params), params_physical_width(fe_hw_params));
97 
98 	dev_dbg(dai->dev, "%s BE hw_params str %p rtd %p",
99 		__func__, substream, substream->runtime);
100 	dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
101 		params_rate(be_hw_params), params_channels(be_hw_params),
102 		params_width(be_hw_params), params_physical_width(be_hw_params));
103 
104 	path = avs_path_create(adev, dma_id, data->template, fe_hw_params, be_hw_params);
105 	if (IS_ERR(path)) {
106 		ret = PTR_ERR(path);
107 		dev_err(dai->dev, "create path failed: %d\n", ret);
108 		return ret;
109 	}
110 
111 	data->path = path;
112 	return 0;
113 }
114 
avs_dai_be_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * be_hw_params,struct snd_soc_dai * dai,int dma_id)115 static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
116 				struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
117 				int dma_id)
118 {
119 	struct snd_pcm_hw_params *fe_hw_params = NULL;
120 	struct snd_soc_pcm_runtime *fe, *be;
121 	struct snd_soc_dpcm *dpcm;
122 
123 	be = asoc_substream_to_rtd(substream);
124 	for_each_dpcm_fe(be, substream->stream, dpcm) {
125 		fe = dpcm->fe;
126 		fe_hw_params = &fe->dpcm[substream->stream].hw_params;
127 	}
128 
129 	return avs_dai_hw_params(substream, fe_hw_params, be_hw_params, dai, dma_id);
130 }
131 
avs_dai_prepare(struct avs_dev * adev,struct snd_pcm_substream * substream,struct snd_soc_dai * dai)132 static int avs_dai_prepare(struct avs_dev *adev, struct snd_pcm_substream *substream,
133 			   struct snd_soc_dai *dai)
134 {
135 	struct avs_dma_data *data;
136 	int ret;
137 
138 	data = snd_soc_dai_get_dma_data(dai, substream);
139 	if (!data->path)
140 		return 0;
141 
142 	ret = avs_path_reset(data->path);
143 	if (ret < 0) {
144 		dev_err(dai->dev, "reset path failed: %d\n", ret);
145 		return ret;
146 	}
147 
148 	ret = avs_path_pause(data->path);
149 	if (ret < 0)
150 		dev_err(dai->dev, "pause path failed: %d\n", ret);
151 	return ret;
152 }
153 
avs_dai_nonhda_be_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)154 static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
155 {
156 	return avs_dai_startup(substream, dai, false);
157 }
158 
avs_dai_nonhda_be_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)159 static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
160 {
161 	struct avs_dma_data *data;
162 
163 	data = snd_soc_dai_get_dma_data(dai, substream);
164 
165 	snd_soc_dai_set_dma_data(dai, substream, NULL);
166 	kfree(data);
167 }
168 
avs_dai_nonhda_be_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params,struct snd_soc_dai * dai)169 static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
170 				       struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
171 {
172 	struct avs_dma_data *data;
173 
174 	data = snd_soc_dai_get_dma_data(dai, substream);
175 	if (data->path)
176 		return 0;
177 
178 	/* Actual port-id comes from topology. */
179 	return avs_dai_be_hw_params(substream, hw_params, dai, 0);
180 }
181 
avs_dai_nonhda_be_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)182 static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
183 {
184 	struct avs_dma_data *data;
185 
186 	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
187 
188 	data = snd_soc_dai_get_dma_data(dai, substream);
189 	if (data->path) {
190 		avs_path_free(data->path);
191 		data->path = NULL;
192 	}
193 
194 	return 0;
195 }
196 
avs_dai_nonhda_be_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)197 static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
198 {
199 	return avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
200 }
201 
avs_dai_nonhda_be_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)202 static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
203 				     struct snd_soc_dai *dai)
204 {
205 	struct avs_dma_data *data;
206 	int ret = 0;
207 
208 	data = snd_soc_dai_get_dma_data(dai, substream);
209 
210 	switch (cmd) {
211 	case SNDRV_PCM_TRIGGER_START:
212 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
213 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
214 		if (ret < 0)
215 			dev_err(dai->dev, "run BE path failed: %d\n", ret);
216 		break;
217 
218 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
219 	case SNDRV_PCM_TRIGGER_STOP:
220 		ret = avs_path_pause(data->path);
221 		if (ret < 0)
222 			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
223 
224 		if (cmd == SNDRV_PCM_TRIGGER_STOP) {
225 			ret = avs_path_reset(data->path);
226 			if (ret < 0)
227 				dev_err(dai->dev, "reset BE path failed: %d\n", ret);
228 		}
229 		break;
230 
231 	default:
232 		ret = -EINVAL;
233 		break;
234 	}
235 
236 	return ret;
237 }
238 
239 static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
240 	.startup = avs_dai_nonhda_be_startup,
241 	.shutdown = avs_dai_nonhda_be_shutdown,
242 	.hw_params = avs_dai_nonhda_be_hw_params,
243 	.hw_free = avs_dai_nonhda_be_hw_free,
244 	.prepare = avs_dai_nonhda_be_prepare,
245 	.trigger = avs_dai_nonhda_be_trigger,
246 };
247 
avs_dai_hda_be_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)248 static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
249 {
250 	return avs_dai_startup(substream, dai, false);
251 }
252 
avs_dai_hda_be_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)253 static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
254 {
255 	return avs_dai_nonhda_be_shutdown(substream, dai);
256 }
257 
avs_dai_hda_be_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params,struct snd_soc_dai * dai)258 static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
259 				    struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
260 {
261 	struct avs_dma_data *data;
262 	struct hdac_ext_stream *link_stream;
263 
264 	data = snd_soc_dai_get_dma_data(dai, substream);
265 	if (data->path)
266 		return 0;
267 
268 	link_stream = substream->runtime->private_data;
269 
270 	return avs_dai_be_hw_params(substream, hw_params, dai,
271 				    hdac_stream(link_stream)->stream_tag - 1);
272 }
273 
avs_dai_hda_be_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)274 static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
275 {
276 	struct avs_dma_data *data;
277 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
278 	struct hdac_ext_stream *link_stream;
279 	struct hdac_ext_link *link;
280 	struct hda_codec *codec;
281 
282 	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
283 
284 	data = snd_soc_dai_get_dma_data(dai, substream);
285 	if (!data->path)
286 		return 0;
287 
288 	link_stream = substream->runtime->private_data;
289 	link_stream->link_prepared = false;
290 	avs_path_free(data->path);
291 	data->path = NULL;
292 
293 	/* clear link <-> stream mapping */
294 	codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
295 	link = snd_hdac_ext_bus_link_at(&codec->bus->core, codec->core.addr);
296 	if (!link)
297 		return -EINVAL;
298 
299 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
300 		snd_hdac_ext_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag);
301 
302 	return 0;
303 }
304 
avs_dai_hda_be_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)305 static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
306 {
307 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
308 	struct snd_pcm_runtime *runtime = substream->runtime;
309 	struct hdac_ext_stream *link_stream = runtime->private_data;
310 	struct hdac_ext_link *link;
311 	struct hda_codec *codec;
312 	struct hdac_bus *bus;
313 	unsigned int format_val;
314 	int ret;
315 
316 	if (link_stream->link_prepared)
317 		return 0;
318 
319 	codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
320 	bus = &codec->bus->core;
321 	format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
322 						 runtime->sample_bits, 0);
323 
324 	snd_hdac_ext_stream_decouple(bus, link_stream, true);
325 	snd_hdac_ext_link_stream_reset(link_stream);
326 	snd_hdac_ext_link_stream_setup(link_stream, format_val);
327 
328 	link = snd_hdac_ext_bus_link_at(bus, codec->core.addr);
329 	if (!link)
330 		return -EINVAL;
331 
332 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
333 		snd_hdac_ext_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag);
334 
335 	ret = avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
336 	if (ret)
337 		return ret;
338 
339 	link_stream->link_prepared = true;
340 	return 0;
341 }
342 
avs_dai_hda_be_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)343 static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
344 				  struct snd_soc_dai *dai)
345 {
346 	struct hdac_ext_stream *link_stream;
347 	struct avs_dma_data *data;
348 	int ret = 0;
349 
350 	dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd);
351 
352 	data = snd_soc_dai_get_dma_data(dai, substream);
353 	link_stream = substream->runtime->private_data;
354 
355 	switch (cmd) {
356 	case SNDRV_PCM_TRIGGER_START:
357 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
358 		snd_hdac_ext_link_stream_start(link_stream);
359 
360 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
361 		if (ret < 0)
362 			dev_err(dai->dev, "run BE path failed: %d\n", ret);
363 		break;
364 
365 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
366 	case SNDRV_PCM_TRIGGER_STOP:
367 		ret = avs_path_pause(data->path);
368 		if (ret < 0)
369 			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
370 
371 		snd_hdac_ext_link_stream_clear(link_stream);
372 
373 		if (cmd == SNDRV_PCM_TRIGGER_STOP) {
374 			ret = avs_path_reset(data->path);
375 			if (ret < 0)
376 				dev_err(dai->dev, "reset BE path failed: %d\n", ret);
377 		}
378 		break;
379 
380 	default:
381 		ret = -EINVAL;
382 		break;
383 	}
384 
385 	return ret;
386 }
387 
388 static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
389 	.startup = avs_dai_hda_be_startup,
390 	.shutdown = avs_dai_hda_be_shutdown,
391 	.hw_params = avs_dai_hda_be_hw_params,
392 	.hw_free = avs_dai_hda_be_hw_free,
393 	.prepare = avs_dai_hda_be_prepare,
394 	.trigger = avs_dai_hda_be_trigger,
395 };
396 
397 static const unsigned int rates[] = {
398 	8000, 11025, 12000, 16000,
399 	22050, 24000, 32000, 44100,
400 	48000, 64000, 88200, 96000,
401 	128000, 176400, 192000,
402 };
403 
404 static const struct snd_pcm_hw_constraint_list hw_rates = {
405 	.count = ARRAY_SIZE(rates),
406 	.list = rates,
407 	.mask = 0,
408 };
409 
avs_dai_fe_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)410 static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
411 {
412 	struct snd_pcm_runtime *runtime = substream->runtime;
413 	struct avs_dma_data *data;
414 	struct avs_dev *adev = to_avs_dev(dai->dev);
415 	struct hdac_bus *bus = &adev->base.core;
416 	struct hdac_ext_stream *host_stream;
417 	int ret;
418 
419 	ret = avs_dai_startup(substream, dai, true);
420 	if (ret)
421 		return ret;
422 
423 	data = snd_soc_dai_get_dma_data(dai, substream);
424 
425 	host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST);
426 	if (!host_stream) {
427 		kfree(data);
428 		return -EBUSY;
429 	}
430 
431 	data->host_stream = host_stream;
432 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
433 	/* avoid wrap-around with wall-clock */
434 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
435 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_rates);
436 	snd_pcm_set_sync(substream);
437 
438 	dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p",
439 		__func__, hdac_stream(host_stream)->stream_tag, substream);
440 
441 	return 0;
442 }
443 
avs_dai_fe_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)444 static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
445 {
446 	struct avs_dma_data *data;
447 
448 	data = snd_soc_dai_get_dma_data(dai, substream);
449 
450 	snd_soc_dai_set_dma_data(dai, substream, NULL);
451 	snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
452 	kfree(data);
453 }
454 
avs_dai_fe_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params,struct snd_soc_dai * dai)455 static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
456 				struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
457 {
458 	struct snd_pcm_hw_params *be_hw_params = NULL;
459 	struct snd_soc_pcm_runtime *fe, *be;
460 	struct snd_soc_dpcm *dpcm;
461 	struct avs_dma_data *data;
462 	struct hdac_ext_stream *host_stream;
463 	int ret;
464 
465 	data = snd_soc_dai_get_dma_data(dai, substream);
466 	if (data->path)
467 		return 0;
468 
469 	host_stream = data->host_stream;
470 
471 	hdac_stream(host_stream)->bufsize = 0;
472 	hdac_stream(host_stream)->period_bytes = 0;
473 	hdac_stream(host_stream)->format_val = 0;
474 
475 	fe = asoc_substream_to_rtd(substream);
476 	for_each_dpcm_be(fe, substream->stream, dpcm) {
477 		be = dpcm->be;
478 		be_hw_params = &be->dpcm[substream->stream].hw_params;
479 	}
480 
481 	ret = avs_dai_hw_params(substream, hw_params, be_hw_params, dai,
482 				hdac_stream(host_stream)->stream_tag - 1);
483 	if (ret)
484 		goto create_err;
485 
486 	ret = avs_path_bind(data->path);
487 	if (ret < 0) {
488 		dev_err(dai->dev, "bind FE <-> BE failed: %d\n", ret);
489 		goto bind_err;
490 	}
491 
492 	return 0;
493 
494 bind_err:
495 	avs_path_free(data->path);
496 	data->path = NULL;
497 create_err:
498 	snd_pcm_lib_free_pages(substream);
499 	return ret;
500 }
501 
avs_dai_fe_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)502 static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
503 {
504 	struct avs_dma_data *data;
505 	struct hdac_ext_stream *host_stream;
506 	int ret;
507 
508 	dev_dbg(dai->dev, "%s fe HW_FREE str %p rtd %p",
509 		__func__, substream, substream->runtime);
510 
511 	data = snd_soc_dai_get_dma_data(dai, substream);
512 	if (!data->path)
513 		return 0;
514 
515 	host_stream = data->host_stream;
516 
517 	ret = avs_path_unbind(data->path);
518 	if (ret < 0)
519 		dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
520 
521 	avs_path_free(data->path);
522 	data->path = NULL;
523 	snd_hdac_stream_cleanup(hdac_stream(host_stream));
524 	hdac_stream(host_stream)->prepared = false;
525 
526 	ret = snd_pcm_lib_free_pages(substream);
527 	if (ret < 0)
528 		dev_dbg(dai->dev, "Failed to free pages!\n");
529 
530 	return ret;
531 }
532 
avs_dai_fe_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)533 static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
534 {
535 	struct snd_pcm_runtime *runtime = substream->runtime;
536 	struct avs_dma_data *data;
537 	struct avs_dev *adev = to_avs_dev(dai->dev);
538 	struct hdac_ext_stream *host_stream;
539 	struct hdac_bus *bus;
540 	unsigned int format_val;
541 	int ret;
542 
543 	data = snd_soc_dai_get_dma_data(dai, substream);
544 	host_stream = data->host_stream;
545 
546 	if (hdac_stream(host_stream)->prepared)
547 		return 0;
548 
549 	bus = hdac_stream(host_stream)->bus;
550 	snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
551 	snd_hdac_stream_reset(hdac_stream(host_stream));
552 
553 	format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
554 						 runtime->sample_bits, 0);
555 
556 	ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
557 	if (ret < 0)
558 		return ret;
559 
560 	ret = snd_hdac_stream_setup(hdac_stream(host_stream));
561 	if (ret < 0)
562 		return ret;
563 
564 	ret = avs_dai_prepare(adev, substream, dai);
565 	if (ret)
566 		return ret;
567 
568 	hdac_stream(host_stream)->prepared = true;
569 	return 0;
570 }
571 
avs_dai_fe_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)572 static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
573 {
574 	struct avs_dma_data *data;
575 	struct hdac_ext_stream *host_stream;
576 	struct hdac_bus *bus;
577 	unsigned long flags;
578 	int ret = 0;
579 
580 	data = snd_soc_dai_get_dma_data(dai, substream);
581 	host_stream = data->host_stream;
582 	bus = hdac_stream(host_stream)->bus;
583 
584 	switch (cmd) {
585 	case SNDRV_PCM_TRIGGER_START:
586 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
587 		spin_lock_irqsave(&bus->reg_lock, flags);
588 		snd_hdac_stream_start(hdac_stream(host_stream), true);
589 		spin_unlock_irqrestore(&bus->reg_lock, flags);
590 
591 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
592 		if (ret < 0)
593 			dev_err(dai->dev, "run FE path failed: %d\n", ret);
594 		break;
595 
596 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
597 	case SNDRV_PCM_TRIGGER_STOP:
598 		ret = avs_path_pause(data->path);
599 		if (ret < 0)
600 			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
601 
602 		spin_lock_irqsave(&bus->reg_lock, flags);
603 		snd_hdac_stream_stop(hdac_stream(host_stream));
604 		spin_unlock_irqrestore(&bus->reg_lock, flags);
605 
606 		if (cmd == SNDRV_PCM_TRIGGER_STOP) {
607 			ret = avs_path_reset(data->path);
608 			if (ret < 0)
609 				dev_err(dai->dev, "reset FE path failed: %d\n", ret);
610 		}
611 		break;
612 
613 	default:
614 		ret = -EINVAL;
615 		break;
616 	}
617 
618 	return ret;
619 }
620 
621 const struct snd_soc_dai_ops avs_dai_fe_ops = {
622 	.startup = avs_dai_fe_startup,
623 	.shutdown = avs_dai_fe_shutdown,
624 	.hw_params = avs_dai_fe_hw_params,
625 	.hw_free = avs_dai_fe_hw_free,
626 	.prepare = avs_dai_fe_prepare,
627 	.trigger = avs_dai_fe_trigger,
628 };
629 
topology_name_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)630 static ssize_t topology_name_read(struct file *file, char __user *user_buf, size_t count,
631 				  loff_t *ppos)
632 {
633 	struct snd_soc_component *component = file->private_data;
634 	struct snd_soc_card *card = component->card;
635 	struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
636 	char buf[64];
637 	size_t len;
638 
639 	len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
640 			mach->tplg_filename);
641 
642 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
643 }
644 
645 static const struct file_operations topology_name_fops = {
646 	.open = simple_open,
647 	.read = topology_name_read,
648 	.llseek = default_llseek,
649 };
650 
avs_component_load_libraries(struct avs_soc_component * acomp)651 static int avs_component_load_libraries(struct avs_soc_component *acomp)
652 {
653 	struct avs_tplg *tplg = acomp->tplg;
654 	struct avs_dev *adev = to_avs_dev(acomp->base.dev);
655 	int ret;
656 
657 	if (!tplg->num_libs)
658 		return 0;
659 
660 	/* Parent device may be asleep and library loading involves IPCs. */
661 	ret = pm_runtime_resume_and_get(adev->dev);
662 	if (ret < 0)
663 		return ret;
664 
665 	avs_hda_clock_gating_enable(adev, false);
666 	avs_hda_l1sen_enable(adev, false);
667 
668 	ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
669 
670 	avs_hda_l1sen_enable(adev, true);
671 	avs_hda_clock_gating_enable(adev, true);
672 
673 	if (!ret)
674 		ret = avs_module_info_init(adev, false);
675 
676 	pm_runtime_mark_last_busy(adev->dev);
677 	pm_runtime_put_autosuspend(adev->dev);
678 
679 	return ret;
680 }
681 
avs_component_probe(struct snd_soc_component * component)682 static int avs_component_probe(struct snd_soc_component *component)
683 {
684 	struct snd_soc_card *card = component->card;
685 	struct snd_soc_acpi_mach *mach;
686 	struct avs_soc_component *acomp;
687 	struct avs_dev *adev;
688 	char *filename;
689 	int ret;
690 
691 	dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
692 	mach = dev_get_platdata(card->dev);
693 	acomp = to_avs_soc_component(component);
694 	adev = to_avs_dev(component->dev);
695 
696 	acomp->tplg = avs_tplg_new(component);
697 	if (!acomp->tplg)
698 		return -ENOMEM;
699 
700 	if (!mach->tplg_filename)
701 		goto finalize;
702 
703 	/* Load specified topology and create debugfs for it. */
704 	filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
705 			     mach->tplg_filename);
706 	if (!filename)
707 		return -ENOMEM;
708 
709 	ret = avs_load_topology(component, filename);
710 	kfree(filename);
711 	if (ret < 0)
712 		return ret;
713 
714 	ret = avs_component_load_libraries(acomp);
715 	if (ret < 0) {
716 		dev_err(card->dev, "libraries loading failed: %d\n", ret);
717 		goto err_load_libs;
718 	}
719 
720 finalize:
721 	debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
722 			    &topology_name_fops);
723 
724 	mutex_lock(&adev->comp_list_mutex);
725 	list_add_tail(&acomp->node, &adev->comp_list);
726 	mutex_unlock(&adev->comp_list_mutex);
727 
728 	return 0;
729 
730 err_load_libs:
731 	avs_remove_topology(component);
732 	return ret;
733 }
734 
avs_component_remove(struct snd_soc_component * component)735 static void avs_component_remove(struct snd_soc_component *component)
736 {
737 	struct avs_soc_component *acomp = to_avs_soc_component(component);
738 	struct snd_soc_acpi_mach *mach;
739 	struct avs_dev *adev = to_avs_dev(component->dev);
740 	int ret;
741 
742 	mach = dev_get_platdata(component->card->dev);
743 
744 	mutex_lock(&adev->comp_list_mutex);
745 	list_del(&acomp->node);
746 	mutex_unlock(&adev->comp_list_mutex);
747 
748 	if (mach->tplg_filename) {
749 		ret = avs_remove_topology(component);
750 		if (ret < 0)
751 			dev_err(component->dev, "unload topology failed: %d\n", ret);
752 	}
753 }
754 
avs_component_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)755 static int avs_component_open(struct snd_soc_component *component,
756 			      struct snd_pcm_substream *substream)
757 {
758 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
759 	struct snd_pcm_hardware hwparams;
760 
761 	/* only FE DAI links are handled here */
762 	if (rtd->dai_link->no_pcm)
763 		return 0;
764 
765 	hwparams.info = SNDRV_PCM_INFO_MMAP |
766 			SNDRV_PCM_INFO_MMAP_VALID |
767 			SNDRV_PCM_INFO_INTERLEAVED |
768 			SNDRV_PCM_INFO_PAUSE |
769 			SNDRV_PCM_INFO_NO_PERIOD_WAKEUP;
770 
771 	hwparams.formats = SNDRV_PCM_FMTBIT_S16_LE |
772 			   SNDRV_PCM_FMTBIT_S24_LE |
773 			   SNDRV_PCM_FMTBIT_S32_LE;
774 	hwparams.period_bytes_min = 128;
775 	hwparams.period_bytes_max = AZX_MAX_BUF_SIZE / 2;
776 	hwparams.periods_min = 2;
777 	hwparams.periods_max = AZX_MAX_FRAG;
778 	hwparams.buffer_bytes_max = AZX_MAX_BUF_SIZE;
779 	hwparams.fifo_size = 0;
780 
781 	return snd_soc_set_runtime_hwparams(substream, &hwparams);
782 }
783 
avs_hda_stream_dpib_read(struct hdac_ext_stream * stream)784 static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
785 {
786 	return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
787 		     (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
788 }
789 
790 static snd_pcm_uframes_t
avs_component_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)791 avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
792 {
793 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
794 	struct avs_dma_data *data;
795 	struct hdac_ext_stream *host_stream;
796 	unsigned int pos;
797 
798 	data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
799 	if (!data->host_stream)
800 		return 0;
801 
802 	host_stream = data->host_stream;
803 	pos = avs_hda_stream_dpib_read(host_stream);
804 
805 	if (pos >= hdac_stream(host_stream)->bufsize)
806 		pos = 0;
807 
808 	return bytes_to_frames(substream->runtime, pos);
809 }
810 
avs_component_mmap(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct vm_area_struct * vma)811 static int avs_component_mmap(struct snd_soc_component *component,
812 			      struct snd_pcm_substream *substream,
813 			      struct vm_area_struct *vma)
814 {
815 	return snd_pcm_lib_default_mmap(substream, vma);
816 }
817 
818 #define MAX_PREALLOC_SIZE	(32 * 1024 * 1024)
819 
avs_component_construct(struct snd_soc_component * component,struct snd_soc_pcm_runtime * rtd)820 static int avs_component_construct(struct snd_soc_component *component,
821 				   struct snd_soc_pcm_runtime *rtd)
822 {
823 	struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
824 	struct snd_pcm *pcm = rtd->pcm;
825 
826 	if (dai->driver->playback.channels_min)
827 		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
828 					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
829 					   MAX_PREALLOC_SIZE);
830 
831 	if (dai->driver->capture.channels_min)
832 		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
833 					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
834 					   MAX_PREALLOC_SIZE);
835 
836 	return 0;
837 }
838 
839 static const struct snd_soc_component_driver avs_component_driver = {
840 	.name			= "avs-pcm",
841 	.probe			= avs_component_probe,
842 	.remove			= avs_component_remove,
843 	.open			= avs_component_open,
844 	.pointer		= avs_component_pointer,
845 	.mmap			= avs_component_mmap,
846 	.pcm_construct		= avs_component_construct,
847 	.module_get_upon_open	= 1, /* increment refcount when a pcm is opened */
848 	.topology_name_prefix	= "intel/avs",
849 	.non_legacy_dai_naming	= true,
850 };
851 
avs_soc_component_register(struct device * dev,const char * name,const struct snd_soc_component_driver * drv,struct snd_soc_dai_driver * cpu_dais,int num_cpu_dais)852 static int avs_soc_component_register(struct device *dev, const char *name,
853 				      const struct snd_soc_component_driver *drv,
854 				      struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
855 {
856 	struct avs_soc_component *acomp;
857 	int ret;
858 
859 	acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
860 	if (!acomp)
861 		return -ENOMEM;
862 
863 	ret = snd_soc_component_initialize(&acomp->base, drv, dev);
864 	if (ret < 0)
865 		return ret;
866 
867 	/* force name change after ASoC is done with its init */
868 	acomp->base.name = name;
869 	INIT_LIST_HEAD(&acomp->node);
870 
871 	return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
872 }
873 
874 static struct snd_soc_dai_driver dmic_cpu_dais[] = {
875 {
876 	.name = "DMIC Pin",
877 	.ops = &avs_dai_nonhda_be_ops,
878 	.capture = {
879 		.stream_name	= "DMIC Rx",
880 		.channels_min	= 1,
881 		.channels_max	= 4,
882 		.rates		= SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
883 		.formats	= SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
884 	},
885 },
886 {
887 	.name = "DMIC WoV Pin",
888 	.ops = &avs_dai_nonhda_be_ops,
889 	.capture = {
890 		.stream_name	= "DMIC WoV Rx",
891 		.channels_min	= 1,
892 		.channels_max	= 4,
893 		.rates		= SNDRV_PCM_RATE_16000,
894 		.formats	= SNDRV_PCM_FMTBIT_S16_LE,
895 	},
896 },
897 };
898 
avs_dmic_platform_register(struct avs_dev * adev,const char * name)899 int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
900 {
901 	return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
902 					  ARRAY_SIZE(dmic_cpu_dais));
903 }
904 
905 static const struct snd_soc_dai_driver i2s_dai_template = {
906 	.ops = &avs_dai_nonhda_be_ops,
907 	.playback = {
908 		.channels_min	= 1,
909 		.channels_max	= 8,
910 		.rates		= SNDRV_PCM_RATE_8000_192000 |
911 				  SNDRV_PCM_RATE_KNOT,
912 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
913 				  SNDRV_PCM_FMTBIT_S24_LE |
914 				  SNDRV_PCM_FMTBIT_S32_LE,
915 	},
916 	.capture = {
917 		.channels_min	= 1,
918 		.channels_max	= 8,
919 		.rates		= SNDRV_PCM_RATE_8000_192000 |
920 				  SNDRV_PCM_RATE_KNOT,
921 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
922 				  SNDRV_PCM_FMTBIT_S24_LE |
923 				  SNDRV_PCM_FMTBIT_S32_LE,
924 	},
925 };
926 
avs_i2s_platform_register(struct avs_dev * adev,const char * name,unsigned long port_mask,unsigned long * tdms)927 int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
928 			      unsigned long *tdms)
929 {
930 	struct snd_soc_dai_driver *cpus, *dai;
931 	size_t ssp_count, cpu_count;
932 	int i, j;
933 
934 	ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
935 	cpu_count = hweight_long(port_mask);
936 	if (tdms)
937 		for_each_set_bit(i, &port_mask, ssp_count)
938 			cpu_count += hweight_long(tdms[i]);
939 
940 	cpus = devm_kzalloc(adev->dev, sizeof(*cpus) * cpu_count, GFP_KERNEL);
941 	if (!cpus)
942 		return -ENOMEM;
943 
944 	dai = cpus;
945 	for_each_set_bit(i, &port_mask, ssp_count) {
946 		memcpy(dai, &i2s_dai_template, sizeof(*dai));
947 
948 		dai->name =
949 			devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
950 		dai->playback.stream_name =
951 			devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
952 		dai->capture.stream_name =
953 			devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
954 
955 		if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
956 			return -ENOMEM;
957 		dai++;
958 	}
959 
960 	if (!tdms)
961 		goto plat_register;
962 
963 	for_each_set_bit(i, &port_mask, ssp_count) {
964 		for_each_set_bit(j, &tdms[i], ssp_count) {
965 			memcpy(dai, &i2s_dai_template, sizeof(*dai));
966 
967 			dai->name =
968 				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
969 			dai->playback.stream_name =
970 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
971 			dai->capture.stream_name =
972 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
973 
974 			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
975 				return -ENOMEM;
976 			dai++;
977 		}
978 	}
979 
980 plat_register:
981 	return avs_soc_component_register(adev->dev, name, &avs_component_driver, cpus, cpu_count);
982 }
983 
984 /* HD-Audio CPU DAI template */
985 static const struct snd_soc_dai_driver hda_cpu_dai = {
986 	.ops = &avs_dai_hda_be_ops,
987 	.playback = {
988 		.channels_min	= 1,
989 		.channels_max	= 8,
990 		.rates		= SNDRV_PCM_RATE_8000_192000,
991 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
992 				  SNDRV_PCM_FMTBIT_S24_LE |
993 				  SNDRV_PCM_FMTBIT_S32_LE,
994 	},
995 	.capture = {
996 		.channels_min	= 1,
997 		.channels_max	= 8,
998 		.rates		= SNDRV_PCM_RATE_8000_192000,
999 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1000 				  SNDRV_PCM_FMTBIT_S24_LE |
1001 				  SNDRV_PCM_FMTBIT_S32_LE,
1002 	},
1003 };
1004 
avs_component_hda_unregister_dais(struct snd_soc_component * component)1005 static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1006 {
1007 	struct snd_soc_acpi_mach *mach;
1008 	struct snd_soc_dai *dai, *save;
1009 	struct hda_codec *codec;
1010 	char name[32];
1011 
1012 	mach = dev_get_platdata(component->card->dev);
1013 	codec = mach->pdata;
1014 	sprintf(name, "%s-cpu", dev_name(&codec->core.dev));
1015 
1016 	for_each_component_dais_safe(component, dai, save) {
1017 		if (!strstr(dai->driver->name, name))
1018 			continue;
1019 
1020 		if (dai->playback_widget)
1021 			snd_soc_dapm_free_widget(dai->playback_widget);
1022 		if (dai->capture_widget)
1023 			snd_soc_dapm_free_widget(dai->capture_widget);
1024 		snd_soc_unregister_dai(dai);
1025 	}
1026 }
1027 
avs_component_hda_probe(struct snd_soc_component * component)1028 static int avs_component_hda_probe(struct snd_soc_component *component)
1029 {
1030 	struct snd_soc_dapm_context *dapm;
1031 	struct snd_soc_dai_driver *dais;
1032 	struct snd_soc_acpi_mach *mach;
1033 	struct hda_codec *codec;
1034 	struct hda_pcm *pcm;
1035 	const char *cname;
1036 	int pcm_count = 0, ret, i;
1037 
1038 	mach = dev_get_platdata(component->card->dev);
1039 	if (!mach)
1040 		return -EINVAL;
1041 
1042 	codec = mach->pdata;
1043 	if (list_empty(&codec->pcm_list_head))
1044 		return -EINVAL;
1045 	list_for_each_entry(pcm, &codec->pcm_list_head, list)
1046 		pcm_count++;
1047 
1048 	dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1049 			    GFP_KERNEL);
1050 	if (!dais)
1051 		return -ENOMEM;
1052 
1053 	cname = dev_name(&codec->core.dev);
1054 	dapm = snd_soc_component_get_dapm(component);
1055 	pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1056 
1057 	for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1058 		struct snd_soc_dai *dai;
1059 
1060 		memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1061 		dais[i].id = i;
1062 		dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1063 					      "%s-cpu%d", cname, i);
1064 		if (!dais[i].name) {
1065 			ret = -ENOMEM;
1066 			goto exit;
1067 		}
1068 
1069 		if (pcm->stream[0].substreams) {
1070 			dais[i].playback.stream_name =
1071 				devm_kasprintf(component->dev, GFP_KERNEL,
1072 					       "%s-cpu%d Tx", cname, i);
1073 			if (!dais[i].playback.stream_name) {
1074 				ret = -ENOMEM;
1075 				goto exit;
1076 			}
1077 		}
1078 
1079 		if (pcm->stream[1].substreams) {
1080 			dais[i].capture.stream_name =
1081 				devm_kasprintf(component->dev, GFP_KERNEL,
1082 					       "%s-cpu%d Rx", cname, i);
1083 			if (!dais[i].capture.stream_name) {
1084 				ret = -ENOMEM;
1085 				goto exit;
1086 			}
1087 		}
1088 
1089 		dai = snd_soc_register_dai(component, &dais[i], false);
1090 		if (!dai) {
1091 			dev_err(component->dev, "register dai for %s failed\n",
1092 				pcm->name);
1093 			ret = -EINVAL;
1094 			goto exit;
1095 		}
1096 
1097 		ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1098 		if (ret < 0) {
1099 			dev_err(component->dev, "create widgets failed: %d\n",
1100 				ret);
1101 			goto exit;
1102 		}
1103 	}
1104 
1105 	ret = avs_component_probe(component);
1106 exit:
1107 	if (ret)
1108 		avs_component_hda_unregister_dais(component);
1109 
1110 	return ret;
1111 }
1112 
avs_component_hda_remove(struct snd_soc_component * component)1113 static void avs_component_hda_remove(struct snd_soc_component *component)
1114 {
1115 	avs_component_hda_unregister_dais(component);
1116 	avs_component_remove(component);
1117 }
1118 
avs_component_hda_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)1119 static int avs_component_hda_open(struct snd_soc_component *component,
1120 				  struct snd_pcm_substream *substream)
1121 {
1122 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1123 	struct hdac_ext_stream *link_stream;
1124 	struct hda_codec *codec;
1125 
1126 	/* only BE DAI links are handled here */
1127 	if (!rtd->dai_link->no_pcm)
1128 		return avs_component_open(component, substream);
1129 
1130 	codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
1131 	link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
1132 					     HDAC_EXT_STREAM_TYPE_LINK);
1133 	if (!link_stream)
1134 		return -EBUSY;
1135 
1136 	substream->runtime->private_data = link_stream;
1137 	return 0;
1138 }
1139 
avs_component_hda_close(struct snd_soc_component * component,struct snd_pcm_substream * substream)1140 static int avs_component_hda_close(struct snd_soc_component *component,
1141 				   struct snd_pcm_substream *substream)
1142 {
1143 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1144 	struct hdac_ext_stream *link_stream;
1145 
1146 	/* only BE DAI links are handled here */
1147 	if (!rtd->dai_link->no_pcm)
1148 		return 0;
1149 
1150 	link_stream = substream->runtime->private_data;
1151 	snd_hdac_ext_stream_release(link_stream, HDAC_EXT_STREAM_TYPE_LINK);
1152 	substream->runtime->private_data = NULL;
1153 
1154 	return 0;
1155 }
1156 
1157 static const struct snd_soc_component_driver avs_hda_component_driver = {
1158 	.name			= "avs-hda-pcm",
1159 	.probe			= avs_component_hda_probe,
1160 	.remove			= avs_component_hda_remove,
1161 	.open			= avs_component_hda_open,
1162 	.close			= avs_component_hda_close,
1163 	.pointer		= avs_component_pointer,
1164 	.mmap			= avs_component_mmap,
1165 	.pcm_construct		= avs_component_construct,
1166 	/*
1167 	 * hda platform component's probe() is dependent on
1168 	 * codec->pcm_list_head, it needs to be initialized after codec
1169 	 * component. remove_order is here for completeness sake
1170 	 */
1171 	.probe_order		= SND_SOC_COMP_ORDER_LATE,
1172 	.remove_order		= SND_SOC_COMP_ORDER_EARLY,
1173 	.module_get_upon_open	= 1,
1174 	.topology_name_prefix	= "intel/avs",
1175 	.non_legacy_dai_naming	= true,
1176 };
1177 
avs_hda_platform_register(struct avs_dev * adev,const char * name)1178 int avs_hda_platform_register(struct avs_dev *adev, const char *name)
1179 {
1180 	return avs_soc_component_register(adev->dev, name,
1181 					  &avs_hda_component_driver, NULL, 0);
1182 }
1183