summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorRohit kumar <rohitkr@codeaurora.org>2018-08-01 05:01:08 -0400
committerMark Brown <broonie@kernel.org>2018-08-01 07:00:21 -0400
commitc25e295cd77b37903ddc9ee27384e17aad08f27c (patch)
tree493a58b8725c8eac47de4b9d82a43fd877a82065 /sound
parent0c901e8cea15ba1e318d8f4342f7dc27a80b5978 (diff)
ASoC: qcom: Add support to parse common audio device nodes
This adds support to parse cpu, platform and codec device nodes and add them in dai-links. Also, update apq8096 machine driver to use the common API. Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Rohit kumar <rohitkr@codeaurora.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/qcom/Makefile2
-rw-r--r--sound/soc/qcom/apq8096.c111
-rw-r--r--sound/soc/qcom/common.c112
-rw-r--r--sound/soc/qcom/common.h12
4 files changed, 136 insertions, 101 deletions
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index 206945bb9ba1..fefecc072265 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += snd-soc-lpass-apq8016.o
13# Machine 13# Machine
14snd-soc-storm-objs := storm.o 14snd-soc-storm-objs := storm.o
15snd-soc-apq8016-sbc-objs := apq8016_sbc.o 15snd-soc-apq8016-sbc-objs := apq8016_sbc.o
16snd-soc-apq8096-objs := apq8096.o 16snd-soc-apq8096-objs := apq8096.o common.o
17 17
18obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o 18obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
19obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o 19obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o
diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c
index a56156281c8d..1e4a90d59228 100644
--- a/sound/soc/qcom/apq8096.c
+++ b/sound/soc/qcom/apq8096.c
@@ -9,6 +9,7 @@
9#include <sound/soc.h> 9#include <sound/soc.h>
10#include <sound/soc-dapm.h> 10#include <sound/soc-dapm.h>
11#include <sound/pcm.h> 11#include <sound/pcm.h>
12#include "common.h"
12 13
13static int apq8096_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 14static int apq8096_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
14 struct snd_pcm_hw_params *params) 15 struct snd_pcm_hw_params *params)
@@ -24,109 +25,16 @@ static int apq8096_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
24 return 0; 25 return 0;
25} 26}
26 27
27static int apq8096_sbc_parse_of(struct snd_soc_card *card) 28static void apq8096_add_be_ops(struct snd_soc_card *card)
28{ 29{
29 struct device_node *np; 30 struct snd_soc_dai_link *link = card->dai_link;
30 struct device_node *codec = NULL; 31 int i, num_links = card->num_links;
31 struct device_node *platform = NULL;
32 struct device_node *cpu = NULL;
33 struct device *dev = card->dev;
34 struct snd_soc_dai_link *link;
35 int ret, num_links;
36
37 ret = snd_soc_of_parse_card_name(card, "qcom,model");
38 if (ret) {
39 dev_err(dev, "Error parsing card name: %d\n", ret);
40 return ret;
41 }
42
43 /* DAPM routes */
44 if (of_property_read_bool(dev->of_node, "qcom,audio-routing")) {
45 ret = snd_soc_of_parse_audio_routing(card,
46 "qcom,audio-routing");
47 if (ret)
48 return ret;
49 }
50
51 /* Populate links */
52 num_links = of_get_child_count(dev->of_node);
53
54 /* Allocate the DAI link array */
55 card->dai_link = kcalloc(num_links, sizeof(*link), GFP_KERNEL);
56 if (!card->dai_link)
57 return -ENOMEM;
58 32
59 card->num_links = num_links; 33 for (i = 0; i < num_links; i++) {
60 link = card->dai_link; 34 if (link->no_pcm == 1)
61
62 for_each_child_of_node(dev->of_node, np) {
63 cpu = of_get_child_by_name(np, "cpu");
64 if (!cpu) {
65 dev_err(dev, "Can't find cpu DT node\n");
66 ret = -EINVAL;
67 goto err;
68 }
69
70 link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
71 if (!link->cpu_of_node) {
72 dev_err(card->dev, "error getting cpu phandle\n");
73 ret = -EINVAL;
74 goto err;
75 }
76
77 ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name);
78 if (ret) {
79 dev_err(card->dev, "error getting cpu dai name\n");
80 goto err;
81 }
82
83 platform = of_get_child_by_name(np, "platform");
84 codec = of_get_child_by_name(np, "codec");
85 if (codec && platform) {
86 link->platform_of_node = of_parse_phandle(platform,
87 "sound-dai",
88 0);
89 if (!link->platform_of_node) {
90 dev_err(card->dev, "platform dai not found\n");
91 ret = -EINVAL;
92 goto err;
93 }
94
95 ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
96 if (ret < 0) {
97 dev_err(card->dev, "codec dai not found\n");
98 goto err;
99 }
100 link->no_pcm = 1;
101 link->ignore_pmdown_time = 1;
102 link->be_hw_params_fixup = apq8096_be_hw_params_fixup; 35 link->be_hw_params_fixup = apq8096_be_hw_params_fixup;
103 } else {
104 link->platform_of_node = link->cpu_of_node;
105 link->codec_dai_name = "snd-soc-dummy-dai";
106 link->codec_name = "snd-soc-dummy";
107 link->dynamic = 1;
108 }
109
110 link->ignore_suspend = 1;
111 ret = of_property_read_string(np, "link-name", &link->name);
112 if (ret) {
113 dev_err(card->dev, "error getting codec dai_link name\n");
114 goto err;
115 }
116
117 link->dpcm_playback = 1;
118 link->dpcm_capture = 1;
119 link->stream_name = link->name;
120 link++; 36 link++;
121 } 37 }
122
123 return 0;
124err:
125 of_node_put(cpu);
126 of_node_put(codec);
127 of_node_put(platform);
128 kfree(card->dai_link);
129 return ret;
130} 38}
131 39
132static int apq8096_platform_probe(struct platform_device *pdev) 40static int apq8096_platform_probe(struct platform_device *pdev)
@@ -142,18 +50,21 @@ static int apq8096_platform_probe(struct platform_device *pdev)
142 card->dev = dev; 50 card->dev = dev;
143 card->auto_bind = true; 51 card->auto_bind = true;
144 dev_set_drvdata(dev, card); 52 dev_set_drvdata(dev, card);
145 ret = apq8096_sbc_parse_of(card); 53 ret = qcom_snd_parse_of(card);
146 if (ret) { 54 if (ret) {
147 dev_err(dev, "Error parsing OF data\n"); 55 dev_err(dev, "Error parsing OF data\n");
148 goto err; 56 goto err;
149 } 57 }
150 58
59 apq8096_add_be_ops(card);
151 ret = snd_soc_register_card(card); 60 ret = snd_soc_register_card(card);
152 if (ret) 61 if (ret)
153 goto err; 62 goto err_card_register;
154 63
155 return 0; 64 return 0;
156 65
66err_card_register:
67 kfree(card->dai_link);
157err: 68err:
158 kfree(card); 69 kfree(card);
159 return ret; 70 return ret;
diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
new file mode 100644
index 000000000000..eb1b9da05dd4
--- /dev/null
+++ b/sound/soc/qcom/common.c
@@ -0,0 +1,112 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018, Linaro Limited.
3// Copyright (c) 2018, The Linux Foundation. All rights reserved.
4
5#include <linux/module.h>
6#include "common.h"
7
8int qcom_snd_parse_of(struct snd_soc_card *card)
9{
10 struct device_node *np;
11 struct device_node *codec = NULL;
12 struct device_node *platform = NULL;
13 struct device_node *cpu = NULL;
14 struct device *dev = card->dev;
15 struct snd_soc_dai_link *link;
16 int ret, num_links;
17
18 ret = snd_soc_of_parse_card_name(card, "model");
19 if (ret) {
20 dev_err(dev, "Error parsing card name: %d\n", ret);
21 return ret;
22 }
23
24 /* DAPM routes */
25 if (of_property_read_bool(dev->of_node, "audio-routing")) {
26 ret = snd_soc_of_parse_audio_routing(card,
27 "audio-routing");
28 if (ret)
29 return ret;
30 }
31
32 /* Populate links */
33 num_links = of_get_child_count(dev->of_node);
34
35 /* Allocate the DAI link array */
36 card->dai_link = kcalloc(num_links, sizeof(*link), GFP_KERNEL);
37 if (!card->dai_link)
38 return -ENOMEM;
39
40 card->num_links = num_links;
41 link = card->dai_link;
42 for_each_child_of_node(dev->of_node, np) {
43 cpu = of_get_child_by_name(np, "cpu");
44 if (!cpu) {
45 dev_err(dev, "Can't find cpu DT node\n");
46 ret = -EINVAL;
47 goto err;
48 }
49
50 link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
51 if (!link->cpu_of_node) {
52 dev_err(card->dev, "error getting cpu phandle\n");
53 ret = -EINVAL;
54 goto err;
55 }
56
57 ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name);
58 if (ret) {
59 dev_err(card->dev, "error getting cpu dai name\n");
60 goto err;
61 }
62
63 platform = of_get_child_by_name(np, "platform");
64 codec = of_get_child_by_name(np, "codec");
65 if (codec && platform) {
66 link->platform_of_node = of_parse_phandle(platform,
67 "sound-dai",
68 0);
69 if (!link->platform_of_node) {
70 dev_err(card->dev, "platform dai not found\n");
71 ret = -EINVAL;
72 goto err;
73 }
74
75 ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
76 if (ret < 0) {
77 dev_err(card->dev, "codec dai not found\n");
78 goto err;
79 }
80 link->no_pcm = 1;
81 link->ignore_pmdown_time = 1;
82 } else {
83 link->platform_of_node = link->cpu_of_node;
84 link->codec_dai_name = "snd-soc-dummy-dai";
85 link->codec_name = "snd-soc-dummy";
86 link->dynamic = 1;
87 }
88
89 link->ignore_suspend = 1;
90 ret = of_property_read_string(np, "link-name", &link->name);
91 if (ret) {
92 dev_err(card->dev, "error getting codec dai_link name\n");
93 goto err;
94 }
95
96 link->dpcm_playback = 1;
97 link->dpcm_capture = 1;
98 link->stream_name = link->name;
99 link++;
100 }
101
102 return 0;
103err:
104 of_node_put(cpu);
105 of_node_put(codec);
106 of_node_put(platform);
107 kfree(card->dai_link);
108 return ret;
109}
110EXPORT_SYMBOL(qcom_snd_parse_of);
111
112MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/common.h b/sound/soc/qcom/common.h
new file mode 100644
index 000000000000..ad5d2cf27459
--- /dev/null
+++ b/sound/soc/qcom/common.h
@@ -0,0 +1,12 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2// Copyright (c) 2018, The Linux Foundation. All rights reserved.
3
4#ifndef __QCOM_SND_COMMON_H__
5#define __QCOM_SND_COMMON_H__
6
7#include <linux/component.h>
8#include <sound/soc.h>
9
10int qcom_snd_parse_of(struct snd_soc_card *card);
11
12#endif