Lines Matching +full:be +full:- +full:dai +full:- +full:link

1 // SPDX-License-Identifier: GPL-2.0+
3 // soc-core.c -- ALSA SoC Audio Layer
11 // with code, comments and ideas from :-
39 #include <sound/soc-dpcm.h>
40 #include <sound/soc-topology.h>
41 #include <sound/soc-link.h>
63 * It can be used to eliminate pops between different playback streams, e.g.
75 return sysfs_emit(buf, "%ld\n", rtd->pmdown_time); in pmdown_time_show()
85 ret = kstrtol(buf, 10, &rtd->pmdown_time); in pmdown_time_store()
109 return attr->mode; /* always visible */ in soc_dev_attr_is_visible()
110 return rtd->dai_link->num_codecs ? attr->mode : 0; /* enabled only with codec */ in soc_dev_attr_is_visible()
135 if (!component->card->debugfs_card_root) in soc_init_component_debugfs()
138 if (component->debugfs_prefix) { in soc_init_component_debugfs()
142 component->debugfs_prefix, component->name); in soc_init_component_debugfs()
144 component->debugfs_root = debugfs_create_dir(name, in soc_init_component_debugfs()
145 component->card->debugfs_card_root); in soc_init_component_debugfs()
149 component->debugfs_root = debugfs_create_dir(component->name, in soc_init_component_debugfs()
150 component->card->debugfs_card_root); in soc_init_component_debugfs()
154 component->debugfs_root); in soc_init_component_debugfs()
159 if (!component->debugfs_root) in soc_cleanup_component_debugfs()
161 debugfs_remove_recursive(component->debugfs_root); in soc_cleanup_component_debugfs()
162 component->debugfs_root = NULL; in soc_cleanup_component_debugfs()
168 struct snd_soc_dai *dai; in dai_list_show() local
173 for_each_component_dais(component, dai) in dai_list_show()
174 seq_printf(m, "%s\n", dai->name); in dai_list_show()
189 seq_printf(m, "%s\n", component->name); in component_list_show()
199 card->debugfs_card_root = debugfs_create_dir(card->name, in soc_init_card_debugfs()
202 debugfs_create_u32("dapm_pop_time", 0644, card->debugfs_card_root, in soc_init_card_debugfs()
203 &card->pop_time); in soc_init_card_debugfs()
205 snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root); in soc_init_card_debugfs()
210 debugfs_remove_recursive(card->debugfs_card_root); in soc_cleanup_card_debugfs()
211 card->debugfs_card_root = NULL; in soc_cleanup_card_debugfs()
247 if (args1->np != args2->np) in snd_soc_is_match_dai_args()
250 for (int i = 0; i < args1->args_count; i++) in snd_soc_is_match_dai_args()
251 if (args1->args[i] != args2->args[i]) in snd_soc_is_match_dai_args()
259 return !(dlc->dai_args || dlc->name || dlc->of_node); in snd_soc_dlc_component_is_empty()
264 return (dlc->name && dlc->of_node); in snd_soc_dlc_component_is_invalid()
269 return !(dlc->dai_args || dlc->dai_name); in snd_soc_dlc_dai_is_empty()
273 struct snd_soc_dai *dai) in snd_soc_is_matching_dai() argument
278 if (dlc->dai_args) in snd_soc_is_matching_dai()
279 return snd_soc_is_match_dai_args(dai->driver->dai_args, dlc->dai_args); in snd_soc_is_matching_dai()
281 if (!dlc->dai_name) in snd_soc_is_matching_dai()
286 if (dai->driver->name && in snd_soc_is_matching_dai()
287 strcmp(dlc->dai_name, dai->driver->name) == 0) in snd_soc_is_matching_dai()
290 if (strcmp(dlc->dai_name, dai->name) == 0) in snd_soc_is_matching_dai()
293 if (dai->component->name && in snd_soc_is_matching_dai()
294 strcmp(dlc->dai_name, dai->component->name) == 0) in snd_soc_is_matching_dai()
300 const char *snd_soc_dai_name_get(const struct snd_soc_dai *dai) in snd_soc_dai_name_get() argument
303 if (dai->driver->name) in snd_soc_dai_name_get()
304 return dai->driver->name; in snd_soc_dai_name_get()
306 if (dai->name) in snd_soc_dai_name_get()
307 return dai->name; in snd_soc_dai_name_get()
309 if (dai->component->name) in snd_soc_dai_name_get()
310 return dai->component->name; in snd_soc_dai_name_get()
329 rtd->num_components++; // increment flex array count at first in snd_soc_rtd_add_component()
330 rtd->components[rtd->num_components - 1] = component; in snd_soc_rtd_add_component()
353 const char *component_name = component->driver->name; in snd_soc_rtdcom_lookup()
375 if ((dev == component->dev) && in snd_soc_lookup_component_nolocked()
377 (driver_name == component->driver->name) || in snd_soc_lookup_component_nolocked()
378 (strcmp(component->driver->name, driver_name) == 0))) { in snd_soc_lookup_component_nolocked()
408 if (rtd->dai_link == dai_link) in snd_soc_get_pcm_runtime()
411 dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link->name); in snd_soc_get_pcm_runtime()
428 dev_dbg(rtd->dev, in snd_soc_close_delayed_work()
430 codec_dai->driver->playback.stream_name, in snd_soc_close_delayed_work()
433 rtd->pop_wait ? "yes" : "no"); in snd_soc_close_delayed_work()
435 /* are we waiting on this codec DAI stream */ in snd_soc_close_delayed_work()
436 if (rtd->pop_wait == 1) { in snd_soc_close_delayed_work()
437 rtd->pop_wait = 0; in snd_soc_close_delayed_work()
448 /* "dev" means "rtd->dev" */ in soc_release_rtd_dev()
457 list_del(&rtd->list); in soc_free_pcm_runtime()
459 if (delayed_work_pending(&rtd->delayed_work)) in soc_free_pcm_runtime()
460 flush_delayed_work(&rtd->delayed_work); in soc_free_pcm_runtime()
464 * we don't need to call kfree() for rtd->dev in soc_free_pcm_runtime()
468 * We don't need rtd->dev NULL check, because in soc_free_pcm_runtime()
474 * because it was created from dev (= rtd->dev) in soc_free_pcm_runtime()
479 * rtd->dev = dev in soc_free_pcm_runtime()
481 device_unregister(rtd->dev); in soc_free_pcm_runtime()
489 if (rtd->close_delayed_work_func) in close_delayed_work()
490 rtd->close_delayed_work_func(rtd); in close_delayed_work()
502 * for rtd->dev in soc_new_pcm_runtime()
508 dev->parent = card->dev; in soc_new_pcm_runtime()
509 dev->release = soc_release_rtd_dev; in soc_new_pcm_runtime()
511 dev_set_name(dev, "%s", dai_link->name); in soc_new_pcm_runtime()
524 dai_link->num_cpus + in soc_new_pcm_runtime()
525 dai_link->num_codecs + in soc_new_pcm_runtime()
526 dai_link->num_platforms), in soc_new_pcm_runtime()
533 rtd->dev = dev; in soc_new_pcm_runtime()
534 INIT_LIST_HEAD(&rtd->list); in soc_new_pcm_runtime()
536 INIT_LIST_HEAD(&rtd->dpcm[stream].be_clients); in soc_new_pcm_runtime()
537 INIT_LIST_HEAD(&rtd->dpcm[stream].fe_clients); in soc_new_pcm_runtime()
540 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); in soc_new_pcm_runtime()
543 * for rtd->dais in soc_new_pcm_runtime()
545 rtd->dais = devm_kcalloc(dev, dai_link->num_cpus + dai_link->num_codecs, in soc_new_pcm_runtime()
548 if (!rtd->dais) in soc_new_pcm_runtime()
554 * |--- num_cpus ---|--- num_codecs --| in soc_new_pcm_runtime()
559 rtd->card = card; in soc_new_pcm_runtime()
560 rtd->dai_link = dai_link; in soc_new_pcm_runtime()
561 rtd->id = card->num_rtd++; in soc_new_pcm_runtime()
562 rtd->pmdown_time = pmdown_time; /* default power off timeout */ in soc_new_pcm_runtime()
565 list_add_tail(&rtd->list, &card->rtd_list); in soc_new_pcm_runtime()
585 * Fill it as dummy DAI in case of CPU/Codec here. in snd_soc_fill_dummy_dai()
589 if (dai_link->num_cpus == 0 && dai_link->cpus) { in snd_soc_fill_dummy_dai()
590 dai_link->num_cpus = 1; in snd_soc_fill_dummy_dai()
591 dai_link->cpus = &snd_soc_dummy_dlc; in snd_soc_fill_dummy_dai()
593 if (dai_link->num_codecs == 0 && dai_link->codecs) { in snd_soc_fill_dummy_dai()
594 dai_link->num_codecs = 1; in snd_soc_fill_dummy_dai()
595 dai_link->codecs = &snd_soc_dummy_dlc; in snd_soc_fill_dummy_dai()
605 flush_delayed_work(&rtd->delayed_work); in snd_soc_flush_all_delayed_work()
612 struct snd_soc_dai *dai; in soc_playback_digital_mute() local
618 if (rtd->dai_link->ignore_suspend) in soc_playback_digital_mute()
621 for_each_rtd_dais(rtd, i, dai) { in soc_playback_digital_mute()
622 if (snd_soc_dai_stream_active(dai, playback)) in soc_playback_digital_mute()
623 snd_soc_dai_digital_mute(dai, mute, playback); in soc_playback_digital_mute()
635 if (rtd->dai_link->ignore_suspend) in soc_dapm_suspend_resume()
657 * suspend before that's finished - wait for it to complete. in snd_soc_suspend()
659 snd_power_wait(card->snd_card); in snd_soc_suspend()
662 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot); in snd_soc_suspend()
669 if (rtd->dai_link->ignore_suspend) in snd_soc_suspend()
672 snd_pcm_suspend_all(rtd->pcm); in snd_soc_suspend()
684 snd_soc_dapm_sync(&card->dapm); in snd_soc_suspend()
689 if (rtd->dai_link->ignore_suspend) in snd_soc_suspend()
703 * If there are paths active then the COMPONENT will be in snd_soc_suspend()
704 * held with bias _ON and should not be suspended. in snd_soc_suspend()
714 if (dapm->idle_bias_off) { in snd_soc_suspend()
715 dev_dbg(component->dev, in snd_soc_suspend()
723 if (component->regmap) in snd_soc_suspend()
724 regcache_mark_dirty(component->regmap); in snd_soc_suspend()
726 pinctrl_pm_select_sleep_state(component->dev); in snd_soc_suspend()
729 dev_dbg(component->dev, in snd_soc_suspend()
744 * setting our codec back up, which can be very slow on I2C
758 dev_dbg(card->dev, "ASoC: starting resume work\n"); in soc_resume_deferred()
761 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2); in soc_resume_deferred()
777 dev_dbg(card->dev, "ASoC: resume work completed\n"); in soc_resume_deferred()
781 snd_soc_dapm_sync(&card->dapm); in soc_resume_deferred()
784 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); in soc_resume_deferred()
800 pinctrl_pm_select_default_state(component->dev); in snd_soc_resume()
803 if (!schedule_work(&card->deferred_resume_work)) in snd_soc_resume()
804 dev_err(dev, "ASoC: resume work item may be lost\n"); in snd_soc_resume()
813 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); in soc_resume_init()
826 of_node = component->dev->of_node; in soc_component_to_node()
827 if (!of_node && component->dev->parent) in soc_component_to_node()
828 of_node = component->dev->parent->of_node; in soc_component_to_node()
856 if (dlc->dai_args) { in snd_soc_is_matching_component()
857 struct snd_soc_dai *dai; in snd_soc_is_matching_component() local
859 for_each_component_dais(component, dai) in snd_soc_is_matching_component()
860 if (snd_soc_is_matching_dai(dlc, dai)) in snd_soc_is_matching_component()
867 if (dlc->of_node && component_of_node != dlc->of_node) in snd_soc_is_matching_component()
869 if (dlc->name && strcmp(component->name, dlc->name)) in snd_soc_is_matching_component()
898 * snd_soc_find_dai - Find a registered DAI
900 * @dlc: name of the DAI or the DAI driver and optional component info to match
903 * find the DAI of the same name. The component's of_node and name
906 * Return: pointer of DAI, or NULL if not found.
912 struct snd_soc_dai *dai; in snd_soc_find_dai() local
916 /* Find CPU DAI from registered DAIs */ in snd_soc_find_dai()
919 for_each_component_dais(component, dai) in snd_soc_find_dai()
920 if (snd_soc_is_matching_dai(dlc, dai)) in snd_soc_find_dai()
921 return dai; in snd_soc_find_dai()
930 struct snd_soc_dai *dai; in snd_soc_find_dai_with_mutex() local
933 dai = snd_soc_find_dai(dlc); in snd_soc_find_dai_with_mutex()
936 return dai; in snd_soc_find_dai_with_mutex()
941 struct snd_soc_dai_link *link) in soc_dai_link_sanity_check() argument
947 for_each_link_codecs(link, i, dlc) { in soc_dai_link_sanity_check()
949 * Codec must be specified by 1 of name or OF node, in soc_dai_link_sanity_check()
958 /* Codec DAI name must be specified */ in soc_dai_link_sanity_check()
971 for_each_link_platforms(link, i, dlc) { in soc_dai_link_sanity_check()
973 * Platform may be specified by either name or OF node, but it in soc_dai_link_sanity_check()
974 * can be left unspecified, then no components will be inserted in soc_dai_link_sanity_check()
992 for_each_link_cpus(link, i, dlc) { in soc_dai_link_sanity_check()
994 * CPU device may be specified by either name or OF node, but in soc_dai_link_sanity_check()
995 * can be left unspecified, and will be matched based on DAI in soc_dai_link_sanity_check()
1004 * At least one of CPU DAI name or CPU device name/node must be specified in soc_dai_link_sanity_check()
1020 dev_err(card->dev, "ASoC: Both Component name/of_node are set for %s\n", link->name); in soc_dai_link_sanity_check()
1021 return -EINVAL; in soc_dai_link_sanity_check()
1024 dev_err(card->dev, "ASoC: Neither Component name/of_node are set for %s\n", link->name); in soc_dai_link_sanity_check()
1025 return -EINVAL; in soc_dai_link_sanity_check()
1028 dev_dbg(card->dev, "ASoC: Component %s not found for link %s\n", dlc->name, link->name); in soc_dai_link_sanity_check()
1029 return -EPROBE_DEFER; in soc_dai_link_sanity_check()
1032 dev_err(card->dev, "ASoC: DAI name is not set for %s\n", link->name); in soc_dai_link_sanity_check()
1033 return -EINVAL; in soc_dai_link_sanity_check()
1036 dev_err(card->dev, "ASoC: Neither DAI/Component name/of_node are set for %s\n", link->name); in soc_dai_link_sanity_check()
1037 return -EINVAL; in soc_dai_link_sanity_check()
1078 * dai_link->ch_maps indicates how CPU/Codec are connected. in snd_soc_compensate_channel_connection_map()
1079 * It will be a map seen from a larger number of DAI. in snd_soc_compensate_channel_connection_map()
1081 * soc.h :: [dai_link->ch_maps Image sample] in snd_soc_compensate_channel_connection_map()
1085 if (dai_link->num_cpus > 1 && dai_link->num_codecs > 1 && in snd_soc_compensate_channel_connection_map()
1086 dai_link->num_cpus != dai_link->num_codecs && !dai_link->ch_maps) { in snd_soc_compensate_channel_connection_map()
1087 dev_err(card->dev, "need to have ch_maps when N:M connection (%s)", in snd_soc_compensate_channel_connection_map()
1088 dai_link->name); in snd_soc_compensate_channel_connection_map()
1089 return -EINVAL; in snd_soc_compensate_channel_connection_map()
1093 if (dai_link->ch_maps) in snd_soc_compensate_channel_connection_map()
1097 if (dai_link->num_cpus > MAX_DEFAULT_CH_MAP_SIZE || in snd_soc_compensate_channel_connection_map()
1098 dai_link->num_codecs > MAX_DEFAULT_CH_MAP_SIZE) { in snd_soc_compensate_channel_connection_map()
1099 dev_err(card->dev, "soc-core.c needs update default_connection_maps"); in snd_soc_compensate_channel_connection_map()
1100 return -EINVAL; in snd_soc_compensate_channel_connection_map()
1104 if (dai_link->num_cpus == dai_link->num_codecs) in snd_soc_compensate_channel_connection_map()
1105 dai_link->ch_maps = default_ch_map_sync; /* for 1:1 or N:N */ in snd_soc_compensate_channel_connection_map()
1106 else if (dai_link->num_cpus < dai_link->num_codecs) in snd_soc_compensate_channel_connection_map()
1107 dai_link->ch_maps = default_ch_map_1cpu; /* for 1:N */ in snd_soc_compensate_channel_connection_map()
1109 dai_link->ch_maps = default_ch_map_1codec; /* for N:1 */ in snd_soc_compensate_channel_connection_map()
1112 dev_dbg(card->dev, "dai_link %s\n", dai_link->stream_name); in snd_soc_compensate_channel_connection_map()
1114 if ((ch_maps->cpu >= dai_link->num_cpus) || in snd_soc_compensate_channel_connection_map()
1115 (ch_maps->codec >= dai_link->num_codecs)) { in snd_soc_compensate_channel_connection_map()
1116 dev_err(card->dev, in snd_soc_compensate_channel_connection_map()
1117 "unexpected dai_link->ch_maps[%d] index (cpu(%d/%d) codec(%d/%d))", in snd_soc_compensate_channel_connection_map()
1119 ch_maps->cpu, dai_link->num_cpus, in snd_soc_compensate_channel_connection_map()
1120 ch_maps->codec, dai_link->num_codecs); in snd_soc_compensate_channel_connection_map()
1121 return -EINVAL; in snd_soc_compensate_channel_connection_map()
1124 dev_dbg(card->dev, " [%d] cpu%d <-> codec%d\n", in snd_soc_compensate_channel_connection_map()
1125 i, ch_maps->cpu, ch_maps->codec); in snd_soc_compensate_channel_connection_map()
1132 * snd_soc_remove_pcm_runtime - Remove a pcm_runtime from card
1146 snd_soc_card_remove_dai_link(card, rtd->dai_link); in snd_soc_remove_pcm_runtime()
1153 * snd_soc_add_pcm_runtime - Add a pcm_runtime dynamically via dai_link
1155 * @dai_link: The DAI link to find pcm_runtime
1161 * DAI links in dai_link array.
1180 if (dai_link->ignore) in snd_soc_add_pcm_runtime()
1183 dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name); in snd_soc_add_pcm_runtime()
1191 return -ENOMEM; in snd_soc_add_pcm_runtime()
1196 dev_info(card->dev, "ASoC: CPU DAI %s not registered\n", in snd_soc_add_pcm_runtime()
1197 cpu->dai_name); in snd_soc_add_pcm_runtime()
1200 snd_soc_rtd_add_component(rtd, snd_soc_rtd_to_cpu(rtd, i)->component); in snd_soc_add_pcm_runtime()
1207 dev_info(card->dev, "ASoC: CODEC DAI %s not registered\n", in snd_soc_add_pcm_runtime()
1208 codec->dai_name); in snd_soc_add_pcm_runtime()
1212 snd_soc_rtd_add_component(rtd, snd_soc_rtd_to_codec(rtd, i)->component); in snd_soc_add_pcm_runtime()
1221 if (snd_soc_component_is_dummy(component) && component->num_dai) in snd_soc_add_pcm_runtime()
1229 * Most drivers will register their PCMs using DAI link ordering but in snd_soc_add_pcm_runtime()
1230 * topology based drivers can use the DAI link id field to set PCM in snd_soc_add_pcm_runtime()
1235 * This should be implemented by using "dai_link" feature instead of in snd_soc_add_pcm_runtime()
1238 id = rtd->id; in snd_soc_add_pcm_runtime()
1240 if (!component->driver->use_dai_pcm_id) in snd_soc_add_pcm_runtime()
1243 if (rtd->dai_link->no_pcm) in snd_soc_add_pcm_runtime()
1244 id += component->driver->be_pcm_base; in snd_soc_add_pcm_runtime()
1246 id = rtd->dai_link->id; in snd_soc_add_pcm_runtime()
1248 rtd->id = id; in snd_soc_add_pcm_runtime()
1254 return -EPROBE_DEFER; in snd_soc_add_pcm_runtime()
1279 struct snd_soc_dai_link *dai_link = rtd->dai_link; in snd_soc_runtime_get_dai_fmt()
1280 struct snd_soc_dai *dai, *not_used; in snd_soc_runtime_get_dai_fmt() local
1302 * "until" will be 3 in this case (MAX array size from DAI0 and DAI1) in snd_soc_runtime_get_dai_fmt()
1325 for_each_rtd_dais(rtd, i, dai) { in snd_soc_runtime_get_dai_fmt()
1328 pri = (j >= i) ? priority : priority - 1; in snd_soc_runtime_get_dai_fmt()
1329 fmt = snd_soc_dai_get_fmt(dai, pri); in snd_soc_runtime_get_dai_fmt()
1348 * these value, and will be overwrite to auto selected value. in snd_soc_runtime_get_dai_fmt()
1351 * Small number of SND_SOC_POSSIBLE_xxx will be Hi priority. in snd_soc_runtime_get_dai_fmt()
1355 for (i = 63; i >= 0; i--) { in snd_soc_runtime_get_dai_fmt()
1414 * In such case, user want to auto-select non-limitation part, in snd_soc_runtime_get_dai_fmt()
1417 * Or for example, if both CPU and Codec can be clock provider, in snd_soc_runtime_get_dai_fmt()
1422 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK)) in snd_soc_runtime_get_dai_fmt()
1424 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_CLOCK_MASK)) in snd_soc_runtime_get_dai_fmt()
1426 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_INV_MASK)) in snd_soc_runtime_get_dai_fmt()
1428 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK)) in snd_soc_runtime_get_dai_fmt()
1431 dai_link->dai_fmt |= (dai_fmt & mask); in snd_soc_runtime_get_dai_fmt()
1435 * snd_soc_runtime_set_dai_fmt() - Change DAI link format for a ASoC runtime
1436 * @rtd: The runtime for which the DAI link format should be changed
1437 * @dai_fmt: The new DAI link format
1439 * This function updates the DAI link format for all DAIs connected to the DAI
1440 * link for the specified runtime.
1460 if (ret != 0 && ret != -ENOTSUPP) in snd_soc_runtime_set_dai_fmt()
1464 /* Flip the polarity for the "CPU" end of link */ in snd_soc_runtime_set_dai_fmt()
1469 if (ret != 0 && ret != -ENOTSUPP) in snd_soc_runtime_set_dai_fmt()
1480 struct snd_soc_dai_link *dai_link = rtd->dai_link; in soc_init_pcm_runtime()
1490 ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt); in soc_init_pcm_runtime()
1499 if (ret != -ENOTSUPP) in soc_init_pcm_runtime()
1505 dev_err(card->dev, "ASoC: can't create pcm %s :%d\n", in soc_init_pcm_runtime()
1506 dai_link->stream_name, ret); in soc_init_pcm_runtime()
1514 rtd->initialized = true; in soc_init_pcm_runtime()
1529 for (i = 0; i < card->num_configs; i++) { in soc_set_name_prefix()
1530 struct snd_soc_codec_conf *map = &card->codec_conf[i]; in soc_set_name_prefix()
1532 if (snd_soc_is_matching_component(&map->dlc, component) && in soc_set_name_prefix()
1533 map->name_prefix) { in soc_set_name_prefix()
1534 component->name_prefix = map->name_prefix; in soc_set_name_prefix()
1543 ret = of_property_read_string(of_node, "sound-name-prefix", &str); in soc_set_name_prefix()
1547 component->name_prefix = str; in soc_set_name_prefix()
1554 if (!component->card) in soc_remove_component()
1560 list_del_init(&component->card_list); in soc_remove_component()
1563 component->card = NULL; in soc_remove_component()
1572 struct snd_soc_dai *dai; in soc_probe_component() local
1579 if (component->card) { in soc_probe_component()
1580 if (component->card != card) { in soc_probe_component()
1581 dev_err(component->dev, in soc_probe_component()
1583 component->name, card->name, component->card->name); in soc_probe_component()
1584 return -ENODEV; in soc_probe_component()
1593 component->card = card; in soc_probe_component()
1601 component->driver->dapm_widgets, in soc_probe_component()
1602 component->driver->num_dapm_widgets); in soc_probe_component()
1605 dev_err(component->dev, in soc_probe_component()
1610 for_each_component_dais(component, dai) { in soc_probe_component()
1611 ret = snd_soc_dapm_new_dai_widgets(dapm, dai); in soc_probe_component()
1613 dev_err(component->dev, in soc_probe_component()
1614 "Failed to create DAI widgets %d\n", ret); in soc_probe_component()
1623 WARN(dapm->idle_bias_off && in soc_probe_component()
1624 dapm->bias_level != SND_SOC_BIAS_OFF, in soc_probe_component()
1625 "codec %s can not start from non-off bias with idle_bias_off==1\n", in soc_probe_component()
1626 component->name); in soc_probe_component()
1639 component->driver->controls, in soc_probe_component()
1640 component->driver->num_controls); in soc_probe_component()
1645 component->driver->dapm_routes, in soc_probe_component()
1646 component->driver->num_dapm_routes); in soc_probe_component()
1648 if (card->disable_route_checks) { in soc_probe_component()
1649 dev_info(card->dev, in soc_probe_component()
1653 dev_err(card->dev, in soc_probe_component()
1661 list_add(&component->card_list, &card->component_dev_list); in soc_probe_component()
1709 if (component->driver->remove_order != order) in soc_remove_link_components()
1727 if (component->driver->probe_order != order) in soc_probe_link_components()
1747 list_del(&component->card_aux_list); in soc_unbind_aux_dev()
1759 component = soc_find_component(&aux->dlc); in soc_bind_aux_dev()
1761 return -EPROBE_DEFER; in soc_bind_aux_dev()
1766 list_add(&component->card_aux_list, &card->aux_comp_list); in soc_bind_aux_dev()
1779 if (component->driver->probe_order != order) in soc_probe_aux_devices()
1798 if (comp->driver->remove_order == order) in soc_remove_aux_devices()
1807 * "Type2 - Board Manufacturer" or "Type1 - TBD by OEM"), it will be taken
1811 "To be filled by OEM",
1821 * Trim special characters, and replace '-' with '_' since '-' is used to
1833 else if (name[i] == '-') in cleanup_dmi_name()
1858 * Append a string to card->dmi_longname with character cleanups.
1862 char *dst = card->dmi_longname; in append_dmi_string()
1863 size_t dst_len = sizeof(card->dmi_longname); in append_dmi_string()
1867 snprintf(dst + len, dst_len - len, "-%s", str); in append_dmi_string()
1869 len++; /* skip the separator "-" */ in append_dmi_string()
1875 * snd_soc_set_dmi_name() - Register DMI names to card
1879 * An Intel machine driver may be used by many different devices but are
1883 * device-specific configurations, this function allows DMI info to be used
1885 * "vendor-product-version-board"
1886 * (Character '-' is used to separate different DMI fields here).
1887 * This will help the user space to load the device-specific Use Case Manager
1890 * Possible card long names may be:
1891 * DellInc.-XPS139343-01-0310JH
1892 * ASUSTeKCOMPUTERINC.-T100TA-1.0-T100TA
1893 * Circuitco-MinnowboardMaxD0PLATFORM-D0-MinnowBoardMAX
1896 * the extra differentiation, like "vendor-product-version-board-flavor".
1909 if (card->long_name) in snd_soc_set_dmi_name()
1915 /* make up dmi long name as: vendor-product-version-board */ in snd_soc_set_dmi_name()
1918 dev_warn(card->dev, "ASoC: no DMI vendor name!\n"); in snd_soc_set_dmi_name()
1922 snprintf(card->dmi_longname, sizeof(card->dmi_longname), "%s", vendor); in snd_soc_set_dmi_name()
1923 cleanup_dmi_name(card->dmi_longname); in snd_soc_set_dmi_name()
1932 * some vendors like Lenovo may only put a self-explanatory in snd_soc_set_dmi_name()
1945 dev_warn(card->dev, "ASoC: no DMI board/product name!\n"); in snd_soc_set_dmi_name()
1954 card->long_name = card->dmi_longname; in snd_soc_set_dmi_name()
1971 if (!component->driver->ignore_machine) in soc_check_tplg_fes()
1975 if (!strcmp(component->driver->ignore_machine, in soc_check_tplg_fes()
1976 card->dev->driver->name)) in soc_check_tplg_fes()
1978 if (strcmp(component->driver->ignore_machine, in soc_check_tplg_fes()
1979 dev_name(card->dev))) in soc_check_tplg_fes()
1986 if (dai_link->dynamic) { in soc_check_tplg_fes()
1987 dai_link->ignore = true; in soc_check_tplg_fes()
1991 dev_dbg(card->dev, "info: override BE DAI link %s\n", in soc_check_tplg_fes()
1992 card->dai_link[i].name); in soc_check_tplg_fes()
1995 if (!dai_link->platforms) { in soc_check_tplg_fes()
1996 dev_err(card->dev, "init platform error"); in soc_check_tplg_fes()
2000 if (component->dev->of_node) in soc_check_tplg_fes()
2001 dai_link->platforms->of_node = component->dev->of_node; in soc_check_tplg_fes()
2003 dai_link->platforms->name = component->name; in soc_check_tplg_fes()
2005 /* convert non BE into BE */ in soc_check_tplg_fes()
2006 dai_link->no_pcm = 1; in soc_check_tplg_fes()
2009 * override any BE fixups in soc_check_tplg_fes()
2013 dai_link->be_hw_params_fixup = in soc_check_tplg_fes()
2014 component->driver->be_hw_params_fixup; in soc_check_tplg_fes()
2017 * most BE links don't set stream name, so set it to in soc_check_tplg_fes()
2018 * dai link name if it's NULL to help bind widgets. in soc_check_tplg_fes()
2020 if (!dai_link->stream_name) in soc_check_tplg_fes()
2021 dai_link->stream_name = dai_link->name; in soc_check_tplg_fes()
2025 if (component->driver->topology_name_prefix) { in soc_check_tplg_fes()
2028 if (!card->topology_shortname_created) { in soc_check_tplg_fes()
2029 comp_drv = component->driver; in soc_check_tplg_fes()
2031 snprintf(card->topology_shortname, 32, "%s-%s", in soc_check_tplg_fes()
2032 comp_drv->topology_name_prefix, in soc_check_tplg_fes()
2033 card->name); in soc_check_tplg_fes()
2034 card->topology_shortname_created = true; in soc_check_tplg_fes()
2038 card->name = card->topology_shortname; in soc_check_tplg_fes()
2054 if (name != card->snd_card->driver) in __soc_setup_card_name()
2061 * searches in the user-space. in __soc_setup_card_name()
2064 * "abcd??efg" -> "abcd__efg" in __soc_setup_card_name()
2069 case '-': in __soc_setup_card_name()
2084 if (strlen(src) > len - 1) in __soc_setup_card_name()
2085 dev_err(card->dev, "ASoC: driver name too long '%s' -> '%s'\n", src, name); in __soc_setup_card_name()
2092 if (card->snd_card) in soc_cleanup_card_resources()
2093 snd_card_disconnect_sync(card->snd_card); in soc_cleanup_card_resources()
2099 if (rtd->initialized) in soc_cleanup_card_resources()
2101 /* remove and free each DAI */ in soc_cleanup_card_resources()
2112 snd_soc_dapm_free(&card->dapm); in soc_cleanup_card_resources()
2118 if (card->snd_card) { in soc_cleanup_card_resources()
2119 snd_card_free(card->snd_card); in soc_cleanup_card_resources()
2120 card->snd_card = NULL; in soc_cleanup_card_resources()
2127 card->instantiated = false; in snd_soc_unbind_card()
2132 list_add(&card->list, &unbind_card_list); in snd_soc_unbind_card()
2135 list_del(&card->list); in snd_soc_unbind_card()
2150 snd_soc_dapm_init(&card->dapm, card, NULL); in snd_soc_bind_card()
2160 /* add predefined DAI links to the list */ in snd_soc_bind_card()
2161 card->num_rtd = 0; in snd_soc_bind_card()
2162 ret = snd_soc_add_pcm_runtimes(card, card->dai_link, card->num_links); in snd_soc_bind_card()
2167 ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, in snd_soc_bind_card()
2168 card->owner, 0, &card->snd_card); in snd_soc_bind_card()
2170 dev_err(card->dev, in snd_soc_bind_card()
2172 card->name, ret); in snd_soc_bind_card()
2180 ret = snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets, in snd_soc_bind_card()
2181 card->num_dapm_widgets); in snd_soc_bind_card()
2185 ret = snd_soc_dapm_new_controls(&card->dapm, card->of_dapm_widgets, in snd_soc_bind_card()
2186 card->num_of_dapm_widgets); in snd_soc_bind_card()
2195 /* probe all components used by DAI links on this card */ in snd_soc_bind_card()
2198 if (ret != -EPROBE_DEFER) { in snd_soc_bind_card()
2199 dev_err(card->dev, in snd_soc_bind_card()
2208 dev_err(card->dev, in snd_soc_bind_card()
2213 /* probe all DAI links on this card */ in snd_soc_bind_card()
2216 dev_err(card->dev, in snd_soc_bind_card()
2230 ret = snd_soc_add_card_controls(card, card->controls, in snd_soc_bind_card()
2231 card->num_controls); in snd_soc_bind_card()
2235 ret = snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, in snd_soc_bind_card()
2236 card->num_dapm_routes); in snd_soc_bind_card()
2238 if (card->disable_route_checks) { in snd_soc_bind_card()
2239 dev_info(card->dev, in snd_soc_bind_card()
2243 dev_err(card->dev, in snd_soc_bind_card()
2250 ret = snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes, in snd_soc_bind_card()
2251 card->num_of_dapm_routes); in snd_soc_bind_card()
2258 soc_setup_card_name(card, card->snd_card->shortname, in snd_soc_bind_card()
2259 card->name, NULL); in snd_soc_bind_card()
2260 soc_setup_card_name(card, card->snd_card->longname, in snd_soc_bind_card()
2261 card->long_name, card->name); in snd_soc_bind_card()
2262 soc_setup_card_name(card, card->snd_card->driver, in snd_soc_bind_card()
2263 card->driver_name, card->name); in snd_soc_bind_card()
2265 if (card->components) { in snd_soc_bind_card()
2270 ret = snd_component_add(card->snd_card, card->components); in snd_soc_bind_card()
2272 dev_err(card->dev, "ASoC: %s snd_component_add() failed: %d\n", in snd_soc_bind_card()
2273 card->name, ret); in snd_soc_bind_card()
2285 ret = snd_card_register(card->snd_card); in snd_soc_bind_card()
2287 dev_err(card->dev, "ASoC: failed to register soundcard %d\n", in snd_soc_bind_card()
2292 card->instantiated = 1; in snd_soc_bind_card()
2294 snd_soc_dapm_sync(&card->dapm); in snd_soc_bind_card()
2299 pinctrl_pm_select_sleep_state(component->dev); in snd_soc_bind_card()
2317 * no card, so machine driver should be registering card in soc_probe()
2318 * we should not be here in that case so ret error in soc_probe()
2321 return -EINVAL; in soc_probe()
2323 dev_warn(&pdev->dev, in soc_probe()
2325 card->name); in soc_probe()
2328 card->dev = &pdev->dev; in soc_probe()
2330 return devm_snd_soc_register_card(&pdev->dev, card); in soc_probe()
2342 * Flush out pmdown_time work - we actually do want to run it in snd_soc_poweroff()
2351 pinctrl_pm_select_sleep_state(component->dev); in snd_soc_poweroff()
2370 .name = "soc-audio",
2377 * snd_soc_cnew - create new control
2428 control->name, prefix)); in snd_soc_add_controls()
2431 control->name, err); in snd_soc_add_controls()
2440 * snd_soc_add_component_controls - Add an array of controls to a component.
2451 struct snd_card *card = component->card->snd_card; in snd_soc_add_component_controls()
2453 return snd_soc_add_controls(card, component->dev, controls, in snd_soc_add_component_controls()
2454 num_controls, component->name_prefix, component); in snd_soc_add_component_controls()
2459 * snd_soc_add_card_controls - add an array of controls to a SoC card.
2471 struct snd_card *card = soc_card->snd_card; in snd_soc_add_card_controls()
2473 return snd_soc_add_controls(card, soc_card->dev, controls, num_controls, in snd_soc_add_card_controls()
2479 * snd_soc_add_dai_controls - add an array of controls to a DAI.
2482 * @dai: DAI to add controls to
2488 int snd_soc_add_dai_controls(struct snd_soc_dai *dai, in snd_soc_add_dai_controls() argument
2491 struct snd_card *card = dai->component->card->snd_card; in snd_soc_add_dai_controls()
2493 return snd_soc_add_controls(card, dai->dev, controls, num_controls, in snd_soc_add_dai_controls()
2494 NULL, dai); in snd_soc_add_dai_controls()
2499 * snd_soc_register_card - Register a card with the ASoC core
2506 if (!card->name || !card->dev) in snd_soc_register_card()
2507 return -EINVAL; in snd_soc_register_card()
2509 dev_set_drvdata(card->dev, card); in snd_soc_register_card()
2511 INIT_LIST_HEAD(&card->widgets); in snd_soc_register_card()
2512 INIT_LIST_HEAD(&card->paths); in snd_soc_register_card()
2513 INIT_LIST_HEAD(&card->dapm_list); in snd_soc_register_card()
2514 INIT_LIST_HEAD(&card->aux_comp_list); in snd_soc_register_card()
2515 INIT_LIST_HEAD(&card->component_dev_list); in snd_soc_register_card()
2516 INIT_LIST_HEAD(&card->list); in snd_soc_register_card()
2517 INIT_LIST_HEAD(&card->rtd_list); in snd_soc_register_card()
2518 INIT_LIST_HEAD(&card->dapm_dirty); in snd_soc_register_card()
2519 INIT_LIST_HEAD(&card->dobj_list); in snd_soc_register_card()
2521 card->instantiated = 0; in snd_soc_register_card()
2522 mutex_init(&card->mutex); in snd_soc_register_card()
2523 mutex_init(&card->dapm_mutex); in snd_soc_register_card()
2524 mutex_init(&card->pcm_mutex); in snd_soc_register_card()
2531 * snd_soc_unregister_card - Unregister a card with the ASoC core
2541 dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); in snd_soc_unregister_card()
2546 * Simplify DAI link configuration by removing ".-1" from device names
2563 found = strstr(name, dev->driver->name); in fmt_single_name()
2566 if (sscanf(&found[strlen(dev->driver->name)], ".%d", id) == 1) { in fmt_single_name()
2568 /* discard ID from name if ID == -1 */ in fmt_single_name()
2569 if (*id == -1) in fmt_single_name()
2570 found[strlen(dev->driver->name)] = '\0'; in fmt_single_name()
2573 /* I2C component devices are named "bus-addr" */ in fmt_single_name()
2574 } else if (sscanf(name, "%x-%x", &id1, &id2) == 2) { in fmt_single_name()
2581 /* sanitize component name for DAI link creation */ in fmt_single_name()
2582 name = devm_kasprintf(dev, GFP_KERNEL, "%s.%s", dev->driver->name, devname); in fmt_single_name()
2591 * Simplify DAI link naming for single devices with multiple DAIs by removing
2592 * any ".-1" and using the DAI name (instead of device name).
2597 if (dai_drv->name == NULL) { in fmt_multiple_name()
2599 "ASoC: error - multiple DAI %s registered with no name\n", in fmt_multiple_name()
2604 return devm_kstrdup(dev, dai_drv->name, GFP_KERNEL); in fmt_multiple_name()
2607 void snd_soc_unregister_dai(struct snd_soc_dai *dai) in snd_soc_unregister_dai() argument
2609 dev_dbg(dai->dev, "ASoC: Unregistered DAI '%s'\n", dai->name); in snd_soc_unregister_dai()
2610 list_del(&dai->list); in snd_soc_unregister_dai()
2615 * snd_soc_register_dai - Register a DAI dynamically & create its widgets
2618 * @dai_drv: DAI driver to use for the DAI
2619 * @legacy_dai_naming: if %true, use legacy single-name format;
2620 * if %false, use multiple-name format;
2623 * These DAIs's widgets will be freed in the card cleanup and the DAIs
2624 * will be freed in the component cleanup.
2630 struct device *dev = component->dev; in snd_soc_register_dai()
2631 struct snd_soc_dai *dai; in snd_soc_register_dai() local
2635 dai = devm_kzalloc(dev, sizeof(*dai), GFP_KERNEL); in snd_soc_register_dai()
2636 if (dai == NULL) in snd_soc_register_dai()
2640 * Back in the old days when we still had component-less DAIs, in snd_soc_register_dai()
2641 * instead of having a static name, component-less DAIs would in snd_soc_register_dai()
2643 * register multiple instances of the DAI. We still need to keep in snd_soc_register_dai()
2645 * component-less anymore. in snd_soc_register_dai()
2648 (dai_drv->id == 0 || dai_drv->name == NULL)) { in snd_soc_register_dai()
2649 dai->name = fmt_single_name(dev, &dai->id); in snd_soc_register_dai()
2651 dai->name = fmt_multiple_name(dev, dai_drv); in snd_soc_register_dai()
2652 if (dai_drv->id) in snd_soc_register_dai()
2653 dai->id = dai_drv->id; in snd_soc_register_dai()
2655 dai->id = component->num_dai; in snd_soc_register_dai()
2657 if (!dai->name) in snd_soc_register_dai()
2660 dai->component = component; in snd_soc_register_dai()
2661 dai->dev = dev; in snd_soc_register_dai()
2662 dai->driver = dai_drv; in snd_soc_register_dai()
2665 list_add_tail(&dai->list, &component->dai_list); in snd_soc_register_dai()
2666 component->num_dai++; in snd_soc_register_dai()
2668 dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); in snd_soc_register_dai()
2669 return dai; in snd_soc_register_dai()
2674 * snd_soc_unregister_dais - Unregister DAIs from the ASoC core
2676 * @component: The component for which the DAIs should be unregistered
2680 struct snd_soc_dai *dai, *_dai; in snd_soc_unregister_dais() local
2682 for_each_component_dais_safe(component, dai, _dai) in snd_soc_unregister_dais()
2683 snd_soc_unregister_dai(dai); in snd_soc_unregister_dais()
2687 * snd_soc_register_dais - Register a DAI with the ASoC core
2690 * @dai_drv: DAI driver to use for the DAIs
2697 struct snd_soc_dai *dai; in snd_soc_register_dais() local
2702 dai = snd_soc_register_dai(component, dai_drv + i, count == 1 && in snd_soc_register_dais()
2703 component->driver->legacy_dai_naming); in snd_soc_register_dais()
2704 if (dai == NULL) { in snd_soc_register_dais()
2705 ret = -ENOMEM; in snd_soc_register_dais()
2719 (SNDRV_PCM_FMTBIT_##name##LE | SNDRV_PCM_FMTBIT_##name##BE)
2739 * Fix up the DAI formats for endianness: codecs don't actually see
2749 if (stream->formats & endianness_format_map[i]) in convert_endianness_formats()
2750 stream->formats |= endianness_format_map[i]; in convert_endianness_formats()
2759 list_del(&card->list); in snd_soc_try_rebind_card()
2764 struct snd_soc_card *card = component->card; in snd_soc_del_component_unlocked()
2771 list_del(&component->list); in snd_soc_del_component_unlocked()
2778 INIT_LIST_HEAD(&component->dai_list); in snd_soc_component_initialize()
2779 INIT_LIST_HEAD(&component->dobj_list); in snd_soc_component_initialize()
2780 INIT_LIST_HEAD(&component->card_list); in snd_soc_component_initialize()
2781 INIT_LIST_HEAD(&component->list); in snd_soc_component_initialize()
2782 mutex_init(&component->io_mutex); in snd_soc_component_initialize()
2784 if (!component->name) { in snd_soc_component_initialize()
2785 component->name = fmt_single_name(dev, &component->id); in snd_soc_component_initialize()
2786 if (!component->name) { in snd_soc_component_initialize()
2788 return -ENOMEM; in snd_soc_component_initialize()
2792 component->dev = dev; in snd_soc_component_initialize()
2793 component->driver = driver; in snd_soc_component_initialize()
2796 if (!component->debugfs_prefix) in snd_soc_component_initialize()
2797 component->debugfs_prefix = driver->debugfs_prefix; in snd_soc_component_initialize()
2813 if (component->driver->endianness) { in snd_soc_add_component()
2822 dev_err(component->dev, "ASoC: Failed to register DAIs: %d\n", in snd_soc_add_component()
2827 if (!component->driver->write && !component->driver->read) { in snd_soc_add_component()
2828 if (!component->regmap) in snd_soc_add_component()
2829 component->regmap = dev_get_regmap(component->dev, in snd_soc_add_component()
2831 if (component->regmap) in snd_soc_add_component()
2836 list_add(&component->list, &component_list); in snd_soc_add_component()
2861 return -ENOMEM; in snd_soc_register_component()
2872 * snd_soc_unregister_component_by_driver - Unregister component using a given driver
2887 component = snd_soc_lookup_component_nolocked(dev, component_driver->name); in snd_soc_unregister_component_by_driver()
2899 * snd_soc_unregister_component - Unregister all related component
2926 if (!card->dev) { in snd_soc_of_parse_card_name()
2927 pr_err("card->dev is not set before calling %s\n", __func__); in snd_soc_of_parse_card_name()
2928 return -EINVAL; in snd_soc_of_parse_card_name()
2931 np = card->dev->of_node; in snd_soc_of_parse_card_name()
2933 ret = of_property_read_string_index(np, propname, 0, &card->name); in snd_soc_of_parse_card_name()
2936 * card->name was previously set, which is checked later in in snd_soc_of_parse_card_name()
2939 if (ret < 0 && ret != -EINVAL) { in snd_soc_of_parse_card_name()
2940 dev_err(card->dev, in snd_soc_of_parse_card_name()
2941 "ASoC: Property '%s' could not be read: %d\n", in snd_soc_of_parse_card_name()
2960 struct device_node *np = card->dev->of_node; in snd_soc_of_parse_audio_simple_widgets()
2967 dev_err(card->dev, in snd_soc_of_parse_audio_simple_widgets()
2969 return -EINVAL; in snd_soc_of_parse_audio_simple_widgets()
2972 dev_err(card->dev, "ASoC: Property '%s's length is zero\n", in snd_soc_of_parse_audio_simple_widgets()
2974 return -EINVAL; in snd_soc_of_parse_audio_simple_widgets()
2977 dev_err(card->dev, in snd_soc_of_parse_audio_simple_widgets()
2979 return -EINVAL; in snd_soc_of_parse_audio_simple_widgets()
2984 widgets = devm_kcalloc(card->dev, num_widgets, sizeof(*widgets), in snd_soc_of_parse_audio_simple_widgets()
2987 dev_err(card->dev, in snd_soc_of_parse_audio_simple_widgets()
2989 return -ENOMEM; in snd_soc_of_parse_audio_simple_widgets()
2996 dev_err(card->dev, in snd_soc_of_parse_audio_simple_widgets()
2999 return -EINVAL; in snd_soc_of_parse_audio_simple_widgets()
3011 dev_err(card->dev, in snd_soc_of_parse_audio_simple_widgets()
3014 return -EINVAL; in snd_soc_of_parse_audio_simple_widgets()
3021 dev_err(card->dev, in snd_soc_of_parse_audio_simple_widgets()
3024 return -EINVAL; in snd_soc_of_parse_audio_simple_widgets()
3030 card->of_dapm_widgets = widgets; in snd_soc_of_parse_audio_simple_widgets()
3031 card->num_of_dapm_widgets = num_widgets; in snd_soc_of_parse_audio_simple_widgets()
3042 struct device *dev = card->dev; in snd_soc_of_parse_pin_switches()
3046 if (!of_property_read_bool(dev->of_node, prop)) in snd_soc_of_parse_pin_switches()
3052 return -ENOMEM; in snd_soc_of_parse_pin_switches()
3054 ret = of_property_read_string_array(dev->of_node, prop, in snd_soc_of_parse_pin_switches()
3064 return -ENOMEM; in snd_soc_of_parse_pin_switches()
3070 return -ENOMEM; in snd_soc_of_parse_pin_switches()
3080 card->controls = controls; in snd_soc_of_parse_pin_switches()
3081 card->num_controls = nb_controls; in snd_soc_of_parse_pin_switches()
3116 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-tx-mask", tx_mask); in snd_soc_of_parse_tdm_slot()
3118 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-rx-mask", rx_mask); in snd_soc_of_parse_tdm_slot()
3120 if (of_property_read_bool(np, "dai-tdm-slot-num")) { in snd_soc_of_parse_tdm_slot()
3121 ret = of_property_read_u32(np, "dai-tdm-slot-num", &val); in snd_soc_of_parse_tdm_slot()
3129 if (of_property_read_bool(np, "dai-tdm-slot-width")) { in snd_soc_of_parse_tdm_slot()
3130 ret = of_property_read_u32(np, "dai-tdm-slot-width", &val); in snd_soc_of_parse_tdm_slot()
3145 platforms->of_node = cpus->of_node; in snd_soc_dlc_use_cpu_as_platform()
3146 platforms->dai_args = cpus->dai_args; in snd_soc_dlc_use_cpu_as_platform()
3164 codec_conf->dlc.of_node = of_node; in snd_soc_of_parse_node_prefix()
3165 codec_conf->name_prefix = str; in snd_soc_of_parse_node_prefix()
3172 struct device_node *np = card->dev->of_node; in snd_soc_of_parse_audio_routing()
3179 dev_err(card->dev, in snd_soc_of_parse_audio_routing()
3182 return -EINVAL; in snd_soc_of_parse_audio_routing()
3186 routes = devm_kcalloc(card->dev, num_routes, sizeof(*routes), in snd_soc_of_parse_audio_routing()
3189 dev_err(card->dev, in snd_soc_of_parse_audio_routing()
3191 return -ENOMEM; in snd_soc_of_parse_audio_routing()
3198 dev_err(card->dev, in snd_soc_of_parse_audio_routing()
3199 "ASoC: Property '%s' index %d could not be read: %d\n", in snd_soc_of_parse_audio_routing()
3201 return -EINVAL; in snd_soc_of_parse_audio_routing()
3206 dev_err(card->dev, in snd_soc_of_parse_audio_routing()
3207 "ASoC: Property '%s' index %d could not be read: %d\n", in snd_soc_of_parse_audio_routing()
3209 return -EINVAL; in snd_soc_of_parse_audio_routing()
3213 card->num_of_dapm_routes = num_routes; in snd_soc_of_parse_audio_routing()
3214 card->of_dapm_routes = routes; in snd_soc_of_parse_audio_routing()
3222 struct device_node *node = card->dev->of_node; in snd_soc_of_parse_aux_devs()
3227 if (num == -ENOENT) { in snd_soc_of_parse_aux_devs()
3230 dev_err(card->dev, "ASOC: Property '%s' could not be read: %d\n", in snd_soc_of_parse_aux_devs()
3235 aux = devm_kcalloc(card->dev, num, sizeof(*aux), GFP_KERNEL); in snd_soc_of_parse_aux_devs()
3237 return -ENOMEM; in snd_soc_of_parse_aux_devs()
3238 card->aux_dev = aux; in snd_soc_of_parse_aux_devs()
3239 card->num_aux_devs = num; in snd_soc_of_parse_aux_devs()
3242 aux->dlc.of_node = of_parse_phandle(node, propname, i); in snd_soc_of_parse_aux_devs()
3243 if (!aux->dlc.of_node) in snd_soc_of_parse_aux_devs()
3244 return -EINVAL; in snd_soc_of_parse_aux_devs()
3324 * check "dai-format = xxx" in snd_soc_daifmt_parse_format()
3328 ret = of_property_read_string(np, "dai-format", &str); in snd_soc_daifmt_parse_format()
3345 * check "[prefix]continuous-clock" in snd_soc_daifmt_parse_format()
3348 snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix); in snd_soc_daifmt_parse_format()
3355 * check "[prefix]bitclock-inversion" in snd_soc_daifmt_parse_format()
3356 * check "[prefix]frame-inversion" in snd_soc_daifmt_parse_format()
3359 snprintf(prop, sizeof(prop), "%sbitclock-inversion", prefix); in snd_soc_daifmt_parse_format()
3362 snprintf(prop, sizeof(prop), "%sframe-inversion", prefix); in snd_soc_daifmt_parse_format()
3396 * check "[prefix]bitclock-master" in snd_soc_daifmt_parse_clock_provider_raw()
3397 * check "[prefix]frame-master" in snd_soc_daifmt_parse_clock_provider_raw()
3399 snprintf(prop, sizeof(prop), "%sbitclock-master", prefix); in snd_soc_daifmt_parse_clock_provider_raw()
3404 snprintf(prop, sizeof(prop), "%sframe-master", prefix); in snd_soc_daifmt_parse_clock_provider_raw()
3411 * It will be parameter of in snd_soc_daifmt_parse_clock_provider_raw()
3431 if (!dai_link->c2c_params) in snd_soc_get_stream_cpu()
3467 ret = -ENOTSUPP; in snd_soc_get_dai_id()
3483 int ret = -EPROBE_DEFER; in snd_soc_get_dlc()
3489 if (component_of_node != args->np || !pos->num_dai) in snd_soc_get_dlc()
3492 ret = snd_soc_component_of_xlate_dai_name(pos, args, &dlc->dai_name); in snd_soc_get_dlc()
3493 if (ret == -ENOTSUPP) { in snd_soc_get_dlc()
3494 struct snd_soc_dai *dai; in snd_soc_get_dlc() local
3495 int id = -1; in snd_soc_get_dlc()
3497 switch (args->args_count) { in snd_soc_get_dlc()
3502 id = args->args[0]; in snd_soc_get_dlc()
3509 if (id < 0 || id >= pos->num_dai) { in snd_soc_get_dlc()
3510 ret = -EINVAL; in snd_soc_get_dlc()
3516 /* find target DAI */ in snd_soc_get_dlc()
3517 for_each_component_dais(pos, dai) { in snd_soc_get_dlc()
3520 id--; in snd_soc_get_dlc()
3523 dlc->dai_name = snd_soc_dai_name_get(dai); in snd_soc_get_dlc()
3538 dlc->of_node = args->np; in snd_soc_get_dlc()
3556 ret = of_parse_phandle_with_args(of_node, "sound-dai", in snd_soc_of_get_dlc()
3557 "#sound-dai-cells", index, args); in snd_soc_of_get_dlc()
3593 struct snd_soc_dai *dai; in snd_soc_get_dai_via_args() local
3598 for_each_component_dais(component, dai) in snd_soc_get_dai_via_args()
3599 if (snd_soc_is_match_dai_args(dai->driver->dai_args, dai_args)) in snd_soc_get_dai_via_args()
3602 dai = NULL; in snd_soc_get_dai_via_args()
3605 return dai; in snd_soc_get_dai_via_args()
3611 if (component->of_node) { in __snd_soc_of_put_component()
3612 of_node_put(component->of_node); in __snd_soc_of_put_component()
3613 component->of_node = NULL; in __snd_soc_of_put_component()
3626 num = of_count_phandle_with_args(of_node, "sound-dai", "#sound-dai-cells"); in __snd_soc_of_get_dai_link_component_alloc()
3628 if (num == -ENOENT) in __snd_soc_of_get_dai_link_component_alloc()
3629 dev_err(dev, "No 'sound-dai' property\n"); in __snd_soc_of_get_dai_link_component_alloc()
3631 dev_err(dev, "Bad phandle in 'sound-dai'\n"); in __snd_soc_of_get_dai_link_component_alloc()
3636 return -ENOMEM; in __snd_soc_of_get_dai_link_component_alloc()
3645 * snd_soc_of_put_dai_link_codecs - Dereference device nodes in the codecs array
3646 * @dai_link: DAI link
3661 * snd_soc_of_get_dai_link_codecs - Parse a list of CODECs in the devicetree
3664 * @dai_link: DAI link
3666 * Builds an array of CODEC DAI components from the DAI link property
3667 * 'sound-dai'.
3668 * The array is set in the DAI link and the number of DAIs is set accordingly.
3669 * The device nodes in the array (of_node) must be dereferenced by calling
3682 &dai_link->codecs, &dai_link->num_codecs); in snd_soc_of_get_dai_link_codecs()
3695 dai_link->codecs = NULL; in snd_soc_of_get_dai_link_codecs()
3696 dai_link->num_codecs = 0; in snd_soc_of_get_dai_link_codecs()
3702 * snd_soc_of_put_dai_link_cpus - Dereference device nodes in the codecs array
3703 * @dai_link: DAI link
3718 * snd_soc_of_get_dai_link_cpus - Parse a list of CPU DAIs in the devicetree
3721 * @dai_link: DAI link
3737 &dai_link->cpus, &dai_link->num_cpus); in snd_soc_of_get_dai_link_cpus()
3750 dai_link->cpus = NULL; in snd_soc_of_get_dai_link_cpus()
3751 dai_link->num_cpus = 0; in snd_soc_of_get_dai_link_cpus()
3791 MODULE_ALIAS("platform:soc-audio");