Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

+321 -105
+288 -105
drivers/extcon/extcon-arizona.c
··· 33 33 #include <linux/mfd/arizona/pdata.h> 34 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 38 #define ARIZONA_ACCDET_MODE_MIC 0 39 39 #define ARIZONA_ACCDET_MODE_HPL 1 40 40 #define ARIZONA_ACCDET_MODE_HPR 2 41 + 42 + #define ARIZONA_HPDET_MAX 10000 43 + 44 + #define HPDET_DEBOUNCE 500 45 + #define DEFAULT_MICD_TIMEOUT 2000 41 46 42 47 struct arizona_extcon_info { 43 48 struct device *dev; ··· 51 46 struct regulator *micvdd; 52 47 struct input_dev *input; 53 48 49 + u16 last_jackdet; 50 + 54 51 int micd_mode; 55 52 const struct arizona_micd_config *micd_modes; 56 53 int micd_num_modes; 54 + 55 + const struct arizona_micd_range *micd_ranges; 56 + int num_micd_ranges; 57 + 58 + int micd_timeout; 57 59 58 60 bool micd_reva; 59 61 bool micd_clamp; 60 62 61 63 struct delayed_work hpdet_work; 64 + struct delayed_work micd_detect_work; 65 + struct delayed_work micd_timeout_work; 62 66 63 67 bool hpdet_active; 64 68 bool hpdet_done; 69 + bool hpdet_retried; 65 70 66 71 int num_hpdet_res; 67 72 unsigned int hpdet_res[3]; ··· 86 71 }; 87 72 88 73 static const struct arizona_micd_config micd_default_modes[] = { 89 - { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 }, 90 74 { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 }, 75 + { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 }, 91 76 }; 92 77 93 - static struct { 94 - u16 status; 95 - int report; 96 - } arizona_lvl_to_key[ARIZONA_NUM_BUTTONS] = { 97 - { 0x1, BTN_0 }, 98 - { 0x2, BTN_1 }, 99 - { 0x4, BTN_2 }, 100 - { 0x8, BTN_3 }, 101 - { 0x10, BTN_4 }, 102 - { 0x20, BTN_5 }, 78 + static const struct arizona_micd_range micd_default_ranges[] = { 79 + { .max = 11, .key = BTN_0 }, 80 + { .max = 28, .key = BTN_1 }, 81 + { .max = 54, .key = BTN_2 }, 82 + { .max = 100, .key = BTN_3 }, 83 + { .max = 186, .key = BTN_4 }, 84 + { .max = 430, .key = BTN_5 }, 85 + }; 86 + 87 + static const int arizona_micd_levels[] = { 88 + 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46, 89 + 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100, 90 + 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245, 91 + 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071, 92 + 1257, 103 93 }; 104 94 105 95 #define ARIZONA_CABLE_MECHANICAL 0 ··· 119 99 "Line-out", 120 100 NULL, 121 101 }; 102 + 103 + static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info); 122 104 123 105 static void arizona_extcon_do_magic(struct arizona_extcon_info *info, 124 106 unsigned int magic) ··· 174 152 static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) 175 153 { 176 154 struct arizona *arizona = info->arizona; 155 + 156 + mode %= info->micd_num_modes; 177 157 178 158 if (arizona->pdata.micd_pol_gpio > 0) 179 159 gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio, ··· 403 379 /* If we go out of range report top of range */ 404 380 if (val < 100 || val > 0x3fb) { 405 381 dev_dbg(arizona->dev, "Measurement out of range\n"); 406 - return 10000; 382 + return ARIZONA_HPDET_MAX; 407 383 } 408 384 409 385 dev_dbg(arizona->dev, "HPDET read %d in range %d\n", ··· 464 440 return val; 465 441 } 466 442 467 - static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading) 443 + static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading, 444 + bool *mic) 468 445 { 469 446 struct arizona *arizona = info->arizona; 470 447 int id_gpio = arizona->pdata.hpdet_id_gpio; ··· 477 452 if (arizona->pdata.hpdet_acc_id) { 478 453 info->hpdet_res[info->num_hpdet_res++] = *reading; 479 454 480 - /* 481 - * If the impedence is too high don't measure the 482 - * second ground. 483 - */ 484 - if (info->num_hpdet_res == 1 && *reading >= 45) { 485 - dev_dbg(arizona->dev, "Skipping ground flip\n"); 486 - info->hpdet_res[info->num_hpdet_res++] = *reading; 487 - } 488 - 489 - if (info->num_hpdet_res == 1) { 490 - dev_dbg(arizona->dev, "Flipping ground\n"); 491 - 492 - regmap_update_bits(arizona->regmap, 493 - ARIZONA_ACCESSORY_DETECT_MODE_1, 494 - ARIZONA_ACCDET_SRC, 495 - ~info->micd_modes[0].src); 496 - 497 - regmap_update_bits(arizona->regmap, 498 - ARIZONA_HEADPHONE_DETECT_1, 499 - ARIZONA_HP_POLL, ARIZONA_HP_POLL); 500 - return -EAGAIN; 501 - } 502 - 503 455 /* Only check the mic directly if we didn't already ID it */ 504 - if (id_gpio && info->num_hpdet_res == 2 && 505 - !((info->hpdet_res[0] > info->hpdet_res[1] * 2))) { 456 + if (id_gpio && info->num_hpdet_res == 1) { 506 457 dev_dbg(arizona->dev, "Measuring mic\n"); 507 458 508 459 regmap_update_bits(arizona->regmap, ··· 497 496 } 498 497 499 498 /* OK, got both. Now, compare... */ 500 - dev_dbg(arizona->dev, "HPDET measured %d %d %d\n", 501 - info->hpdet_res[0], info->hpdet_res[1], 502 - info->hpdet_res[2]); 503 - 499 + dev_dbg(arizona->dev, "HPDET measured %d %d\n", 500 + info->hpdet_res[0], info->hpdet_res[1]); 504 501 505 502 /* Take the headphone impedance for the main report */ 506 503 *reading = info->hpdet_res[0]; 507 504 505 + /* Sometimes we get false readings due to slow insert */ 506 + if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) { 507 + dev_dbg(arizona->dev, "Retrying high impedance\n"); 508 + info->num_hpdet_res = 0; 509 + info->hpdet_retried = true; 510 + arizona_start_hpdet_acc_id(info); 511 + pm_runtime_put(info->dev); 512 + return -EAGAIN; 513 + } 514 + 508 515 /* 509 - * Either the two grounds measure differently or we 510 - * measure the mic as high impedance. 516 + * If we measure the mic as 511 517 */ 512 - if ((info->hpdet_res[0] > info->hpdet_res[1] * 2) || 513 - (id_gpio && info->hpdet_res[2] > 10)) { 518 + if (!id_gpio || info->hpdet_res[1] > 50) { 514 519 dev_dbg(arizona->dev, "Detected mic\n"); 515 - info->mic = true; 520 + *mic = true; 516 521 info->detecting = true; 517 522 } else { 518 523 dev_dbg(arizona->dev, "Detected headphone\n"); ··· 541 534 int id_gpio = arizona->pdata.hpdet_id_gpio; 542 535 int report = ARIZONA_CABLE_HEADPHONE; 543 536 int ret, reading; 537 + bool mic = false; 544 538 545 539 mutex_lock(&info->lock); 546 540 ··· 577 569 ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL, 578 570 0); 579 571 580 - ret = arizona_hpdet_do_id(info, &reading); 572 + ret = arizona_hpdet_do_id(info, &reading, &mic); 581 573 if (ret == -EAGAIN) { 582 574 goto out; 583 575 } else if (ret < 0) { ··· 607 599 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); 608 600 609 601 /* If we have a mic then reenable MICDET */ 610 - if (info->mic) 602 + if (mic || info->mic) 611 603 arizona_start_mic(info); 612 604 613 605 if (info->hpdet_active) { ··· 682 674 static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) 683 675 { 684 676 struct arizona *arizona = info->arizona; 677 + int hp_reading = 32; 678 + bool mic; 685 679 int ret; 686 680 687 681 dev_dbg(arizona->dev, "Starting identification via HPDET\n"); ··· 692 682 pm_runtime_get_sync(info->dev); 693 683 694 684 info->hpdet_active = true; 695 - 696 - arizona_extcon_pulse_micbias(info); 697 685 698 686 arizona_extcon_do_magic(info, 0x4000); 699 687 ··· 705 697 goto err; 706 698 } 707 699 708 - ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, 709 - ARIZONA_HP_POLL, ARIZONA_HP_POLL); 710 - if (ret != 0) { 711 - dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n", 712 - ret); 713 - goto err; 700 + if (arizona->pdata.hpdet_acc_id_line) { 701 + ret = regmap_update_bits(arizona->regmap, 702 + ARIZONA_HEADPHONE_DETECT_1, 703 + ARIZONA_HP_POLL, ARIZONA_HP_POLL); 704 + if (ret != 0) { 705 + dev_err(arizona->dev, 706 + "Can't start HPDETL measurement: %d\n", 707 + ret); 708 + goto err; 709 + } 710 + } else { 711 + arizona_hpdet_do_id(info, &hp_reading, &mic); 714 712 } 715 713 716 714 return; ··· 735 721 info->hpdet_active = false; 736 722 } 737 723 738 - static irqreturn_t arizona_micdet(int irq, void *data) 724 + static void arizona_micd_timeout_work(struct work_struct *work) 739 725 { 740 - struct arizona_extcon_info *info = data; 741 - struct arizona *arizona = info->arizona; 742 - unsigned int val, lvl; 743 - int ret, i; 726 + struct arizona_extcon_info *info = container_of(work, 727 + struct arizona_extcon_info, 728 + micd_timeout_work.work); 744 729 745 730 mutex_lock(&info->lock); 746 731 747 - ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); 748 - if (ret != 0) { 749 - dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); 750 - mutex_unlock(&info->lock); 751 - return IRQ_NONE; 732 + dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n"); 733 + arizona_identify_headphone(info); 734 + 735 + info->detecting = false; 736 + 737 + arizona_stop_mic(info); 738 + 739 + mutex_unlock(&info->lock); 740 + } 741 + 742 + static void arizona_micd_detect(struct work_struct *work) 743 + { 744 + struct arizona_extcon_info *info = container_of(work, 745 + struct arizona_extcon_info, 746 + micd_detect_work.work); 747 + struct arizona *arizona = info->arizona; 748 + unsigned int val = 0, lvl; 749 + int ret, i, key; 750 + 751 + cancel_delayed_work_sync(&info->micd_timeout_work); 752 + 753 + mutex_lock(&info->lock); 754 + 755 + for (i = 0; i < 10 && !(val & 0x7fc); i++) { 756 + ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); 757 + if (ret != 0) { 758 + dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); 759 + mutex_unlock(&info->lock); 760 + return; 761 + } 762 + 763 + dev_dbg(arizona->dev, "MICDET: %x\n", val); 764 + 765 + if (!(val & ARIZONA_MICD_VALID)) { 766 + dev_warn(arizona->dev, "Microphone detection state invalid\n"); 767 + mutex_unlock(&info->lock); 768 + return; 769 + } 752 770 } 753 771 754 - dev_dbg(arizona->dev, "MICDET: %x\n", val); 755 - 756 - if (!(val & ARIZONA_MICD_VALID)) { 757 - dev_warn(arizona->dev, "Microphone detection state invalid\n"); 772 + if (i == 10 && !(val & 0x7fc)) { 773 + dev_err(arizona->dev, "Failed to get valid MICDET value\n"); 758 774 mutex_unlock(&info->lock); 759 - return IRQ_NONE; 775 + return; 760 776 } 761 777 762 778 /* Due to jack detect this should never happen */ ··· 827 783 * impedence then give up and report headphones. 828 784 */ 829 785 if (info->detecting && (val & 0x3f8)) { 830 - if (info->jack_flips >= info->micd_num_modes) { 786 + if (info->jack_flips >= info->micd_num_modes * 10) { 831 787 dev_dbg(arizona->dev, "Detected HP/line\n"); 832 788 arizona_identify_headphone(info); 833 789 ··· 857 813 lvl = val & ARIZONA_MICD_LVL_MASK; 858 814 lvl >>= ARIZONA_MICD_LVL_SHIFT; 859 815 860 - for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 861 - if (lvl & arizona_lvl_to_key[i].status) 862 - input_report_key(info->input, 863 - arizona_lvl_to_key[i].report, 864 - 1); 865 - input_sync(info->input); 816 + for (i = 0; i < info->num_micd_ranges; i++) 817 + input_report_key(info->input, 818 + info->micd_ranges[i].key, 0); 819 + 820 + WARN_ON(!lvl); 821 + WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges); 822 + if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) { 823 + key = info->micd_ranges[ffs(lvl) - 1].key; 824 + input_report_key(info->input, key, 1); 825 + input_sync(info->input); 826 + } 866 827 867 828 } else if (info->detecting) { 868 829 dev_dbg(arizona->dev, "Headphone detected\n"); ··· 881 832 } 882 833 } else { 883 834 dev_dbg(arizona->dev, "Mic button released\n"); 884 - for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 835 + for (i = 0; i < info->num_micd_ranges; i++) 885 836 input_report_key(info->input, 886 - arizona_lvl_to_key[i].report, 0); 837 + info->micd_ranges[i].key, 0); 887 838 input_sync(info->input); 888 839 arizona_extcon_pulse_micbias(info); 889 840 } 890 841 891 842 handled: 843 + if (info->detecting) 844 + schedule_delayed_work(&info->micd_timeout_work, 845 + msecs_to_jiffies(info->micd_timeout)); 846 + 892 847 pm_runtime_mark_last_busy(info->dev); 893 848 mutex_unlock(&info->lock); 849 + } 850 + 851 + static irqreturn_t arizona_micdet(int irq, void *data) 852 + { 853 + struct arizona_extcon_info *info = data; 854 + struct arizona *arizona = info->arizona; 855 + int debounce = arizona->pdata.micd_detect_debounce; 856 + 857 + cancel_delayed_work_sync(&info->micd_detect_work); 858 + cancel_delayed_work_sync(&info->micd_timeout_work); 859 + 860 + mutex_lock(&info->lock); 861 + if (!info->detecting) 862 + debounce = 0; 863 + mutex_unlock(&info->lock); 864 + 865 + if (debounce) 866 + schedule_delayed_work(&info->micd_detect_work, 867 + msecs_to_jiffies(debounce)); 868 + else 869 + arizona_micd_detect(&info->micd_detect_work.work); 894 870 895 871 return IRQ_HANDLED; 896 872 } ··· 936 862 struct arizona_extcon_info *info = data; 937 863 struct arizona *arizona = info->arizona; 938 864 unsigned int val, present, mask; 865 + bool cancelled_hp, cancelled_mic; 939 866 int ret, i; 940 867 941 - pm_runtime_get_sync(info->dev); 868 + cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work); 869 + cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work); 942 870 943 - cancel_delayed_work_sync(&info->hpdet_work); 871 + pm_runtime_get_sync(info->dev); 944 872 945 873 mutex_lock(&info->lock); 946 874 ··· 963 887 return IRQ_NONE; 964 888 } 965 889 966 - if ((val & mask) == present) { 890 + val &= mask; 891 + if (val == info->last_jackdet) { 892 + dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n"); 893 + if (cancelled_hp) 894 + schedule_delayed_work(&info->hpdet_work, 895 + msecs_to_jiffies(HPDET_DEBOUNCE)); 896 + 897 + if (cancelled_mic) 898 + schedule_delayed_work(&info->micd_timeout_work, 899 + msecs_to_jiffies(info->micd_timeout)); 900 + 901 + goto out; 902 + } 903 + info->last_jackdet = val; 904 + 905 + if (info->last_jackdet == present) { 967 906 dev_dbg(arizona->dev, "Detected jack\n"); 968 907 ret = extcon_set_cable_state_(&info->edev, 969 908 ARIZONA_CABLE_MECHANICAL, true); ··· 995 904 arizona_start_mic(info); 996 905 } else { 997 906 schedule_delayed_work(&info->hpdet_work, 998 - msecs_to_jiffies(250)); 907 + msecs_to_jiffies(HPDET_DEBOUNCE)); 999 908 } 1000 909 1001 910 regmap_update_bits(arizona->regmap, ··· 1011 920 info->hpdet_res[i] = 0; 1012 921 info->mic = false; 1013 922 info->hpdet_done = false; 923 + info->hpdet_retried = false; 1014 924 1015 - for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 925 + for (i = 0; i < info->num_micd_ranges; i++) 1016 926 input_report_key(info->input, 1017 - arizona_lvl_to_key[i].report, 0); 927 + info->micd_ranges[i].key, 0); 1018 928 input_sync(info->input); 1019 929 1020 930 ret = extcon_update_state(&info->edev, 0xffffffff, 0); ··· 1029 937 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB); 1030 938 } 1031 939 940 + if (arizona->pdata.micd_timeout) 941 + info->micd_timeout = arizona->pdata.micd_timeout; 942 + else 943 + info->micd_timeout = DEFAULT_MICD_TIMEOUT; 944 + 1032 945 /* Clear trig_sts to make sure DCVDD is not forced up */ 1033 946 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG, 1034 947 ARIZONA_MICD_CLAMP_FALL_TRIG_STS | ··· 1041 944 ARIZONA_JD1_FALL_TRIG_STS | 1042 945 ARIZONA_JD1_RISE_TRIG_STS); 1043 946 947 + out: 1044 948 mutex_unlock(&info->lock); 1045 949 1046 950 pm_runtime_mark_last_busy(info->dev); ··· 1050 952 return IRQ_HANDLED; 1051 953 } 1052 954 955 + /* Map a level onto a slot in the register bank */ 956 + static void arizona_micd_set_level(struct arizona *arizona, int index, 957 + unsigned int level) 958 + { 959 + int reg; 960 + unsigned int mask; 961 + 962 + reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2); 963 + 964 + if (!(index % 2)) { 965 + mask = 0x3f00; 966 + level <<= 8; 967 + } else { 968 + mask = 0x3f; 969 + } 970 + 971 + /* Program the level itself */ 972 + regmap_update_bits(arizona->regmap, reg, mask, level); 973 + } 974 + 1053 975 static int arizona_extcon_probe(struct platform_device *pdev) 1054 976 { 1055 977 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 1056 978 struct arizona_pdata *pdata; 1057 979 struct arizona_extcon_info *info; 980 + unsigned int val; 1058 981 int jack_irq_fall, jack_irq_rise; 1059 - int ret, mode, i; 982 + int ret, mode, i, j; 1060 983 1061 984 if (!arizona->dapm || !arizona->dapm->card) 1062 985 return -EPROBE_DEFER; ··· 1101 982 mutex_init(&info->lock); 1102 983 info->arizona = arizona; 1103 984 info->dev = &pdev->dev; 985 + info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS); 1104 986 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work); 987 + INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect); 988 + INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work); 1105 989 platform_set_drvdata(pdev, info); 1106 990 1107 991 switch (arizona->type) { ··· 1132 1010 ret); 1133 1011 goto err; 1134 1012 } 1013 + 1014 + info->input = devm_input_allocate_device(&pdev->dev); 1015 + if (!info->input) { 1016 + dev_err(arizona->dev, "Can't allocate input dev\n"); 1017 + ret = -ENOMEM; 1018 + goto err_register; 1019 + } 1020 + 1021 + info->input->name = "Headset"; 1022 + info->input->phys = "arizona/extcon"; 1023 + info->input->dev.parent = &pdev->dev; 1135 1024 1136 1025 if (pdata->num_micd_configs) { 1137 1026 info->micd_modes = pdata->micd_configs; ··· 1199 1066 arizona->pdata.micd_dbtime 1200 1067 << ARIZONA_MICD_DBTIME_SHIFT); 1201 1068 1069 + BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40); 1070 + 1071 + if (arizona->pdata.num_micd_ranges) { 1072 + info->micd_ranges = pdata->micd_ranges; 1073 + info->num_micd_ranges = pdata->num_micd_ranges; 1074 + } else { 1075 + info->micd_ranges = micd_default_ranges; 1076 + info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges); 1077 + } 1078 + 1079 + if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) { 1080 + dev_err(arizona->dev, "Too many MICD ranges: %d\n", 1081 + arizona->pdata.num_micd_ranges); 1082 + } 1083 + 1084 + if (info->num_micd_ranges > 1) { 1085 + for (i = 1; i < info->num_micd_ranges; i++) { 1086 + if (info->micd_ranges[i - 1].max > 1087 + info->micd_ranges[i].max) { 1088 + dev_err(arizona->dev, 1089 + "MICD ranges must be sorted\n"); 1090 + ret = -EINVAL; 1091 + goto err_input; 1092 + } 1093 + } 1094 + } 1095 + 1096 + /* Disable all buttons by default */ 1097 + regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2, 1098 + ARIZONA_MICD_LVL_SEL_MASK, 0x81); 1099 + 1100 + /* Set up all the buttons the user specified */ 1101 + for (i = 0; i < info->num_micd_ranges; i++) { 1102 + for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++) 1103 + if (arizona_micd_levels[j] >= info->micd_ranges[i].max) 1104 + break; 1105 + 1106 + if (j == ARRAY_SIZE(arizona_micd_levels)) { 1107 + dev_err(arizona->dev, "Unsupported MICD level %d\n", 1108 + info->micd_ranges[i].max); 1109 + ret = -EINVAL; 1110 + goto err_input; 1111 + } 1112 + 1113 + dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n", 1114 + arizona_micd_levels[j], i); 1115 + 1116 + arizona_micd_set_level(arizona, i, j); 1117 + input_set_capability(info->input, EV_KEY, 1118 + info->micd_ranges[i].key); 1119 + 1120 + /* Enable reporting of that range */ 1121 + regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2, 1122 + 1 << i, 1 << i); 1123 + } 1124 + 1125 + /* Set all the remaining keys to a maximum */ 1126 + for (; i < ARIZONA_MAX_MICD_RANGE; i++) 1127 + arizona_micd_set_level(arizona, i, 0x3f); 1128 + 1202 1129 /* 1203 1130 * If we have a clamp use it, activating in conjunction with 1204 1131 * GPIO5 if that is connected for jack detect operation. 1205 1132 */ 1206 1133 if (info->micd_clamp) { 1207 1134 if (arizona->pdata.jd_gpio5) { 1208 - /* Put the GPIO into input mode */ 1135 + /* Put the GPIO into input mode with optional pull */ 1136 + val = 0xc101; 1137 + if (arizona->pdata.jd_gpio5_nopull) 1138 + val &= ~ARIZONA_GPN_PU; 1139 + 1209 1140 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL, 1210 - 0xc101); 1141 + val); 1211 1142 1212 1143 regmap_update_bits(arizona->regmap, 1213 1144 ARIZONA_MICD_CLAMP_CONTROL, ··· 1289 1092 } 1290 1093 1291 1094 arizona_extcon_set_mode(info, 0); 1292 - 1293 - info->input = devm_input_allocate_device(&pdev->dev); 1294 - if (!info->input) { 1295 - dev_err(arizona->dev, "Can't allocate input dev\n"); 1296 - ret = -ENOMEM; 1297 - goto err_register; 1298 - } 1299 - 1300 - for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 1301 - input_set_capability(info->input, EV_KEY, 1302 - arizona_lvl_to_key[i].report); 1303 - info->input->name = "Headset"; 1304 - info->input->phys = "arizona/extcon"; 1305 - info->input->dev.parent = &pdev->dev; 1306 1095 1307 1096 pm_runtime_enable(&pdev->dev); 1308 1097 pm_runtime_idle(&pdev->dev);
+8
drivers/mfd/wm5102-tables.c
··· 331 331 { 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */ 332 332 { 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */ 333 333 { 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */ 334 + { 0x000002A6, 0x3737 }, /* R678 - Mic Detect Level 1 */ 335 + { 0x000002A7, 0x372C }, /* R679 - Mic Detect Level 2 */ 336 + { 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */ 337 + { 0x000002A9, 0x030A }, /* R681 - Mic Detect Level 4 */ 334 338 { 0x000002C3, 0x0000 }, /* R707 - Mic noise mix control 1 */ 335 339 { 0x000002CB, 0x0000 }, /* R715 - Isolation control */ 336 340 { 0x000002D3, 0x0000 }, /* R723 - Jack detect analogue */ ··· 1094 1090 case ARIZONA_MIC_DETECT_1: 1095 1091 case ARIZONA_MIC_DETECT_2: 1096 1092 case ARIZONA_MIC_DETECT_3: 1093 + case ARIZONA_MIC_DETECT_LEVEL_1: 1094 + case ARIZONA_MIC_DETECT_LEVEL_2: 1095 + case ARIZONA_MIC_DETECT_LEVEL_3: 1096 + case ARIZONA_MIC_DETECT_LEVEL_4: 1097 1097 case ARIZONA_MIC_NOISE_MIX_CONTROL_1: 1098 1098 case ARIZONA_ISOLATION_CONTROL: 1099 1099 case ARIZONA_JACK_DETECT_ANALOGUE:
+21
include/linux/mfd/arizona/pdata.h
··· 86 86 bool gpio; 87 87 }; 88 88 89 + struct arizona_micd_range { 90 + int max; /** Ohms */ 91 + int key; /** Key to report to input layer */ 92 + }; 93 + 89 94 struct arizona_pdata { 90 95 int reset; /** GPIO controlling /RESET, if any */ 91 96 int ldoena; /** GPIO controlling LODENA, if any */ ··· 122 117 /** GPIO5 is used for jack detection */ 123 118 bool jd_gpio5; 124 119 120 + /** Internal pull on GPIO5 is disabled when used for jack detection */ 121 + bool jd_gpio5_nopull; 122 + 125 123 /** Use the headphone detect circuit to identify the accessory */ 126 124 bool hpdet_acc_id; 127 125 126 + /** Check for line output with HPDET method */ 127 + bool hpdet_acc_id_line; 128 + 128 129 /** GPIO used for mic isolation with HPDET */ 129 130 int hpdet_id_gpio; 131 + 132 + /** Extra debounce timeout used during initial mic detection (ms) */ 133 + int micd_detect_debounce; 130 134 131 135 /** GPIO for mic detection polarity */ 132 136 int micd_pol_gpio; ··· 149 135 /** Mic detect debounce level */ 150 136 int micd_dbtime; 151 137 138 + /** Mic detect timeout (ms) */ 139 + int micd_timeout; 140 + 152 141 /** Force MICBIAS on for mic detect */ 153 142 bool micd_force_micbias; 143 + 144 + /** Mic detect level parameters */ 145 + const struct arizona_micd_range *micd_ranges; 146 + int num_micd_ranges; 154 147 155 148 /** Headset polarity configurations */ 156 149 struct arizona_micd_config *micd_configs;
+4
include/linux/mfd/arizona/registers.h
··· 124 124 #define ARIZONA_MIC_DETECT_1 0x2A3 125 125 #define ARIZONA_MIC_DETECT_2 0x2A4 126 126 #define ARIZONA_MIC_DETECT_3 0x2A5 127 + #define ARIZONA_MIC_DETECT_LEVEL_1 0x2A6 128 + #define ARIZONA_MIC_DETECT_LEVEL_2 0x2A7 129 + #define ARIZONA_MIC_DETECT_LEVEL_3 0x2A8 130 + #define ARIZONA_MIC_DETECT_LEVEL_4 0x2A9 127 131 #define ARIZONA_MIC_NOISE_MIX_CONTROL_1 0x2C3 128 132 #define ARIZONA_ISOLATION_CONTROL 0x2CB 129 133 #define ARIZONA_JACK_DETECT_ANALOGUE 0x2D3