Lines Matching +full:sound +full:- +full:name +full:- +full:prefix
1 // SPDX-License-Identifier: GPL-2.0
3 // simple-card-utils.c
7 #include <dt-bindings/sound/audio-graph.h>
14 #include <sound/jack.h>
15 #include <sound/pcm_params.h>
16 #include <sound/simple_card_utils.h>
28 int val = -EINVAL; in simple_util_get_sample_fmt()
42 if (!strcmp(data->convert_sample_format, in simple_util_get_sample_fmt()
67 char *prefix, in simple_util_parse_convert() argument
75 if (!prefix) in simple_util_parse_convert()
76 prefix = ""; in simple_util_parse_convert()
79 snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-rate"); in simple_util_parse_convert()
80 of_property_read_u32(np, prop, &data->convert_rate); in simple_util_parse_convert()
83 snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-channels"); in simple_util_parse_convert()
84 of_property_read_u32(np, prop, &data->convert_channels); in simple_util_parse_convert()
87 snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-sample-format"); in simple_util_parse_convert()
88 of_property_read_string(np, prop, &data->convert_sample_format); in simple_util_parse_convert()
93 * simple_util_is_convert_required() - Query if HW param conversion was requested
97 * any "convert-xxx" properties.
101 return data->convert_rate || in simple_util_is_convert_required()
102 data->convert_channels || in simple_util_is_convert_required()
103 data->convert_sample_format; in simple_util_is_convert_required()
110 char *prefix, in simple_util_parse_daifmt() argument
117 daifmt = snd_soc_daifmt_parse_format(node, prefix); in simple_util_parse_daifmt()
119 snd_soc_daifmt_parse_clock_provider_as_phandle(node, prefix, &bitclkmaster, &framemaster); in simple_util_parse_daifmt()
122 * No dai-link level and master setting was not found from in simple_util_parse_daifmt()
123 * sound node level, revert back to legacy DT parsing and in simple_util_parse_daifmt()
157 n = of_property_count_elems_of_size(np, "dai-tdm-slot-width-map", sizeof(u32)); in simple_util_parse_tdm_width_map()
162 dev_err(dev, "Invalid number of cells for dai-tdm-slot-width-map\n"); in simple_util_parse_tdm_width_map()
163 return simple_ret(priv, -EINVAL); /* see NOTE */ in simple_util_parse_tdm_width_map()
166 ret = -ENOMEM; in simple_util_parse_tdm_width_map()
167 dai->tdm_width_map = devm_kcalloc(dev, n, sizeof(*dai->tdm_width_map), GFP_KERNEL); in simple_util_parse_tdm_width_map()
168 if (!dai->tdm_width_map) in simple_util_parse_tdm_width_map()
175 ret = of_property_read_u32_array(np, "dai-tdm-slot-width-map", array_values, n); in simple_util_parse_tdm_width_map()
177 dev_err(dev, "Could not read dai-tdm-slot-width-map: %d\n", ret); in simple_util_parse_tdm_width_map()
183 dai->tdm_width_map[i].sample_bits = *p++; in simple_util_parse_tdm_width_map()
184 dai->tdm_width_map[i].slot_width = *p++; in simple_util_parse_tdm_width_map()
185 dai->tdm_width_map[i].slot_count = *p++; in simple_util_parse_tdm_width_map()
188 dai->n_tdm_widths = i; in simple_util_parse_tdm_width_map()
201 char *name = NULL; in simple_util_set_dailink_name() local
202 int ret = -ENOMEM; in simple_util_set_dailink_name()
205 name = devm_kvasprintf(dev, GFP_KERNEL, fmt, ap); in simple_util_set_dailink_name()
208 if (name) { in simple_util_set_dailink_name()
211 dai_link->name = name; in simple_util_set_dailink_name()
212 dai_link->stream_name = name; in simple_util_set_dailink_name()
220 char *prefix) in simple_util_parse_card_name() argument
225 if (!prefix) in simple_util_parse_card_name()
226 prefix = ""; in simple_util_parse_card_name()
228 /* Parse the card name from DT */ in simple_util_parse_card_name()
230 if (ret < 0 || !card->name) { in simple_util_parse_card_name()
233 snprintf(prop, sizeof(prop), "%sname", prefix); in simple_util_parse_card_name()
239 if (!card->name && card->dai_link) in simple_util_parse_card_name()
240 card->name = card->dai_link->name; in simple_util_parse_card_name()
249 return clk_prepare_enable(dai->clk); in simple_clk_enable()
257 clk_disable_unprepare(dai->clk); in simple_clk_disable()
269 * Parse dai->sysclk come from "clocks = <&xxx>" in simple_util_parse_clk()
271 * or "system-clock-frequency = <xxx>" in simple_util_parse_clk()
275 simple_dai->clk_fixed = of_property_read_bool( in simple_util_parse_clk()
276 node, "system-clock-fixed"); in simple_util_parse_clk()
278 simple_dai->sysclk = clk_get_rate(clk); in simple_util_parse_clk()
280 simple_dai->clk = clk; in simple_util_parse_clk()
281 } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { in simple_util_parse_clk()
282 simple_dai->sysclk = val; in simple_util_parse_clk()
283 simple_dai->clk_fixed = true; in simple_util_parse_clk()
285 clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); in simple_util_parse_clk()
287 simple_dai->sysclk = clk_get_rate(clk); in simple_util_parse_clk()
290 if (of_property_read_bool(node, "system-clock-direction-out")) in simple_util_parse_clk()
291 simple_dai->clk_direction = SND_SOC_CLOCK_OUT; in simple_util_parse_clk()
301 if (dai->clk_fixed) { in simple_check_fixed_sysclk()
302 if (*fixed_sysclk && *fixed_sysclk != dai->sysclk) { in simple_check_fixed_sysclk()
304 *fixed_sysclk, dai->sysclk); in simple_check_fixed_sysclk()
305 return -EINVAL; in simple_check_fixed_sysclk()
307 *fixed_sysclk = dai->sysclk; in simple_check_fixed_sysclk()
316 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); in simple_util_startup()
327 ret = simple_check_fixed_sysclk(rtd->dev, dai, &fixed_sysclk); in simple_util_startup()
336 ret = simple_check_fixed_sysclk(rtd->dev, dai, &fixed_sysclk); in simple_util_startup()
341 if (fixed_sysclk && props->mclk_fs) { in simple_util_startup()
342 unsigned int fixed_rate = fixed_sysclk / props->mclk_fs; in simple_util_startup()
344 if (fixed_sysclk % props->mclk_fs) { in simple_util_startup()
345 dev_err(rtd->dev, "fixed sysclk %u not divisible by mclk_fs %u\n", in simple_util_startup()
346 fixed_sysclk, props->mclk_fs); in simple_util_startup()
347 ret = -EINVAL; in simple_util_startup()
350 ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, in simple_util_startup()
378 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); in simple_util_shutdown()
386 if (props->mclk_fs && !dai->clk_fixed && !snd_soc_dai_active(cpu_dai)) in simple_util_shutdown()
387 snd_soc_dai_set_sysclk(cpu_dai, 0, 0, dai->clk_direction); in simple_util_shutdown()
394 if (props->mclk_fs && !dai->clk_fixed && !snd_soc_dai_active(codec_dai)) in simple_util_shutdown()
395 snd_soc_dai_set_sysclk(codec_dai, 0, 0, dai->clk_direction); in simple_util_shutdown()
407 int ret = -EINVAL; in simple_set_clk_rate()
412 if (simple_dai->clk_fixed && rate != simple_dai->sysclk) { in simple_set_clk_rate()
413 dev_err(dev, "dai %s invalid clock rate %lu\n", simple_dai->name, rate); in simple_set_clk_rate()
417 if (!simple_dai->clk) in simple_set_clk_rate()
420 if (clk_get_rate(simple_dai->clk) == rate) in simple_set_clk_rate()
423 ret = clk_set_rate(simple_dai->clk, rate); in simple_set_clk_rate()
437 if (!simple_dai || !simple_dai->tdm_width_map) in simple_set_tdm()
440 slot_width = simple_dai->slot_width; in simple_set_tdm()
441 slot_count = simple_dai->slots; in simple_set_tdm()
446 for (i = 0; i < simple_dai->n_tdm_widths; ++i) { in simple_set_tdm()
447 if (simple_dai->tdm_width_map[i].sample_bits == sample_bits) { in simple_set_tdm()
448 slot_width = simple_dai->tdm_width_map[i].slot_width; in simple_set_tdm()
449 slot_count = simple_dai->tdm_width_map[i].slot_count; in simple_set_tdm()
455 simple_dai->tx_slot_mask, in simple_set_tdm()
456 simple_dai->rx_slot_mask, in simple_set_tdm()
469 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); in simple_util_hw_params()
474 if (props->mclk_fs) in simple_util_hw_params()
475 mclk_fs = props->mclk_fs; in simple_util_hw_params()
500 if (ret && ret != -ENOTSUPP) in simple_util_hw_params()
506 ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction); in simple_util_hw_params()
507 if (ret && ret != -ENOTSUPP) in simple_util_hw_params()
513 ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction); in simple_util_hw_params()
514 if (ret && ret != -ENOTSUPP) in simple_util_hw_params()
541 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); in simple_util_be_hw_params_fixup()
543 struct simple_util_data *data = &dai_props->adata; in simple_util_be_hw_params_fixup()
547 if (data->convert_rate) in simple_util_be_hw_params_fixup()
548 rate->min = in simple_util_be_hw_params_fixup()
549 rate->max = data->convert_rate; in simple_util_be_hw_params_fixup()
551 if (data->convert_channels) in simple_util_be_hw_params_fixup()
552 channels->min = in simple_util_be_hw_params_fixup()
553 channels->max = data->convert_channels; in simple_util_be_hw_params_fixup()
555 if (data->convert_sample_format) in simple_util_be_hw_params_fixup()
570 if (simple_dai->sysclk) { in simple_init_dai()
571 ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, in simple_init_dai()
572 simple_dai->clk_direction); in simple_init_dai()
573 if (ret && ret != -ENOTSUPP) { in simple_init_dai()
574 dev_err(dai->dev, "simple-card: set_sysclk error\n"); in simple_init_dai()
579 if (simple_dai->slots) { in simple_init_dai()
581 simple_dai->tx_slot_mask, in simple_init_dai()
582 simple_dai->rx_slot_mask, in simple_init_dai()
583 simple_dai->slots, in simple_init_dai()
584 simple_dai->slot_width); in simple_init_dai()
585 if (ret && ret != -ENOTSUPP) { in simple_init_dai()
586 dev_err(dai->dev, "simple-card: set_tdm_slot error\n"); in simple_init_dai()
597 return component->driver->endianness; in simple_component_is_codec()
604 struct snd_soc_dai_link *dai_link = rtd->dai_link; in simple_init_for_codec2codec()
611 if (dai_link->c2c_params) in simple_init_for_codec2codec()
615 if (dai_link->no_pcm) in simple_init_for_codec2codec()
632 dev_err(rtd->dev, "simple-card: no valid dai_link params\n"); in simple_init_for_codec2codec()
636 ret = -ENOMEM; in simple_init_for_codec2codec()
637 c2c_params = devm_kzalloc(rtd->dev, sizeof(*c2c_params), GFP_KERNEL); in simple_init_for_codec2codec()
641 c2c_params->formats = hw.formats; in simple_init_for_codec2codec()
642 c2c_params->rates = hw.rates; in simple_init_for_codec2codec()
643 c2c_params->rate_min = hw.rate_min; in simple_init_for_codec2codec()
644 c2c_params->rate_max = hw.rate_max; in simple_init_for_codec2codec()
645 c2c_params->channels_min = hw.channels_min; in simple_init_for_codec2codec()
646 c2c_params->channels_max = hw.channels_max; in simple_init_for_codec2codec()
648 dai_link->c2c_params = c2c_params; in simple_init_for_codec2codec()
649 dai_link->num_c2c_params = 1; in simple_init_for_codec2codec()
658 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); in simple_util_dai_init()
686 * Some CPU might be using soc-generic-dmaengine-pcm. This means CPU and Platform in simple_util_canonicalize_platform()
687 * are different Component, but are sharing same component->dev. in simple_util_canonicalize_platform()
691 * simple-card.c :: simple_count_noml() in simple_util_canonicalize_platform()
693 if (!platforms->of_node) in simple_util_canonicalize_platform()
702 * In soc_bind_dai_link() will check cpu name after in simple_util_canonicalize_cpu()
704 * but, it will never match if name was created by in simple_util_canonicalize_cpu()
711 cpus->dai_name = NULL; in simple_util_canonicalize_cpu()
724 of_node_put(cpu->of_node); in simple_util_clean_reference()
726 of_node_put(codec->of_node); in simple_util_clean_reference()
732 char *prefix) in simple_util_parse_routing() argument
734 struct device_node *node = card->dev->of_node; in simple_util_parse_routing()
737 if (!prefix) in simple_util_parse_routing()
738 prefix = ""; in simple_util_parse_routing()
740 snprintf(prop, sizeof(prop), "%s%s", prefix, "routing"); in simple_util_parse_routing()
750 char *prefix) in simple_util_parse_widgets() argument
752 struct device_node *node = card->dev->of_node; in simple_util_parse_widgets()
755 if (!prefix) in simple_util_parse_widgets()
756 prefix = ""; in simple_util_parse_widgets()
758 snprintf(prop, sizeof(prop), "%s%s", prefix, "widgets"); in simple_util_parse_widgets()
769 char *prefix) in simple_util_parse_pin_switches() argument
773 if (!prefix) in simple_util_parse_pin_switches()
774 prefix = ""; in simple_util_parse_pin_switches()
776 snprintf(prop, sizeof(prop), "%s%s", prefix, "pin-switches"); in simple_util_parse_pin_switches()
784 int is_hp, char *prefix, in simple_util_init_jack() argument
787 struct device *dev = card->dev; in simple_util_init_jack()
795 if (!prefix) in simple_util_init_jack()
796 prefix = ""; in simple_util_init_jack()
799 snprintf(prop, sizeof(prop), "%shp-det", prefix); in simple_util_init_jack()
804 snprintf(prop, sizeof(prop), "%smic-det", prefix); in simple_util_init_jack()
820 sjack->pin.pin = pin_name; in simple_util_init_jack()
821 sjack->pin.mask = mask; in simple_util_init_jack()
823 sjack->gpio.name = gpio_name; in simple_util_init_jack()
824 sjack->gpio.report = mask; in simple_util_init_jack()
825 sjack->gpio.desc = desc; in simple_util_init_jack()
826 sjack->gpio.debounce_time = 150; in simple_util_init_jack()
828 snd_soc_card_jack_new_pins(card, pin_name, mask, &sjack->jack, in simple_util_init_jack()
829 &sjack->pin, 1); in simple_util_init_jack()
831 snd_soc_jack_add_gpios(&sjack->jack, 1, &sjack->gpio); in simple_util_init_jack()
838 int simple_util_init_aux_jacks(struct simple_util_priv *priv, char *prefix) in simple_util_init_aux_jacks() argument
847 if (priv->aux_jacks) in simple_util_init_aux_jacks()
858 priv->aux_jacks = devm_kcalloc(card->dev, num, in simple_util_init_aux_jacks()
860 if (!priv->aux_jacks) in simple_util_init_aux_jacks()
861 return simple_ret(priv, -ENOMEM); in simple_util_init_aux_jacks()
875 jack = &(priv->aux_jacks[found_jack_index++]); in simple_util_init_aux_jacks()
876 snprintf(id, sizeof(id), "%s-jack", component->name); in simple_util_init_aux_jacks()
888 .name = "dummy_util_dais",
903 dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL); in simple_util_init_priv()
904 dai_link = devm_kcalloc(dev, li->link, sizeof(*dai_link), GFP_KERNEL); in simple_util_init_priv()
906 return -ENOMEM; in simple_util_init_priv()
912 for (i = 0; i < li->link; i++) { in simple_util_init_priv()
913 int cc = li->num[i].cpus + li->num[i].codecs; in simple_util_init_priv()
916 dlc_num += cc + li->num[i].platforms; in simple_util_init_priv()
918 if (!li->num[i].cpus) in simple_util_init_priv()
919 cnf_num += li->num[i].codecs; in simple_util_init_priv()
925 return -ENOMEM; in simple_util_init_priv()
930 return -ENOMEM; in simple_util_init_priv()
934 li->link, dai_num, cnf_num); in simple_util_init_priv()
936 priv->dai_props = dai_props; in simple_util_init_priv()
937 priv->dai_link = dai_link; in simple_util_init_priv()
938 priv->dais = dais; in simple_util_init_priv()
939 priv->dlcs = dlcs; in simple_util_init_priv()
940 priv->codec_conf = cconf; in simple_util_init_priv()
942 card->dai_link = priv->dai_link; in simple_util_init_priv()
943 card->num_links = li->link; in simple_util_init_priv()
944 card->codec_conf = cconf; in simple_util_init_priv()
945 card->num_configs = cnf_num; in simple_util_init_priv()
947 for (i = 0; i < li->link; i++) { in simple_util_init_priv()
948 if (li->num[i].cpus) { in simple_util_init_priv()
952 dai_link[i].num_cpus = li->num[i].cpus; in simple_util_init_priv()
955 dlcs += li->num[i].cpus; in simple_util_init_priv()
956 dais += li->num[i].cpus; in simple_util_init_priv()
965 if (li->num[i].codecs) { in simple_util_init_priv()
969 dai_link[i].num_codecs = li->num[i].codecs; in simple_util_init_priv()
972 dlcs += li->num[i].codecs; in simple_util_init_priv()
973 dais += li->num[i].codecs; in simple_util_init_priv()
975 if (!li->num[i].cpus) { in simple_util_init_priv()
978 cconf += li->num[i].codecs; in simple_util_init_priv()
988 if (li->num[i].platforms) { in simple_util_init_priv()
992 dai_link[i].num_platforms = li->num[i].platforms; in simple_util_init_priv()
994 dlcs += li->num[i].platforms; in simple_util_init_priv()
1020 ret = simple_util_init_hp(card, &priv->hp_jack, NULL); in graph_util_card_probe()
1024 ret = simple_util_init_mic(card, &priv->mic_jack, NULL); in graph_util_card_probe()
1059 if (ret != -ENOTSUPP) in graph_get_dai_id()
1083 * Non HDMI sound case, counting port/endpoint on its DT in graph_get_dai_id()
1087 id = -1; in graph_get_dai_id()
1097 return -ENODEV; in graph_get_dai_id()
1122 ret = -ENOMEM; in graph_util_parse_dai()
1123 dlc->of_node = node; in graph_util_parse_dai()
1124 dlc->dai_name = snd_soc_dai_name_get(dai); in graph_util_parse_dai()
1125 dlc->dai_args = snd_soc_copy_dai_args(dev, &args); in graph_util_parse_dai()
1126 if (!dlc->dai_args) in graph_util_parse_dai()
1132 /* Get dai->name */ in graph_util_parse_dai()
1140 * Here, dlc->dai_name is pointer to CPU/Codec DAI name. in graph_util_parse_dai()
1141 * If user unbinded CPU or Codec driver, but not for Sound Card, in graph_util_parse_dai()
1142 * dlc->dai_name is keeping unbinded CPU or Codec in graph_util_parse_dai()
1145 * If user re-bind CPU or Codec driver again, ALSA SoC will try in graph_util_parse_dai()
1147 * above reason, it might can't bind Sound Card. in graph_util_parse_dai()
1148 * Because Sound Card is pointing to released dai_name pointer. in graph_util_parse_dai()
1153 * 2) user need to rebind Sound Card everytime in graph_util_parse_dai()
1174 bool is_playback_only = of_property_read_bool(np, "playback-only"); in graph_util_parse_link_direction()
1175 bool is_capture_only = of_property_read_bool(np, "capture-only"); in graph_util_parse_link_direction()
1229 * #include <dt-bindings/sound/audio-graph.h> in graph_util_parse_trigger_order()
1231 * link-trigger-order = <SND_SOC_TRIGGER_LINK in graph_util_parse_trigger_order()
1236 order = __graph_util_parse_trigger_order(priv, np, "link-trigger-order"); in graph_util_parse_trigger_order()
1242 order = __graph_util_parse_trigger_order(priv, np, "link-trigger-order-start"); in graph_util_parse_trigger_order()
1246 order = __graph_util_parse_trigger_order(priv, np, "link-trigger-order-stop"); in graph_util_parse_trigger_order()