aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/max9877.c96
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
75static 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
91static 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
91static int max9877_get_out_mode(struct snd_kcontrol *kcontrol, 121static 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),