aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/mfld_machine.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/mfld_machine.c')
-rw-r--r--sound/soc/intel/mfld_machine.c108
1 files changed, 58 insertions, 50 deletions
diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/mfld_machine.c
index d3d4c32434f7..031d78783fc8 100644
--- a/sound/soc/intel/mfld_machine.c
+++ b/sound/soc/intel/mfld_machine.c
@@ -53,6 +53,7 @@ enum soc_mic_bias_zones {
53 53
54static unsigned int hs_switch; 54static unsigned int hs_switch;
55static unsigned int lo_dac; 55static unsigned int lo_dac;
56static struct snd_soc_codec *mfld_codec;
56 57
57struct mfld_mc_private { 58struct mfld_mc_private {
58 void __iomem *int_base; 59 void __iomem *int_base;
@@ -100,40 +101,47 @@ static int headset_get_switch(struct snd_kcontrol *kcontrol,
100static int headset_set_switch(struct snd_kcontrol *kcontrol, 101static int headset_set_switch(struct snd_kcontrol *kcontrol,
101 struct snd_ctl_elem_value *ucontrol) 102 struct snd_ctl_elem_value *ucontrol)
102{ 103{
103 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 104 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
105 struct snd_soc_dapm_context *dapm = &card->dapm;
104 106
105 if (ucontrol->value.integer.value[0] == hs_switch) 107 if (ucontrol->value.integer.value[0] == hs_switch)
106 return 0; 108 return 0;
107 109
110 snd_soc_dapm_mutex_lock(dapm);
111
108 if (ucontrol->value.integer.value[0]) { 112 if (ucontrol->value.integer.value[0]) {
109 pr_debug("hs_set HS path\n"); 113 pr_debug("hs_set HS path\n");
110 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones"); 114 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones");
111 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 115 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
112 } else { 116 } else {
113 pr_debug("hs_set EP path\n"); 117 pr_debug("hs_set EP path\n");
114 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); 118 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
115 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); 119 snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT");
116 } 120 }
117 snd_soc_dapm_sync(&codec->dapm); 121
122 snd_soc_dapm_sync_unlocked(dapm);
123
124 snd_soc_dapm_mutex_unlock(dapm);
125
118 hs_switch = ucontrol->value.integer.value[0]; 126 hs_switch = ucontrol->value.integer.value[0];
119 127
120 return 0; 128 return 0;
121} 129}
122 130
123static void lo_enable_out_pins(struct snd_soc_codec *codec) 131static void lo_enable_out_pins(struct snd_soc_dapm_context *dapm)
124{ 132{
125 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTL"); 133 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTL");
126 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTR"); 134 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTR");
127 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTL"); 135 snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTL");
128 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTR"); 136 snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTR");
129 snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT"); 137 snd_soc_dapm_enable_pin_unlocked(dapm, "VIB1OUT");
130 snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT"); 138 snd_soc_dapm_enable_pin_unlocked(dapm, "VIB2OUT");
131 if (hs_switch) { 139 if (hs_switch) {
132 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones"); 140 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones");
133 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 141 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
134 } else { 142 } else {
135 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); 143 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
136 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); 144 snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT");
137 } 145 }
138} 146}
139 147
@@ -147,45 +155,53 @@ static int lo_get_switch(struct snd_kcontrol *kcontrol,
147static int lo_set_switch(struct snd_kcontrol *kcontrol, 155static int lo_set_switch(struct snd_kcontrol *kcontrol,
148 struct snd_ctl_elem_value *ucontrol) 156 struct snd_ctl_elem_value *ucontrol)
149{ 157{
150 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 158 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
159 struct snd_soc_dapm_context *dapm = &card->dapm;
151 160
152 if (ucontrol->value.integer.value[0] == lo_dac) 161 if (ucontrol->value.integer.value[0] == lo_dac)
153 return 0; 162 return 0;
154 163
164 snd_soc_dapm_mutex_lock(dapm);
165
155 /* we dont want to work with last state of lineout so just enable all 166 /* we dont want to work with last state of lineout so just enable all
156 * pins and then disable pins not required 167 * pins and then disable pins not required
157 */ 168 */
158 lo_enable_out_pins(codec); 169 lo_enable_out_pins(dapm);
170
159 switch (ucontrol->value.integer.value[0]) { 171 switch (ucontrol->value.integer.value[0]) {
160 case 0: 172 case 0:
161 pr_debug("set vibra path\n"); 173 pr_debug("set vibra path\n");
162 snd_soc_dapm_disable_pin(&codec->dapm, "VIB1OUT"); 174 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB1OUT");
163 snd_soc_dapm_disable_pin(&codec->dapm, "VIB2OUT"); 175 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB2OUT");
164 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0); 176 snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0);
165 break; 177 break;
166 178
167 case 1: 179 case 1:
168 pr_debug("set hs path\n"); 180 pr_debug("set hs path\n");
169 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); 181 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
170 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 182 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
171 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22); 183 snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x22);
172 break; 184 break;
173 185
174 case 2: 186 case 2:
175 pr_debug("set spkr path\n"); 187 pr_debug("set spkr path\n");
176 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTL"); 188 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTL");
177 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTR"); 189 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTR");
178 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44); 190 snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x44);
179 break; 191 break;
180 192
181 case 3: 193 case 3:
182 pr_debug("set null path\n"); 194 pr_debug("set null path\n");
183 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTL"); 195 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTL");
184 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTR"); 196 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTR");
185 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66); 197 snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x66);
186 break; 198 break;
187 } 199 }
188 snd_soc_dapm_sync(&codec->dapm); 200
201 snd_soc_dapm_sync_unlocked(dapm);
202
203 snd_soc_dapm_mutex_unlock(dapm);
204
189 lo_dac = ucontrol->value.integer.value[0]; 205 lo_dac = ucontrol->value.integer.value[0];
190 return 0; 206 return 0;
191} 207}
@@ -221,26 +237,11 @@ static void mfld_jack_check(unsigned int intr_status)
221 237
222static int mfld_init(struct snd_soc_pcm_runtime *runtime) 238static int mfld_init(struct snd_soc_pcm_runtime *runtime)
223{ 239{
224 struct snd_soc_codec *codec = runtime->codec; 240 struct snd_soc_dapm_context *dapm = &runtime->card->dapm;
225 struct snd_soc_dapm_context *dapm = &codec->dapm;
226 int ret_val; 241 int ret_val;
227 242
228 /* Add jack sense widgets */ 243 mfld_codec = runtime->codec;
229 snd_soc_dapm_new_controls(dapm, mfld_widgets, ARRAY_SIZE(mfld_widgets));
230
231 /* Set up the map */
232 snd_soc_dapm_add_routes(dapm, mfld_map, ARRAY_SIZE(mfld_map));
233 244
234 /* always connected */
235 snd_soc_dapm_enable_pin(dapm, "Headphones");
236 snd_soc_dapm_enable_pin(dapm, "Mic");
237
238 ret_val = snd_soc_add_codec_controls(codec, mfld_snd_controls,
239 ARRAY_SIZE(mfld_snd_controls));
240 if (ret_val) {
241 pr_err("soc_add_controls failed %d", ret_val);
242 return ret_val;
243 }
244 /* default is earpiece pin, userspace sets it explcitly */ 245 /* default is earpiece pin, userspace sets it explcitly */
245 snd_soc_dapm_disable_pin(dapm, "Headphones"); 246 snd_soc_dapm_disable_pin(dapm, "Headphones");
246 /* default is lineout NC, userspace sets it explcitly */ 247 /* default is lineout NC, userspace sets it explcitly */
@@ -253,7 +254,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
253 snd_soc_dapm_disable_pin(dapm, "LINEINR"); 254 snd_soc_dapm_disable_pin(dapm, "LINEINR");
254 255
255 /* Headset and button jack detection */ 256 /* Headset and button jack detection */
256 ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack", 257 ret_val = snd_soc_jack_new(mfld_codec, "Intel(R) MID Audio Jack",
257 SND_JACK_HEADSET | SND_JACK_BTN_0 | 258 SND_JACK_HEADSET | SND_JACK_BTN_0 |
258 SND_JACK_BTN_1, &mfld_jack); 259 SND_JACK_BTN_1, &mfld_jack);
259 if (ret_val) { 260 if (ret_val) {
@@ -335,6 +336,13 @@ static struct snd_soc_card snd_soc_card_mfld = {
335 .owner = THIS_MODULE, 336 .owner = THIS_MODULE,
336 .dai_link = mfld_msic_dailink, 337 .dai_link = mfld_msic_dailink,
337 .num_links = ARRAY_SIZE(mfld_msic_dailink), 338 .num_links = ARRAY_SIZE(mfld_msic_dailink),
339
340 .controls = mfld_snd_controls,
341 .num_controls = ARRAY_SIZE(mfld_snd_controls),
342 .dapm_widgets = mfld_widgets,
343 .num_dapm_widgets = ARRAY_SIZE(mfld_widgets),
344 .dapm_routes = mfld_map,
345 .num_dapm_routes = ARRAY_SIZE(mfld_map),
338}; 346};
339 347
340static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev) 348static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev)