diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2013-07-29 11:14:02 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-07-29 13:41:00 -0400 |
commit | 2553628e1973709bf378320ecffd3e4fb34458db (patch) | |
tree | 38ab7961bb923e3ffca25ec02704f7fb65a7e8f3 /sound/soc/soc-dapm.c | |
parent | de9ba98b6d2629f53fd271a973176c2fa9736d9c (diff) |
ASoC: dapm: Add snd_soc_dapm_add_path() helper function
snd_soc_dapm_add_path() is similar to snd_soc_dapm_add_route() except that it
expects the pointer to the source and sink widgets instead of their names. This
allows us to simplify the case where we already have a pointer to widgets. (E.g.
as we have in snd_soc_dapm_link_dai_widgets()). snd_soc_dapm_add_route() will be
updated to just look up the widget and then use snd_soc_dapm_add_path() to
handle everything else.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r-- | sound/soc/soc-dapm.c | 151 |
1 files changed, 81 insertions, 70 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 59bcc66358ca..b811a27bf21a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -2263,64 +2263,14 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) | |||
2263 | } | 2263 | } |
2264 | EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); | 2264 | EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); |
2265 | 2265 | ||
2266 | static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | 2266 | static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, |
2267 | const struct snd_soc_dapm_route *route) | 2267 | struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink, |
2268 | const char *control, | ||
2269 | int (*connected)(struct snd_soc_dapm_widget *source, | ||
2270 | struct snd_soc_dapm_widget *sink)) | ||
2268 | { | 2271 | { |
2269 | struct snd_soc_dapm_path *path; | 2272 | struct snd_soc_dapm_path *path; |
2270 | struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; | 2273 | int ret; |
2271 | struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL; | ||
2272 | const char *sink; | ||
2273 | const char *control = route->control; | ||
2274 | const char *source; | ||
2275 | char prefixed_sink[80]; | ||
2276 | char prefixed_source[80]; | ||
2277 | int ret = 0; | ||
2278 | |||
2279 | if (dapm->codec && dapm->codec->name_prefix) { | ||
2280 | snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", | ||
2281 | dapm->codec->name_prefix, route->sink); | ||
2282 | sink = prefixed_sink; | ||
2283 | snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", | ||
2284 | dapm->codec->name_prefix, route->source); | ||
2285 | source = prefixed_source; | ||
2286 | } else { | ||
2287 | sink = route->sink; | ||
2288 | source = route->source; | ||
2289 | } | ||
2290 | |||
2291 | /* | ||
2292 | * find src and dest widgets over all widgets but favor a widget from | ||
2293 | * current DAPM context | ||
2294 | */ | ||
2295 | list_for_each_entry(w, &dapm->card->widgets, list) { | ||
2296 | if (!wsink && !(strcmp(w->name, sink))) { | ||
2297 | wtsink = w; | ||
2298 | if (w->dapm == dapm) | ||
2299 | wsink = w; | ||
2300 | continue; | ||
2301 | } | ||
2302 | if (!wsource && !(strcmp(w->name, source))) { | ||
2303 | wtsource = w; | ||
2304 | if (w->dapm == dapm) | ||
2305 | wsource = w; | ||
2306 | } | ||
2307 | } | ||
2308 | /* use widget from another DAPM context if not found from this */ | ||
2309 | if (!wsink) | ||
2310 | wsink = wtsink; | ||
2311 | if (!wsource) | ||
2312 | wsource = wtsource; | ||
2313 | |||
2314 | if (wsource == NULL) { | ||
2315 | dev_err(dapm->dev, "ASoC: no source widget found for %s\n", | ||
2316 | route->source); | ||
2317 | return -ENODEV; | ||
2318 | } | ||
2319 | if (wsink == NULL) { | ||
2320 | dev_err(dapm->dev, "ASoC: no sink widget found for %s\n", | ||
2321 | route->sink); | ||
2322 | return -ENODEV; | ||
2323 | } | ||
2324 | 2274 | ||
2325 | path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); | 2275 | path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); |
2326 | if (!path) | 2276 | if (!path) |
@@ -2328,7 +2278,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | |||
2328 | 2278 | ||
2329 | path->source = wsource; | 2279 | path->source = wsource; |
2330 | path->sink = wsink; | 2280 | path->sink = wsink; |
2331 | path->connected = route->connected; | 2281 | path->connected = connected; |
2332 | INIT_LIST_HEAD(&path->list); | 2282 | INIT_LIST_HEAD(&path->list); |
2333 | INIT_LIST_HEAD(&path->list_source); | 2283 | INIT_LIST_HEAD(&path->list_source); |
2334 | INIT_LIST_HEAD(&path->list_sink); | 2284 | INIT_LIST_HEAD(&path->list_sink); |
@@ -2414,11 +2364,77 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | |||
2414 | dapm_mark_dirty(wsink, "Route added"); | 2364 | dapm_mark_dirty(wsink, "Route added"); |
2415 | 2365 | ||
2416 | return 0; | 2366 | return 0; |
2367 | err: | ||
2368 | kfree(path); | ||
2369 | return ret; | ||
2370 | } | ||
2417 | 2371 | ||
2372 | static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | ||
2373 | const struct snd_soc_dapm_route *route) | ||
2374 | { | ||
2375 | struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; | ||
2376 | struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL; | ||
2377 | const char *sink; | ||
2378 | const char *source; | ||
2379 | char prefixed_sink[80]; | ||
2380 | char prefixed_source[80]; | ||
2381 | int ret; | ||
2382 | |||
2383 | if (dapm->codec && dapm->codec->name_prefix) { | ||
2384 | snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", | ||
2385 | dapm->codec->name_prefix, route->sink); | ||
2386 | sink = prefixed_sink; | ||
2387 | snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", | ||
2388 | dapm->codec->name_prefix, route->source); | ||
2389 | source = prefixed_source; | ||
2390 | } else { | ||
2391 | sink = route->sink; | ||
2392 | source = route->source; | ||
2393 | } | ||
2394 | |||
2395 | /* | ||
2396 | * find src and dest widgets over all widgets but favor a widget from | ||
2397 | * current DAPM context | ||
2398 | */ | ||
2399 | list_for_each_entry(w, &dapm->card->widgets, list) { | ||
2400 | if (!wsink && !(strcmp(w->name, sink))) { | ||
2401 | wtsink = w; | ||
2402 | if (w->dapm == dapm) | ||
2403 | wsink = w; | ||
2404 | continue; | ||
2405 | } | ||
2406 | if (!wsource && !(strcmp(w->name, source))) { | ||
2407 | wtsource = w; | ||
2408 | if (w->dapm == dapm) | ||
2409 | wsource = w; | ||
2410 | } | ||
2411 | } | ||
2412 | /* use widget from another DAPM context if not found from this */ | ||
2413 | if (!wsink) | ||
2414 | wsink = wtsink; | ||
2415 | if (!wsource) | ||
2416 | wsource = wtsource; | ||
2417 | |||
2418 | if (wsource == NULL) { | ||
2419 | dev_err(dapm->dev, "ASoC: no source widget found for %s\n", | ||
2420 | route->source); | ||
2421 | return -ENODEV; | ||
2422 | } | ||
2423 | if (wsink == NULL) { | ||
2424 | dev_err(dapm->dev, "ASoC: no sink widget found for %s\n", | ||
2425 | route->sink); | ||
2426 | return -ENODEV; | ||
2427 | } | ||
2428 | |||
2429 | ret = snd_soc_dapm_add_path(dapm, wsource, wsink, route->control, | ||
2430 | route->connected); | ||
2431 | if (ret) | ||
2432 | goto err; | ||
2433 | |||
2434 | return 0; | ||
2418 | err: | 2435 | err: |
2419 | dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n", | 2436 | dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n", |
2420 | source, control, sink); | 2437 | source, route->control, sink); |
2421 | kfree(path); | ||
2422 | return ret; | 2438 | return ret; |
2423 | } | 2439 | } |
2424 | 2440 | ||
@@ -3421,9 +3437,6 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) | |||
3421 | { | 3437 | { |
3422 | struct snd_soc_dapm_widget *dai_w, *w; | 3438 | struct snd_soc_dapm_widget *dai_w, *w; |
3423 | struct snd_soc_dai *dai; | 3439 | struct snd_soc_dai *dai; |
3424 | struct snd_soc_dapm_route r; | ||
3425 | |||
3426 | memset(&r, 0, sizeof(r)); | ||
3427 | 3440 | ||
3428 | /* For each DAI widget... */ | 3441 | /* For each DAI widget... */ |
3429 | list_for_each_entry(dai_w, &card->widgets, list) { | 3442 | list_for_each_entry(dai_w, &card->widgets, list) { |
@@ -3456,23 +3469,21 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) | |||
3456 | if (dai->driver->playback.stream_name && | 3469 | if (dai->driver->playback.stream_name && |
3457 | strstr(w->sname, | 3470 | strstr(w->sname, |
3458 | dai->driver->playback.stream_name)) { | 3471 | dai->driver->playback.stream_name)) { |
3459 | r.source = dai->playback_widget->name; | ||
3460 | r.sink = w->name; | ||
3461 | dev_dbg(dai->dev, "%s -> %s\n", | 3472 | dev_dbg(dai->dev, "%s -> %s\n", |
3462 | r.source, r.sink); | 3473 | dai->playback_widget->name, w->name); |
3463 | 3474 | ||
3464 | snd_soc_dapm_add_route(w->dapm, &r); | 3475 | snd_soc_dapm_add_path(w->dapm, |
3476 | dai->playback_widget, w, NULL, NULL); | ||
3465 | } | 3477 | } |
3466 | 3478 | ||
3467 | if (dai->driver->capture.stream_name && | 3479 | if (dai->driver->capture.stream_name && |
3468 | strstr(w->sname, | 3480 | strstr(w->sname, |
3469 | dai->driver->capture.stream_name)) { | 3481 | dai->driver->capture.stream_name)) { |
3470 | r.source = w->name; | ||
3471 | r.sink = dai->capture_widget->name; | ||
3472 | dev_dbg(dai->dev, "%s -> %s\n", | 3482 | dev_dbg(dai->dev, "%s -> %s\n", |
3473 | r.source, r.sink); | 3483 | w->name, dai->capture_widget->name); |
3474 | 3484 | ||
3475 | snd_soc_dapm_add_route(w->dapm, &r); | 3485 | snd_soc_dapm_add_path(w->dapm, w, |
3486 | dai->capture_widget, NULL, NULL); | ||
3476 | } | 3487 | } |
3477 | } | 3488 | } |
3478 | } | 3489 | } |