aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2014-02-28 02:31:12 -0500
committerMark Brown <broonie@linaro.org>2014-02-28 22:03:36 -0500
commit234c0b8fb0db790aaebec07d1d190e789d8ec7b9 (patch)
tree5a2d46dc06cb7bff76c948b6f843ca8378e78324 /sound/soc
parent236aaa6863581634bd6d599ccf7f7b38deeafdc0 (diff)
ASoC: dapm: Break dapm_set_path_status() appart
There are three different completely independent code paths in dapm_set_path_status(). One of them is never used at all and the other two (one for mixers, one for MUXs) have their distincive callsites that always go onto the same path. Breaking the function into two parts allows us to reduce the code size and in the MUX case also do some optimizations to avoid having to calcualte the selected item for each item again. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/soc-dapm.c133
1 files changed, 44 insertions, 89 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index c07c7fb7593a..3651a37bb2c7 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -495,93 +495,6 @@ out:
495 return ret; 495 return ret;
496} 496}
497 497
498/* set up initial codec paths */
499static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
500 struct snd_soc_dapm_path *p, int i)
501{
502 switch (w->id) {
503 case snd_soc_dapm_switch:
504 case snd_soc_dapm_mixer:
505 case snd_soc_dapm_mixer_named_ctl: {
506 unsigned int val;
507 struct soc_mixer_control *mc = (struct soc_mixer_control *)
508 w->kcontrol_news[i].private_value;
509 int reg = mc->reg;
510 unsigned int shift = mc->shift;
511 int max = mc->max;
512 unsigned int mask = (1 << fls(max)) - 1;
513 unsigned int invert = mc->invert;
514
515 if (reg != SND_SOC_NOPM) {
516 soc_widget_read(w, reg, &val);
517 val = (val >> shift) & mask;
518 if (invert)
519 val = max - val;
520 p->connect = !!val;
521 } else {
522 p->connect = 0;
523 }
524
525 }
526 break;
527 case snd_soc_dapm_mux: {
528 struct soc_enum *e = (struct soc_enum *)
529 w->kcontrol_news[i].private_value;
530 unsigned int val, item;
531
532 if (e->reg != SND_SOC_NOPM) {
533 soc_widget_read(w, e->reg, &val);
534 val = (val >> e->shift_l) & e->mask;
535 item = snd_soc_enum_val_to_item(e, val);
536 } else {
537 /* since a virtual mux has no backing registers to
538 * decide which path to connect, it will try to match
539 * with the first enumeration. This is to ensure
540 * that the default mux choice (the first) will be
541 * correctly powered up during initialization.
542 */
543 item = 0;
544 }
545
546 if (item < e->items && !strcmp(p->name, e->texts[item]))
547 p->connect = 1;
548 else
549 p->connect = 0;
550 }
551 break;
552 /* does not affect routing - always connected */
553 case snd_soc_dapm_pga:
554 case snd_soc_dapm_out_drv:
555 case snd_soc_dapm_output:
556 case snd_soc_dapm_adc:
557 case snd_soc_dapm_input:
558 case snd_soc_dapm_siggen:
559 case snd_soc_dapm_dac:
560 case snd_soc_dapm_micbias:
561 case snd_soc_dapm_vmid:
562 case snd_soc_dapm_supply:
563 case snd_soc_dapm_regulator_supply:
564 case snd_soc_dapm_clock_supply:
565 case snd_soc_dapm_aif_in:
566 case snd_soc_dapm_aif_out:
567 case snd_soc_dapm_dai_in:
568 case snd_soc_dapm_dai_out:
569 case snd_soc_dapm_hp:
570 case snd_soc_dapm_mic:
571 case snd_soc_dapm_spk:
572 case snd_soc_dapm_line:
573 case snd_soc_dapm_dai_link:
574 case snd_soc_dapm_kcontrol:
575 p->connect = 1;
576 break;
577 /* does affect routing - dynamically connected */
578 case snd_soc_dapm_pre:
579 case snd_soc_dapm_post:
580 p->connect = 0;
581 break;
582 }
583}
584
585/* connect mux widget to its interconnecting audio paths */ 498/* connect mux widget to its interconnecting audio paths */
586static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, 499static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
587 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 500 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
@@ -589,15 +502,33 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
589 const struct snd_kcontrol_new *kcontrol) 502 const struct snd_kcontrol_new *kcontrol)
590{ 503{
591 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 504 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
505 unsigned int val, item;
592 int i; 506 int i;
593 507
508 if (e->reg != SND_SOC_NOPM) {
509 soc_widget_read(dest, e->reg, &val);
510 val = (val >> e->shift_l) & e->mask;
511 item = snd_soc_enum_val_to_item(e, val);
512 } else {
513 /* since a virtual mux has no backing registers to
514 * decide which path to connect, it will try to match
515 * with the first enumeration. This is to ensure
516 * that the default mux choice (the first) will be
517 * correctly powered up during initialization.
518 */
519 item = 0;
520 }
521
594 for (i = 0; i < e->items; i++) { 522 for (i = 0; i < e->items; i++) {
595 if (!(strcmp(control_name, e->texts[i]))) { 523 if (!(strcmp(control_name, e->texts[i]))) {
596 list_add(&path->list, &dapm->card->paths); 524 list_add(&path->list, &dapm->card->paths);
597 list_add(&path->list_sink, &dest->sources); 525 list_add(&path->list_sink, &dest->sources);
598 list_add(&path->list_source, &src->sinks); 526 list_add(&path->list_source, &src->sinks);
599 path->name = (char*)e->texts[i]; 527 path->name = (char*)e->texts[i];
600 dapm_set_path_status(dest, path, 0); 528 if (i == item)
529 path->connect = 1;
530 else
531 path->connect = 0;
601 return 0; 532 return 0;
602 } 533 }
603 } 534 }
@@ -605,6 +536,30 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
605 return -ENODEV; 536 return -ENODEV;
606} 537}
607 538
539/* set up initial codec paths */
540static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w,
541 struct snd_soc_dapm_path *p, int i)
542{
543 struct soc_mixer_control *mc = (struct soc_mixer_control *)
544 w->kcontrol_news[i].private_value;
545 unsigned int reg = mc->reg;
546 unsigned int shift = mc->shift;
547 unsigned int max = mc->max;
548 unsigned int mask = (1 << fls(max)) - 1;
549 unsigned int invert = mc->invert;
550 unsigned int val;
551
552 if (reg != SND_SOC_NOPM) {
553 soc_widget_read(w, reg, &val);
554 val = (val >> shift) & mask;
555 if (invert)
556 val = max - val;
557 p->connect = !!val;
558 } else {
559 p->connect = 0;
560 }
561}
562
608/* connect mixer widget to its interconnecting audio paths */ 563/* connect mixer widget to its interconnecting audio paths */
609static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, 564static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
610 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 565 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
@@ -619,7 +574,7 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
619 list_add(&path->list_sink, &dest->sources); 574 list_add(&path->list_sink, &dest->sources);
620 list_add(&path->list_source, &src->sinks); 575 list_add(&path->list_source, &src->sinks);
621 path->name = dest->kcontrol_news[i].name; 576 path->name = dest->kcontrol_news[i].name;
622 dapm_set_path_status(dest, path, i); 577 dapm_set_mixer_path_status(dest, path, i);
623 return 0; 578 return 0;
624 } 579 }
625 } 580 }