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