aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic3x.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tlv320aic3x.c')
-rw-r--r--sound/soc/codecs/tlv320aic3x.c56
1 files changed, 21 insertions, 35 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index e5b926883131..6e3f269243e0 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -138,8 +138,7 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
138static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, 138static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
139 struct snd_ctl_elem_value *ucontrol) 139 struct snd_ctl_elem_value *ucontrol)
140{ 140{
141 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 141 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
142 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
143 struct soc_mixer_control *mc = 142 struct soc_mixer_control *mc =
144 (struct soc_mixer_control *)kcontrol->private_value; 143 (struct soc_mixer_control *)kcontrol->private_value;
145 unsigned int reg = mc->reg; 144 unsigned int reg = mc->reg;
@@ -147,10 +146,9 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
147 int max = mc->max; 146 int max = mc->max;
148 unsigned int mask = (1 << fls(max)) - 1; 147 unsigned int mask = (1 << fls(max)) - 1;
149 unsigned int invert = mc->invert; 148 unsigned int invert = mc->invert;
150 unsigned short val, val_mask; 149 unsigned short val;
151 int ret; 150 struct snd_soc_dapm_update update;
152 struct snd_soc_dapm_path *path; 151 int connect, change;
153 int found = 0;
154 152
155 val = (ucontrol->value.integer.value[0] & mask); 153 val = (ucontrol->value.integer.value[0] & mask);
156 154
@@ -158,42 +156,26 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
158 if (val) 156 if (val)
159 val = mask; 157 val = mask;
160 158
159 connect = !!val;
160
161 if (invert) 161 if (invert)
162 val = mask - val; 162 val = mask - val;
163 val_mask = mask << shift;
164 val = val << shift;
165
166 mutex_lock(&widget->codec->mutex);
167 163
168 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { 164 mask <<= shift;
169 /* find dapm widget path assoc with kcontrol */ 165 val <<= shift;
170 list_for_each_entry(path, &widget->dapm->card->paths, list) {
171 if (path->kcontrol != kcontrol)
172 continue;
173 166
174 /* found, now check type */ 167 change = snd_soc_test_bits(codec, val, mask, reg);
175 found = 1; 168 if (change) {
176 if (val) 169 update.kcontrol = kcontrol;
177 /* new connection */ 170 update.reg = reg;
178 path->connect = invert ? 0 : 1; 171 update.mask = mask;
179 else 172 update.val = val;
180 /* old connection must be powered down */
181 path->connect = invert ? 1 : 0;
182 173
183 dapm_mark_dirty(path->source, "tlv320aic3x source"); 174 snd_soc_dapm_mixer_update_power(&codec->dapm, kcontrol, connect,
184 dapm_mark_dirty(path->sink, "tlv320aic3x sink"); 175 &update);
185
186 break;
187 }
188 } 176 }
189 177
190 mutex_unlock(&widget->codec->mutex); 178 return change;
191
192 if (found)
193 snd_soc_dapm_sync(widget->dapm);
194
195 ret = snd_soc_update_bits_locked(widget->codec, reg, val_mask, val);
196 return ret;
197} 179}
198 180
199/* 181/*
@@ -1492,6 +1474,7 @@ static const struct i2c_device_id aic3x_i2c_id[] = {
1492 { "tlv320aic3x", AIC3X_MODEL_3X }, 1474 { "tlv320aic3x", AIC3X_MODEL_3X },
1493 { "tlv320aic33", AIC3X_MODEL_33 }, 1475 { "tlv320aic33", AIC3X_MODEL_33 },
1494 { "tlv320aic3007", AIC3X_MODEL_3007 }, 1476 { "tlv320aic3007", AIC3X_MODEL_3007 },
1477 { "tlv320aic3106", AIC3X_MODEL_3X },
1495 { } 1478 { }
1496}; 1479};
1497MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); 1480MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
@@ -1582,6 +1565,9 @@ static int aic3x_i2c_remove(struct i2c_client *client)
1582#if defined(CONFIG_OF) 1565#if defined(CONFIG_OF)
1583static const struct of_device_id tlv320aic3x_of_match[] = { 1566static const struct of_device_id tlv320aic3x_of_match[] = {
1584 { .compatible = "ti,tlv320aic3x", }, 1567 { .compatible = "ti,tlv320aic3x", },
1568 { .compatible = "ti,tlv320aic33" },
1569 { .compatible = "ti,tlv320aic3007" },
1570 { .compatible = "ti,tlv320aic3106" },
1585 {}, 1571 {},
1586}; 1572};
1587MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match); 1573MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match);