xref: /linux/sound/soc/generic/simple-card-utils.c (revision e5c91aac491def6ab3f90c4cc246e3fcb0f8f058)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // simple-card-utils.c
4 //
5 // Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 
7 #include <dt-bindings/sound/audio-graph.h>
8 #include <linux/cleanup.h>
9 #include <linux/clk.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/of_graph.h>
14 #include <sound/jack.h>
15 #include <sound/pcm_params.h>
16 #include <sound/simple_card_utils.h>
17 
18 #define simple_ret(priv, ret) _simple_ret(priv, __func__, ret)
19 static inline int _simple_ret(struct simple_util_priv *priv,
20 			      const char *func, int ret)
21 {
22 	return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func);
23 }
24 
25 int simple_util_get_sample_fmt(struct simple_util_data *data)
26 {
27 	int i;
28 	int val = -EINVAL;
29 
30 	struct {
31 		char *fmt;
32 		u32 val;
33 	} of_sample_fmt_table[] = {
34 		{ "s8",		SNDRV_PCM_FORMAT_S8},
35 		{ "s16_le",	SNDRV_PCM_FORMAT_S16_LE},
36 		{ "s24_le",	SNDRV_PCM_FORMAT_S24_LE},
37 		{ "s24_3le",	SNDRV_PCM_FORMAT_S24_3LE},
38 		{ "s32_le",	SNDRV_PCM_FORMAT_S32_LE},
39 	};
40 
41 	for (i = 0; i < ARRAY_SIZE(of_sample_fmt_table); i++) {
42 		if (!strcmp(data->convert_sample_format,
43 			    of_sample_fmt_table[i].fmt)) {
44 			val = of_sample_fmt_table[i].val;
45 			break;
46 		}
47 	}
48 	return val;
49 }
50 EXPORT_SYMBOL_GPL(simple_util_get_sample_fmt);
51 
52 static void simple_fixup_sample_fmt(struct simple_util_data *data,
53 				    struct snd_pcm_hw_params *params)
54 {
55 	int val;
56 	struct snd_mask *mask = hw_param_mask(params,
57 					      SNDRV_PCM_HW_PARAM_FORMAT);
58 
59 	val = simple_util_get_sample_fmt(data);
60 	if (val >= 0) {
61 		snd_mask_none(mask);
62 		snd_mask_set(mask, val);
63 	}
64 }
65 
66 void simple_util_parse_convert(struct device_node *np,
67 			       char *prefix,
68 			       struct simple_util_data *data)
69 {
70 	char prop[128];
71 
72 	if (!np)
73 		return;
74 
75 	if (!prefix)
76 		prefix = "";
77 
78 	/* sampling rate convert */
79 	snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-rate");
80 	of_property_read_u32(np, prop, &data->convert_rate);
81 
82 	/* channels transfer */
83 	snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-channels");
84 	of_property_read_u32(np, prop, &data->convert_channels);
85 
86 	/* convert sample format */
87 	snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-sample-format");
88 	of_property_read_string(np, prop, &data->convert_sample_format);
89 }
90 EXPORT_SYMBOL_GPL(simple_util_parse_convert);
91 
92 /**
93  * simple_util_is_convert_required() - Query if HW param conversion was requested
94  * @data: Link data.
95  *
96  * Returns true if any HW param conversion was requested for this DAI link with
97  * any "convert-xxx" properties.
98  */
99 bool simple_util_is_convert_required(const struct simple_util_data *data)
100 {
101 	return data->convert_rate ||
102 	       data->convert_channels ||
103 	       data->convert_sample_format;
104 }
105 EXPORT_SYMBOL_GPL(simple_util_is_convert_required);
106 
107 int simple_util_parse_daifmt(struct device *dev,
108 			     struct device_node *node,
109 			     struct device_node *codec,
110 			     char *prefix,
111 			     unsigned int *retfmt)
112 {
113 	struct device_node *bitclkmaster = NULL;
114 	struct device_node *framemaster = NULL;
115 	unsigned int daifmt;
116 
117 	daifmt = snd_soc_daifmt_parse_format(node, prefix);
118 
119 	snd_soc_daifmt_parse_clock_provider_as_phandle(node, prefix, &bitclkmaster, &framemaster);
120 	if (!bitclkmaster && !framemaster) {
121 		/*
122 		 * No dai-link level and master setting was not found from
123 		 * sound node level, revert back to legacy DT parsing and
124 		 * take the settings from codec node.
125 		 */
126 		dev_dbg(dev, "Revert to legacy daifmt parsing\n");
127 
128 		daifmt |= snd_soc_daifmt_parse_clock_provider_as_flag(codec, NULL);
129 	} else {
130 		daifmt |= snd_soc_daifmt_clock_provider_from_bitmap(
131 				((codec == bitclkmaster) << 4) | (codec == framemaster));
132 	}
133 
134 	of_node_put(bitclkmaster);
135 	of_node_put(framemaster);
136 
137 	*retfmt = daifmt;
138 
139 	return 0;
140 }
141 EXPORT_SYMBOL_GPL(simple_util_parse_daifmt);
142 
143 int simple_util_parse_tdm_width_map(struct simple_util_priv *priv, struct device_node *np,
144 				    struct simple_util_dai *dai)
145 {
146 	struct device *dev = simple_priv_to_dev(priv);
147 	int n, i, ret;
148 	u32 *p;
149 
150 	/*
151 	 * NOTE
152 	 *
153 	 * Clang doesn't allow to use "goto end" before calling __free(),
154 	 * because it bypasses the initialization. Use simple_ret() directly.
155 	 */
156 
157 	n = of_property_count_elems_of_size(np, "dai-tdm-slot-width-map", sizeof(u32));
158 	if (n <= 0)
159 		return 0;
160 
161 	if (n % 3) {
162 		dev_err(dev, "Invalid number of cells for dai-tdm-slot-width-map\n");
163 		return simple_ret(priv, -EINVAL); /* see NOTE */
164 	}
165 
166 	ret = -ENOMEM;
167 	dai->tdm_width_map = devm_kcalloc(dev, n, sizeof(*dai->tdm_width_map), GFP_KERNEL);
168 	if (!dai->tdm_width_map)
169 		return simple_ret(priv, ret); /* see NOTE */
170 
171 	u32 *array_values __free(kfree) = kcalloc(n, sizeof(*array_values), GFP_KERNEL);
172 	if (!array_values)
173 		goto end;
174 
175 	ret = of_property_read_u32_array(np, "dai-tdm-slot-width-map", array_values, n);
176 	if (ret < 0) {
177 		dev_err(dev, "Could not read dai-tdm-slot-width-map: %d\n", ret);
178 		goto end;
179 	}
180 
181 	p = array_values;
182 	for (i = 0; i < n / 3; ++i) {
183 		dai->tdm_width_map[i].sample_bits = *p++;
184 		dai->tdm_width_map[i].slot_width = *p++;
185 		dai->tdm_width_map[i].slot_count = *p++;
186 	}
187 
188 	dai->n_tdm_widths = i;
189 	ret = 0;
190 end:
191 	return simple_ret(priv, ret);
192 }
193 EXPORT_SYMBOL_GPL(simple_util_parse_tdm_width_map);
194 
195 int simple_util_set_dailink_name(struct simple_util_priv *priv,
196 				 struct snd_soc_dai_link *dai_link,
197 				 const char *fmt, ...)
198 {
199 	struct device *dev = simple_priv_to_dev(priv);
200 	va_list ap;
201 	char *name = NULL;
202 	int ret = -ENOMEM;
203 
204 	va_start(ap, fmt);
205 	name = devm_kvasprintf(dev, GFP_KERNEL, fmt, ap);
206 	va_end(ap);
207 
208 	if (name) {
209 		ret = 0;
210 
211 		dai_link->name		= name;
212 		dai_link->stream_name	= name;
213 	}
214 
215 	return simple_ret(priv, ret);
216 }
217 EXPORT_SYMBOL_GPL(simple_util_set_dailink_name);
218 
219 int simple_util_parse_property(struct simple_util_priv *priv,
220 			       int (*func)(struct snd_soc_card *card, const char *propname),
221 			       char *prefix, char *property)
222 {
223 	struct snd_soc_card *card = simple_priv_to_card(priv);
224 	struct device_node *node = card->dev->of_node;
225 	char prop[128];
226 
227 	if (!prefix)
228 		prefix = "";
229 
230 	snprintf(prop, sizeof(prop), "%s%s", prefix, property);
231 
232 	/* no property is not error */
233 	if (!of_property_present(node, prop))
234 		return 0;
235 
236 	return func(card, prop);
237 }
238 EXPORT_SYMBOL_GPL(simple_util_parse_property);
239 
240 int simple_util_parse_card_name(struct simple_util_priv *priv,
241 				char *prefix)
242 {
243 	struct snd_soc_card *card = simple_priv_to_card(priv);
244 	int ret;
245 
246 	if (!prefix)
247 		prefix = "";
248 
249 	/* Parse the card name from DT */
250 	ret = snd_soc_of_parse_card_name(card, "label");
251 	if (ret < 0 || !card->name) {
252 		char prop[128];
253 
254 		snprintf(prop, sizeof(prop), "%sname", prefix);
255 		ret = snd_soc_of_parse_card_name(card, prop);
256 		if (ret < 0)
257 			goto end;
258 	}
259 
260 	if (!card->name && card->dai_link)
261 		card->name = card->dai_link->name;
262 end:
263 	return simple_ret(priv, ret);
264 }
265 EXPORT_SYMBOL_GPL(simple_util_parse_card_name);
266 
267 static int simple_clk_enable(struct simple_util_dai *dai)
268 {
269 	if (dai)
270 		return clk_prepare_enable(dai->clk);
271 
272 	return 0;
273 }
274 
275 static void simple_clk_disable(struct simple_util_dai *dai)
276 {
277 	if (dai)
278 		clk_disable_unprepare(dai->clk);
279 }
280 
281 int simple_util_parse_clk(struct device *dev,
282 			  struct device_node *node,
283 			  struct simple_util_dai *simple_dai,
284 			  struct snd_soc_dai_link_component *dlc)
285 {
286 	struct clk *clk;
287 	u32 val;
288 
289 	/*
290 	 * Parse dai->sysclk come from "clocks = <&xxx>"
291 	 * (if system has common clock)
292 	 *  or "system-clock-frequency = <xxx>"
293 	 *  or device's module clock.
294 	 */
295 	clk = devm_get_clk_from_child(dev, node, NULL);
296 	simple_dai->clk_fixed = of_property_read_bool(
297 		node, "system-clock-fixed");
298 	if (!IS_ERR(clk)) {
299 		simple_dai->sysclk = clk_get_rate(clk);
300 
301 		simple_dai->clk = clk;
302 	} else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
303 		simple_dai->sysclk = val;
304 		simple_dai->clk_fixed = true;
305 	} else {
306 		clk = devm_get_clk_from_child(dev, dlc->of_node, NULL);
307 		if (!IS_ERR(clk))
308 			simple_dai->sysclk = clk_get_rate(clk);
309 	}
310 
311 	if (of_property_read_bool(node, "system-clock-direction-out"))
312 		simple_dai->clk_direction = SND_SOC_CLOCK_OUT;
313 
314 	return 0;
315 }
316 EXPORT_SYMBOL_GPL(simple_util_parse_clk);
317 
318 static int simple_check_fixed_sysclk(struct device *dev,
319 					  struct simple_util_dai *dai,
320 					  unsigned int *fixed_sysclk)
321 {
322 	if (dai->clk_fixed) {
323 		if (*fixed_sysclk && *fixed_sysclk != dai->sysclk) {
324 			dev_err(dev, "inconsistent fixed sysclk rates (%u vs %u)\n",
325 				*fixed_sysclk, dai->sysclk);
326 			return -EINVAL;
327 		}
328 		*fixed_sysclk = dai->sysclk;
329 	}
330 
331 	return 0;
332 }
333 
334 int simple_util_startup(struct snd_pcm_substream *substream)
335 {
336 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
337 	struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card);
338 	struct simple_dai_props *props = runtime_simple_priv_to_props(priv, rtd);
339 	struct simple_util_dai *dai;
340 	unsigned int fixed_sysclk = 0;
341 	int i1, i2, i;
342 	int ret;
343 
344 	for_each_prop_dai_cpu(props, i1, dai) {
345 		ret = simple_clk_enable(dai);
346 		if (ret)
347 			goto cpu_err;
348 		ret = simple_check_fixed_sysclk(rtd->dev, dai, &fixed_sysclk);
349 		if (ret)
350 			goto cpu_err;
351 	}
352 
353 	for_each_prop_dai_codec(props, i2, dai) {
354 		ret = simple_clk_enable(dai);
355 		if (ret)
356 			goto codec_err;
357 		ret = simple_check_fixed_sysclk(rtd->dev, dai, &fixed_sysclk);
358 		if (ret)
359 			goto codec_err;
360 	}
361 
362 	if (fixed_sysclk && props->mclk_fs) {
363 		unsigned int fixed_rate = fixed_sysclk / props->mclk_fs;
364 
365 		if (fixed_sysclk % props->mclk_fs) {
366 			dev_err(rtd->dev, "fixed sysclk %u not divisible by mclk_fs %u\n",
367 				fixed_sysclk, props->mclk_fs);
368 			ret = -EINVAL;
369 			goto codec_err;
370 		}
371 		ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE,
372 			fixed_rate, fixed_rate);
373 		if (ret < 0)
374 			goto codec_err;
375 	}
376 
377 	return 0;
378 
379 codec_err:
380 	for_each_prop_dai_codec(props, i, dai) {
381 		if (i >= i2)
382 			break;
383 		simple_clk_disable(dai);
384 	}
385 cpu_err:
386 	for_each_prop_dai_cpu(props, i, dai) {
387 		if (i >= i1)
388 			break;
389 		simple_clk_disable(dai);
390 	}
391 
392 	return simple_ret(priv, ret);
393 }
394 EXPORT_SYMBOL_GPL(simple_util_startup);
395 
396 void simple_util_shutdown(struct snd_pcm_substream *substream)
397 {
398 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
399 	struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card);
400 	struct simple_dai_props *props = runtime_simple_priv_to_props(priv, rtd);
401 	struct simple_util_dai *dai;
402 	int i;
403 
404 	for_each_prop_dai_cpu(props, i, dai) {
405 		struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, i);
406 
407 		if (props->mclk_fs && !dai->clk_fixed && !snd_soc_dai_active(cpu_dai))
408 			snd_soc_dai_set_sysclk(cpu_dai, 0, 0, dai->clk_direction);
409 
410 		simple_clk_disable(dai);
411 	}
412 	for_each_prop_dai_codec(props, i, dai) {
413 		struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, i);
414 
415 		if (props->mclk_fs && !dai->clk_fixed && !snd_soc_dai_active(codec_dai))
416 			snd_soc_dai_set_sysclk(codec_dai, 0, 0, dai->clk_direction);
417 
418 		simple_clk_disable(dai);
419 	}
420 }
421 EXPORT_SYMBOL_GPL(simple_util_shutdown);
422 
423 static int simple_set_clk_rate(struct simple_util_priv *priv,
424 			       struct simple_util_dai *simple_dai,
425 			       unsigned long rate)
426 {
427 	struct device *dev = simple_priv_to_dev(priv);
428 	int ret = -EINVAL;
429 
430 	if (!simple_dai)
431 		return 0;
432 
433 	if (simple_dai->clk_fixed && rate != simple_dai->sysclk) {
434 		dev_err(dev, "dai %s invalid clock rate %lu\n", simple_dai->name, rate);
435 		goto end;
436 	}
437 
438 	if (!simple_dai->clk)
439 		return 0;
440 
441 	if (clk_get_rate(simple_dai->clk) == rate)
442 		return 0;
443 
444 	ret = clk_set_rate(simple_dai->clk, rate);
445 end:
446 	return simple_ret(priv, ret);
447 }
448 
449 static int simple_set_tdm(struct simple_util_priv *priv,
450 			  struct snd_soc_dai *dai,
451 			  struct simple_util_dai *simple_dai,
452 			  struct snd_pcm_hw_params *params)
453 {
454 	int sample_bits = params_width(params);
455 	int slot_width, slot_count;
456 	int i, ret;
457 
458 	if (!simple_dai || !simple_dai->tdm_width_map)
459 		return 0;
460 
461 	slot_width = simple_dai->slot_width;
462 	slot_count = simple_dai->slots;
463 
464 	if (slot_width == 0)
465 		slot_width = sample_bits;
466 
467 	for (i = 0; i < simple_dai->n_tdm_widths; ++i) {
468 		if (simple_dai->tdm_width_map[i].sample_bits == sample_bits) {
469 			slot_width = simple_dai->tdm_width_map[i].slot_width;
470 			slot_count = simple_dai->tdm_width_map[i].slot_count;
471 			break;
472 		}
473 	}
474 
475 	ret = snd_soc_dai_set_tdm_slot(dai,
476 				       simple_dai->tx_slot_mask,
477 				       simple_dai->rx_slot_mask,
478 				       slot_count,
479 				       slot_width);
480 
481 	return simple_ret(priv, ret);
482 }
483 
484 int simple_util_hw_params(struct snd_pcm_substream *substream,
485 			  struct snd_pcm_hw_params *params)
486 {
487 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
488 	struct simple_util_dai *pdai;
489 	struct snd_soc_dai *sdai;
490 	struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card);
491 	struct simple_dai_props *props = runtime_simple_priv_to_props(priv, rtd);
492 	enum simple_util_sysclk_order order = props->sysclk_order;
493 	unsigned int mclk, mclk_fs = 0;
494 	int i, ret;
495 
496 	if (props->mclk_fs)
497 		mclk_fs = props->mclk_fs;
498 
499 	if (mclk_fs) {
500 		struct snd_soc_component *component;
501 		mclk = params_rate(params) * mclk_fs;
502 
503 		for_each_prop_dai_codec(props, i, pdai) {
504 			ret = simple_set_clk_rate(priv, pdai, mclk);
505 			if (ret < 0)
506 				goto end;
507 		}
508 
509 		for_each_prop_dai_cpu(props, i, pdai) {
510 			ret = simple_set_clk_rate(priv, pdai, mclk);
511 			if (ret < 0)
512 				goto end;
513 		}
514 
515 		/* Ensure sysclk is set on all components in case any
516 		 * (such as platform components) are missed by calls to
517 		 * snd_soc_dai_set_sysclk.
518 		 */
519 		for_each_rtd_components(rtd, i, component) {
520 			ret = snd_soc_component_set_sysclk(component, 0, 0,
521 							   mclk, SND_SOC_CLOCK_IN);
522 			if (ret && ret != -ENOTSUPP)
523 				goto end;
524 		}
525 
526 		if (order == SIMPLE_SYSCLK_ORDER_CPU_FIRST) {
527 			/* CPU first */
528 			for_each_rtd_cpu_dais(rtd, i, sdai) {
529 				pdai = simple_props_to_dai_cpu(props, i);
530 				ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
531 				if (ret && ret != -ENOTSUPP)
532 					goto end;
533 			}
534 
535 			for_each_rtd_codec_dais(rtd, i, sdai) {
536 				pdai = simple_props_to_dai_codec(props, i);
537 				ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
538 				if (ret && ret != -ENOTSUPP)
539 					goto end;
540 			}
541 		} else {
542 			/* default: codec first */
543 			for_each_rtd_codec_dais(rtd, i, sdai) {
544 				pdai = simple_props_to_dai_codec(props, i);
545 				ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
546 				if (ret && ret != -ENOTSUPP)
547 					goto end;
548 			}
549 
550 			for_each_rtd_cpu_dais(rtd, i, sdai) {
551 				pdai = simple_props_to_dai_cpu(props, i);
552 				ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
553 				if (ret && ret != -ENOTSUPP)
554 					goto end;
555 			}
556 		}
557 	}
558 
559 	for_each_prop_dai_codec(props, i, pdai) {
560 		sdai = snd_soc_rtd_to_codec(rtd, i);
561 		ret = simple_set_tdm(priv, sdai, pdai, params);
562 		if (ret < 0)
563 			goto end;
564 	}
565 
566 	for_each_prop_dai_cpu(props, i, pdai) {
567 		sdai = snd_soc_rtd_to_cpu(rtd, i);
568 		ret = simple_set_tdm(priv, sdai, pdai, params);
569 		if (ret < 0)
570 			goto end;
571 	}
572 	ret = 0;
573 end:
574 	return simple_ret(priv, ret);
575 }
576 EXPORT_SYMBOL_GPL(simple_util_hw_params);
577 
578 int simple_util_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
579 				   struct snd_pcm_hw_params *params)
580 {
581 	struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card);
582 	struct simple_dai_props *dai_props = runtime_simple_priv_to_props(priv, rtd);
583 	struct simple_util_data *data = &dai_props->adata;
584 	struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
585 	struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
586 
587 	if (data->convert_rate)
588 		rate->min =
589 		rate->max = data->convert_rate;
590 
591 	if (data->convert_channels)
592 		channels->min =
593 		channels->max = data->convert_channels;
594 
595 	if (data->convert_sample_format)
596 		simple_fixup_sample_fmt(data, params);
597 
598 	return 0;
599 }
600 EXPORT_SYMBOL_GPL(simple_util_be_hw_params_fixup);
601 
602 static int simple_init_dai(struct simple_util_priv *priv,
603 			   struct snd_soc_dai *dai, struct simple_util_dai *simple_dai)
604 {
605 	int ret;
606 
607 	if (!simple_dai)
608 		return 0;
609 
610 	if (simple_dai->sysclk) {
611 		ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk,
612 					     simple_dai->clk_direction);
613 		if (ret && ret != -ENOTSUPP) {
614 			dev_err(dai->dev, "simple-card: set_sysclk error\n");
615 			goto end;
616 		}
617 	}
618 
619 	if (simple_dai->slots) {
620 		ret = snd_soc_dai_set_tdm_slot(dai,
621 					       simple_dai->tx_slot_mask,
622 					       simple_dai->rx_slot_mask,
623 					       simple_dai->slots,
624 					       simple_dai->slot_width);
625 		if (ret && ret != -ENOTSUPP) {
626 			dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
627 			goto end;
628 		}
629 	}
630 	ret = 0;
631 end:
632 	return simple_ret(priv, ret);
633 }
634 
635 static inline int simple_component_is_codec(struct snd_soc_component *component)
636 {
637 	return component->driver->endianness;
638 }
639 
640 static int simple_init_for_codec2codec(struct simple_util_priv *priv,
641 				       struct snd_soc_pcm_runtime *rtd,
642 				       struct simple_dai_props *dai_props)
643 {
644 	struct snd_soc_dai_link *dai_link = rtd->dai_link;
645 	struct snd_soc_component *component;
646 	struct snd_soc_pcm_stream *c2c_params;
647 	struct snd_pcm_hardware hw;
648 	int i, ret, stream;
649 
650 	/* Do nothing if it already has Codec2Codec settings */
651 	if (dai_link->c2c_params)
652 		return 0;
653 
654 	/* Do nothing if it was DPCM :: BE */
655 	if (dai_link->no_pcm)
656 		return 0;
657 
658 	/* Only Codecs */
659 	for_each_rtd_components(rtd, i, component) {
660 		if (!simple_component_is_codec(component))
661 			return 0;
662 	}
663 
664 	/* Assumes the capabilities are the same for all supported streams */
665 	for_each_pcm_streams(stream) {
666 		ret = snd_soc_runtime_calc_hw(rtd, &hw, stream);
667 		if (ret == 0)
668 			break;
669 	}
670 
671 	if (ret < 0) {
672 		dev_err(rtd->dev, "simple-card: no valid dai_link params\n");
673 		goto end;
674 	}
675 
676 	ret = -ENOMEM;
677 	c2c_params = devm_kzalloc(rtd->dev, sizeof(*c2c_params), GFP_KERNEL);
678 	if (!c2c_params)
679 		goto end;
680 
681 	c2c_params->formats		= hw.formats;
682 	c2c_params->rates		= hw.rates;
683 	c2c_params->rate_min		= hw.rate_min;
684 	c2c_params->rate_max		= hw.rate_max;
685 	c2c_params->channels_min	= hw.channels_min;
686 	c2c_params->channels_max	= hw.channels_max;
687 
688 	dai_link->c2c_params		= c2c_params;
689 	dai_link->num_c2c_params	= 1;
690 
691 	ret = 0;
692 end:
693 	return simple_ret(priv, ret);
694 }
695 
696 int simple_util_dai_init(struct snd_soc_pcm_runtime *rtd)
697 {
698 	struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card);
699 	struct simple_dai_props *props = runtime_simple_priv_to_props(priv, rtd);
700 	struct simple_util_dai *dai;
701 	int i, ret;
702 
703 	for_each_prop_dai_codec(props, i, dai) {
704 		ret = simple_init_dai(priv, snd_soc_rtd_to_codec(rtd, i), dai);
705 		if (ret < 0)
706 			goto end;
707 	}
708 	for_each_prop_dai_cpu(props, i, dai) {
709 		ret = simple_init_dai(priv, snd_soc_rtd_to_cpu(rtd, i), dai);
710 		if (ret < 0)
711 			goto end;
712 	}
713 
714 	ret = simple_init_for_codec2codec(priv, rtd, props);
715 end:
716 	return simple_ret(priv, ret);
717 }
718 EXPORT_SYMBOL_GPL(simple_util_dai_init);
719 
720 void simple_util_canonicalize_platform(struct snd_soc_dai_link_component *platforms,
721 				       struct snd_soc_dai_link_component *cpus)
722 {
723 	/*
724 	 * Assumes Platform == CPU
725 	 *
726 	 * Some CPU might be using soc-generic-dmaengine-pcm. This means CPU and Platform
727 	 * are different Component, but are sharing same component->dev.
728 	 *
729 	 * Let's assume Platform is same as CPU if it doesn't identify Platform on DT.
730 	 * see
731 	 *	simple-card.c :: simple_count_noml()
732 	 */
733 	if (!platforms->of_node)
734 		snd_soc_dlc_use_cpu_as_platform(platforms, cpus);
735 }
736 EXPORT_SYMBOL_GPL(simple_util_canonicalize_platform);
737 
738 void simple_util_canonicalize_cpu(struct snd_soc_dai_link_component *cpus,
739 				  int is_single_links)
740 {
741 	/*
742 	 * In snd_soc_add_pcm_runtime() will check cpu name after
743 	 * of_node matching if dai_link has cpu_dai_name.
744 	 * but, it will never match if name was created by
745 	 * fmt_single_name() remove cpu_dai_name if cpu_args
746 	 * was 0. See:
747 	 *	fmt_single_name()
748 	 *	fmt_multiple_name()
749 	 */
750 	if (is_single_links)
751 		cpus->dai_name = NULL;
752 }
753 EXPORT_SYMBOL_GPL(simple_util_canonicalize_cpu);
754 
755 void simple_util_clean_reference(struct simple_util_priv *priv)
756 {
757 	struct snd_soc_dai_link *dai_link;
758 	struct snd_soc_dai_link_component *cpu;
759 	struct snd_soc_dai_link_component *codec;
760 	struct snd_soc_card *card = simple_priv_to_card(priv);
761 	int i, j;
762 
763 	for_each_card_prelinks(card, i, dai_link) {
764 		for_each_link_cpus(dai_link, j, cpu)
765 			of_node_put(cpu->of_node);
766 		for_each_link_codecs(dai_link, j, codec)
767 			of_node_put(codec->of_node);
768 	}
769 }
770 EXPORT_SYMBOL_GPL(simple_util_clean_reference);
771 
772 int simple_util_init_jack(struct snd_soc_card *card,
773 			  struct simple_util_jack *sjack,
774 			  int is_hp, char *prefix,
775 			  char *pin)
776 {
777 	struct device *dev = card->dev;
778 	struct gpio_desc *desc;
779 	char prop[128];
780 	char *pin_name;
781 	char *gpio_name;
782 	int mask;
783 	int error;
784 
785 	if (!prefix)
786 		prefix = "";
787 
788 	if (is_hp) {
789 		snprintf(prop, sizeof(prop), "%shp-det", prefix);
790 		pin_name	= pin ? pin : "Headphones";
791 		gpio_name	= "Headphone detection";
792 		mask		= SND_JACK_HEADPHONE;
793 	} else {
794 		snprintf(prop, sizeof(prop), "%smic-det", prefix);
795 		pin_name	= pin ? pin : "Mic Jack";
796 		gpio_name	= "Mic detection";
797 		mask		= SND_JACK_MICROPHONE;
798 	}
799 
800 	desc = gpiod_get_optional(dev, prop, GPIOD_IN);
801 	error = PTR_ERR_OR_ZERO(desc);
802 	if (error)
803 		return error;
804 
805 	if (desc) {
806 		error = gpiod_set_consumer_name(desc, gpio_name);
807 		if (error)
808 			return error;
809 
810 		sjack->pin.pin		= pin_name;
811 		sjack->pin.mask		= mask;
812 
813 		sjack->gpio.name	= gpio_name;
814 		sjack->gpio.report	= mask;
815 		sjack->gpio.desc	= desc;
816 		sjack->gpio.debounce_time = 150;
817 
818 		snd_soc_card_jack_new_pins(card, pin_name, mask, &sjack->jack,
819 					   &sjack->pin, 1);
820 
821 		snd_soc_jack_add_gpios(&sjack->jack, 1, &sjack->gpio);
822 	}
823 
824 	return 0;
825 }
826 EXPORT_SYMBOL_GPL(simple_util_init_jack);
827 
828 int simple_util_init_aux_jacks(struct snd_soc_card *card, char *prefix)
829 {
830 	struct simple_util_priv *priv = snd_soc_card_get_drvdata(card);
831 	struct snd_soc_component *component;
832 	int found_jack_index = 0;
833 	int type = 0;
834 	int num = 0;
835 	int ret;
836 
837 	if (priv->aux_jacks)
838 		return 0;
839 
840 	for_each_card_auxs(card, component) {
841 		type = snd_soc_component_get_jack_type(component);
842 		if (type > 0)
843 			num++;
844 	}
845 	if (num < 1)
846 		return 0;
847 
848 	priv->aux_jacks = devm_kcalloc(card->dev, num,
849 				       sizeof(struct snd_soc_jack), GFP_KERNEL);
850 	if (!priv->aux_jacks)
851 		return simple_ret(priv, -ENOMEM);
852 
853 	for_each_card_auxs(card, component) {
854 		char id[128];
855 		struct snd_soc_jack *jack;
856 
857 		if (found_jack_index >= num)
858 			break;
859 
860 		type = snd_soc_component_get_jack_type(component);
861 		if (type <= 0)
862 			continue;
863 
864 		/* create jack */
865 		jack = &(priv->aux_jacks[found_jack_index++]);
866 		snprintf(id, sizeof(id), "%s-jack", component->name);
867 		ret = snd_soc_card_jack_new(card, id, type, jack);
868 		if (ret)
869 			continue;
870 
871 		(void)snd_soc_component_set_jack(component, jack, NULL);
872 	}
873 	return 0;
874 }
875 EXPORT_SYMBOL_GPL(simple_util_init_aux_jacks);
876 
877 static struct simple_util_dai dummy_util_dais = {
878 	.name = "dummy_util_dais",
879 };
880 
881 int simple_util_init_priv(struct simple_util_priv *priv,
882 			  struct link_info *li)
883 {
884 	struct snd_soc_card *card = simple_priv_to_card(priv);
885 	struct device *dev = simple_priv_to_dev(priv);
886 	struct snd_soc_dai_link *dai_link;
887 	struct simple_dai_props *dai_props;
888 	struct simple_util_dai *dais;
889 	struct snd_soc_dai_link_component *dlcs;
890 	struct snd_soc_codec_conf *cconf = NULL;
891 	int i, dai_num = 0, dlc_num = 0, cnf_num = 0;
892 
893 	dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL);
894 	dai_link  = devm_kcalloc(dev, li->link, sizeof(*dai_link),  GFP_KERNEL);
895 	if (!dai_props || !dai_link)
896 		return -ENOMEM;
897 
898 	/*
899 	 * dais (= CPU+Codec)
900 	 * dlcs (= CPU+Codec+Platform)
901 	 */
902 	for (i = 0; i < li->link; i++) {
903 		int cc = li->num[i].cpus + li->num[i].codecs;
904 
905 		dai_num += cc;
906 		dlc_num += cc + li->num[i].platforms;
907 
908 		if (!li->num[i].cpus)
909 			cnf_num += li->num[i].codecs;
910 	}
911 
912 	dais = devm_kcalloc(dev, dai_num, sizeof(*dais), GFP_KERNEL);
913 	dlcs = devm_kcalloc(dev, dlc_num, sizeof(*dlcs), GFP_KERNEL);
914 	if (!dais || !dlcs)
915 		return -ENOMEM;
916 
917 	if (cnf_num) {
918 		cconf = devm_kcalloc(dev, cnf_num, sizeof(*cconf), GFP_KERNEL);
919 		if (!cconf)
920 			return -ENOMEM;
921 	}
922 
923 	dev_dbg(dev, "link %d, dais %d, ccnf %d\n",
924 		li->link, dai_num, cnf_num);
925 
926 	priv->dai_props		= dai_props;
927 	priv->dai_link		= dai_link;
928 	priv->dais		= dais;
929 	priv->dlcs		= dlcs;
930 	priv->codec_conf	= cconf;
931 
932 	card->dai_link		= priv->dai_link;
933 	card->num_links		= li->link;
934 	card->codec_conf	= cconf;
935 	card->num_configs	= cnf_num;
936 
937 	for (i = 0; i < li->link; i++) {
938 		if (li->num[i].cpus) {
939 			/* Normal CPU */
940 			dai_link[i].cpus	= dlcs;
941 			dai_props[i].num.cpus	=
942 			dai_link[i].num_cpus	= li->num[i].cpus;
943 			dai_props[i].cpu_dai	= dais;
944 
945 			dlcs += li->num[i].cpus;
946 			dais += li->num[i].cpus;
947 		} else {
948 			/* DPCM Be's CPU = dummy */
949 			dai_link[i].cpus	= &snd_soc_dummy_dlc;
950 			dai_props[i].num.cpus	=
951 			dai_link[i].num_cpus	= 1;
952 			dai_props[i].cpu_dai	= &dummy_util_dais;
953 		}
954 
955 		if (li->num[i].codecs) {
956 			/* Normal Codec */
957 			dai_link[i].codecs	= dlcs;
958 			dai_props[i].num.codecs	=
959 			dai_link[i].num_codecs	= li->num[i].codecs;
960 			dai_props[i].codec_dai	= dais;
961 
962 			dlcs += li->num[i].codecs;
963 			dais += li->num[i].codecs;
964 
965 			if (!li->num[i].cpus) {
966 				/* DPCM Be's Codec */
967 				dai_props[i].codec_conf = cconf;
968 				cconf += li->num[i].codecs;
969 			}
970 		} else {
971 			/* DPCM Fe's Codec = dummy */
972 			dai_link[i].codecs	= &snd_soc_dummy_dlc;
973 			dai_props[i].num.codecs	=
974 			dai_link[i].num_codecs	= 1;
975 			dai_props[i].codec_dai	= &dummy_util_dais;
976 		}
977 
978 		if (li->num[i].platforms) {
979 			/* Have Platform */
980 			dai_link[i].platforms		= dlcs;
981 			dai_props[i].num.platforms	=
982 			dai_link[i].num_platforms	= li->num[i].platforms;
983 
984 			dlcs += li->num[i].platforms;
985 		} else {
986 			/* Doesn't have Platform */
987 			dai_link[i].platforms		= NULL;
988 			dai_props[i].num.platforms	=
989 			dai_link[i].num_platforms	= 0;
990 		}
991 	}
992 
993 	return 0;
994 }
995 EXPORT_SYMBOL_GPL(simple_util_init_priv);
996 
997 void simple_util_remove(struct platform_device *pdev)
998 {
999 	struct snd_soc_card *card = platform_get_drvdata(pdev);
1000 	struct simple_util_priv *priv = snd_soc_card_get_drvdata(card);
1001 
1002 	simple_util_clean_reference(priv);
1003 }
1004 EXPORT_SYMBOL_GPL(simple_util_remove);
1005 
1006 int graph_util_card_probe(struct snd_soc_card *card)
1007 {
1008 	struct simple_util_priv *priv = snd_soc_card_get_drvdata(card);
1009 	int ret;
1010 
1011 	ret = simple_util_init_hp(card, &priv->hp_jack, NULL);
1012 	if (ret < 0)
1013 		goto end;
1014 
1015 	ret = simple_util_init_mic(card, &priv->mic_jack, NULL);
1016 end:
1017 	return simple_ret(priv, ret);
1018 }
1019 EXPORT_SYMBOL_GPL(graph_util_card_probe);
1020 
1021 int graph_util_is_ports0(struct device_node *np)
1022 {
1023 	struct device_node *parent __free(device_node) = of_get_parent(np);
1024 	struct device_node *port;
1025 
1026 	/* np is "endpoint" or "port" */
1027 	if (of_node_name_eq(np, "endpoint"))
1028 		port = parent;
1029 	else
1030 		port = np;
1031 
1032 	struct device_node *ports __free(device_node) = of_get_parent(port);
1033 	const char *at = strchr(kbasename(ports->full_name), '@');
1034 
1035 	/*
1036 	 * Since child iteration order may differ
1037 	 * between a base DT and DT overlays,
1038 	 * string match "ports" or "ports@0" in the node name instead.
1039 	 */
1040 	return !at || !strcmp(at, "@0");
1041 }
1042 EXPORT_SYMBOL_GPL(graph_util_is_ports0);
1043 
1044 static int graph_get_dai_id(struct device_node *ep)
1045 {
1046 	struct device_node *node __free(device_node) = of_graph_get_port_parent(ep);
1047 	struct device_node *port __free(device_node) = of_get_parent(ep);
1048 	struct of_endpoint info;
1049 	int i, id;
1050 	int ret;
1051 
1052 	/* use driver specified DAI ID if exist */
1053 	ret = snd_soc_get_dai_id(ep);
1054 	if (ret != -ENOTSUPP)
1055 		return ret;
1056 
1057 	/* use endpoint/port reg if exist */
1058 	ret = of_graph_parse_endpoint(ep, &info);
1059 	if (ret == 0) {
1060 		/*
1061 		 * Because it will count port/endpoint if it doesn't have "reg".
1062 		 * But, we can't judge whether it has "no reg", or "reg = <0>"
1063 		 * only of_graph_parse_endpoint().
1064 		 * We need to check "reg" property
1065 		 */
1066 
1067 		/* check port first */
1068 		ret = of_property_present(port, "reg");
1069 		if (ret)
1070 			return info.port;
1071 
1072 		/* check endpoint 2nd as backup */
1073 		if (of_property_present(ep,   "reg"))
1074 			return info.id;
1075 	}
1076 
1077 	/*
1078 	 * Non HDMI sound case, counting port/endpoint on its DT
1079 	 * is enough. Let's count it.
1080 	 */
1081 	i = 0;
1082 	id = -1;
1083 	for_each_of_graph_port(node, p) {
1084 		if (port == p) {
1085 			id = i;
1086 			break;
1087 		}
1088 		i++;
1089 	}
1090 
1091 	if (id < 0)
1092 		return -ENODEV;
1093 
1094 	return id;
1095 }
1096 
1097 int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep,
1098 			 struct snd_soc_dai_link_component *dlc, int *is_single_link)
1099 {
1100 	struct device *dev = simple_priv_to_dev(priv);
1101 	struct device_node *node;
1102 	struct of_phandle_args args = {};
1103 	struct snd_soc_dai_link_component resolved_dlc = {};
1104 	struct snd_soc_dai *dai;
1105 	const char *fallback_dai_name;
1106 	int ret;
1107 
1108 	if (!ep)
1109 		return 0;
1110 
1111 	node = of_graph_get_port_parent(ep);
1112 
1113 	/*
1114 	 * Try to find from DAI node
1115 	 */
1116 	args.np = ep;
1117 	dai = snd_soc_get_dai_via_args(&args);
1118 	if (dai) {
1119 		const char *dai_name = snd_soc_dai_name_get(dai);
1120 		const struct of_phandle_args *dai_args = snd_soc_copy_dai_args(dev, &args);
1121 
1122 		ret = -ENOMEM;
1123 		if (!dai_args)
1124 			goto err;
1125 
1126 		dlc->of_node  = node;
1127 		dlc->dai_name = dai_name;
1128 		dlc->dai_args = dai_args;
1129 	} else {
1130 		/* Get dai->name */
1131 		args.np		= node;
1132 		args.args[0]	= graph_get_dai_id(ep);
1133 		args.args_count	= (of_graph_get_endpoint_count(node) > 1);
1134 
1135 		ret = snd_soc_get_dlc(&args, &resolved_dlc);
1136 		if (ret < 0)
1137 			goto err;
1138 
1139 		/* Keep fallback dai_name valid across component rebind */
1140 		fallback_dai_name = resolved_dlc.dai_name;
1141 		if (fallback_dai_name) {
1142 			fallback_dai_name = devm_kstrdup_const(dev, fallback_dai_name,
1143 							       GFP_KERNEL);
1144 			ret = -ENOMEM;
1145 			if (!fallback_dai_name)
1146 				goto err;
1147 		}
1148 
1149 		dlc->of_node = resolved_dlc.of_node;
1150 		dlc->dai_name = fallback_dai_name;
1151 		dlc->dai_args = resolved_dlc.dai_args;
1152 	}
1153 
1154 	if (is_single_link)
1155 		*is_single_link = of_graph_get_endpoint_count(node) == 1;
1156 	ret = 0;
1157 err:
1158 	if (ret < 0)
1159 		of_node_put(node);
1160 
1161 	return simple_ret(priv, ret);
1162 }
1163 EXPORT_SYMBOL_GPL(graph_util_parse_dai);
1164 
1165 void graph_util_parse_link_direction(struct device_node *np,
1166 				    bool *playback_only, bool *capture_only)
1167 {
1168 	bool is_playback_only = of_property_read_bool(np, "playback-only");
1169 	bool is_capture_only  = of_property_read_bool(np, "capture-only");
1170 
1171 	if (playback_only && is_playback_only)
1172 		*playback_only = is_playback_only;
1173 	if (capture_only && is_capture_only)
1174 		*capture_only = is_capture_only;
1175 }
1176 EXPORT_SYMBOL_GPL(graph_util_parse_link_direction);
1177 
1178 static enum snd_soc_trigger_order
1179 __graph_util_parse_trigger_order(struct simple_util_priv *priv,
1180 				 struct device_node *np,
1181 				 const char *prop)
1182 {
1183 	u32 val[SND_SOC_TRIGGER_SIZE];
1184 	int ret;
1185 
1186 	ret = of_property_read_u32_array(np, prop, val, SND_SOC_TRIGGER_SIZE);
1187 	if (ret == 0) {
1188 		struct device *dev = simple_priv_to_dev(priv);
1189 		u32 order =	(val[0] << 8) +
1190 			(val[1] << 4) +
1191 			(val[2]);
1192 
1193 		switch (order) {
1194 		case	(SND_SOC_TRIGGER_LINK		<< 8) +
1195 			(SND_SOC_TRIGGER_COMPONENT	<< 4) +
1196 			(SND_SOC_TRIGGER_DAI):
1197 			return SND_SOC_TRIGGER_ORDER_DEFAULT;
1198 
1199 		case	(SND_SOC_TRIGGER_LINK		<< 8) +
1200 			(SND_SOC_TRIGGER_DAI		<< 4) +
1201 			(SND_SOC_TRIGGER_COMPONENT):
1202 			return SND_SOC_TRIGGER_ORDER_LDC;
1203 
1204 		default:
1205 			dev_err(dev, "unsupported trigger order [0x%x]\n", order);
1206 		}
1207 	}
1208 
1209 	/* SND_SOC_TRIGGER_ORDER_MAX means error */
1210 	return SND_SOC_TRIGGER_ORDER_MAX;
1211 }
1212 
1213 void graph_util_parse_trigger_order(struct simple_util_priv *priv,
1214 				    struct device_node *np,
1215 				    enum snd_soc_trigger_order *trigger_start,
1216 				    enum snd_soc_trigger_order *trigger_stop)
1217 {
1218 	static enum snd_soc_trigger_order order;
1219 
1220 	/*
1221 	 * We can use it like below
1222 	 *
1223 	 * #include <dt-bindings/sound/audio-graph.h>
1224 	 *
1225 	 * link-trigger-order = <SND_SOC_TRIGGER_LINK
1226 	 *			 SND_SOC_TRIGGER_COMPONENT
1227 	 *			 SND_SOC_TRIGGER_DAI>;
1228 	 */
1229 
1230 	order = __graph_util_parse_trigger_order(priv, np, "link-trigger-order");
1231 	if (order < SND_SOC_TRIGGER_ORDER_MAX) {
1232 		*trigger_start = order;
1233 		*trigger_stop  = order;
1234 	}
1235 
1236 	order = __graph_util_parse_trigger_order(priv, np, "link-trigger-order-start");
1237 	if (order < SND_SOC_TRIGGER_ORDER_MAX)
1238 		*trigger_start = order;
1239 
1240 	order = __graph_util_parse_trigger_order(priv, np, "link-trigger-order-stop");
1241 	if (order < SND_SOC_TRIGGER_ORDER_MAX)
1242 		*trigger_stop  = order;
1243 
1244 	return;
1245 }
1246 EXPORT_SYMBOL_GPL(graph_util_parse_trigger_order);
1247 
1248 /* Module information */
1249 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
1250 MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
1251 MODULE_LICENSE("GPL v2");
1252