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 	disable_work_sync(&data->period_elapsed_work);
655 	snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
656 	avs_dai_shutdown(substream, dai);
657 }
658 
avs_dai_fe_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params,struct snd_soc_dai * dai)659 static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
660 				struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
661 {
662 	struct snd_pcm_hw_params *be_hw_params = NULL;
663 	struct snd_soc_pcm_runtime *fe, *be;
664 	struct snd_soc_dpcm *dpcm;
665 	struct avs_dma_data *data;
666 	struct hdac_ext_stream *host_stream;
667 	int ret;
668 
669 	data = snd_soc_dai_get_dma_data(dai, substream);
670 	if (data->path)
671 		return 0;
672 
673 	host_stream = data->host_stream;
674 
675 	hdac_stream(host_stream)->bufsize = 0;
676 	hdac_stream(host_stream)->period_bytes = 0;
677 	hdac_stream(host_stream)->format_val = 0;
678 
679 	fe = snd_soc_substream_to_rtd(substream);
680 	/* dpcm_fe_dai_open() guarantees the list is not empty at this point. */
681 	for_each_dpcm_be(fe, substream->stream, dpcm) {
682 		be = dpcm->be;
683 		be_hw_params = &be->dpcm[substream->stream].hw_params;
684 	}
685 
686 	ret = avs_dai_hw_params(substream, hw_params, be_hw_params, dai,
687 				hdac_stream(host_stream)->stream_tag - 1);
688 	if (ret)
689 		goto create_err;
690 
691 	ret = avs_path_bind(data->path);
692 	if (ret < 0) {
693 		dev_err(dai->dev, "bind FE <-> BE failed: %d\n", ret);
694 		goto bind_err;
695 	}
696 
697 	return 0;
698 
699 bind_err:
700 	avs_path_free(data->path);
701 	data->path = NULL;
702 create_err:
703 	snd_pcm_lib_free_pages(substream);
704 	return ret;
705 }
706 
__avs_dai_fe_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)707 static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
708 {
709 	struct avs_dma_data *data;
710 	struct hdac_ext_stream *host_stream;
711 	int ret;
712 
713 	dev_dbg(dai->dev, "%s fe HW_FREE str %p rtd %p",
714 		__func__, substream, substream->runtime);
715 
716 	data = snd_soc_dai_get_dma_data(dai, substream);
717 	if (!data->path)
718 		return 0;
719 
720 	host_stream = data->host_stream;
721 
722 	ret = avs_path_unbind(data->path);
723 	if (ret < 0)
724 		dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
725 
726 	avs_path_free(data->path);
727 	data->path = NULL;
728 	snd_hdac_stream_cleanup(hdac_stream(host_stream));
729 	hdac_stream(host_stream)->prepared = false;
730 
731 	return ret;
732 }
733 
avs_dai_fe_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)734 static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
735 {
736 	int ret;
737 
738 	ret = __avs_dai_fe_hw_free(substream, dai);
739 	snd_pcm_lib_free_pages(substream);
740 
741 	return ret;
742 }
743 
avs_dai_fe_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)744 static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
745 {
746 	struct snd_pcm_runtime *runtime = substream->runtime;
747 	const struct snd_soc_pcm_stream *stream_info;
748 	struct avs_dma_data *data;
749 	struct hdac_ext_stream *host_stream;
750 	unsigned int format_val;
751 	struct hdac_bus *bus;
752 	unsigned int bits;
753 	int ret;
754 
755 	data = snd_soc_dai_get_dma_data(dai, substream);
756 	host_stream = data->host_stream;
757 
758 	if (runtime->state == SNDRV_PCM_STATE_XRUN)
759 		hdac_stream(host_stream)->prepared = false;
760 	if (hdac_stream(host_stream)->prepared)
761 		return 0;
762 
763 	bus = hdac_stream(host_stream)->bus;
764 	snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
765 	snd_hdac_stream_reset(hdac_stream(host_stream));
766 
767 	stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
768 	bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
769 					   stream_info->sig_bits);
770 	format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
771 
772 	ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
773 	if (ret < 0)
774 		return ret;
775 
776 	ret = snd_hdac_ext_host_stream_setup(host_stream, false);
777 	if (ret < 0)
778 		return ret;
779 
780 	ret = avs_dai_prepare(substream, dai);
781 	if (ret)
782 		return ret;
783 
784 	hdac_stream(host_stream)->prepared = true;
785 	return 0;
786 }
787 
avs_hda_stream_start(struct hdac_bus * bus,struct hdac_ext_stream * host_stream)788 static void avs_hda_stream_start(struct hdac_bus *bus, struct hdac_ext_stream *host_stream)
789 {
790 	struct hdac_stream *first_running = NULL;
791 	struct hdac_stream *pos;
792 	struct avs_dev *adev = hdac_to_avs(bus);
793 
794 	list_for_each_entry(pos, &bus->stream_list, list) {
795 		if (pos->running) {
796 			if (first_running)
797 				break; /* more than one running */
798 			first_running = pos;
799 		}
800 	}
801 
802 	/*
803 	 * If host_stream is a CAPTURE stream and will be the only one running,
804 	 * disable L1SEN to avoid sound clipping.
805 	 */
806 	if (!first_running) {
807 		if (hdac_stream(host_stream)->direction == SNDRV_PCM_STREAM_CAPTURE)
808 			avs_hda_l1sen_enable(adev, false);
809 		snd_hdac_stream_start(hdac_stream(host_stream));
810 		return;
811 	}
812 
813 	snd_hdac_stream_start(hdac_stream(host_stream));
814 	/*
815 	 * If host_stream is the first stream to break the rule above,
816 	 * re-enable L1SEN.
817 	 */
818 	if (list_entry_is_head(pos, &bus->stream_list, list) &&
819 	    first_running->direction == SNDRV_PCM_STREAM_CAPTURE)
820 		avs_hda_l1sen_enable(adev, true);
821 }
822 
avs_hda_stream_stop(struct hdac_bus * bus,struct hdac_ext_stream * host_stream)823 static void avs_hda_stream_stop(struct hdac_bus *bus, struct hdac_ext_stream *host_stream)
824 {
825 	struct hdac_stream *first_running = NULL;
826 	struct hdac_stream *pos;
827 	struct avs_dev *adev = hdac_to_avs(bus);
828 
829 	list_for_each_entry(pos, &bus->stream_list, list) {
830 		if (pos == hdac_stream(host_stream))
831 			continue; /* ignore stream that is about to be stopped */
832 		if (pos->running) {
833 			if (first_running)
834 				break; /* more than one running */
835 			first_running = pos;
836 		}
837 	}
838 
839 	/*
840 	 * If host_stream is a CAPTURE stream and is the only one running,
841 	 * re-enable L1SEN.
842 	 */
843 	if (!first_running) {
844 		snd_hdac_stream_stop(hdac_stream(host_stream));
845 		if (hdac_stream(host_stream)->direction == SNDRV_PCM_STREAM_CAPTURE)
846 			avs_hda_l1sen_enable(adev, true);
847 		return;
848 	}
849 
850 	/*
851 	 * If by stopping host_stream there is only a single, CAPTURE stream running
852 	 * left, disable L1SEN to avoid sound clipping.
853 	 */
854 	if (list_entry_is_head(pos, &bus->stream_list, list) &&
855 	    first_running->direction == SNDRV_PCM_STREAM_CAPTURE)
856 		avs_hda_l1sen_enable(adev, false);
857 
858 	snd_hdac_stream_stop(hdac_stream(host_stream));
859 }
860 
avs_dai_fe_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)861 static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
862 {
863 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
864 	struct avs_dma_data *data;
865 	struct hdac_ext_stream *host_stream;
866 	struct hdac_bus *bus;
867 	unsigned long flags;
868 	int ret = 0;
869 
870 	data = snd_soc_dai_get_dma_data(dai, substream);
871 	host_stream = data->host_stream;
872 	bus = hdac_stream(host_stream)->bus;
873 
874 	switch (cmd) {
875 	case SNDRV_PCM_TRIGGER_RESUME:
876 		if (rtd->dai_link->ignore_suspend)
877 			break;
878 		fallthrough;
879 	case SNDRV_PCM_TRIGGER_START:
880 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
881 		spin_lock_irqsave(&bus->reg_lock, flags);
882 		avs_hda_stream_start(bus, host_stream);
883 		spin_unlock_irqrestore(&bus->reg_lock, flags);
884 
885 		/* Timeout on DRSM poll shall not stop the resume so ignore the result. */
886 		if (cmd == SNDRV_PCM_TRIGGER_RESUME)
887 			snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
888 
889 		ret = avs_path_pause(data->path);
890 		if (ret < 0) {
891 			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
892 			break;
893 		}
894 
895 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
896 		if (ret < 0)
897 			dev_err(dai->dev, "run FE path failed: %d\n", ret);
898 
899 		break;
900 
901 	case SNDRV_PCM_TRIGGER_SUSPEND:
902 		if (rtd->dai_link->ignore_suspend)
903 			break;
904 		fallthrough;
905 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
906 	case SNDRV_PCM_TRIGGER_STOP:
907 		ret = avs_path_pause(data->path);
908 		if (ret < 0)
909 			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
910 
911 		spin_lock_irqsave(&bus->reg_lock, flags);
912 		avs_hda_stream_stop(bus, host_stream);
913 		spin_unlock_irqrestore(&bus->reg_lock, flags);
914 
915 		ret = avs_path_reset(data->path);
916 		if (ret < 0)
917 			dev_err(dai->dev, "reset FE path failed: %d\n", ret);
918 		break;
919 
920 	default:
921 		ret = -EINVAL;
922 		break;
923 	}
924 
925 	return ret;
926 }
927 
928 const struct snd_soc_dai_ops avs_dai_fe_ops = {
929 	.startup = avs_dai_fe_startup,
930 	.shutdown = avs_dai_fe_shutdown,
931 	.hw_params = avs_dai_fe_hw_params,
932 	.hw_free = avs_dai_fe_hw_free,
933 	.prepare = avs_dai_fe_prepare,
934 	.trigger = avs_dai_fe_trigger,
935 };
936 
topology_name_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)937 static ssize_t topology_name_read(struct file *file, char __user *user_buf, size_t count,
938 				  loff_t *ppos)
939 {
940 	struct snd_soc_component *component = file->private_data;
941 	struct snd_soc_card *card = component->card;
942 	struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
943 	char buf[64];
944 	size_t len;
945 
946 	len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
947 			mach->tplg_filename);
948 
949 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
950 }
951 
952 static const struct file_operations topology_name_fops = {
953 	.open = simple_open,
954 	.read = topology_name_read,
955 	.llseek = default_llseek,
956 };
957 
avs_component_load_libraries(struct avs_soc_component * acomp)958 static int avs_component_load_libraries(struct avs_soc_component *acomp)
959 {
960 	struct avs_tplg *tplg = acomp->tplg;
961 	struct avs_dev *adev = to_avs_dev(acomp->base.dev);
962 	int ret;
963 
964 	if (!tplg->num_libs)
965 		return 0;
966 
967 	/* Parent device may be asleep and library loading involves IPCs. */
968 	ret = pm_runtime_resume_and_get(adev->dev);
969 	if (ret < 0)
970 		return ret;
971 
972 	avs_hda_power_gating_enable(adev, false);
973 	avs_hda_clock_gating_enable(adev, false);
974 	avs_hda_l1sen_enable(adev, false);
975 
976 	ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
977 
978 	avs_hda_l1sen_enable(adev, true);
979 	avs_hda_clock_gating_enable(adev, true);
980 	avs_hda_power_gating_enable(adev, true);
981 
982 	if (!ret)
983 		ret = avs_module_info_init(adev, false);
984 
985 	pm_runtime_put_autosuspend(adev->dev);
986 
987 	return ret;
988 }
989 
avs_component_probe(struct snd_soc_component * component)990 static int avs_component_probe(struct snd_soc_component *component)
991 {
992 	struct snd_soc_card *card = component->card;
993 	struct snd_soc_acpi_mach *mach;
994 	struct avs_soc_component *acomp;
995 	struct avs_dev *adev;
996 	char *filename;
997 	int ret;
998 
999 	dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
1000 	mach = dev_get_platdata(card->dev);
1001 	acomp = to_avs_soc_component(component);
1002 	adev = to_avs_dev(component->dev);
1003 
1004 	acomp->tplg = avs_tplg_new(component);
1005 	if (!acomp->tplg)
1006 		return -ENOMEM;
1007 
1008 	if (!mach->tplg_filename)
1009 		goto finalize;
1010 
1011 	/* Load specified topology and create debugfs for it. */
1012 	filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
1013 			     mach->tplg_filename);
1014 	if (!filename)
1015 		return -ENOMEM;
1016 
1017 	ret = avs_load_topology(component, filename);
1018 	kfree(filename);
1019 	if (ret == -ENOENT && !strncmp(mach->tplg_filename, "hda-", 4)) {
1020 		unsigned int vendor_id;
1021 
1022 		if (sscanf(mach->tplg_filename, "hda-%08x-tplg.bin", &vendor_id) != 1)
1023 			return ret;
1024 
1025 		if (((vendor_id >> 16) & 0xFFFF) == 0x8086)
1026 			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
1027 							     "hda-8086-generic-tplg.bin");
1028 		else
1029 			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
1030 							     "hda-generic-tplg.bin");
1031 		if (!mach->tplg_filename)
1032 			return -ENOMEM;
1033 		filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
1034 				     mach->tplg_filename);
1035 		if (!filename)
1036 			return -ENOMEM;
1037 
1038 		dev_info(card->dev, "trying to load fallback topology %s\n", mach->tplg_filename);
1039 		ret = avs_load_topology(component, filename);
1040 		kfree(filename);
1041 	}
1042 	if (ret < 0)
1043 		return ret;
1044 
1045 	ret = avs_component_load_libraries(acomp);
1046 	if (ret < 0) {
1047 		dev_err(card->dev, "libraries loading failed: %d\n", ret);
1048 		goto err_load_libs;
1049 	}
1050 
1051 finalize:
1052 	debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
1053 			    &topology_name_fops);
1054 
1055 	mutex_lock(&adev->comp_list_mutex);
1056 	list_add_tail(&acomp->node, &adev->comp_list);
1057 	mutex_unlock(&adev->comp_list_mutex);
1058 
1059 	return 0;
1060 
1061 err_load_libs:
1062 	avs_remove_topology(component);
1063 	return ret;
1064 }
1065 
avs_component_remove(struct snd_soc_component * component)1066 static void avs_component_remove(struct snd_soc_component *component)
1067 {
1068 	struct avs_soc_component *acomp = to_avs_soc_component(component);
1069 	struct snd_soc_acpi_mach *mach;
1070 	struct avs_dev *adev = to_avs_dev(component->dev);
1071 	int ret;
1072 
1073 	mach = dev_get_platdata(component->card->dev);
1074 
1075 	mutex_lock(&adev->comp_list_mutex);
1076 	list_del(&acomp->node);
1077 	mutex_unlock(&adev->comp_list_mutex);
1078 
1079 	if (mach->tplg_filename) {
1080 		ret = avs_remove_topology(component);
1081 		if (ret < 0)
1082 			dev_err(component->dev, "unload topology failed: %d\n", ret);
1083 	}
1084 }
1085 
avs_dai_resume_hw_params(struct snd_soc_dai * dai,struct avs_dma_data * data)1086 static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data)
1087 {
1088 	struct snd_pcm_substream *substream;
1089 	struct snd_soc_pcm_runtime *rtd;
1090 	int ret;
1091 
1092 	substream = data->substream;
1093 	rtd = snd_soc_substream_to_rtd(substream);
1094 
1095 	ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai);
1096 	if (ret)
1097 		dev_err(dai->dev, "hw_params on resume failed: %d\n", ret);
1098 
1099 	return ret;
1100 }
1101 
avs_dai_resume_fe_prepare(struct snd_soc_dai * dai,struct avs_dma_data * data)1102 static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
1103 {
1104 	struct hdac_ext_stream *host_stream;
1105 	struct hdac_stream *hstream;
1106 	struct hdac_bus *bus;
1107 	int ret;
1108 
1109 	host_stream = data->host_stream;
1110 	hstream = hdac_stream(host_stream);
1111 	bus = hdac_stream(host_stream)->bus;
1112 
1113 	/* Set DRSM before programming stream and position registers. */
1114 	snd_hdac_stream_drsm_enable(bus, true, hstream->index);
1115 
1116 	ret = dai->driver->ops->prepare(data->substream, dai);
1117 	if (ret) {
1118 		dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret);
1119 		return ret;
1120 	}
1121 
1122 	writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1123 	writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1124 	writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1125 	writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1126 
1127 	/* As per HW spec recommendation, program LPIB and DPIB to the same value. */
1128 	snd_hdac_stream_set_lpib(hstream, hstream->lpib);
1129 	snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
1130 
1131 	return 0;
1132 }
1133 
avs_dai_resume_be_prepare(struct snd_soc_dai * dai,struct avs_dma_data * data)1134 static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
1135 {
1136 	int ret;
1137 
1138 	ret = dai->driver->ops->prepare(data->substream, dai);
1139 	if (ret)
1140 		dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret);
1141 
1142 	return ret;
1143 }
1144 
avs_dai_suspend_fe_hw_free(struct snd_soc_dai * dai,struct avs_dma_data * data)1145 static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1146 {
1147 	struct hdac_ext_stream *host_stream;
1148 	int ret;
1149 
1150 	host_stream = data->host_stream;
1151 
1152 	/* Store position addresses so we can resume from them later on. */
1153 	hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream));
1154 	host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1155 	host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1156 	host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1157 	host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1158 
1159 	ret = __avs_dai_fe_hw_free(data->substream, dai);
1160 	if (ret < 0)
1161 		dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret);
1162 
1163 	return ret;
1164 }
1165 
avs_dai_suspend_be_hw_free(struct snd_soc_dai * dai,struct avs_dma_data * data)1166 static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1167 {
1168 	int ret;
1169 
1170 	ret = dai->driver->ops->hw_free(data->substream, dai);
1171 	if (ret < 0)
1172 		dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret);
1173 
1174 	return ret;
1175 }
1176 
avs_component_pm_op(struct snd_soc_component * component,bool be,int (* op)(struct snd_soc_dai *,struct avs_dma_data *))1177 static int avs_component_pm_op(struct snd_soc_component *component, bool be,
1178 			       int (*op)(struct snd_soc_dai *, struct avs_dma_data *))
1179 {
1180 	struct snd_soc_pcm_runtime *rtd;
1181 	struct avs_dma_data *data;
1182 	struct snd_soc_dai *dai;
1183 	int ret;
1184 
1185 	for_each_component_dais(component, dai) {
1186 		data = snd_soc_dai_dma_data_get_playback(dai);
1187 		if (data) {
1188 			rtd = snd_soc_substream_to_rtd(data->substream);
1189 			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1190 				ret = op(dai, data);
1191 				if (ret < 0) {
1192 					__snd_pcm_set_state(data->substream->runtime,
1193 							    SNDRV_PCM_STATE_DISCONNECTED);
1194 					return ret;
1195 				}
1196 			}
1197 		}
1198 
1199 		data = snd_soc_dai_dma_data_get_capture(dai);
1200 		if (data) {
1201 			rtd = snd_soc_substream_to_rtd(data->substream);
1202 			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1203 				ret = op(dai, data);
1204 				if (ret < 0) {
1205 					__snd_pcm_set_state(data->substream->runtime,
1206 							    SNDRV_PCM_STATE_DISCONNECTED);
1207 					return ret;
1208 				}
1209 			}
1210 		}
1211 	}
1212 
1213 	return 0;
1214 }
1215 
avs_component_resume_hw_params(struct snd_soc_component * component,bool be)1216 static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be)
1217 {
1218 	return avs_component_pm_op(component, be, &avs_dai_resume_hw_params);
1219 }
1220 
avs_component_resume_prepare(struct snd_soc_component * component,bool be)1221 static int avs_component_resume_prepare(struct snd_soc_component *component, bool be)
1222 {
1223 	int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1224 
1225 	if (be)
1226 		prepare_cb = &avs_dai_resume_be_prepare;
1227 	else
1228 		prepare_cb = &avs_dai_resume_fe_prepare;
1229 
1230 	return avs_component_pm_op(component, be, prepare_cb);
1231 }
1232 
avs_component_suspend_hw_free(struct snd_soc_component * component,bool be)1233 static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be)
1234 {
1235 	int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1236 
1237 	if (be)
1238 		hw_free_cb = &avs_dai_suspend_be_hw_free;
1239 	else
1240 		hw_free_cb = &avs_dai_suspend_fe_hw_free;
1241 
1242 	return avs_component_pm_op(component, be, hw_free_cb);
1243 }
1244 
avs_component_suspend(struct snd_soc_component * component)1245 static int avs_component_suspend(struct snd_soc_component *component)
1246 {
1247 	int ret;
1248 
1249 	/*
1250 	 * When freeing paths, FEs need to be first as they perform
1251 	 * path unbinding.
1252 	 */
1253 	ret = avs_component_suspend_hw_free(component, false);
1254 	if (ret)
1255 		return ret;
1256 
1257 	return avs_component_suspend_hw_free(component, true);
1258 }
1259 
avs_component_resume(struct snd_soc_component * component)1260 static int avs_component_resume(struct snd_soc_component *component)
1261 {
1262 	int ret;
1263 
1264 	/*
1265 	 * When creating paths, FEs need to be last as they perform
1266 	 * path binding.
1267 	 */
1268 	ret = avs_component_resume_hw_params(component, true);
1269 	if (ret)
1270 		return ret;
1271 
1272 	ret = avs_component_resume_hw_params(component, false);
1273 	if (ret)
1274 		return ret;
1275 
1276 	/* It is expected that the LINK stream is prepared first. */
1277 	ret = avs_component_resume_prepare(component, true);
1278 	if (ret)
1279 		return ret;
1280 
1281 	return avs_component_resume_prepare(component, false);
1282 }
1283 
1284 static const struct snd_pcm_hardware avs_pcm_hardware = {
1285 	.info			= SNDRV_PCM_INFO_MMAP |
1286 				  SNDRV_PCM_INFO_MMAP_VALID |
1287 				  SNDRV_PCM_INFO_INTERLEAVED |
1288 				  SNDRV_PCM_INFO_PAUSE |
1289 				  SNDRV_PCM_INFO_RESUME |
1290 				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
1291 	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
1292 				  SNDRV_PCM_FMTBIT_S32_LE,
1293 	.subformats		= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1294 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1295 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1296 	.buffer_bytes_max	= AZX_MAX_BUF_SIZE,
1297 	.period_bytes_min	= 128,
1298 	.period_bytes_max	= AZX_MAX_BUF_SIZE / 2,
1299 	.periods_min		= 2,
1300 	.periods_max		= AZX_MAX_FRAG,
1301 	.fifo_size		= 0,
1302 };
1303 
avs_component_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)1304 static int avs_component_open(struct snd_soc_component *component,
1305 			      struct snd_pcm_substream *substream)
1306 {
1307 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1308 
1309 	/* only FE DAI links are handled here */
1310 	if (rtd->dai_link->no_pcm)
1311 		return 0;
1312 
1313 	return snd_soc_set_runtime_hwparams(substream, &avs_pcm_hardware);
1314 }
1315 
avs_hda_stream_dpib_read(struct hdac_ext_stream * stream)1316 static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
1317 {
1318 	return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1319 		     (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
1320 }
1321 
1322 static snd_pcm_uframes_t
avs_component_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)1323 avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
1324 {
1325 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1326 	struct avs_dma_data *data;
1327 	struct hdac_ext_stream *host_stream;
1328 	unsigned int pos;
1329 
1330 	data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0), substream);
1331 	if (!data->host_stream)
1332 		return 0;
1333 
1334 	host_stream = data->host_stream;
1335 	pos = avs_hda_stream_dpib_read(host_stream);
1336 
1337 	if (pos >= hdac_stream(host_stream)->bufsize)
1338 		pos = 0;
1339 
1340 	return bytes_to_frames(substream->runtime, pos);
1341 }
1342 
avs_component_mmap(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct vm_area_struct * vma)1343 static int avs_component_mmap(struct snd_soc_component *component,
1344 			      struct snd_pcm_substream *substream,
1345 			      struct vm_area_struct *vma)
1346 {
1347 	return snd_pcm_lib_default_mmap(substream, vma);
1348 }
1349 
1350 #define MAX_PREALLOC_SIZE	(32 * 1024 * 1024)
1351 
avs_component_construct(struct snd_soc_component * component,struct snd_soc_pcm_runtime * rtd)1352 static int avs_component_construct(struct snd_soc_component *component,
1353 				   struct snd_soc_pcm_runtime *rtd)
1354 {
1355 	struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
1356 	struct snd_pcm *pcm = rtd->pcm;
1357 
1358 	if (dai->driver->playback.channels_min)
1359 		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
1360 					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1361 					   MAX_PREALLOC_SIZE);
1362 
1363 	if (dai->driver->capture.channels_min)
1364 		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
1365 					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1366 					   MAX_PREALLOC_SIZE);
1367 
1368 	return 0;
1369 }
1370 
1371 static struct snd_soc_component_driver avs_component_driver = {
1372 	.name			= "avs-pcm",
1373 	.probe			= avs_component_probe,
1374 	.remove			= avs_component_remove,
1375 	.suspend		= avs_component_suspend,
1376 	.resume			= avs_component_resume,
1377 	.open			= avs_component_open,
1378 	.pointer		= avs_component_pointer,
1379 	.mmap			= avs_component_mmap,
1380 	.pcm_construct		= avs_component_construct,
1381 	.module_get_upon_open	= 1, /* increment refcount when a pcm is opened */
1382 	.topology_name_prefix	= "intel/avs",
1383 };
1384 
avs_register_component(struct device * dev,const char * name,struct snd_soc_component_driver * drv,struct snd_soc_dai_driver * cpu_dais,int num_cpu_dais)1385 int avs_register_component(struct device *dev, const char *name,
1386 			   struct snd_soc_component_driver *drv,
1387 			   struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
1388 {
1389 	struct avs_soc_component *acomp;
1390 	int ret;
1391 
1392 	acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
1393 	if (!acomp)
1394 		return -ENOMEM;
1395 
1396 	acomp->base.name = devm_kstrdup(dev, name, GFP_KERNEL);
1397 	if (!acomp->base.name)
1398 		return -ENOMEM;
1399 
1400 	INIT_LIST_HEAD(&acomp->node);
1401 
1402 	drv->use_dai_pcm_id = !obsolete_card_names;
1403 
1404 	ret = snd_soc_component_initialize(&acomp->base, drv, dev);
1405 	if (ret < 0)
1406 		return ret;
1407 
1408 	return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
1409 }
1410 
1411 static struct snd_soc_dai_driver dmic_cpu_dais[] = {
1412 {
1413 	.name = "DMIC Pin",
1414 	.capture = {
1415 		.stream_name	= "DMIC Rx",
1416 		.channels_min	= 1,
1417 		.channels_max	= 4,
1418 		.rates		= SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
1419 		.formats	= SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
1420 	},
1421 },
1422 {
1423 	.name = "DMIC WoV Pin",
1424 	.capture = {
1425 		.stream_name	= "DMIC WoV Rx",
1426 		.channels_min	= 1,
1427 		.channels_max	= 4,
1428 		.rates		= SNDRV_PCM_RATE_16000,
1429 		.formats	= SNDRV_PCM_FMTBIT_S16_LE,
1430 	},
1431 },
1432 };
1433 
avs_register_dmic_component(struct avs_dev * adev,const char * name)1434 int avs_register_dmic_component(struct avs_dev *adev, const char *name)
1435 {
1436 	const struct snd_soc_dai_ops *ops;
1437 
1438 	if (avs_platattr_test(adev, ALTHDA))
1439 		ops = &avs_dai_dmichda_be_ops;
1440 	else
1441 		ops = &avs_dai_nonhda_be_ops;
1442 
1443 	dmic_cpu_dais[0].ops = ops;
1444 	dmic_cpu_dais[1].ops = ops;
1445 	return avs_register_component(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
1446 				      ARRAY_SIZE(dmic_cpu_dais));
1447 }
1448 
1449 static const struct snd_soc_dai_driver i2s_dai_template = {
1450 	.playback = {
1451 		.channels_min	= 1,
1452 		.channels_max	= AVS_CHANNELS_MAX,
1453 		.rates		= SNDRV_PCM_RATE_8000_192000 |
1454 				  SNDRV_PCM_RATE_12000 |
1455 				  SNDRV_PCM_RATE_24000 |
1456 				  SNDRV_PCM_RATE_128000,
1457 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1458 				  SNDRV_PCM_FMTBIT_S32_LE,
1459 		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1460 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1461 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1462 	},
1463 	.capture = {
1464 		.channels_min	= 1,
1465 		.channels_max	= AVS_CHANNELS_MAX,
1466 		.rates		= SNDRV_PCM_RATE_8000_192000 |
1467 				  SNDRV_PCM_RATE_12000 |
1468 				  SNDRV_PCM_RATE_24000 |
1469 				  SNDRV_PCM_RATE_128000,
1470 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1471 				  SNDRV_PCM_FMTBIT_S32_LE,
1472 		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1473 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1474 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1475 	},
1476 };
1477 
avs_register_i2s_component(struct avs_dev * adev,const char * name,unsigned long port_mask,unsigned long * tdms)1478 int avs_register_i2s_component(struct avs_dev *adev, const char *name, unsigned long port_mask,
1479 			       unsigned long *tdms)
1480 {
1481 	struct snd_soc_dai_driver *cpus, *dai;
1482 	const struct snd_soc_dai_ops *ops;
1483 	size_t ssp_count, cpu_count;
1484 	int i, j;
1485 
1486 	ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
1487 	if (avs_platattr_test(adev, ALTHDA))
1488 		ops = &avs_dai_i2shda_be_ops;
1489 	else
1490 		ops = &avs_dai_nonhda_be_ops;
1491 
1492 	cpu_count = 0;
1493 	for_each_set_bit(i, &port_mask, ssp_count)
1494 		if (!tdms || test_bit(0, &tdms[i]))
1495 			cpu_count++;
1496 	if (tdms)
1497 		for_each_set_bit(i, &port_mask, ssp_count)
1498 			cpu_count += hweight_long(tdms[i]);
1499 
1500 	cpus = devm_kcalloc(adev->dev, cpu_count, sizeof(*cpus), GFP_KERNEL);
1501 	if (!cpus)
1502 		return -ENOMEM;
1503 
1504 	dai = cpus;
1505 	for_each_set_bit(i, &port_mask, ssp_count) {
1506 		if (!tdms || test_bit(0, &tdms[i])) {
1507 			memcpy(dai, &i2s_dai_template, sizeof(*dai));
1508 
1509 			dai->name =
1510 				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
1511 			dai->playback.stream_name =
1512 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
1513 			dai->capture.stream_name =
1514 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
1515 
1516 			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1517 				return -ENOMEM;
1518 			dai->ops = ops;
1519 			dai++;
1520 		}
1521 	}
1522 
1523 	if (!tdms)
1524 		goto plat_register;
1525 
1526 	for_each_set_bit(i, &port_mask, ssp_count) {
1527 		for_each_set_bit(j, &tdms[i], AVS_CHANNELS_MAX) {
1528 			memcpy(dai, &i2s_dai_template, sizeof(*dai));
1529 
1530 			dai->name =
1531 				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
1532 			dai->playback.stream_name =
1533 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
1534 			dai->capture.stream_name =
1535 				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
1536 
1537 			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1538 				return -ENOMEM;
1539 			dai->ops = ops;
1540 			dai++;
1541 		}
1542 	}
1543 
1544 plat_register:
1545 	return avs_register_component(adev->dev, name, &avs_component_driver, cpus, cpu_count);
1546 }
1547 
1548 /* HD-Audio CPU DAI template */
1549 static const struct snd_soc_dai_driver hda_cpu_dai = {
1550 	.ops = &avs_dai_hda_be_ops,
1551 	.playback = {
1552 		.channels_min	= 1,
1553 		.channels_max	= AVS_CHANNELS_MAX,
1554 		.rates		= SNDRV_PCM_RATE_8000_192000,
1555 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1556 				  SNDRV_PCM_FMTBIT_S32_LE,
1557 		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1558 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1559 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1560 	},
1561 	.capture = {
1562 		.channels_min	= 1,
1563 		.channels_max	= AVS_CHANNELS_MAX,
1564 		.rates		= SNDRV_PCM_RATE_8000_192000,
1565 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1566 				  SNDRV_PCM_FMTBIT_S32_LE,
1567 		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1568 				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1569 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1570 	},
1571 };
1572 
avs_component_hda_unregister_dais(struct snd_soc_component * component)1573 static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1574 {
1575 	struct snd_soc_acpi_mach *mach;
1576 	struct snd_soc_dai *dai, *save;
1577 	struct avs_mach_pdata *pdata;
1578 	struct hda_codec *codec;
1579 	char name[32];
1580 
1581 	mach = dev_get_platdata(component->card->dev);
1582 	pdata = mach->pdata;
1583 	codec = pdata->codec;
1584 	snprintf(name, sizeof(name), "%s-cpu", dev_name(&codec->core.dev));
1585 
1586 	for_each_component_dais_safe(component, dai, save) {
1587 		int stream;
1588 
1589 		if (!strstr(dai->driver->name, name))
1590 			continue;
1591 
1592 		for_each_pcm_streams(stream)
1593 			snd_soc_dapm_free_widget(snd_soc_dai_get_widget(dai, stream));
1594 
1595 		snd_soc_unregister_dai(dai);
1596 	}
1597 }
1598 
avs_component_hda_probe(struct snd_soc_component * component)1599 static int avs_component_hda_probe(struct snd_soc_component *component)
1600 {
1601 	struct snd_soc_dapm_context *dapm;
1602 	struct snd_soc_dai_driver *dais;
1603 	struct snd_soc_acpi_mach *mach;
1604 	struct avs_mach_pdata *pdata;
1605 	struct hda_codec *codec;
1606 	struct hda_pcm *pcm;
1607 	const char *cname;
1608 	int pcm_count = 0, ret, i;
1609 
1610 	mach = dev_get_platdata(component->card->dev);
1611 	if (!mach)
1612 		return -EINVAL;
1613 
1614 	pdata = mach->pdata;
1615 	codec = pdata->codec;
1616 	if (list_empty(&codec->pcm_list_head))
1617 		return -EINVAL;
1618 	list_for_each_entry(pcm, &codec->pcm_list_head, list)
1619 		pcm_count++;
1620 
1621 	dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1622 			    GFP_KERNEL);
1623 	if (!dais)
1624 		return -ENOMEM;
1625 
1626 	cname = dev_name(&codec->core.dev);
1627 	dapm = snd_soc_component_get_dapm(component);
1628 	pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1629 
1630 	for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1631 		struct snd_soc_dai *dai;
1632 
1633 		memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1634 		dais[i].id = i;
1635 		dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1636 					      "%s-cpu%d", cname, i);
1637 		if (!dais[i].name) {
1638 			ret = -ENOMEM;
1639 			goto exit;
1640 		}
1641 
1642 		if (pcm->stream[0].substreams) {
1643 			dais[i].playback.stream_name =
1644 				devm_kasprintf(component->dev, GFP_KERNEL,
1645 					       "%s-cpu%d Tx", cname, i);
1646 			if (!dais[i].playback.stream_name) {
1647 				ret = -ENOMEM;
1648 				goto exit;
1649 			}
1650 
1651 			if (!hda_codec_is_display(codec)) {
1652 				dais[i].playback.formats = pcm->stream[0].formats;
1653 				dais[i].playback.subformats = pcm->stream[0].subformats;
1654 				dais[i].playback.rates = pcm->stream[0].rates;
1655 				dais[i].playback.channels_min = pcm->stream[0].channels_min;
1656 				dais[i].playback.channels_max = pcm->stream[0].channels_max;
1657 				dais[i].playback.sig_bits = pcm->stream[0].maxbps;
1658 			}
1659 		}
1660 
1661 		if (pcm->stream[1].substreams) {
1662 			dais[i].capture.stream_name =
1663 				devm_kasprintf(component->dev, GFP_KERNEL,
1664 					       "%s-cpu%d Rx", cname, i);
1665 			if (!dais[i].capture.stream_name) {
1666 				ret = -ENOMEM;
1667 				goto exit;
1668 			}
1669 
1670 			if (!hda_codec_is_display(codec)) {
1671 				dais[i].capture.formats = pcm->stream[1].formats;
1672 				dais[i].capture.subformats = pcm->stream[1].subformats;
1673 				dais[i].capture.rates = pcm->stream[1].rates;
1674 				dais[i].capture.channels_min = pcm->stream[1].channels_min;
1675 				dais[i].capture.channels_max = pcm->stream[1].channels_max;
1676 				dais[i].capture.sig_bits = pcm->stream[1].maxbps;
1677 			}
1678 		}
1679 
1680 		dai = snd_soc_register_dai(component, &dais[i], false);
1681 		if (!dai) {
1682 			dev_err(component->dev, "register dai for %s failed\n",
1683 				pcm->name);
1684 			ret = -EINVAL;
1685 			goto exit;
1686 		}
1687 
1688 		ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1689 		if (ret < 0) {
1690 			dev_err(component->dev, "create widgets failed: %d\n",
1691 				ret);
1692 			snd_soc_unregister_dai(dai);
1693 			goto exit;
1694 		}
1695 	}
1696 
1697 	ret = avs_component_probe(component);
1698 exit:
1699 	if (ret)
1700 		avs_component_hda_unregister_dais(component);
1701 
1702 	return ret;
1703 }
1704 
avs_component_hda_remove(struct snd_soc_component * component)1705 static void avs_component_hda_remove(struct snd_soc_component *component)
1706 {
1707 	avs_component_remove(component);
1708 	avs_component_hda_unregister_dais(component);
1709 }
1710 
avs_component_hda_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)1711 static int avs_component_hda_open(struct snd_soc_component *component,
1712 				  struct snd_pcm_substream *substream)
1713 {
1714 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1715 
1716 	if (!rtd->dai_link->no_pcm) {
1717 		struct snd_pcm_hardware hwparams = avs_pcm_hardware;
1718 		struct snd_soc_pcm_runtime *be;
1719 		struct snd_soc_dpcm *dpcm;
1720 		int dir = substream->stream;
1721 
1722 		/*
1723 		 * Support the DPCM reparenting while still fulfilling expectations of HDAudio
1724 		 * common code - a valid stream pointer at substream->runtime->private_data -
1725 		 * by having all FEs point to the same private data.
1726 		 */
1727 		for_each_dpcm_be(rtd, dir, dpcm) {
1728 			struct snd_pcm_substream *be_substream;
1729 
1730 			be = dpcm->be;
1731 			if (be->dpcm[dir].users == 1)
1732 				break;
1733 
1734 			be_substream = snd_soc_dpcm_get_substream(be, dir);
1735 			substream->runtime->private_data = be_substream->runtime->private_data;
1736 			break;
1737 		}
1738 
1739 		/* RESUME unsupported for de-coupled HD-Audio capture. */
1740 		if (dir == SNDRV_PCM_STREAM_CAPTURE)
1741 			hwparams.info &= ~SNDRV_PCM_INFO_RESUME;
1742 
1743 		return snd_soc_set_runtime_hwparams(substream, &hwparams);
1744 	}
1745 
1746 	return 0;
1747 }
1748 
1749 static struct snd_soc_component_driver avs_hda_component_driver = {
1750 	.name			= "avs-hda-pcm",
1751 	.probe			= avs_component_hda_probe,
1752 	.remove			= avs_component_hda_remove,
1753 	.suspend		= avs_component_suspend,
1754 	.resume			= avs_component_resume,
1755 	.open			= avs_component_hda_open,
1756 	.pointer		= avs_component_pointer,
1757 	.mmap			= avs_component_mmap,
1758 	.pcm_construct		= avs_component_construct,
1759 	/*
1760 	 * hda platform component's probe() is dependent on
1761 	 * codec->pcm_list_head, it needs to be initialized after codec
1762 	 * component. remove_order is here for completeness sake
1763 	 */
1764 	.probe_order		= SND_SOC_COMP_ORDER_LATE,
1765 	.remove_order		= SND_SOC_COMP_ORDER_EARLY,
1766 	.module_get_upon_open	= 1,
1767 	.topology_name_prefix	= "intel/avs",
1768 };
1769 
avs_register_hda_component(struct avs_dev * adev,const char * name)1770 int avs_register_hda_component(struct avs_dev *adev, const char *name)
1771 {
1772 	return avs_register_component(adev->dev, name, &avs_hda_component_driver, NULL, 0);
1773 }
1774