aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon/extcon-arizona.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/extcon/extcon-arizona.c')
-rw-r--r--drivers/extcon/extcon-arizona.c498
1 files changed, 339 insertions, 159 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index dc357a4051f6..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,10 +120,63 @@ 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
125static void arizona_extcon_do_magic(struct arizona_extcon_info *info,
126 unsigned int magic)
127{
128 struct arizona *arizona = info->arizona;
129 int ret;
130
131 mutex_lock(&arizona->dapm->card->dapm_mutex);
132
133 arizona->hpdet_magic = magic;
134
135 /* Keep the HP output stages disabled while doing the magic */
136 if (magic) {
137 ret = regmap_update_bits(arizona->regmap,
138 ARIZONA_OUTPUT_ENABLES_1,
139 ARIZONA_OUT1L_ENA |
140 ARIZONA_OUT1R_ENA, 0);
141 if (ret != 0)
142 dev_warn(arizona->dev,
143 "Failed to disable headphone outputs: %d\n",
144 ret);
145 }
146
147 ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000,
148 magic);
149 if (ret != 0)
150 dev_warn(arizona->dev, "Failed to do magic: %d\n",
151 ret);
152
153 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000,
154 magic);
155 if (ret != 0)
156 dev_warn(arizona->dev, "Failed to do magic: %d\n",
157 ret);
158
159 /* Restore the desired state while not doing the magic */
160 if (!magic) {
161 ret = regmap_update_bits(arizona->regmap,
162 ARIZONA_OUTPUT_ENABLES_1,
163 ARIZONA_OUT1L_ENA |
164 ARIZONA_OUT1R_ENA, arizona->hp_ena);
165 if (ret != 0)
166 dev_warn(arizona->dev,
167 "Failed to restore headphone outputs: %d\n",
168 ret);
169 }
170
171 mutex_unlock(&arizona->dapm->card->dapm_mutex);
172}
173
103static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) 174static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
104{ 175{
105 struct arizona *arizona = info->arizona; 176 struct arizona *arizona = info->arizona;
106 177
178 mode %= info->micd_num_modes;
179
107 if (arizona->pdata.micd_pol_gpio > 0) 180 if (arizona->pdata.micd_pol_gpio > 0)
108 gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio, 181 gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio,
109 info->micd_modes[mode].gpio); 182 info->micd_modes[mode].gpio);
@@ -330,7 +403,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
330 /* If we go out of range report top of range */ 403 /* If we go out of range report top of range */
331 if (val < 100 || val > 0x3fb) { 404 if (val < 100 || val > 0x3fb) {
332 dev_dbg(arizona->dev, "Measurement out of range\n"); 405 dev_dbg(arizona->dev, "Measurement out of range\n");
333 return 10000; 406 return ARIZONA_HPDET_MAX;
334 } 407 }
335 408
336 dev_dbg(arizona->dev, "HPDET read %d in range %d\n", 409 dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
@@ -391,7 +464,8 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
391 return val; 464 return val;
392} 465}
393 466
394static 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)
395{ 469{
396 struct arizona *arizona = info->arizona; 470 struct arizona *arizona = info->arizona;
397 int id_gpio = arizona->pdata.hpdet_id_gpio; 471 int id_gpio = arizona->pdata.hpdet_id_gpio;
@@ -403,32 +477,8 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading)
403 if (arizona->pdata.hpdet_acc_id) { 477 if (arizona->pdata.hpdet_acc_id) {
404 info->hpdet_res[info->num_hpdet_res++] = *reading; 478 info->hpdet_res[info->num_hpdet_res++] = *reading;
405 479
406 /*
407 * If the impedence is too high don't measure the
408 * second ground.
409 */
410 if (info->num_hpdet_res == 1 && *reading >= 45) {
411 dev_dbg(arizona->dev, "Skipping ground flip\n");
412 info->hpdet_res[info->num_hpdet_res++] = *reading;
413 }
414
415 if (info->num_hpdet_res == 1) {
416 dev_dbg(arizona->dev, "Flipping ground\n");
417
418 regmap_update_bits(arizona->regmap,
419 ARIZONA_ACCESSORY_DETECT_MODE_1,
420 ARIZONA_ACCDET_SRC,
421 ~info->micd_modes[0].src);
422
423 regmap_update_bits(arizona->regmap,
424 ARIZONA_HEADPHONE_DETECT_1,
425 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
426 return -EAGAIN;
427 }
428
429 /* 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 */
430 if (id_gpio && info->num_hpdet_res == 2 && 481 if (id_gpio && info->num_hpdet_res == 1) {
431 !((info->hpdet_res[0] > info->hpdet_res[1] * 2))) {
432 dev_dbg(arizona->dev, "Measuring mic\n"); 482 dev_dbg(arizona->dev, "Measuring mic\n");
433 483
434 regmap_update_bits(arizona->regmap, 484 regmap_update_bits(arizona->regmap,
@@ -447,22 +497,28 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading)
447 } 497 }
448 498
449 /* OK, got both. Now, compare... */ 499 /* OK, got both. Now, compare... */
450 dev_dbg(arizona->dev, "HPDET measured %d %d %d\n", 500 dev_dbg(arizona->dev, "HPDET measured %d %d\n",
451 info->hpdet_res[0], info->hpdet_res[1], 501 info->hpdet_res[0], info->hpdet_res[1]);
452 info->hpdet_res[2]);
453
454 502
455 /* Take the headphone impedance for the main report */ 503 /* Take the headphone impedance for the main report */
456 *reading = info->hpdet_res[0]; 504 *reading = info->hpdet_res[0];
457 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
458 /* 516 /*
459 * Either the two grounds measure differently or we 517 * If we measure the mic as
460 * measure the mic as high impedance.
461 */ 518 */
462 if ((info->hpdet_res[0] > info->hpdet_res[1] * 2) || 519 if (!id_gpio || info->hpdet_res[1] > 50) {
463 (id_gpio && info->hpdet_res[2] > 10)) {
464 dev_dbg(arizona->dev, "Detected mic\n"); 520 dev_dbg(arizona->dev, "Detected mic\n");
465 info->mic = true; 521 *mic = true;
466 info->detecting = true; 522 info->detecting = true;
467 } else { 523 } else {
468 dev_dbg(arizona->dev, "Detected headphone\n"); 524 dev_dbg(arizona->dev, "Detected headphone\n");
@@ -484,8 +540,8 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
484 struct arizona *arizona = info->arizona; 540 struct arizona *arizona = info->arizona;
485 int id_gpio = arizona->pdata.hpdet_id_gpio; 541 int id_gpio = arizona->pdata.hpdet_id_gpio;
486 int report = ARIZONA_CABLE_HEADPHONE; 542 int report = ARIZONA_CABLE_HEADPHONE;
487 unsigned int val;
488 int ret, reading; 543 int ret, reading;
544 bool mic = false;
489 545
490 mutex_lock(&info->lock); 546 mutex_lock(&info->lock);
491 547
@@ -521,7 +577,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
521 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL, 577 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
522 0); 578 0);
523 579
524 ret = arizona_hpdet_do_id(info, &reading); 580 ret = arizona_hpdet_do_id(info, &reading, &mic);
525 if (ret == -EAGAIN) { 581 if (ret == -EAGAIN) {
526 goto out; 582 goto out;
527 } else if (ret < 0) { 583 } else if (ret < 0) {
@@ -539,28 +595,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
539 dev_err(arizona->dev, "Failed to report HP/line: %d\n", 595 dev_err(arizona->dev, "Failed to report HP/line: %d\n",
540 ret); 596 ret);
541 597
542 mutex_lock(&arizona->dapm->card->dapm_mutex); 598 arizona_extcon_do_magic(info, 0);
543
544 ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val);
545 if (ret != 0) {
546 dev_err(arizona->dev, "Failed to read output enables: %d\n",
547 ret);
548 val = 0;
549 }
550
551 if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) {
552 ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0);
553 if (ret != 0)
554 dev_warn(arizona->dev, "Failed to undo magic: %d\n",
555 ret);
556
557 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0);
558 if (ret != 0)
559 dev_warn(arizona->dev, "Failed to undo magic: %d\n",
560 ret);
561 }
562
563 mutex_unlock(&arizona->dapm->card->dapm_mutex);
564 599
565done: 600done:
566 if (id_gpio) 601 if (id_gpio)
@@ -572,7 +607,7 @@ done:
572 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); 607 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
573 608
574 /* If we have a mic then reenable MICDET */ 609 /* If we have a mic then reenable MICDET */
575 if (info->mic) 610 if (mic || info->mic)
576 arizona_start_mic(info); 611 arizona_start_mic(info);
577 612
578 if (info->hpdet_active) { 613 if (info->hpdet_active) {
@@ -606,13 +641,7 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info)
606 if (info->mic) 641 if (info->mic)
607 arizona_stop_mic(info); 642 arizona_stop_mic(info);
608 643
609 ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000); 644 arizona_extcon_do_magic(info, 0x4000);
610 if (ret != 0)
611 dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
612
613 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000);
614 if (ret != 0)
615 dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
616 645
617 ret = regmap_update_bits(arizona->regmap, 646 ret = regmap_update_bits(arizona->regmap,
618 ARIZONA_ACCESSORY_DETECT_MODE_1, 647 ARIZONA_ACCESSORY_DETECT_MODE_1,
@@ -653,7 +682,8 @@ err:
653static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) 682static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
654{ 683{
655 struct arizona *arizona = info->arizona; 684 struct arizona *arizona = info->arizona;
656 unsigned int val; 685 int hp_reading = 32;
686 bool mic;
657 int ret; 687 int ret;
658 688
659 dev_dbg(arizona->dev, "Starting identification via HPDET\n"); 689 dev_dbg(arizona->dev, "Starting identification via HPDET\n");
@@ -663,32 +693,7 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
663 693
664 info->hpdet_active = true; 694 info->hpdet_active = true;
665 695
666 arizona_extcon_pulse_micbias(info); 696 arizona_extcon_do_magic(info, 0x4000);
667
668 mutex_lock(&arizona->dapm->card->dapm_mutex);
669
670 ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val);
671 if (ret != 0) {
672 dev_err(arizona->dev, "Failed to read output enables: %d\n",
673 ret);
674 val = 0;
675 }
676
677 if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) {
678 ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000,
679 0x4000);
680 if (ret != 0)
681 dev_warn(arizona->dev, "Failed to do magic: %d\n",
682 ret);
683
684 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000,
685 0x4000);
686 if (ret != 0)
687 dev_warn(arizona->dev, "Failed to do magic: %d\n",
688 ret);
689 }
690
691 mutex_unlock(&arizona->dapm->card->dapm_mutex);
692 697
693 ret = regmap_update_bits(arizona->regmap, 698 ret = regmap_update_bits(arizona->regmap,
694 ARIZONA_ACCESSORY_DETECT_MODE_1, 699 ARIZONA_ACCESSORY_DETECT_MODE_1,
@@ -700,12 +705,18 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
700 goto err; 705 goto err;
701 } 706 }
702 707
703 ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, 708 if (arizona->pdata.hpdet_acc_id_line) {
704 ARIZONA_HP_POLL, ARIZONA_HP_POLL); 709 ret = regmap_update_bits(arizona->regmap,
705 if (ret != 0) { 710 ARIZONA_HEADPHONE_DETECT_1,
706 dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n", 711 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
707 ret); 712 if (ret != 0) {
708 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);
709 } 720 }
710 721
711 return; 722 return;
@@ -724,28 +735,58 @@ err:
724 info->hpdet_active = false; 735 info->hpdet_active = false;
725} 736}
726 737
727static irqreturn_t arizona_micdet(int irq, void *data) 738static void arizona_micd_timeout_work(struct work_struct *work)
728{ 739{
729 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);
730 struct arizona *arizona = info->arizona; 761 struct arizona *arizona = info->arizona;
731 unsigned int val, lvl; 762 unsigned int val = 0, lvl;
732 int ret, i; 763 int ret, i, key;
764
765 cancel_delayed_work_sync(&info->micd_timeout_work);
733 766
734 mutex_lock(&info->lock); 767 mutex_lock(&info->lock);
735 768
736 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); 769 for (i = 0; i < 10 && !(val & 0x7fc); i++) {
737 if (ret != 0) { 770 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
738 dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); 771 if (ret != 0) {
739 mutex_unlock(&info->lock); 772 dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret);
740 return IRQ_NONE; 773 mutex_unlock(&info->lock);
741 } 774 return;
775 }
742 776
743 dev_dbg(arizona->dev, "MICDET: %x\n", val); 777 dev_dbg(arizona->dev, "MICDET: %x\n", val);
778
779 if (!(val & ARIZONA_MICD_VALID)) {
780 dev_warn(arizona->dev, "Microphone detection state invalid\n");
781 mutex_unlock(&info->lock);
782 return;
783 }
784 }
744 785
745 if (!(val & ARIZONA_MICD_VALID)) { 786 if (i == 10 && !(val & 0x7fc)) {
746 dev_warn(arizona->dev, "Microphone detection state invalid\n"); 787 dev_err(arizona->dev, "Failed to get valid MICDET value\n");
747 mutex_unlock(&info->lock); 788 mutex_unlock(&info->lock);
748 return IRQ_NONE; 789 return;
749 } 790 }
750 791
751 /* Due to jack detect this should never happen */ 792 /* Due to jack detect this should never happen */
@@ -786,7 +827,7 @@ static irqreturn_t arizona_micdet(int irq, void *data)
786 * impedence then give up and report headphones. 827 * impedence then give up and report headphones.
787 */ 828 */
788 if (info->detecting && (val & 0x3f8)) { 829 if (info->detecting && (val & 0x3f8)) {
789 if (info->jack_flips >= info->micd_num_modes) { 830 if (info->jack_flips >= info->micd_num_modes * 10) {
790 dev_dbg(arizona->dev, "Detected HP/line\n"); 831 dev_dbg(arizona->dev, "Detected HP/line\n");
791 arizona_identify_headphone(info); 832 arizona_identify_headphone(info);
792 833
@@ -816,12 +857,17 @@ static irqreturn_t arizona_micdet(int irq, void *data)
816 lvl = val & ARIZONA_MICD_LVL_MASK; 857 lvl = val & ARIZONA_MICD_LVL_MASK;
817 lvl >>= ARIZONA_MICD_LVL_SHIFT; 858 lvl >>= ARIZONA_MICD_LVL_SHIFT;
818 859
819 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 860 for (i = 0; i < info->num_micd_ranges; i++)
820 if (lvl & arizona_lvl_to_key[i].status) 861 input_report_key(info->input,
821 input_report_key(info->input, 862 info->micd_ranges[i].key, 0);
822 arizona_lvl_to_key[i].report, 863
823 1); 864 WARN_ON(!lvl);
824 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 }
825 871
826 } else if (info->detecting) { 872 } else if (info->detecting) {
827 dev_dbg(arizona->dev, "Headphone detected\n"); 873 dev_dbg(arizona->dev, "Headphone detected\n");
@@ -835,16 +881,41 @@ static irqreturn_t arizona_micdet(int irq, void *data)
835 } 881 }
836 } else { 882 } else {
837 dev_dbg(arizona->dev, "Mic button released\n"); 883 dev_dbg(arizona->dev, "Mic button released\n");
838 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 884 for (i = 0; i < info->num_micd_ranges; i++)
839 input_report_key(info->input, 885 input_report_key(info->input,
840 arizona_lvl_to_key[i].report, 0); 886 info->micd_ranges[i].key, 0);
841 input_sync(info->input); 887 input_sync(info->input);
842 arizona_extcon_pulse_micbias(info); 888 arizona_extcon_pulse_micbias(info);
843 } 889 }
844 890
845handled: 891handled:
892 if (info->detecting)
893 schedule_delayed_work(&info->micd_timeout_work,
894 msecs_to_jiffies(info->micd_timeout));
895
846 pm_runtime_mark_last_busy(info->dev); 896 pm_runtime_mark_last_busy(info->dev);
847 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);
848 919
849 return IRQ_HANDLED; 920 return IRQ_HANDLED;
850} 921}
@@ -865,11 +936,13 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
865 struct arizona_extcon_info *info = data; 936 struct arizona_extcon_info *info = data;
866 struct arizona *arizona = info->arizona; 937 struct arizona *arizona = info->arizona;
867 unsigned int val, present, mask; 938 unsigned int val, present, mask;
939 bool cancelled_hp, cancelled_mic;
868 int ret, i; 940 int ret, i;
869 941
870 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);
871 944
872 cancel_delayed_work_sync(&info->hpdet_work); 945 pm_runtime_get_sync(info->dev);
873 946
874 mutex_lock(&info->lock); 947 mutex_lock(&info->lock);
875 948
@@ -890,7 +963,22 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
890 return IRQ_NONE; 963 return IRQ_NONE;
891 } 964 }
892 965
893 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) {
894 dev_dbg(arizona->dev, "Detected jack\n"); 982 dev_dbg(arizona->dev, "Detected jack\n");
895 ret = extcon_set_cable_state_(&info->edev, 983 ret = extcon_set_cable_state_(&info->edev,
896 ARIZONA_CABLE_MECHANICAL, true); 984 ARIZONA_CABLE_MECHANICAL, true);
@@ -907,7 +995,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
907 arizona_start_mic(info); 995 arizona_start_mic(info);
908 } else { 996 } else {
909 schedule_delayed_work(&info->hpdet_work, 997 schedule_delayed_work(&info->hpdet_work,
910 msecs_to_jiffies(250)); 998 msecs_to_jiffies(HPDET_DEBOUNCE));
911 } 999 }
912 1000
913 regmap_update_bits(arizona->regmap, 1001 regmap_update_bits(arizona->regmap,
@@ -923,10 +1011,11 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
923 info->hpdet_res[i] = 0; 1011 info->hpdet_res[i] = 0;
924 info->mic = false; 1012 info->mic = false;
925 info->hpdet_done = false; 1013 info->hpdet_done = false;
1014 info->hpdet_retried = false;
926 1015
927 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 1016 for (i = 0; i < info->num_micd_ranges; i++)
928 input_report_key(info->input, 1017 input_report_key(info->input,
929 arizona_lvl_to_key[i].report, 0); 1018 info->micd_ranges[i].key, 0);
930 input_sync(info->input); 1019 input_sync(info->input);
931 1020
932 ret = extcon_update_state(&info->edev, 0xffffffff, 0); 1021 ret = extcon_update_state(&info->edev, 0xffffffff, 0);
@@ -940,6 +1029,11 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
940 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB); 1029 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
941 } 1030 }
942 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
943 /* Clear trig_sts to make sure DCVDD is not forced up */ 1037 /* Clear trig_sts to make sure DCVDD is not forced up */
944 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG, 1038 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
945 ARIZONA_MICD_CLAMP_FALL_TRIG_STS | 1039 ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
@@ -947,6 +1041,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
947 ARIZONA_JD1_FALL_TRIG_STS | 1041 ARIZONA_JD1_FALL_TRIG_STS |
948 ARIZONA_JD1_RISE_TRIG_STS); 1042 ARIZONA_JD1_RISE_TRIG_STS);
949 1043
1044out:
950 mutex_unlock(&info->lock); 1045 mutex_unlock(&info->lock);
951 1046
952 pm_runtime_mark_last_busy(info->dev); 1047 pm_runtime_mark_last_busy(info->dev);
@@ -955,13 +1050,34 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
955 return IRQ_HANDLED; 1050 return IRQ_HANDLED;
956} 1051}
957 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
958static int arizona_extcon_probe(struct platform_device *pdev) 1073static int arizona_extcon_probe(struct platform_device *pdev)
959{ 1074{
960 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 1075 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
961 struct arizona_pdata *pdata; 1076 struct arizona_pdata *pdata;
962 struct arizona_extcon_info *info; 1077 struct arizona_extcon_info *info;
1078 unsigned int val;
963 int jack_irq_fall, jack_irq_rise; 1079 int jack_irq_fall, jack_irq_rise;
964 int ret, mode, i; 1080 int ret, mode, i, j;
965 1081
966 if (!arizona->dapm || !arizona->dapm->card) 1082 if (!arizona->dapm || !arizona->dapm->card)
967 return -EPROBE_DEFER; 1083 return -EPROBE_DEFER;
@@ -985,7 +1101,10 @@ static int arizona_extcon_probe(struct platform_device *pdev)
985 mutex_init(&info->lock); 1101 mutex_init(&info->lock);
986 info->arizona = arizona; 1102 info->arizona = arizona;
987 info->dev = &pdev->dev; 1103 info->dev = &pdev->dev;
1104 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
988 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);
989 platform_set_drvdata(pdev, info); 1108 platform_set_drvdata(pdev, info);
990 1109
991 switch (arizona->type) { 1110 switch (arizona->type) {
@@ -1014,6 +1133,17 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1014 goto err; 1133 goto err;
1015 } 1134 }
1016 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
1017 if (pdata->num_micd_configs) { 1147 if (pdata->num_micd_configs) {
1018 info->micd_modes = pdata->micd_configs; 1148 info->micd_modes = pdata->micd_configs;
1019 info->micd_num_modes = pdata->num_micd_configs; 1149 info->micd_num_modes = pdata->num_micd_configs;
@@ -1069,15 +1199,79 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1069 arizona->pdata.micd_dbtime 1199 arizona->pdata.micd_dbtime
1070 << ARIZONA_MICD_DBTIME_SHIFT); 1200 << ARIZONA_MICD_DBTIME_SHIFT);
1071 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
1072 /* 1262 /*
1073 * If we have a clamp use it, activating in conjunction with 1263 * If we have a clamp use it, activating in conjunction with
1074 * GPIO5 if that is connected for jack detect operation. 1264 * GPIO5 if that is connected for jack detect operation.
1075 */ 1265 */
1076 if (info->micd_clamp) { 1266 if (info->micd_clamp) {
1077 if (arizona->pdata.jd_gpio5) { 1267 if (arizona->pdata.jd_gpio5) {
1078 /* 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
1079 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL, 1273 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
1080 0xc101); 1274 val);
1081 1275
1082 regmap_update_bits(arizona->regmap, 1276 regmap_update_bits(arizona->regmap,
1083 ARIZONA_MICD_CLAMP_CONTROL, 1277 ARIZONA_MICD_CLAMP_CONTROL,
@@ -1096,20 +1290,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1096 1290
1097 arizona_extcon_set_mode(info, 0); 1291 arizona_extcon_set_mode(info, 0);
1098 1292
1099 info->input = devm_input_allocate_device(&pdev->dev);
1100 if (!info->input) {
1101 dev_err(arizona->dev, "Can't allocate input dev\n");
1102 ret = -ENOMEM;
1103 goto err_register;
1104 }
1105
1106 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
1107 input_set_capability(info->input, EV_KEY,
1108 arizona_lvl_to_key[i].report);
1109 info->input->name = "Headset";
1110 info->input->phys = "arizona/extcon";
1111 info->input->dev.parent = &pdev->dev;
1112
1113 pm_runtime_enable(&pdev->dev); 1293 pm_runtime_enable(&pdev->dev);
1114 pm_runtime_idle(&pdev->dev); 1294 pm_runtime_idle(&pdev->dev);
1115 pm_runtime_get_sync(&pdev->dev); 1295 pm_runtime_get_sync(&pdev->dev);