3806 lines · c
1// SPDX-License-Identifier: GPL-2.0+2//3// soc-core.c -- ALSA SoC Audio Layer4//5// Copyright 2005 Wolfson Microelectronics PLC.6// Copyright 2005 Openedhand Ltd.7// Copyright (C) 2010 Slimlogic Ltd.8// Copyright (C) 2010 Texas Instruments Inc.9//10// Author: Liam Girdwood <lrg@slimlogic.co.uk>11// with code, comments and ideas from :-12// Richard Purdie <richard@openedhand.com>13//14// TODO:15// o Add hw rules to enforce rates, etc.16// o More testing with other codecs/machines.17// o Add more codecs and platforms to ensure good API coverage.18// o Support TDM on PCM and I2S19 20#include <linux/module.h>21#include <linux/moduleparam.h>22#include <linux/init.h>23#include <linux/delay.h>24#include <linux/pm.h>25#include <linux/bitops.h>26#include <linux/debugfs.h>27#include <linux/platform_device.h>28#include <linux/pinctrl/consumer.h>29#include <linux/ctype.h>30#include <linux/slab.h>31#include <linux/of.h>32#include <linux/of_graph.h>33#include <linux/dmi.h>34#include <linux/acpi.h>35#include <sound/core.h>36#include <sound/pcm.h>37#include <sound/pcm_params.h>38#include <sound/soc.h>39#include <sound/soc-dpcm.h>40#include <sound/soc-topology.h>41#include <sound/soc-link.h>42#include <sound/initval.h>43 44#define CREATE_TRACE_POINTS45#include <trace/events/asoc.h>46 47static DEFINE_MUTEX(client_mutex);48static LIST_HEAD(component_list);49static LIST_HEAD(unbind_card_list);50 51#define for_each_component(component) \52 list_for_each_entry(component, &component_list, list)53 54/*55 * This is used if driver don't need to have CPU/Codec/Platform56 * dai_link. see soc.h57 */58struct snd_soc_dai_link_component null_dailink_component[0];59EXPORT_SYMBOL_GPL(null_dailink_component);60 61/*62 * This is a timeout to do a DAPM powerdown after a stream is closed().63 * It can be used to eliminate pops between different playback streams, e.g.64 * between two audio tracks.65 */66static int pmdown_time = 5000;67module_param(pmdown_time, int, 0);68MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");69 70static ssize_t pmdown_time_show(struct device *dev,71 struct device_attribute *attr, char *buf)72{73 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);74 75 return sysfs_emit(buf, "%ld\n", rtd->pmdown_time);76}77 78static ssize_t pmdown_time_store(struct device *dev,79 struct device_attribute *attr,80 const char *buf, size_t count)81{82 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);83 int ret;84 85 ret = kstrtol(buf, 10, &rtd->pmdown_time);86 if (ret)87 return ret;88 89 return count;90}91 92static DEVICE_ATTR_RW(pmdown_time);93 94static struct attribute *soc_dev_attrs[] = {95 &dev_attr_pmdown_time.attr,96 NULL97};98 99static umode_t soc_dev_attr_is_visible(struct kobject *kobj,100 struct attribute *attr, int idx)101{102 struct device *dev = kobj_to_dev(kobj);103 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);104 105 if (!rtd)106 return 0;107 108 if (attr == &dev_attr_pmdown_time.attr)109 return attr->mode; /* always visible */110 return rtd->dai_link->num_codecs ? attr->mode : 0; /* enabled only with codec */111}112 113static const struct attribute_group soc_dapm_dev_group = {114 .attrs = soc_dapm_dev_attrs,115 .is_visible = soc_dev_attr_is_visible,116};117 118static const struct attribute_group soc_dev_group = {119 .attrs = soc_dev_attrs,120 .is_visible = soc_dev_attr_is_visible,121};122 123static const struct attribute_group *soc_dev_attr_groups[] = {124 &soc_dapm_dev_group,125 &soc_dev_group,126 NULL127};128 129#ifdef CONFIG_DEBUG_FS130struct dentry *snd_soc_debugfs_root;131EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);132 133static void soc_init_component_debugfs(struct snd_soc_component *component)134{135 if (!component->card->debugfs_card_root)136 return;137 138 if (component->debugfs_prefix) {139 char *name;140 141 name = kasprintf(GFP_KERNEL, "%s:%s",142 component->debugfs_prefix, component->name);143 if (name) {144 component->debugfs_root = debugfs_create_dir(name,145 component->card->debugfs_card_root);146 kfree(name);147 }148 } else {149 component->debugfs_root = debugfs_create_dir(component->name,150 component->card->debugfs_card_root);151 }152 153 snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component),154 component->debugfs_root);155}156 157static void soc_cleanup_component_debugfs(struct snd_soc_component *component)158{159 if (!component->debugfs_root)160 return;161 debugfs_remove_recursive(component->debugfs_root);162 component->debugfs_root = NULL;163}164 165static int dai_list_show(struct seq_file *m, void *v)166{167 struct snd_soc_component *component;168 struct snd_soc_dai *dai;169 170 mutex_lock(&client_mutex);171 172 for_each_component(component)173 for_each_component_dais(component, dai)174 seq_printf(m, "%s\n", dai->name);175 176 mutex_unlock(&client_mutex);177 178 return 0;179}180DEFINE_SHOW_ATTRIBUTE(dai_list);181 182static int component_list_show(struct seq_file *m, void *v)183{184 struct snd_soc_component *component;185 186 mutex_lock(&client_mutex);187 188 for_each_component(component)189 seq_printf(m, "%s\n", component->name);190 191 mutex_unlock(&client_mutex);192 193 return 0;194}195DEFINE_SHOW_ATTRIBUTE(component_list);196 197static void soc_init_card_debugfs(struct snd_soc_card *card)198{199 card->debugfs_card_root = debugfs_create_dir(card->name,200 snd_soc_debugfs_root);201 202 debugfs_create_u32("dapm_pop_time", 0644, card->debugfs_card_root,203 &card->pop_time);204 205 snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root);206}207 208static void soc_cleanup_card_debugfs(struct snd_soc_card *card)209{210 debugfs_remove_recursive(card->debugfs_card_root);211 card->debugfs_card_root = NULL;212}213 214static void snd_soc_debugfs_init(void)215{216 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);217 218 debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,219 &dai_list_fops);220 221 debugfs_create_file("components", 0444, snd_soc_debugfs_root, NULL,222 &component_list_fops);223}224 225static void snd_soc_debugfs_exit(void)226{227 debugfs_remove_recursive(snd_soc_debugfs_root);228}229 230#else231 232static inline void soc_init_component_debugfs(struct snd_soc_component *component) { }233static inline void soc_cleanup_component_debugfs(struct snd_soc_component *component) { }234static inline void soc_init_card_debugfs(struct snd_soc_card *card) { }235static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card) { }236static inline void snd_soc_debugfs_init(void) { }237static inline void snd_soc_debugfs_exit(void) { }238 239#endif240 241static int snd_soc_is_match_dai_args(const struct of_phandle_args *args1,242 const struct of_phandle_args *args2)243{244 if (!args1 || !args2)245 return 0;246 247 if (args1->np != args2->np)248 return 0;249 250 for (int i = 0; i < args1->args_count; i++)251 if (args1->args[i] != args2->args[i])252 return 0;253 254 return 1;255}256 257static inline int snd_soc_dlc_component_is_empty(struct snd_soc_dai_link_component *dlc)258{259 return !(dlc->dai_args || dlc->name || dlc->of_node);260}261 262static inline int snd_soc_dlc_component_is_invalid(struct snd_soc_dai_link_component *dlc)263{264 return (dlc->name && dlc->of_node);265}266 267static inline int snd_soc_dlc_dai_is_empty(struct snd_soc_dai_link_component *dlc)268{269 return !(dlc->dai_args || dlc->dai_name);270}271 272static int snd_soc_is_matching_dai(const struct snd_soc_dai_link_component *dlc,273 struct snd_soc_dai *dai)274{275 if (!dlc)276 return 0;277 278 if (dlc->dai_args)279 return snd_soc_is_match_dai_args(dai->driver->dai_args, dlc->dai_args);280 281 if (!dlc->dai_name)282 return 1;283 284 /* see snd_soc_dai_name_get() */285 286 if (dai->driver->name &&287 strcmp(dlc->dai_name, dai->driver->name) == 0)288 return 1;289 290 if (strcmp(dlc->dai_name, dai->name) == 0)291 return 1;292 293 if (dai->component->name &&294 strcmp(dlc->dai_name, dai->component->name) == 0)295 return 1;296 297 return 0;298}299 300const char *snd_soc_dai_name_get(const struct snd_soc_dai *dai)301{302 /* see snd_soc_is_matching_dai() */303 if (dai->driver->name)304 return dai->driver->name;305 306 if (dai->name)307 return dai->name;308 309 if (dai->component->name)310 return dai->component->name;311 312 return NULL;313}314EXPORT_SYMBOL_GPL(snd_soc_dai_name_get);315 316static int snd_soc_rtd_add_component(struct snd_soc_pcm_runtime *rtd,317 struct snd_soc_component *component)318{319 struct snd_soc_component *comp;320 int i;321 322 for_each_rtd_components(rtd, i, comp) {323 /* already connected */324 if (comp == component)325 return 0;326 }327 328 /* see for_each_rtd_components */329 rtd->num_components++; // increment flex array count at first330 rtd->components[rtd->num_components - 1] = component;331 332 return 0;333}334 335struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,336 const char *driver_name)337{338 struct snd_soc_component *component;339 int i;340 341 if (!driver_name)342 return NULL;343 344 /*345 * NOTE346 *347 * snd_soc_rtdcom_lookup() will find component from rtd by using348 * specified driver name.349 * But, if many components which have same driver name are connected350 * to 1 rtd, this function will return 1st found component.351 */352 for_each_rtd_components(rtd, i, component) {353 const char *component_name = component->driver->name;354 355 if (!component_name)356 continue;357 358 if ((component_name == driver_name) ||359 strcmp(component_name, driver_name) == 0)360 return component;361 }362 363 return NULL;364}365EXPORT_SYMBOL_GPL(snd_soc_rtdcom_lookup);366 367struct snd_soc_component368*snd_soc_lookup_component_nolocked(struct device *dev, const char *driver_name)369{370 struct snd_soc_component *component;371 struct snd_soc_component *found_component;372 373 found_component = NULL;374 for_each_component(component) {375 if ((dev == component->dev) &&376 (!driver_name ||377 (driver_name == component->driver->name) ||378 (strcmp(component->driver->name, driver_name) == 0))) {379 found_component = component;380 break;381 }382 }383 384 return found_component;385}386EXPORT_SYMBOL_GPL(snd_soc_lookup_component_nolocked);387 388struct snd_soc_component *snd_soc_lookup_component(struct device *dev,389 const char *driver_name)390{391 struct snd_soc_component *component;392 393 mutex_lock(&client_mutex);394 component = snd_soc_lookup_component_nolocked(dev, driver_name);395 mutex_unlock(&client_mutex);396 397 return component;398}399EXPORT_SYMBOL_GPL(snd_soc_lookup_component);400 401struct snd_soc_pcm_runtime402*snd_soc_get_pcm_runtime(struct snd_soc_card *card,403 struct snd_soc_dai_link *dai_link)404{405 struct snd_soc_pcm_runtime *rtd;406 407 for_each_card_rtds(card, rtd) {408 if (rtd->dai_link == dai_link)409 return rtd;410 }411 dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link->name);412 return NULL;413}414EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime);415 416/*417 * Power down the audio subsystem pmdown_time msecs after close is called.418 * This is to ensure there are no pops or clicks in between any music tracks419 * due to DAPM power cycling.420 */421void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd)422{423 struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);424 int playback = SNDRV_PCM_STREAM_PLAYBACK;425 426 snd_soc_dpcm_mutex_lock(rtd);427 428 dev_dbg(rtd->dev,429 "ASoC: pop wq checking: %s status: %s waiting: %s\n",430 codec_dai->driver->playback.stream_name,431 snd_soc_dai_stream_active(codec_dai, playback) ?432 "active" : "inactive",433 rtd->pop_wait ? "yes" : "no");434 435 /* are we waiting on this codec DAI stream */436 if (rtd->pop_wait == 1) {437 rtd->pop_wait = 0;438 snd_soc_dapm_stream_event(rtd, playback,439 SND_SOC_DAPM_STREAM_STOP);440 }441 442 snd_soc_dpcm_mutex_unlock(rtd);443}444EXPORT_SYMBOL_GPL(snd_soc_close_delayed_work);445 446static void soc_release_rtd_dev(struct device *dev)447{448 /* "dev" means "rtd->dev" */449 kfree(dev);450}451 452static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)453{454 if (!rtd)455 return;456 457 list_del(&rtd->list);458 459 if (delayed_work_pending(&rtd->delayed_work))460 flush_delayed_work(&rtd->delayed_work);461 snd_soc_pcm_component_free(rtd);462 463 /*464 * we don't need to call kfree() for rtd->dev465 * see466 * soc_release_rtd_dev()467 *468 * We don't need rtd->dev NULL check, because469 * it is alloced *before* rtd.470 * see471 * soc_new_pcm_runtime()472 *473 * We don't need to mind freeing for rtd,474 * because it was created from dev (= rtd->dev)475 * see476 * soc_new_pcm_runtime()477 *478 * rtd = devm_kzalloc(dev, ...);479 * rtd->dev = dev480 */481 device_unregister(rtd->dev);482}483 484static void close_delayed_work(struct work_struct *work) {485 struct snd_soc_pcm_runtime *rtd =486 container_of(work, struct snd_soc_pcm_runtime,487 delayed_work.work);488 489 if (rtd->close_delayed_work_func)490 rtd->close_delayed_work_func(rtd);491}492 493static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(494 struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)495{496 struct snd_soc_pcm_runtime *rtd;497 struct device *dev;498 int ret;499 int stream;500 501 /*502 * for rtd->dev503 */504 dev = kzalloc(sizeof(struct device), GFP_KERNEL);505 if (!dev)506 return NULL;507 508 dev->parent = card->dev;509 dev->release = soc_release_rtd_dev;510 511 dev_set_name(dev, "%s", dai_link->name);512 513 ret = device_register(dev);514 if (ret < 0) {515 put_device(dev); /* soc_release_rtd_dev */516 return NULL;517 }518 519 /*520 * for rtd521 */522 rtd = devm_kzalloc(dev,523 struct_size(rtd, components,524 dai_link->num_cpus +525 dai_link->num_codecs +526 dai_link->num_platforms),527 GFP_KERNEL);528 if (!rtd) {529 device_unregister(dev);530 return NULL;531 }532 533 rtd->dev = dev;534 INIT_LIST_HEAD(&rtd->list);535 for_each_pcm_streams(stream) {536 INIT_LIST_HEAD(&rtd->dpcm[stream].be_clients);537 INIT_LIST_HEAD(&rtd->dpcm[stream].fe_clients);538 }539 dev_set_drvdata(dev, rtd);540 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);541 542 /*543 * for rtd->dais544 */545 rtd->dais = devm_kcalloc(dev, dai_link->num_cpus + dai_link->num_codecs,546 sizeof(struct snd_soc_dai *),547 GFP_KERNEL);548 if (!rtd->dais)549 goto free_rtd;550 551 /*552 * dais = [][][][][][][][][][][][][][][][][][]553 * ^cpu_dais ^codec_dais554 * |--- num_cpus ---|--- num_codecs --|555 * see556 * snd_soc_rtd_to_cpu()557 * snd_soc_rtd_to_codec()558 */559 rtd->card = card;560 rtd->dai_link = dai_link;561 rtd->num = card->num_rtd++;562 rtd->pmdown_time = pmdown_time; /* default power off timeout */563 564 /* see for_each_card_rtds */565 list_add_tail(&rtd->list, &card->rtd_list);566 567 ret = device_add_groups(dev, soc_dev_attr_groups);568 if (ret < 0)569 goto free_rtd;570 571 return rtd;572 573free_rtd:574 soc_free_pcm_runtime(rtd);575 return NULL;576}577 578static void snd_soc_fill_dummy_dai(struct snd_soc_card *card)579{580 struct snd_soc_dai_link *dai_link;581 int i;582 583 /*584 * COMP_DUMMY() creates size 0 array on dai_link.585 * Fill it as dummy DAI in case of CPU/Codec here.586 * Do nothing for Platform.587 */588 for_each_card_prelinks(card, i, dai_link) {589 if (dai_link->num_cpus == 0 && dai_link->cpus) {590 dai_link->num_cpus = 1;591 dai_link->cpus = &snd_soc_dummy_dlc;592 }593 if (dai_link->num_codecs == 0 && dai_link->codecs) {594 dai_link->num_codecs = 1;595 dai_link->codecs = &snd_soc_dummy_dlc;596 }597 }598}599 600static void snd_soc_flush_all_delayed_work(struct snd_soc_card *card)601{602 struct snd_soc_pcm_runtime *rtd;603 604 for_each_card_rtds(card, rtd)605 flush_delayed_work(&rtd->delayed_work);606}607 608#ifdef CONFIG_PM_SLEEP609static void soc_playback_digital_mute(struct snd_soc_card *card, int mute)610{611 struct snd_soc_pcm_runtime *rtd;612 struct snd_soc_dai *dai;613 int playback = SNDRV_PCM_STREAM_PLAYBACK;614 int i;615 616 for_each_card_rtds(card, rtd) {617 618 if (rtd->dai_link->ignore_suspend)619 continue;620 621 for_each_rtd_dais(rtd, i, dai) {622 if (snd_soc_dai_stream_active(dai, playback))623 snd_soc_dai_digital_mute(dai, mute, playback);624 }625 }626}627 628static void soc_dapm_suspend_resume(struct snd_soc_card *card, int event)629{630 struct snd_soc_pcm_runtime *rtd;631 int stream;632 633 for_each_card_rtds(card, rtd) {634 635 if (rtd->dai_link->ignore_suspend)636 continue;637 638 for_each_pcm_streams(stream)639 snd_soc_dapm_stream_event(rtd, stream, event);640 }641}642 643/* powers down audio subsystem for suspend */644int snd_soc_suspend(struct device *dev)645{646 struct snd_soc_card *card = dev_get_drvdata(dev);647 struct snd_soc_component *component;648 struct snd_soc_pcm_runtime *rtd;649 int i;650 651 /* If the card is not initialized yet there is nothing to do */652 if (!snd_soc_card_is_instantiated(card))653 return 0;654 655 /*656 * Due to the resume being scheduled into a workqueue we could657 * suspend before that's finished - wait for it to complete.658 */659 snd_power_wait(card->snd_card);660 661 /* we're going to block userspace touching us until resume completes */662 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);663 664 /* mute any active DACs */665 soc_playback_digital_mute(card, 1);666 667 /* suspend all pcms */668 for_each_card_rtds(card, rtd) {669 if (rtd->dai_link->ignore_suspend)670 continue;671 672 snd_pcm_suspend_all(rtd->pcm);673 }674 675 snd_soc_card_suspend_pre(card);676 677 /* close any waiting streams */678 snd_soc_flush_all_delayed_work(card);679 680 soc_dapm_suspend_resume(card, SND_SOC_DAPM_STREAM_SUSPEND);681 682 /* Recheck all endpoints too, their state is affected by suspend */683 dapm_mark_endpoints_dirty(card);684 snd_soc_dapm_sync(&card->dapm);685 686 /* suspend all COMPONENTs */687 for_each_card_rtds(card, rtd) {688 689 if (rtd->dai_link->ignore_suspend)690 continue;691 692 for_each_rtd_components(rtd, i, component) {693 struct snd_soc_dapm_context *dapm =694 snd_soc_component_get_dapm(component);695 696 /*697 * ignore if component was already suspended698 */699 if (snd_soc_component_is_suspended(component))700 continue;701 702 /*703 * If there are paths active then the COMPONENT will be704 * held with bias _ON and should not be suspended.705 */706 switch (snd_soc_dapm_get_bias_level(dapm)) {707 case SND_SOC_BIAS_STANDBY:708 /*709 * If the COMPONENT is capable of idle710 * bias off then being in STANDBY711 * means it's doing something,712 * otherwise fall through.713 */714 if (dapm->idle_bias_off) {715 dev_dbg(component->dev,716 "ASoC: idle_bias_off CODEC on over suspend\n");717 break;718 }719 fallthrough;720 721 case SND_SOC_BIAS_OFF:722 snd_soc_component_suspend(component);723 if (component->regmap)724 regcache_mark_dirty(component->regmap);725 /* deactivate pins to sleep state */726 pinctrl_pm_select_sleep_state(component->dev);727 break;728 default:729 dev_dbg(component->dev,730 "ASoC: COMPONENT is on over suspend\n");731 break;732 }733 }734 }735 736 snd_soc_card_suspend_post(card);737 738 return 0;739}740EXPORT_SYMBOL_GPL(snd_soc_suspend);741 742/*743 * deferred resume work, so resume can complete before we finished744 * setting our codec back up, which can be very slow on I2C745 */746static void soc_resume_deferred(struct work_struct *work)747{748 struct snd_soc_card *card =749 container_of(work, struct snd_soc_card,750 deferred_resume_work);751 struct snd_soc_component *component;752 753 /*754 * our power state is still SNDRV_CTL_POWER_D3hot from suspend time,755 * so userspace apps are blocked from touching us756 */757 758 dev_dbg(card->dev, "ASoC: starting resume work\n");759 760 /* Bring us up into D2 so that DAPM starts enabling things */761 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2);762 763 snd_soc_card_resume_pre(card);764 765 for_each_card_components(card, component) {766 if (snd_soc_component_is_suspended(component))767 snd_soc_component_resume(component);768 }769 770 soc_dapm_suspend_resume(card, SND_SOC_DAPM_STREAM_RESUME);771 772 /* unmute any active DACs */773 soc_playback_digital_mute(card, 0);774 775 snd_soc_card_resume_post(card);776 777 dev_dbg(card->dev, "ASoC: resume work completed\n");778 779 /* Recheck all endpoints too, their state is affected by suspend */780 dapm_mark_endpoints_dirty(card);781 snd_soc_dapm_sync(&card->dapm);782 783 /* userspace can access us now we are back as we were before */784 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);785}786 787/* powers up audio subsystem after a suspend */788int snd_soc_resume(struct device *dev)789{790 struct snd_soc_card *card = dev_get_drvdata(dev);791 struct snd_soc_component *component;792 793 /* If the card is not initialized yet there is nothing to do */794 if (!snd_soc_card_is_instantiated(card))795 return 0;796 797 /* activate pins from sleep state */798 for_each_card_components(card, component)799 if (snd_soc_component_active(component))800 pinctrl_pm_select_default_state(component->dev);801 802 dev_dbg(dev, "ASoC: Scheduling resume work\n");803 if (!schedule_work(&card->deferred_resume_work))804 dev_err(dev, "ASoC: resume work item may be lost\n");805 806 return 0;807}808EXPORT_SYMBOL_GPL(snd_soc_resume);809 810static void soc_resume_init(struct snd_soc_card *card)811{812 /* deferred resume work */813 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);814}815#else816#define snd_soc_suspend NULL817#define snd_soc_resume NULL818static inline void soc_resume_init(struct snd_soc_card *card) { }819#endif820 821static struct device_node822*soc_component_to_node(struct snd_soc_component *component)823{824 struct device_node *of_node;825 826 of_node = component->dev->of_node;827 if (!of_node && component->dev->parent)828 of_node = component->dev->parent->of_node;829 830 return of_node;831}832 833struct of_phandle_args *snd_soc_copy_dai_args(struct device *dev,834 const struct of_phandle_args *args)835{836 struct of_phandle_args *ret = devm_kzalloc(dev, sizeof(*ret), GFP_KERNEL);837 838 if (!ret)839 return NULL;840 841 *ret = *args;842 843 return ret;844}845EXPORT_SYMBOL_GPL(snd_soc_copy_dai_args);846 847static int snd_soc_is_matching_component(848 const struct snd_soc_dai_link_component *dlc,849 struct snd_soc_component *component)850{851 struct device_node *component_of_node;852 853 if (!dlc)854 return 0;855 856 if (dlc->dai_args) {857 struct snd_soc_dai *dai;858 859 for_each_component_dais(component, dai)860 if (snd_soc_is_matching_dai(dlc, dai))861 return 1;862 return 0;863 }864 865 component_of_node = soc_component_to_node(component);866 867 if (dlc->of_node && component_of_node != dlc->of_node)868 return 0;869 if (dlc->name && strcmp(component->name, dlc->name))870 return 0;871 872 return 1;873}874 875static struct snd_soc_component *soc_find_component(876 const struct snd_soc_dai_link_component *dlc)877{878 struct snd_soc_component *component;879 880 lockdep_assert_held(&client_mutex);881 882 /*883 * NOTE884 *885 * It returns *1st* found component, but some driver886 * has few components by same of_node/name887 * ex)888 * CPU component and generic DMAEngine component889 */890 for_each_component(component)891 if (snd_soc_is_matching_component(dlc, component))892 return component;893 894 return NULL;895}896 897/**898 * snd_soc_find_dai - Find a registered DAI899 *900 * @dlc: name of the DAI or the DAI driver and optional component info to match901 *902 * This function will search all registered components and their DAIs to903 * find the DAI of the same name. The component's of_node and name904 * should also match if being specified.905 *906 * Return: pointer of DAI, or NULL if not found.907 */908struct snd_soc_dai *snd_soc_find_dai(909 const struct snd_soc_dai_link_component *dlc)910{911 struct snd_soc_component *component;912 struct snd_soc_dai *dai;913 914 lockdep_assert_held(&client_mutex);915 916 /* Find CPU DAI from registered DAIs */917 for_each_component(component)918 if (snd_soc_is_matching_component(dlc, component))919 for_each_component_dais(component, dai)920 if (snd_soc_is_matching_dai(dlc, dai))921 return dai;922 923 return NULL;924}925EXPORT_SYMBOL_GPL(snd_soc_find_dai);926 927struct snd_soc_dai *snd_soc_find_dai_with_mutex(928 const struct snd_soc_dai_link_component *dlc)929{930 struct snd_soc_dai *dai;931 932 mutex_lock(&client_mutex);933 dai = snd_soc_find_dai(dlc);934 mutex_unlock(&client_mutex);935 936 return dai;937}938EXPORT_SYMBOL_GPL(snd_soc_find_dai_with_mutex);939 940static int soc_dai_link_sanity_check(struct snd_soc_card *card,941 struct snd_soc_dai_link *link)942{943 int i;944 struct snd_soc_dai_link_component *dlc;945 946 /* Codec check */947 for_each_link_codecs(link, i, dlc) {948 /*949 * Codec must be specified by 1 of name or OF node,950 * not both or neither.951 */952 if (snd_soc_dlc_component_is_invalid(dlc))953 goto component_invalid;954 955 if (snd_soc_dlc_component_is_empty(dlc))956 goto component_empty;957 958 /* Codec DAI name must be specified */959 if (snd_soc_dlc_dai_is_empty(dlc))960 goto dai_empty;961 962 /*963 * Defer card registration if codec component is not added to964 * component list.965 */966 if (!soc_find_component(dlc))967 goto component_not_found;968 }969 970 /* Platform check */971 for_each_link_platforms(link, i, dlc) {972 /*973 * Platform may be specified by either name or OF node, but it974 * can be left unspecified, then no components will be inserted975 * in the rtdcom list976 */977 if (snd_soc_dlc_component_is_invalid(dlc))978 goto component_invalid;979 980 if (snd_soc_dlc_component_is_empty(dlc))981 goto component_empty;982 983 /*984 * Defer card registration if platform component is not added to985 * component list.986 */987 if (!soc_find_component(dlc))988 goto component_not_found;989 }990 991 /* CPU check */992 for_each_link_cpus(link, i, dlc) {993 /*994 * CPU device may be specified by either name or OF node, but995 * can be left unspecified, and will be matched based on DAI996 * name alone..997 */998 if (snd_soc_dlc_component_is_invalid(dlc))999 goto component_invalid;1000 1001 1002 if (snd_soc_dlc_component_is_empty(dlc)) {1003 /*1004 * At least one of CPU DAI name or CPU device name/node must be specified1005 */1006 if (snd_soc_dlc_dai_is_empty(dlc))1007 goto component_dai_empty;1008 } else {1009 /*1010 * Defer card registration if Component is not added1011 */1012 if (!soc_find_component(dlc))1013 goto component_not_found;1014 }1015 }1016 1017 return 0;1018 1019component_invalid:1020 dev_err(card->dev, "ASoC: Both Component name/of_node are set for %s\n", link->name);1021 return -EINVAL;1022 1023component_empty:1024 dev_err(card->dev, "ASoC: Neither Component name/of_node are set for %s\n", link->name);1025 return -EINVAL;1026 1027component_not_found:1028 dev_dbg(card->dev, "ASoC: Component %s not found for link %s\n", dlc->name, link->name);1029 return -EPROBE_DEFER;1030 1031dai_empty:1032 dev_err(card->dev, "ASoC: DAI name is not set for %s\n", link->name);1033 return -EINVAL;1034 1035component_dai_empty:1036 dev_err(card->dev, "ASoC: Neither DAI/Component name/of_node are set for %s\n", link->name);1037 return -EINVAL;1038}1039 1040#define MAX_DEFAULT_CH_MAP_SIZE 81041static struct snd_soc_dai_link_ch_map default_ch_map_sync[MAX_DEFAULT_CH_MAP_SIZE] = {1042 { .cpu = 0, .codec = 0 },1043 { .cpu = 1, .codec = 1 },1044 { .cpu = 2, .codec = 2 },1045 { .cpu = 3, .codec = 3 },1046 { .cpu = 4, .codec = 4 },1047 { .cpu = 5, .codec = 5 },1048 { .cpu = 6, .codec = 6 },1049 { .cpu = 7, .codec = 7 },1050};1051static struct snd_soc_dai_link_ch_map default_ch_map_1cpu[MAX_DEFAULT_CH_MAP_SIZE] = {1052 { .cpu = 0, .codec = 0 },1053 { .cpu = 0, .codec = 1 },1054 { .cpu = 0, .codec = 2 },1055 { .cpu = 0, .codec = 3 },1056 { .cpu = 0, .codec = 4 },1057 { .cpu = 0, .codec = 5 },1058 { .cpu = 0, .codec = 6 },1059 { .cpu = 0, .codec = 7 },1060};1061static struct snd_soc_dai_link_ch_map default_ch_map_1codec[MAX_DEFAULT_CH_MAP_SIZE] = {1062 { .cpu = 0, .codec = 0 },1063 { .cpu = 1, .codec = 0 },1064 { .cpu = 2, .codec = 0 },1065 { .cpu = 3, .codec = 0 },1066 { .cpu = 4, .codec = 0 },1067 { .cpu = 5, .codec = 0 },1068 { .cpu = 6, .codec = 0 },1069 { .cpu = 7, .codec = 0 },1070};1071static int snd_soc_compensate_channel_connection_map(struct snd_soc_card *card,1072 struct snd_soc_dai_link *dai_link)1073{1074 struct snd_soc_dai_link_ch_map *ch_maps;1075 int i;1076 1077 /*1078 * dai_link->ch_maps indicates how CPU/Codec are connected.1079 * It will be a map seen from a larger number of DAI.1080 * see1081 * soc.h :: [dai_link->ch_maps Image sample]1082 */1083 1084 /* it should have ch_maps if connection was N:M */1085 if (dai_link->num_cpus > 1 && dai_link->num_codecs > 1 &&1086 dai_link->num_cpus != dai_link->num_codecs && !dai_link->ch_maps) {1087 dev_err(card->dev, "need to have ch_maps when N:M connection (%s)",1088 dai_link->name);1089 return -EINVAL;1090 }1091 1092 /* do nothing if it has own maps */1093 if (dai_link->ch_maps)1094 goto sanity_check;1095 1096 /* check default map size */1097 if (dai_link->num_cpus > MAX_DEFAULT_CH_MAP_SIZE ||1098 dai_link->num_codecs > MAX_DEFAULT_CH_MAP_SIZE) {1099 dev_err(card->dev, "soc-core.c needs update default_connection_maps");1100 return -EINVAL;1101 }1102 1103 /* Compensate missing map for ... */1104 if (dai_link->num_cpus == dai_link->num_codecs)1105 dai_link->ch_maps = default_ch_map_sync; /* for 1:1 or N:N */1106 else if (dai_link->num_cpus < dai_link->num_codecs)1107 dai_link->ch_maps = default_ch_map_1cpu; /* for 1:N */1108 else1109 dai_link->ch_maps = default_ch_map_1codec; /* for N:1 */1110 1111sanity_check:1112 dev_dbg(card->dev, "dai_link %s\n", dai_link->stream_name);1113 for_each_link_ch_maps(dai_link, i, ch_maps) {1114 if ((ch_maps->cpu >= dai_link->num_cpus) ||1115 (ch_maps->codec >= dai_link->num_codecs)) {1116 dev_err(card->dev,1117 "unexpected dai_link->ch_maps[%d] index (cpu(%d/%d) codec(%d/%d))",1118 i,1119 ch_maps->cpu, dai_link->num_cpus,1120 ch_maps->codec, dai_link->num_codecs);1121 return -EINVAL;1122 }1123 1124 dev_dbg(card->dev, " [%d] cpu%d <-> codec%d\n",1125 i, ch_maps->cpu, ch_maps->codec);1126 }1127 1128 return 0;1129}1130 1131/**1132 * snd_soc_remove_pcm_runtime - Remove a pcm_runtime from card1133 * @card: The ASoC card to which the pcm_runtime has1134 * @rtd: The pcm_runtime to remove1135 *1136 * This function removes a pcm_runtime from the ASoC card.1137 */1138void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,1139 struct snd_soc_pcm_runtime *rtd)1140{1141 lockdep_assert_held(&client_mutex);1142 1143 /*1144 * Notify the machine driver for extra destruction1145 */1146 snd_soc_card_remove_dai_link(card, rtd->dai_link);1147 1148 soc_free_pcm_runtime(rtd);1149}1150EXPORT_SYMBOL_GPL(snd_soc_remove_pcm_runtime);1151 1152/**1153 * snd_soc_add_pcm_runtime - Add a pcm_runtime dynamically via dai_link1154 * @card: The ASoC card to which the pcm_runtime is added1155 * @dai_link: The DAI link to find pcm_runtime1156 *1157 * This function adds a pcm_runtime ASoC card by using dai_link.1158 *1159 * Note: Topology can use this API to add pcm_runtime when probing the1160 * topology component. And machine drivers can still define static1161 * DAI links in dai_link array.1162 */1163static int snd_soc_add_pcm_runtime(struct snd_soc_card *card,1164 struct snd_soc_dai_link *dai_link)1165{1166 struct snd_soc_pcm_runtime *rtd;1167 struct snd_soc_dai_link_component *codec, *platform, *cpu;1168 struct snd_soc_component *component;1169 int i, ret;1170 1171 lockdep_assert_held(&client_mutex);1172 1173 /*1174 * Notify the machine driver for extra initialization1175 */1176 ret = snd_soc_card_add_dai_link(card, dai_link);1177 if (ret < 0)1178 return ret;1179 1180 if (dai_link->ignore)1181 return 0;1182 1183 dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);1184 1185 ret = soc_dai_link_sanity_check(card, dai_link);1186 if (ret < 0)1187 return ret;1188 1189 rtd = soc_new_pcm_runtime(card, dai_link);1190 if (!rtd)1191 return -ENOMEM;1192 1193 for_each_link_cpus(dai_link, i, cpu) {1194 snd_soc_rtd_to_cpu(rtd, i) = snd_soc_find_dai(cpu);1195 if (!snd_soc_rtd_to_cpu(rtd, i)) {1196 dev_info(card->dev, "ASoC: CPU DAI %s not registered\n",1197 cpu->dai_name);1198 goto _err_defer;1199 }1200 snd_soc_rtd_add_component(rtd, snd_soc_rtd_to_cpu(rtd, i)->component);1201 }1202 1203 /* Find CODEC from registered CODECs */1204 for_each_link_codecs(dai_link, i, codec) {1205 snd_soc_rtd_to_codec(rtd, i) = snd_soc_find_dai(codec);1206 if (!snd_soc_rtd_to_codec(rtd, i)) {1207 dev_info(card->dev, "ASoC: CODEC DAI %s not registered\n",1208 codec->dai_name);1209 goto _err_defer;1210 }1211 1212 snd_soc_rtd_add_component(rtd, snd_soc_rtd_to_codec(rtd, i)->component);1213 }1214 1215 /* Find PLATFORM from registered PLATFORMs */1216 for_each_link_platforms(dai_link, i, platform) {1217 for_each_component(component) {1218 if (!snd_soc_is_matching_component(platform, component))1219 continue;1220 1221 if (snd_soc_component_is_dummy(component) && component->num_dai)1222 continue;1223 1224 snd_soc_rtd_add_component(rtd, component);1225 }1226 }1227 1228 return 0;1229 1230_err_defer:1231 snd_soc_remove_pcm_runtime(card, rtd);1232 return -EPROBE_DEFER;1233}1234 1235int snd_soc_add_pcm_runtimes(struct snd_soc_card *card,1236 struct snd_soc_dai_link *dai_link,1237 int num_dai_link)1238{1239 for (int i = 0; i < num_dai_link; i++) {1240 int ret;1241 1242 ret = snd_soc_compensate_channel_connection_map(card, dai_link + i);1243 if (ret < 0)1244 return ret;1245 1246 ret = snd_soc_add_pcm_runtime(card, dai_link + i);1247 if (ret < 0)1248 return ret;1249 }1250 1251 return 0;1252}1253EXPORT_SYMBOL_GPL(snd_soc_add_pcm_runtimes);1254 1255static void snd_soc_runtime_get_dai_fmt(struct snd_soc_pcm_runtime *rtd)1256{1257 struct snd_soc_dai_link *dai_link = rtd->dai_link;1258 struct snd_soc_dai *dai, *not_used;1259 u64 pos, possible_fmt;1260 unsigned int mask = 0, dai_fmt = 0;1261 int i, j, priority, pri, until;1262 1263 /*1264 * Get selectable format from each DAIs.1265 *1266 ****************************1267 * NOTE1268 * Using .auto_selectable_formats is not mandatory,1269 * we can select format manually from Sound Card.1270 * When use it, driver should list well tested format only.1271 ****************************1272 *1273 * ex)1274 * auto_selectable_formats (= SND_SOC_POSSIBLE_xxx)1275 * (A) (B) (C)1276 * DAI0_: { 0x000F, 0x00F0, 0x0F00 };1277 * DAI1 : { 0xF000, 0x0F00 };1278 * (X) (Y)1279 *1280 * "until" will be 3 in this case (MAX array size from DAI0 and DAI1)1281 * Here is dev_dbg() message and comments1282 *1283 * priority = 11284 * DAI0: (pri, fmt) = (1, 000000000000000F) // 1st check (A) DAI1 is not selected1285 * DAI1: (pri, fmt) = (0, 0000000000000000) // Necessary Waste1286 * DAI0: (pri, fmt) = (1, 000000000000000F) // 2nd check (A)1287 * DAI1: (pri, fmt) = (1, 000000000000F000) // (X)1288 * priority = 21289 * DAI0: (pri, fmt) = (2, 00000000000000FF) // 3rd check (A) + (B)1290 * DAI1: (pri, fmt) = (1, 000000000000F000) // (X)1291 * DAI0: (pri, fmt) = (2, 00000000000000FF) // 4th check (A) + (B)1292 * DAI1: (pri, fmt) = (2, 000000000000FF00) // (X) + (Y)1293 * priority = 31294 * DAI0: (pri, fmt) = (3, 0000000000000FFF) // 5th check (A) + (B) + (C)1295 * DAI1: (pri, fmt) = (2, 000000000000FF00) // (X) + (Y)1296 * found auto selected format: 0000000000000F001297 */1298 until = snd_soc_dai_get_fmt_max_priority(rtd);1299 for (priority = 1; priority <= until; priority++) {1300 for_each_rtd_dais(rtd, j, not_used) {1301 1302 possible_fmt = ULLONG_MAX;1303 for_each_rtd_dais(rtd, i, dai) {1304 u64 fmt = 0;1305 1306 pri = (j >= i) ? priority : priority - 1;1307 fmt = snd_soc_dai_get_fmt(dai, pri);1308 possible_fmt &= fmt;1309 }1310 if (possible_fmt)1311 goto found;1312 }1313 }1314 /* Not Found */1315 return;1316found:1317 /*1318 * convert POSSIBLE_DAIFMT to DAIFMT1319 *1320 * Some basic/default settings on each is defined as 0.1321 * see1322 * SND_SOC_DAIFMT_NB_NF1323 * SND_SOC_DAIFMT_GATED1324 *1325 * SND_SOC_DAIFMT_xxx_MASK can't notice it if Sound Card specify1326 * these value, and will be overwrite to auto selected value.1327 *1328 * To avoid such issue, loop from 63 to 0 here.1329 * Small number of SND_SOC_POSSIBLE_xxx will be Hi priority.1330 * Basic/Default settings of each part and above are defined1331 * as Hi priority (= small number) of SND_SOC_POSSIBLE_xxx.1332 */1333 for (i = 63; i >= 0; i--) {1334 pos = 1ULL << i;1335 switch (possible_fmt & pos) {1336 /*1337 * for format1338 */1339 case SND_SOC_POSSIBLE_DAIFMT_I2S:1340 case SND_SOC_POSSIBLE_DAIFMT_RIGHT_J:1341 case SND_SOC_POSSIBLE_DAIFMT_LEFT_J:1342 case SND_SOC_POSSIBLE_DAIFMT_DSP_A:1343 case SND_SOC_POSSIBLE_DAIFMT_DSP_B:1344 case SND_SOC_POSSIBLE_DAIFMT_AC97:1345 case SND_SOC_POSSIBLE_DAIFMT_PDM:1346 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) | i;1347 break;1348 /*1349 * for clock1350 */1351 case SND_SOC_POSSIBLE_DAIFMT_CONT:1352 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_MASK) | SND_SOC_DAIFMT_CONT;1353 break;1354 case SND_SOC_POSSIBLE_DAIFMT_GATED:1355 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_MASK) | SND_SOC_DAIFMT_GATED;1356 break;1357 /*1358 * for clock invert1359 */1360 case SND_SOC_POSSIBLE_DAIFMT_NB_NF:1361 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_NB_NF;1362 break;1363 case SND_SOC_POSSIBLE_DAIFMT_NB_IF:1364 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_NB_IF;1365 break;1366 case SND_SOC_POSSIBLE_DAIFMT_IB_NF:1367 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_IB_NF;1368 break;1369 case SND_SOC_POSSIBLE_DAIFMT_IB_IF:1370 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_IB_IF;1371 break;1372 /*1373 * for clock provider / consumer1374 */1375 case SND_SOC_POSSIBLE_DAIFMT_CBP_CFP:1376 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBP_CFP;1377 break;1378 case SND_SOC_POSSIBLE_DAIFMT_CBC_CFP:1379 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBC_CFP;1380 break;1381 case SND_SOC_POSSIBLE_DAIFMT_CBP_CFC:1382 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBP_CFC;1383 break;1384 case SND_SOC_POSSIBLE_DAIFMT_CBC_CFC:1385 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBC_CFC;1386 break;1387 }1388 }1389 1390 /*1391 * Some driver might have very complex limitation.1392 * In such case, user want to auto-select non-limitation part,1393 * and want to manually specify complex part.1394 *1395 * Or for example, if both CPU and Codec can be clock provider,1396 * but because of its quality, user want to specify it manually.1397 *1398 * Use manually specified settings if sound card did.1399 */1400 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK))1401 mask |= SND_SOC_DAIFMT_FORMAT_MASK;1402 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_CLOCK_MASK))1403 mask |= SND_SOC_DAIFMT_CLOCK_MASK;1404 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_INV_MASK))1405 mask |= SND_SOC_DAIFMT_INV_MASK;1406 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK))1407 mask |= SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;1408 1409 dai_link->dai_fmt |= (dai_fmt & mask);1410}1411 1412/**1413 * snd_soc_runtime_set_dai_fmt() - Change DAI link format for a ASoC runtime1414 * @rtd: The runtime for which the DAI link format should be changed1415 * @dai_fmt: The new DAI link format1416 *1417 * This function updates the DAI link format for all DAIs connected to the DAI1418 * link for the specified runtime.1419 *1420 * Note: For setups with a static format set the dai_fmt field in the1421 * corresponding snd_dai_link struct instead of using this function.1422 *1423 * Returns 0 on success, otherwise a negative error code.1424 */1425int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,1426 unsigned int dai_fmt)1427{1428 struct snd_soc_dai *cpu_dai;1429 struct snd_soc_dai *codec_dai;1430 unsigned int i;1431 int ret;1432 1433 if (!dai_fmt)1434 return 0;1435 1436 for_each_rtd_codec_dais(rtd, i, codec_dai) {1437 ret = snd_soc_dai_set_fmt(codec_dai, dai_fmt);1438 if (ret != 0 && ret != -ENOTSUPP)1439 return ret;1440 }1441 1442 /* Flip the polarity for the "CPU" end of link */1443 dai_fmt = snd_soc_daifmt_clock_provider_flipped(dai_fmt);1444 1445 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {1446 ret = snd_soc_dai_set_fmt(cpu_dai, dai_fmt);1447 if (ret != 0 && ret != -ENOTSUPP)1448 return ret;1449 }1450 1451 return 0;1452}1453EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt);1454 1455static int soc_init_pcm_runtime(struct snd_soc_card *card,1456 struct snd_soc_pcm_runtime *rtd)1457{1458 struct snd_soc_dai_link *dai_link = rtd->dai_link;1459 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);1460 struct snd_soc_component *component;1461 int ret, num, i;1462 1463 /* do machine specific initialization */1464 ret = snd_soc_link_init(rtd);1465 if (ret < 0)1466 return ret;1467 1468 snd_soc_runtime_get_dai_fmt(rtd);1469 ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);1470 if (ret)1471 goto err;1472 1473 /* add DPCM sysfs entries */1474 soc_dpcm_debugfs_add(rtd);1475 1476 num = rtd->num;1477 1478 /*1479 * most drivers will register their PCMs using DAI link ordering but1480 * topology based drivers can use the DAI link id field to set PCM1481 * device number and then use rtd + a base offset of the BEs.1482 */1483 for_each_rtd_components(rtd, i, component) {1484 if (!component->driver->use_dai_pcm_id)1485 continue;1486 1487 if (rtd->dai_link->no_pcm)1488 num += component->driver->be_pcm_base;1489 else1490 num = rtd->dai_link->id;1491 }1492 1493 /* create compress_device if possible */1494 ret = snd_soc_dai_compress_new(cpu_dai, rtd, num);1495 if (ret != -ENOTSUPP)1496 goto err;1497 1498 /* create the pcm */1499 ret = soc_new_pcm(rtd, num);1500 if (ret < 0) {1501 dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",1502 dai_link->stream_name, ret);1503 goto err;1504 }1505 1506 ret = snd_soc_pcm_dai_new(rtd);1507 if (ret < 0)1508 goto err;1509 1510 rtd->initialized = true;1511 1512 return 0;1513err:1514 snd_soc_link_exit(rtd);1515 return ret;1516}1517 1518static void soc_set_name_prefix(struct snd_soc_card *card,1519 struct snd_soc_component *component)1520{1521 struct device_node *of_node = soc_component_to_node(component);1522 const char *str;1523 int ret, i;1524 1525 for (i = 0; i < card->num_configs; i++) {1526 struct snd_soc_codec_conf *map = &card->codec_conf[i];1527 1528 if (snd_soc_is_matching_component(&map->dlc, component) &&1529 map->name_prefix) {1530 component->name_prefix = map->name_prefix;1531 return;1532 }1533 }1534 1535 /*1536 * If there is no configuration table or no match in the table,1537 * check if a prefix is provided in the node1538 */1539 ret = of_property_read_string(of_node, "sound-name-prefix", &str);1540 if (ret < 0)1541 return;1542 1543 component->name_prefix = str;1544}1545 1546static void soc_remove_component(struct snd_soc_component *component,1547 int probed)1548{1549 1550 if (!component->card)1551 return;1552 1553 if (probed)1554 snd_soc_component_remove(component);1555 1556 list_del_init(&component->card_list);1557 snd_soc_dapm_free(snd_soc_component_get_dapm(component));1558 soc_cleanup_component_debugfs(component);1559 component->card = NULL;1560 snd_soc_component_module_put_when_remove(component);1561}1562 1563static int soc_probe_component(struct snd_soc_card *card,1564 struct snd_soc_component *component)1565{1566 struct snd_soc_dapm_context *dapm =1567 snd_soc_component_get_dapm(component);1568 struct snd_soc_dai *dai;1569 int probed = 0;1570 int ret;1571 1572 if (snd_soc_component_is_dummy(component))1573 return 0;1574 1575 if (component->card) {1576 if (component->card != card) {1577 dev_err(component->dev,1578 "Trying to bind component \"%s\" to card \"%s\" but is already bound to card \"%s\"\n",1579 component->name, card->name, component->card->name);1580 return -ENODEV;1581 }1582 return 0;1583 }1584 1585 ret = snd_soc_component_module_get_when_probe(component);1586 if (ret < 0)1587 return ret;1588 1589 component->card = card;1590 soc_set_name_prefix(card, component);1591 1592 soc_init_component_debugfs(component);1593 1594 snd_soc_dapm_init(dapm, card, component);1595 1596 ret = snd_soc_dapm_new_controls(dapm,1597 component->driver->dapm_widgets,1598 component->driver->num_dapm_widgets);1599 1600 if (ret != 0) {1601 dev_err(component->dev,1602 "Failed to create new controls %d\n", ret);1603 goto err_probe;1604 }1605 1606 for_each_component_dais(component, dai) {1607 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);1608 if (ret != 0) {1609 dev_err(component->dev,1610 "Failed to create DAI widgets %d\n", ret);1611 goto err_probe;1612 }1613 }1614 1615 ret = snd_soc_component_probe(component);1616 if (ret < 0)1617 goto err_probe;1618 1619 WARN(dapm->idle_bias_off &&1620 dapm->bias_level != SND_SOC_BIAS_OFF,1621 "codec %s can not start from non-off bias with idle_bias_off==1\n",1622 component->name);1623 probed = 1;1624 1625 /*1626 * machine specific init1627 * see1628 * snd_soc_component_set_aux()1629 */1630 ret = snd_soc_component_init(component);1631 if (ret < 0)1632 goto err_probe;1633 1634 ret = snd_soc_add_component_controls(component,1635 component->driver->controls,1636 component->driver->num_controls);1637 if (ret < 0)1638 goto err_probe;1639 1640 ret = snd_soc_dapm_add_routes(dapm,1641 component->driver->dapm_routes,1642 component->driver->num_dapm_routes);1643 if (ret < 0) {1644 if (card->disable_route_checks) {1645 dev_info(card->dev,1646 "%s: disable_route_checks set, ignoring errors on add_routes\n",1647 __func__);1648 } else {1649 dev_err(card->dev,1650 "%s: snd_soc_dapm_add_routes failed: %d\n",1651 __func__, ret);1652 goto err_probe;1653 }1654 }1655 1656 /* see for_each_card_components */1657 list_add(&component->card_list, &card->component_dev_list);1658 1659err_probe:1660 if (ret < 0)1661 soc_remove_component(component, probed);1662 1663 return ret;1664}1665 1666static void soc_remove_link_dais(struct snd_soc_card *card)1667{1668 struct snd_soc_pcm_runtime *rtd;1669 int order;1670 1671 for_each_comp_order(order) {1672 for_each_card_rtds(card, rtd) {1673 /* remove all rtd connected DAIs in good order */1674 snd_soc_pcm_dai_remove(rtd, order);1675 }1676 }1677}1678 1679static int soc_probe_link_dais(struct snd_soc_card *card)1680{1681 struct snd_soc_pcm_runtime *rtd;1682 int order, ret;1683 1684 for_each_comp_order(order) {1685 for_each_card_rtds(card, rtd) {1686 /* probe all rtd connected DAIs in good order */1687 ret = snd_soc_pcm_dai_probe(rtd, order);1688 if (ret)1689 return ret;1690 }1691 }1692 1693 return 0;1694}1695 1696static void soc_remove_link_components(struct snd_soc_card *card)1697{1698 struct snd_soc_component *component;1699 struct snd_soc_pcm_runtime *rtd;1700 int i, order;1701 1702 for_each_comp_order(order) {1703 for_each_card_rtds(card, rtd) {1704 for_each_rtd_components(rtd, i, component) {1705 if (component->driver->remove_order != order)1706 continue;1707 1708 soc_remove_component(component, 1);1709 }1710 }1711 }1712}1713 1714static int soc_probe_link_components(struct snd_soc_card *card)1715{1716 struct snd_soc_component *component;1717 struct snd_soc_pcm_runtime *rtd;1718 int i, ret, order;1719 1720 for_each_comp_order(order) {1721 for_each_card_rtds(card, rtd) {1722 for_each_rtd_components(rtd, i, component) {1723 if (component->driver->probe_order != order)1724 continue;1725 1726 ret = soc_probe_component(card, component);1727 if (ret < 0)1728 return ret;1729 }1730 }1731 }1732 1733 return 0;1734}1735 1736static void soc_unbind_aux_dev(struct snd_soc_card *card)1737{1738 struct snd_soc_component *component, *_component;1739 1740 for_each_card_auxs_safe(card, component, _component) {1741 /* for snd_soc_component_init() */1742 snd_soc_component_set_aux(component, NULL);1743 list_del(&component->card_aux_list);1744 }1745}1746 1747static int soc_bind_aux_dev(struct snd_soc_card *card)1748{1749 struct snd_soc_component *component;1750 struct snd_soc_aux_dev *aux;1751 int i;1752 1753 for_each_card_pre_auxs(card, i, aux) {1754 /* codecs, usually analog devices */1755 component = soc_find_component(&aux->dlc);1756 if (!component)1757 return -EPROBE_DEFER;1758 1759 /* for snd_soc_component_init() */1760 snd_soc_component_set_aux(component, aux);1761 /* see for_each_card_auxs */1762 list_add(&component->card_aux_list, &card->aux_comp_list);1763 }1764 return 0;1765}1766 1767static int soc_probe_aux_devices(struct snd_soc_card *card)1768{1769 struct snd_soc_component *component;1770 int order;1771 int ret;1772 1773 for_each_comp_order(order) {1774 for_each_card_auxs(card, component) {1775 if (component->driver->probe_order != order)1776 continue;1777 1778 ret = soc_probe_component(card, component);1779 if (ret < 0)1780 return ret;1781 }1782 }1783 1784 return 0;1785}1786 1787static void soc_remove_aux_devices(struct snd_soc_card *card)1788{1789 struct snd_soc_component *comp, *_comp;1790 int order;1791 1792 for_each_comp_order(order) {1793 for_each_card_auxs_safe(card, comp, _comp) {1794 if (comp->driver->remove_order == order)1795 soc_remove_component(comp, 1);1796 }1797 }1798}1799 1800#ifdef CONFIG_DMI1801/*1802 * If a DMI filed contain strings in this blacklist (e.g.1803 * "Type2 - Board Manufacturer" or "Type1 - TBD by OEM"), it will be taken1804 * as invalid and dropped when setting the card long name from DMI info.1805 */1806static const char * const dmi_blacklist[] = {1807 "To be filled by OEM",1808 "TBD by OEM",1809 "Default String",1810 "Board Manufacturer",1811 "Board Vendor Name",1812 "Board Product Name",1813 NULL, /* terminator */1814};1815 1816/*1817 * Trim special characters, and replace '-' with '_' since '-' is used to1818 * separate different DMI fields in the card long name. Only number and1819 * alphabet characters and a few separator characters are kept.1820 */1821static void cleanup_dmi_name(char *name)1822{1823 int i, j = 0;1824 1825 for (i = 0; name[i]; i++) {1826 if (isalnum(name[i]) || (name[i] == '.')1827 || (name[i] == '_'))1828 name[j++] = name[i];1829 else if (name[i] == '-')1830 name[j++] = '_';1831 }1832 1833 name[j] = '\0';1834}1835 1836/*1837 * Check if a DMI field is valid, i.e. not containing any string1838 * in the black list.1839 */1840static int is_dmi_valid(const char *field)1841{1842 int i = 0;1843 1844 while (dmi_blacklist[i]) {1845 if (strstr(field, dmi_blacklist[i]))1846 return 0;1847 i++;1848 }1849 1850 return 1;1851}1852 1853/*1854 * Append a string to card->dmi_longname with character cleanups.1855 */1856static void append_dmi_string(struct snd_soc_card *card, const char *str)1857{1858 char *dst = card->dmi_longname;1859 size_t dst_len = sizeof(card->dmi_longname);1860 size_t len;1861 1862 len = strlen(dst);1863 snprintf(dst + len, dst_len - len, "-%s", str);1864 1865 len++; /* skip the separator "-" */1866 if (len < dst_len)1867 cleanup_dmi_name(dst + len);1868}1869 1870/**1871 * snd_soc_set_dmi_name() - Register DMI names to card1872 * @card: The card to register DMI names1873 * @flavour: The flavour "differentiator" for the card amongst its peers.1874 *1875 * An Intel machine driver may be used by many different devices but are1876 * difficult for userspace to differentiate, since machine drivers usually1877 * use their own name as the card short name and leave the card long name1878 * blank. To differentiate such devices and fix bugs due to lack of1879 * device-specific configurations, this function allows DMI info to be used1880 * as the sound card long name, in the format of1881 * "vendor-product-version-board"1882 * (Character '-' is used to separate different DMI fields here).1883 * This will help the user space to load the device-specific Use Case Manager1884 * (UCM) configurations for the card.1885 *1886 * Possible card long names may be:1887 * DellInc.-XPS139343-01-0310JH1888 * ASUSTeKCOMPUTERINC.-T100TA-1.0-T100TA1889 * Circuitco-MinnowboardMaxD0PLATFORM-D0-MinnowBoardMAX1890 *1891 * This function also supports flavoring the card longname to provide1892 * the extra differentiation, like "vendor-product-version-board-flavor".1893 *1894 * We only keep number and alphabet characters and a few separator characters1895 * in the card long name since UCM in the user space uses the card long names1896 * as card configuration directory names and AudoConf cannot support special1897 * characters like SPACE.1898 *1899 * Returns 0 on success, otherwise a negative error code.1900 */1901int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)1902{1903 const char *vendor, *product, *board;1904 1905 if (card->long_name)1906 return 0; /* long name already set by driver or from DMI */1907 1908 if (!dmi_available)1909 return 0;1910 1911 /* make up dmi long name as: vendor-product-version-board */1912 vendor = dmi_get_system_info(DMI_BOARD_VENDOR);1913 if (!vendor || !is_dmi_valid(vendor)) {1914 dev_warn(card->dev, "ASoC: no DMI vendor name!\n");1915 return 0;1916 }1917 1918 snprintf(card->dmi_longname, sizeof(card->dmi_longname), "%s", vendor);1919 cleanup_dmi_name(card->dmi_longname);1920 1921 product = dmi_get_system_info(DMI_PRODUCT_NAME);1922 if (product && is_dmi_valid(product)) {1923 const char *product_version = dmi_get_system_info(DMI_PRODUCT_VERSION);1924 1925 append_dmi_string(card, product);1926 1927 /*1928 * some vendors like Lenovo may only put a self-explanatory1929 * name in the product version field1930 */1931 if (product_version && is_dmi_valid(product_version))1932 append_dmi_string(card, product_version);1933 }1934 1935 board = dmi_get_system_info(DMI_BOARD_NAME);1936 if (board && is_dmi_valid(board)) {1937 if (!product || strcasecmp(board, product))1938 append_dmi_string(card, board);1939 } else if (!product) {1940 /* fall back to using legacy name */1941 dev_warn(card->dev, "ASoC: no DMI board/product name!\n");1942 return 0;1943 }1944 1945 /* Add flavour to dmi long name */1946 if (flavour)1947 append_dmi_string(card, flavour);1948 1949 /* set the card long name */1950 card->long_name = card->dmi_longname;1951 1952 return 0;1953}1954EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name);1955#endif /* CONFIG_DMI */1956 1957static void soc_check_tplg_fes(struct snd_soc_card *card)1958{1959 struct snd_soc_component *component;1960 const struct snd_soc_component_driver *comp_drv;1961 struct snd_soc_dai_link *dai_link;1962 int i;1963 1964 for_each_component(component) {1965 1966 /* does this component override BEs ? */1967 if (!component->driver->ignore_machine)1968 continue;1969 1970 /* for this machine ? */1971 if (!strcmp(component->driver->ignore_machine,1972 card->dev->driver->name))1973 goto match;1974 if (strcmp(component->driver->ignore_machine,1975 dev_name(card->dev)))1976 continue;1977match:1978 /* machine matches, so override the rtd data */1979 for_each_card_prelinks(card, i, dai_link) {1980 1981 /* ignore this FE */1982 if (dai_link->dynamic) {1983 dai_link->ignore = true;1984 continue;1985 }1986 1987 dev_dbg(card->dev, "info: override BE DAI link %s\n",1988 card->dai_link[i].name);1989 1990 /* override platform component */1991 if (!dai_link->platforms) {1992 dev_err(card->dev, "init platform error");1993 continue;1994 }1995 1996 if (component->dev->of_node)1997 dai_link->platforms->of_node = component->dev->of_node;1998 else1999 dai_link->platforms->name = component->name;2000 2001 /* convert non BE into BE */2002 if (!dai_link->no_pcm) {2003 dai_link->no_pcm = 1;2004 2005 if (dai_link->dpcm_playback)2006 dev_warn(card->dev,2007 "invalid configuration, dailink %s has flags no_pcm=0 and dpcm_playback=1\n",2008 dai_link->name);2009 if (dai_link->dpcm_capture)2010 dev_warn(card->dev,2011 "invalid configuration, dailink %s has flags no_pcm=0 and dpcm_capture=1\n",2012 dai_link->name);2013 2014 /* convert normal link into DPCM one */2015 if (!(dai_link->dpcm_playback ||2016 dai_link->dpcm_capture)) {2017 dai_link->dpcm_playback = !dai_link->capture_only;2018 dai_link->dpcm_capture = !dai_link->playback_only;2019 }2020 }2021 2022 /*2023 * override any BE fixups2024 * see2025 * snd_soc_link_be_hw_params_fixup()2026 */2027 dai_link->be_hw_params_fixup =2028 component->driver->be_hw_params_fixup;2029 2030 /*2031 * most BE links don't set stream name, so set it to2032 * dai link name if it's NULL to help bind widgets.2033 */2034 if (!dai_link->stream_name)2035 dai_link->stream_name = dai_link->name;2036 }2037 2038 /* Inform userspace we are using alternate topology */2039 if (component->driver->topology_name_prefix) {2040 2041 /* topology shortname created? */2042 if (!card->topology_shortname_created) {2043 comp_drv = component->driver;2044 2045 snprintf(card->topology_shortname, 32, "%s-%s",2046 comp_drv->topology_name_prefix,2047 card->name);2048 card->topology_shortname_created = true;2049 }2050 2051 /* use topology shortname */2052 card->name = card->topology_shortname;2053 }2054 }2055}2056 2057#define soc_setup_card_name(card, name, name1, name2) \2058 __soc_setup_card_name(card, name, sizeof(name), name1, name2)2059static void __soc_setup_card_name(struct snd_soc_card *card,2060 char *name, int len,2061 const char *name1, const char *name2)2062{2063 const char *src = name1 ? name1 : name2;2064 int i;2065 2066 snprintf(name, len, "%s", src);2067 2068 if (name != card->snd_card->driver)2069 return;2070 2071 /*2072 * Name normalization (driver field)2073 *2074 * The driver name is somewhat special, as it's used as a key for2075 * searches in the user-space.2076 *2077 * ex)2078 * "abcd??efg" -> "abcd__efg"2079 */2080 for (i = 0; i < len; i++) {2081 switch (name[i]) {2082 case '_':2083 case '-':2084 case '\0':2085 break;2086 default:2087 if (!isalnum(name[i]))2088 name[i] = '_';2089 break;2090 }2091 }2092 2093 /*2094 * The driver field should contain a valid string from the user view.2095 * The wrapping usually does not work so well here. Set a smaller string2096 * in the specific ASoC driver.2097 */2098 if (strlen(src) > len - 1)2099 dev_err(card->dev, "ASoC: driver name too long '%s' -> '%s'\n", src, name);2100}2101 2102static void soc_cleanup_card_resources(struct snd_soc_card *card)2103{2104 struct snd_soc_pcm_runtime *rtd, *n;2105 2106 if (card->snd_card)2107 snd_card_disconnect_sync(card->snd_card);2108 2109 snd_soc_dapm_shutdown(card);2110 2111 /* release machine specific resources */2112 for_each_card_rtds(card, rtd)2113 if (rtd->initialized)2114 snd_soc_link_exit(rtd);2115 /* remove and free each DAI */2116 soc_remove_link_dais(card);2117 soc_remove_link_components(card);2118 2119 for_each_card_rtds_safe(card, rtd, n)2120 snd_soc_remove_pcm_runtime(card, rtd);2121 2122 /* remove auxiliary devices */2123 soc_remove_aux_devices(card);2124 soc_unbind_aux_dev(card);2125 2126 snd_soc_dapm_free(&card->dapm);2127 soc_cleanup_card_debugfs(card);2128 2129 /* remove the card */2130 snd_soc_card_remove(card);2131 2132 if (card->snd_card) {2133 snd_card_free(card->snd_card);2134 card->snd_card = NULL;2135 }2136}2137 2138static void snd_soc_unbind_card(struct snd_soc_card *card, bool unregister)2139{2140 if (snd_soc_card_is_instantiated(card)) {2141 card->instantiated = false;2142 snd_soc_flush_all_delayed_work(card);2143 2144 soc_cleanup_card_resources(card);2145 if (!unregister)2146 list_add(&card->list, &unbind_card_list);2147 } else {2148 if (unregister)2149 list_del(&card->list);2150 }2151}2152 2153static int snd_soc_bind_card(struct snd_soc_card *card)2154{2155 struct snd_soc_pcm_runtime *rtd;2156 struct snd_soc_component *component;2157 int ret;2158 2159 mutex_lock(&client_mutex);2160 snd_soc_card_mutex_lock_root(card);2161 2162 snd_soc_fill_dummy_dai(card);2163 2164 snd_soc_dapm_init(&card->dapm, card, NULL);2165 2166 /* check whether any platform is ignore machine FE and using topology */2167 soc_check_tplg_fes(card);2168 2169 /* bind aux_devs too */2170 ret = soc_bind_aux_dev(card);2171 if (ret < 0)2172 goto probe_end;2173 2174 /* add predefined DAI links to the list */2175 card->num_rtd = 0;2176 ret = snd_soc_add_pcm_runtimes(card, card->dai_link, card->num_links);2177 if (ret < 0)2178 goto probe_end;2179 2180 /* card bind complete so register a sound card */2181 ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,2182 card->owner, 0, &card->snd_card);2183 if (ret < 0) {2184 dev_err(card->dev,2185 "ASoC: can't create sound card for card %s: %d\n",2186 card->name, ret);2187 goto probe_end;2188 }2189 2190 soc_init_card_debugfs(card);2191 2192 soc_resume_init(card);2193 2194 ret = snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,2195 card->num_dapm_widgets);2196 if (ret < 0)2197 goto probe_end;2198 2199 ret = snd_soc_dapm_new_controls(&card->dapm, card->of_dapm_widgets,2200 card->num_of_dapm_widgets);2201 if (ret < 0)2202 goto probe_end;2203 2204 /* initialise the sound card only once */2205 ret = snd_soc_card_probe(card);2206 if (ret < 0)2207 goto probe_end;2208 2209 /* probe all components used by DAI links on this card */2210 ret = soc_probe_link_components(card);2211 if (ret < 0) {2212 if (ret != -EPROBE_DEFER) {2213 dev_err(card->dev,2214 "ASoC: failed to instantiate card %d\n", ret);2215 }2216 goto probe_end;2217 }2218 2219 /* probe auxiliary components */2220 ret = soc_probe_aux_devices(card);2221 if (ret < 0) {2222 dev_err(card->dev,2223 "ASoC: failed to probe aux component %d\n", ret);2224 goto probe_end;2225 }2226 2227 /* probe all DAI links on this card */2228 ret = soc_probe_link_dais(card);2229 if (ret < 0) {2230 dev_err(card->dev,2231 "ASoC: failed to instantiate card %d\n", ret);2232 goto probe_end;2233 }2234 2235 for_each_card_rtds(card, rtd) {2236 ret = soc_init_pcm_runtime(card, rtd);2237 if (ret < 0)2238 goto probe_end;2239 }2240 2241 snd_soc_dapm_link_dai_widgets(card);2242 snd_soc_dapm_connect_dai_link_widgets(card);2243 2244 ret = snd_soc_add_card_controls(card, card->controls,2245 card->num_controls);2246 if (ret < 0)2247 goto probe_end;2248 2249 ret = snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,2250 card->num_dapm_routes);2251 if (ret < 0) {2252 if (card->disable_route_checks) {2253 dev_info(card->dev,2254 "%s: disable_route_checks set, ignoring errors on add_routes\n",2255 __func__);2256 } else {2257 dev_err(card->dev,2258 "%s: snd_soc_dapm_add_routes failed: %d\n",2259 __func__, ret);2260 goto probe_end;2261 }2262 }2263 2264 ret = snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes,2265 card->num_of_dapm_routes);2266 if (ret < 0)2267 goto probe_end;2268 2269 /* try to set some sane longname if DMI is available */2270 snd_soc_set_dmi_name(card, NULL);2271 2272 soc_setup_card_name(card, card->snd_card->shortname,2273 card->name, NULL);2274 soc_setup_card_name(card, card->snd_card->longname,2275 card->long_name, card->name);2276 soc_setup_card_name(card, card->snd_card->driver,2277 card->driver_name, card->name);2278 2279 if (card->components) {2280 /* the current implementation of snd_component_add() accepts */2281 /* multiple components in the string separated by space, */2282 /* but the string collision (identical string) check might */2283 /* not work correctly */2284 ret = snd_component_add(card->snd_card, card->components);2285 if (ret < 0) {2286 dev_err(card->dev, "ASoC: %s snd_component_add() failed: %d\n",2287 card->name, ret);2288 goto probe_end;2289 }2290 }2291 2292 ret = snd_soc_card_late_probe(card);2293 if (ret < 0)2294 goto probe_end;2295 2296 snd_soc_dapm_new_widgets(card);2297 snd_soc_card_fixup_controls(card);2298 2299 ret = snd_card_register(card->snd_card);2300 if (ret < 0) {2301 dev_err(card->dev, "ASoC: failed to register soundcard %d\n",2302 ret);2303 goto probe_end;2304 }2305 2306 card->instantiated = 1;2307 dapm_mark_endpoints_dirty(card);2308 snd_soc_dapm_sync(&card->dapm);2309 2310 /* deactivate pins to sleep state */2311 for_each_card_components(card, component)2312 if (!snd_soc_component_active(component))2313 pinctrl_pm_select_sleep_state(component->dev);2314 2315probe_end:2316 if (ret < 0)2317 soc_cleanup_card_resources(card);2318 2319 snd_soc_card_mutex_unlock(card);2320 mutex_unlock(&client_mutex);2321 2322 return ret;2323}2324 2325/* probes a new socdev */2326static int soc_probe(struct platform_device *pdev)2327{2328 struct snd_soc_card *card = platform_get_drvdata(pdev);2329 2330 /*2331 * no card, so machine driver should be registering card2332 * we should not be here in that case so ret error2333 */2334 if (!card)2335 return -EINVAL;2336 2337 dev_warn(&pdev->dev,2338 "ASoC: machine %s should use snd_soc_register_card()\n",2339 card->name);2340 2341 /* Bodge while we unpick instantiation */2342 card->dev = &pdev->dev;2343 2344 return devm_snd_soc_register_card(&pdev->dev, card);2345}2346 2347int snd_soc_poweroff(struct device *dev)2348{2349 struct snd_soc_card *card = dev_get_drvdata(dev);2350 struct snd_soc_component *component;2351 2352 if (!snd_soc_card_is_instantiated(card))2353 return 0;2354 2355 /*2356 * Flush out pmdown_time work - we actually do want to run it2357 * now, we're shutting down so no imminent restart.2358 */2359 snd_soc_flush_all_delayed_work(card);2360 2361 snd_soc_dapm_shutdown(card);2362 2363 /* deactivate pins to sleep state */2364 for_each_card_components(card, component)2365 pinctrl_pm_select_sleep_state(component->dev);2366 2367 return 0;2368}2369EXPORT_SYMBOL_GPL(snd_soc_poweroff);2370 2371const struct dev_pm_ops snd_soc_pm_ops = {2372 .suspend = snd_soc_suspend,2373 .resume = snd_soc_resume,2374 .freeze = snd_soc_suspend,2375 .thaw = snd_soc_resume,2376 .poweroff = snd_soc_poweroff,2377 .restore = snd_soc_resume,2378};2379EXPORT_SYMBOL_GPL(snd_soc_pm_ops);2380 2381/* ASoC platform driver */2382static struct platform_driver soc_driver = {2383 .driver = {2384 .name = "soc-audio",2385 .pm = &snd_soc_pm_ops,2386 },2387 .probe = soc_probe,2388};2389 2390/**2391 * snd_soc_cnew - create new control2392 * @_template: control template2393 * @data: control private data2394 * @long_name: control long name2395 * @prefix: control name prefix2396 *2397 * Create a new mixer control from a template control.2398 *2399 * Returns 0 for success, else error.2400 */2401struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,2402 void *data, const char *long_name,2403 const char *prefix)2404{2405 struct snd_kcontrol_new template;2406 struct snd_kcontrol *kcontrol;2407 char *name = NULL;2408 2409 memcpy(&template, _template, sizeof(template));2410 template.index = 0;2411 2412 if (!long_name)2413 long_name = template.name;2414 2415 if (prefix) {2416 name = kasprintf(GFP_KERNEL, "%s %s", prefix, long_name);2417 if (!name)2418 return NULL;2419 2420 template.name = name;2421 } else {2422 template.name = long_name;2423 }2424 2425 kcontrol = snd_ctl_new1(&template, data);2426 2427 kfree(name);2428 2429 return kcontrol;2430}2431EXPORT_SYMBOL_GPL(snd_soc_cnew);2432 2433static int snd_soc_add_controls(struct snd_card *card, struct device *dev,2434 const struct snd_kcontrol_new *controls, int num_controls,2435 const char *prefix, void *data)2436{2437 int i;2438 2439 for (i = 0; i < num_controls; i++) {2440 const struct snd_kcontrol_new *control = &controls[i];2441 int err = snd_ctl_add(card, snd_soc_cnew(control, data,2442 control->name, prefix));2443 if (err < 0) {2444 dev_err(dev, "ASoC: Failed to add %s: %d\n",2445 control->name, err);2446 return err;2447 }2448 }2449 2450 return 0;2451}2452 2453/**2454 * snd_soc_add_component_controls - Add an array of controls to a component.2455 *2456 * @component: Component to add controls to2457 * @controls: Array of controls to add2458 * @num_controls: Number of elements in the array2459 *2460 * Return: 0 for success, else error.2461 */2462int snd_soc_add_component_controls(struct snd_soc_component *component,2463 const struct snd_kcontrol_new *controls, unsigned int num_controls)2464{2465 struct snd_card *card = component->card->snd_card;2466 2467 return snd_soc_add_controls(card, component->dev, controls,2468 num_controls, component->name_prefix, component);2469}2470EXPORT_SYMBOL_GPL(snd_soc_add_component_controls);2471 2472/**2473 * snd_soc_add_card_controls - add an array of controls to a SoC card.2474 * Convenience function to add a list of controls.2475 *2476 * @soc_card: SoC card to add controls to2477 * @controls: array of controls to add2478 * @num_controls: number of elements in the array2479 *2480 * Return 0 for success, else error.2481 */2482int snd_soc_add_card_controls(struct snd_soc_card *soc_card,2483 const struct snd_kcontrol_new *controls, int num_controls)2484{2485 struct snd_card *card = soc_card->snd_card;2486 2487 return snd_soc_add_controls(card, soc_card->dev, controls, num_controls,2488 NULL, soc_card);2489}2490EXPORT_SYMBOL_GPL(snd_soc_add_card_controls);2491 2492/**2493 * snd_soc_add_dai_controls - add an array of controls to a DAI.2494 * Convenience function to add a list of controls.2495 *2496 * @dai: DAI to add controls to2497 * @controls: array of controls to add2498 * @num_controls: number of elements in the array2499 *2500 * Return 0 for success, else error.2501 */2502int snd_soc_add_dai_controls(struct snd_soc_dai *dai,2503 const struct snd_kcontrol_new *controls, int num_controls)2504{2505 struct snd_card *card = dai->component->card->snd_card;2506 2507 return snd_soc_add_controls(card, dai->dev, controls, num_controls,2508 NULL, dai);2509}2510EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);2511 2512/**2513 * snd_soc_register_card - Register a card with the ASoC core2514 *2515 * @card: Card to register2516 *2517 */2518int snd_soc_register_card(struct snd_soc_card *card)2519{2520 if (!card->name || !card->dev)2521 return -EINVAL;2522 2523 dev_set_drvdata(card->dev, card);2524 2525 INIT_LIST_HEAD(&card->widgets);2526 INIT_LIST_HEAD(&card->paths);2527 INIT_LIST_HEAD(&card->dapm_list);2528 INIT_LIST_HEAD(&card->aux_comp_list);2529 INIT_LIST_HEAD(&card->component_dev_list);2530 INIT_LIST_HEAD(&card->list);2531 INIT_LIST_HEAD(&card->rtd_list);2532 INIT_LIST_HEAD(&card->dapm_dirty);2533 INIT_LIST_HEAD(&card->dobj_list);2534 2535 card->instantiated = 0;2536 mutex_init(&card->mutex);2537 mutex_init(&card->dapm_mutex);2538 mutex_init(&card->pcm_mutex);2539 2540 return snd_soc_bind_card(card);2541}2542EXPORT_SYMBOL_GPL(snd_soc_register_card);2543 2544/**2545 * snd_soc_unregister_card - Unregister a card with the ASoC core2546 *2547 * @card: Card to unregister2548 *2549 */2550void snd_soc_unregister_card(struct snd_soc_card *card)2551{2552 mutex_lock(&client_mutex);2553 snd_soc_unbind_card(card, true);2554 mutex_unlock(&client_mutex);2555 dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name);2556}2557EXPORT_SYMBOL_GPL(snd_soc_unregister_card);2558 2559/*2560 * Simplify DAI link configuration by removing ".-1" from device names2561 * and sanitizing names.2562 */2563static char *fmt_single_name(struct device *dev, int *id)2564{2565 const char *devname = dev_name(dev);2566 char *found, *name;2567 unsigned int id1, id2;2568 2569 if (devname == NULL)2570 return NULL;2571 2572 name = devm_kstrdup(dev, devname, GFP_KERNEL);2573 if (!name)2574 return NULL;2575 2576 /* are we a "%s.%d" name (platform and SPI components) */2577 found = strstr(name, dev->driver->name);2578 if (found) {2579 /* get ID */2580 if (sscanf(&found[strlen(dev->driver->name)], ".%d", id) == 1) {2581 2582 /* discard ID from name if ID == -1 */2583 if (*id == -1)2584 found[strlen(dev->driver->name)] = '\0';2585 }2586 2587 /* I2C component devices are named "bus-addr" */2588 } else if (sscanf(name, "%x-%x", &id1, &id2) == 2) {2589 2590 /* create unique ID number from I2C addr and bus */2591 *id = ((id1 & 0xffff) << 16) + id2;2592 2593 devm_kfree(dev, name);2594 2595 /* sanitize component name for DAI link creation */2596 name = devm_kasprintf(dev, GFP_KERNEL, "%s.%s", dev->driver->name, devname);2597 } else {2598 *id = 0;2599 }2600 2601 return name;2602}2603 2604/*2605 * Simplify DAI link naming for single devices with multiple DAIs by removing2606 * any ".-1" and using the DAI name (instead of device name).2607 */2608static inline char *fmt_multiple_name(struct device *dev,2609 struct snd_soc_dai_driver *dai_drv)2610{2611 if (dai_drv->name == NULL) {2612 dev_err(dev,2613 "ASoC: error - multiple DAI %s registered with no name\n",2614 dev_name(dev));2615 return NULL;2616 }2617 2618 return devm_kstrdup(dev, dai_drv->name, GFP_KERNEL);2619}2620 2621void snd_soc_unregister_dai(struct snd_soc_dai *dai)2622{2623 dev_dbg(dai->dev, "ASoC: Unregistered DAI '%s'\n", dai->name);2624 list_del(&dai->list);2625}2626EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);2627 2628/**2629 * snd_soc_register_dai - Register a DAI dynamically & create its widgets2630 *2631 * @component: The component the DAIs are registered for2632 * @dai_drv: DAI driver to use for the DAI2633 * @legacy_dai_naming: if %true, use legacy single-name format;2634 * if %false, use multiple-name format;2635 *2636 * Topology can use this API to register DAIs when probing a component.2637 * These DAIs's widgets will be freed in the card cleanup and the DAIs2638 * will be freed in the component cleanup.2639 */2640struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,2641 struct snd_soc_dai_driver *dai_drv,2642 bool legacy_dai_naming)2643{2644 struct device *dev = component->dev;2645 struct snd_soc_dai *dai;2646 2647 lockdep_assert_held(&client_mutex);2648 2649 dai = devm_kzalloc(dev, sizeof(*dai), GFP_KERNEL);2650 if (dai == NULL)2651 return NULL;2652 2653 /*2654 * Back in the old days when we still had component-less DAIs,2655 * instead of having a static name, component-less DAIs would2656 * inherit the name of the parent device so it is possible to2657 * register multiple instances of the DAI. We still need to keep2658 * the same naming style even though those DAIs are not2659 * component-less anymore.2660 */2661 if (legacy_dai_naming &&2662 (dai_drv->id == 0 || dai_drv->name == NULL)) {2663 dai->name = fmt_single_name(dev, &dai->id);2664 } else {2665 dai->name = fmt_multiple_name(dev, dai_drv);2666 if (dai_drv->id)2667 dai->id = dai_drv->id;2668 else2669 dai->id = component->num_dai;2670 }2671 if (!dai->name)2672 return NULL;2673 2674 dai->component = component;2675 dai->dev = dev;2676 dai->driver = dai_drv;2677 2678 /* see for_each_component_dais */2679 list_add_tail(&dai->list, &component->dai_list);2680 component->num_dai++;2681 2682 dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);2683 return dai;2684}2685EXPORT_SYMBOL_GPL(snd_soc_register_dai);2686 2687/**2688 * snd_soc_unregister_dais - Unregister DAIs from the ASoC core2689 *2690 * @component: The component for which the DAIs should be unregistered2691 */2692static void snd_soc_unregister_dais(struct snd_soc_component *component)2693{2694 struct snd_soc_dai *dai, *_dai;2695 2696 for_each_component_dais_safe(component, dai, _dai)2697 snd_soc_unregister_dai(dai);2698}2699 2700/**2701 * snd_soc_register_dais - Register a DAI with the ASoC core2702 *2703 * @component: The component the DAIs are registered for2704 * @dai_drv: DAI driver to use for the DAIs2705 * @count: Number of DAIs2706 */2707static int snd_soc_register_dais(struct snd_soc_component *component,2708 struct snd_soc_dai_driver *dai_drv,2709 size_t count)2710{2711 struct snd_soc_dai *dai;2712 unsigned int i;2713 int ret;2714 2715 for (i = 0; i < count; i++) {2716 dai = snd_soc_register_dai(component, dai_drv + i, count == 1 &&2717 component->driver->legacy_dai_naming);2718 if (dai == NULL) {2719 ret = -ENOMEM;2720 goto err;2721 }2722 }2723 2724 return 0;2725 2726err:2727 snd_soc_unregister_dais(component);2728 2729 return ret;2730}2731 2732#define ENDIANNESS_MAP(name) \2733 (SNDRV_PCM_FMTBIT_##name##LE | SNDRV_PCM_FMTBIT_##name##BE)2734static u64 endianness_format_map[] = {2735 ENDIANNESS_MAP(S16_),2736 ENDIANNESS_MAP(U16_),2737 ENDIANNESS_MAP(S24_),2738 ENDIANNESS_MAP(U24_),2739 ENDIANNESS_MAP(S32_),2740 ENDIANNESS_MAP(U32_),2741 ENDIANNESS_MAP(S24_3),2742 ENDIANNESS_MAP(U24_3),2743 ENDIANNESS_MAP(S20_3),2744 ENDIANNESS_MAP(U20_3),2745 ENDIANNESS_MAP(S18_3),2746 ENDIANNESS_MAP(U18_3),2747 ENDIANNESS_MAP(FLOAT_),2748 ENDIANNESS_MAP(FLOAT64_),2749 ENDIANNESS_MAP(IEC958_SUBFRAME_),2750};2751 2752/*2753 * Fix up the DAI formats for endianness: codecs don't actually see2754 * the endianness of the data but we're using the CPU format2755 * definitions which do need to include endianness so we ensure that2756 * codec DAIs always have both big and little endian variants set.2757 */2758static void convert_endianness_formats(struct snd_soc_pcm_stream *stream)2759{2760 int i;2761 2762 for (i = 0; i < ARRAY_SIZE(endianness_format_map); i++)2763 if (stream->formats & endianness_format_map[i])2764 stream->formats |= endianness_format_map[i];2765}2766 2767static void snd_soc_try_rebind_card(void)2768{2769 struct snd_soc_card *card, *c;2770 2771 list_for_each_entry_safe(card, c, &unbind_card_list, list)2772 if (!snd_soc_bind_card(card))2773 list_del(&card->list);2774}2775 2776static void snd_soc_del_component_unlocked(struct snd_soc_component *component)2777{2778 struct snd_soc_card *card = component->card;2779 2780 snd_soc_unregister_dais(component);2781 2782 if (card)2783 snd_soc_unbind_card(card, false);2784 2785 list_del(&component->list);2786}2787 2788int snd_soc_component_initialize(struct snd_soc_component *component,2789 const struct snd_soc_component_driver *driver,2790 struct device *dev)2791{2792 INIT_LIST_HEAD(&component->dai_list);2793 INIT_LIST_HEAD(&component->dobj_list);2794 INIT_LIST_HEAD(&component->card_list);2795 INIT_LIST_HEAD(&component->list);2796 mutex_init(&component->io_mutex);2797 2798 if (!component->name) {2799 component->name = fmt_single_name(dev, &component->id);2800 if (!component->name) {2801 dev_err(dev, "ASoC: Failed to allocate name\n");2802 return -ENOMEM;2803 }2804 }2805 2806 component->dev = dev;2807 component->driver = driver;2808 2809#ifdef CONFIG_DEBUG_FS2810 if (!component->debugfs_prefix)2811 component->debugfs_prefix = driver->debugfs_prefix;2812#endif2813 2814 return 0;2815}2816EXPORT_SYMBOL_GPL(snd_soc_component_initialize);2817 2818int snd_soc_add_component(struct snd_soc_component *component,2819 struct snd_soc_dai_driver *dai_drv,2820 int num_dai)2821{2822 int ret;2823 int i;2824 2825 mutex_lock(&client_mutex);2826 2827 if (component->driver->endianness) {2828 for (i = 0; i < num_dai; i++) {2829 convert_endianness_formats(&dai_drv[i].playback);2830 convert_endianness_formats(&dai_drv[i].capture);2831 }2832 }2833 2834 ret = snd_soc_register_dais(component, dai_drv, num_dai);2835 if (ret < 0) {2836 dev_err(component->dev, "ASoC: Failed to register DAIs: %d\n",2837 ret);2838 goto err_cleanup;2839 }2840 2841 if (!component->driver->write && !component->driver->read) {2842 if (!component->regmap)2843 component->regmap = dev_get_regmap(component->dev,2844 NULL);2845 if (component->regmap)2846 snd_soc_component_setup_regmap(component);2847 }2848 2849 /* see for_each_component */2850 list_add(&component->list, &component_list);2851 2852err_cleanup:2853 if (ret < 0)2854 snd_soc_del_component_unlocked(component);2855 2856 mutex_unlock(&client_mutex);2857 2858 if (ret == 0)2859 snd_soc_try_rebind_card();2860 2861 return ret;2862}2863EXPORT_SYMBOL_GPL(snd_soc_add_component);2864 2865int snd_soc_register_component(struct device *dev,2866 const struct snd_soc_component_driver *component_driver,2867 struct snd_soc_dai_driver *dai_drv,2868 int num_dai)2869{2870 struct snd_soc_component *component;2871 int ret;2872 2873 component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL);2874 if (!component)2875 return -ENOMEM;2876 2877 ret = snd_soc_component_initialize(component, component_driver, dev);2878 if (ret < 0)2879 return ret;2880 2881 return snd_soc_add_component(component, dai_drv, num_dai);2882}2883EXPORT_SYMBOL_GPL(snd_soc_register_component);2884 2885/**2886 * snd_soc_unregister_component_by_driver - Unregister component using a given driver2887 * from the ASoC core2888 *2889 * @dev: The device to unregister2890 * @component_driver: The component driver to unregister2891 */2892void snd_soc_unregister_component_by_driver(struct device *dev,2893 const struct snd_soc_component_driver *component_driver)2894{2895 struct snd_soc_component *component;2896 2897 if (!component_driver)2898 return;2899 2900 mutex_lock(&client_mutex);2901 component = snd_soc_lookup_component_nolocked(dev, component_driver->name);2902 if (!component)2903 goto out;2904 2905 snd_soc_del_component_unlocked(component);2906 2907out:2908 mutex_unlock(&client_mutex);2909}2910EXPORT_SYMBOL_GPL(snd_soc_unregister_component_by_driver);2911 2912/**2913 * snd_soc_unregister_component - Unregister all related component2914 * from the ASoC core2915 *2916 * @dev: The device to unregister2917 */2918void snd_soc_unregister_component(struct device *dev)2919{2920 mutex_lock(&client_mutex);2921 while (1) {2922 struct snd_soc_component *component = snd_soc_lookup_component_nolocked(dev, NULL);2923 2924 if (!component)2925 break;2926 2927 snd_soc_del_component_unlocked(component);2928 }2929 mutex_unlock(&client_mutex);2930}2931EXPORT_SYMBOL_GPL(snd_soc_unregister_component);2932 2933/* Retrieve a card's name from device tree */2934int snd_soc_of_parse_card_name(struct snd_soc_card *card,2935 const char *propname)2936{2937 struct device_node *np;2938 int ret;2939 2940 if (!card->dev) {2941 pr_err("card->dev is not set before calling %s\n", __func__);2942 return -EINVAL;2943 }2944 2945 np = card->dev->of_node;2946 2947 ret = of_property_read_string_index(np, propname, 0, &card->name);2948 /*2949 * EINVAL means the property does not exist. This is fine providing2950 * card->name was previously set, which is checked later in2951 * snd_soc_register_card.2952 */2953 if (ret < 0 && ret != -EINVAL) {2954 dev_err(card->dev,2955 "ASoC: Property '%s' could not be read: %d\n",2956 propname, ret);2957 return ret;2958 }2959 2960 return 0;2961}2962EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);2963 2964static const struct snd_soc_dapm_widget simple_widgets[] = {2965 SND_SOC_DAPM_MIC("Microphone", NULL),2966 SND_SOC_DAPM_LINE("Line", NULL),2967 SND_SOC_DAPM_HP("Headphone", NULL),2968 SND_SOC_DAPM_SPK("Speaker", NULL),2969};2970 2971int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,2972 const char *propname)2973{2974 struct device_node *np = card->dev->of_node;2975 struct snd_soc_dapm_widget *widgets;2976 const char *template, *wname;2977 int i, j, num_widgets;2978 2979 num_widgets = of_property_count_strings(np, propname);2980 if (num_widgets < 0) {2981 dev_err(card->dev,2982 "ASoC: Property '%s' does not exist\n", propname);2983 return -EINVAL;2984 }2985 if (!num_widgets) {2986 dev_err(card->dev, "ASoC: Property '%s's length is zero\n",2987 propname);2988 return -EINVAL;2989 }2990 if (num_widgets & 1) {2991 dev_err(card->dev,2992 "ASoC: Property '%s' length is not even\n", propname);2993 return -EINVAL;2994 }2995 2996 num_widgets /= 2;2997 2998 widgets = devm_kcalloc(card->dev, num_widgets, sizeof(*widgets),2999 GFP_KERNEL);3000 if (!widgets) {3001 dev_err(card->dev,3002 "ASoC: Could not allocate memory for widgets\n");3003 return -ENOMEM;3004 }3005 3006 for (i = 0; i < num_widgets; i++) {3007 int ret = of_property_read_string_index(np, propname,3008 2 * i, &template);3009 if (ret) {3010 dev_err(card->dev,3011 "ASoC: Property '%s' index %d read error:%d\n",3012 propname, 2 * i, ret);3013 return -EINVAL;3014 }3015 3016 for (j = 0; j < ARRAY_SIZE(simple_widgets); j++) {3017 if (!strncmp(template, simple_widgets[j].name,3018 strlen(simple_widgets[j].name))) {3019 widgets[i] = simple_widgets[j];3020 break;3021 }3022 }3023 3024 if (j >= ARRAY_SIZE(simple_widgets)) {3025 dev_err(card->dev,3026 "ASoC: DAPM widget '%s' is not supported\n",3027 template);3028 return -EINVAL;3029 }3030 3031 ret = of_property_read_string_index(np, propname,3032 (2 * i) + 1,3033 &wname);3034 if (ret) {3035 dev_err(card->dev,3036 "ASoC: Property '%s' index %d read error:%d\n",3037 propname, (2 * i) + 1, ret);3038 return -EINVAL;3039 }3040 3041 widgets[i].name = wname;3042 }3043 3044 card->of_dapm_widgets = widgets;3045 card->num_of_dapm_widgets = num_widgets;3046 3047 return 0;3048}3049EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);3050 3051int snd_soc_of_parse_pin_switches(struct snd_soc_card *card, const char *prop)3052{3053 const unsigned int nb_controls_max = 16;3054 const char **strings, *control_name;3055 struct snd_kcontrol_new *controls;3056 struct device *dev = card->dev;3057 unsigned int i, nb_controls;3058 int ret;3059 3060 if (!of_property_read_bool(dev->of_node, prop))3061 return 0;3062 3063 strings = devm_kcalloc(dev, nb_controls_max,3064 sizeof(*strings), GFP_KERNEL);3065 if (!strings)3066 return -ENOMEM;3067 3068 ret = of_property_read_string_array(dev->of_node, prop,3069 strings, nb_controls_max);3070 if (ret < 0)3071 return ret;3072 3073 nb_controls = (unsigned int)ret;3074 3075 controls = devm_kcalloc(dev, nb_controls,3076 sizeof(*controls), GFP_KERNEL);3077 if (!controls)3078 return -ENOMEM;3079 3080 for (i = 0; i < nb_controls; i++) {3081 control_name = devm_kasprintf(dev, GFP_KERNEL,3082 "%s Switch", strings[i]);3083 if (!control_name)3084 return -ENOMEM;3085 3086 controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;3087 controls[i].name = control_name;3088 controls[i].info = snd_soc_dapm_info_pin_switch;3089 controls[i].get = snd_soc_dapm_get_pin_switch;3090 controls[i].put = snd_soc_dapm_put_pin_switch;3091 controls[i].private_value = (unsigned long)strings[i];3092 }3093 3094 card->controls = controls;3095 card->num_controls = nb_controls;3096 3097 return 0;3098}3099EXPORT_SYMBOL_GPL(snd_soc_of_parse_pin_switches);3100 3101int snd_soc_of_get_slot_mask(struct device_node *np,3102 const char *prop_name,3103 unsigned int *mask)3104{3105 u32 val;3106 const __be32 *of_slot_mask = of_get_property(np, prop_name, &val);3107 int i;3108 3109 if (!of_slot_mask)3110 return 0;3111 val /= sizeof(u32);3112 for (i = 0; i < val; i++)3113 if (be32_to_cpup(&of_slot_mask[i]))3114 *mask |= (1 << i);3115 3116 return val;3117}3118EXPORT_SYMBOL_GPL(snd_soc_of_get_slot_mask);3119 3120int snd_soc_of_parse_tdm_slot(struct device_node *np,3121 unsigned int *tx_mask,3122 unsigned int *rx_mask,3123 unsigned int *slots,3124 unsigned int *slot_width)3125{3126 u32 val;3127 int ret;3128 3129 if (tx_mask)3130 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-tx-mask", tx_mask);3131 if (rx_mask)3132 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-rx-mask", rx_mask);3133 3134 if (of_property_read_bool(np, "dai-tdm-slot-num")) {3135 ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);3136 if (ret)3137 return ret;3138 3139 if (slots)3140 *slots = val;3141 }3142 3143 if (of_property_read_bool(np, "dai-tdm-slot-width")) {3144 ret = of_property_read_u32(np, "dai-tdm-slot-width", &val);3145 if (ret)3146 return ret;3147 3148 if (slot_width)3149 *slot_width = val;3150 }3151 3152 return 0;3153}3154EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);3155 3156void snd_soc_dlc_use_cpu_as_platform(struct snd_soc_dai_link_component *platforms,3157 struct snd_soc_dai_link_component *cpus)3158{3159 platforms->of_node = cpus->of_node;3160 platforms->dai_args = cpus->dai_args;3161}3162EXPORT_SYMBOL_GPL(snd_soc_dlc_use_cpu_as_platform);3163 3164void snd_soc_of_parse_node_prefix(struct device_node *np,3165 struct snd_soc_codec_conf *codec_conf,3166 struct device_node *of_node,3167 const char *propname)3168{3169 const char *str;3170 int ret;3171 3172 ret = of_property_read_string(np, propname, &str);3173 if (ret < 0) {3174 /* no prefix is not error */3175 return;3176 }3177 3178 codec_conf->dlc.of_node = of_node;3179 codec_conf->name_prefix = str;3180}3181EXPORT_SYMBOL_GPL(snd_soc_of_parse_node_prefix);3182 3183int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,3184 const char *propname)3185{3186 struct device_node *np = card->dev->of_node;3187 int num_routes;3188 struct snd_soc_dapm_route *routes;3189 int i;3190 3191 num_routes = of_property_count_strings(np, propname);3192 if (num_routes < 0 || num_routes & 1) {3193 dev_err(card->dev,3194 "ASoC: Property '%s' does not exist or its length is not even\n",3195 propname);3196 return -EINVAL;3197 }3198 num_routes /= 2;3199 3200 routes = devm_kcalloc(card->dev, num_routes, sizeof(*routes),3201 GFP_KERNEL);3202 if (!routes) {3203 dev_err(card->dev,3204 "ASoC: Could not allocate DAPM route table\n");3205 return -ENOMEM;3206 }3207 3208 for (i = 0; i < num_routes; i++) {3209 int ret = of_property_read_string_index(np, propname,3210 2 * i, &routes[i].sink);3211 if (ret) {3212 dev_err(card->dev,3213 "ASoC: Property '%s' index %d could not be read: %d\n",3214 propname, 2 * i, ret);3215 return -EINVAL;3216 }3217 ret = of_property_read_string_index(np, propname,3218 (2 * i) + 1, &routes[i].source);3219 if (ret) {3220 dev_err(card->dev,3221 "ASoC: Property '%s' index %d could not be read: %d\n",3222 propname, (2 * i) + 1, ret);3223 return -EINVAL;3224 }3225 }3226 3227 card->num_of_dapm_routes = num_routes;3228 card->of_dapm_routes = routes;3229 3230 return 0;3231}3232EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);3233 3234int snd_soc_of_parse_aux_devs(struct snd_soc_card *card, const char *propname)3235{3236 struct device_node *node = card->dev->of_node;3237 struct snd_soc_aux_dev *aux;3238 int num, i;3239 3240 num = of_count_phandle_with_args(node, propname, NULL);3241 if (num == -ENOENT) {3242 return 0;3243 } else if (num < 0) {3244 dev_err(card->dev, "ASOC: Property '%s' could not be read: %d\n",3245 propname, num);3246 return num;3247 }3248 3249 aux = devm_kcalloc(card->dev, num, sizeof(*aux), GFP_KERNEL);3250 if (!aux)3251 return -ENOMEM;3252 card->aux_dev = aux;3253 card->num_aux_devs = num;3254 3255 for_each_card_pre_auxs(card, i, aux) {3256 aux->dlc.of_node = of_parse_phandle(node, propname, i);3257 if (!aux->dlc.of_node)3258 return -EINVAL;3259 }3260 3261 return 0;3262}3263EXPORT_SYMBOL_GPL(snd_soc_of_parse_aux_devs);3264 3265unsigned int snd_soc_daifmt_clock_provider_flipped(unsigned int dai_fmt)3266{3267 unsigned int inv_dai_fmt = dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;3268 3269 switch (dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {3270 case SND_SOC_DAIFMT_CBP_CFP:3271 inv_dai_fmt |= SND_SOC_DAIFMT_CBC_CFC;3272 break;3273 case SND_SOC_DAIFMT_CBP_CFC:3274 inv_dai_fmt |= SND_SOC_DAIFMT_CBC_CFP;3275 break;3276 case SND_SOC_DAIFMT_CBC_CFP:3277 inv_dai_fmt |= SND_SOC_DAIFMT_CBP_CFC;3278 break;3279 case SND_SOC_DAIFMT_CBC_CFC:3280 inv_dai_fmt |= SND_SOC_DAIFMT_CBP_CFP;3281 break;3282 }3283 3284 return inv_dai_fmt;3285}3286EXPORT_SYMBOL_GPL(snd_soc_daifmt_clock_provider_flipped);3287 3288unsigned int snd_soc_daifmt_clock_provider_from_bitmap(unsigned int bit_frame)3289{3290 /*3291 * bit_frame is return value from3292 * snd_soc_daifmt_parse_clock_provider_raw()3293 */3294 3295 /* Codec base */3296 switch (bit_frame) {3297 case 0x11:3298 return SND_SOC_DAIFMT_CBP_CFP;3299 case 0x10:3300 return SND_SOC_DAIFMT_CBP_CFC;3301 case 0x01:3302 return SND_SOC_DAIFMT_CBC_CFP;3303 default:3304 return SND_SOC_DAIFMT_CBC_CFC;3305 }3306 3307 return 0;3308}3309EXPORT_SYMBOL_GPL(snd_soc_daifmt_clock_provider_from_bitmap);3310 3311unsigned int snd_soc_daifmt_parse_format(struct device_node *np,3312 const char *prefix)3313{3314 int ret;3315 char prop[128];3316 unsigned int format = 0;3317 int bit, frame;3318 const char *str;3319 struct {3320 char *name;3321 unsigned int val;3322 } of_fmt_table[] = {3323 { "i2s", SND_SOC_DAIFMT_I2S },3324 { "right_j", SND_SOC_DAIFMT_RIGHT_J },3325 { "left_j", SND_SOC_DAIFMT_LEFT_J },3326 { "dsp_a", SND_SOC_DAIFMT_DSP_A },3327 { "dsp_b", SND_SOC_DAIFMT_DSP_B },3328 { "ac97", SND_SOC_DAIFMT_AC97 },3329 { "pdm", SND_SOC_DAIFMT_PDM},3330 { "msb", SND_SOC_DAIFMT_MSB },3331 { "lsb", SND_SOC_DAIFMT_LSB },3332 };3333 3334 if (!prefix)3335 prefix = "";3336 3337 /*3338 * check "dai-format = xxx"3339 * or "[prefix]format = xxx"3340 * SND_SOC_DAIFMT_FORMAT_MASK area3341 */3342 ret = of_property_read_string(np, "dai-format", &str);3343 if (ret < 0) {3344 snprintf(prop, sizeof(prop), "%sformat", prefix);3345 ret = of_property_read_string(np, prop, &str);3346 }3347 if (ret == 0) {3348 int i;3349 3350 for (i = 0; i < ARRAY_SIZE(of_fmt_table); i++) {3351 if (strcmp(str, of_fmt_table[i].name) == 0) {3352 format |= of_fmt_table[i].val;3353 break;3354 }3355 }3356 }3357 3358 /*3359 * check "[prefix]continuous-clock"3360 * SND_SOC_DAIFMT_CLOCK_MASK area3361 */3362 snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix);3363 if (of_property_read_bool(np, prop))3364 format |= SND_SOC_DAIFMT_CONT;3365 else3366 format |= SND_SOC_DAIFMT_GATED;3367 3368 /*3369 * check "[prefix]bitclock-inversion"3370 * check "[prefix]frame-inversion"3371 * SND_SOC_DAIFMT_INV_MASK area3372 */3373 snprintf(prop, sizeof(prop), "%sbitclock-inversion", prefix);3374 bit = of_property_read_bool(np, prop);3375 3376 snprintf(prop, sizeof(prop), "%sframe-inversion", prefix);3377 frame = of_property_read_bool(np, prop);3378 3379 switch ((bit << 4) + frame) {3380 case 0x11:3381 format |= SND_SOC_DAIFMT_IB_IF;3382 break;3383 case 0x10:3384 format |= SND_SOC_DAIFMT_IB_NF;3385 break;3386 case 0x01:3387 format |= SND_SOC_DAIFMT_NB_IF;3388 break;3389 default:3390 /* SND_SOC_DAIFMT_NB_NF is default */3391 break;3392 }3393 3394 return format;3395}3396EXPORT_SYMBOL_GPL(snd_soc_daifmt_parse_format);3397 3398unsigned int snd_soc_daifmt_parse_clock_provider_raw(struct device_node *np,3399 const char *prefix,3400 struct device_node **bitclkmaster,3401 struct device_node **framemaster)3402{3403 char prop[128];3404 unsigned int bit, frame;3405 3406 if (!prefix)3407 prefix = "";3408 3409 /*3410 * check "[prefix]bitclock-master"3411 * check "[prefix]frame-master"3412 */3413 snprintf(prop, sizeof(prop), "%sbitclock-master", prefix);3414 bit = of_property_read_bool(np, prop);3415 if (bit && bitclkmaster)3416 *bitclkmaster = of_parse_phandle(np, prop, 0);3417 3418 snprintf(prop, sizeof(prop), "%sframe-master", prefix);3419 frame = of_property_read_bool(np, prop);3420 if (frame && framemaster)3421 *framemaster = of_parse_phandle(np, prop, 0);3422 3423 /*3424 * return bitmap.3425 * It will be parameter of3426 * snd_soc_daifmt_clock_provider_from_bitmap()3427 */3428 return (bit << 4) + frame;3429}3430EXPORT_SYMBOL_GPL(snd_soc_daifmt_parse_clock_provider_raw);3431 3432int snd_soc_get_stream_cpu(const struct snd_soc_dai_link *dai_link, int stream)3433{3434 /*3435 * [Normal]3436 *3437 * Playback3438 * CPU : SNDRV_PCM_STREAM_PLAYBACK3439 * Codec: SNDRV_PCM_STREAM_PLAYBACK3440 *3441 * Capture3442 * CPU : SNDRV_PCM_STREAM_CAPTURE3443 * Codec: SNDRV_PCM_STREAM_CAPTURE3444 */3445 if (!dai_link->c2c_params)3446 return stream;3447 3448 /*3449 * [Codec2Codec]3450 *3451 * Playback3452 * CPU : SNDRV_PCM_STREAM_CAPTURE3453 * Codec: SNDRV_PCM_STREAM_PLAYBACK3454 *3455 * Capture3456 * CPU : SNDRV_PCM_STREAM_PLAYBACK3457 * Codec: SNDRV_PCM_STREAM_CAPTURE3458 */3459 if (stream == SNDRV_PCM_STREAM_CAPTURE)3460 return SNDRV_PCM_STREAM_PLAYBACK;3461 3462 return SNDRV_PCM_STREAM_CAPTURE;3463}3464EXPORT_SYMBOL_GPL(snd_soc_get_stream_cpu);3465 3466int snd_soc_get_dai_id(struct device_node *ep)3467{3468 struct snd_soc_component *component;3469 struct snd_soc_dai_link_component dlc = {3470 .of_node = of_graph_get_port_parent(ep),3471 };3472 int ret;3473 3474 3475 /*3476 * For example HDMI case, HDMI has video/sound port,3477 * but ALSA SoC needs sound port number only.3478 * Thus counting HDMI DT port/endpoint doesn't work.3479 * Then, it should have .of_xlate_dai_id3480 */3481 ret = -ENOTSUPP;3482 mutex_lock(&client_mutex);3483 component = soc_find_component(&dlc);3484 if (component)3485 ret = snd_soc_component_of_xlate_dai_id(component, ep);3486 mutex_unlock(&client_mutex);3487 3488 of_node_put(dlc.of_node);3489 3490 return ret;3491}3492EXPORT_SYMBOL_GPL(snd_soc_get_dai_id);3493 3494int snd_soc_get_dlc(const struct of_phandle_args *args, struct snd_soc_dai_link_component *dlc)3495{3496 struct snd_soc_component *pos;3497 int ret = -EPROBE_DEFER;3498 3499 mutex_lock(&client_mutex);3500 for_each_component(pos) {3501 struct device_node *component_of_node = soc_component_to_node(pos);3502 3503 if (component_of_node != args->np || !pos->num_dai)3504 continue;3505 3506 ret = snd_soc_component_of_xlate_dai_name(pos, args, &dlc->dai_name);3507 if (ret == -ENOTSUPP) {3508 struct snd_soc_dai *dai;3509 int id = -1;3510 3511 switch (args->args_count) {3512 case 0:3513 id = 0; /* same as dai_drv[0] */3514 break;3515 case 1:3516 id = args->args[0];3517 break;3518 default:3519 /* not supported */3520 break;3521 }3522 3523 if (id < 0 || id >= pos->num_dai) {3524 ret = -EINVAL;3525 continue;3526 }3527 3528 ret = 0;3529 3530 /* find target DAI */3531 for_each_component_dais(pos, dai) {3532 if (id == 0)3533 break;3534 id--;3535 }3536 3537 dlc->dai_name = snd_soc_dai_name_get(dai);3538 } else if (ret) {3539 /*3540 * if another error than ENOTSUPP is returned go on and3541 * check if another component is provided with the same3542 * node. This may happen if a device provides several3543 * components3544 */3545 continue;3546 }3547 3548 break;3549 }3550 3551 if (ret == 0)3552 dlc->of_node = args->np;3553 3554 mutex_unlock(&client_mutex);3555 return ret;3556}3557EXPORT_SYMBOL_GPL(snd_soc_get_dlc);3558 3559int snd_soc_of_get_dlc(struct device_node *of_node,3560 struct of_phandle_args *args,3561 struct snd_soc_dai_link_component *dlc,3562 int index)3563{3564 struct of_phandle_args __args;3565 int ret;3566 3567 if (!args)3568 args = &__args;3569 3570 ret = of_parse_phandle_with_args(of_node, "sound-dai",3571 "#sound-dai-cells", index, args);3572 if (ret)3573 return ret;3574 3575 return snd_soc_get_dlc(args, dlc);3576}3577EXPORT_SYMBOL_GPL(snd_soc_of_get_dlc);3578 3579int snd_soc_get_dai_name(const struct of_phandle_args *args,3580 const char **dai_name)3581{3582 struct snd_soc_dai_link_component dlc;3583 int ret = snd_soc_get_dlc(args, &dlc);3584 3585 if (ret == 0)3586 *dai_name = dlc.dai_name;3587 3588 return ret;3589}3590EXPORT_SYMBOL_GPL(snd_soc_get_dai_name);3591 3592int snd_soc_of_get_dai_name(struct device_node *of_node,3593 const char **dai_name, int index)3594{3595 struct snd_soc_dai_link_component dlc;3596 int ret = snd_soc_of_get_dlc(of_node, NULL, &dlc, index);3597 3598 if (ret == 0)3599 *dai_name = dlc.dai_name;3600 3601 return ret;3602}3603EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);3604 3605struct snd_soc_dai *snd_soc_get_dai_via_args(const struct of_phandle_args *dai_args)3606{3607 struct snd_soc_dai *dai;3608 struct snd_soc_component *component;3609 3610 mutex_lock(&client_mutex);3611 for_each_component(component) {3612 for_each_component_dais(component, dai)3613 if (snd_soc_is_match_dai_args(dai->driver->dai_args, dai_args))3614 goto found;3615 }3616 dai = NULL;3617found:3618 mutex_unlock(&client_mutex);3619 return dai;3620}3621EXPORT_SYMBOL_GPL(snd_soc_get_dai_via_args);3622 3623static void __snd_soc_of_put_component(struct snd_soc_dai_link_component *component)3624{3625 if (component->of_node) {3626 of_node_put(component->of_node);3627 component->of_node = NULL;3628 }3629}3630 3631static int __snd_soc_of_get_dai_link_component_alloc(3632 struct device *dev, struct device_node *of_node,3633 struct snd_soc_dai_link_component **ret_component,3634 int *ret_num)3635{3636 struct snd_soc_dai_link_component *component;3637 int num;3638 3639 /* Count the number of CPUs/CODECs */3640 num = of_count_phandle_with_args(of_node, "sound-dai", "#sound-dai-cells");3641 if (num <= 0) {3642 if (num == -ENOENT)3643 dev_err(dev, "No 'sound-dai' property\n");3644 else3645 dev_err(dev, "Bad phandle in 'sound-dai'\n");3646 return num;3647 }3648 component = devm_kcalloc(dev, num, sizeof(*component), GFP_KERNEL);3649 if (!component)3650 return -ENOMEM;3651 3652 *ret_component = component;3653 *ret_num = num;3654 3655 return 0;3656}3657 3658/*3659 * snd_soc_of_put_dai_link_codecs - Dereference device nodes in the codecs array3660 * @dai_link: DAI link3661 *3662 * Dereference device nodes acquired by snd_soc_of_get_dai_link_codecs().3663 */3664void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link)3665{3666 struct snd_soc_dai_link_component *component;3667 int index;3668 3669 for_each_link_codecs(dai_link, index, component)3670 __snd_soc_of_put_component(component);3671}3672EXPORT_SYMBOL_GPL(snd_soc_of_put_dai_link_codecs);3673 3674/*3675 * snd_soc_of_get_dai_link_codecs - Parse a list of CODECs in the devicetree3676 * @dev: Card device3677 * @of_node: Device node3678 * @dai_link: DAI link3679 *3680 * Builds an array of CODEC DAI components from the DAI link property3681 * 'sound-dai'.3682 * The array is set in the DAI link and the number of DAIs is set accordingly.3683 * The device nodes in the array (of_node) must be dereferenced by calling3684 * snd_soc_of_put_dai_link_codecs() on @dai_link.3685 *3686 * Returns 0 for success3687 */3688int snd_soc_of_get_dai_link_codecs(struct device *dev,3689 struct device_node *of_node,3690 struct snd_soc_dai_link *dai_link)3691{3692 struct snd_soc_dai_link_component *component;3693 int index, ret;3694 3695 ret = __snd_soc_of_get_dai_link_component_alloc(dev, of_node,3696 &dai_link->codecs, &dai_link->num_codecs);3697 if (ret < 0)3698 return ret;3699 3700 /* Parse the list */3701 for_each_link_codecs(dai_link, index, component) {3702 ret = snd_soc_of_get_dlc(of_node, NULL, component, index);3703 if (ret)3704 goto err;3705 }3706 return 0;3707err:3708 snd_soc_of_put_dai_link_codecs(dai_link);3709 dai_link->codecs = NULL;3710 dai_link->num_codecs = 0;3711 return ret;3712}3713EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs);3714 3715/*3716 * snd_soc_of_put_dai_link_cpus - Dereference device nodes in the codecs array3717 * @dai_link: DAI link3718 *3719 * Dereference device nodes acquired by snd_soc_of_get_dai_link_cpus().3720 */3721void snd_soc_of_put_dai_link_cpus(struct snd_soc_dai_link *dai_link)3722{3723 struct snd_soc_dai_link_component *component;3724 int index;3725 3726 for_each_link_cpus(dai_link, index, component)3727 __snd_soc_of_put_component(component);3728}3729EXPORT_SYMBOL_GPL(snd_soc_of_put_dai_link_cpus);3730 3731/*3732 * snd_soc_of_get_dai_link_cpus - Parse a list of CPU DAIs in the devicetree3733 * @dev: Card device3734 * @of_node: Device node3735 * @dai_link: DAI link3736 *3737 * Is analogous to snd_soc_of_get_dai_link_codecs but parses a list of CPU DAIs3738 * instead.3739 *3740 * Returns 0 for success3741 */3742int snd_soc_of_get_dai_link_cpus(struct device *dev,3743 struct device_node *of_node,3744 struct snd_soc_dai_link *dai_link)3745{3746 struct snd_soc_dai_link_component *component;3747 int index, ret;3748 3749 /* Count the number of CPUs */3750 ret = __snd_soc_of_get_dai_link_component_alloc(dev, of_node,3751 &dai_link->cpus, &dai_link->num_cpus);3752 if (ret < 0)3753 return ret;3754 3755 /* Parse the list */3756 for_each_link_cpus(dai_link, index, component) {3757 ret = snd_soc_of_get_dlc(of_node, NULL, component, index);3758 if (ret)3759 goto err;3760 }3761 return 0;3762err:3763 snd_soc_of_put_dai_link_cpus(dai_link);3764 dai_link->cpus = NULL;3765 dai_link->num_cpus = 0;3766 return ret;3767}3768EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_cpus);3769 3770static int __init snd_soc_init(void)3771{3772 int ret;3773 3774 snd_soc_debugfs_init();3775 ret = snd_soc_util_init();3776 if (ret)3777 goto err_util_init;3778 3779 ret = platform_driver_register(&soc_driver);3780 if (ret)3781 goto err_register;3782 return 0;3783 3784err_register:3785 snd_soc_util_exit();3786err_util_init:3787 snd_soc_debugfs_exit();3788 return ret;3789}3790module_init(snd_soc_init);3791 3792static void __exit snd_soc_exit(void)3793{3794 snd_soc_util_exit();3795 snd_soc_debugfs_exit();3796 3797 platform_driver_unregister(&soc_driver);3798}3799module_exit(snd_soc_exit);3800 3801/* Module information */3802MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");3803MODULE_DESCRIPTION("ALSA SoC Core");3804MODULE_LICENSE("GPL");3805MODULE_ALIAS("platform:soc-audio");3806