diff options
-rw-r--r-- | include/sound/soc.h | 3 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 110 |
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); |
1452 | int snd_soc_of_get_dai_name(struct device_node *of_node, | 1452 | int snd_soc_of_get_dai_name(struct device_node *of_node, |
1453 | const char **dai_name); | 1453 | const char **dai_name); |
1454 | int 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 | } |
4751 | EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt); | 4751 | EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt); |
4752 | 4752 | ||
4753 | int snd_soc_of_get_dai_name(struct device_node *of_node, | 4753 | static 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 | |||
4801 | int 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 | } |
4809 | EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name); | 4818 | EXPORT_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 | */ | ||
4833 | int 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; | ||
4876 | err: | ||
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 | } | ||
4889 | EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs); | ||
4890 | |||
4811 | static int __init snd_soc_init(void) | 4891 | static int __init snd_soc_init(void) |
4812 | { | 4892 | { |
4813 | #ifdef CONFIG_DEBUG_FS | 4893 | #ifdef CONFIG_DEBUG_FS |