ASoC: wcd9310: Add plug detection through mechanical switch
Use mechanical switch on the phone jack to detect headset/headphone
insertion and removal. Mechanical switch is beneficial to avoid fake
button press and high impedance microphone headset detection.
CRs-fixed: 341402
Change-Id: Idffba14316ab25e07736d1b7385f0edb16216089
Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c
index c1febcf..ba3c1e8 100644
--- a/drivers/mfd/wcd9xxx-irq.c
+++ b/drivers/mfd/wcd9xxx-irq.c
@@ -100,7 +100,7 @@
}
EXPORT_SYMBOL_GPL(wcd9xxx_pm_cmpxchg);
-void wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx)
+bool wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx)
{
enum wcd9xxx_pm_state os;
@@ -111,10 +111,12 @@
* so need to embrace wlock_holders with mutex.
*/
mutex_lock(&wcd9xxx->pm_lock);
- if (wcd9xxx->wlock_holders++ == 0)
+ if (wcd9xxx->wlock_holders++ == 0) {
+ pr_debug("%s: holding wake lock\n", __func__);
wake_lock(&wcd9xxx->wlock);
+ }
mutex_unlock(&wcd9xxx->pm_lock);
- while (!wait_event_timeout(wcd9xxx->pm_wq,
+ if (!wait_event_timeout(wcd9xxx->pm_wq,
((os = wcd9xxx_pm_cmpxchg(wcd9xxx, WCD9XXX_PM_SLEEPABLE,
WCD9XXX_PM_AWAKE)) ==
WCD9XXX_PM_SLEEPABLE ||
@@ -123,9 +125,12 @@
pr_err("%s: system didn't resume within 5000ms, state %d, "
"wlock %d\n", __func__, wcd9xxx->pm_state,
wcd9xxx->wlock_holders);
- WARN_ON_ONCE(1);
+ WARN_ON(1);
+ wcd9xxx_unlock_sleep(wcd9xxx);
+ return false;
}
wake_up_all(&wcd9xxx->pm_wq);
+ return true;
}
EXPORT_SYMBOL_GPL(wcd9xxx_lock_sleep);
@@ -134,6 +139,7 @@
mutex_lock(&wcd9xxx->pm_lock);
if (--wcd9xxx->wlock_holders == 0) {
wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
+ pr_debug("%s: releasing wake lock\n", __func__);
wake_unlock(&wcd9xxx->wlock);
}
mutex_unlock(&wcd9xxx->pm_lock);
@@ -166,7 +172,10 @@
u8 status[WCD9XXX_NUM_IRQ_REGS];
int i;
- wcd9xxx_lock_sleep(wcd9xxx);
+ if (unlikely(wcd9xxx_lock_sleep(wcd9xxx) == false)) {
+ dev_err(wcd9xxx->dev, "Failed to hold suspend\n");
+ return IRQ_NONE;
+ }
ret = wcd9xxx_bulk_read(wcd9xxx, TABLA_A_INTR_STATUS0,
WCD9XXX_NUM_IRQ_REGS, status);
if (ret < 0) {