xref: /linux/sound/soc/intel/avs/pcm.c (revision 177bf8620cf4ed290ee170a6c5966adc0924b336)
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_put_autosuspend(adev->dev);
983 
984 	return ret;
985 }
986 
avs_component_probe(struct snd_soc_component * component)987 static int avs_component_probe(struct snd_soc_component *component)
988 {
989 	struct snd_soc_card *card = component->card;
990 	struct snd_soc_acpi_mach *mach;
991 	struct avs_soc_component *acomp;
992 	struct avs_dev *adev;
993 	char *filename;
994 	int ret;
995 
996 	dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
997 	mach = dev_get_platdata(card->dev);
998 	acomp = to_avs_soc_component(component);
999 	adev = to_avs_dev(component->dev);
1000 
1001 	acomp->tplg = avs_tplg_new(component);
1002 	if (!acomp->tplg)
1003 		return -ENOMEM;
1004 
1005 	if (!mach->tplg_filename)
1006 		goto finalize;
1007 
1008 	/* Load specified topology and create debugfs for it. */
1009 	filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
1010 			     mach->tplg_filename);
1011 	if (!filename)
1012 		return -ENOMEM;
1013 
1014 	ret = avs_load_topology(component, filename);
1015 	kfree(filename);
1016 	if (ret == -ENOENT && !strncmp(mach->tplg_filename, "hda-", 4)) {
1017 		unsigned int vendor_id;
1018 
1019 		if (sscanf(mach->tplg_filename, "hda-%08x-tplg.bin", &vendor_id) != 1)
1020 			return ret;
1021 
1022 		if (((vendor_id >> 16) & 0xFFFF) == 0x8086)
1023 			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
1024 							     "hda-8086-generic-tplg.bin");
1025 		else
1026 			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
1027 							     "hda-generic-tplg.bin");
1028 		if (!mach->tplg_filename)
1029 			return -ENOMEM;
1030 		filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
1031 				     mach->tplg_filename);
1032 		if (!filename)
1033 			return -ENOMEM;
1034 
1035 		dev_info(card->dev, "trying to load fallback topology %s\n", mach->tplg_filename);
1036 		ret = avs_load_topology(component, filename);
1037 		kfree(filename);
1038 	}
1039 	if (ret < 0)
1040 		return ret;
1041 
1042 	ret = avs_component_load_libraries(acomp);
1043 	if (ret < 0) {
1044 		dev_err(card->dev, "libraries loading failed: %d\n", ret);
1045 		goto err_load_libs;
1046 	}
1047 
1048 finalize:
1049 	debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
1050 			    &topology_name_fops);
1051 
1052 	mutex_lock(&adev->comp_list_mutex);
1053 	list_add_tail(&acomp->node, &adev->comp_list);
1054 	mutex_unlock(&adev->comp_list_mutex);
1055 
1056 	return 0;
1057 
1058 err_load_libs:
1059 	avs_remove_topology(component);
1060 	return ret;
1061 }
1062 
avs_component_remove(struct snd_soc_component * component)1063 static void avs_component_remove(struct snd_soc_component *component)
1064 {
1065 	struct avs_soc_component *acomp = to_avs_soc_component(component);
1066 	struct snd_soc_acpi_mach *mach;
1067 	struct avs_dev *adev = to_avs_dev(component->dev);
1068 	int ret;
1069 
1070 	mach = dev_get_platdata(component->card->dev);
1071 
1072 	mutex_lock(&adev->comp_list_mutex);
1073 	list_del(&acomp->node);
1074 	mutex_unlock(&adev->comp_list_mutex);
1075 
1076 	if (mach->tplg_filename) {
1077 		ret = avs_remove_topology(component);
1078 		if (ret < 0)
1079 			dev_err(component->dev, "unload topology failed: %d\n", ret);
1080 	}
1081 }
1082 
avs_dai_resume_hw_params(struct snd_soc_dai * dai,struct avs_dma_data * data)1083 static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data)
1084 {
1085 	struct snd_pcm_substream *substream;
1086 	struct snd_soc_pcm_runtime *rtd;
1087 	int ret;
1088 
1089 	substream = data->substream;
1090 	rtd = snd_soc_substream_to_rtd(substream);
1091 
1092 	ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai);
1093 	if (ret)
1094 		dev_err(dai->dev, "hw_params on resume failed: %d\n", ret);
1095 
1096 	return ret;
1097 }
1098 
avs_dai_resume_fe_prepare(struct snd_soc_dai * dai,struct avs_dma_data * data)1099 static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
1100 {
1101 	struct hdac_ext_stream *host_stream;
1102 	struct hdac_stream *hstream;
1103 	struct hdac_bus *bus;
1104 	int ret;
1105 
1106 	host_stream = data->host_stream;
1107 	hstream = hdac_stream(host_stream);
1108 	bus = hdac_stream(host_stream)->bus;
1109 
1110 	/* Set DRSM before programming stream and position registers. */
1111 	snd_hdac_stream_drsm_enable(bus, true, hstream->index);
1112 
1113 	ret = dai->driver->ops->prepare(data->substream, dai);
1114 	if (ret) {
1115 		dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret);
1116 		return ret;
1117 	}
1118 
1119 	writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1120 	writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1121 	writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1122 	writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1123 
1124 	/* As per HW spec recommendation, program LPIB and DPIB to the same value. */
1125 	snd_hdac_stream_set_lpib(hstream, hstream->lpib);
1126 	snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
1127 
1128 	return 0;
1129 }
1130 
avs_dai_resume_be_prepare(struct snd_soc_dai * dai,struct avs_dma_data * data)1131 static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
1132 {
1133 	int ret;
1134 
1135 	ret = dai->driver->ops->prepare(data->substream, dai);
1136 	if (ret)
1137 		dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret);
1138 
1139 	return ret;
1140 }
1141 
avs_dai_suspend_fe_hw_free(struct snd_soc_dai * dai,struct avs_dma_data * data)1142 static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1143 {
1144 	struct hdac_ext_stream *host_stream;
1145 	int ret;
1146 
1147 	host_stream = data->host_stream;
1148 
1149 	/* Store position addresses so we can resume from them later on. */
1150 	hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream));
1151 	host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1152 	host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1153 	host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1154 	host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1155 
1156 	ret = __avs_dai_fe_hw_free(data->substream, dai);
1157 	if (ret < 0)
1158 		dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret);
1159 
1160 	return ret;
1161 }
1162 
avs_dai_suspend_be_hw_free(struct snd_soc_dai * dai,struct avs_dma_data * data)1163 static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1164 {
1165 	int ret;
1166 
1167 	ret = dai->driver->ops->hw_free(data->substream, dai);
1168 	if (ret < 0)
1169 		dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret);
1170 
1171 	return ret;
1172 }
1173 
avs_component_pm_op(struct snd_soc_component * component,bool be,int (* op)(struct snd_soc_dai *,struct avs_dma_data *))1174 static int avs_component_pm_op(struct snd_soc_component *component, bool be,
1175 			       int (*op)(struct snd_soc_dai *, struct avs_dma_data *))
1176 {
1177 	struct snd_soc_pcm_runtime *rtd;
1178 	struct avs_dma_data *data;
1179 	struct snd_soc_dai *dai;
1180 	int ret;
1181 
1182 	for_each_component_dais(component, dai) {
1183 		data = snd_soc_dai_dma_data_get_playback(dai);
1184 		if (data) {
1185 			rtd = snd_soc_substream_to_rtd(data->substream);
1186 			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1187 				ret = op(dai, data);
1188 				if (ret < 0) {
1189 					__snd_pcm_set_state(data->substream->runtime,
1190 							    SNDRV_PCM_STATE_DISCONNECTED);
1191 					return ret;
1192 				}
1193 			}
1194 		}
1195 
1196 		data = snd_soc_dai_dma_data_get_capture(dai);
1197 		if (data) {
1198 			rtd = snd_soc_substream_to_rtd(data->substream);
1199 			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1200 				ret = op(dai, data);
1201 				if (ret < 0) {
1202 					__snd_pcm_set_state(data->substream->runtime,
1203 							    SNDRV_PCM_STATE_DISCONNECTED);
1204 					return ret;
1205 				}
1206 			}
1207 		}
1208 	}
1209 
1210 	return 0;
1211 }
1212 
avs_component_resume_hw_params(struct snd_soc_component * component,bool be)1213 static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be)
1214 {
1215 	return avs_component_pm_op(component, be, &avs_dai_resume_hw_params);
1216 }
1217 
avs_component_resume_prepare(struct snd_soc_component * component,bool be)1218 static int avs_component_resume_prepare(struct snd_soc_component *component, bool be)
1219 {
1220 	int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1221 
1222 	if (be)
1223 		prepare_cb = &avs_dai_resume_be_prepare;
1224 	else
1225 		prepare_cb = &avs_dai_resume_fe_prepare;
1226 
1227 	return avs_component_pm_op(component, be, prepare_cb);
1228 }
1229 
avs_component_suspend_hw_free(struct snd_soc_component * component,bool be)1230 static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be)
1231 {
1232 	int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1233 
1234 	if (be)
1235 		hw_free_cb = &avs_dai_suspend_be_hw_free;
1236 	else
1237 		hw_free_cb = &avs_dai_suspend_fe_hw_free;
1238 
1239 	return avs_component_pm_op(component, be, hw_free_cb);
1240 }
1241 
avs_component_suspend(struct snd_soc_component * component)1242 static int avs_component_suspend(struct snd_soc_component *component)
1243 {
1244 	int ret;
1245 
1246 	/*
1247 	 * When freeing paths, FEs need to be first as they perform
1248 	 * path unbinding.
1249 	 */
1250 	ret = avs_component_suspend_hw_free(component, false);
1251 	if (ret)
1252 		return ret;
1253 
1254 	return avs_component_suspend_hw_free(component, true);
1255 }
1256 
avs_component_resume(struct snd_soc_component * component)1257 static int avs_component_resume(struct snd_soc_component *component)
1258 {
1259 	int ret;
1260 
1261 	/*
1262 	 * When creating paths, FEs need to be last as they perform
1263 	 * path binding.
1264 	 */
1265 	ret = avs_component_resume_hw_params(component, true);
1266 	if (ret)
1267 		return ret;
1268 
1269 	ret = avs_component_resume_hw_params(component, false);
1270 	if (ret)
1271 		return ret;
1272 
1273 	/* It is expected that the LINK stream is prepared first. */
1274 	ret = avs_component_resume_prepare(component, true);
1275 	if (ret)
1276 		return ret;
1277 
1278 	return avs_component_resume_prepare(component, false);
1279 }
1280 
1281 static const struct snd_pcm_hardware avs_pcm_hardware = {
1282 	.info			= SNDRV_PCM_INFO_MMAP |
1283 				  SNDRV_PCM_INFO_MMAP_VALID |
1284 				  SNDRV_PCM_INFO_INTERLEAVED |
1285 				  SNDRV_PCM_INFO_PAUSE |
1286 				  SNDRV_PCM_INFO_RESUME |
1287 				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
1288 	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
1289 				  SNDRV_PCM_FMTBIT_S32_LE,
1290 	.subformats		= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1291 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1292 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1293 	.buffer_bytes_max	= AZX_MAX_BUF_SIZE,
1294 	.period_bytes_min	= 128,
1295 	.period_bytes_max	= AZX_MAX_BUF_SIZE / 2,
1296 	.periods_min		= 2,
1297 	.periods_max		= AZX_MAX_FRAG,
1298 	.fifo_size		= 0,
1299 };
1300 
avs_component_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)1301 static int avs_component_open(struct snd_soc_component *component,
1302 			      struct snd_pcm_substream *substream)
1303 {
1304 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1305 
1306 	/* only FE DAI links are handled here */
1307 	if (rtd->dai_link->no_pcm)
1308 		return 0;
1309 
1310 	return snd_soc_set_runtime_hwparams(substream, &avs_pcm_hardware);
1311 }
1312 
avs_hda_stream_dpib_read(struct hdac_ext_stream * stream)1313 static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
1314 {
1315 	return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1316 		     (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
1317 }
1318 
1319 static snd_pcm_uframes_t
avs_component_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)1320 avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
1321 {
1322 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1323 	struct avs_dma_data *data;
1324 	struct hdac_ext_stream *host_stream;
1325 	unsigned int pos;
1326 
1327 	data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0), substream);
1328 	if (!data->host_stream)
1329 		return 0;
1330 
1331 	host_stream = data->host_stream;
1332 	pos = avs_hda_stream_dpib_read(host_stream);
1333 
1334 	if (pos >= hdac_stream(host_stream)->bufsize)
1335 		pos = 0;
1336 
1337 	return bytes_to_frames(substream->runtime, pos);
1338 }
1339 
avs_component_mmap(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct vm_area_struct * vma)1340 static int avs_component_mmap(struct snd_soc_component *component,
1341 			      struct snd_pcm_substream *substream,
1342 			      struct vm_area_struct *vma)
1343 {
1344 	return snd_pcm_lib_default_mmap(substream, vma);
1345 }
1346 
1347 #define MAX_PREALLOC_SIZE	(32 * 1024 * 1024)
1348 
avs_component_construct(struct snd_soc_component * component,struct snd_soc_pcm_runtime * rtd)1349 static int avs_component_construct(struct snd_soc_component *component,
1350 				   struct snd_soc_pcm_runtime *rtd)
1351 {
1352 	struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
1353 	struct snd_pcm *pcm = rtd->pcm;
1354 
1355 	if (dai->driver->playback.channels_min)
1356 		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
1357 					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1358 					   MAX_PREALLOC_SIZE);
1359 
1360 	if (dai->driver->capture.channels_min)
1361 		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
1362 					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1363 					   MAX_PREALLOC_SIZE);
1364 
1365 	return 0;
1366 }
1367 
1368 static struct snd_soc_component_driver avs_component_driver = {
1369 	.name			= "avs-pcm",
1370 	.probe			= avs_component_probe,
1371 	.remove			= avs_component_remove,
1372 	.suspend		= avs_component_suspend,
1373 	.resume			= avs_component_resume,
1374 	.open			= avs_component_open,
1375 	.pointer		= avs_component_pointer,
1376 	.mmap			= avs_component_mmap,
1377 	.pcm_construct		= avs_component_construct,
1378 	.module_get_upon_open	= 1, /* increment refcount when a pcm is opened */
1379 	.topology_name_prefix	= "intel/avs",
1380 };
1381 
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)1382 int avs_soc_component_register(struct device *dev, const char *name,
1383 			       struct snd_soc_component_driver *drv,
1384 			       struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
1385 {
1386 	struct avs_soc_component *acomp;
1387 	int ret;
1388 
1389 	acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
1390 	if (!acomp)
1391 		return -ENOMEM;
1392 
1393 	ret = snd_soc_component_initialize(&acomp->base, drv, dev);
1394 	if (ret < 0)
1395 		return ret;
1396 
1397 	/* force name change after ASoC is done with its init */
1398 	acomp->base.name = name;
1399 	INIT_LIST_HEAD(&acomp->node);
1400 
1401 	drv->use_dai_pcm_id = !obsolete_card_names;
1402 
1403 	return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
1404 }
1405 
1406 static struct snd_soc_dai_driver dmic_cpu_dais[] = {
1407 {
1408 	.name = "DMIC Pin",
1409 	.capture = {
1410 		.stream_name	= "DMIC Rx",
1411 		.channels_min	= 1,
1412 		.channels_max	= 4,
1413 		.rates		= SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
1414 		.formats	= SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
1415 	},
1416 },
1417 {
1418 	.name = "DMIC WoV Pin",
1419 	.capture = {
1420 		.stream_name	= "DMIC WoV Rx",
1421 		.channels_min	= 1,
1422 		.channels_max	= 4,
1423 		.rates		= SNDRV_PCM_RATE_16000,
1424 		.formats	= SNDRV_PCM_FMTBIT_S16_LE,
1425 	},
1426 },
1427 };
1428 
avs_dmic_platform_register(struct avs_dev * adev,const char * name)1429 int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
1430 {
1431 	const struct snd_soc_dai_ops *ops;
1432 
1433 	if (avs_platattr_test(adev, ALTHDA))
1434 		ops = &avs_dai_dmichda_be_ops;
1435 	else
1436 		ops = &avs_dai_nonhda_be_ops;
1437 
1438 	dmic_cpu_dais[0].ops = ops;
1439 	dmic_cpu_dais[1].ops = ops;
1440 	return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
1441 					  ARRAY_SIZE(dmic_cpu_dais));
1442 }
1443 
1444 static const struct snd_soc_dai_driver i2s_dai_template = {
1445 	.playback = {
1446 		.channels_min	= 1,
1447 		.channels_max	= AVS_CHANNELS_MAX,
1448 		.rates		= SNDRV_PCM_RATE_8000_192000 |
1449 				  SNDRV_PCM_RATE_12000 |
1450 				  SNDRV_PCM_RATE_24000 |
1451 				  SNDRV_PCM_RATE_128000,
1452 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1453 				  SNDRV_PCM_FMTBIT_S32_LE,
1454 		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1455 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1456 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1457 	},
1458 	.capture = {
1459 		.channels_min	= 1,
1460 		.channels_max	= AVS_CHANNELS_MAX,
1461 		.rates		= SNDRV_PCM_RATE_8000_192000 |
1462 				  SNDRV_PCM_RATE_12000 |
1463 				  SNDRV_PCM_RATE_24000 |
1464 				  SNDRV_PCM_RATE_128000,
1465 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1466 				  SNDRV_PCM_FMTBIT_S32_LE,
1467 		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1468 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1469 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1470 	},
1471 };
1472 
avs_i2s_platform_register(struct avs_dev * adev,const char * name,unsigned long port_mask,unsigned long * tdms)1473 int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
1474 			      unsigned long *tdms)
1475 {
1476 	struct snd_soc_dai_driver *cpus, *dai;
1477 	const struct snd_soc_dai_ops *ops;
1478 	size_t ssp_count, cpu_count;
1479 	int i, j;
1480 
1481 	ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
1482 	if (avs_platattr_test(adev, ALTHDA))
1483 		ops = &avs_dai_i2shda_be_ops;
1484 	else
1485 		ops = &avs_dai_nonhda_be_ops;
1486 
1487 	cpu_count = 0;
1488 	for_each_set_bit(i, &port_mask, ssp_count)
1489 		if (!tdms || test_bit(0, &tdms[i]))
1490 			cpu_count++;
1491 	if (tdms)
1492 		for_each_set_bit(i, &port_mask, ssp_count)
1493 			cpu_count += hweight_long(tdms[i]);
1494 
1495 	cpus = devm_kcalloc(adev->dev, cpu_count, sizeof(*cpus), GFP_KERNEL);
1496 	if (!cpus)
1497 		return -ENOMEM;
1498 
1499 	dai = cpus;
1500 	for_each_set_bit(i, &port_mask, ssp_count) {
1501 		if (!tdms || test_bit(0, &tdms[i])) {
1502 			memcpy(dai, &i2s_dai_template, sizeof(*dai));
1503 
1504 			dai->name =
1505 				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
1506 			dai->playback.stream_name =
1507 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
1508 			dai->capture.stream_name =
1509 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
1510 
1511 			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1512 				return -ENOMEM;
1513 			dai->ops = ops;
1514 			dai++;
1515 		}
1516 	}
1517 
1518 	if (!tdms)
1519 		goto plat_register;
1520 
1521 	for_each_set_bit(i, &port_mask, ssp_count) {
1522 		for_each_set_bit(j, &tdms[i], AVS_CHANNELS_MAX) {
1523 			memcpy(dai, &i2s_dai_template, sizeof(*dai));
1524 
1525 			dai->name =
1526 				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
1527 			dai->playback.stream_name =
1528 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
1529 			dai->capture.stream_name =
1530 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
1531 
1532 			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1533 				return -ENOMEM;
1534 			dai->ops = ops;
1535 			dai++;
1536 		}
1537 	}
1538 
1539 plat_register:
1540 	return avs_soc_component_register(adev->dev, name, &avs_component_driver, cpus, cpu_count);
1541 }
1542 
1543 /* HD-Audio CPU DAI template */
1544 static const struct snd_soc_dai_driver hda_cpu_dai = {
1545 	.ops = &avs_dai_hda_be_ops,
1546 	.playback = {
1547 		.channels_min	= 1,
1548 		.channels_max	= AVS_CHANNELS_MAX,
1549 		.rates		= SNDRV_PCM_RATE_8000_192000,
1550 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1551 				  SNDRV_PCM_FMTBIT_S32_LE,
1552 		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1553 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1554 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1555 	},
1556 	.capture = {
1557 		.channels_min	= 1,
1558 		.channels_max	= AVS_CHANNELS_MAX,
1559 		.rates		= SNDRV_PCM_RATE_8000_192000,
1560 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1561 				  SNDRV_PCM_FMTBIT_S32_LE,
1562 		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1563 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1564 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1565 	},
1566 };
1567 
avs_component_hda_unregister_dais(struct snd_soc_component * component)1568 static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1569 {
1570 	struct snd_soc_acpi_mach *mach;
1571 	struct snd_soc_dai *dai, *save;
1572 	struct avs_mach_pdata *pdata;
1573 	struct hda_codec *codec;
1574 	char name[32];
1575 
1576 	mach = dev_get_platdata(component->card->dev);
1577 	pdata = mach->pdata;
1578 	codec = pdata->codec;
1579 	snprintf(name, sizeof(name), "%s-cpu", dev_name(&codec->core.dev));
1580 
1581 	for_each_component_dais_safe(component, dai, save) {
1582 		int stream;
1583 
1584 		if (!strstr(dai->driver->name, name))
1585 			continue;
1586 
1587 		for_each_pcm_streams(stream)
1588 			snd_soc_dapm_free_widget(snd_soc_dai_get_widget(dai, stream));
1589 
1590 		snd_soc_unregister_dai(dai);
1591 	}
1592 }
1593 
avs_component_hda_probe(struct snd_soc_component * component)1594 static int avs_component_hda_probe(struct snd_soc_component *component)
1595 {
1596 	struct snd_soc_dapm_context *dapm;
1597 	struct snd_soc_dai_driver *dais;
1598 	struct snd_soc_acpi_mach *mach;
1599 	struct avs_mach_pdata *pdata;
1600 	struct hda_codec *codec;
1601 	struct hda_pcm *pcm;
1602 	const char *cname;
1603 	int pcm_count = 0, ret, i;
1604 
1605 	mach = dev_get_platdata(component->card->dev);
1606 	if (!mach)
1607 		return -EINVAL;
1608 
1609 	pdata = mach->pdata;
1610 	codec = pdata->codec;
1611 	if (list_empty(&codec->pcm_list_head))
1612 		return -EINVAL;
1613 	list_for_each_entry(pcm, &codec->pcm_list_head, list)
1614 		pcm_count++;
1615 
1616 	dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1617 			    GFP_KERNEL);
1618 	if (!dais)
1619 		return -ENOMEM;
1620 
1621 	cname = dev_name(&codec->core.dev);
1622 	dapm = snd_soc_component_get_dapm(component);
1623 	pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1624 
1625 	for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1626 		struct snd_soc_dai *dai;
1627 
1628 		memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1629 		dais[i].id = i;
1630 		dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1631 					      "%s-cpu%d", cname, i);
1632 		if (!dais[i].name) {
1633 			ret = -ENOMEM;
1634 			goto exit;
1635 		}
1636 
1637 		if (pcm->stream[0].substreams) {
1638 			dais[i].playback.stream_name =
1639 				devm_kasprintf(component->dev, GFP_KERNEL,
1640 					       "%s-cpu%d Tx", cname, i);
1641 			if (!dais[i].playback.stream_name) {
1642 				ret = -ENOMEM;
1643 				goto exit;
1644 			}
1645 
1646 			if (!hda_codec_is_display(codec)) {
1647 				dais[i].playback.formats = pcm->stream[0].formats;
1648 				dais[i].playback.subformats = pcm->stream[0].subformats;
1649 				dais[i].playback.rates = pcm->stream[0].rates;
1650 				dais[i].playback.channels_min = pcm->stream[0].channels_min;
1651 				dais[i].playback.channels_max = pcm->stream[0].channels_max;
1652 				dais[i].playback.sig_bits = pcm->stream[0].maxbps;
1653 			}
1654 		}
1655 
1656 		if (pcm->stream[1].substreams) {
1657 			dais[i].capture.stream_name =
1658 				devm_kasprintf(component->dev, GFP_KERNEL,
1659 					       "%s-cpu%d Rx", cname, i);
1660 			if (!dais[i].capture.stream_name) {
1661 				ret = -ENOMEM;
1662 				goto exit;
1663 			}
1664 
1665 			if (!hda_codec_is_display(codec)) {
1666 				dais[i].capture.formats = pcm->stream[1].formats;
1667 				dais[i].capture.subformats = pcm->stream[1].subformats;
1668 				dais[i].capture.rates = pcm->stream[1].rates;
1669 				dais[i].capture.channels_min = pcm->stream[1].channels_min;
1670 				dais[i].capture.channels_max = pcm->stream[1].channels_max;
1671 				dais[i].capture.sig_bits = pcm->stream[1].maxbps;
1672 			}
1673 		}
1674 
1675 		dai = snd_soc_register_dai(component, &dais[i], false);
1676 		if (!dai) {
1677 			dev_err(component->dev, "register dai for %s failed\n",
1678 				pcm->name);
1679 			ret = -EINVAL;
1680 			goto exit;
1681 		}
1682 
1683 		ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1684 		if (ret < 0) {
1685 			dev_err(component->dev, "create widgets failed: %d\n",
1686 				ret);
1687 			snd_soc_unregister_dai(dai);
1688 			goto exit;
1689 		}
1690 	}
1691 
1692 	ret = avs_component_probe(component);
1693 exit:
1694 	if (ret)
1695 		avs_component_hda_unregister_dais(component);
1696 
1697 	return ret;
1698 }
1699 
avs_component_hda_remove(struct snd_soc_component * component)1700 static void avs_component_hda_remove(struct snd_soc_component *component)
1701 {
1702 	avs_component_remove(component);
1703 	avs_component_hda_unregister_dais(component);
1704 }
1705 
avs_component_hda_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)1706 static int avs_component_hda_open(struct snd_soc_component *component,
1707 				  struct snd_pcm_substream *substream)
1708 {
1709 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1710 
1711 	if (!rtd->dai_link->no_pcm) {
1712 		struct snd_pcm_hardware hwparams = avs_pcm_hardware;
1713 		struct snd_soc_pcm_runtime *be;
1714 		struct snd_soc_dpcm *dpcm;
1715 		int dir = substream->stream;
1716 
1717 		/*
1718 		 * Support the DPCM reparenting while still fulfilling expectations of HDAudio
1719 		 * common code - a valid stream pointer at substream->runtime->private_data -
1720 		 * by having all FEs point to the same private data.
1721 		 */
1722 		for_each_dpcm_be(rtd, dir, dpcm) {
1723 			struct snd_pcm_substream *be_substream;
1724 
1725 			be = dpcm->be;
1726 			if (be->dpcm[dir].users == 1)
1727 				break;
1728 
1729 			be_substream = snd_soc_dpcm_get_substream(be, dir);
1730 			substream->runtime->private_data = be_substream->runtime->private_data;
1731 			break;
1732 		}
1733 
1734 		/* RESUME unsupported for de-coupled HD-Audio capture. */
1735 		if (dir == SNDRV_PCM_STREAM_CAPTURE)
1736 			hwparams.info &= ~SNDRV_PCM_INFO_RESUME;
1737 
1738 		return snd_soc_set_runtime_hwparams(substream, &hwparams);
1739 	}
1740 
1741 	return 0;
1742 }
1743 
1744 static struct snd_soc_component_driver avs_hda_component_driver = {
1745 	.name			= "avs-hda-pcm",
1746 	.probe			= avs_component_hda_probe,
1747 	.remove			= avs_component_hda_remove,
1748 	.suspend		= avs_component_suspend,
1749 	.resume			= avs_component_resume,
1750 	.open			= avs_component_hda_open,
1751 	.pointer		= avs_component_pointer,
1752 	.mmap			= avs_component_mmap,
1753 	.pcm_construct		= avs_component_construct,
1754 	/*
1755 	 * hda platform component's probe() is dependent on
1756 	 * codec->pcm_list_head, it needs to be initialized after codec
1757 	 * component. remove_order is here for completeness sake
1758 	 */
1759 	.probe_order		= SND_SOC_COMP_ORDER_LATE,
1760 	.remove_order		= SND_SOC_COMP_ORDER_EARLY,
1761 	.module_get_upon_open	= 1,
1762 	.topology_name_prefix	= "intel/avs",
1763 };
1764 
avs_hda_platform_register(struct avs_dev * adev,const char * name)1765 int avs_hda_platform_register(struct avs_dev *adev, const char *name)
1766 {
1767 	return avs_soc_component_register(adev->dev, name,
1768 					  &avs_hda_component_driver, NULL, 0);
1769 }
1770