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 | |
| 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>
| -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 | } |
