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