Browse Source

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 <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Charles Keepax 12 years ago
parent
commit
e2c0f476ec
1 changed files with 18 additions and 10 deletions
  1. 18 10
      drivers/extcon/extcon-arizona.c

+ 18 - 10
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);
 
-	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;
 	}