Lines Matching +full:tdm +full:- +full:data +full:- +full:out

1 // SPDX-License-Identifier: GPL-2.0
3 // simple-card-utils.c
17 static void asoc_simple_fixup_sample_fmt(struct asoc_simple_data *data, in asoc_simple_fixup_sample_fmt() argument
35 if (!strcmp(data->convert_sample_format, in asoc_simple_fixup_sample_fmt()
44 void asoc_simple_convert_fixup(struct asoc_simple_data *data, in asoc_simple_convert_fixup() argument
52 if (data->convert_rate) in asoc_simple_convert_fixup()
53 rate->min = in asoc_simple_convert_fixup()
54 rate->max = data->convert_rate; in asoc_simple_convert_fixup()
56 if (data->convert_channels) in asoc_simple_convert_fixup()
57 channels->min = in asoc_simple_convert_fixup()
58 channels->max = data->convert_channels; in asoc_simple_convert_fixup()
60 if (data->convert_sample_format) in asoc_simple_convert_fixup()
61 asoc_simple_fixup_sample_fmt(data, params); in asoc_simple_convert_fixup()
67 struct asoc_simple_data *data) in asoc_simple_parse_convert() argument
75 snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-rate"); in asoc_simple_parse_convert()
76 of_property_read_u32(np, prop, &data->convert_rate); in asoc_simple_parse_convert()
79 snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-channels"); in asoc_simple_parse_convert()
80 of_property_read_u32(np, prop, &data->convert_channels); in asoc_simple_parse_convert()
83 snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-sample-format"); in asoc_simple_parse_convert()
84 of_property_read_string(np, prop, &data->convert_sample_format); in asoc_simple_parse_convert()
89 * asoc_simple_is_convert_required() - Query if HW param conversion was requested
90 * @data: Link data.
93 * any "convert-xxx" properties.
95 bool asoc_simple_is_convert_required(const struct asoc_simple_data *data) in asoc_simple_is_convert_required() argument
97 return data->convert_rate || in asoc_simple_is_convert_required()
98 data->convert_channels || in asoc_simple_is_convert_required()
99 data->convert_sample_format; in asoc_simple_is_convert_required()
118 * No dai-link level and master setting was not found from in asoc_simple_parse_daifmt()
145 if (!of_property_read_bool(np, "dai-tdm-slot-width-map")) in asoc_simple_parse_tdm_width_map()
148 n = of_property_count_elems_of_size(np, "dai-tdm-slot-width-map", sizeof(u32)); in asoc_simple_parse_tdm_width_map()
150 dev_err(dev, "Invalid number of cells for dai-tdm-slot-width-map\n"); in asoc_simple_parse_tdm_width_map()
151 return -EINVAL; in asoc_simple_parse_tdm_width_map()
154 dai->tdm_width_map = devm_kcalloc(dev, n, sizeof(*dai->tdm_width_map), GFP_KERNEL); in asoc_simple_parse_tdm_width_map()
155 if (!dai->tdm_width_map) in asoc_simple_parse_tdm_width_map()
156 return -ENOMEM; in asoc_simple_parse_tdm_width_map()
160 return -ENOMEM; in asoc_simple_parse_tdm_width_map()
162 ret = of_property_read_u32_array(np, "dai-tdm-slot-width-map", array_values, n); in asoc_simple_parse_tdm_width_map()
164 dev_err(dev, "Could not read dai-tdm-slot-width-map: %d\n", ret); in asoc_simple_parse_tdm_width_map()
165 goto out; in asoc_simple_parse_tdm_width_map()
170 dai->tdm_width_map[i].sample_bits = *p++; in asoc_simple_parse_tdm_width_map()
171 dai->tdm_width_map[i].slot_width = *p++; in asoc_simple_parse_tdm_width_map()
172 dai->tdm_width_map[i].slot_count = *p++; in asoc_simple_parse_tdm_width_map()
175 dai->n_tdm_widths = i; in asoc_simple_parse_tdm_width_map()
177 out: in asoc_simple_parse_tdm_width_map()
190 int ret = -ENOMEM; in asoc_simple_set_dailink_name()
199 dai_link->name = name; in asoc_simple_set_dailink_name()
200 dai_link->stream_name = name; in asoc_simple_set_dailink_name()
217 if (ret < 0 || !card->name) { in asoc_simple_parse_card_name()
226 if (!card->name && card->dai_link) in asoc_simple_parse_card_name()
227 card->name = card->dai_link->name; in asoc_simple_parse_card_name()
236 return clk_prepare_enable(dai->clk); in asoc_simple_clk_enable()
244 clk_disable_unprepare(dai->clk); in asoc_simple_clk_disable()
256 * Parse dai->sysclk come from "clocks = <&xxx>" in asoc_simple_parse_clk()
258 * or "system-clock-frequency = <xxx>" in asoc_simple_parse_clk()
262 simple_dai->clk_fixed = of_property_read_bool( in asoc_simple_parse_clk()
263 node, "system-clock-fixed"); in asoc_simple_parse_clk()
265 simple_dai->sysclk = clk_get_rate(clk); in asoc_simple_parse_clk()
267 simple_dai->clk = clk; in asoc_simple_parse_clk()
268 } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { in asoc_simple_parse_clk()
269 simple_dai->sysclk = val; in asoc_simple_parse_clk()
270 simple_dai->clk_fixed = true; in asoc_simple_parse_clk()
272 clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); in asoc_simple_parse_clk()
274 simple_dai->sysclk = clk_get_rate(clk); in asoc_simple_parse_clk()
277 if (of_property_read_bool(node, "system-clock-direction-out")) in asoc_simple_parse_clk()
278 simple_dai->clk_direction = SND_SOC_CLOCK_OUT; in asoc_simple_parse_clk()
288 if (dai->clk_fixed) { in asoc_simple_check_fixed_sysclk()
289 if (*fixed_sysclk && *fixed_sysclk != dai->sysclk) { in asoc_simple_check_fixed_sysclk()
291 *fixed_sysclk, dai->sysclk); in asoc_simple_check_fixed_sysclk()
292 return -EINVAL; in asoc_simple_check_fixed_sysclk()
294 *fixed_sysclk = dai->sysclk; in asoc_simple_check_fixed_sysclk()
303 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); in asoc_simple_startup()
304 struct simple_dai_props *props = simple_priv_to_props(priv, rtd->num); in asoc_simple_startup()
314 ret = asoc_simple_check_fixed_sysclk(rtd->dev, dai, &fixed_sysclk); in asoc_simple_startup()
323 ret = asoc_simple_check_fixed_sysclk(rtd->dev, dai, &fixed_sysclk); in asoc_simple_startup()
328 if (fixed_sysclk && props->mclk_fs) { in asoc_simple_startup()
329 unsigned int fixed_rate = fixed_sysclk / props->mclk_fs; in asoc_simple_startup()
331 if (fixed_sysclk % props->mclk_fs) { in asoc_simple_startup()
332 dev_err(rtd->dev, "fixed sysclk %u not divisible by mclk_fs %u\n", in asoc_simple_startup()
333 fixed_sysclk, props->mclk_fs); in asoc_simple_startup()
334 return -EINVAL; in asoc_simple_startup()
336 ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, in asoc_simple_startup()
363 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); in asoc_simple_shutdown()
364 struct simple_dai_props *props = simple_priv_to_props(priv, rtd->num); in asoc_simple_shutdown()
371 if (props->mclk_fs && !dai->clk_fixed && !snd_soc_dai_active(cpu_dai)) in asoc_simple_shutdown()
380 if (props->mclk_fs && !dai->clk_fixed && !snd_soc_dai_active(codec_dai)) in asoc_simple_shutdown()
396 if (simple_dai->clk_fixed && rate != simple_dai->sysclk) { in asoc_simple_set_clk_rate()
397 dev_err(dev, "dai %s invalid clock rate %lu\n", simple_dai->name, rate); in asoc_simple_set_clk_rate()
398 return -EINVAL; in asoc_simple_set_clk_rate()
401 if (!simple_dai->clk) in asoc_simple_set_clk_rate()
404 if (clk_get_rate(simple_dai->clk) == rate) in asoc_simple_set_clk_rate()
407 return clk_set_rate(simple_dai->clk, rate); in asoc_simple_set_clk_rate()
418 if (!simple_dai || !simple_dai->tdm_width_map) in asoc_simple_set_tdm()
421 slot_width = simple_dai->slot_width; in asoc_simple_set_tdm()
422 slot_count = simple_dai->slots; in asoc_simple_set_tdm()
427 for (i = 0; i < simple_dai->n_tdm_widths; ++i) { in asoc_simple_set_tdm()
428 if (simple_dai->tdm_width_map[i].sample_bits == sample_bits) { in asoc_simple_set_tdm()
429 slot_width = simple_dai->tdm_width_map[i].slot_width; in asoc_simple_set_tdm()
430 slot_count = simple_dai->tdm_width_map[i].slot_count; in asoc_simple_set_tdm()
436 simple_dai->tx_slot_mask, in asoc_simple_set_tdm()
437 simple_dai->rx_slot_mask, in asoc_simple_set_tdm()
440 if (ret && ret != -ENOTSUPP) { in asoc_simple_set_tdm()
441 dev_err(dai->dev, "simple-card: set_tdm_slot error: %d\n", ret); in asoc_simple_set_tdm()
454 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); in asoc_simple_hw_params()
455 struct simple_dai_props *props = simple_priv_to_props(priv, rtd->num); in asoc_simple_hw_params()
459 if (props->mclk_fs) in asoc_simple_hw_params()
460 mclk_fs = props->mclk_fs; in asoc_simple_hw_params()
467 ret = asoc_simple_set_clk_rate(rtd->dev, pdai, mclk); in asoc_simple_hw_params()
473 ret = asoc_simple_set_clk_rate(rtd->dev, pdai, mclk); in asoc_simple_hw_params()
485 if (ret && ret != -ENOTSUPP) in asoc_simple_hw_params()
491 if (ret && ret != -ENOTSUPP) in asoc_simple_hw_params()
497 if (ret && ret != -ENOTSUPP) in asoc_simple_hw_params()
523 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); in asoc_simple_be_hw_params_fixup()
524 struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num); in asoc_simple_be_hw_params_fixup()
526 asoc_simple_convert_fixup(&dai_props->adata, params); in asoc_simple_be_hw_params_fixup()
540 if (simple_dai->sysclk) { in asoc_simple_init_dai()
541 ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, in asoc_simple_init_dai()
542 simple_dai->clk_direction); in asoc_simple_init_dai()
543 if (ret && ret != -ENOTSUPP) { in asoc_simple_init_dai()
544 dev_err(dai->dev, "simple-card: set_sysclk error\n"); in asoc_simple_init_dai()
549 if (simple_dai->slots) { in asoc_simple_init_dai()
551 simple_dai->tx_slot_mask, in asoc_simple_init_dai()
552 simple_dai->rx_slot_mask, in asoc_simple_init_dai()
553 simple_dai->slots, in asoc_simple_init_dai()
554 simple_dai->slot_width); in asoc_simple_init_dai()
555 if (ret && ret != -ENOTSUPP) { in asoc_simple_init_dai()
556 dev_err(dai->dev, "simple-card: set_tdm_slot error\n"); in asoc_simple_init_dai()
566 return component->driver->endianness; in asoc_simple_component_is_codec()
572 struct snd_soc_dai_link *dai_link = rtd->dai_link; in asoc_simple_init_for_codec2codec()
579 if (dai_link->params) in asoc_simple_init_for_codec2codec()
583 if (dai_link->no_pcm) in asoc_simple_init_for_codec2codec()
600 dev_err(rtd->dev, "simple-card: no valid dai_link params\n"); in asoc_simple_init_for_codec2codec()
604 params = devm_kzalloc(rtd->dev, sizeof(*params), GFP_KERNEL); in asoc_simple_init_for_codec2codec()
606 return -ENOMEM; in asoc_simple_init_for_codec2codec()
608 params->formats = hw.formats; in asoc_simple_init_for_codec2codec()
609 params->rates = hw.rates; in asoc_simple_init_for_codec2codec()
610 params->rate_min = hw.rate_min; in asoc_simple_init_for_codec2codec()
611 params->rate_max = hw.rate_max; in asoc_simple_init_for_codec2codec()
612 params->channels_min = hw.channels_min; in asoc_simple_init_for_codec2codec()
613 params->channels_max = hw.channels_max; in asoc_simple_init_for_codec2codec()
615 dai_link->params = params; in asoc_simple_init_for_codec2codec()
616 dai_link->num_params = 1; in asoc_simple_init_for_codec2codec()
623 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); in asoc_simple_dai_init()
624 struct simple_dai_props *props = simple_priv_to_props(priv, rtd->num); in asoc_simple_dai_init()
651 if (!platforms->of_node) in asoc_simple_canonicalize_platform()
652 platforms->of_node = cpus->of_node; in asoc_simple_canonicalize_platform()
669 cpus->dai_name = NULL; in asoc_simple_canonicalize_cpu()
682 of_node_put(cpu->of_node); in asoc_simple_clean_reference()
684 of_node_put(codec->of_node); in asoc_simple_clean_reference()
692 struct device_node *node = card->dev->of_node; in asoc_simple_parse_routing()
710 struct device_node *node = card->dev->of_node; in asoc_simple_parse_widgets()
734 snprintf(prop, sizeof(prop), "%s%s", prefix, "pin-switches"); in asoc_simple_parse_pin_switches()
745 struct device *dev = card->dev; in asoc_simple_init_jack()
756 sjack->gpio.gpio = -ENOENT; in asoc_simple_init_jack()
759 snprintf(prop, sizeof(prop), "%shp-det", prefix); in asoc_simple_init_jack()
764 snprintf(prop, sizeof(prop), "%smic-det", prefix); in asoc_simple_init_jack()
780 sjack->pin.pin = pin_name; in asoc_simple_init_jack()
781 sjack->pin.mask = mask; in asoc_simple_init_jack()
783 sjack->gpio.name = gpio_name; in asoc_simple_init_jack()
784 sjack->gpio.report = mask; in asoc_simple_init_jack()
785 sjack->gpio.desc = desc; in asoc_simple_init_jack()
786 sjack->gpio.debounce_time = 150; in asoc_simple_init_jack()
788 snd_soc_card_jack_new_pins(card, pin_name, mask, &sjack->jack, in asoc_simple_init_jack()
789 &sjack->pin, 1); in asoc_simple_init_jack()
791 snd_soc_jack_add_gpios(&sjack->jack, 1, &sjack->gpio); in asoc_simple_init_jack()
810 dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL); in asoc_simple_init_priv()
811 dai_link = devm_kcalloc(dev, li->link, sizeof(*dai_link), GFP_KERNEL); in asoc_simple_init_priv()
813 return -ENOMEM; in asoc_simple_init_priv()
819 for (i = 0; i < li->link; i++) { in asoc_simple_init_priv()
820 int cc = li->num[i].cpus + li->num[i].codecs; in asoc_simple_init_priv()
823 dlc_num += cc + li->num[i].platforms; in asoc_simple_init_priv()
825 if (!li->num[i].cpus) in asoc_simple_init_priv()
826 cnf_num += li->num[i].codecs; in asoc_simple_init_priv()
832 return -ENOMEM; in asoc_simple_init_priv()
837 return -ENOMEM; in asoc_simple_init_priv()
841 li->link, dai_num, cnf_num); in asoc_simple_init_priv()
844 priv->dummy.of_node = NULL; in asoc_simple_init_priv()
845 priv->dummy.dai_name = "snd-soc-dummy-dai"; in asoc_simple_init_priv()
846 priv->dummy.name = "snd-soc-dummy"; in asoc_simple_init_priv()
848 priv->dai_props = dai_props; in asoc_simple_init_priv()
849 priv->dai_link = dai_link; in asoc_simple_init_priv()
850 priv->dais = dais; in asoc_simple_init_priv()
851 priv->dlcs = dlcs; in asoc_simple_init_priv()
852 priv->codec_conf = cconf; in asoc_simple_init_priv()
854 card->dai_link = priv->dai_link; in asoc_simple_init_priv()
855 card->num_links = li->link; in asoc_simple_init_priv()
856 card->codec_conf = cconf; in asoc_simple_init_priv()
857 card->num_configs = cnf_num; in asoc_simple_init_priv()
859 for (i = 0; i < li->link; i++) { in asoc_simple_init_priv()
860 if (li->num[i].cpus) { in asoc_simple_init_priv()
865 dai_link[i].num_cpus = li->num[i].cpus; in asoc_simple_init_priv()
868 dlcs += li->num[i].cpus; in asoc_simple_init_priv()
869 dais += li->num[i].cpus; in asoc_simple_init_priv()
873 dai_link[i].cpus = &priv->dummy; in asoc_simple_init_priv()
878 if (li->num[i].codecs) { in asoc_simple_init_priv()
883 dai_link[i].num_codecs = li->num[i].codecs; in asoc_simple_init_priv()
886 dlcs += li->num[i].codecs; in asoc_simple_init_priv()
887 dais += li->num[i].codecs; in asoc_simple_init_priv()
889 if (!li->num[i].cpus) { in asoc_simple_init_priv()
892 cconf += li->num[i].codecs; in asoc_simple_init_priv()
897 dai_link[i].codecs = &priv->dummy; in asoc_simple_init_priv()
902 if (li->num[i].platforms) { in asoc_simple_init_priv()
907 dai_link[i].num_platforms = li->num[i].platforms; in asoc_simple_init_priv()
909 dlcs += li->num[i].platforms; in asoc_simple_init_priv()
938 ret = asoc_simple_init_hp(card, &priv->hp_jack, NULL); in asoc_graph_card_probe()
942 ret = asoc_simple_init_mic(card, &priv->mic_jack, NULL); in asoc_graph_card_probe()