diff options
-rw-r--r-- | include/sound/soc-dapm.h | 4 | ||||
-rw-r--r-- | include/sound/soc.h | 3 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 45 |
3 files changed, 33 insertions, 19 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 27a72d5d4b00..2037c45adfe6 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
@@ -286,6 +286,8 @@ struct device; | |||
286 | .info = snd_soc_info_volsw, \ | 286 | .info = snd_soc_info_volsw, \ |
287 | .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ | 287 | .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ |
288 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) } | 288 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) } |
289 | #define SOC_DAPM_SINGLE_VIRT(xname, max) \ | ||
290 | SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0) | ||
289 | #define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ | 291 | #define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ |
290 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 292 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
291 | .info = snd_soc_info_volsw, \ | 293 | .info = snd_soc_info_volsw, \ |
@@ -300,6 +302,8 @@ struct device; | |||
300 | .tlv.p = (tlv_array), \ | 302 | .tlv.p = (tlv_array), \ |
301 | .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ | 303 | .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ |
302 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) } | 304 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) } |
305 | #define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array) \ | ||
306 | SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0, tlv_array) | ||
303 | #define SOC_DAPM_ENUM(xname, xenum) \ | 307 | #define SOC_DAPM_ENUM(xname, xenum) \ |
304 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 308 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
305 | .info = snd_soc_info_enum_double, \ | 309 | .info = snd_soc_info_enum_double, \ |
diff --git a/include/sound/soc.h b/include/sound/soc.h index d22cb0a06feb..b429dba57bf6 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -1088,7 +1088,8 @@ struct snd_soc_pcm_runtime { | |||
1088 | /* mixer control */ | 1088 | /* mixer control */ |
1089 | struct soc_mixer_control { | 1089 | struct soc_mixer_control { |
1090 | int min, max, platform_max; | 1090 | int min, max, platform_max; |
1091 | unsigned int reg, rreg, shift, rshift; | 1091 | int reg, rreg; |
1092 | unsigned int shift, rshift; | ||
1092 | unsigned int invert:1; | 1093 | unsigned int invert:1; |
1093 | unsigned int autodisable:1; | 1094 | unsigned int autodisable:1; |
1094 | }; | 1095 | }; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 177f8a1938da..9273216f22fc 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -499,18 +499,22 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
499 | int val; | 499 | int val; |
500 | struct soc_mixer_control *mc = (struct soc_mixer_control *) | 500 | struct soc_mixer_control *mc = (struct soc_mixer_control *) |
501 | w->kcontrol_news[i].private_value; | 501 | w->kcontrol_news[i].private_value; |
502 | unsigned int reg = mc->reg; | 502 | int reg = mc->reg; |
503 | unsigned int shift = mc->shift; | 503 | unsigned int shift = mc->shift; |
504 | int max = mc->max; | 504 | int max = mc->max; |
505 | unsigned int mask = (1 << fls(max)) - 1; | 505 | unsigned int mask = (1 << fls(max)) - 1; |
506 | unsigned int invert = mc->invert; | 506 | unsigned int invert = mc->invert; |
507 | 507 | ||
508 | val = soc_widget_read(w, reg); | 508 | if (reg != SND_SOC_NOPM) { |
509 | val = (val >> shift) & mask; | 509 | val = soc_widget_read(w, reg); |
510 | if (invert) | 510 | val = (val >> shift) & mask; |
511 | val = max - val; | 511 | if (invert) |
512 | val = max - val; | ||
513 | p->connect = !!val; | ||
514 | } else { | ||
515 | p->connect = 0; | ||
516 | } | ||
512 | 517 | ||
513 | p->connect = !!val; | ||
514 | } | 518 | } |
515 | break; | 519 | break; |
516 | case snd_soc_dapm_mux: { | 520 | case snd_soc_dapm_mux: { |
@@ -2792,7 +2796,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, | |||
2792 | struct snd_soc_card *card = codec->card; | 2796 | struct snd_soc_card *card = codec->card; |
2793 | struct soc_mixer_control *mc = | 2797 | struct soc_mixer_control *mc = |
2794 | (struct soc_mixer_control *)kcontrol->private_value; | 2798 | (struct soc_mixer_control *)kcontrol->private_value; |
2795 | unsigned int reg = mc->reg; | 2799 | int reg = mc->reg; |
2796 | unsigned int shift = mc->shift; | 2800 | unsigned int shift = mc->shift; |
2797 | int max = mc->max; | 2801 | int max = mc->max; |
2798 | unsigned int mask = (1 << fls(max)) - 1; | 2802 | unsigned int mask = (1 << fls(max)) - 1; |
@@ -2805,7 +2809,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, | |||
2805 | kcontrol->id.name); | 2809 | kcontrol->id.name); |
2806 | 2810 | ||
2807 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | 2811 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); |
2808 | if (dapm_kcontrol_is_powered(kcontrol)) | 2812 | if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM) |
2809 | val = (snd_soc_read(codec, reg) >> shift) & mask; | 2813 | val = (snd_soc_read(codec, reg) >> shift) & mask; |
2810 | else | 2814 | else |
2811 | val = dapm_kcontrol_get_value(kcontrol); | 2815 | val = dapm_kcontrol_get_value(kcontrol); |
@@ -2836,7 +2840,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
2836 | struct snd_soc_card *card = codec->card; | 2840 | struct snd_soc_card *card = codec->card; |
2837 | struct soc_mixer_control *mc = | 2841 | struct soc_mixer_control *mc = |
2838 | (struct soc_mixer_control *)kcontrol->private_value; | 2842 | (struct soc_mixer_control *)kcontrol->private_value; |
2839 | unsigned int reg = mc->reg; | 2843 | int reg = mc->reg; |
2840 | unsigned int shift = mc->shift; | 2844 | unsigned int shift = mc->shift; |
2841 | int max = mc->max; | 2845 | int max = mc->max; |
2842 | unsigned int mask = (1 << fls(max)) - 1; | 2846 | unsigned int mask = (1 << fls(max)) - 1; |
@@ -2858,19 +2862,24 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
2858 | 2862 | ||
2859 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | 2863 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); |
2860 | 2864 | ||
2861 | dapm_kcontrol_set_value(kcontrol, val); | 2865 | change = dapm_kcontrol_set_value(kcontrol, val); |
2862 | 2866 | ||
2863 | mask = mask << shift; | 2867 | if (reg != SND_SOC_NOPM) { |
2864 | val = val << shift; | 2868 | mask = mask << shift; |
2869 | val = val << shift; | ||
2870 | |||
2871 | change = snd_soc_test_bits(codec, reg, mask, val); | ||
2872 | } | ||
2865 | 2873 | ||
2866 | change = snd_soc_test_bits(codec, reg, mask, val); | ||
2867 | if (change) { | 2874 | if (change) { |
2868 | update.kcontrol = kcontrol; | 2875 | if (reg != SND_SOC_NOPM) { |
2869 | update.reg = reg; | 2876 | update.kcontrol = kcontrol; |
2870 | update.mask = mask; | 2877 | update.reg = reg; |
2871 | update.val = val; | 2878 | update.mask = mask; |
2879 | update.val = val; | ||
2872 | 2880 | ||
2873 | card->update = &update; | 2881 | card->update = &update; |
2882 | } | ||
2874 | 2883 | ||
2875 | soc_dapm_mixer_update_power(card, kcontrol, connect); | 2884 | soc_dapm_mixer_update_power(card, kcontrol, connect); |
2876 | 2885 | ||