From e2c0f476ec90dbb020b1da7e399072e062ad6c9e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 1 Apr 2013 19:06:29 +0100 Subject: [PATCH] extcon: arizona: Check we report a valid impedance Occasionally we can trigger an interrupt before we have completed impedance measurement, although the valid bit will still be set. This patch spins reading the impedance value until a valid value is seen. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- drivers/extcon/extcon-arizona.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 9e4bffe610b6..4022fe207926 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -737,22 +737,30 @@ static irqreturn_t arizona_micdet(int irq, void *data) { struct arizona_extcon_info *info = data; struct arizona *arizona = info->arizona; - unsigned int val, lvl; + unsigned int val = 0, lvl; int ret, i, key; mutex_lock(&info->lock); - ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); - if (ret != 0) { - dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); - mutex_unlock(&info->lock); - return IRQ_NONE; + for (i = 0; i < 10 && !(val & 0x7fc); i++) { + ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); + mutex_unlock(&info->lock); + return IRQ_NONE; + } + + dev_dbg(arizona->dev, "MICDET: %x\n", val); + + if (!(val & ARIZONA_MICD_VALID)) { + dev_warn(arizona->dev, "Microphone detection state invalid\n"); + mutex_unlock(&info->lock); + return IRQ_NONE; + } } - dev_dbg(arizona->dev, "MICDET: %x\n", val); - - if (!(val & ARIZONA_MICD_VALID)) { - dev_warn(arizona->dev, "Microphone detection state invalid\n"); + if (i == 10 && !(val & 0x7fc)) { + dev_err(arizona->dev, "Failed to get valid MICDET value\n"); mutex_unlock(&info->lock); return IRQ_NONE; }