ASoC: wcd9xxx: don't clear pending mbhc interrupt
Clear mbhc irq before dispatching it to avoid lost irq when the same
irq asserts while driver is handling previous one.
CRs-fixed: 488535
Change-Id: I43ff7553258c0e8b260f233bbb064a5b8f118120
Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index e6c68a2..3d0abce 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -283,14 +283,6 @@
},
};
-
-enum wcd9xxx_chipid_major {
- TABLA_MAJOR = cpu_to_le16(0x100),
- SITAR_MAJOR = cpu_to_le16(0x101),
- TAIKO_MAJOR = cpu_to_le16(0x102),
- TAPAN_MAJOR = cpu_to_le16(0x103),
-};
-
static const struct wcd9xxx_codec_type wcd9xxx_codecs[] = {
{
TABLA_MAJOR, cpu_to_le16(0x1), tabla1x_devs,
diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c
index 5efd905..062351d 100644
--- a/drivers/mfd/wcd9xxx-irq.c
+++ b/drivers/mfd/wcd9xxx-irq.c
@@ -193,10 +193,24 @@
mutex_unlock(&wcd9xxx->nested_irq_lock);
}
-static void wcd9xxx_irq_dispatch(struct wcd9xxx *wcd9xxx, int irqbit)
+static bool wcd9xxx_is_mbhc_irq(struct wcd9xxx *wcd9xxx, int irqbit)
{
if ((irqbit <= WCD9XXX_IRQ_MBHC_INSERTION) &&
- (irqbit >= WCD9XXX_IRQ_MBHC_REMOVAL)) {
+ (irqbit >= WCD9XXX_IRQ_MBHC_REMOVAL))
+ return true;
+ else if (wcd9xxx->codec_type->id_major == TAIKO_MAJOR &&
+ irqbit == WCD9320_IRQ_MBHC_JACK_SWITCH)
+ return true;
+ else if (wcd9xxx->codec_type->id_major == TAPAN_MAJOR &&
+ irqbit == WCD9306_IRQ_MBHC_JACK_SWITCH)
+ return true;
+ else
+ return false;
+}
+
+static void wcd9xxx_irq_dispatch(struct wcd9xxx *wcd9xxx, int irqbit)
+{
+ if (wcd9xxx_is_mbhc_irq(wcd9xxx, irqbit)) {
wcd9xxx_nested_irq_lock(wcd9xxx);
wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_INTR_CLEAR0 +
BIT_BYTE(irqbit),
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index 0d1f49f..e688bd9 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -76,7 +76,8 @@
WCD9XXX_IRQ_EAR_PA_OCPL_FAULT,
WCD9XXX_IRQ_HPH_L_PA_STARTUP,
WCD9XXX_IRQ_HPH_R_PA_STARTUP,
- WCD9XXX_IRQ_EAR_PA_STARTUP,
+ WCD9320_IRQ_EAR_PA_STARTUP,
+ WCD9306_IRQ_MBHC_JACK_SWITCH = WCD9320_IRQ_EAR_PA_STARTUP,
WCD9310_NUM_IRQS,
WCD9XXX_IRQ_RESERVED_0 = WCD9310_NUM_IRQS,
WCD9XXX_IRQ_RESERVED_1,
@@ -85,7 +86,7 @@
WCD9XXX_IRQ_MAD_BEACON,
WCD9XXX_IRQ_MAD_ULTRASOUND,
WCD9XXX_IRQ_SPEAKER_CLIPPING,
- WCD9XXX_IRQ_MBHC_JACK_SWITCH,
+ WCD9320_IRQ_MBHC_JACK_SWITCH,
WCD9XXX_IRQ_VBAT_MONITOR_ATTACK,
WCD9XXX_IRQ_VBAT_MONITOR_RELEASE,
WCD9XXX_NUM_IRQS,
@@ -153,6 +154,13 @@
#define WCD9XXX_CH(xport, xshift) \
{.port = xport, .shift = xshift}
+enum wcd9xxx_chipid_major {
+ TABLA_MAJOR = cpu_to_le16(0x100),
+ SITAR_MAJOR = cpu_to_le16(0x101),
+ TAIKO_MAJOR = cpu_to_le16(0x102),
+ TAPAN_MAJOR = cpu_to_le16(0x103),
+};
+
struct wcd9xxx_codec_type {
u16 id_major;
u16 id_minor;
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index f47cf0f..5be67cf 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -94,9 +94,6 @@
#define WCD9XXX_USLEEP_RANGE_MARGIN_US 1000
-#define WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAIKO 28
-#define WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAPAN 21
-
static bool detect_use_vddio_switch = true;
struct wcd9xxx_mbhc_detect {
@@ -3117,10 +3114,10 @@
switch (mbhc->mbhc_version) {
case WCD9XXX_MBHC_VERSION_TAIKO:
- jack_irq = WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAIKO;
+ jack_irq = WCD9320_IRQ_MBHC_JACK_SWITCH;
break;
case WCD9XXX_MBHC_VERSION_TAPAN:
- jack_irq = WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAPAN;
+ jack_irq = WCD9306_IRQ_MBHC_JACK_SWITCH;
break;
default:
return -EINVAL;
@@ -3804,12 +3801,10 @@
switch (mbhc->mbhc_version) {
case WCD9XXX_MBHC_VERSION_TAIKO:
- wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAIKO,
- mbhc);
+ wcd9xxx_free_irq(cdata, WCD9320_IRQ_MBHC_JACK_SWITCH, mbhc);
break;
case WCD9XXX_MBHC_VERSION_TAPAN:
- wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAPAN,
- mbhc);
+ wcd9xxx_free_irq(cdata, WCD9306_IRQ_MBHC_JACK_SWITCH, mbhc);
break;
default:
pr_err("%s: irq free failed! Invalid MBHC version %d\n",