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