aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);