diff options
-rw-r--r-- | sound/soc/soc-dapm.c | 112 |
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 */ |
471 | static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, | 471 | static 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 */ |
512 | static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w, | 508 | static 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 */ |
536 | static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, | 531 | static 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; |
2339 | err: | 2301 | err: |
2340 | kfree(path); | 2302 | kfree(path); |