^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * extcon-arizona.c - Extcon driver Wolfson Arizona devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2012-2014 Wolfson Microelectronics plc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/extcon-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/mfd/arizona/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mfd/arizona/pdata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/mfd/arizona/registers.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <dt-bindings/mfd/arizona.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define ARIZONA_MAX_MICD_RANGE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define ARIZONA_MICD_CLAMP_MODE_JDL 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define ARIZONA_MICD_CLAMP_MODE_JDH 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define ARIZONA_TST_CAP_DEFAULT 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define ARIZONA_TST_CAP_CLAMP 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ARIZONA_HPDET_MAX 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define HPDET_DEBOUNCE 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DEFAULT_MICD_TIMEOUT 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ARIZONA_HPDET_WAIT_COUNT 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define ARIZONA_HPDET_WAIT_DELAY_MS 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define QUICK_HEADPHONE_MAX_OHM 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MICROPHONE_MIN_OHM 1257
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MICROPHONE_MAX_OHM 30000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MICD_DBTIME_TWO_READINGS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MICD_DBTIME_FOUR_READINGS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MICD_LVL_1_TO_7 (ARIZONA_MICD_LVL_1 | ARIZONA_MICD_LVL_2 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ARIZONA_MICD_LVL_3 | ARIZONA_MICD_LVL_4 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ARIZONA_MICD_LVL_5 | ARIZONA_MICD_LVL_6 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ARIZONA_MICD_LVL_7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define MICD_LVL_0_TO_7 (ARIZONA_MICD_LVL_0 | MICD_LVL_1_TO_7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define MICD_LVL_0_TO_8 (MICD_LVL_0_TO_7 | ARIZONA_MICD_LVL_8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct arizona_extcon_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct arizona *arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct regulator *micvdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u16 last_jackdet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int micd_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) const struct arizona_micd_config *micd_modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int micd_num_modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) const struct arizona_micd_range *micd_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int num_micd_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) bool micd_reva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) bool micd_clamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct delayed_work hpdet_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct delayed_work micd_detect_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct delayed_work micd_timeout_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) bool hpdet_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) bool hpdet_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) bool hpdet_retried;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int num_hpdet_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned int hpdet_res[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) bool mic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) bool detecting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int jack_flips;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int hpdet_ip_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct extcon_dev *edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct gpio_desc *micd_pol_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static const struct arizona_micd_config micd_default_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) { ARIZONA_ACCDET_SRC, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) { 0, 2, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static const struct arizona_micd_range micd_default_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) { .max = 11, .key = BTN_0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) { .max = 28, .key = BTN_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { .max = 54, .key = BTN_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) { .max = 100, .key = BTN_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) { .max = 186, .key = BTN_4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { .max = 430, .key = BTN_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* The number of levels in arizona_micd_levels valid for button thresholds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define ARIZONA_NUM_MICD_BUTTON_LEVELS 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static const int arizona_micd_levels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 1257, 30000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static const unsigned int arizona_cable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) EXTCON_MECHANICAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) EXTCON_JACK_MICROPHONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) EXTCON_JACK_HEADPHONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) EXTCON_JACK_LINE_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) EXTCON_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) bool clamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) unsigned int mask = 0, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned int cap_sel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) switch (arizona->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) case WM8998:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case WM1814:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case WM5110:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) case WM8280:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ARIZONA_HP1L_SHRTI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (clamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) val = ARIZONA_HP1L_SHRTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) cap_sel = ARIZONA_TST_CAP_CLAMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) val = ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) cap_sel = ARIZONA_TST_CAP_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ret = regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ARIZONA_HP_TEST_CTRL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ARIZONA_HP1_TST_CAP_SEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) cap_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dev_warn(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) "Failed to set TST_CAP_SEL: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) mask = ARIZONA_RMV_SHRT_HP1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (clamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) val = ARIZONA_RMV_SHRT_HP1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) snd_soc_dapm_mutex_lock(arizona->dapm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) arizona->hpdet_clamp = clamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Keep the HP output stages disabled while doing the clamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (clamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ret = regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ARIZONA_OUTPUT_ENABLES_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ARIZONA_OUT1L_ENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ARIZONA_OUT1R_ENA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dev_warn(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) "Failed to disable headphone outputs: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) dev_warn(arizona->dev, "Failed to do clamp: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1R,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) dev_warn(arizona->dev, "Failed to do clamp: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* Restore the desired state while not doing the clamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!clamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ret = regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ARIZONA_OUTPUT_ENABLES_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ARIZONA_OUT1L_ENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ARIZONA_OUT1R_ENA, arizona->hp_ena);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dev_warn(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) "Failed to restore headphone outputs: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) snd_soc_dapm_mutex_unlock(arizona->dapm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) mode %= info->micd_num_modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) gpiod_set_value_cansleep(info->micd_pol_gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) info->micd_modes[mode].gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ARIZONA_MICD_BIAS_SRC_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) info->micd_modes[mode].bias <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ARIZONA_MICD_BIAS_SRC_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) info->micd_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) switch (info->micd_modes[0].bias) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return "MICBIAS1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return "MICBIAS2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return "MICBIAS3";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return "MICVDD";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) const char *widget = arizona_extcon_get_micbias(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct snd_soc_dapm_context *dapm = arizona->dapm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = snd_soc_component_force_enable_pin(component, widget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) dev_warn(arizona->dev, "Failed to enable %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) widget, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) snd_soc_dapm_sync(dapm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (!arizona->pdata.micd_force_micbias) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ret = snd_soc_component_disable_pin(component, widget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) dev_warn(arizona->dev, "Failed to disable %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) widget, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) snd_soc_dapm_sync(dapm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void arizona_start_mic(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) bool change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* Microphone detection can't use idle mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) pm_runtime_get(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (info->detecting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ret = regulator_allow_bypass(info->micvdd, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) dev_err(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) "Failed to regulate MICVDD: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ret = regulator_enable(info->micvdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (info->micd_reva) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) const struct reg_sequence reva[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { 0x80, 0x3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) { 0x294, 0x0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) { 0x80, 0x0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) regmap_multi_reg_write(arizona->regmap, reva, ARRAY_SIZE(reva));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (info->detecting && arizona->pdata.micd_software_compare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mode = ARIZONA_ACCDET_MODE_ADC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) mode = ARIZONA_ACCDET_MODE_MIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ARIZONA_ACCESSORY_DETECT_MODE_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ARIZONA_ACCDET_MODE_MASK, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) arizona_extcon_pulse_micbias(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) &change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_err(arizona->dev, "Failed to enable micd: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) } else if (!change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) regulator_disable(info->micvdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) pm_runtime_put_autosuspend(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static void arizona_stop_mic(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) const char *widget = arizona_extcon_get_micbias(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct snd_soc_dapm_context *dapm = arizona->dapm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) bool change = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ARIZONA_MICD_ENA, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) &change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dev_err(arizona->dev, "Failed to disable micd: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ret = snd_soc_component_disable_pin(component, widget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_warn(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) "Failed to disable %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) widget, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) snd_soc_dapm_sync(dapm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (info->micd_reva) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) const struct reg_sequence reva[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) { 0x80, 0x3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) { 0x294, 0x2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) { 0x80, 0x0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) regmap_multi_reg_write(arizona->regmap, reva, ARRAY_SIZE(reva));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = regulator_allow_bypass(info->micvdd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) regulator_disable(info->micvdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) pm_runtime_mark_last_busy(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) pm_runtime_put_autosuspend(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) unsigned int threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) unsigned int factor_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) unsigned int factor_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) } arizona_hpdet_b_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) { 100, 5528, 362464 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) { 169, 11084, 6186851 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) { 169, 11065, 65460395 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) #define ARIZONA_HPDET_B_RANGE_MAX 0x3fb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) } arizona_hpdet_c_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) { 0, 30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) { 8, 100 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { 100, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) { 1000, 10000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static int arizona_hpdet_read(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) unsigned int val, range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) switch (info->hpdet_ip_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (!(val & ARIZONA_HP_DONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dev_err(arizona->dev, "HPDET did not complete: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) val &= ARIZONA_HP_LVL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (!(val & ARIZONA_HP_DONE_B)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) dev_err(arizona->dev, "HPDET did not complete: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dev_err(arizona->dev, "Failed to read HP value: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) &range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) (val < arizona_hpdet_b_ranges[range].threshold ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) val >= ARIZONA_HPDET_B_RANGE_MAX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) range++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ARIZONA_HEADPHONE_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ARIZONA_HP_IMPEDANCE_RANGE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) range <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* If we go out of range report top of range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (val < arizona_hpdet_b_ranges[range].threshold ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) val >= ARIZONA_HPDET_B_RANGE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) dev_dbg(arizona->dev, "Measurement out of range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ARIZONA_HPDET_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) val, range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) val = arizona_hpdet_b_ranges[range].factor_b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) / ((val * 100) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) arizona_hpdet_b_ranges[range].factor_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (!(val & ARIZONA_HP_DONE_B)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dev_err(arizona->dev, "HPDET did not complete: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) val &= ARIZONA_HP_LVL_B_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Convert to ohms, the value is in 0.5 ohm increments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) val /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) &range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* Skip up a range, or report? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) (val >= arizona_hpdet_c_ranges[range].max)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) range++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) arizona_hpdet_c_ranges[range].min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) arizona_hpdet_c_ranges[range].max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ARIZONA_HEADPHONE_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ARIZONA_HP_IMPEDANCE_RANGE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) range <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (range && (val < arizona_hpdet_c_ranges[range].min)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dev_dbg(arizona->dev, "Reporting range boundary %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) arizona_hpdet_c_ranges[range].min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) val = arizona_hpdet_c_ranges[range].min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) info->hpdet_ip_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) bool *mic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int id_gpio = arizona->pdata.hpdet_id_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (!arizona->pdata.hpdet_acc_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * If we're using HPDET for accessory identification we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * to take multiple measurements, step through them in sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) info->hpdet_res[info->num_hpdet_res++] = *reading;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* Only check the mic directly if we didn't already ID it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (id_gpio && info->num_hpdet_res == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) dev_dbg(arizona->dev, "Measuring mic\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ARIZONA_ACCESSORY_DETECT_MODE_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ARIZONA_ACCDET_MODE_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ARIZONA_ACCDET_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ARIZONA_ACCDET_MODE_HPR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) info->micd_modes[0].src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) gpio_set_value_cansleep(id_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ARIZONA_HP_POLL, ARIZONA_HP_POLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* OK, got both. Now, compare... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) dev_dbg(arizona->dev, "HPDET measured %d %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) info->hpdet_res[0], info->hpdet_res[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* Take the headphone impedance for the main report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) *reading = info->hpdet_res[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* Sometimes we get false readings due to slow insert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dev_dbg(arizona->dev, "Retrying high impedance\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) info->num_hpdet_res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) info->hpdet_retried = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) arizona_start_hpdet_acc_id(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) pm_runtime_put(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * If we measure the mic as high impedance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (!id_gpio || info->hpdet_res[1] > 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) dev_dbg(arizona->dev, "Detected mic\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) *mic = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) info->detecting = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) dev_dbg(arizona->dev, "Detected headphone\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* Make sure everything is reset back to the real polarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ARIZONA_ACCDET_SRC, info->micd_modes[0].src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static irqreturn_t arizona_hpdet_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct arizona_extcon_info *info = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int id_gpio = arizona->pdata.hpdet_id_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) unsigned int report = EXTCON_JACK_HEADPHONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) int ret, reading, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) bool mic = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) mutex_lock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* If we got a spurious IRQ for some reason then ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!info->hpdet_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) dev_warn(arizona->dev, "Spurious HPDET IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* If the cable was removed while measuring ignore the result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) state = extcon_get_state(info->edev, EXTCON_MECHANICAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (state < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) dev_err(arizona->dev, "Failed to check cable state: %d\n", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) } else if (!state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ret = arizona_hpdet_read(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (ret == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) reading = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /* Reset back to starting range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ARIZONA_HEADPHONE_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) ret = arizona_hpdet_do_id(info, &reading, &mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (ret == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* Report high impedence cables as line outputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (reading >= 5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) report = EXTCON_JACK_LINE_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) report = EXTCON_JACK_HEADPHONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) ret = extcon_set_state_sync(info->edev, report, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) dev_err(arizona->dev, "Failed to report HP/line: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* Reset back to starting range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) ARIZONA_HEADPHONE_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) arizona_extcon_hp_clamp(info, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (id_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) gpio_set_value_cansleep(id_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* If we have a mic then reenable MICDET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (state && (mic || info->mic))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) arizona_start_mic(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (info->hpdet_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) pm_runtime_put_autosuspend(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) info->hpdet_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* Do not set hp_det done when the cable has been unplugged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) info->hpdet_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static void arizona_identify_headphone(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (info->hpdet_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) dev_dbg(arizona->dev, "Starting HPDET\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /* Make sure we keep the device enabled during the measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) pm_runtime_get(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) info->hpdet_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) arizona_stop_mic(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) arizona_extcon_hp_clamp(info, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ret = regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ARIZONA_ACCESSORY_DETECT_MODE_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) ARIZONA_ACCDET_MODE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) arizona->pdata.hpdet_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ARIZONA_HP_POLL, ARIZONA_HP_POLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) arizona_extcon_hp_clamp(info, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) pm_runtime_put_autosuspend(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* Just report headphone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (info->mic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) arizona_start_mic(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) info->hpdet_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) int hp_reading = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) bool mic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dev_dbg(arizona->dev, "Starting identification via HPDET\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /* Make sure we keep the device enabled during the measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) pm_runtime_get_sync(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) info->hpdet_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) arizona_extcon_hp_clamp(info, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ret = regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ARIZONA_ACCESSORY_DETECT_MODE_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) info->micd_modes[0].src |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) arizona->pdata.hpdet_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (arizona->pdata.hpdet_acc_id_line) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) ret = regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) ARIZONA_HEADPHONE_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ARIZONA_HP_POLL, ARIZONA_HP_POLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) dev_err(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) "Can't start HPDETL measurement: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) arizona_hpdet_do_id(info, &hp_reading, &mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* Just report headphone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) info->hpdet_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static void arizona_micd_timeout_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct arizona_extcon_info *info = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct arizona_extcon_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) micd_timeout_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) mutex_lock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) info->detecting = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) arizona_identify_headphone(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) static int arizona_micd_adc_read(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* Must disable MICD before we read the ADCVAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ARIZONA_MICD_ENA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) dev_err(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) "Failed to read MICDET_ADCVAL: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) val &= ARIZONA_MICDET_ADCVAL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (val < ARRAY_SIZE(arizona_micd_levels))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) val = arizona_micd_levels[val];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) val = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (val <= QUICK_HEADPHONE_MAX_OHM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) else if (val <= MICROPHONE_MIN_OHM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) else if (val <= MICROPHONE_MAX_OHM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) val = ARIZONA_MICD_LVL_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static int arizona_micd_read(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) unsigned int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) dev_err(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) "Failed to read MICDET: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) dev_dbg(arizona->dev, "MICDET: %x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (!(val & ARIZONA_MICD_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) dev_warn(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) "Microphone detection state invalid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) dev_err(arizona->dev, "Failed to get valid MICDET value\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static int arizona_micdet_reading(void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct arizona_extcon_info *info = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) int ret, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (info->detecting && arizona->pdata.micd_software_compare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) ret = arizona_micd_adc_read(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ret = arizona_micd_read(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /* Due to jack detect this should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (!(val & ARIZONA_MICD_STS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) dev_warn(arizona->dev, "Detected open circuit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) info->mic = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) info->detecting = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) arizona_identify_headphone(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /* If we got a high impedence we should have a headset, report it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (val & ARIZONA_MICD_LVL_8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) info->mic = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) info->detecting = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) arizona_identify_headphone(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ret = extcon_set_state_sync(info->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) EXTCON_JACK_MICROPHONE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) dev_err(arizona->dev, "Headset report failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) /* Don't need to regulate for button detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) ret = regulator_allow_bypass(info->micvdd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /* If we detected a lower impedence during initial startup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * then we probably have the wrong polarity, flip it. Don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * do this for the lowest impedences to speed up detection of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * plain headphones. If both polarities report a low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * impedence then give up and report headphones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (val & MICD_LVL_1_TO_7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (info->jack_flips >= info->micd_num_modes * 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) dev_dbg(arizona->dev, "Detected HP/line\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) info->detecting = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) arizona_identify_headphone(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) info->micd_mode++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (info->micd_mode == info->micd_num_modes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) info->micd_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) arizona_extcon_set_mode(info, info->micd_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) info->jack_flips++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (arizona->pdata.micd_software_compare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ARIZONA_MICD_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) ARIZONA_MICD_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) queue_delayed_work(system_power_efficient_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) &info->micd_timeout_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) msecs_to_jiffies(arizona->pdata.micd_timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * If we're still detecting and we detect a short then we've
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * got a headphone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) dev_dbg(arizona->dev, "Headphone detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) info->detecting = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) arizona_identify_headphone(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static int arizona_button_reading(void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct arizona_extcon_info *info = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) int val, key, lvl, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) val = arizona_micd_read(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * If we're still detecting and we detect a short then we've
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) * got a headphone. Otherwise it's a button press.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (val & MICD_LVL_0_TO_7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (info->mic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) dev_dbg(arizona->dev, "Mic button detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) lvl = val & ARIZONA_MICD_LVL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) lvl >>= ARIZONA_MICD_LVL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) for (i = 0; i < info->num_micd_ranges; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) input_report_key(info->input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) info->micd_ranges[i].key, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) key = info->micd_ranges[ffs(lvl) - 1].key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) input_report_key(info->input, key, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) input_sync(info->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) dev_err(arizona->dev, "Button out of range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) dev_warn(arizona->dev, "Button with no mic: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dev_dbg(arizona->dev, "Mic button released\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) for (i = 0; i < info->num_micd_ranges; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) input_report_key(info->input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) info->micd_ranges[i].key, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) input_sync(info->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) arizona_extcon_pulse_micbias(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static void arizona_micd_detect(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) struct arizona_extcon_info *info = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct arizona_extcon_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) micd_detect_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) cancel_delayed_work_sync(&info->micd_timeout_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) mutex_lock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* If the cable was removed while measuring ignore the result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) dev_err(arizona->dev, "Failed to check cable state: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) } else if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (info->detecting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) arizona_micdet_reading(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) arizona_button_reading(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) pm_runtime_mark_last_busy(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static irqreturn_t arizona_micdet(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct arizona_extcon_info *info = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) int debounce = arizona->pdata.micd_detect_debounce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) cancel_delayed_work_sync(&info->micd_detect_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) cancel_delayed_work_sync(&info->micd_timeout_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) mutex_lock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (!info->detecting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) debounce = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (debounce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) queue_delayed_work(system_power_efficient_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) &info->micd_detect_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) msecs_to_jiffies(debounce));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) arizona_micd_detect(&info->micd_detect_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) static void arizona_hpdet_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct arizona_extcon_info *info = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct arizona_extcon_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) hpdet_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) mutex_lock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) arizona_start_hpdet_acc_id(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static int arizona_hpdet_wait(struct arizona_extcon_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) for (i = 0; i < ARIZONA_HPDET_WAIT_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) dev_err(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) "Failed to read HPDET state: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) switch (info->hpdet_ip_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (val & ARIZONA_HP_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (val & ARIZONA_HP_DONE_B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) msleep(ARIZONA_HPDET_WAIT_DELAY_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dev_warn(arizona->dev, "HPDET did not appear to complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) static irqreturn_t arizona_jackdet(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) struct arizona_extcon_info *info = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) unsigned int val, present, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) bool cancelled_hp, cancelled_mic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) pm_runtime_get_sync(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) mutex_lock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (info->micd_clamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) mask = ARIZONA_MICD_CLAMP_STS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) present = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) mask = ARIZONA_JD1_STS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (arizona->pdata.jd_invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) present = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) present = ARIZONA_JD1_STS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) pm_runtime_put_autosuspend(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) val &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (val == info->last_jackdet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (cancelled_hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) queue_delayed_work(system_power_efficient_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) &info->hpdet_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) msecs_to_jiffies(HPDET_DEBOUNCE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (cancelled_mic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) int micd_timeout = arizona->pdata.micd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) queue_delayed_work(system_power_efficient_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) &info->micd_timeout_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) msecs_to_jiffies(micd_timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) info->last_jackdet = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (info->last_jackdet == present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) dev_dbg(arizona->dev, "Detected jack\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) ret = extcon_set_state_sync(info->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) EXTCON_MECHANICAL, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) dev_err(arizona->dev, "Mechanical report failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) info->detecting = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) info->mic = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) info->jack_flips = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (!arizona->pdata.hpdet_acc_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) arizona_start_mic(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) queue_delayed_work(system_power_efficient_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) &info->hpdet_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) msecs_to_jiffies(HPDET_DEBOUNCE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (info->micd_clamp || !arizona->pdata.jd_invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) ARIZONA_JACK_DETECT_DEBOUNCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ARIZONA_MICD_CLAMP_DB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) ARIZONA_JD1_DB, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) dev_dbg(arizona->dev, "Detected jack removal\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) arizona_stop_mic(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) info->num_hpdet_res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) info->hpdet_res[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) info->mic = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) info->hpdet_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) info->hpdet_retried = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) for (i = 0; i < info->num_micd_ranges; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) input_report_key(info->input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) info->micd_ranges[i].key, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) input_sync(info->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) for (i = 0; i < ARRAY_SIZE(arizona_cable) - 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) ret = extcon_set_state_sync(info->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) arizona_cable[i], false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) dev_err(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) "Removal report failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * If the jack was removed during a headphone detection we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * need to wait for the headphone detection to finish, as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * it can not be aborted. We don't want to be able to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * a new headphone detection from a fresh insert until this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * one is finished.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) arizona_hpdet_wait(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) ARIZONA_JACK_DETECT_DEBOUNCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) /* Clear trig_sts to make sure DCVDD is not forced up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) ARIZONA_JD1_FALL_TRIG_STS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ARIZONA_JD1_RISE_TRIG_STS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) mutex_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) pm_runtime_mark_last_busy(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) pm_runtime_put_autosuspend(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) /* Map a level onto a slot in the register bank */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) static void arizona_micd_set_level(struct arizona *arizona, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) unsigned int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) if (!(index % 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) mask = 0x3f00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) level <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) mask = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /* Program the level itself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) regmap_update_bits(arizona->regmap, reg, mask, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) static int arizona_extcon_get_micd_configs(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct arizona *arizona)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) const char * const prop = "wlf,micd-configs";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) const int entries_per_config = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) struct arizona_micd_config *micd_configs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) int nconfs, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) u32 *vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) nconfs = device_property_count_u32(arizona->dev, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (nconfs <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) vals = kcalloc(nconfs, sizeof(u32), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (!vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) ret = device_property_read_u32_array(arizona->dev, prop, vals, nconfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) nconfs /= entries_per_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) micd_configs = devm_kcalloc(dev, nconfs, sizeof(*micd_configs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (!micd_configs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) for (i = 0, j = 0; i < nconfs; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) micd_configs[i].src = vals[j++] ? ARIZONA_ACCDET_SRC : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) micd_configs[i].bias = vals[j++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) micd_configs[i].gpio = vals[j++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) arizona->pdata.micd_configs = micd_configs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) arizona->pdata.num_micd_configs = nconfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) kfree(vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) static int arizona_extcon_device_get_pdata(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) struct arizona *arizona)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct arizona_pdata *pdata = &arizona->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) unsigned int val = ARIZONA_ACCDET_MODE_HPL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) device_property_read_u32(arizona->dev, "wlf,hpdet-channel", &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) case ARIZONA_ACCDET_MODE_HPL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) case ARIZONA_ACCDET_MODE_HPR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) pdata->hpdet_channel = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) dev_err(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) "Wrong wlf,hpdet-channel DT value %d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) pdata->hpdet_channel = ARIZONA_ACCDET_MODE_HPL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) device_property_read_u32(arizona->dev, "wlf,micd-detect-debounce",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) &pdata->micd_detect_debounce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) device_property_read_u32(arizona->dev, "wlf,micd-bias-start-time",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) &pdata->micd_bias_start_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) device_property_read_u32(arizona->dev, "wlf,micd-rate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) &pdata->micd_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) device_property_read_u32(arizona->dev, "wlf,micd-dbtime",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) &pdata->micd_dbtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) device_property_read_u32(arizona->dev, "wlf,micd-timeout-ms",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) &pdata->micd_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) pdata->micd_force_micbias = device_property_read_bool(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) "wlf,micd-force-micbias");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) pdata->micd_software_compare = device_property_read_bool(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) "wlf,micd-software-compare");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) pdata->jd_invert = device_property_read_bool(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) "wlf,jd-invert");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) pdata->jd_gpio5 = device_property_read_bool(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) "wlf,use-jd2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) pdata->jd_gpio5_nopull = device_property_read_bool(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) "wlf,use-jd2-nopull");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) ret = arizona_extcon_get_micd_configs(dev, arizona);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) dev_err(arizona->dev, "Failed to read micd configs: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) static int arizona_extcon_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct arizona_pdata *pdata = &arizona->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) struct arizona_extcon_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) unsigned int clamp_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) int jack_irq_fall, jack_irq_rise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) int ret, mode, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (!arizona->dapm || !arizona->dapm->card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (!dev_get_platdata(arizona->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) arizona_extcon_device_get_pdata(&pdev->dev, arizona);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (IS_ERR(info->micvdd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) ret = PTR_ERR(info->micvdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) mutex_init(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) info->arizona = arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) info->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) platform_set_drvdata(pdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) switch (arizona->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) case WM5102:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) switch (arizona->rev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) info->micd_reva = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) info->micd_clamp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) info->hpdet_ip_version = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) case WM5110:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) case WM8280:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) switch (arizona->rev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) case 0 ... 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) info->micd_clamp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) info->hpdet_ip_version = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) case WM8998:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) case WM1814:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) info->micd_clamp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) info->hpdet_ip_version = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) info->edev = devm_extcon_dev_allocate(&pdev->dev, arizona_cable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) if (IS_ERR(info->edev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) dev_err(&pdev->dev, "failed to allocate extcon device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) ret = devm_extcon_dev_register(&pdev->dev, info->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) info->input = devm_input_allocate_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) if (!info->input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) dev_err(arizona->dev, "Can't allocate input dev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) info->input->name = "Headset";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) info->input->phys = "arizona/extcon";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (!pdata->micd_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) pdata->micd_timeout = DEFAULT_MICD_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (pdata->num_micd_configs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) info->micd_modes = pdata->micd_configs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) info->micd_num_modes = pdata->num_micd_configs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) info->micd_modes = micd_default_modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (arizona->pdata.gpsw > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) if (pdata->micd_pol_gpio > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (info->micd_modes[0].gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) mode = GPIOF_OUT_INIT_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) mode = GPIOF_OUT_INIT_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) ret = devm_gpio_request_one(&pdev->dev, pdata->micd_pol_gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) mode, "MICD polarity");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) pdata->micd_pol_gpio, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) info->micd_pol_gpio = gpio_to_desc(pdata->micd_pol_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if (info->micd_modes[0].gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) mode = GPIOD_OUT_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) mode = GPIOD_OUT_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) /* We can't use devm here because we need to do the get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * against the MFD device, as that is where the of_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * will reside, but if we devm against that the GPIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * will not be freed if the extcon driver is unloaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) info->micd_pol_gpio = gpiod_get_optional(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) "wlf,micd-pol",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (IS_ERR(info->micd_pol_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) ret = PTR_ERR(info->micd_pol_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) dev_err(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) "Failed to get microphone polarity GPIO: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (arizona->pdata.hpdet_id_gpio > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) ret = devm_gpio_request_one(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) arizona->pdata.hpdet_id_gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) GPIOF_OUT_INIT_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) "HPDET");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) arizona->pdata.hpdet_id_gpio, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) goto err_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (arizona->pdata.micd_bias_start_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) ARIZONA_MICD_BIAS_STARTTIME_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) arizona->pdata.micd_bias_start_time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (arizona->pdata.micd_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) ARIZONA_MICD_RATE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) arizona->pdata.micd_rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) << ARIZONA_MICD_RATE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) switch (arizona->pdata.micd_dbtime) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) case MICD_DBTIME_FOUR_READINGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) ARIZONA_MICD_DBTIME_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) ARIZONA_MICD_DBTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) case MICD_DBTIME_TWO_READINGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) ARIZONA_MICD_DBTIME_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) ARIZONA_NUM_MICD_BUTTON_LEVELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) if (arizona->pdata.num_micd_ranges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) info->micd_ranges = pdata->micd_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) info->num_micd_ranges = pdata->num_micd_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) info->micd_ranges = micd_default_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) dev_err(arizona->dev, "Too many MICD ranges: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) arizona->pdata.num_micd_ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) if (info->num_micd_ranges > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) for (i = 1; i < info->num_micd_ranges; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) if (info->micd_ranges[i - 1].max >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) info->micd_ranges[i].max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) dev_err(arizona->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) "MICD ranges must be sorted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) goto err_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) /* Disable all buttons by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) ARIZONA_MICD_LVL_SEL_MASK, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) /* Set up all the buttons the user specified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) for (i = 0; i < info->num_micd_ranges; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) for (j = 0; j < ARIZONA_NUM_MICD_BUTTON_LEVELS; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (j == ARIZONA_NUM_MICD_BUTTON_LEVELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) dev_err(arizona->dev, "Unsupported MICD level %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) info->micd_ranges[i].max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) goto err_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) arizona_micd_levels[j], i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) arizona_micd_set_level(arizona, i, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) input_set_capability(info->input, EV_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) info->micd_ranges[i].key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) /* Enable reporting of that range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 1 << i, 1 << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) /* Set all the remaining keys to a maximum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) for (; i < ARIZONA_MAX_MICD_RANGE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) arizona_micd_set_level(arizona, i, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) * If we have a clamp use it, activating in conjunction with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) * GPIO5 if that is connected for jack detect operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (info->micd_clamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (arizona->pdata.jd_gpio5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /* Put the GPIO into input mode with optional pull */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) val = 0xc101;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (arizona->pdata.jd_gpio5_nopull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) val &= ~ARIZONA_GPN_PU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if (arizona->pdata.jd_invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (arizona->pdata.jd_invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) ARIZONA_MICD_CLAMP_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) ARIZONA_JACK_DETECT_DEBOUNCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) ARIZONA_MICD_CLAMP_DB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) ARIZONA_MICD_CLAMP_DB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) arizona_extcon_set_mode(info, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) pm_runtime_idle(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) pm_runtime_get_sync(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) if (info->micd_clamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) jack_irq_rise = ARIZONA_IRQ_JD_RISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) jack_irq_fall = ARIZONA_IRQ_JD_FALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) ret = arizona_request_irq(arizona, jack_irq_rise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) "JACKDET rise", arizona_jackdet, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) goto err_pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) goto err_rise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) ret = arizona_request_irq(arizona, jack_irq_fall,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) "JACKDET fall", arizona_jackdet, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) goto err_rise_wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) goto err_fall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) "MICDET", arizona_micdet, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) goto err_fall_wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) "HPDET", arizona_hpdet_irq, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) goto err_micdet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) arizona_clk32k_enable(arizona);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) ARIZONA_JD1_DB, ARIZONA_JD1_DB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) ret = regulator_allow_bypass(info->micvdd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) ret = input_register_device(info->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) goto err_hpdet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) pm_runtime_put(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) err_hpdet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) err_micdet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) err_fall_wake:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) arizona_set_irq_wake(arizona, jack_irq_fall, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) err_fall:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) arizona_free_irq(arizona, jack_irq_fall, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) err_rise_wake:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) arizona_set_irq_wake(arizona, jack_irq_rise, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) err_rise:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) arizona_free_irq(arizona, jack_irq_rise, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) err_pm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) pm_runtime_put(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) err_gpio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) gpiod_put(info->micd_pol_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) static int arizona_extcon_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) struct arizona_extcon_info *info = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) struct arizona *arizona = info->arizona;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) int jack_irq_rise, jack_irq_fall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) bool change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) if (info->micd_clamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) jack_irq_rise = ARIZONA_IRQ_JD_RISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) jack_irq_fall = ARIZONA_IRQ_JD_FALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) arizona_set_irq_wake(arizona, jack_irq_rise, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) arizona_set_irq_wake(arizona, jack_irq_fall, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) arizona_free_irq(arizona, jack_irq_rise, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) arizona_free_irq(arizona, jack_irq_fall, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) cancel_delayed_work_sync(&info->hpdet_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) cancel_delayed_work_sync(&info->micd_detect_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) cancel_delayed_work_sync(&info->micd_timeout_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) ARIZONA_MICD_ENA, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) &change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) } else if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) regulator_disable(info->micvdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) pm_runtime_put(info->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) regmap_update_bits(arizona->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) ARIZONA_MICD_CLAMP_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) ARIZONA_MICD_CLAMP_MODE_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) ARIZONA_JD1_ENA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) arizona_clk32k_disable(arizona);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) gpiod_put(info->micd_pol_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) static struct platform_driver arizona_extcon_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) .name = "arizona-extcon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) .probe = arizona_extcon_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) .remove = arizona_extcon_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) module_platform_driver(arizona_extcon_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) MODULE_DESCRIPTION("Arizona Extcon driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) MODULE_ALIAS("platform:extcon-arizona");