aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/generic
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2014-10-27 21:04:52 -0400
committerMark Brown <broonie@kernel.org>2014-10-28 12:35:51 -0400
commit1b5721b24306c2daf786f3b31f678b40ab9b2ce7 (patch)
treee121a26aa29b180df93e3d3ae81b2ffe6ad8cf3d /sound/soc/generic
parent84d4cbe9a60a1fdd35b4dd69951f31c518b467d8 (diff)
ASoC: simple-card: add asoc_simple_card_parse_daifmt()
Current daifmt setting method in simple-card driver is placed to many places, and using un-readable/confusable method. This patch adds new asoc_simple_card_parse_daifmt() and tidyup code. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/generic')
-rw-r--r--sound/soc/generic/simple-card.c134
1 files changed, 65 insertions, 69 deletions
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 4f192ee3cb16..cac95d79fc8f 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -226,6 +226,53 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
226 return 0; 226 return 0;
227} 227}
228 228
229static int asoc_simple_card_parse_daifmt(struct device_node *node,
230 struct simple_card_data *priv,
231 struct device_node *cpu,
232 struct device_node *codec,
233 char *prefix, int idx)
234{
235 struct device *dev = simple_priv_to_dev(priv);
236 struct device_node *bitclkmaster = NULL;
237 struct device_node *framemaster = NULL;
238 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
239 struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
240 struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
241 unsigned int daifmt;
242
243 daifmt = snd_soc_of_parse_daifmt(node, prefix,
244 &bitclkmaster, &framemaster);
245 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
246
247 if (strlen(prefix) && !bitclkmaster && !framemaster) {
248 /*
249 * No dai-link level and master setting was not found from
250 * sound node level, revert back to legacy DT parsing and
251 * take the settings from codec node.
252 */
253 dev_dbg(dev, "Revert to legacy daifmt parsing\n");
254
255 cpu_dai->fmt = codec_dai->fmt =
256 snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
257 (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
258 } else {
259 if (codec == bitclkmaster)
260 daifmt |= (codec == framemaster) ?
261 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
262 else
263 daifmt |= (codec == framemaster) ?
264 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
265
266 cpu_dai->fmt = daifmt;
267 codec_dai->fmt = daifmt;
268 }
269
270 of_node_put(bitclkmaster);
271 of_node_put(framemaster);
272
273 return 0;
274}
275
229static int asoc_simple_card_dai_link_of(struct device_node *node, 276static int asoc_simple_card_dai_link_of(struct device_node *node,
230 struct simple_card_data *priv, 277 struct simple_card_data *priv,
231 int idx, 278 int idx,
@@ -234,10 +281,8 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
234 struct device *dev = simple_priv_to_dev(priv); 281 struct device *dev = simple_priv_to_dev(priv);
235 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); 282 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
236 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); 283 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
237 struct device_node *np = NULL; 284 struct device_node *cpu = NULL;
238 struct device_node *bitclkmaster = NULL; 285 struct device_node *codec = NULL;
239 struct device_node *framemaster = NULL;
240 unsigned int daifmt;
241 char *name; 286 char *name;
242 char prop[128]; 287 char prop[128];
243 char *prefix = ""; 288 char *prefix = "";
@@ -247,85 +292,36 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
247 if (is_top_level_node) 292 if (is_top_level_node)
248 prefix = "simple-audio-card,"; 293 prefix = "simple-audio-card,";
249 294
250 daifmt = snd_soc_of_parse_daifmt(node, prefix,
251 &bitclkmaster, &framemaster);
252 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
253
254 snprintf(prop, sizeof(prop), "%scpu", prefix); 295 snprintf(prop, sizeof(prop), "%scpu", prefix);
255 np = of_get_child_by_name(node, prop); 296 cpu = of_get_child_by_name(node, prop);
256 if (!np) { 297
298 snprintf(prop, sizeof(prop), "%scodec", prefix);
299 codec = of_get_child_by_name(node, prop);
300
301 if (!cpu || !codec) {
257 ret = -EINVAL; 302 ret = -EINVAL;
258 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); 303 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
259 goto dai_link_of_err; 304 goto dai_link_of_err;
260 } 305 }
261 306
262 ret = asoc_simple_card_sub_parse_of(np, &dai_props->cpu_dai, 307 ret = asoc_simple_card_parse_daifmt(node, priv,
308 cpu, codec, prefix, idx);
309 if (ret < 0)
310 goto dai_link_of_err;
311
312 ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai,
263 &dai_link->cpu_of_node, 313 &dai_link->cpu_of_node,
264 &dai_link->cpu_dai_name, 314 &dai_link->cpu_dai_name,
265 &cpu_args); 315 &cpu_args);
266 if (ret < 0) 316 if (ret < 0)
267 goto dai_link_of_err; 317 goto dai_link_of_err;
268 318
269 dai_props->cpu_dai.fmt = daifmt; 319 ret = asoc_simple_card_sub_parse_of(codec, &dai_props->codec_dai,
270 switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
271 case 0x11:
272 dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS;
273 break;
274 case 0x10:
275 dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM;
276 break;
277 case 0x01:
278 dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS;
279 break;
280 default:
281 dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM;
282 break;
283 }
284
285 of_node_put(np);
286 snprintf(prop, sizeof(prop), "%scodec", prefix);
287 np = of_get_child_by_name(node, prop);
288 if (!np) {
289 ret = -EINVAL;
290 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
291 goto dai_link_of_err;
292 }
293
294 ret = asoc_simple_card_sub_parse_of(np, &dai_props->codec_dai,
295 &dai_link->codec_of_node, 320 &dai_link->codec_of_node,
296 &dai_link->codec_dai_name, NULL); 321 &dai_link->codec_dai_name, NULL);
297 if (ret < 0) 322 if (ret < 0)
298 goto dai_link_of_err; 323 goto dai_link_of_err;
299 324
300 if (strlen(prefix) && !bitclkmaster && !framemaster) {
301 /*
302 * No DAI link level and master setting was found
303 * from sound node level, revert back to legacy DT
304 * parsing and take the settings from codec node.
305 */
306 dev_dbg(dev, "%s: Revert to legacy daifmt parsing\n",
307 __func__);
308 dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt =
309 snd_soc_of_parse_daifmt(np, NULL, NULL, NULL) |
310 (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
311 } else {
312 dai_props->codec_dai.fmt = daifmt;
313 switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
314 case 0x11:
315 dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM;
316 break;
317 case 0x10:
318 dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS;
319 break;
320 case 0x01:
321 dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM;
322 break;
323 default:
324 dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS;
325 break;
326 }
327 }
328
329 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { 325 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
330 ret = -EINVAL; 326 ret = -EINVAL;
331 goto dai_link_of_err; 327 goto dai_link_of_err;
@@ -368,9 +364,9 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
368 dai_link->cpu_dai_name = NULL; 364 dai_link->cpu_dai_name = NULL;
369 365
370dai_link_of_err: 366dai_link_of_err:
371 of_node_put(np); 367 of_node_put(cpu);
372 of_node_put(bitclkmaster); 368 of_node_put(codec);
373 of_node_put(framemaster); 369
374 return ret; 370 return ret;
375} 371}
376 372