aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2014-10-25 11:41:58 -0400
committerMark Brown <broonie@kernel.org>2014-10-27 20:19:59 -0400
commit5fe5b767dc6fb3df6fa6eaa8e05b727914f2bb4c (patch)
tree99c5814c3be1eeaaebe7f11fe051080828b3a545
parent98407efc1384b31cdcb1eeddc74ee35499d3418f (diff)
ASoC: dapm: Do not pretend to support controls for non mixer/mux widgets
Controls on a path only have an effect if the sink on the path is either a mixer or mux widget. Currently we sort of silently ignore controls on other paths, but since they don't do anything having them on other paths does not make much sense and it is probably safe to assume that if we see such a path it is a mistake in the driver that registered the path. This patch modifies snd_soc_dapm_add_path() to report an error if a path with and control is encountered where we didn't expect a control. This also allows to simplify the code quite a bit. The patch also moves the connecting of the path lists out of dapm_connect_mux() and dapm_connect_mixer() into snd_soc_dapm_add_path(). Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/soc-dapm.c112
1 files changed, 37 insertions, 75 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1fed2207b024..c49df10d1c33 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -469,10 +469,9 @@ out:
469 469
470/* connect mux widget to its interconnecting audio paths */ 470/* connect mux widget to its interconnecting audio paths */
471static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, 471static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
472 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 472 struct snd_soc_dapm_path *path, const char *control_name)
473 struct snd_soc_dapm_path *path, const char *control_name,
474 const struct snd_kcontrol_new *kcontrol)
475{ 473{
474 const struct snd_kcontrol_new *kcontrol = &path->sink->kcontrol_news[0];
476 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 475 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
477 unsigned int val, item; 476 unsigned int val, item;
478 int i; 477 int i;
@@ -493,9 +492,6 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
493 492
494 for (i = 0; i < e->items; i++) { 493 for (i = 0; i < e->items; i++) {
495 if (!(strcmp(control_name, e->texts[i]))) { 494 if (!(strcmp(control_name, e->texts[i]))) {
496 list_add(&path->list, &dapm->card->paths);
497 list_add(&path->list_sink, &dest->sources);
498 list_add(&path->list_source, &src->sinks);
499 path->name = e->texts[i]; 495 path->name = e->texts[i];
500 if (i == item) 496 if (i == item)
501 path->connect = 1; 497 path->connect = 1;
@@ -509,11 +505,10 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
509} 505}
510 506
511/* set up initial codec paths */ 507/* set up initial codec paths */
512static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w, 508static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i)
513 struct snd_soc_dapm_path *p, int i)
514{ 509{
515 struct soc_mixer_control *mc = (struct soc_mixer_control *) 510 struct soc_mixer_control *mc = (struct soc_mixer_control *)
516 w->kcontrol_news[i].private_value; 511 p->sink->kcontrol_news[i].private_value;
517 unsigned int reg = mc->reg; 512 unsigned int reg = mc->reg;
518 unsigned int shift = mc->shift; 513 unsigned int shift = mc->shift;
519 unsigned int max = mc->max; 514 unsigned int max = mc->max;
@@ -522,7 +517,7 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w,
522 unsigned int val; 517 unsigned int val;
523 518
524 if (reg != SND_SOC_NOPM) { 519 if (reg != SND_SOC_NOPM) {
525 soc_dapm_read(w->dapm, reg, &val); 520 soc_dapm_read(p->sink->dapm, reg, &val);
526 val = (val >> shift) & mask; 521 val = (val >> shift) & mask;
527 if (invert) 522 if (invert)
528 val = max - val; 523 val = max - val;
@@ -534,19 +529,15 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w,
534 529
535/* connect mixer widget to its interconnecting audio paths */ 530/* connect mixer widget to its interconnecting audio paths */
536static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, 531static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
537 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
538 struct snd_soc_dapm_path *path, const char *control_name) 532 struct snd_soc_dapm_path *path, const char *control_name)
539{ 533{
540 int i; 534 int i;
541 535
542 /* search for mixer kcontrol */ 536 /* search for mixer kcontrol */
543 for (i = 0; i < dest->num_kcontrols; i++) { 537 for (i = 0; i < path->sink->num_kcontrols; i++) {
544 if (!strcmp(control_name, dest->kcontrol_news[i].name)) { 538 if (!strcmp(control_name, path->sink->kcontrol_news[i].name)) {
545 list_add(&path->list, &dapm->card->paths); 539 path->name = path->sink->kcontrol_news[i].name;
546 list_add(&path->list_sink, &dest->sources); 540 dapm_set_mixer_path_status(path, i);
547 list_add(&path->list_source, &src->sinks);
548 path->name = dest->kcontrol_news[i].name;
549 dapm_set_mixer_path_status(dest, path, i);
550 return 0; 541 return 0;
551 } 542 }
552 } 543 }
@@ -2272,69 +2263,40 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
2272 wsource->ext = 1; 2263 wsource->ext = 1;
2273 } 2264 }
2274 2265
2275 dapm_mark_dirty(wsource, "Route added");
2276 dapm_mark_dirty(wsink, "Route added");
2277
2278 /* connect static paths */ 2266 /* connect static paths */
2279 if (control == NULL) { 2267 if (control == NULL) {
2280 list_add(&path->list, &dapm->card->paths);
2281 list_add(&path->list_sink, &wsink->sources);
2282 list_add(&path->list_source, &wsource->sinks);
2283 path->connect = 1; 2268 path->connect = 1;
2284 return 0; 2269 } else {
2285 } 2270 /* connect dynamic paths */
2286 2271 switch (wsink->id) {
2287 /* connect dynamic paths */ 2272 case snd_soc_dapm_mux:
2288 switch (wsink->id) { 2273 ret = dapm_connect_mux(dapm, path, control);
2289 case snd_soc_dapm_adc: 2274 if (ret != 0)
2290 case snd_soc_dapm_dac: 2275 goto err;
2291 case snd_soc_dapm_pga: 2276 break;
2292 case snd_soc_dapm_out_drv: 2277 case snd_soc_dapm_switch:
2293 case snd_soc_dapm_input: 2278 case snd_soc_dapm_mixer:
2294 case snd_soc_dapm_output: 2279 case snd_soc_dapm_mixer_named_ctl:
2295 case snd_soc_dapm_siggen: 2280 ret = dapm_connect_mixer(dapm, path, control);
2296 case snd_soc_dapm_micbias: 2281 if (ret != 0)
2297 case snd_soc_dapm_vmid: 2282 goto err;
2298 case snd_soc_dapm_pre: 2283 break;
2299 case snd_soc_dapm_post: 2284 default:
2300 case snd_soc_dapm_supply: 2285 dev_err(dapm->dev,
2301 case snd_soc_dapm_regulator_supply: 2286 "Control not supported for path %s -> [%s] -> %s\n",
2302 case snd_soc_dapm_clock_supply: 2287 wsource->name, control, wsink->name);
2303 case snd_soc_dapm_aif_in: 2288 ret = -EINVAL;
2304 case snd_soc_dapm_aif_out:
2305 case snd_soc_dapm_dai_in:
2306 case snd_soc_dapm_dai_out:
2307 case snd_soc_dapm_dai_link:
2308 case snd_soc_dapm_kcontrol:
2309 list_add(&path->list, &dapm->card->paths);
2310 list_add(&path->list_sink, &wsink->sources);
2311 list_add(&path->list_source, &wsource->sinks);
2312 path->connect = 1;
2313 return 0;
2314 case snd_soc_dapm_mux:
2315 ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
2316 &wsink->kcontrol_news[0]);
2317 if (ret != 0)
2318 goto err;
2319 break;
2320 case snd_soc_dapm_switch:
2321 case snd_soc_dapm_mixer:
2322 case snd_soc_dapm_mixer_named_ctl:
2323 ret = dapm_connect_mixer(dapm, wsource, wsink, path, control);
2324 if (ret != 0)
2325 goto err; 2289 goto err;
2326 break; 2290 }
2327 case snd_soc_dapm_hp:
2328 case snd_soc_dapm_mic:
2329 case snd_soc_dapm_line:
2330 case snd_soc_dapm_spk:
2331 list_add(&path->list, &dapm->card->paths);
2332 list_add(&path->list_sink, &wsink->sources);
2333 list_add(&path->list_source, &wsource->sinks);
2334 path->connect = 0;
2335 return 0;
2336 } 2291 }
2337 2292
2293 list_add(&path->list, &dapm->card->paths);
2294 list_add(&path->list_sink, &wsink->sources);
2295 list_add(&path->list_source, &wsource->sinks);
2296
2297 dapm_mark_dirty(wsource, "Route added");
2298 dapm_mark_dirty(wsink, "Route added");
2299
2338 return 0; 2300 return 0;
2339err: 2301err:
2340 kfree(path); 2302 kfree(path);