aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-03 14:28:18 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-03 14:28:18 -0400
commit2638953fcd6eeea27b4975c1cdd5e62e32758f8f (patch)
tree0ea42b074ce2432bb1a38e4cc977d197e9439341 /drivers/extcon
parent33facb4d69cd60895073ed0a018a524a8e2a01ba (diff)
parent7abd4e2a8f1c3e534da44c35e2d3d6353573e51f (diff)
Merge tag 'extcon-arizona-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc into char-misc-next
Mark writes: extcon: arizona: Updates for v3.10 There's a bunch of different things in this series, I can split them out if need be: - Support for configuring the button detection circuit to reflect the accessories supplied with the system. - Improvements in the HPDET based detection scheme. - Additional robustness against more pathological use cases. - A few small standalone fixes.
Diffstat (limited to 'drivers/extcon')
-rw-r--r--drivers/extcon/extcon-arizona.c391
1 files changed, 287 insertions, 104 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index b28927972128..7a1b4a7791ba 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -33,12 +33,17 @@
33#include <linux/mfd/arizona/pdata.h> 33#include <linux/mfd/arizona/pdata.h>
34#include <linux/mfd/arizona/registers.h> 34#include <linux/mfd/arizona/registers.h>
35 35
36#define ARIZONA_NUM_BUTTONS 6 36#define ARIZONA_MAX_MICD_RANGE 8
37 37
38#define ARIZONA_ACCDET_MODE_MIC 0 38#define ARIZONA_ACCDET_MODE_MIC 0
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 ARIZONA_HPDET_MAX 10000
43
44#define HPDET_DEBOUNCE 500
45#define DEFAULT_MICD_TIMEOUT 2000
46
42struct arizona_extcon_info { 47struct arizona_extcon_info {
43 struct device *dev; 48 struct device *dev;
44 struct arizona *arizona; 49 struct arizona *arizona;
@@ -46,17 +51,27 @@ struct arizona_extcon_info {
46 struct regulator *micvdd; 51 struct regulator *micvdd;
47 struct input_dev *input; 52 struct input_dev *input;
48 53
54 u16 last_jackdet;
55
49 int micd_mode; 56 int micd_mode;
50 const struct arizona_micd_config *micd_modes; 57 const struct arizona_micd_config *micd_modes;
51 int micd_num_modes; 58 int micd_num_modes;
52 59
60 const struct arizona_micd_range *micd_ranges;
61 int num_micd_ranges;
62
63 int micd_timeout;
64
53 bool micd_reva; 65 bool micd_reva;
54 bool micd_clamp; 66 bool micd_clamp;
55 67
56 struct delayed_work hpdet_work; 68 struct delayed_work hpdet_work;
69 struct delayed_work micd_detect_work;
70 struct delayed_work micd_timeout_work;
57 71
58 bool hpdet_active; 72 bool hpdet_active;
59 bool hpdet_done; 73 bool hpdet_done;
74 bool hpdet_retried;
60 75
61 int num_hpdet_res; 76 int num_hpdet_res;
62 unsigned int hpdet_res[3]; 77 unsigned int hpdet_res[3];
@@ -71,20 +86,25 @@ struct arizona_extcon_info {
71}; 86};
72 87
73static const struct arizona_micd_config micd_default_modes[] = { 88static const struct arizona_micd_config micd_default_modes[] = {
74 { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 },
75 { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 }, 89 { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 },
90 { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 },
76}; 91};
77 92
78static struct { 93static const struct arizona_micd_range micd_default_ranges[] = {
79 u16 status; 94 { .max = 11, .key = BTN_0 },
80 int report; 95 { .max = 28, .key = BTN_1 },
81} arizona_lvl_to_key[ARIZONA_NUM_BUTTONS] = { 96 { .max = 54, .key = BTN_2 },
82 { 0x1, BTN_0 }, 97 { .max = 100, .key = BTN_3 },
83 { 0x2, BTN_1 }, 98 { .max = 186, .key = BTN_4 },
84 { 0x4, BTN_2 }, 99 { .max = 430, .key = BTN_5 },
85 { 0x8, BTN_3 }, 100};
86 { 0x10, BTN_4 }, 101
87 { 0x20, BTN_5 }, 102static const int arizona_micd_levels[] = {
103 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
104 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
105 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
106 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
107 1257,
88}; 108};
89 109
90#define ARIZONA_CABLE_MECHANICAL 0 110#define ARIZONA_CABLE_MECHANICAL 0
@@ -100,6 +120,8 @@ static const char *arizona_cable[] = {
100 NULL, 120 NULL,
101}; 121};
102 122
123static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info);
124
103static void arizona_extcon_do_magic(struct arizona_extcon_info *info, 125static void arizona_extcon_do_magic(struct arizona_extcon_info *info,
104 unsigned int magic) 126 unsigned int magic)
105{ 127{
@@ -153,6 +175,8 @@ static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
153{ 175{
154 struct arizona *arizona = info->arizona; 176 struct arizona *arizona = info->arizona;
155 177
178 mode %= info->micd_num_modes;
179
156 if (arizona->pdata.micd_pol_gpio > 0) 180 if (arizona->pdata.micd_pol_gpio > 0)
157 gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio, 181 gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio,
158 info->micd_modes[mode].gpio); 182 info->micd_modes[mode].gpio);
@@ -379,7 +403,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
379 /* If we go out of range report top of range */ 403 /* If we go out of range report top of range */
380 if (val < 100 || val > 0x3fb) { 404 if (val < 100 || val > 0x3fb) {
381 dev_dbg(arizona->dev, "Measurement out of range\n"); 405 dev_dbg(arizona->dev, "Measurement out of range\n");
382 return 10000; 406 return ARIZONA_HPDET_MAX;
383 } 407 }
384 408
385 dev_dbg(arizona->dev, "HPDET read %d in range %d\n", 409 dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
@@ -440,7 +464,8 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
440 return val; 464 return val;
441} 465}
442 466
443static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading) 467static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
468 bool *mic)
444{ 469{
445 struct arizona *arizona = info->arizona; 470 struct arizona *arizona = info->arizona;
446 int id_gpio = arizona->pdata.hpdet_id_gpio; 471 int id_gpio = arizona->pdata.hpdet_id_gpio;
@@ -452,32 +477,8 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading)
452 if (arizona->pdata.hpdet_acc_id) { 477 if (arizona->pdata.hpdet_acc_id) {
453 info->hpdet_res[info->num_hpdet_res++] = *reading; 478 info->hpdet_res[info->num_hpdet_res++] = *reading;
454 479
455 /*
456 * If the impedence is too high don't measure the
457 * second ground.
458 */
459 if (info->num_hpdet_res == 1 && *reading >= 45) {
460 dev_dbg(arizona->dev, "Skipping ground flip\n");
461 info->hpdet_res[info->num_hpdet_res++] = *reading;
462 }
463
464 if (info->num_hpdet_res == 1) {
465 dev_dbg(arizona->dev, "Flipping ground\n");
466
467 regmap_update_bits(arizona->regmap,
468 ARIZONA_ACCESSORY_DETECT_MODE_1,
469 ARIZONA_ACCDET_SRC,
470 ~info->micd_modes[0].src);
471
472 regmap_update_bits(arizona->regmap,
473 ARIZONA_HEADPHONE_DETECT_1,
474 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
475 return -EAGAIN;
476 }
477
478 /* Only check the mic directly if we didn't already ID it */ 480 /* Only check the mic directly if we didn't already ID it */
479 if (id_gpio && info->num_hpdet_res == 2 && 481 if (id_gpio && info->num_hpdet_res == 1) {
480 !((info->hpdet_res[0] > info->hpdet_res[1] * 2))) {
481 dev_dbg(arizona->dev, "Measuring mic\n"); 482 dev_dbg(arizona->dev, "Measuring mic\n");
482 483
483 regmap_update_bits(arizona->regmap, 484 regmap_update_bits(arizona->regmap,
@@ -496,22 +497,28 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading)
496 } 497 }
497 498
498 /* OK, got both. Now, compare... */ 499 /* OK, got both. Now, compare... */
499 dev_dbg(arizona->dev, "HPDET measured %d %d %d\n", 500 dev_dbg(arizona->dev, "HPDET measured %d %d\n",
500 info->hpdet_res[0], info->hpdet_res[1], 501 info->hpdet_res[0], info->hpdet_res[1]);
501 info->hpdet_res[2]);
502
503 502
504 /* Take the headphone impedance for the main report */ 503 /* Take the headphone impedance for the main report */
505 *reading = info->hpdet_res[0]; 504 *reading = info->hpdet_res[0];
506 505
506 /* Sometimes we get false readings due to slow insert */
507 if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
508 dev_dbg(arizona->dev, "Retrying high impedance\n");
509 info->num_hpdet_res = 0;
510 info->hpdet_retried = true;
511 arizona_start_hpdet_acc_id(info);
512 pm_runtime_put(info->dev);
513 return -EAGAIN;
514 }
515
507 /* 516 /*
508 * Either the two grounds measure differently or we 517 * If we measure the mic as
509 * measure the mic as high impedance.
510 */ 518 */
511 if ((info->hpdet_res[0] > info->hpdet_res[1] * 2) || 519 if (!id_gpio || info->hpdet_res[1] > 50) {
512 (id_gpio && info->hpdet_res[2] > 10)) {
513 dev_dbg(arizona->dev, "Detected mic\n"); 520 dev_dbg(arizona->dev, "Detected mic\n");
514 info->mic = true; 521 *mic = true;
515 info->detecting = true; 522 info->detecting = true;
516 } else { 523 } else {
517 dev_dbg(arizona->dev, "Detected headphone\n"); 524 dev_dbg(arizona->dev, "Detected headphone\n");
@@ -534,6 +541,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
534 int id_gpio = arizona->pdata.hpdet_id_gpio; 541 int id_gpio = arizona->pdata.hpdet_id_gpio;
535 int report = ARIZONA_CABLE_HEADPHONE; 542 int report = ARIZONA_CABLE_HEADPHONE;
536 int ret, reading; 543 int ret, reading;
544 bool mic = false;
537 545
538 mutex_lock(&info->lock); 546 mutex_lock(&info->lock);
539 547
@@ -569,7 +577,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
569 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL, 577 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
570 0); 578 0);
571 579
572 ret = arizona_hpdet_do_id(info, &reading); 580 ret = arizona_hpdet_do_id(info, &reading, &mic);
573 if (ret == -EAGAIN) { 581 if (ret == -EAGAIN) {
574 goto out; 582 goto out;
575 } else if (ret < 0) { 583 } else if (ret < 0) {
@@ -599,7 +607,7 @@ done:
599 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); 607 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
600 608
601 /* If we have a mic then reenable MICDET */ 609 /* If we have a mic then reenable MICDET */
602 if (info->mic) 610 if (mic || info->mic)
603 arizona_start_mic(info); 611 arizona_start_mic(info);
604 612
605 if (info->hpdet_active) { 613 if (info->hpdet_active) {
@@ -674,6 +682,8 @@ err:
674static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) 682static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
675{ 683{
676 struct arizona *arizona = info->arizona; 684 struct arizona *arizona = info->arizona;
685 int hp_reading = 32;
686 bool mic;
677 int ret; 687 int ret;
678 688
679 dev_dbg(arizona->dev, "Starting identification via HPDET\n"); 689 dev_dbg(arizona->dev, "Starting identification via HPDET\n");
@@ -683,8 +693,6 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
683 693
684 info->hpdet_active = true; 694 info->hpdet_active = true;
685 695
686 arizona_extcon_pulse_micbias(info);
687
688 arizona_extcon_do_magic(info, 0x4000); 696 arizona_extcon_do_magic(info, 0x4000);
689 697
690 ret = regmap_update_bits(arizona->regmap, 698 ret = regmap_update_bits(arizona->regmap,
@@ -697,12 +705,18 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
697 goto err; 705 goto err;
698 } 706 }
699 707
700 ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, 708 if (arizona->pdata.hpdet_acc_id_line) {
701 ARIZONA_HP_POLL, ARIZONA_HP_POLL); 709 ret = regmap_update_bits(arizona->regmap,
702 if (ret != 0) { 710 ARIZONA_HEADPHONE_DETECT_1,
703 dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n", 711 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
704 ret); 712 if (ret != 0) {
705 goto err; 713 dev_err(arizona->dev,
714 "Can't start HPDETL measurement: %d\n",
715 ret);
716 goto err;
717 }
718 } else {
719 arizona_hpdet_do_id(info, &hp_reading, &mic);
706 } 720 }
707 721
708 return; 722 return;
@@ -721,28 +735,58 @@ err:
721 info->hpdet_active = false; 735 info->hpdet_active = false;
722} 736}
723 737
724static irqreturn_t arizona_micdet(int irq, void *data) 738static void arizona_micd_timeout_work(struct work_struct *work)
725{ 739{
726 struct arizona_extcon_info *info = data; 740 struct arizona_extcon_info *info = container_of(work,
741 struct arizona_extcon_info,
742 micd_timeout_work.work);
743
744 mutex_lock(&info->lock);
745
746 dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n");
747 arizona_identify_headphone(info);
748
749 info->detecting = false;
750
751 arizona_stop_mic(info);
752
753 mutex_unlock(&info->lock);
754}
755
756static void arizona_micd_detect(struct work_struct *work)
757{
758 struct arizona_extcon_info *info = container_of(work,
759 struct arizona_extcon_info,
760 micd_detect_work.work);
727 struct arizona *arizona = info->arizona; 761 struct arizona *arizona = info->arizona;
728 unsigned int val, lvl; 762 unsigned int val = 0, lvl;
729 int ret, i; 763 int ret, i, key;
764
765 cancel_delayed_work_sync(&info->micd_timeout_work);
730 766
731 mutex_lock(&info->lock); 767 mutex_lock(&info->lock);
732 768
733 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); 769 for (i = 0; i < 10 && !(val & 0x7fc); i++) {
734 if (ret != 0) { 770 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
735 dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); 771 if (ret != 0) {
736 mutex_unlock(&info->lock); 772 dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret);
737 return IRQ_NONE; 773 mutex_unlock(&info->lock);
738 } 774 return;
775 }
739 776
740 dev_dbg(arizona->dev, "MICDET: %x\n", val); 777 dev_dbg(arizona->dev, "MICDET: %x\n", val);
741 778
742 if (!(val & ARIZONA_MICD_VALID)) { 779 if (!(val & ARIZONA_MICD_VALID)) {
743 dev_warn(arizona->dev, "Microphone detection state invalid\n"); 780 dev_warn(arizona->dev, "Microphone detection state invalid\n");
781 mutex_unlock(&info->lock);
782 return;
783 }
784 }
785
786 if (i == 10 && !(val & 0x7fc)) {
787 dev_err(arizona->dev, "Failed to get valid MICDET value\n");
744 mutex_unlock(&info->lock); 788 mutex_unlock(&info->lock);
745 return IRQ_NONE; 789 return;
746 } 790 }
747 791
748 /* Due to jack detect this should never happen */ 792 /* Due to jack detect this should never happen */
@@ -783,7 +827,7 @@ static irqreturn_t arizona_micdet(int irq, void *data)
783 * impedence then give up and report headphones. 827 * impedence then give up and report headphones.
784 */ 828 */
785 if (info->detecting && (val & 0x3f8)) { 829 if (info->detecting && (val & 0x3f8)) {
786 if (info->jack_flips >= info->micd_num_modes) { 830 if (info->jack_flips >= info->micd_num_modes * 10) {
787 dev_dbg(arizona->dev, "Detected HP/line\n"); 831 dev_dbg(arizona->dev, "Detected HP/line\n");
788 arizona_identify_headphone(info); 832 arizona_identify_headphone(info);
789 833
@@ -813,12 +857,17 @@ static irqreturn_t arizona_micdet(int irq, void *data)
813 lvl = val & ARIZONA_MICD_LVL_MASK; 857 lvl = val & ARIZONA_MICD_LVL_MASK;
814 lvl >>= ARIZONA_MICD_LVL_SHIFT; 858 lvl >>= ARIZONA_MICD_LVL_SHIFT;
815 859
816 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 860 for (i = 0; i < info->num_micd_ranges; i++)
817 if (lvl & arizona_lvl_to_key[i].status) 861 input_report_key(info->input,
818 input_report_key(info->input, 862 info->micd_ranges[i].key, 0);
819 arizona_lvl_to_key[i].report, 863
820 1); 864 WARN_ON(!lvl);
821 input_sync(info->input); 865 WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges);
866 if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
867 key = info->micd_ranges[ffs(lvl) - 1].key;
868 input_report_key(info->input, key, 1);
869 input_sync(info->input);
870 }
822 871
823 } else if (info->detecting) { 872 } else if (info->detecting) {
824 dev_dbg(arizona->dev, "Headphone detected\n"); 873 dev_dbg(arizona->dev, "Headphone detected\n");
@@ -832,16 +881,41 @@ static irqreturn_t arizona_micdet(int irq, void *data)
832 } 881 }
833 } else { 882 } else {
834 dev_dbg(arizona->dev, "Mic button released\n"); 883 dev_dbg(arizona->dev, "Mic button released\n");
835 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 884 for (i = 0; i < info->num_micd_ranges; i++)
836 input_report_key(info->input, 885 input_report_key(info->input,
837 arizona_lvl_to_key[i].report, 0); 886 info->micd_ranges[i].key, 0);
838 input_sync(info->input); 887 input_sync(info->input);
839 arizona_extcon_pulse_micbias(info); 888 arizona_extcon_pulse_micbias(info);
840 } 889 }
841 890
842handled: 891handled:
892 if (info->detecting)
893 schedule_delayed_work(&info->micd_timeout_work,
894 msecs_to_jiffies(info->micd_timeout));
895
843 pm_runtime_mark_last_busy(info->dev); 896 pm_runtime_mark_last_busy(info->dev);
844 mutex_unlock(&info->lock); 897 mutex_unlock(&info->lock);
898}
899
900static irqreturn_t arizona_micdet(int irq, void *data)
901{
902 struct arizona_extcon_info *info = data;
903 struct arizona *arizona = info->arizona;
904 int debounce = arizona->pdata.micd_detect_debounce;
905
906 cancel_delayed_work_sync(&info->micd_detect_work);
907 cancel_delayed_work_sync(&info->micd_timeout_work);
908
909 mutex_lock(&info->lock);
910 if (!info->detecting)
911 debounce = 0;
912 mutex_unlock(&info->lock);
913
914 if (debounce)
915 schedule_delayed_work(&info->micd_detect_work,
916 msecs_to_jiffies(debounce));
917 else
918 arizona_micd_detect(&info->micd_detect_work.work);
845 919
846 return IRQ_HANDLED; 920 return IRQ_HANDLED;
847} 921}
@@ -862,11 +936,13 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
862 struct arizona_extcon_info *info = data; 936 struct arizona_extcon_info *info = data;
863 struct arizona *arizona = info->arizona; 937 struct arizona *arizona = info->arizona;
864 unsigned int val, present, mask; 938 unsigned int val, present, mask;
939 bool cancelled_hp, cancelled_mic;
865 int ret, i; 940 int ret, i;
866 941
867 pm_runtime_get_sync(info->dev); 942 cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
943 cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
868 944
869 cancel_delayed_work_sync(&info->hpdet_work); 945 pm_runtime_get_sync(info->dev);
870 946
871 mutex_lock(&info->lock); 947 mutex_lock(&info->lock);
872 948
@@ -887,7 +963,22 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
887 return IRQ_NONE; 963 return IRQ_NONE;
888 } 964 }
889 965
890 if ((val & mask) == present) { 966 val &= mask;
967 if (val == info->last_jackdet) {
968 dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
969 if (cancelled_hp)
970 schedule_delayed_work(&info->hpdet_work,
971 msecs_to_jiffies(HPDET_DEBOUNCE));
972
973 if (cancelled_mic)
974 schedule_delayed_work(&info->micd_timeout_work,
975 msecs_to_jiffies(info->micd_timeout));
976
977 goto out;
978 }
979 info->last_jackdet = val;
980
981 if (info->last_jackdet == present) {
891 dev_dbg(arizona->dev, "Detected jack\n"); 982 dev_dbg(arizona->dev, "Detected jack\n");
892 ret = extcon_set_cable_state_(&info->edev, 983 ret = extcon_set_cable_state_(&info->edev,
893 ARIZONA_CABLE_MECHANICAL, true); 984 ARIZONA_CABLE_MECHANICAL, true);
@@ -904,7 +995,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
904 arizona_start_mic(info); 995 arizona_start_mic(info);
905 } else { 996 } else {
906 schedule_delayed_work(&info->hpdet_work, 997 schedule_delayed_work(&info->hpdet_work,
907 msecs_to_jiffies(250)); 998 msecs_to_jiffies(HPDET_DEBOUNCE));
908 } 999 }
909 1000
910 regmap_update_bits(arizona->regmap, 1001 regmap_update_bits(arizona->regmap,
@@ -920,10 +1011,11 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
920 info->hpdet_res[i] = 0; 1011 info->hpdet_res[i] = 0;
921 info->mic = false; 1012 info->mic = false;
922 info->hpdet_done = false; 1013 info->hpdet_done = false;
1014 info->hpdet_retried = false;
923 1015
924 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 1016 for (i = 0; i < info->num_micd_ranges; i++)
925 input_report_key(info->input, 1017 input_report_key(info->input,
926 arizona_lvl_to_key[i].report, 0); 1018 info->micd_ranges[i].key, 0);
927 input_sync(info->input); 1019 input_sync(info->input);
928 1020
929 ret = extcon_update_state(&info->edev, 0xffffffff, 0); 1021 ret = extcon_update_state(&info->edev, 0xffffffff, 0);
@@ -937,6 +1029,11 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
937 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB); 1029 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
938 } 1030 }
939 1031
1032 if (arizona->pdata.micd_timeout)
1033 info->micd_timeout = arizona->pdata.micd_timeout;
1034 else
1035 info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1036
940 /* Clear trig_sts to make sure DCVDD is not forced up */ 1037 /* Clear trig_sts to make sure DCVDD is not forced up */
941 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG, 1038 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
942 ARIZONA_MICD_CLAMP_FALL_TRIG_STS | 1039 ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
@@ -944,6 +1041,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
944 ARIZONA_JD1_FALL_TRIG_STS | 1041 ARIZONA_JD1_FALL_TRIG_STS |
945 ARIZONA_JD1_RISE_TRIG_STS); 1042 ARIZONA_JD1_RISE_TRIG_STS);
946 1043
1044out:
947 mutex_unlock(&info->lock); 1045 mutex_unlock(&info->lock);
948 1046
949 pm_runtime_mark_last_busy(info->dev); 1047 pm_runtime_mark_last_busy(info->dev);
@@ -952,13 +1050,34 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
952 return IRQ_HANDLED; 1050 return IRQ_HANDLED;
953} 1051}
954 1052
1053/* Map a level onto a slot in the register bank */
1054static void arizona_micd_set_level(struct arizona *arizona, int index,
1055 unsigned int level)
1056{
1057 int reg;
1058 unsigned int mask;
1059
1060 reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1061
1062 if (!(index % 2)) {
1063 mask = 0x3f00;
1064 level <<= 8;
1065 } else {
1066 mask = 0x3f;
1067 }
1068
1069 /* Program the level itself */
1070 regmap_update_bits(arizona->regmap, reg, mask, level);
1071}
1072
955static int arizona_extcon_probe(struct platform_device *pdev) 1073static int arizona_extcon_probe(struct platform_device *pdev)
956{ 1074{
957 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 1075 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
958 struct arizona_pdata *pdata; 1076 struct arizona_pdata *pdata;
959 struct arizona_extcon_info *info; 1077 struct arizona_extcon_info *info;
1078 unsigned int val;
960 int jack_irq_fall, jack_irq_rise; 1079 int jack_irq_fall, jack_irq_rise;
961 int ret, mode, i; 1080 int ret, mode, i, j;
962 1081
963 if (!arizona->dapm || !arizona->dapm->card) 1082 if (!arizona->dapm || !arizona->dapm->card)
964 return -EPROBE_DEFER; 1083 return -EPROBE_DEFER;
@@ -982,7 +1101,10 @@ static int arizona_extcon_probe(struct platform_device *pdev)
982 mutex_init(&info->lock); 1101 mutex_init(&info->lock);
983 info->arizona = arizona; 1102 info->arizona = arizona;
984 info->dev = &pdev->dev; 1103 info->dev = &pdev->dev;
1104 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
985 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work); 1105 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
1106 INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
1107 INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
986 platform_set_drvdata(pdev, info); 1108 platform_set_drvdata(pdev, info);
987 1109
988 switch (arizona->type) { 1110 switch (arizona->type) {
@@ -1011,6 +1133,17 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1011 goto err; 1133 goto err;
1012 } 1134 }
1013 1135
1136 info->input = devm_input_allocate_device(&pdev->dev);
1137 if (!info->input) {
1138 dev_err(arizona->dev, "Can't allocate input dev\n");
1139 ret = -ENOMEM;
1140 goto err_register;
1141 }
1142
1143 info->input->name = "Headset";
1144 info->input->phys = "arizona/extcon";
1145 info->input->dev.parent = &pdev->dev;
1146
1014 if (pdata->num_micd_configs) { 1147 if (pdata->num_micd_configs) {
1015 info->micd_modes = pdata->micd_configs; 1148 info->micd_modes = pdata->micd_configs;
1016 info->micd_num_modes = pdata->num_micd_configs; 1149 info->micd_num_modes = pdata->num_micd_configs;
@@ -1066,15 +1199,79 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1066 arizona->pdata.micd_dbtime 1199 arizona->pdata.micd_dbtime
1067 << ARIZONA_MICD_DBTIME_SHIFT); 1200 << ARIZONA_MICD_DBTIME_SHIFT);
1068 1201
1202 BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40);
1203
1204 if (arizona->pdata.num_micd_ranges) {
1205 info->micd_ranges = pdata->micd_ranges;
1206 info->num_micd_ranges = pdata->num_micd_ranges;
1207 } else {
1208 info->micd_ranges = micd_default_ranges;
1209 info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1210 }
1211
1212 if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1213 dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1214 arizona->pdata.num_micd_ranges);
1215 }
1216
1217 if (info->num_micd_ranges > 1) {
1218 for (i = 1; i < info->num_micd_ranges; i++) {
1219 if (info->micd_ranges[i - 1].max >
1220 info->micd_ranges[i].max) {
1221 dev_err(arizona->dev,
1222 "MICD ranges must be sorted\n");
1223 ret = -EINVAL;
1224 goto err_input;
1225 }
1226 }
1227 }
1228
1229 /* Disable all buttons by default */
1230 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1231 ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1232
1233 /* Set up all the buttons the user specified */
1234 for (i = 0; i < info->num_micd_ranges; i++) {
1235 for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++)
1236 if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1237 break;
1238
1239 if (j == ARRAY_SIZE(arizona_micd_levels)) {
1240 dev_err(arizona->dev, "Unsupported MICD level %d\n",
1241 info->micd_ranges[i].max);
1242 ret = -EINVAL;
1243 goto err_input;
1244 }
1245
1246 dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1247 arizona_micd_levels[j], i);
1248
1249 arizona_micd_set_level(arizona, i, j);
1250 input_set_capability(info->input, EV_KEY,
1251 info->micd_ranges[i].key);
1252
1253 /* Enable reporting of that range */
1254 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1255 1 << i, 1 << i);
1256 }
1257
1258 /* Set all the remaining keys to a maximum */
1259 for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1260 arizona_micd_set_level(arizona, i, 0x3f);
1261
1069 /* 1262 /*
1070 * If we have a clamp use it, activating in conjunction with 1263 * If we have a clamp use it, activating in conjunction with
1071 * GPIO5 if that is connected for jack detect operation. 1264 * GPIO5 if that is connected for jack detect operation.
1072 */ 1265 */
1073 if (info->micd_clamp) { 1266 if (info->micd_clamp) {
1074 if (arizona->pdata.jd_gpio5) { 1267 if (arizona->pdata.jd_gpio5) {
1075 /* Put the GPIO into input mode */ 1268 /* Put the GPIO into input mode with optional pull */
1269 val = 0xc101;
1270 if (arizona->pdata.jd_gpio5_nopull)
1271 val &= ~ARIZONA_GPN_PU;
1272
1076 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL, 1273 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
1077 0xc101); 1274 val);
1078 1275
1079 regmap_update_bits(arizona->regmap, 1276 regmap_update_bits(arizona->regmap,
1080 ARIZONA_MICD_CLAMP_CONTROL, 1277 ARIZONA_MICD_CLAMP_CONTROL,
@@ -1093,20 +1290,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1093 1290
1094 arizona_extcon_set_mode(info, 0); 1291 arizona_extcon_set_mode(info, 0);
1095 1292
1096 info->input = devm_input_allocate_device(&pdev->dev);
1097 if (!info->input) {
1098 dev_err(arizona->dev, "Can't allocate input dev\n");
1099 ret = -ENOMEM;
1100 goto err_register;
1101 }
1102
1103 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
1104 input_set_capability(info->input, EV_KEY,
1105 arizona_lvl_to_key[i].report);
1106 info->input->name = "Headset";
1107 info->input->phys = "arizona/extcon";
1108 info->input->dev.parent = &pdev->dev;
1109
1110 pm_runtime_enable(&pdev->dev); 1293 pm_runtime_enable(&pdev->dev);
1111 pm_runtime_idle(&pdev->dev); 1294 pm_runtime_idle(&pdev->dev);
1112 pm_runtime_get_sync(&pdev->dev); 1295 pm_runtime_get_sync(&pdev->dev);