From c541c59f0460e037e6b8c6598a7b6d529f1e35ad Mon Sep 17 00:00:00 2001
From: Vladimir Karpovich <vkarpovich@motorola.com>
Date: Mon, 11 May 2015 14:35:40 -0500
Subject: [PATCH] asoc: fsa8500: Add extra delay to LINT detection

The moisture can cause false headset detection.In this case
the LINT detection will trigger several detect/undetect events.
Add 200ms debounce timeout to let it settle.

Change-Id: Ia2b4837cdf5194ca5c6de83c3a401c736542a183
Signed-off-by: Vladimir Karpovich <vkarpovich@motorola.com>
---
 sound/soc/codecs/fsa8500.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/sound/soc/codecs/fsa8500.c b/sound/soc/codecs/fsa8500.c
index 8b8622abfa15..20bf4a5f6e02 100644
--- a/sound/soc/codecs/fsa8500.c
+++ b/sound/soc/codecs/fsa8500.c
@@ -57,6 +57,7 @@
 				SND_JACK_BTN_6 | SND_JACK_BTN_7)
 
 #define	SND_JACK_BTN_SHIFT	20
+#define	FSA8500_LINT_DEBOUNCE	200
 
 static struct snd_soc_jack hs_jack;
 static struct snd_soc_jack button_jack;
@@ -632,6 +633,7 @@ static irqreturn_t fsa8500_irq_handler(int irq, void *data)
 
 static void fsa8500_det_thread(struct work_struct *work)
 {
+	u8 tmp_status[5];
 	struct fsa8500_data *irq_data =
 				i2c_get_clientdata(fsa8500_client);
 
@@ -639,11 +641,28 @@ static void fsa8500_det_thread(struct work_struct *work)
 	mutex_lock(&irq_data->lock);
 	wake_lock(&irq_data->wake_lock);
 
-	if (fsa8500_update_device_status(irq_data))
+	if (fsa8500_update_device_status(irq_data)) {
 		queue_delayed_work(irq_data->wq, &irq_data->work_det,
 					msecs_to_jiffies(2000));
-	fsa8500_report_hs(irq_data);
+		goto skip_report;
+	} else if ((irq_data->irq_status[0] & 0x2) &&
+			(irq_data->irq_status[0] & 0x7)) {
+		/* LINT detected, delay for 200ms*/
+		memcpy(tmp_status, irq_data->irq_status, sizeof(tmp_status));
+		msleep(FSA8500_LINT_DEBOUNCE);
+		fsa8500_update_device_status(irq_data);
+		if (irq_data->irq_status[0] & 0x18) {
+			/* Disconnect event in 200ms, retry in 2sec */
+			queue_delayed_work(irq_data->wq, &irq_data->work_det,
+					msecs_to_jiffies(2000));
+			goto skip_report;
+		} else
+			memcpy(irq_data->irq_status,
+				tmp_status, sizeof(tmp_status));
+	}
 
+	fsa8500_report_hs(irq_data);
+skip_report:
 	wake_unlock(&irq_data->wake_lock);
 	mutex_unlock(&irq_data->lock);
 }
-- 
GitLab