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