diff options
-rw-r--r-- | sound/soc/codecs/max9877.c | 96 |
1 files changed, 63 insertions, 33 deletions
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index 7df9a7c0208b..a1f1119e1b7a 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c | |||
@@ -34,16 +34,16 @@ static int max9877_get_reg(struct snd_kcontrol *kcontrol, | |||
34 | { | 34 | { |
35 | struct soc_mixer_control *mc = | 35 | struct soc_mixer_control *mc = |
36 | (struct soc_mixer_control *)kcontrol->private_value; | 36 | (struct soc_mixer_control *)kcontrol->private_value; |
37 | int reg = mc->reg; | 37 | unsigned int reg = mc->reg; |
38 | int reg2 = mc->rreg; | 38 | unsigned int shift = mc->shift; |
39 | int shift = mc->shift; | 39 | unsigned int mask = mc->max; |
40 | int mask = mc->max; | 40 | unsigned int invert = mc->invert; |
41 | 41 | ||
42 | ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask; | 42 | ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask; |
43 | 43 | ||
44 | if (reg2) | 44 | if (invert) |
45 | ucontrol->value.integer.value[1] = | 45 | ucontrol->value.integer.value[0] = |
46 | (max9877_regs[reg2] >> shift) & mask; | 46 | mask - ucontrol->value.integer.value[0]; |
47 | 47 | ||
48 | return 0; | 48 | return 0; |
49 | } | 49 | } |
@@ -53,39 +53,69 @@ static int max9877_set_reg(struct snd_kcontrol *kcontrol, | |||
53 | { | 53 | { |
54 | struct soc_mixer_control *mc = | 54 | struct soc_mixer_control *mc = |
55 | (struct soc_mixer_control *)kcontrol->private_value; | 55 | (struct soc_mixer_control *)kcontrol->private_value; |
56 | int reg = mc->reg; | 56 | unsigned int reg = mc->reg; |
57 | int reg2 = mc->rreg; | 57 | unsigned int shift = mc->shift; |
58 | int shift = mc->shift; | 58 | unsigned int mask = mc->max; |
59 | int mask = mc->max; | 59 | unsigned int invert = mc->invert; |
60 | int change = 1; | 60 | unsigned int val = (ucontrol->value.integer.value[0] & mask); |
61 | int change2 = 1; | 61 | |
62 | int ret = 0; | 62 | if (invert) |
63 | 63 | val = mask - val; | |
64 | if (((max9877_regs[reg] >> shift) & mask) == | 64 | |
65 | ucontrol->value.integer.value[0]) | 65 | if (((max9877_regs[reg] >> shift) & mask) == val) |
66 | return 0; | ||
67 | |||
68 | max9877_regs[reg] &= ~(mask << shift); | ||
69 | max9877_regs[reg] |= val << shift; | ||
70 | max9877_write_regs(); | ||
71 | |||
72 | return 1; | ||
73 | } | ||
74 | |||
75 | static int max9877_get_2reg(struct snd_kcontrol *kcontrol, | ||
76 | struct snd_ctl_elem_value *ucontrol) | ||
77 | { | ||
78 | struct soc_mixer_control *mc = | ||
79 | (struct soc_mixer_control *)kcontrol->private_value; | ||
80 | unsigned int reg = mc->reg; | ||
81 | unsigned int reg2 = mc->rreg; | ||
82 | unsigned int shift = mc->shift; | ||
83 | unsigned int mask = mc->max; | ||
84 | |||
85 | ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask; | ||
86 | ucontrol->value.integer.value[1] = (max9877_regs[reg2] >> shift) & mask; | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int max9877_set_2reg(struct snd_kcontrol *kcontrol, | ||
92 | struct snd_ctl_elem_value *ucontrol) | ||
93 | { | ||
94 | struct soc_mixer_control *mc = | ||
95 | (struct soc_mixer_control *)kcontrol->private_value; | ||
96 | unsigned int reg = mc->reg; | ||
97 | unsigned int reg2 = mc->rreg; | ||
98 | unsigned int shift = mc->shift; | ||
99 | unsigned int mask = mc->max; | ||
100 | unsigned int val = (ucontrol->value.integer.value[0] & mask); | ||
101 | unsigned int val2 = (ucontrol->value.integer.value[1] & mask); | ||
102 | unsigned int change = 1; | ||
103 | |||
104 | if (((max9877_regs[reg] >> shift) & mask) == val) | ||
66 | change = 0; | 105 | change = 0; |
67 | 106 | ||
68 | if (reg2) | 107 | if (((max9877_regs[reg2] >> shift) & mask) == val2) |
69 | if (((max9877_regs[reg2] >> shift) & mask) == | 108 | change = 0; |
70 | ucontrol->value.integer.value[1]) | ||
71 | change2 = 0; | ||
72 | 109 | ||
73 | if (change) { | 110 | if (change) { |
74 | max9877_regs[reg] &= ~(mask << shift); | 111 | max9877_regs[reg] &= ~(mask << shift); |
75 | max9877_regs[reg] |= ucontrol->value.integer.value[0] << shift; | 112 | max9877_regs[reg] |= val << shift; |
76 | ret = change; | ||
77 | } | ||
78 | |||
79 | if (reg2 && change2) { | ||
80 | max9877_regs[reg2] &= ~(mask << shift); | 113 | max9877_regs[reg2] &= ~(mask << shift); |
81 | max9877_regs[reg2] |= ucontrol->value.integer.value[1] << shift; | 114 | max9877_regs[reg2] |= val2 << shift; |
82 | ret = change2; | ||
83 | } | ||
84 | |||
85 | if (ret) | ||
86 | max9877_write_regs(); | 115 | max9877_write_regs(); |
116 | } | ||
87 | 117 | ||
88 | return ret; | 118 | return change; |
89 | } | 119 | } |
90 | 120 | ||
91 | static int max9877_get_out_mode(struct snd_kcontrol *kcontrol, | 121 | static int max9877_get_out_mode(struct snd_kcontrol *kcontrol, |
@@ -190,7 +220,7 @@ static const struct snd_kcontrol_new max9877_controls[] = { | |||
190 | max9877_get_reg, max9877_set_reg, max9877_output_tlv), | 220 | max9877_get_reg, max9877_set_reg, max9877_output_tlv), |
191 | SOC_DOUBLE_R_EXT_TLV("MAX9877 Amp HP Playback Volume", | 221 | SOC_DOUBLE_R_EXT_TLV("MAX9877 Amp HP Playback Volume", |
192 | MAX9877_HPL_VOLUME, MAX9877_HPR_VOLUME, 0, 31, 0, | 222 | MAX9877_HPL_VOLUME, MAX9877_HPR_VOLUME, 0, 31, 0, |
193 | max9877_get_reg, max9877_set_reg, max9877_output_tlv), | 223 | max9877_get_2reg, max9877_set_2reg, max9877_output_tlv), |
194 | SOC_SINGLE_EXT("MAX9877 INB Stereo Switch", | 224 | SOC_SINGLE_EXT("MAX9877 INB Stereo Switch", |
195 | MAX9877_INPUT_MODE, 4, 1, 1, | 225 | MAX9877_INPUT_MODE, 4, 1, 1, |
196 | max9877_get_reg, max9877_set_reg), | 226 | max9877_get_reg, max9877_set_reg), |