Skip to content

Commit

Permalink
extcon: arizona: Suppress duplicate JACKDET reports
Browse files Browse the repository at this point in the history
In cases where we see a brief (dis)connection of the jack detection signals
we may see a noop jack insertion or removal where the jack has returned to
the original state by the time the interrupt is serviced. Suppress these
events in order to save work and avoid confusing the rest of the code.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Mark Brown committed Apr 2, 2013
1 parent 82e2e0f commit a3e2078
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions drivers/extcon/extcon-arizona.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,17 @@
#define ARIZONA_ACCDET_MODE_HPL 1
#define ARIZONA_ACCDET_MODE_HPR 2

#define HPDET_DEBOUNCE 250

struct arizona_extcon_info {
struct device *dev;
struct arizona *arizona;
struct mutex lock;
struct regulator *micvdd;
struct input_dev *input;

u16 last_jackdet;

int micd_mode;
const struct arizona_micd_config *micd_modes;
int micd_num_modes;
Expand Down Expand Up @@ -871,11 +875,12 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
struct arizona_extcon_info *info = data;
struct arizona *arizona = info->arizona;
unsigned int val, present, mask;
bool cancelled;
int ret, i;

pm_runtime_get_sync(info->dev);
cancelled = cancel_delayed_work_sync(&info->hpdet_work);

cancel_delayed_work_sync(&info->hpdet_work);
pm_runtime_get_sync(info->dev);

mutex_lock(&info->lock);

Expand All @@ -896,7 +901,18 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
return IRQ_NONE;
}

if ((val & mask) == present) {
val &= mask;
if (val == info->last_jackdet) {
dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
if (cancelled)
schedule_delayed_work(&info->hpdet_work,
msecs_to_jiffies(HPDET_DEBOUNCE));

goto out;
}
info->last_jackdet = val;

if (info->last_jackdet == present) {
dev_dbg(arizona->dev, "Detected jack\n");
ret = extcon_set_cable_state_(&info->edev,
ARIZONA_CABLE_MECHANICAL, true);
Expand All @@ -913,7 +929,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
arizona_start_mic(info);
} else {
schedule_delayed_work(&info->hpdet_work,
msecs_to_jiffies(250));
msecs_to_jiffies(HPDET_DEBOUNCE));
}

regmap_update_bits(arizona->regmap,
Expand Down Expand Up @@ -953,6 +969,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
ARIZONA_JD1_FALL_TRIG_STS |
ARIZONA_JD1_RISE_TRIG_STS);

out:
mutex_unlock(&info->lock);

pm_runtime_mark_last_busy(info->dev);
Expand Down Expand Up @@ -1012,6 +1029,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
mutex_init(&info->lock);
info->arizona = arizona;
info->dev = &pdev->dev;
info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
platform_set_drvdata(pdev, info);

Expand Down

0 comments on commit a3e2078

Please sign in to comment.