diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index bc12d097ef0d..15fcb1bb7148 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -3166,9 +3166,16 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3166 | 3166 | ||
3167 | /* If we have jackdet that will detect removal */ | 3167 | /* If we have jackdet that will detect removal */ |
3168 | if (wm8994->jackdet) { | 3168 | if (wm8994->jackdet) { |
3169 | mutex_lock(&wm8994->accdet_lock); | ||
3170 | |||
3169 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 3171 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
3170 | WM8958_MICD_ENA, 0); | 3172 | WM8958_MICD_ENA, 0); |
3171 | 3173 | ||
3174 | wm1811_jackdet_set_mode(codec, | ||
3175 | WM1811_JACKDET_MODE_JACK); | ||
3176 | |||
3177 | mutex_unlock(&wm8994->accdet_lock); | ||
3178 | |||
3172 | if (wm8994->pdata->jd_ext_cap) { | 3179 | if (wm8994->pdata->jd_ext_cap) { |
3173 | mutex_lock(&codec->mutex); | 3180 | mutex_lock(&codec->mutex); |
3174 | snd_soc_dapm_disable_pin(&codec->dapm, | 3181 | snd_soc_dapm_disable_pin(&codec->dapm, |
@@ -3176,9 +3183,6 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3176 | snd_soc_dapm_sync(&codec->dapm); | 3183 | snd_soc_dapm_sync(&codec->dapm); |
3177 | mutex_unlock(&codec->mutex); | 3184 | mutex_unlock(&codec->mutex); |
3178 | } | 3185 | } |
3179 | |||
3180 | wm1811_jackdet_set_mode(codec, | ||
3181 | WM1811_JACKDET_MODE_JACK); | ||
3182 | } | 3186 | } |
3183 | } | 3187 | } |
3184 | 3188 | ||
@@ -3213,6 +3217,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3213 | struct wm8994_priv *wm8994 = data; | 3217 | struct wm8994_priv *wm8994 = data; |
3214 | struct snd_soc_codec *codec = wm8994->codec; | 3218 | struct snd_soc_codec *codec = wm8994->codec; |
3215 | int reg; | 3219 | int reg; |
3220 | bool present; | ||
3216 | 3221 | ||
3217 | mutex_lock(&wm8994->accdet_lock); | 3222 | mutex_lock(&wm8994->accdet_lock); |
3218 | 3223 | ||
@@ -3225,11 +3230,10 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3225 | 3230 | ||
3226 | dev_dbg(codec->dev, "JACKDET %x\n", reg); | 3231 | dev_dbg(codec->dev, "JACKDET %x\n", reg); |
3227 | 3232 | ||
3228 | if (reg & WM1811_JACKDET_LVL) { | 3233 | present = reg & WM1811_JACKDET_LVL; |
3229 | dev_dbg(codec->dev, "Jack detected\n"); | ||
3230 | 3234 | ||
3231 | snd_soc_jack_report(wm8994->micdet[0].jack, | 3235 | if (present) { |
3232 | SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); | 3236 | dev_dbg(codec->dev, "Jack detected\n"); |
3233 | 3237 | ||
3234 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | 3238 | snd_soc_update_bits(codec, WM8958_MICBIAS2, |
3235 | WM8958_MICB2_DISCH, 0); | 3239 | WM8958_MICB2_DISCH, 0); |
@@ -3247,32 +3251,12 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3247 | 3251 | ||
3248 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 3252 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
3249 | WM8958_MICD_ENA, WM8958_MICD_ENA); | 3253 | WM8958_MICD_ENA, WM8958_MICD_ENA); |
3250 | |||
3251 | /* If required for an external cap force MICBIAS on */ | ||
3252 | if (wm8994->pdata->jd_ext_cap) { | ||
3253 | mutex_lock(&codec->mutex); | ||
3254 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
3255 | "MICBIAS2"); | ||
3256 | snd_soc_dapm_sync(&codec->dapm); | ||
3257 | mutex_unlock(&codec->mutex); | ||
3258 | } | ||
3259 | } else { | 3254 | } else { |
3260 | dev_dbg(codec->dev, "Jack not detected\n"); | 3255 | dev_dbg(codec->dev, "Jack not detected\n"); |
3261 | 3256 | ||
3262 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | 3257 | snd_soc_update_bits(codec, WM8958_MICBIAS2, |
3263 | WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); | 3258 | WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); |
3264 | 3259 | ||
3265 | if (wm8994->pdata->jd_ext_cap) { | ||
3266 | mutex_lock(&codec->mutex); | ||
3267 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); | ||
3268 | snd_soc_dapm_sync(&codec->dapm); | ||
3269 | mutex_unlock(&codec->mutex); | ||
3270 | } | ||
3271 | |||
3272 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | ||
3273 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | | ||
3274 | wm8994->btn_mask); | ||
3275 | |||
3276 | /* Enable debounce while removed */ | 3260 | /* Enable debounce while removed */ |
3277 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, | 3261 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, |
3278 | WM1811_JACKDET_DB, WM1811_JACKDET_DB); | 3262 | WM1811_JACKDET_DB, WM1811_JACKDET_DB); |
@@ -3286,6 +3270,28 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3286 | 3270 | ||
3287 | mutex_unlock(&wm8994->accdet_lock); | 3271 | mutex_unlock(&wm8994->accdet_lock); |
3288 | 3272 | ||
3273 | /* If required for an external cap force MICBIAS on */ | ||
3274 | if (wm8994->pdata->jd_ext_cap) { | ||
3275 | mutex_lock(&codec->mutex); | ||
3276 | |||
3277 | if (present) | ||
3278 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
3279 | "MICBIAS2"); | ||
3280 | else | ||
3281 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); | ||
3282 | |||
3283 | snd_soc_dapm_sync(&codec->dapm); | ||
3284 | mutex_unlock(&codec->mutex); | ||
3285 | } | ||
3286 | |||
3287 | if (present) | ||
3288 | snd_soc_jack_report(wm8994->micdet[0].jack, | ||
3289 | SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); | ||
3290 | else | ||
3291 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | ||
3292 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | | ||
3293 | wm8994->btn_mask); | ||
3294 | |||
3289 | return IRQ_HANDLED; | 3295 | return IRQ_HANDLED; |
3290 | } | 3296 | } |
3291 | 3297 | ||
@@ -3389,17 +3395,13 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3389 | struct snd_soc_codec *codec = wm8994->codec; | 3395 | struct snd_soc_codec *codec = wm8994->codec; |
3390 | int reg, count; | 3396 | int reg, count; |
3391 | 3397 | ||
3392 | mutex_lock(&wm8994->accdet_lock); | ||
3393 | |||
3394 | /* | 3398 | /* |
3395 | * Jack detection may have detected a removal simulataneously | 3399 | * Jack detection may have detected a removal simulataneously |
3396 | * with an update of the MICDET status; if so it will have | 3400 | * with an update of the MICDET status; if so it will have |
3397 | * stopped detection and we can ignore this interrupt. | 3401 | * stopped detection and we can ignore this interrupt. |
3398 | */ | 3402 | */ |
3399 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) { | 3403 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) |
3400 | mutex_unlock(&wm8994->accdet_lock); | ||
3401 | return IRQ_HANDLED; | 3404 | return IRQ_HANDLED; |
3402 | } | ||
3403 | 3405 | ||
3404 | /* We may occasionally read a detection without an impedence | 3406 | /* We may occasionally read a detection without an impedence |
3405 | * range being provided - if that happens loop again. | 3407 | * range being provided - if that happens loop again. |
@@ -3408,7 +3410,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3408 | do { | 3410 | do { |
3409 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); | 3411 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); |
3410 | if (reg < 0) { | 3412 | if (reg < 0) { |
3411 | mutex_unlock(&wm8994->accdet_lock); | ||
3412 | dev_err(codec->dev, | 3413 | dev_err(codec->dev, |
3413 | "Failed to read mic detect status: %d\n", | 3414 | "Failed to read mic detect status: %d\n", |
3414 | reg); | 3415 | reg); |
@@ -3439,8 +3440,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3439 | dev_warn(codec->dev, "Accessory detection with no callback\n"); | 3440 | dev_warn(codec->dev, "Accessory detection with no callback\n"); |
3440 | 3441 | ||
3441 | out: | 3442 | out: |
3442 | mutex_unlock(&wm8994->accdet_lock); | ||
3443 | |||
3444 | return IRQ_HANDLED; | 3443 | return IRQ_HANDLED; |
3445 | } | 3444 | } |
3446 | 3445 | ||