diff options
Diffstat (limited to 'drivers/extcon')
-rw-r--r-- | drivers/extcon/extcon-arizona.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 2f0bd4938fcc..9e4bffe610b6 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #define ARIZONA_ACCDET_MODE_HPL 1 | 39 | #define ARIZONA_ACCDET_MODE_HPL 1 |
40 | #define ARIZONA_ACCDET_MODE_HPR 2 | 40 | #define ARIZONA_ACCDET_MODE_HPR 2 |
41 | 41 | ||
42 | #define HPDET_DEBOUNCE 250 | ||
43 | |||
42 | struct arizona_extcon_info { | 44 | struct arizona_extcon_info { |
43 | struct device *dev; | 45 | struct device *dev; |
44 | struct arizona *arizona; | 46 | struct arizona *arizona; |
@@ -46,6 +48,8 @@ struct arizona_extcon_info { | |||
46 | struct regulator *micvdd; | 48 | struct regulator *micvdd; |
47 | struct input_dev *input; | 49 | struct input_dev *input; |
48 | 50 | ||
51 | u16 last_jackdet; | ||
52 | |||
49 | int micd_mode; | 53 | int micd_mode; |
50 | const struct arizona_micd_config *micd_modes; | 54 | const struct arizona_micd_config *micd_modes; |
51 | int micd_num_modes; | 55 | int micd_num_modes; |
@@ -871,11 +875,12 @@ static irqreturn_t arizona_jackdet(int irq, void *data) | |||
871 | struct arizona_extcon_info *info = data; | 875 | struct arizona_extcon_info *info = data; |
872 | struct arizona *arizona = info->arizona; | 876 | struct arizona *arizona = info->arizona; |
873 | unsigned int val, present, mask; | 877 | unsigned int val, present, mask; |
878 | bool cancelled; | ||
874 | int ret, i; | 879 | int ret, i; |
875 | 880 | ||
876 | pm_runtime_get_sync(info->dev); | 881 | cancelled = cancel_delayed_work_sync(&info->hpdet_work); |
877 | 882 | ||
878 | cancel_delayed_work_sync(&info->hpdet_work); | 883 | pm_runtime_get_sync(info->dev); |
879 | 884 | ||
880 | mutex_lock(&info->lock); | 885 | mutex_lock(&info->lock); |
881 | 886 | ||
@@ -896,7 +901,18 @@ static irqreturn_t arizona_jackdet(int irq, void *data) | |||
896 | return IRQ_NONE; | 901 | return IRQ_NONE; |
897 | } | 902 | } |
898 | 903 | ||
899 | if ((val & mask) == present) { | 904 | val &= mask; |
905 | if (val == info->last_jackdet) { | ||
906 | dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n"); | ||
907 | if (cancelled) | ||
908 | schedule_delayed_work(&info->hpdet_work, | ||
909 | msecs_to_jiffies(HPDET_DEBOUNCE)); | ||
910 | |||
911 | goto out; | ||
912 | } | ||
913 | info->last_jackdet = val; | ||
914 | |||
915 | if (info->last_jackdet == present) { | ||
900 | dev_dbg(arizona->dev, "Detected jack\n"); | 916 | dev_dbg(arizona->dev, "Detected jack\n"); |
901 | ret = extcon_set_cable_state_(&info->edev, | 917 | ret = extcon_set_cable_state_(&info->edev, |
902 | ARIZONA_CABLE_MECHANICAL, true); | 918 | ARIZONA_CABLE_MECHANICAL, true); |
@@ -913,7 +929,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data) | |||
913 | arizona_start_mic(info); | 929 | arizona_start_mic(info); |
914 | } else { | 930 | } else { |
915 | schedule_delayed_work(&info->hpdet_work, | 931 | schedule_delayed_work(&info->hpdet_work, |
916 | msecs_to_jiffies(250)); | 932 | msecs_to_jiffies(HPDET_DEBOUNCE)); |
917 | } | 933 | } |
918 | 934 | ||
919 | regmap_update_bits(arizona->regmap, | 935 | regmap_update_bits(arizona->regmap, |
@@ -953,6 +969,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data) | |||
953 | ARIZONA_JD1_FALL_TRIG_STS | | 969 | ARIZONA_JD1_FALL_TRIG_STS | |
954 | ARIZONA_JD1_RISE_TRIG_STS); | 970 | ARIZONA_JD1_RISE_TRIG_STS); |
955 | 971 | ||
972 | out: | ||
956 | mutex_unlock(&info->lock); | 973 | mutex_unlock(&info->lock); |
957 | 974 | ||
958 | pm_runtime_mark_last_busy(info->dev); | 975 | pm_runtime_mark_last_busy(info->dev); |
@@ -1012,6 +1029,7 @@ static int arizona_extcon_probe(struct platform_device *pdev) | |||
1012 | mutex_init(&info->lock); | 1029 | mutex_init(&info->lock); |
1013 | info->arizona = arizona; | 1030 | info->arizona = arizona; |
1014 | info->dev = &pdev->dev; | 1031 | info->dev = &pdev->dev; |
1032 | info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS); | ||
1015 | INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work); | 1033 | INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work); |
1016 | platform_set_drvdata(pdev, info); | 1034 | platform_set_drvdata(pdev, info); |
1017 | 1035 | ||