1 // SPDX-License-Identifier: GPL-2.0
5 // Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 #include <dt-bindings/sound/audio-graph.h>
8 #include <linux/cleanup.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/module.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>
18 int simple_util_get_sample_fmt(struct simple_util_data
*data
)
26 } of_sample_fmt_table
[] = {
27 { "s8", SNDRV_PCM_FORMAT_S8
},
28 { "s16_le", SNDRV_PCM_FORMAT_S16_LE
},
29 { "s24_le", SNDRV_PCM_FORMAT_S24_LE
},
30 { "s24_3le", SNDRV_PCM_FORMAT_S24_3LE
},
31 { "s32_le", SNDRV_PCM_FORMAT_S32_LE
},
34 for (i
= 0; i
< ARRAY_SIZE(of_sample_fmt_table
); i
++) {
35 if (!strcmp(data
->convert_sample_format
,
36 of_sample_fmt_table
[i
].fmt
)) {
37 val
= of_sample_fmt_table
[i
].val
;
43 EXPORT_SYMBOL_GPL(simple_util_get_sample_fmt
);
45 static void simple_fixup_sample_fmt(struct simple_util_data
*data
,
46 struct snd_pcm_hw_params
*params
)
49 struct snd_mask
*mask
= hw_param_mask(params
,
50 SNDRV_PCM_HW_PARAM_FORMAT
);
52 val
= simple_util_get_sample_fmt(data
);
55 snd_mask_set(mask
, val
);
59 void simple_util_parse_convert(struct device_node
*np
,
61 struct simple_util_data
*data
)
71 /* sampling rate convert */
72 snprintf(prop
, sizeof(prop
), "%s%s", prefix
, "convert-rate");
73 of_property_read_u32(np
, prop
, &data
->convert_rate
);
75 /* channels transfer */
76 snprintf(prop
, sizeof(prop
), "%s%s", prefix
, "convert-channels");
77 of_property_read_u32(np
, prop
, &data
->convert_channels
);
79 /* convert sample format */
80 snprintf(prop
, sizeof(prop
), "%s%s", prefix
, "convert-sample-format");
81 of_property_read_string(np
, prop
, &data
->convert_sample_format
);
83 EXPORT_SYMBOL_GPL(simple_util_parse_convert
);
86 * simple_util_is_convert_required() - Query if HW param conversion was requested
89 * Returns true if any HW param conversion was requested for this DAI link with
90 * any "convert-xxx" properties.
92 bool simple_util_is_convert_required(const struct simple_util_data
*data
)
94 return data
->convert_rate
||
95 data
->convert_channels
||
96 data
->convert_sample_format
;
98 EXPORT_SYMBOL_GPL(simple_util_is_convert_required
);
100 int simple_util_parse_daifmt(struct device
*dev
,
101 struct device_node
*node
,
102 struct device_node
*codec
,
104 unsigned int *retfmt
)
106 struct device_node
*bitclkmaster
= NULL
;
107 struct device_node
*framemaster
= NULL
;
110 daifmt
= snd_soc_daifmt_parse_format(node
, prefix
);
112 snd_soc_daifmt_parse_clock_provider_as_phandle(node
, prefix
, &bitclkmaster
, &framemaster
);
113 if (!bitclkmaster
&& !framemaster
) {
115 * No dai-link level and master setting was not found from
116 * sound node level, revert back to legacy DT parsing and
117 * take the settings from codec node.
119 dev_dbg(dev
, "Revert to legacy daifmt parsing\n");
121 daifmt
|= snd_soc_daifmt_parse_clock_provider_as_flag(codec
, NULL
);
123 daifmt
|= snd_soc_daifmt_clock_provider_from_bitmap(
124 ((codec
== bitclkmaster
) << 4) | (codec
== framemaster
));
127 of_node_put(bitclkmaster
);
128 of_node_put(framemaster
);
134 EXPORT_SYMBOL_GPL(simple_util_parse_daifmt
);
136 int simple_util_parse_tdm_width_map(struct device
*dev
, struct device_node
*np
,
137 struct simple_util_dai
*dai
)
142 if (!of_property_read_bool(np
, "dai-tdm-slot-width-map"))
145 n
= of_property_count_elems_of_size(np
, "dai-tdm-slot-width-map", sizeof(u32
));
147 dev_err(dev
, "Invalid number of cells for dai-tdm-slot-width-map\n");
151 dai
->tdm_width_map
= devm_kcalloc(dev
, n
, sizeof(*dai
->tdm_width_map
), GFP_KERNEL
);
152 if (!dai
->tdm_width_map
)
155 u32
*array_values
__free(kfree
) = kcalloc(n
, sizeof(*array_values
),
160 ret
= of_property_read_u32_array(np
, "dai-tdm-slot-width-map", array_values
, n
);
162 dev_err(dev
, "Could not read dai-tdm-slot-width-map: %d\n", ret
);
167 for (i
= 0; i
< n
/ 3; ++i
) {
168 dai
->tdm_width_map
[i
].sample_bits
= *p
++;
169 dai
->tdm_width_map
[i
].slot_width
= *p
++;
170 dai
->tdm_width_map
[i
].slot_count
= *p
++;
173 dai
->n_tdm_widths
= i
;
177 EXPORT_SYMBOL_GPL(simple_util_parse_tdm_width_map
);
179 int simple_util_set_dailink_name(struct device
*dev
,
180 struct snd_soc_dai_link
*dai_link
,
181 const char *fmt
, ...)
188 name
= devm_kvasprintf(dev
, GFP_KERNEL
, fmt
, ap
);
194 dai_link
->name
= name
;
195 dai_link
->stream_name
= name
;
200 EXPORT_SYMBOL_GPL(simple_util_set_dailink_name
);
202 int simple_util_parse_card_name(struct snd_soc_card
*card
,
210 /* Parse the card name from DT */
211 ret
= snd_soc_of_parse_card_name(card
, "label");
212 if (ret
< 0 || !card
->name
) {
215 snprintf(prop
, sizeof(prop
), "%sname", prefix
);
216 ret
= snd_soc_of_parse_card_name(card
, prop
);
221 if (!card
->name
&& card
->dai_link
)
222 card
->name
= card
->dai_link
->name
;
226 EXPORT_SYMBOL_GPL(simple_util_parse_card_name
);
228 static int simple_clk_enable(struct simple_util_dai
*dai
)
231 return clk_prepare_enable(dai
->clk
);
236 static void simple_clk_disable(struct simple_util_dai
*dai
)
239 clk_disable_unprepare(dai
->clk
);
242 int simple_util_parse_clk(struct device
*dev
,
243 struct device_node
*node
,
244 struct simple_util_dai
*simple_dai
,
245 struct snd_soc_dai_link_component
*dlc
)
251 * Parse dai->sysclk come from "clocks = <&xxx>"
252 * (if system has common clock)
253 * or "system-clock-frequency = <xxx>"
254 * or device's module clock.
256 clk
= devm_get_clk_from_child(dev
, node
, NULL
);
257 simple_dai
->clk_fixed
= of_property_read_bool(
258 node
, "system-clock-fixed");
260 simple_dai
->sysclk
= clk_get_rate(clk
);
262 simple_dai
->clk
= clk
;
263 } else if (!of_property_read_u32(node
, "system-clock-frequency", &val
)) {
264 simple_dai
->sysclk
= val
;
265 simple_dai
->clk_fixed
= true;
267 clk
= devm_get_clk_from_child(dev
, dlc
->of_node
, NULL
);
269 simple_dai
->sysclk
= clk_get_rate(clk
);
272 if (of_property_read_bool(node
, "system-clock-direction-out"))
273 simple_dai
->clk_direction
= SND_SOC_CLOCK_OUT
;
277 EXPORT_SYMBOL_GPL(simple_util_parse_clk
);
279 static int simple_check_fixed_sysclk(struct device
*dev
,
280 struct simple_util_dai
*dai
,
281 unsigned int *fixed_sysclk
)
283 if (dai
->clk_fixed
) {
284 if (*fixed_sysclk
&& *fixed_sysclk
!= dai
->sysclk
) {
285 dev_err(dev
, "inconsistent fixed sysclk rates (%u vs %u)\n",
286 *fixed_sysclk
, dai
->sysclk
);
289 *fixed_sysclk
= dai
->sysclk
;
295 int simple_util_startup(struct snd_pcm_substream
*substream
)
297 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
298 struct simple_util_priv
*priv
= snd_soc_card_get_drvdata(rtd
->card
);
299 struct simple_dai_props
*props
= simple_priv_to_props(priv
, rtd
->num
);
300 struct simple_util_dai
*dai
;
301 unsigned int fixed_sysclk
= 0;
305 for_each_prop_dai_cpu(props
, i1
, dai
) {
306 ret
= simple_clk_enable(dai
);
309 ret
= simple_check_fixed_sysclk(rtd
->dev
, dai
, &fixed_sysclk
);
314 for_each_prop_dai_codec(props
, i2
, dai
) {
315 ret
= simple_clk_enable(dai
);
318 ret
= simple_check_fixed_sysclk(rtd
->dev
, dai
, &fixed_sysclk
);
323 if (fixed_sysclk
&& props
->mclk_fs
) {
324 unsigned int fixed_rate
= fixed_sysclk
/ props
->mclk_fs
;
326 if (fixed_sysclk
% props
->mclk_fs
) {
327 dev_err(rtd
->dev
, "fixed sysclk %u not divisible by mclk_fs %u\n",
328 fixed_sysclk
, props
->mclk_fs
);
332 ret
= snd_pcm_hw_constraint_minmax(substream
->runtime
, SNDRV_PCM_HW_PARAM_RATE
,
333 fixed_rate
, fixed_rate
);
341 for_each_prop_dai_codec(props
, i
, dai
) {
344 simple_clk_disable(dai
);
347 for_each_prop_dai_cpu(props
, i
, dai
) {
350 simple_clk_disable(dai
);
354 EXPORT_SYMBOL_GPL(simple_util_startup
);
356 void simple_util_shutdown(struct snd_pcm_substream
*substream
)
358 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
359 struct simple_util_priv
*priv
= snd_soc_card_get_drvdata(rtd
->card
);
360 struct simple_dai_props
*props
= simple_priv_to_props(priv
, rtd
->num
);
361 struct simple_util_dai
*dai
;
364 for_each_prop_dai_cpu(props
, i
, dai
) {
365 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, i
);
367 if (props
->mclk_fs
&& !dai
->clk_fixed
&& !snd_soc_dai_active(cpu_dai
))
368 snd_soc_dai_set_sysclk(cpu_dai
,
369 0, 0, SND_SOC_CLOCK_OUT
);
371 simple_clk_disable(dai
);
373 for_each_prop_dai_codec(props
, i
, dai
) {
374 struct snd_soc_dai
*codec_dai
= snd_soc_rtd_to_codec(rtd
, i
);
376 if (props
->mclk_fs
&& !dai
->clk_fixed
&& !snd_soc_dai_active(codec_dai
))
377 snd_soc_dai_set_sysclk(codec_dai
,
378 0, 0, SND_SOC_CLOCK_IN
);
380 simple_clk_disable(dai
);
383 EXPORT_SYMBOL_GPL(simple_util_shutdown
);
385 static int simple_set_clk_rate(struct device
*dev
,
386 struct simple_util_dai
*simple_dai
,
392 if (simple_dai
->clk_fixed
&& rate
!= simple_dai
->sysclk
) {
393 dev_err(dev
, "dai %s invalid clock rate %lu\n", simple_dai
->name
, rate
);
397 if (!simple_dai
->clk
)
400 if (clk_get_rate(simple_dai
->clk
) == rate
)
403 return clk_set_rate(simple_dai
->clk
, rate
);
406 static int simple_set_tdm(struct snd_soc_dai
*dai
,
407 struct simple_util_dai
*simple_dai
,
408 struct snd_pcm_hw_params
*params
)
410 int sample_bits
= params_width(params
);
411 int slot_width
, slot_count
;
414 if (!simple_dai
|| !simple_dai
->tdm_width_map
)
417 slot_width
= simple_dai
->slot_width
;
418 slot_count
= simple_dai
->slots
;
421 slot_width
= sample_bits
;
423 for (i
= 0; i
< simple_dai
->n_tdm_widths
; ++i
) {
424 if (simple_dai
->tdm_width_map
[i
].sample_bits
== sample_bits
) {
425 slot_width
= simple_dai
->tdm_width_map
[i
].slot_width
;
426 slot_count
= simple_dai
->tdm_width_map
[i
].slot_count
;
431 ret
= snd_soc_dai_set_tdm_slot(dai
,
432 simple_dai
->tx_slot_mask
,
433 simple_dai
->rx_slot_mask
,
436 if (ret
&& ret
!= -ENOTSUPP
) {
437 dev_err(dai
->dev
, "simple-card: set_tdm_slot error: %d\n", ret
);
444 int simple_util_hw_params(struct snd_pcm_substream
*substream
,
445 struct snd_pcm_hw_params
*params
)
447 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
448 struct simple_util_dai
*pdai
;
449 struct snd_soc_dai
*sdai
;
450 struct simple_util_priv
*priv
= snd_soc_card_get_drvdata(rtd
->card
);
451 struct simple_dai_props
*props
= simple_priv_to_props(priv
, rtd
->num
);
452 unsigned int mclk
, mclk_fs
= 0;
456 mclk_fs
= props
->mclk_fs
;
459 struct snd_soc_component
*component
;
460 mclk
= params_rate(params
) * mclk_fs
;
462 for_each_prop_dai_codec(props
, i
, pdai
) {
463 ret
= simple_set_clk_rate(rtd
->dev
, pdai
, mclk
);
468 for_each_prop_dai_cpu(props
, i
, pdai
) {
469 ret
= simple_set_clk_rate(rtd
->dev
, pdai
, mclk
);
474 /* Ensure sysclk is set on all components in case any
475 * (such as platform components) are missed by calls to
476 * snd_soc_dai_set_sysclk.
478 for_each_rtd_components(rtd
, i
, component
) {
479 ret
= snd_soc_component_set_sysclk(component
, 0, 0,
480 mclk
, SND_SOC_CLOCK_IN
);
481 if (ret
&& ret
!= -ENOTSUPP
)
485 for_each_rtd_codec_dais(rtd
, i
, sdai
) {
486 ret
= snd_soc_dai_set_sysclk(sdai
, 0, mclk
, SND_SOC_CLOCK_IN
);
487 if (ret
&& ret
!= -ENOTSUPP
)
491 for_each_rtd_cpu_dais(rtd
, i
, sdai
) {
492 ret
= snd_soc_dai_set_sysclk(sdai
, 0, mclk
, SND_SOC_CLOCK_OUT
);
493 if (ret
&& ret
!= -ENOTSUPP
)
498 for_each_prop_dai_codec(props
, i
, pdai
) {
499 sdai
= snd_soc_rtd_to_codec(rtd
, i
);
500 ret
= simple_set_tdm(sdai
, pdai
, params
);
505 for_each_prop_dai_cpu(props
, i
, pdai
) {
506 sdai
= snd_soc_rtd_to_cpu(rtd
, i
);
507 ret
= simple_set_tdm(sdai
, pdai
, params
);
514 EXPORT_SYMBOL_GPL(simple_util_hw_params
);
516 int simple_util_be_hw_params_fixup(struct snd_soc_pcm_runtime
*rtd
,
517 struct snd_pcm_hw_params
*params
)
519 struct simple_util_priv
*priv
= snd_soc_card_get_drvdata(rtd
->card
);
520 struct simple_dai_props
*dai_props
= simple_priv_to_props(priv
, rtd
->num
);
521 struct simple_util_data
*data
= &dai_props
->adata
;
522 struct snd_interval
*rate
= hw_param_interval(params
, SNDRV_PCM_HW_PARAM_RATE
);
523 struct snd_interval
*channels
= hw_param_interval(params
, SNDRV_PCM_HW_PARAM_CHANNELS
);
525 if (data
->convert_rate
)
527 rate
->max
= data
->convert_rate
;
529 if (data
->convert_channels
)
531 channels
->max
= data
->convert_channels
;
533 if (data
->convert_sample_format
)
534 simple_fixup_sample_fmt(data
, params
);
538 EXPORT_SYMBOL_GPL(simple_util_be_hw_params_fixup
);
540 static int simple_init_dai(struct snd_soc_dai
*dai
, struct simple_util_dai
*simple_dai
)
547 if (simple_dai
->sysclk
) {
548 ret
= snd_soc_dai_set_sysclk(dai
, 0, simple_dai
->sysclk
,
549 simple_dai
->clk_direction
);
550 if (ret
&& ret
!= -ENOTSUPP
) {
551 dev_err(dai
->dev
, "simple-card: set_sysclk error\n");
556 if (simple_dai
->slots
) {
557 ret
= snd_soc_dai_set_tdm_slot(dai
,
558 simple_dai
->tx_slot_mask
,
559 simple_dai
->rx_slot_mask
,
561 simple_dai
->slot_width
);
562 if (ret
&& ret
!= -ENOTSUPP
) {
563 dev_err(dai
->dev
, "simple-card: set_tdm_slot error\n");
571 static inline int simple_component_is_codec(struct snd_soc_component
*component
)
573 return component
->driver
->endianness
;
576 static int simple_init_for_codec2codec(struct snd_soc_pcm_runtime
*rtd
,
577 struct simple_dai_props
*dai_props
)
579 struct snd_soc_dai_link
*dai_link
= rtd
->dai_link
;
580 struct snd_soc_component
*component
;
581 struct snd_soc_pcm_stream
*c2c_params
;
582 struct snd_pcm_hardware hw
;
585 /* Do nothing if it already has Codec2Codec settings */
586 if (dai_link
->c2c_params
)
589 /* Do nothing if it was DPCM :: BE */
590 if (dai_link
->no_pcm
)
594 for_each_rtd_components(rtd
, i
, component
) {
595 if (!simple_component_is_codec(component
))
599 /* Assumes the capabilities are the same for all supported streams */
600 for_each_pcm_streams(stream
) {
601 ret
= snd_soc_runtime_calc_hw(rtd
, &hw
, stream
);
607 dev_err(rtd
->dev
, "simple-card: no valid dai_link params\n");
611 c2c_params
= devm_kzalloc(rtd
->dev
, sizeof(*c2c_params
), GFP_KERNEL
);
615 c2c_params
->formats
= hw
.formats
;
616 c2c_params
->rates
= hw
.rates
;
617 c2c_params
->rate_min
= hw
.rate_min
;
618 c2c_params
->rate_max
= hw
.rate_max
;
619 c2c_params
->channels_min
= hw
.channels_min
;
620 c2c_params
->channels_max
= hw
.channels_max
;
622 dai_link
->c2c_params
= c2c_params
;
623 dai_link
->num_c2c_params
= 1;
628 int simple_util_dai_init(struct snd_soc_pcm_runtime
*rtd
)
630 struct simple_util_priv
*priv
= snd_soc_card_get_drvdata(rtd
->card
);
631 struct simple_dai_props
*props
= simple_priv_to_props(priv
, rtd
->num
);
632 struct simple_util_dai
*dai
;
635 for_each_prop_dai_codec(props
, i
, dai
) {
636 ret
= simple_init_dai(snd_soc_rtd_to_codec(rtd
, i
), dai
);
640 for_each_prop_dai_cpu(props
, i
, dai
) {
641 ret
= simple_init_dai(snd_soc_rtd_to_cpu(rtd
, i
), dai
);
646 ret
= simple_init_for_codec2codec(rtd
, props
);
652 EXPORT_SYMBOL_GPL(simple_util_dai_init
);
654 void simple_util_canonicalize_platform(struct snd_soc_dai_link_component
*platforms
,
655 struct snd_soc_dai_link_component
*cpus
)
658 * Assumes Platform == CPU
660 * Some CPU might be using soc-generic-dmaengine-pcm. This means CPU and Platform
661 * are different Component, but are sharing same component->dev.
663 * Let's assume Platform is same as CPU if it doesn't identify Platform on DT.
665 * simple-card.c :: simple_count_noml()
667 if (!platforms
->of_node
)
668 snd_soc_dlc_use_cpu_as_platform(platforms
, cpus
);
670 EXPORT_SYMBOL_GPL(simple_util_canonicalize_platform
);
672 void simple_util_canonicalize_cpu(struct snd_soc_dai_link_component
*cpus
,
676 * In soc_bind_dai_link() will check cpu name after
677 * of_node matching if dai_link has cpu_dai_name.
678 * but, it will never match if name was created by
679 * fmt_single_name() remove cpu_dai_name if cpu_args
682 * fmt_multiple_name()
685 cpus
->dai_name
= NULL
;
687 EXPORT_SYMBOL_GPL(simple_util_canonicalize_cpu
);
689 void simple_util_clean_reference(struct snd_soc_card
*card
)
691 struct snd_soc_dai_link
*dai_link
;
692 struct snd_soc_dai_link_component
*cpu
;
693 struct snd_soc_dai_link_component
*codec
;
696 for_each_card_prelinks(card
, i
, dai_link
) {
697 for_each_link_cpus(dai_link
, j
, cpu
)
698 of_node_put(cpu
->of_node
);
699 for_each_link_codecs(dai_link
, j
, codec
)
700 of_node_put(codec
->of_node
);
703 EXPORT_SYMBOL_GPL(simple_util_clean_reference
);
705 int simple_util_parse_routing(struct snd_soc_card
*card
,
708 struct device_node
*node
= card
->dev
->of_node
;
714 snprintf(prop
, sizeof(prop
), "%s%s", prefix
, "routing");
716 if (!of_property_read_bool(node
, prop
))
719 return snd_soc_of_parse_audio_routing(card
, prop
);
721 EXPORT_SYMBOL_GPL(simple_util_parse_routing
);
723 int simple_util_parse_widgets(struct snd_soc_card
*card
,
726 struct device_node
*node
= card
->dev
->of_node
;
732 snprintf(prop
, sizeof(prop
), "%s%s", prefix
, "widgets");
734 if (of_property_read_bool(node
, prop
))
735 return snd_soc_of_parse_audio_simple_widgets(card
, prop
);
737 /* no widgets is not error */
740 EXPORT_SYMBOL_GPL(simple_util_parse_widgets
);
742 int simple_util_parse_pin_switches(struct snd_soc_card
*card
,
750 snprintf(prop
, sizeof(prop
), "%s%s", prefix
, "pin-switches");
752 return snd_soc_of_parse_pin_switches(card
, prop
);
754 EXPORT_SYMBOL_GPL(simple_util_parse_pin_switches
);
756 int simple_util_init_jack(struct snd_soc_card
*card
,
757 struct simple_util_jack
*sjack
,
758 int is_hp
, char *prefix
,
761 struct device
*dev
= card
->dev
;
762 struct gpio_desc
*desc
;
773 snprintf(prop
, sizeof(prop
), "%shp-det", prefix
);
774 pin_name
= pin
? pin
: "Headphones";
775 gpio_name
= "Headphone detection";
776 mask
= SND_JACK_HEADPHONE
;
778 snprintf(prop
, sizeof(prop
), "%smic-det", prefix
);
779 pin_name
= pin
? pin
: "Mic Jack";
780 gpio_name
= "Mic detection";
781 mask
= SND_JACK_MICROPHONE
;
784 desc
= gpiod_get_optional(dev
, prop
, GPIOD_IN
);
785 error
= PTR_ERR_OR_ZERO(desc
);
790 error
= gpiod_set_consumer_name(desc
, gpio_name
);
794 sjack
->pin
.pin
= pin_name
;
795 sjack
->pin
.mask
= mask
;
797 sjack
->gpio
.name
= gpio_name
;
798 sjack
->gpio
.report
= mask
;
799 sjack
->gpio
.desc
= desc
;
800 sjack
->gpio
.debounce_time
= 150;
802 snd_soc_card_jack_new_pins(card
, pin_name
, mask
, &sjack
->jack
,
805 snd_soc_jack_add_gpios(&sjack
->jack
, 1, &sjack
->gpio
);
810 EXPORT_SYMBOL_GPL(simple_util_init_jack
);
812 int simple_util_init_aux_jacks(struct simple_util_priv
*priv
, char *prefix
)
814 struct snd_soc_card
*card
= simple_priv_to_card(priv
);
815 struct snd_soc_component
*component
;
816 int found_jack_index
= 0;
824 for_each_card_auxs(card
, component
) {
825 type
= snd_soc_component_get_jack_type(component
);
832 priv
->aux_jacks
= devm_kcalloc(card
->dev
, num
,
833 sizeof(struct snd_soc_jack
), GFP_KERNEL
);
834 if (!priv
->aux_jacks
)
837 for_each_card_auxs(card
, component
) {
839 struct snd_soc_jack
*jack
;
841 if (found_jack_index
>= num
)
844 type
= snd_soc_component_get_jack_type(component
);
849 jack
= &(priv
->aux_jacks
[found_jack_index
++]);
850 snprintf(id
, sizeof(id
), "%s-jack", component
->name
);
851 ret
= snd_soc_card_jack_new(card
, id
, type
, jack
);
855 (void)snd_soc_component_set_jack(component
, jack
, NULL
);
859 EXPORT_SYMBOL_GPL(simple_util_init_aux_jacks
);
861 int simple_util_init_priv(struct simple_util_priv
*priv
,
862 struct link_info
*li
)
864 struct snd_soc_card
*card
= simple_priv_to_card(priv
);
865 struct device
*dev
= simple_priv_to_dev(priv
);
866 struct snd_soc_dai_link
*dai_link
;
867 struct simple_dai_props
*dai_props
;
868 struct simple_util_dai
*dais
;
869 struct snd_soc_dai_link_component
*dlcs
;
870 struct snd_soc_codec_conf
*cconf
= NULL
;
871 int i
, dai_num
= 0, dlc_num
= 0, cnf_num
= 0;
873 dai_props
= devm_kcalloc(dev
, li
->link
, sizeof(*dai_props
), GFP_KERNEL
);
874 dai_link
= devm_kcalloc(dev
, li
->link
, sizeof(*dai_link
), GFP_KERNEL
);
875 if (!dai_props
|| !dai_link
)
880 * dlcs (= CPU+Codec+Platform)
882 for (i
= 0; i
< li
->link
; i
++) {
883 int cc
= li
->num
[i
].cpus
+ li
->num
[i
].codecs
;
886 dlc_num
+= cc
+ li
->num
[i
].platforms
;
888 if (!li
->num
[i
].cpus
)
889 cnf_num
+= li
->num
[i
].codecs
;
892 dais
= devm_kcalloc(dev
, dai_num
, sizeof(*dais
), GFP_KERNEL
);
893 dlcs
= devm_kcalloc(dev
, dlc_num
, sizeof(*dlcs
), GFP_KERNEL
);
898 cconf
= devm_kcalloc(dev
, cnf_num
, sizeof(*cconf
), GFP_KERNEL
);
903 dev_dbg(dev
, "link %d, dais %d, ccnf %d\n",
904 li
->link
, dai_num
, cnf_num
);
906 priv
->dai_props
= dai_props
;
907 priv
->dai_link
= dai_link
;
910 priv
->codec_conf
= cconf
;
912 card
->dai_link
= priv
->dai_link
;
913 card
->num_links
= li
->link
;
914 card
->codec_conf
= cconf
;
915 card
->num_configs
= cnf_num
;
917 for (i
= 0; i
< li
->link
; i
++) {
918 if (li
->num
[i
].cpus
) {
920 dai_link
[i
].cpus
= dlcs
;
921 dai_props
[i
].num
.cpus
=
922 dai_link
[i
].num_cpus
= li
->num
[i
].cpus
;
923 dai_props
[i
].cpu_dai
= dais
;
925 dlcs
+= li
->num
[i
].cpus
;
926 dais
+= li
->num
[i
].cpus
;
928 /* DPCM Be's CPU = dummy */
929 dai_link
[i
].cpus
= &snd_soc_dummy_dlc
;
930 dai_props
[i
].num
.cpus
=
931 dai_link
[i
].num_cpus
= 1;
934 if (li
->num
[i
].codecs
) {
936 dai_link
[i
].codecs
= dlcs
;
937 dai_props
[i
].num
.codecs
=
938 dai_link
[i
].num_codecs
= li
->num
[i
].codecs
;
939 dai_props
[i
].codec_dai
= dais
;
941 dlcs
+= li
->num
[i
].codecs
;
942 dais
+= li
->num
[i
].codecs
;
944 if (!li
->num
[i
].cpus
) {
945 /* DPCM Be's Codec */
946 dai_props
[i
].codec_conf
= cconf
;
947 cconf
+= li
->num
[i
].codecs
;
950 /* DPCM Fe's Codec = dummy */
951 dai_link
[i
].codecs
= &snd_soc_dummy_dlc
;
952 dai_props
[i
].num
.codecs
=
953 dai_link
[i
].num_codecs
= 1;
956 if (li
->num
[i
].platforms
) {
958 dai_link
[i
].platforms
= dlcs
;
959 dai_props
[i
].num
.platforms
=
960 dai_link
[i
].num_platforms
= li
->num
[i
].platforms
;
962 dlcs
+= li
->num
[i
].platforms
;
964 /* Doesn't have Platform */
965 dai_link
[i
].platforms
= NULL
;
966 dai_props
[i
].num
.platforms
=
967 dai_link
[i
].num_platforms
= 0;
973 EXPORT_SYMBOL_GPL(simple_util_init_priv
);
975 void simple_util_remove(struct platform_device
*pdev
)
977 struct snd_soc_card
*card
= platform_get_drvdata(pdev
);
979 simple_util_clean_reference(card
);
981 EXPORT_SYMBOL_GPL(simple_util_remove
);
983 int graph_util_card_probe(struct snd_soc_card
*card
)
985 struct simple_util_priv
*priv
= snd_soc_card_get_drvdata(card
);
988 ret
= simple_util_init_hp(card
, &priv
->hp_jack
, NULL
);
992 ret
= simple_util_init_mic(card
, &priv
->mic_jack
, NULL
);
998 EXPORT_SYMBOL_GPL(graph_util_card_probe
);
1000 int graph_util_is_ports0(struct device_node
*np
)
1002 struct device_node
*port
, *ports
, *ports0
, *top
;
1005 /* np is "endpoint" or "port" */
1006 if (of_node_name_eq(np
, "endpoint")) {
1007 port
= of_get_parent(np
);
1013 ports
= of_get_parent(port
);
1014 top
= of_get_parent(ports
);
1015 ports0
= of_get_child_by_name(top
, "ports");
1017 ret
= ports0
== ports
;
1021 of_node_put(ports0
);
1026 EXPORT_SYMBOL_GPL(graph_util_is_ports0
);
1028 static int graph_get_dai_id(struct device_node
*ep
)
1030 struct device_node
*node
;
1031 struct device_node
*endpoint
;
1032 struct of_endpoint info
;
1036 /* use driver specified DAI ID if exist */
1037 ret
= snd_soc_get_dai_id(ep
);
1038 if (ret
!= -ENOTSUPP
)
1041 /* use endpoint/port reg if exist */
1042 ret
= of_graph_parse_endpoint(ep
, &info
);
1045 * Because it will count port/endpoint if it doesn't have "reg".
1046 * But, we can't judge whether it has "no reg", or "reg = <0>"
1047 * only of_graph_parse_endpoint().
1048 * We need to check "reg" property
1050 if (of_property_present(ep
, "reg"))
1053 node
= of_get_parent(ep
);
1054 ret
= of_property_present(node
, "reg");
1059 node
= of_graph_get_port_parent(ep
);
1062 * Non HDMI sound case, counting port/endpoint on its DT
1063 * is enough. Let's count it.
1067 for_each_endpoint_of_node(node
, endpoint
) {
1081 int graph_util_parse_dai(struct device
*dev
, struct device_node
*ep
,
1082 struct snd_soc_dai_link_component
*dlc
, int *is_single_link
)
1084 struct device_node
*node
;
1085 struct of_phandle_args args
= {};
1086 struct snd_soc_dai
*dai
;
1092 node
= of_graph_get_port_parent(ep
);
1095 * Try to find from DAI node
1098 dai
= snd_soc_get_dai_via_args(&args
);
1100 dlc
->dai_name
= snd_soc_dai_name_get(dai
);
1101 dlc
->dai_args
= snd_soc_copy_dai_args(dev
, &args
);
1110 args
.args
[0] = graph_get_dai_id(ep
);
1111 args
.args_count
= (of_graph_get_endpoint_count(node
) > 1);
1116 * Here, dlc->dai_name is pointer to CPU/Codec DAI name.
1117 * If user unbinded CPU or Codec driver, but not for Sound Card,
1118 * dlc->dai_name is keeping unbinded CPU or Codec
1121 * If user re-bind CPU or Codec driver again, ALSA SoC will try
1122 * to rebind Card via snd_soc_try_rebind_card(), but because of
1123 * above reason, it might can't bind Sound Card.
1124 * Because Sound Card is pointing to released dai_name pointer.
1126 * To avoid this rebind Card issue,
1127 * 1) It needs to alloc memory to keep dai_name eventhough
1128 * CPU or Codec driver was unbinded, or
1129 * 2) user need to rebind Sound Card everytime
1130 * if he unbinded CPU or Codec.
1132 ret
= snd_soc_get_dlc(&args
, dlc
);
1140 *is_single_link
= of_graph_get_endpoint_count(node
) == 1;
1144 EXPORT_SYMBOL_GPL(graph_util_parse_dai
);
1146 void graph_util_parse_link_direction(struct device_node
*np
,
1147 bool *playback_only
, bool *capture_only
)
1149 bool is_playback_only
= of_property_read_bool(np
, "playback-only");
1150 bool is_capture_only
= of_property_read_bool(np
, "capture-only");
1152 if (is_playback_only
)
1153 *playback_only
= is_playback_only
;
1154 if (is_capture_only
)
1155 *capture_only
= is_capture_only
;
1157 EXPORT_SYMBOL_GPL(graph_util_parse_link_direction
);
1159 static enum snd_soc_trigger_order
1160 __graph_util_parse_trigger_order(struct simple_util_priv
*priv
,
1161 struct device_node
*np
,
1164 u32 val
[SND_SOC_TRIGGER_SIZE
];
1167 ret
= of_property_read_u32_array(np
, prop
, val
, SND_SOC_TRIGGER_SIZE
);
1169 struct device
*dev
= simple_priv_to_dev(priv
);
1170 u32 order
= (val
[0] << 8) +
1175 case (SND_SOC_TRIGGER_LINK
<< 8) +
1176 (SND_SOC_TRIGGER_COMPONENT
<< 4) +
1177 (SND_SOC_TRIGGER_DAI
):
1178 return SND_SOC_TRIGGER_ORDER_DEFAULT
;
1180 case (SND_SOC_TRIGGER_LINK
<< 8) +
1181 (SND_SOC_TRIGGER_DAI
<< 4) +
1182 (SND_SOC_TRIGGER_COMPONENT
):
1183 return SND_SOC_TRIGGER_ORDER_LDC
;
1186 dev_err(dev
, "unsupported trigger order [0x%x]\n", order
);
1190 /* SND_SOC_TRIGGER_ORDER_MAX means error */
1191 return SND_SOC_TRIGGER_ORDER_MAX
;
1194 void graph_util_parse_trigger_order(struct simple_util_priv
*priv
,
1195 struct device_node
*np
,
1196 enum snd_soc_trigger_order
*trigger_start
,
1197 enum snd_soc_trigger_order
*trigger_stop
)
1199 static enum snd_soc_trigger_order order
;
1202 * We can use it like below
1204 * #include <dt-bindings/sound/audio-graph.h>
1206 * link-trigger-order = <SND_SOC_TRIGGER_LINK
1207 * SND_SOC_TRIGGER_COMPONENT
1208 * SND_SOC_TRIGGER_DAI>;
1211 order
= __graph_util_parse_trigger_order(priv
, np
, "link-trigger-order");
1212 if (order
< SND_SOC_TRIGGER_ORDER_MAX
) {
1213 *trigger_start
= order
;
1214 *trigger_stop
= order
;
1217 order
= __graph_util_parse_trigger_order(priv
, np
, "link-trigger-order-start");
1218 if (order
< SND_SOC_TRIGGER_ORDER_MAX
)
1219 *trigger_start
= order
;
1221 order
= __graph_util_parse_trigger_order(priv
, np
, "link-trigger-order-stop");
1222 if (order
< SND_SOC_TRIGGER_ORDER_MAX
)
1223 *trigger_stop
= order
;
1227 EXPORT_SYMBOL_GPL(graph_util_parse_trigger_order
);
1229 /* Module information */
1230 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
1231 MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
1232 MODULE_LICENSE("GPL v2");