diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2014-10-27 21:04:52 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-10-28 12:35:51 -0400 |
commit | 1b5721b24306c2daf786f3b31f678b40ab9b2ce7 (patch) | |
tree | e121a26aa29b180df93e3d3ae81b2ffe6ad8cf3d /sound/soc/generic | |
parent | 84d4cbe9a60a1fdd35b4dd69951f31c518b467d8 (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.c | 134 |
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 | ||
229 | static 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 | |||
229 | static int asoc_simple_card_dai_link_of(struct device_node *node, | 276 | static 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 | ||
370 | dai_link_of_err: | 366 | dai_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 | ||