diff options
Diffstat (limited to 'sound/soc/intel/mfld_machine.c')
-rw-r--r-- | sound/soc/intel/mfld_machine.c | 108 |
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 | ||
54 | static unsigned int hs_switch; | 54 | static unsigned int hs_switch; |
55 | static unsigned int lo_dac; | 55 | static unsigned int lo_dac; |
56 | static struct snd_soc_codec *mfld_codec; | ||
56 | 57 | ||
57 | struct mfld_mc_private { | 58 | struct 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, | |||
100 | static int headset_set_switch(struct snd_kcontrol *kcontrol, | 101 | static 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 | ||
123 | static void lo_enable_out_pins(struct snd_soc_codec *codec) | 131 | static 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, | |||
147 | static int lo_set_switch(struct snd_kcontrol *kcontrol, | 155 | static 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 | ||
222 | static int mfld_init(struct snd_soc_pcm_runtime *runtime) | 238 | static 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 | ||
340 | static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev) | 348 | static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev) |