aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-07-05 12:24:19 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-07-06 14:06:59 -0400
commitefcc3c61b9b1e4f764e14c48c553e6d477f40512 (patch)
treef74c4890308519ef9e8563e6645d82408947bd36
parentfabd03842b77b1eb6c9b08c79be86fa38afbe310 (diff)
ASoC: dapm: Allow routes to be deleted at runtime
Since we're now relying on DAPM for things like enabling clocks when we reparent the clocks for widgets we need to either use conditional routes (which are expensive) or remove routes at runtime. Add a route removal API to support this use case. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@ti.com>
-rw-r--r--include/sound/soc-dapm.h2
-rw-r--r--sound/soc/soc-dapm.c77
2 files changed, 79 insertions, 0 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 05559e571d44..abe373d57adc 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -374,6 +374,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
374void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm); 374void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
375int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, 375int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
376 const struct snd_soc_dapm_route *route, int num); 376 const struct snd_soc_dapm_route *route, int num);
377int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
378 const struct snd_soc_dapm_route *route, int num);
377int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm, 379int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
378 const struct snd_soc_dapm_route *route, int num); 380 const struct snd_soc_dapm_route *route, int num);
379 381
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 19fda1339510..4ba47aab9801 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2264,6 +2264,59 @@ err:
2264 return ret; 2264 return ret;
2265} 2265}
2266 2266
2267static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
2268 const struct snd_soc_dapm_route *route)
2269{
2270 struct snd_soc_dapm_path *path, *p;
2271 const char *sink;
2272 const char *source;
2273 char prefixed_sink[80];
2274 char prefixed_source[80];
2275
2276 if (route->control) {
2277 dev_err(dapm->dev,
2278 "Removal of routes with controls not supported\n");
2279 return -EINVAL;
2280 }
2281
2282 if (dapm->codec && dapm->codec->name_prefix) {
2283 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
2284 dapm->codec->name_prefix, route->sink);
2285 sink = prefixed_sink;
2286 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
2287 dapm->codec->name_prefix, route->source);
2288 source = prefixed_source;
2289 } else {
2290 sink = route->sink;
2291 source = route->source;
2292 }
2293
2294 path = NULL;
2295 list_for_each_entry(p, &dapm->card->paths, list) {
2296 if (strcmp(p->source->name, source) != 0)
2297 continue;
2298 if (strcmp(p->sink->name, sink) != 0)
2299 continue;
2300 path = p;
2301 break;
2302 }
2303
2304 if (path) {
2305 dapm_mark_dirty(path->source, "Route removed");
2306 dapm_mark_dirty(path->sink, "Route removed");
2307
2308 list_del(&path->list);
2309 list_del(&path->list_sink);
2310 list_del(&path->list_source);
2311 kfree(path);
2312 } else {
2313 dev_warn(dapm->dev, "Route %s->%s does not exist\n",
2314 source, sink);
2315 }
2316
2317 return 0;
2318}
2319
2267/** 2320/**
2268 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 2321 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
2269 * @dapm: DAPM context 2322 * @dapm: DAPM context
@@ -2298,6 +2351,30 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
2298} 2351}
2299EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); 2352EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
2300 2353
2354/**
2355 * snd_soc_dapm_del_routes - Remove routes between DAPM widgets
2356 * @dapm: DAPM context
2357 * @route: audio routes
2358 * @num: number of routes
2359 *
2360 * Removes routes from the DAPM context.
2361 */
2362int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
2363 const struct snd_soc_dapm_route *route, int num)
2364{
2365 int i, ret = 0;
2366
2367 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2368 for (i = 0; i < num; i++) {
2369 snd_soc_dapm_del_route(dapm, route);
2370 route++;
2371 }
2372 mutex_unlock(&dapm->card->dapm_mutex);
2373
2374 return ret;
2375}
2376EXPORT_SYMBOL_GPL(snd_soc_dapm_del_routes);
2377
2301static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, 2378static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm,
2302 const struct snd_soc_dapm_route *route) 2379 const struct snd_soc_dapm_route *route)
2303{ 2380{