aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon/extcon-arizona.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-01 14:21:48 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-02 06:54:06 -0400
commitcd59e79656f4e7137909166248a935d422b1245a (patch)
tree008f928dbea75080e8498ae48b9af2ebac8c4b04 /drivers/extcon/extcon-arizona.c
parent41a57850b5e5c450da351465efcc41383def7f8a (diff)
extcon: arizona: Allow additional debounce during microphone detection
Help mitigate against mechanical bounce during the initial detection by allowing the configuration of an additional debounce on top of that the hardware does during the initial phase of microphone detection operation. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/extcon/extcon-arizona.c')
-rw-r--r--drivers/extcon/extcon-arizona.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 26f9a1ae15c4..c7f8eb4299d2 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -64,6 +64,7 @@ struct arizona_extcon_info {
64 bool micd_clamp; 64 bool micd_clamp;
65 65
66 struct delayed_work hpdet_work; 66 struct delayed_work hpdet_work;
67 struct delayed_work micd_detect_work;
67 struct delayed_work micd_timeout_work; 68 struct delayed_work micd_timeout_work;
68 69
69 bool hpdet_active; 70 bool hpdet_active;
@@ -750,9 +751,11 @@ static void arizona_micd_timeout_work(struct work_struct *work)
750 mutex_unlock(&info->lock); 751 mutex_unlock(&info->lock);
751} 752}
752 753
753static irqreturn_t arizona_micdet(int irq, void *data) 754static void arizona_micd_detect(struct work_struct *work)
754{ 755{
755 struct arizona_extcon_info *info = data; 756 struct arizona_extcon_info *info = container_of(work,
757 struct arizona_extcon_info,
758 micd_detect_work.work);
756 struct arizona *arizona = info->arizona; 759 struct arizona *arizona = info->arizona;
757 unsigned int val = 0, lvl; 760 unsigned int val = 0, lvl;
758 int ret, i, key; 761 int ret, i, key;
@@ -766,7 +769,7 @@ static irqreturn_t arizona_micdet(int irq, void *data)
766 if (ret != 0) { 769 if (ret != 0) {
767 dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); 770 dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret);
768 mutex_unlock(&info->lock); 771 mutex_unlock(&info->lock);
769 return IRQ_NONE; 772 return;
770 } 773 }
771 774
772 dev_dbg(arizona->dev, "MICDET: %x\n", val); 775 dev_dbg(arizona->dev, "MICDET: %x\n", val);
@@ -774,14 +777,14 @@ static irqreturn_t arizona_micdet(int irq, void *data)
774 if (!(val & ARIZONA_MICD_VALID)) { 777 if (!(val & ARIZONA_MICD_VALID)) {
775 dev_warn(arizona->dev, "Microphone detection state invalid\n"); 778 dev_warn(arizona->dev, "Microphone detection state invalid\n");
776 mutex_unlock(&info->lock); 779 mutex_unlock(&info->lock);
777 return IRQ_NONE; 780 return;
778 } 781 }
779 } 782 }
780 783
781 if (i == 10 && !(val & 0x7fc)) { 784 if (i == 10 && !(val & 0x7fc)) {
782 dev_err(arizona->dev, "Failed to get valid MICDET value\n"); 785 dev_err(arizona->dev, "Failed to get valid MICDET value\n");
783 mutex_unlock(&info->lock); 786 mutex_unlock(&info->lock);
784 return IRQ_NONE; 787 return;
785 } 788 }
786 789
787 /* Due to jack detect this should never happen */ 790 /* Due to jack detect this should never happen */
@@ -890,6 +893,27 @@ handled:
890 893
891 pm_runtime_mark_last_busy(info->dev); 894 pm_runtime_mark_last_busy(info->dev);
892 mutex_unlock(&info->lock); 895 mutex_unlock(&info->lock);
896}
897
898static irqreturn_t arizona_micdet(int irq, void *data)
899{
900 struct arizona_extcon_info *info = data;
901 struct arizona *arizona = info->arizona;
902 int debounce = arizona->pdata.micd_detect_debounce;
903
904 cancel_delayed_work_sync(&info->micd_detect_work);
905 cancel_delayed_work_sync(&info->micd_timeout_work);
906
907 mutex_lock(&info->lock);
908 if (!info->detecting)
909 debounce = 0;
910 mutex_unlock(&info->lock);
911
912 if (debounce)
913 schedule_delayed_work(&info->micd_detect_work,
914 msecs_to_jiffies(debounce));
915 else
916 arizona_micd_detect(&info->micd_detect_work.work);
893 917
894 return IRQ_HANDLED; 918 return IRQ_HANDLED;
895} 919}
@@ -1072,6 +1096,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1072 info->dev = &pdev->dev; 1096 info->dev = &pdev->dev;
1073 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS); 1097 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
1074 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work); 1098 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
1099 INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
1075 INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work); 1100 INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
1076 platform_set_drvdata(pdev, info); 1101 platform_set_drvdata(pdev, info);
1077 1102