aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc-dapm.h15
-rw-r--r--sound/soc/soc-dapm.c157
2 files changed, 21 insertions, 151 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 3b991766a8f2..2ec14cb3ff1e 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -112,9 +112,7 @@ struct device;
112 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ 112 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
113 .kcontrol_news = wcontrols, .num_kcontrols = 1} 113 .kcontrol_news = wcontrols, .num_kcontrols = 1}
114#define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \ 114#define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \
115{ .id = snd_soc_dapm_value_mux, .name = wname, \ 115 SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols)
116 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
117 .kcontrol_news = wcontrols, .num_kcontrols = 1}
118 116
119/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ 117/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
120#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\ 118#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
@@ -324,11 +322,7 @@ struct device;
324 .put = xput, \ 322 .put = xput, \
325 .private_value = (unsigned long)&xenum } 323 .private_value = (unsigned long)&xenum }
326#define SOC_DAPM_VALUE_ENUM(xname, xenum) \ 324#define SOC_DAPM_VALUE_ENUM(xname, xenum) \
327{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 325 SOC_DAPM_ENUM(xname, xenum)
328 .info = snd_soc_info_enum_double, \
329 .get = snd_soc_dapm_get_value_enum_double, \
330 .put = snd_soc_dapm_put_value_enum_double, \
331 .private_value = (unsigned long)&xenum }
332#define SOC_DAPM_PIN_SWITCH(xname) \ 326#define SOC_DAPM_PIN_SWITCH(xname) \
333{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \ 327{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \
334 .info = snd_soc_dapm_info_pin_switch, \ 328 .info = snd_soc_dapm_info_pin_switch, \
@@ -396,10 +390,6 @@ int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_value *ucontrol); 390 struct snd_ctl_elem_value *ucontrol);
397int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, 391int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
398 struct snd_ctl_elem_value *ucontrol); 392 struct snd_ctl_elem_value *ucontrol);
399int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
400 struct snd_ctl_elem_value *ucontrol);
401int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol);
403int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol, 393int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
404 struct snd_ctl_elem_info *uinfo); 394 struct snd_ctl_elem_info *uinfo);
405int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, 395int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
@@ -486,7 +476,6 @@ enum snd_soc_dapm_type {
486 snd_soc_dapm_output, /* output pin */ 476 snd_soc_dapm_output, /* output pin */
487 snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */ 477 snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */
488 snd_soc_dapm_virt_mux, /* virtual version of snd_soc_dapm_mux */ 478 snd_soc_dapm_virt_mux, /* virtual version of snd_soc_dapm_mux */
489 snd_soc_dapm_value_mux, /* selects 1 analog signal from many inputs */
490 snd_soc_dapm_mixer, /* mixes several analog signals together */ 479 snd_soc_dapm_mixer, /* mixes several analog signals together */
491 snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */ 480 snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */
492 snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */ 481 snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 96a97a3dfb68..f23eeeeaafc5 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -71,7 +71,6 @@ static int dapm_up_seq[] = {
71 [snd_soc_dapm_mic] = 5, 71 [snd_soc_dapm_mic] = 5,
72 [snd_soc_dapm_mux] = 6, 72 [snd_soc_dapm_mux] = 6,
73 [snd_soc_dapm_virt_mux] = 6, 73 [snd_soc_dapm_virt_mux] = 6,
74 [snd_soc_dapm_value_mux] = 6,
75 [snd_soc_dapm_dac] = 7, 74 [snd_soc_dapm_dac] = 7,
76 [snd_soc_dapm_switch] = 8, 75 [snd_soc_dapm_switch] = 8,
77 [snd_soc_dapm_mixer] = 8, 76 [snd_soc_dapm_mixer] = 8,
@@ -103,7 +102,6 @@ static int dapm_down_seq[] = {
103 [snd_soc_dapm_micbias] = 8, 102 [snd_soc_dapm_micbias] = 8,
104 [snd_soc_dapm_mux] = 9, 103 [snd_soc_dapm_mux] = 9,
105 [snd_soc_dapm_virt_mux] = 9, 104 [snd_soc_dapm_virt_mux] = 9,
106 [snd_soc_dapm_value_mux] = 9,
107 [snd_soc_dapm_aif_in] = 10, 105 [snd_soc_dapm_aif_in] = 10,
108 [snd_soc_dapm_aif_out] = 10, 106 [snd_soc_dapm_aif_out] = 10,
109 [snd_soc_dapm_dai_in] = 10, 107 [snd_soc_dapm_dai_in] = 10,
@@ -534,7 +532,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
534 unsigned int val, item; 532 unsigned int val, item;
535 533
536 soc_widget_read(w, e->reg, &val); 534 soc_widget_read(w, e->reg, &val);
537 item = (val >> e->shift_l) & e->mask; 535 val = (val >> e->shift_l) & e->mask;
536 item = snd_soc_enum_val_to_item(e, val);
538 537
539 if (item < e->items && !strcmp(p->name, e->texts[item])) 538 if (item < e->items && !strcmp(p->name, e->texts[item]))
540 p->connect = 1; 539 p->connect = 1;
@@ -557,24 +556,6 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
557 p->connect = 1; 556 p->connect = 1;
558 } 557 }
559 break; 558 break;
560 case snd_soc_dapm_value_mux: {
561 struct soc_enum *e = (struct soc_enum *)
562 w->kcontrol_news[i].private_value;
563 unsigned int val, item;
564
565 soc_widget_read(w, e->reg, &val);
566 val = (val >> e->shift_l) & e->mask;
567 for (item = 0; item < e->items; item++) {
568 if (val == e->values[item])
569 break;
570 }
571
572 if (item < e->items && !strcmp(p->name, e->texts[item]))
573 p->connect = 1;
574 else
575 p->connect = 0;
576 }
577 break;
578 /* does not affect routing - always connected */ 559 /* does not affect routing - always connected */
579 case snd_soc_dapm_pga: 560 case snd_soc_dapm_pga:
580 case snd_soc_dapm_out_drv: 561 case snd_soc_dapm_out_drv:
@@ -725,7 +706,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
725 break; 706 break;
726 case snd_soc_dapm_mux: 707 case snd_soc_dapm_mux:
727 case snd_soc_dapm_virt_mux: 708 case snd_soc_dapm_virt_mux:
728 case snd_soc_dapm_value_mux:
729 wname_in_long_name = true; 709 wname_in_long_name = true;
730 kcname_in_long_name = false; 710 kcname_in_long_name = false;
731 break; 711 break;
@@ -2463,7 +2443,6 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
2463 return 0; 2443 return 0;
2464 case snd_soc_dapm_mux: 2444 case snd_soc_dapm_mux:
2465 case snd_soc_dapm_virt_mux: 2445 case snd_soc_dapm_virt_mux:
2466 case snd_soc_dapm_value_mux:
2467 ret = dapm_connect_mux(dapm, wsource, wsink, path, control, 2446 ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
2468 &wsink->kcontrol_news[0]); 2447 &wsink->kcontrol_news[0]);
2469 if (ret != 0) 2448 if (ret != 0)
@@ -2791,7 +2770,6 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
2791 break; 2770 break;
2792 case snd_soc_dapm_mux: 2771 case snd_soc_dapm_mux:
2793 case snd_soc_dapm_virt_mux: 2772 case snd_soc_dapm_virt_mux:
2794 case snd_soc_dapm_value_mux:
2795 dapm_new_mux(w); 2773 dapm_new_mux(w);
2796 break; 2774 break;
2797 case snd_soc_dapm_pga: 2775 case snd_soc_dapm_pga:
@@ -2953,13 +2931,16 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
2953{ 2931{
2954 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); 2932 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2955 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2933 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2956 unsigned int val; 2934 unsigned int reg_val, val;
2957 2935
2958 val = snd_soc_read(codec, e->reg); 2936 reg_val = snd_soc_read(codec, e->reg);
2959 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask; 2937 val = (reg_val >> e->shift_l) & e->mask;
2960 if (e->shift_l != e->shift_r) 2938 ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val);
2961 ucontrol->value.enumerated.item[1] = 2939 if (e->shift_l != e->shift_r) {
2962 (val >> e->shift_r) & e->mask; 2940 val = (reg_val >> e->shift_r) & e->mask;
2941 val = snd_soc_enum_val_to_item(e, val);
2942 ucontrol->value.enumerated.item[1] = val;
2943 }
2963 2944
2964 return 0; 2945 return 0;
2965} 2946}
@@ -2980,20 +2961,21 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2980 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); 2961 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2981 struct snd_soc_card *card = codec->card; 2962 struct snd_soc_card *card = codec->card;
2982 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2963 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2983 unsigned int val, mux, change; 2964 unsigned int *item = ucontrol->value.enumerated.item;
2965 unsigned int val, change;
2984 unsigned int mask; 2966 unsigned int mask;
2985 struct snd_soc_dapm_update update; 2967 struct snd_soc_dapm_update update;
2986 int ret = 0; 2968 int ret = 0;
2987 2969
2988 if (ucontrol->value.enumerated.item[0] >= e->items) 2970 if (item[0] >= e->items)
2989 return -EINVAL; 2971 return -EINVAL;
2990 mux = ucontrol->value.enumerated.item[0]; 2972
2991 val = mux << e->shift_l; 2973 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
2992 mask = e->mask << e->shift_l; 2974 mask = e->mask << e->shift_l;
2993 if (e->shift_l != e->shift_r) { 2975 if (e->shift_l != e->shift_r) {
2994 if (ucontrol->value.enumerated.item[1] >= e->items) 2976 if (item[1] > e->items)
2995 return -EINVAL; 2977 return -EINVAL;
2996 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 2978 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l;
2997 mask |= e->mask << e->shift_r; 2979 mask |= e->mask << e->shift_r;
2998 } 2980 }
2999 2981
@@ -3007,7 +2989,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
3007 update.val = val; 2989 update.val = val;
3008 card->update = &update; 2990 card->update = &update;
3009 2991
3010 ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); 2992 ret = soc_dapm_mux_update_power(card, kcontrol, item[0], e);
3011 2993
3012 card->update = NULL; 2994 card->update = NULL;
3013 } 2995 }
@@ -3074,106 +3056,6 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
3074EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt); 3056EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
3075 3057
3076/** 3058/**
3077 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
3078 * callback
3079 * @kcontrol: mixer control
3080 * @ucontrol: control element information
3081 *
3082 * Callback to get the value of a dapm semi enumerated double mixer control.
3083 *
3084 * Semi enumerated mixer: the enumerated items are referred as values. Can be
3085 * used for handling bitfield coded enumeration for example.
3086 *
3087 * Returns 0 for success.
3088 */
3089int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
3090 struct snd_ctl_elem_value *ucontrol)
3091{
3092 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
3093 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3094 unsigned int reg_val, val, mux;
3095
3096 reg_val = snd_soc_read(codec, e->reg);
3097 val = (reg_val >> e->shift_l) & e->mask;
3098 for (mux = 0; mux < e->items; mux++) {
3099 if (val == e->values[mux])
3100 break;
3101 }
3102 ucontrol->value.enumerated.item[0] = mux;
3103 if (e->shift_l != e->shift_r) {
3104 val = (reg_val >> e->shift_r) & e->mask;
3105 for (mux = 0; mux < e->items; mux++) {
3106 if (val == e->values[mux])
3107 break;
3108 }
3109 ucontrol->value.enumerated.item[1] = mux;
3110 }
3111
3112 return 0;
3113}
3114EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
3115
3116/**
3117 * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set
3118 * callback
3119 * @kcontrol: mixer control
3120 * @ucontrol: control element information
3121 *
3122 * Callback to set the value of a dapm semi enumerated double mixer control.
3123 *
3124 * Semi enumerated mixer: the enumerated items are referred as values. Can be
3125 * used for handling bitfield coded enumeration for example.
3126 *
3127 * Returns 0 for success.
3128 */
3129int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
3130 struct snd_ctl_elem_value *ucontrol)
3131{
3132 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
3133 struct snd_soc_card *card = codec->card;
3134 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3135 unsigned int val, mux, change;
3136 unsigned int mask;
3137 struct snd_soc_dapm_update update;
3138 int ret = 0;
3139
3140 if (ucontrol->value.enumerated.item[0] >= e->items)
3141 return -EINVAL;
3142 mux = ucontrol->value.enumerated.item[0];
3143 val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
3144 mask = e->mask << e->shift_l;
3145 if (e->shift_l != e->shift_r) {
3146 if (ucontrol->value.enumerated.item[1] >= e->items)
3147 return -EINVAL;
3148 val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
3149 mask |= e->mask << e->shift_r;
3150 }
3151
3152 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3153
3154 change = snd_soc_test_bits(codec, e->reg, mask, val);
3155 if (change) {
3156 update.kcontrol = kcontrol;
3157 update.reg = e->reg;
3158 update.mask = mask;
3159 update.val = val;
3160 card->update = &update;
3161
3162 ret = soc_dapm_mux_update_power(card, kcontrol, mux, e);
3163
3164 card->update = NULL;
3165 }
3166
3167 mutex_unlock(&card->dapm_mutex);
3168
3169 if (ret > 0)
3170 soc_dpcm_runtime_update(card);
3171
3172 return change;
3173}
3174EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
3175
3176/**
3177 * snd_soc_dapm_info_pin_switch - Info for a pin switch 3059 * snd_soc_dapm_info_pin_switch - Info for a pin switch
3178 * 3060 *
3179 * @kcontrol: mixer control 3061 * @kcontrol: mixer control
@@ -3302,7 +3184,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3302 break; 3184 break;
3303 case snd_soc_dapm_mux: 3185 case snd_soc_dapm_mux:
3304 case snd_soc_dapm_virt_mux: 3186 case snd_soc_dapm_virt_mux:
3305 case snd_soc_dapm_value_mux:
3306 w->power_check = dapm_generic_check_power; 3187 w->power_check = dapm_generic_check_power;
3307 break; 3188 break;
3308 case snd_soc_dapm_dai_out: 3189 case snd_soc_dapm_dai_out: