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