aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/simple-card.txt6
-rw-r--r--sound/soc/codecs/sirf-audio-codec.c9
-rw-r--r--sound/soc/generic/simple-card.c80
3 files changed, 62 insertions, 33 deletions
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
index b30c222f9cd3..881914b139ca 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -43,6 +43,12 @@ Optional CPU/CODEC subnodes properties:
43 clock node (= common clock), or "system-clock-frequency" 43 clock node (= common clock), or "system-clock-frequency"
44 (if system doens't support common clock) 44 (if system doens't support common clock)
45 45
46Note:
47 * For 'format', 'frame-master', 'bitclock-master', 'bitclock-inversion' and
48 'frame-inversion', the simple card will use the settings of CODEC for both
49 CPU and CODEC sides as we need to keep the settings identical for both ends
50 of the link.
51
46Example: 52Example:
47 53
48sound { 54sound {
diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c
index 90e3a228bae4..58e7c1f23771 100644
--- a/sound/soc/codecs/sirf-audio-codec.c
+++ b/sound/soc/codecs/sirf-audio-codec.c
@@ -337,18 +337,9 @@ struct snd_soc_dai_driver sirf_audio_codec_dai = {
337 337
338static int sirf_audio_codec_probe(struct snd_soc_codec *codec) 338static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
339{ 339{
340 int ret;
341 struct snd_soc_dapm_context *dapm = &codec->dapm; 340 struct snd_soc_dapm_context *dapm = &codec->dapm;
342 struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
343 341
344 pm_runtime_enable(codec->dev); 342 pm_runtime_enable(codec->dev);
345 codec->control_data = sirf_audio_codec->regmap;
346
347 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
348 if (ret != 0) {
349 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
350 return ret;
351 }
352 343
353 if (of_device_is_compatible(codec->dev->of_node, "sirf,prima2-audio-codec")) { 344 if (of_device_is_compatible(codec->dev->of_node, "sirf,prima2-audio-codec")) {
354 snd_soc_dapm_new_controls(dapm, 345 snd_soc_dapm_new_controls(dapm,
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 5dd47691ba41..2ee8ed56bcf1 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -20,7 +20,6 @@
20 20
21struct simple_card_data { 21struct simple_card_data {
22 struct snd_soc_card snd_card; 22 struct snd_soc_card snd_card;
23 unsigned int daifmt;
24 struct asoc_simple_dai cpu_dai; 23 struct asoc_simple_dai cpu_dai;
25 struct asoc_simple_dai codec_dai; 24 struct asoc_simple_dai codec_dai;
26 struct snd_soc_dai_link snd_link; 25 struct snd_soc_dai_link snd_link;
@@ -105,12 +104,12 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
105 /* get dai->name */ 104 /* get dai->name */
106 ret = snd_soc_of_get_dai_name(np, name); 105 ret = snd_soc_of_get_dai_name(np, name);
107 if (ret < 0) 106 if (ret < 0)
108 goto parse_error; 107 return ret;
109 108
110 /* parse TDM slot */ 109 /* parse TDM slot */
111 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width); 110 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
112 if (ret) 111 if (ret)
113 goto parse_error; 112 return ret;
114 113
115 /* 114 /*
116 * bitclock-inversion, frame-inversion 115 * bitclock-inversion, frame-inversion
@@ -130,7 +129,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
130 clk = of_clk_get(np, 0); 129 clk = of_clk_get(np, 0);
131 if (IS_ERR(clk)) { 130 if (IS_ERR(clk)) {
132 ret = PTR_ERR(clk); 131 ret = PTR_ERR(clk);
133 goto parse_error; 132 return ret;
134 } 133 }
135 134
136 dai->sysclk = clk_get_rate(clk); 135 dai->sysclk = clk_get_rate(clk);
@@ -144,12 +143,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
144 dai->sysclk = clk_get_rate(clk); 143 dai->sysclk = clk_get_rate(clk);
145 } 144 }
146 145
147 ret = 0; 146 return 0;
148
149parse_error:
150 of_node_put(node);
151
152 return ret;
153} 147}
154 148
155static int asoc_simple_card_parse_of(struct device_node *node, 149static int asoc_simple_card_parse_of(struct device_node *node,
@@ -157,15 +151,18 @@ static int asoc_simple_card_parse_of(struct device_node *node,
157 struct device *dev) 151 struct device *dev)
158{ 152{
159 struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; 153 struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link;
154 struct asoc_simple_dai *codec_dai = &priv->codec_dai;
155 struct asoc_simple_dai *cpu_dai = &priv->cpu_dai;
160 struct device_node *np; 156 struct device_node *np;
161 char *name; 157 char *name;
158 unsigned int daifmt;
162 int ret; 159 int ret;
163 160
164 /* parsing the card name from DT */ 161 /* parsing the card name from DT */
165 snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name"); 162 snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");
166 163
167 /* get CPU/CODEC common format via simple-audio-card,format */ 164 /* get CPU/CODEC common format via simple-audio-card,format */
168 priv->daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") & 165 daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") &
169 (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK); 166 (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK);
170 167
171 /* off-codec widgets */ 168 /* off-codec widgets */
@@ -187,25 +184,35 @@ static int asoc_simple_card_parse_of(struct device_node *node,
187 /* CPU sub-node */ 184 /* CPU sub-node */
188 ret = -EINVAL; 185 ret = -EINVAL;
189 np = of_get_child_by_name(node, "simple-audio-card,cpu"); 186 np = of_get_child_by_name(node, "simple-audio-card,cpu");
190 if (np) 187 if (np) {
191 ret = asoc_simple_card_sub_parse_of(np, priv->daifmt, 188 ret = asoc_simple_card_sub_parse_of(np, daifmt,
192 &priv->cpu_dai, 189 cpu_dai,
193 &dai_link->cpu_of_node, 190 &dai_link->cpu_of_node,
194 &dai_link->cpu_dai_name); 191 &dai_link->cpu_dai_name);
192 of_node_put(np);
193 }
195 if (ret < 0) 194 if (ret < 0)
196 return ret; 195 return ret;
197 196
198 /* CODEC sub-node */ 197 /* CODEC sub-node */
199 ret = -EINVAL; 198 ret = -EINVAL;
200 np = of_get_child_by_name(node, "simple-audio-card,codec"); 199 np = of_get_child_by_name(node, "simple-audio-card,codec");
201 if (np) 200 if (np) {
202 ret = asoc_simple_card_sub_parse_of(np, priv->daifmt, 201 ret = asoc_simple_card_sub_parse_of(np, daifmt,
203 &priv->codec_dai, 202 codec_dai,
204 &dai_link->codec_of_node, 203 &dai_link->codec_of_node,
205 &dai_link->codec_dai_name); 204 &dai_link->codec_dai_name);
205 of_node_put(np);
206 }
206 if (ret < 0) 207 if (ret < 0)
207 return ret; 208 return ret;
208 209
210 /*
211 * overwrite cpu_dai->fmt as its DAIFMT_MASTER bit is based on CODEC
212 * while the other bits should be identical unless buggy SW/HW design.
213 */
214 cpu_dai->fmt = codec_dai->fmt;
215
209 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) 216 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name)
210 return -EINVAL; 217 return -EINVAL;
211 218
@@ -224,15 +231,15 @@ static int asoc_simple_card_parse_of(struct device_node *node,
224 dai_link->platform_of_node = dai_link->cpu_of_node; 231 dai_link->platform_of_node = dai_link->cpu_of_node;
225 232
226 dev_dbg(dev, "card-name : %s\n", name); 233 dev_dbg(dev, "card-name : %s\n", name);
227 dev_dbg(dev, "platform : %04x\n", priv->daifmt); 234 dev_dbg(dev, "platform : %04x\n", daifmt);
228 dev_dbg(dev, "cpu : %s / %04x / %d\n", 235 dev_dbg(dev, "cpu : %s / %04x / %d\n",
229 dai_link->cpu_dai_name, 236 dai_link->cpu_dai_name,
230 priv->cpu_dai.fmt, 237 cpu_dai->fmt,
231 priv->cpu_dai.sysclk); 238 cpu_dai->sysclk);
232 dev_dbg(dev, "codec : %s / %04x / %d\n", 239 dev_dbg(dev, "codec : %s / %04x / %d\n",
233 dai_link->codec_dai_name, 240 dai_link->codec_dai_name,
234 priv->codec_dai.fmt, 241 codec_dai->fmt,
235 priv->codec_dai.sysclk); 242 codec_dai->sysclk);
236 243
237 /* 244 /*
238 * soc_bind_dai_link() will check cpu name 245 * soc_bind_dai_link() will check cpu name
@@ -248,6 +255,27 @@ static int asoc_simple_card_parse_of(struct device_node *node,
248 return 0; 255 return 0;
249} 256}
250 257
258/* update the reference count of the devices nodes at end of probe */
259static int asoc_simple_card_unref(struct platform_device *pdev)
260{
261 struct snd_soc_card *card = platform_get_drvdata(pdev);
262 struct snd_soc_dai_link *dai_link;
263 struct device_node *np;
264 int num_links;
265
266 for (num_links = 0, dai_link = card->dai_link;
267 num_links < card->num_links;
268 num_links++, dai_link++) {
269 np = (struct device_node *) dai_link->cpu_of_node;
270 if (np)
271 of_node_put(np);
272 np = (struct device_node *) dai_link->codec_of_node;
273 if (np)
274 of_node_put(np);
275 }
276 return 0;
277}
278
251static int asoc_simple_card_probe(struct platform_device *pdev) 279static int asoc_simple_card_probe(struct platform_device *pdev)
252{ 280{
253 struct simple_card_data *priv; 281 struct simple_card_data *priv;
@@ -275,7 +303,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
275 if (ret < 0) { 303 if (ret < 0) {
276 if (ret != -EPROBE_DEFER) 304 if (ret != -EPROBE_DEFER)
277 dev_err(dev, "parse error %d\n", ret); 305 dev_err(dev, "parse error %d\n", ret);
278 return ret; 306 goto err;
279 } 307 }
280 } else { 308 } else {
281 struct asoc_simple_card_info *cinfo; 309 struct asoc_simple_card_info *cinfo;
@@ -318,7 +346,11 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
318 346
319 snd_soc_card_set_drvdata(&priv->snd_card, priv); 347 snd_soc_card_set_drvdata(&priv->snd_card, priv);
320 348
321 return devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 349 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
350
351err:
352 asoc_simple_card_unref(pdev);
353 return ret;
322} 354}
323 355
324static const struct of_device_id asoc_simple_of_match[] = { 356static const struct of_device_id asoc_simple_of_match[] = {