aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h3
-rw-r--r--sound/soc/soc-core.c110
2 files changed, 98 insertions, 15 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 7ba7130037a0..2750e6ad0128 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1451,6 +1451,9 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
1451 struct device_node **framemaster); 1451 struct device_node **framemaster);
1452int snd_soc_of_get_dai_name(struct device_node *of_node, 1452int snd_soc_of_get_dai_name(struct device_node *of_node,
1453 const char **dai_name); 1453 const char **dai_name);
1454int snd_soc_of_get_dai_link_codecs(struct device *dev,
1455 struct device_node *of_node,
1456 struct snd_soc_dai_link *dai_link);
1454 1457
1455#include <sound/soc-dai.h> 1458#include <sound/soc-dai.h>
1456 1459
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4c8f8a23a0e9..72a3ad047048 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4750,36 +4750,30 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
4750} 4750}
4751EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt); 4751EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
4752 4752
4753int snd_soc_of_get_dai_name(struct device_node *of_node, 4753static int snd_soc_get_dai_name(struct of_phandle_args *args,
4754 const char **dai_name) 4754 const char **dai_name)
4755{ 4755{
4756 struct snd_soc_component *pos; 4756 struct snd_soc_component *pos;
4757 struct of_phandle_args args; 4757 int ret = -EPROBE_DEFER;
4758 int ret;
4759
4760 ret = of_parse_phandle_with_args(of_node, "sound-dai",
4761 "#sound-dai-cells", 0, &args);
4762 if (ret)
4763 return ret;
4764
4765 ret = -EPROBE_DEFER;
4766 4758
4767 mutex_lock(&client_mutex); 4759 mutex_lock(&client_mutex);
4768 list_for_each_entry(pos, &component_list, list) { 4760 list_for_each_entry(pos, &component_list, list) {
4769 if (pos->dev->of_node != args.np) 4761 if (pos->dev->of_node != args->np)
4770 continue; 4762 continue;
4771 4763
4772 if (pos->driver->of_xlate_dai_name) { 4764 if (pos->driver->of_xlate_dai_name) {
4773 ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name); 4765 ret = pos->driver->of_xlate_dai_name(pos,
4766 args,
4767 dai_name);
4774 } else { 4768 } else {
4775 int id = -1; 4769 int id = -1;
4776 4770
4777 switch (args.args_count) { 4771 switch (args->args_count) {
4778 case 0: 4772 case 0:
4779 id = 0; /* same as dai_drv[0] */ 4773 id = 0; /* same as dai_drv[0] */
4780 break; 4774 break;
4781 case 1: 4775 case 1:
4782 id = args.args[0]; 4776 id = args->args[0];
4783 break; 4777 break;
4784 default: 4778 default:
4785 /* not supported */ 4779 /* not supported */
@@ -4801,6 +4795,21 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
4801 break; 4795 break;
4802 } 4796 }
4803 mutex_unlock(&client_mutex); 4797 mutex_unlock(&client_mutex);
4798 return ret;
4799}
4800
4801int snd_soc_of_get_dai_name(struct device_node *of_node,
4802 const char **dai_name)
4803{
4804 struct of_phandle_args args;
4805 int ret;
4806
4807 ret = of_parse_phandle_with_args(of_node, "sound-dai",
4808 "#sound-dai-cells", 0, &args);
4809 if (ret)
4810 return ret;
4811
4812 ret = snd_soc_get_dai_name(&args, dai_name);
4804 4813
4805 of_node_put(args.np); 4814 of_node_put(args.np);
4806 4815
@@ -4808,6 +4817,77 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
4808} 4817}
4809EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name); 4818EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
4810 4819
4820/*
4821 * snd_soc_of_get_dai_link_codecs - Parse a list of CODECs in the devicetree
4822 * @dev: Card device
4823 * @of_node: Device node
4824 * @dai_link: DAI link
4825 *
4826 * Builds an array of CODEC DAI components from the DAI link property
4827 * 'sound-dai'.
4828 * The array is set in the DAI link and the number of DAIs is set accordingly.
4829 * The device nodes in the array (of_node) must be dereferenced by the caller.
4830 *
4831 * Returns 0 for success
4832 */
4833int snd_soc_of_get_dai_link_codecs(struct device *dev,
4834 struct device_node *of_node,
4835 struct snd_soc_dai_link *dai_link)
4836{
4837 struct of_phandle_args args;
4838 struct snd_soc_dai_link_component *component;
4839 char *name;
4840 int index, num_codecs, ret;
4841
4842 /* Count the number of CODECs */
4843 name = "sound-dai";
4844 num_codecs = of_count_phandle_with_args(of_node, name,
4845 "#sound-dai-cells");
4846 if (num_codecs <= 0) {
4847 if (num_codecs == -ENOENT)
4848 dev_err(dev, "No 'sound-dai' property\n");
4849 else
4850 dev_err(dev, "Bad phandle in 'sound-dai'\n");
4851 return num_codecs;
4852 }
4853 component = devm_kzalloc(dev,
4854 sizeof *component * num_codecs,
4855 GFP_KERNEL);
4856 if (!component)
4857 return -ENOMEM;
4858 dai_link->codecs = component;
4859 dai_link->num_codecs = num_codecs;
4860
4861 /* Parse the list */
4862 for (index = 0, component = dai_link->codecs;
4863 index < dai_link->num_codecs;
4864 index++, component++) {
4865 ret = of_parse_phandle_with_args(of_node, name,
4866 "#sound-dai-cells",
4867 index, &args);
4868 if (ret)
4869 goto err;
4870 component->of_node = args.np;
4871 ret = snd_soc_get_dai_name(&args, &component->dai_name);
4872 if (ret < 0)
4873 goto err;
4874 }
4875 return 0;
4876err:
4877 for (index = 0, component = dai_link->codecs;
4878 index < dai_link->num_codecs;
4879 index++, component++) {
4880 if (!component->of_node)
4881 break;
4882 of_node_put(component->of_node);
4883 component->of_node = NULL;
4884 }
4885 dai_link->codecs = NULL;
4886 dai_link->num_codecs = 0;
4887 return ret;
4888}
4889EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs);
4890
4811static int __init snd_soc_init(void) 4891static int __init snd_soc_init(void)
4812{ 4892{
4813#ifdef CONFIG_DEBUG_FS 4893#ifdef CONFIG_DEBUG_FS