extcon: arizona: Check we report a valid impedance
authorCharles Keepax <ckeepax@opensource.wolfsonmicro.com>
Mon, 1 Apr 2013 18:06:29 +0000 (19:06 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 2 Apr 2013 10:53:57 +0000 (11:53 +0100)
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 <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
drivers/extcon/extcon-arizona.c

index 9e4bffe..4022fe2 100644 (file)
@@ -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);
 
-       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;
+               }
+       }
 
-       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;
        }