From e76e397a7f99bffbd91fb21f96370cbb165b5bcd Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 16 Sep 2015 10:42:13 +0100 Subject: [PATCH 01/21] mfd: arizona: Add registers for ADC microphone detection The newer devices support using a software comparison to determine whether a 3/4 pole jack is present. Add the registers necessary for this. Signed-off-by: Charles Keepax Acked-by: Lee Jones Signed-off-by: Chanwoo Choi --- drivers/mfd/wm5110-tables.c | 2 ++ include/dt-bindings/mfd/arizona.h | 2 ++ include/linux/mfd/arizona/pdata.h | 3 +++ include/linux/mfd/arizona/registers.h | 6 +++--- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c index c4b9374efd76..5f604e00aaf1 100644 --- a/drivers/mfd/wm5110-tables.c +++ b/drivers/mfd/wm5110-tables.c @@ -1811,6 +1811,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) case ARIZONA_MIC_DETECT_1: case ARIZONA_MIC_DETECT_2: case ARIZONA_MIC_DETECT_3: + case ARIZONA_MIC_DETECT_4: case ARIZONA_MIC_DETECT_LEVEL_1: case ARIZONA_MIC_DETECT_LEVEL_2: case ARIZONA_MIC_DETECT_LEVEL_3: @@ -2847,6 +2848,7 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg) case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS: case ARIZONA_ASYNC_SAMPLE_RATE_2_STATUS: case ARIZONA_MIC_DETECT_3: + case ARIZONA_MIC_DETECT_4: case ARIZONA_HP_CTRL_1L: case ARIZONA_HP_CTRL_1R: case ARIZONA_HEADPHONE_DETECT_2: diff --git a/include/dt-bindings/mfd/arizona.h b/include/dt-bindings/mfd/arizona.h index 7b2000cead43..c40f665e2712 100644 --- a/include/dt-bindings/mfd/arizona.h +++ b/include/dt-bindings/mfd/arizona.h @@ -107,5 +107,7 @@ #define ARIZONA_ACCDET_MODE_MIC 0 #define ARIZONA_ACCDET_MODE_HPL 1 #define ARIZONA_ACCDET_MODE_HPR 2 +#define ARIZONA_ACCDET_MODE_HPM 4 +#define ARIZONA_ACCDET_MODE_ADC 7 #endif diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 1dc385850ba2..92f31ffaf866 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -124,6 +124,9 @@ struct arizona_pdata { /** Channel to use for headphone detection */ unsigned int hpdet_channel; + /** Use software comparison to determine mic presence */ + bool micd_software_compare; + /** Extra debounce timeout used during initial mic detection (ms) */ unsigned int micd_detect_debounce; diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h index fdd70b3c7418..ab219c9b0b08 100644 --- a/include/linux/mfd/arizona/registers.h +++ b/include/linux/mfd/arizona/registers.h @@ -2359,9 +2359,9 @@ #define ARIZONA_ACCDET_SRC_MASK 0x2000 /* ACCDET_SRC */ #define ARIZONA_ACCDET_SRC_SHIFT 13 /* ACCDET_SRC */ #define ARIZONA_ACCDET_SRC_WIDTH 1 /* ACCDET_SRC */ -#define ARIZONA_ACCDET_MODE_MASK 0x0003 /* ACCDET_MODE - [1:0] */ -#define ARIZONA_ACCDET_MODE_SHIFT 0 /* ACCDET_MODE - [1:0] */ -#define ARIZONA_ACCDET_MODE_WIDTH 2 /* ACCDET_MODE - [1:0] */ +#define ARIZONA_ACCDET_MODE_MASK 0x0007 /* ACCDET_MODE - [2:0] */ +#define ARIZONA_ACCDET_MODE_SHIFT 0 /* ACCDET_MODE - [2:0] */ +#define ARIZONA_ACCDET_MODE_WIDTH 3 /* ACCDET_MODE - [2:0] */ /* * R667 (0x29B) - Headphone Detect 1 From 1ce376897e02e623ba357594604ca655df61053b Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 16 Sep 2015 10:42:14 +0100 Subject: [PATCH 02/21] mfd: arizona: Add register bits for general purpose switch The switch is typically used in conjunction with the MICDET clamp in order to suppress pops and clicks associated with jack insertion. Signed-off-by: Charles Keepax Acked-by: Lee Jones Signed-off-by: Chanwoo Choi --- drivers/mfd/wm5110-tables.c | 2 ++ include/linux/mfd/arizona/pdata.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c index 5f604e00aaf1..aae17d6997b1 100644 --- a/drivers/mfd/wm5110-tables.c +++ b/drivers/mfd/wm5110-tables.c @@ -1481,6 +1481,7 @@ static const struct reg_default wm5110_reg_default[] = { { 0x00000C04, 0xA101 }, /* R3076 - GPIO5 CTRL */ { 0x00000C0F, 0x0400 }, /* R3087 - IRQ CTRL 1 */ { 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */ + { 0x00000C18, 0x0000 }, /* R3096 - GP Switch 1 */ { 0x00000C20, 0x8002 }, /* R3104 - Misc Pad Ctrl 1 */ { 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */ { 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */ @@ -2528,6 +2529,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) case ARIZONA_GPIO5_CTRL: case ARIZONA_IRQ_CTRL_1: case ARIZONA_GPIO_DEBOUNCE_CONFIG: + case ARIZONA_GP_SWITCH_1: case ARIZONA_MISC_PAD_CTRL_1: case ARIZONA_MISC_PAD_CTRL_2: case ARIZONA_MISC_PAD_CTRL_3: diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 92f31ffaf866..57b45caaea80 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -184,6 +184,9 @@ struct arizona_pdata { /** GPIO for primary IRQ (used for edge triggered emulation) */ int irq_gpio; + + /** General purpose switch control */ + unsigned int gpsw; }; #endif From b8ba9edb911102b452c815879f520bfe2713fab6 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 16 Sep 2015 10:42:15 +0100 Subject: [PATCH 03/21] mfd: arizona: Add TST_CAP bits for headphone detection On wm5110/8280 some additional settings are required to get accurate measurements at the top end of the headphone detection range. This patch adds the bits required for this. Signed-off-by: Charles Keepax Acked-by: Lee Jones Signed-off-by: Chanwoo Choi --- drivers/mfd/wm5110-tables.c | 2 ++ include/linux/mfd/arizona/registers.h | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c index aae17d6997b1..28f2ae30507a 100644 --- a/drivers/mfd/wm5110-tables.c +++ b/drivers/mfd/wm5110-tables.c @@ -1912,6 +1912,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) case ARIZONA_HP1_SHORT_CIRCUIT_CTRL: case ARIZONA_HP2_SHORT_CIRCUIT_CTRL: case ARIZONA_HP3_SHORT_CIRCUIT_CTRL: + case ARIZONA_HP_TEST_CTRL_1: case ARIZONA_AIF1_BCLK_CTRL: case ARIZONA_AIF1_TX_PIN_CTRL: case ARIZONA_AIF1_RX_PIN_CTRL: @@ -2857,6 +2858,7 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg) case ARIZONA_INPUT_ENABLES_STATUS: case ARIZONA_OUTPUT_STATUS_1: case ARIZONA_RAW_OUTPUT_STATUS_1: + case ARIZONA_HP_TEST_CTRL_1: case ARIZONA_SLIMBUS_RX_PORT_STATUS: case ARIZONA_SLIMBUS_TX_PORT_STATUS: case ARIZONA_INTERRUPT_STATUS_1: diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h index ab219c9b0b08..c7c11c900196 100644 --- a/include/linux/mfd/arizona/registers.h +++ b/include/linux/mfd/arizona/registers.h @@ -242,6 +242,7 @@ #define ARIZONA_HP1_SHORT_CIRCUIT_CTRL 0x4A0 #define ARIZONA_HP2_SHORT_CIRCUIT_CTRL 0x4A1 #define ARIZONA_HP3_SHORT_CIRCUIT_CTRL 0x4A2 +#define ARIZONA_HP_TEST_CTRL_1 0x4A4 #define ARIZONA_SPK_CTRL_2 0x4B5 #define ARIZONA_SPK_CTRL_3 0x4B6 #define ARIZONA_DAC_COMP_1 0x4DC @@ -3701,6 +3702,13 @@ #define ARIZONA_HP3_SC_ENA_SHIFT 12 /* HP3_SC_ENA */ #define ARIZONA_HP3_SC_ENA_WIDTH 1 /* HP3_SC_ENA */ +/* + * R1188 (0x4A4) HP Test Ctrl 1 + */ +#define ARIZONA_HP1_TST_CAP_SEL_MASK 0x0003 /* HP1_TST_CAP_SEL - [1:0] */ +#define ARIZONA_HP1_TST_CAP_SEL_SHIFT 0 /* HP1_TST_CAP_SEL - [1:0] */ +#define ARIZONA_HP1_TST_CAP_SEL_WIDTH 2 /* HP1_TST_CAP_SEL - [1:0] */ + /* * R1244 (0x4DC) - DAC comp 1 */ From df8b6771bdd4004c743ad8ffff6fb7059d6687d1 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 16 Sep 2015 10:42:16 +0100 Subject: [PATCH 04/21] extcon: arizona: Add support for new ADC value mic detect Newer devices give users the option to make the 3/4 pole jack determination using a software comparison rather than a hardware one. This patch adds support for this functionality. Signed-off-by: Charles Keepax Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 64 +++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 4b9f09cc38d8..f213e14ff93f 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -48,6 +48,10 @@ #define HPDET_DEBOUNCE 500 #define DEFAULT_MICD_TIMEOUT 2000 +#define QUICK_HEADPHONE_MAX_OHM 3 +#define MICROPHONE_MIN_OHM 1257 +#define MICROPHONE_MAX_OHM 30000 + #define MICD_DBTIME_TWO_READINGS 2 #define MICD_DBTIME_FOUR_READINGS 4 @@ -117,12 +121,15 @@ static const struct arizona_micd_range micd_default_ranges[] = { { .max = 430, .key = BTN_5 }, }; +/* The number of levels in arizona_micd_levels valid for button thresholds */ +#define ARIZONA_NUM_MICD_BUTTON_LEVELS 64 + static const int arizona_micd_levels[] = { 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46, 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100, 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245, 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071, - 1257, + 1257, 30000, }; static const unsigned int arizona_cable[] = { @@ -270,6 +277,7 @@ static void arizona_start_mic(struct arizona_extcon_info *info) struct arizona *arizona = info->arizona; bool change; int ret; + unsigned int mode; /* Microphone detection can't use idle mode */ pm_runtime_get(info->dev); @@ -295,9 +303,14 @@ static void arizona_start_mic(struct arizona_extcon_info *info) regmap_write(arizona->regmap, 0x80, 0x0); } + if (info->detecting && arizona->pdata.micd_software_compare) + mode = ARIZONA_ACCDET_MODE_ADC; + else + mode = ARIZONA_ACCDET_MODE_MIC; + regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, - ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); + ARIZONA_ACCDET_MODE_MASK, mode); arizona_extcon_pulse_micbias(info); @@ -804,6 +817,37 @@ static void arizona_micd_detect(struct work_struct *work) return; } + if (info->detecting && arizona->pdata.micd_software_compare) { + /* Must disable MICD before we read the ADCVAL */ + regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_ENA, 0); + ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val); + if (ret != 0) { + dev_err(arizona->dev, + "Failed to read MICDET_ADCVAL: %d\n", + ret); + mutex_unlock(&info->lock); + return; + } + + dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val); + + val &= ARIZONA_MICDET_ADCVAL_MASK; + if (val < ARRAY_SIZE(arizona_micd_levels)) + val = arizona_micd_levels[val]; + else + val = INT_MAX; + + if (val <= QUICK_HEADPHONE_MAX_OHM) + val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0; + else if (val <= MICROPHONE_MIN_OHM) + val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1; + else if (val <= MICROPHONE_MAX_OHM) + val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8; + else + val = ARIZONA_MICD_LVL_8; + } + for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) { ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); if (ret != 0) { @@ -932,10 +976,17 @@ static void arizona_micd_detect(struct work_struct *work) } handled: - if (info->detecting) + if (info->detecting) { + if (arizona->pdata.micd_software_compare) + regmap_update_bits(arizona->regmap, + ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_ENA, + ARIZONA_MICD_ENA); + queue_delayed_work(system_power_efficient_wq, &info->micd_timeout_work, msecs_to_jiffies(info->micd_timeout)); + } pm_runtime_mark_last_busy(info->dev); mutex_unlock(&info->lock); @@ -1335,7 +1386,8 @@ static int arizona_extcon_probe(struct platform_device *pdev) break; } - BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40); + BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) < + ARIZONA_NUM_MICD_BUTTON_LEVELS); if (arizona->pdata.num_micd_ranges) { info->micd_ranges = pdata->micd_ranges; @@ -1368,11 +1420,11 @@ static int arizona_extcon_probe(struct platform_device *pdev) /* Set up all the buttons the user specified */ for (i = 0; i < info->num_micd_ranges; i++) { - for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++) + for (j = 0; j < ARIZONA_NUM_MICD_BUTTON_LEVELS; j++) if (arizona_micd_levels[j] >= info->micd_ranges[i].max) break; - if (j == ARRAY_SIZE(arizona_micd_levels)) { + if (j == ARIZONA_NUM_MICD_BUTTON_LEVELS) { dev_err(arizona->dev, "Unsupported MICD level %d\n", info->micd_ranges[i].max); ret = -EINVAL; From 6772a5ab4f53672adce6310dffe2b0c6987d8f92 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 16 Sep 2015 10:42:17 +0100 Subject: [PATCH 05/21] extcon: arizona: Add support for general purpose switch The switch is typically used in conjunction with the MICDET clamp in order to suppress pops and clicks associated with jack insertion. Signed-off-by: Charles Keepax Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index f213e14ff93f..d719ee724651 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1310,6 +1310,10 @@ static int arizona_extcon_probe(struct platform_device *pdev) info->micd_num_modes = ARRAY_SIZE(micd_default_modes); } + if (arizona->pdata.gpsw > 0) + regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1, + ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw); + if (arizona->pdata.micd_pol_gpio > 0) { if (info->micd_modes[0].gpio) mode = GPIOF_OUT_INIT_HIGH; From f719ae3311f9b609151a0319f0cc2fdb7491d37a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 16 Sep 2015 10:42:18 +0100 Subject: [PATCH 06/21] extcon: arizona: Additional settings to improve accuracy of HP detect If the TST_CAP_SEL bits aren't set correctly on wm5110/8280 there will be a 100k load along side the headphones, which will affect the accurary towards the very top of the detection range. This patch sets those bits. Signed-off-by: Charles Keepax Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index d719ee724651..6d35147b1d6c 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -43,6 +43,9 @@ #define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9 #define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb +#define ARIZONA_TST_CAP_DEFAULT 0x3 +#define ARIZONA_TST_CAP_CLAMP 0x1 + #define ARIZONA_HPDET_MAX 10000 #define HPDET_DEBOUNCE 500 @@ -147,6 +150,7 @@ static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info, { struct arizona *arizona = info->arizona; unsigned int mask = 0, val = 0; + unsigned int cap_sel = 0; int ret; switch (arizona->type) { @@ -154,10 +158,21 @@ static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info, case WM8280: mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI; - if (clamp) + if (clamp) { val = ARIZONA_HP1L_SHRTO; - else + cap_sel = ARIZONA_TST_CAP_CLAMP; + } else { val = ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI; + cap_sel = ARIZONA_TST_CAP_DEFAULT; + } + + ret = regmap_update_bits(arizona->regmap, + ARIZONA_HP_TEST_CTRL_1, + ARIZONA_HP1_TST_CAP_SEL_MASK, + cap_sel); + if (ret != 0) + dev_warn(arizona->dev, + "Failed to set TST_CAP_SEL: %d\n", ret); break; default: mask = ARIZONA_RMV_SHRT_HP1L; From a0ef642849f6319a031f1dcc2fa444d651179131 Mon Sep 17 00:00:00 2001 From: Nariman Poushin Date: Wed, 16 Sep 2015 10:42:19 +0100 Subject: [PATCH 07/21] extcon: arizona: Ignore jd_invert for MICD_CLAMP_STS The polarity of MICD_CLAMP_STS does not change when different clamp modes are used, this patch corrects this issue. Signed-off-by: Nariman Poushin Signed-off-by: Charles Keepax Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 6d35147b1d6c..ece5892824d1 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1059,10 +1059,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data) if (arizona->pdata.jd_gpio5) { mask = ARIZONA_MICD_CLAMP_STS; - if (arizona->pdata.jd_invert) - present = ARIZONA_MICD_CLAMP_STS; - else - present = 0; + present = 0; } else { mask = ARIZONA_JD1_STS; if (arizona->pdata.jd_invert) From ff1cb0ed716304e9f7835ecc5f12ad580b0637ea Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 16 Sep 2015 10:42:20 +0100 Subject: [PATCH 08/21] extcon: arizona: Use the micd_clamp for interrupts if it is available Currently we only use the microphone clamp IRQ if GPIO5 is being used as a second jack detection pin. But we should be using it on any system where the clamp is available. This patch updates the driver to do so. Signed-off-by: Charles Keepax Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index ece5892824d1..9255c1f1f285 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1057,7 +1057,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data) mutex_lock(&info->lock); - if (arizona->pdata.jd_gpio5) { + if (info->micd_clamp) { mask = ARIZONA_MICD_CLAMP_STS; present = 0; } else { @@ -1504,7 +1504,7 @@ static int arizona_extcon_probe(struct platform_device *pdev) pm_runtime_idle(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - if (arizona->pdata.jd_gpio5) { + if (info->micd_clamp) { jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE; jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL; } else { @@ -1609,7 +1609,7 @@ static int arizona_extcon_remove(struct platform_device *pdev) ARIZONA_MICD_CLAMP_CONTROL, ARIZONA_MICD_CLAMP_MODE_MASK, 0); - if (arizona->pdata.jd_gpio5) { + if (info->micd_clamp) { jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE; jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL; } else { From 6c20b934247875f41fe9bcc74072bb072b4f28d8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 16 Sep 2015 10:42:21 +0100 Subject: [PATCH 09/21] extcon: arizona: Don't disable debounce for inverted jacks Whilst the jack is connected we disable the jack detection debounce to ensure as quick as possible a detection of jack removal. However, it is only safe to disable the jack debounce whilst the jack is connected if using the micd clamp or the jack is not inverted. Otherwise spurious interrupts might be generated when we re-enable the debounce. Signed-off-by: Charles Keepax Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 9255c1f1f285..4479781ee941 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1118,9 +1118,11 @@ static irqreturn_t arizona_jackdet(int irq, void *data) msecs_to_jiffies(HPDET_DEBOUNCE)); } - regmap_update_bits(arizona->regmap, - ARIZONA_JACK_DETECT_DEBOUNCE, - ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0); + if (info->micd_clamp || !arizona->pdata.jd_invert) + regmap_update_bits(arizona->regmap, + ARIZONA_JACK_DETECT_DEBOUNCE, + ARIZONA_MICD_CLAMP_DB | + ARIZONA_JD1_DB, 0); } else { dev_dbg(arizona->dev, "Detected jack removal\n"); From ff612f9170eaa9ca7ade357b270f582b0c44ed70 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 25 Aug 2015 08:31:15 +0200 Subject: [PATCH 10/21] extcon: Export OF module alias information in missing drivers The I2C core always reports the MODALIAS uevent as "i2c:" regardless of the mechanism that was used to register the device (i.e: OF or board code) and the table that is used later to match the driver with the device (i.e: I2C id table or OF match table). So drivers needs to export the I2C id table and this be built into the module or udev won't have the necessary information to autoload the needed driver module when the device is added. But this means that OF-only drivers needs to have both OF and I2C id tables that have to be kept in sync and also the dev node compatible manufacturer prefix is stripped when reporting the MODALIAS. Which can lead to issues if two vendors use the same I2C device name for example. To avoid the above, the I2C core behavior may be changed in the future to not require an SPI device table for OF-only drivers and report the OF module alias. So, it's better to also export the OF table even when is unused now to prevent breaking module loading when the core changes. Signed-off-by: Javier Martinez Canillas Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-rt8973a.c | 1 + drivers/extcon/extcon-sm5502.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c index 11592e980bc1..3428b6aae1a2 100644 --- a/drivers/extcon/extcon-rt8973a.c +++ b/drivers/extcon/extcon-rt8973a.c @@ -658,6 +658,7 @@ static const struct of_device_id rt8973a_dt_match[] = { { .compatible = "richtek,rt8973a-muic" }, { }, }; +MODULE_DEVICE_TABLE(of, rt8973a_dt_match); #ifdef CONFIG_PM_SLEEP static int rt8973a_muic_suspend(struct device *dev) diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index 0ffefefa2e26..92ae48415fb2 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -650,6 +650,7 @@ static const struct of_device_id sm5502_dt_match[] = { { .compatible = "siliconmitus,sm5502-muic" }, { }, }; +MODULE_DEVICE_TABLE(of, sm5502_dt_match); #ifdef CONFIG_PM_SLEEP static int sm5502_muic_suspend(struct device *dev) From 4bf27b7038c23fe789aa9bd553a6391cc33ccfa1 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Mon, 14 Sep 2015 23:19:35 +0530 Subject: [PATCH 11/21] extcon: axp288: Convert to using managed resources Use resource managed functions devm_usb_get_phy and devm_gpio_request to make error path simpler. To be compatible the change, various gotos are replaced with direct returns and unnecessary label gpio_req_failed is dropped. Also, remove function axp288_extcon_remove as it is now redundant. Signed-off-by: Vaishali Thakkar Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-axp288.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/extcon/extcon-axp288.c b/drivers/extcon/extcon-axp288.c index ea962bc547b8..9668d6a94e38 100644 --- a/drivers/extcon/extcon-axp288.c +++ b/drivers/extcon/extcon-axp288.c @@ -309,7 +309,7 @@ static int axp288_extcon_probe(struct platform_device *pdev) } /* Get otg transceiver phy */ - info->otg = usb_get_phy(USB_PHY_TYPE_USB2); + info->otg = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(info->otg)) { dev_err(&pdev->dev, "failed to get otg transceiver\n"); return PTR_ERR(info->otg); @@ -318,11 +318,11 @@ static int axp288_extcon_probe(struct platform_device *pdev) /* Set up gpio control for USB Mux */ if (info->pdata->gpio_mux_cntl) { gpio = desc_to_gpio(info->pdata->gpio_mux_cntl); - ret = gpio_request(gpio, "USB_MUX"); + ret = devm_gpio_request(&pdev->dev, gpio, "USB_MUX"); if (ret < 0) { dev_err(&pdev->dev, "failed to request the gpio=%d\n", gpio); - goto gpio_req_failed; + return ret; } gpiod_direction_output(info->pdata->gpio_mux_cntl, EXTCON_GPIO_MUX_SEL_PMIC); @@ -335,7 +335,7 @@ static int axp288_extcon_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to get virtual interrupt=%d\n", pirq); ret = info->irq[i]; - goto gpio_req_failed; + return ret; } ret = devm_request_threaded_irq(&pdev->dev, info->irq[i], @@ -345,7 +345,7 @@ static int axp288_extcon_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "failed to request interrupt=%d\n", info->irq[i]); - goto gpio_req_failed; + return ret; } } @@ -353,23 +353,10 @@ static int axp288_extcon_probe(struct platform_device *pdev) axp288_extcon_enable_irq(info); return 0; - -gpio_req_failed: - usb_put_phy(info->otg); - return ret; -} - -static int axp288_extcon_remove(struct platform_device *pdev) -{ - struct axp288_extcon_info *info = platform_get_drvdata(pdev); - - usb_put_phy(info->otg); - return 0; } static struct platform_driver axp288_extcon_driver = { .probe = axp288_extcon_probe, - .remove = axp288_extcon_remove, .driver = { .name = "axp288_extcon", }, From 238ffc2e64646951d2d3c541f3624b01be5f65e4 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Thu, 24 Sep 2015 16:00:20 +0200 Subject: [PATCH 12/21] extcon: rt8973a: fix handling regmap_irq_get_virq result The function can return negative value. The problem has been detected using proposed semantic patch scripts/coccinelle/tests/assign_signed_to_unsigned.cocci [1]. [1]: http://permalink.gmane.org/gmane.linux.kernel/2046107 Signed-off-by: Andrzej Hajda Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-rt8973a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c index 3428b6aae1a2..1bc3737ea01c 100644 --- a/drivers/extcon/extcon-rt8973a.c +++ b/drivers/extcon/extcon-rt8973a.c @@ -594,7 +594,7 @@ static int rt8973a_muic_i2c_probe(struct i2c_client *i2c, for (i = 0; i < info->num_muic_irqs; i++) { struct muic_irq *muic_irq = &info->muic_irqs[i]; - unsigned int virq = 0; + int virq = 0; virq = regmap_irq_get_virq(info->irq_data, muic_irq->irq); if (virq <= 0) From 363b389106e6762bc855d3da794461be18597d52 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Thu, 24 Sep 2015 16:00:21 +0200 Subject: [PATCH 13/21] extcon: sm5502: fix handling regmap_irq_get_virq result The function can return negative value. The problem has been detected using proposed semantic patch scripts/coccinelle/tests/assign_signed_to_unsigned.cocci [1]. [1]: http://permalink.gmane.org/gmane.linux.kernel/2046107 Signed-off-by: Andrzej Hajda Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-sm5502.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index 92ae48415fb2..2945091bfd0e 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -586,7 +586,7 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c, for (i = 0; i < info->num_muic_irqs; i++) { struct muic_irq *muic_irq = &info->muic_irqs[i]; - unsigned int virq = 0; + int virq = 0; virq = regmap_irq_get_virq(info->irq_data, muic_irq->irq); if (virq <= 0) From d8d09564b830c2040a39039dd1e683c26158f466 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 28 Sep 2015 12:41:42 +0100 Subject: [PATCH 14/21] extcon: arizona: Add support for WM8998 and WM1814 This patch adds support for the WM8998 and WM1814 codecs. These use the same IP version as WM5110 but have different clamp control. Signed-off-by: Richard Fitzgerald Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 4479781ee941..b01030735f0c 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1,7 +1,7 @@ /* * extcon-arizona.c - Extcon driver Wolfson Arizona devices * - * Copyright (C) 2012 Wolfson Microelectronics plc + * Copyright (C) 2012-2014 Wolfson Microelectronics plc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -154,6 +154,10 @@ static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info, int ret; switch (arizona->type) { + case WM8998: + case WM1814: + mask = 0; + break; case WM5110: case WM8280: mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR | @@ -197,17 +201,19 @@ static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info, ret); } - ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1L, - mask, val); - if (ret != 0) - dev_warn(arizona->dev, "Failed to do clamp: %d\n", + if (mask) { + ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1L, + mask, val); + if (ret != 0) + dev_warn(arizona->dev, "Failed to do clamp: %d\n", ret); - ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1R, - mask, val); - if (ret != 0) - dev_warn(arizona->dev, "Failed to do clamp: %d\n", - ret); + ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1R, + mask, val); + if (ret != 0) + dev_warn(arizona->dev, "Failed to do clamp: %d\n", + ret); + } /* Restore the desired state while not doing the clamp */ if (!clamp) { @@ -1289,6 +1295,11 @@ static int arizona_extcon_probe(struct platform_device *pdev) break; } break; + case WM8998: + case WM1814: + info->micd_clamp = true; + info->hpdet_ip_version = 2; + break; default: break; } From e9844b2cafd7b78486400f9b6cf3188e9a527312 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 29 Sep 2015 19:06:31 +0900 Subject: [PATCH 15/21] extcon: arizona: Reorder the default statement to remove unnecessary warning This patch reorders the default statement to remove unnecessary warning message when info->hpdet_ip_version is higher than 2. Signed-off-by: Chanwoo Choi Acked-by: Charles Keepax --- drivers/extcon/extcon-arizona.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index b01030735f0c..a1ab0a56b798 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -477,9 +477,6 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info) arizona_hpdet_b_ranges[range].factor_a); break; - default: - dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n", - info->hpdet_ip_version); case 2: if (!(val & ARIZONA_HP_DONE_B)) { dev_err(arizona->dev, "HPDET did not complete: %x\n", @@ -516,6 +513,12 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info) arizona_hpdet_c_ranges[range].min); val = arizona_hpdet_c_ranges[range].min; } + break; + + default: + dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n", + info->hpdet_ip_version); + return -EINVAL; } dev_dbg(arizona->dev, "HP impedance %d ohms\n", val); From ae59f3a21fbe4b9ef3a9a09deabd2b0afb80942d Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 25 Sep 2015 22:40:51 +0900 Subject: [PATCH 16/21] extcon: gpio: Use resource managed function for request_irq This patch uses the resource managed function for registering interrupt. Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-gpio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 57c24fa52edb..7e7fd8f5d838 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c @@ -118,9 +118,9 @@ static int gpio_extcon_probe(struct platform_device *pdev) if (extcon_data->irq < 0) return extcon_data->irq; - ret = request_any_context_irq(extcon_data->irq, gpio_irq_handler, - pdata->irq_flags, pdev->name, - extcon_data); + ret = devm_request_any_context_irq(&pdev->dev, extcon_data->irq, + gpio_irq_handler, pdata->irq_flags, + pdev->name, extcon_data); if (ret < 0) return ret; @@ -136,7 +136,6 @@ static int gpio_extcon_remove(struct platform_device *pdev) struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev); cancel_delayed_work_sync(&extcon_data->work); - free_irq(extcon_data->irq, extcon_data); return 0; } From 60f9b9e65c82cc610cc9c02c1f555df8fb2ce4f0 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 29 Sep 2015 20:53:12 +0900 Subject: [PATCH 17/21] extcon: gpio: Remove duplicate data from struct gpio_extcon_data There are duplicate data between struct gpio_extcon_data and struct gpio_extcon_platform_data. This patch removes them from struct gpio_extcon_data. Instead, this patch add pdata field to struct gpio_extcon_data. Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-gpio.c | 70 ++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 7e7fd8f5d838..2a89c89dfaf5 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c @@ -33,14 +33,11 @@ struct gpio_extcon_data { struct extcon_dev *edev; - unsigned gpio; - bool gpio_active_low; - const char *state_on; - const char *state_off; int irq; struct delayed_work work; unsigned long debounce_jiffies; - bool check_on_resume; + + struct gpio_extcon_platform_data *pdata; }; static void gpio_extcon_work(struct work_struct *work) @@ -50,25 +47,25 @@ static void gpio_extcon_work(struct work_struct *work) container_of(to_delayed_work(work), struct gpio_extcon_data, work); - state = gpio_get_value(data->gpio); - if (data->gpio_active_low) + state = gpio_get_value(data->pdata->gpio); + if (data->pdata->gpio_active_low) state = !state; extcon_set_state(data->edev, state); } static irqreturn_t gpio_irq_handler(int irq, void *dev_id) { - struct gpio_extcon_data *extcon_data = dev_id; + struct gpio_extcon_data *data = dev_id; - queue_delayed_work(system_power_efficient_wq, &extcon_data->work, - extcon_data->debounce_jiffies); + queue_delayed_work(system_power_efficient_wq, &data->work, + data->debounce_jiffies); return IRQ_HANDLED; } static int gpio_extcon_probe(struct platform_device *pdev) { struct gpio_extcon_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct gpio_extcon_data *extcon_data; + struct gpio_extcon_data *data; int ret; if (!pdata) @@ -78,64 +75,59 @@ static int gpio_extcon_probe(struct platform_device *pdev) return -EINVAL; } - extcon_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_extcon_data), + data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_extcon_data), GFP_KERNEL); - if (!extcon_data) + if (!data) return -ENOMEM; - extcon_data->edev = devm_extcon_dev_allocate(&pdev->dev, NULL); - if (IS_ERR(extcon_data->edev)) { + data->edev = devm_extcon_dev_allocate(&pdev->dev, NULL); + if (IS_ERR(data->edev)) { dev_err(&pdev->dev, "failed to allocate extcon device\n"); return -ENOMEM; } + data->pdata = pdata; - extcon_data->gpio = pdata->gpio; - extcon_data->gpio_active_low = pdata->gpio_active_low; - extcon_data->state_on = pdata->state_on; - extcon_data->state_off = pdata->state_off; - extcon_data->check_on_resume = pdata->check_on_resume; - - ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN, + ret = devm_gpio_request_one(&pdev->dev, data->pdata->gpio, GPIOF_DIR_IN, pdev->name); if (ret < 0) return ret; if (pdata->debounce) { - ret = gpio_set_debounce(extcon_data->gpio, + ret = gpio_set_debounce(data->pdata->gpio, pdata->debounce * 1000); if (ret < 0) - extcon_data->debounce_jiffies = + data->debounce_jiffies = msecs_to_jiffies(pdata->debounce); } - ret = devm_extcon_dev_register(&pdev->dev, extcon_data->edev); + ret = devm_extcon_dev_register(&pdev->dev, data->edev); if (ret < 0) return ret; - INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work); + INIT_DELAYED_WORK(&data->work, gpio_extcon_work); - extcon_data->irq = gpio_to_irq(extcon_data->gpio); - if (extcon_data->irq < 0) - return extcon_data->irq; + data->irq = gpio_to_irq(data->pdata->gpio); + if (data->irq < 0) + return data->irq; - ret = devm_request_any_context_irq(&pdev->dev, extcon_data->irq, + ret = devm_request_any_context_irq(&pdev->dev, data->irq, gpio_irq_handler, pdata->irq_flags, - pdev->name, extcon_data); + pdev->name, data); if (ret < 0) return ret; - platform_set_drvdata(pdev, extcon_data); + platform_set_drvdata(pdev, data); /* Perform initial detection */ - gpio_extcon_work(&extcon_data->work.work); + gpio_extcon_work(&data->work.work); return 0; } static int gpio_extcon_remove(struct platform_device *pdev) { - struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev); + struct gpio_extcon_data *data = platform_get_drvdata(pdev); - cancel_delayed_work_sync(&extcon_data->work); + cancel_delayed_work_sync(&data->work); return 0; } @@ -143,12 +135,12 @@ static int gpio_extcon_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int gpio_extcon_resume(struct device *dev) { - struct gpio_extcon_data *extcon_data; + struct gpio_extcon_data *data; - extcon_data = dev_get_drvdata(dev); - if (extcon_data->check_on_resume) + data = dev_get_drvdata(dev); + if (data->pdata->check_on_resume) queue_delayed_work(system_power_efficient_wq, - &extcon_data->work, extcon_data->debounce_jiffies); + &data->work, data->debounce_jiffies); return 0; } From ce6f7496050e29108bcefe0413df1789648fb38f Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 29 Sep 2015 22:57:24 +0900 Subject: [PATCH 18/21] extcon: gpio: Add the missing supported_cable parameter to devm_extcon_dev_allocate() The commit 2a9de9c0 ("extcon: Use the unique id for external connector instead of string") defines the unique id of each external connector to identify the type of external connector instead of string name. So, devm_extcon_dev_allocate() should include the second parameter (unsigned int *supported_cable). This patch adds the supported_cable parameter which is passed by platform data. Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-gpio.c | 6 ++---- include/linux/extcon/extcon-gpio.h | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 2a89c89dfaf5..ba927df2fb91 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c @@ -70,17 +70,15 @@ static int gpio_extcon_probe(struct platform_device *pdev) if (!pdata) return -EBUSY; - if (!pdata->irq_flags) { - dev_err(&pdev->dev, "IRQ flag is not specified.\n"); + if (!pdata->irq_flags || pdata->extcon_id > EXTCON_NONE) return -EINVAL; - } data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_extcon_data), GFP_KERNEL); if (!data) return -ENOMEM; - data->edev = devm_extcon_dev_allocate(&pdev->dev, NULL); + data->edev = devm_extcon_dev_allocate(&pdev->dev, &pdata->extcon_id); if (IS_ERR(data->edev)) { dev_err(&pdev->dev, "failed to allocate extcon device\n"); return -ENOMEM; diff --git a/include/linux/extcon/extcon-gpio.h b/include/linux/extcon/extcon-gpio.h index 0b17ad43fbfc..232bb8f80b51 100644 --- a/include/linux/extcon/extcon-gpio.h +++ b/include/linux/extcon/extcon-gpio.h @@ -26,6 +26,7 @@ /** * struct gpio_extcon_platform_data - A simple GPIO-controlled extcon device. * @name: The name of this GPIO extcon device. + * @extcon_id: The unique id of specific external connector. * @gpio: Corresponding GPIO. * @gpio_active_low: Boolean describing whether gpio active state is 1 or 0 * If true, low state of gpio means active. @@ -45,6 +46,7 @@ */ struct gpio_extcon_platform_data { const char *name; + unsigned int extcon_id; unsigned gpio; bool gpio_active_low; unsigned long debounce; From 6ba129974a3d6bcb236cbd96aa1db6001d163678 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 29 Sep 2015 22:59:55 +0900 Subject: [PATCH 19/21] extcon: gpio: Fix minor coding style and remove the unused fields. This patch fixes the minor coding style about indentation and removes the unused fields from struct gpio_extcon_platform_data. Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-gpio.c | 11 ++++------- include/linux/extcon/extcon-gpio.h | 22 ++++------------------ 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index ba927df2fb91..27de6aee890f 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c @@ -1,7 +1,5 @@ /* - * drivers/extcon/extcon_gpio.c - * - * Single-state GPIO extcon driver based on extcon class + * extcon_gpio.c - Single-state GPIO extcon driver based on extcon class * * Copyright (C) 2008 Google, Inc. * Author: Mike Lockwood @@ -17,8 +15,7 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * -*/ + */ #include #include @@ -37,7 +34,7 @@ struct gpio_extcon_data { struct delayed_work work; unsigned long debounce_jiffies; - struct gpio_extcon_platform_data *pdata; + struct gpio_extcon_pdata *pdata; }; static void gpio_extcon_work(struct work_struct *work) @@ -64,7 +61,7 @@ static irqreturn_t gpio_irq_handler(int irq, void *dev_id) static int gpio_extcon_probe(struct platform_device *pdev) { - struct gpio_extcon_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct gpio_extcon_pdata *pdata = dev_get_platdata(&pdev->dev); struct gpio_extcon_data *data; int ret; diff --git a/include/linux/extcon/extcon-gpio.h b/include/linux/extcon/extcon-gpio.h index 232bb8f80b51..7cacafb78b09 100644 --- a/include/linux/extcon/extcon-gpio.h +++ b/include/linux/extcon/extcon-gpio.h @@ -1,5 +1,5 @@ /* - * External connector (extcon) class generic GPIO driver + * Single-state GPIO extcon driver based on extcon class * * Copyright (C) 2012 Samsung Electronics * Author: MyungJoo Ham @@ -16,16 +16,14 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * -*/ + */ #ifndef __EXTCON_GPIO_H__ #define __EXTCON_GPIO_H__ __FILE__ #include /** - * struct gpio_extcon_platform_data - A simple GPIO-controlled extcon device. - * @name: The name of this GPIO extcon device. + * struct gpio_extcon_pdata - A simple GPIO-controlled extcon device. * @extcon_id: The unique id of specific external connector. * @gpio: Corresponding GPIO. * @gpio_active_low: Boolean describing whether gpio active state is 1 or 0 @@ -33,28 +31,16 @@ * If false, high state of gpio means active. * @debounce: Debounce time for GPIO IRQ in ms. * @irq_flags: IRQ Flags (e.g., IRQF_TRIGGER_LOW). - * @state_on: print_state is overriden with state_on if attached. - * If NULL, default method of extcon class is used. - * @state_off: print_state is overriden with state_off if detached. - * If NUll, default method of extcon class is used. * @check_on_resume: Boolean describing whether to check the state of gpio * while resuming from sleep. - * - * Note that in order for state_on or state_off to be valid, both state_on - * and state_off should be not NULL. If at least one of them is NULL, - * the print_state is not overriden. */ -struct gpio_extcon_platform_data { - const char *name; +struct gpio_extcon_pdata { unsigned int extcon_id; unsigned gpio; bool gpio_active_low; unsigned long debounce; unsigned long irq_flags; - /* if NULL, "0" or "1" will be printed */ - const char *state_on; - const char *state_off; bool check_on_resume; }; From de992acb93df41fd6cd0ea975ae192363033694a Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 30 Sep 2015 14:57:57 +0900 Subject: [PATCH 20/21] extcon: gpio: Use descriptor-based GPIO interface instead of legacy gpio_* API This patch uses the descriptor-based GPIO interface (gpiod_* API) instead of legacy gpio_* API and add the internal gpio_extcon_init() to handle all gpio-related tasks. Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-gpio.c | 62 +++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 27de6aee890f..279ff8f6637d 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,7 @@ struct gpio_extcon_data { struct delayed_work work; unsigned long debounce_jiffies; + struct gpio_desc *id_gpiod; struct gpio_extcon_pdata *pdata; }; @@ -44,7 +46,7 @@ static void gpio_extcon_work(struct work_struct *work) container_of(to_delayed_work(work), struct gpio_extcon_data, work); - state = gpio_get_value(data->pdata->gpio); + state = gpiod_get_value_cansleep(data->id_gpiod); if (data->pdata->gpio_active_low) state = !state; extcon_set_state(data->edev, state); @@ -59,6 +61,35 @@ static irqreturn_t gpio_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static int gpio_extcon_init(struct device *dev, struct gpio_extcon_data *data) +{ + struct gpio_extcon_pdata *pdata = data->pdata; + int ret; + + ret = devm_gpio_request_one(dev, pdata->gpio, GPIOF_DIR_IN, + dev_name(dev)); + if (ret < 0) + return ret; + + data->id_gpiod = gpio_to_desc(pdata->gpio); + if (!data->id_gpiod) + return -EINVAL; + + if (pdata->debounce) { + ret = gpiod_set_debounce(data->id_gpiod, + pdata->debounce * 1000); + if (ret < 0) + data->debounce_jiffies = + msecs_to_jiffies(pdata->debounce); + } + + data->irq = gpiod_to_irq(data->id_gpiod); + if (data->irq < 0) + return data->irq; + + return 0; +} + static int gpio_extcon_probe(struct platform_device *pdev) { struct gpio_extcon_pdata *pdata = dev_get_platdata(&pdev->dev); @@ -74,26 +105,19 @@ static int gpio_extcon_probe(struct platform_device *pdev) GFP_KERNEL); if (!data) return -ENOMEM; + data->pdata = pdata; + /* Initialize the gpio */ + ret = gpio_extcon_init(&pdev->dev, data); + if (ret < 0) + return ret; + + /* Allocate the memory of extcon devie and register extcon device */ data->edev = devm_extcon_dev_allocate(&pdev->dev, &pdata->extcon_id); if (IS_ERR(data->edev)) { dev_err(&pdev->dev, "failed to allocate extcon device\n"); return -ENOMEM; } - data->pdata = pdata; - - ret = devm_gpio_request_one(&pdev->dev, data->pdata->gpio, GPIOF_DIR_IN, - pdev->name); - if (ret < 0) - return ret; - - if (pdata->debounce) { - ret = gpio_set_debounce(data->pdata->gpio, - pdata->debounce * 1000); - if (ret < 0) - data->debounce_jiffies = - msecs_to_jiffies(pdata->debounce); - } ret = devm_extcon_dev_register(&pdev->dev, data->edev); if (ret < 0) @@ -101,10 +125,10 @@ static int gpio_extcon_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&data->work, gpio_extcon_work); - data->irq = gpio_to_irq(data->pdata->gpio); - if (data->irq < 0) - return data->irq; - + /* + * Request the interrput of gpio to detect whether external connector + * is attached or detached. + */ ret = devm_request_any_context_irq(&pdev->dev, data->irq, gpio_irq_handler, pdata->irq_flags, pdev->name, data); From 11eecf910bd81d36425020743b2df73651c5b466 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Sat, 3 Oct 2015 14:15:13 +0900 Subject: [PATCH 21/21] extcon: Modify the id and name of external connector This patch modifies the id and name of external connector with the additional prefix to clarify both attribute and meaning of external connector as following: - EXTCON_CHG_* mean the charger connector. - EXTCON_JACK_* mean the jack connector. - EXTCON_DISP_* mean the display port connector. Following table show the new name of external connector with old name: -------------------------------------------------- Old extcon name | New extcon name | -------------------------------------------------- EXTCON_TA | EXTCON_CHG_USB_DCP | EXTCON_CHARGE_DOWNSTREAM| EXTCON_CHG_USB_CDP | EXTCON_FAST_CHARGER | EXTCON_CHG_USB_FAST | EXTCON_SLOW_CHARGER | EXTCON_CHG_USB_SLOW | -------------------------------------------------- EXTCON_MICROPHONE | EXTCON_JACK_MICROPHONE | EXTCON_HEADPHONE | EXTCON_JACK_HEADPHONE | EXTCON_LINE_IN | EXTCON_JACK_LINE_IN | EXTCON_LINE_OUT | EXTCON_JACK_LINE_OUT | EXTCON_VIDEO_IN | EXTCON_JACK_VIDEO_IN | EXTCON_VIDEO_OUT | EXTCON_JACK_VIDEO_OUT | EXTCON_SPDIF_IN | EXTCON_JACK_SPDIF_IN | EXTCON_SPDIF_OUT | EXTCON_JACK_SPDIF_OUT | -------------------------------------------------- EXTCON_HMDI | EXTCON_DISP_HDMI | EXTCON_MHL | EXTCON_DISP_MHL | EXTCON_DVI | EXTCON_DISP_DVI | EXTCON_VGA | EXTCON_DISP_VGA | -------------------------------------------------- And, when altering the name of USB charger connector, EXTCON refers to the "Battery Charging v1.2 Spec and Adopters Agreement"[1] to use the standard name of USB charging port as following. Following name of USB charging port are already used in power_supply subsystem. We chan check it on patch[2]. - EXTCON_CHG_USB_SDP /* Standard Downstream Port */ - EXTCON_CHG_USB_DCP /* Dedicated Charging Port */ - EXTCON_CHG_USB_CDP /* Charging Downstream Port */ - EXTCON_CHG_USB_ACA /* Accessory Charger Adapter */ [1] www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip [2] commit 85efc8a18ced ("power_supply: Add types for USB chargers") Signed-off-by: Chanwoo Choi [ckeepax: For the Arizona changes] Acked-by: Charles Keepax Reviewed-by: Roger Quadros --- drivers/extcon/extcon-arizona.c | 18 +++++------ drivers/extcon/extcon-axp288.c | 12 +++---- drivers/extcon/extcon-max14577.c | 17 +++++----- drivers/extcon/extcon-max77693.c | 32 ++++++++++--------- drivers/extcon/extcon-max77843.c | 27 +++++++++------- drivers/extcon/extcon-max8997.c | 21 +++++++------ drivers/extcon/extcon-rt8973a.c | 4 +-- drivers/extcon/extcon-sm5502.c | 4 +-- drivers/extcon/extcon.c | 53 ++++++++++++++++--------------- include/linux/extcon.h | 54 +++++++++++++++++++------------- 10 files changed, 131 insertions(+), 111 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index a1ab0a56b798..e4890dd4fefd 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -137,9 +137,9 @@ static const int arizona_micd_levels[] = { static const unsigned int arizona_cable[] = { EXTCON_MECHANICAL, - EXTCON_MICROPHONE, - EXTCON_HEADPHONE, - EXTCON_LINE_OUT, + EXTCON_JACK_MICROPHONE, + EXTCON_JACK_HEADPHONE, + EXTCON_JACK_LINE_OUT, EXTCON_NONE, }; @@ -600,7 +600,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) struct arizona_extcon_info *info = data; struct arizona *arizona = info->arizona; int id_gpio = arizona->pdata.hpdet_id_gpio; - unsigned int report = EXTCON_HEADPHONE; + unsigned int report = EXTCON_JACK_HEADPHONE; int ret, reading; bool mic = false; @@ -645,9 +645,9 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) /* Report high impedence cables as line outputs */ if (reading >= 5000) - report = EXTCON_LINE_OUT; + report = EXTCON_JACK_LINE_OUT; else - report = EXTCON_HEADPHONE; + report = EXTCON_JACK_HEADPHONE; ret = extcon_set_cable_state_(info->edev, report, true); if (ret != 0) @@ -732,7 +732,7 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info) ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); /* Just report headphone */ - ret = extcon_set_cable_state_(info->edev, EXTCON_HEADPHONE, true); + ret = extcon_set_cable_state_(info->edev, EXTCON_JACK_HEADPHONE, true); if (ret != 0) dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); @@ -789,7 +789,7 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); /* Just report headphone */ - ret = extcon_set_cable_state_(info->edev, EXTCON_HEADPHONE, true); + ret = extcon_set_cable_state_(info->edev, EXTCON_JACK_HEADPHONE, true); if (ret != 0) dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); @@ -915,7 +915,7 @@ static void arizona_micd_detect(struct work_struct *work) arizona_identify_headphone(info); ret = extcon_set_cable_state_(info->edev, - EXTCON_MICROPHONE, true); + EXTCON_JACK_MICROPHONE, true); if (ret != 0) dev_err(arizona->dev, "Headset report failed: %d\n", ret); diff --git a/drivers/extcon/extcon-axp288.c b/drivers/extcon/extcon-axp288.c index 9668d6a94e38..fd55c2f2080a 100644 --- a/drivers/extcon/extcon-axp288.c +++ b/drivers/extcon/extcon-axp288.c @@ -102,9 +102,9 @@ enum axp288_extcon_irq { }; static const unsigned int axp288_extcon_cables[] = { - EXTCON_SLOW_CHARGER, - EXTCON_CHARGE_DOWNSTREAM, - EXTCON_FAST_CHARGER, + EXTCON_CHG_USB_SDP, + EXTCON_CHG_USB_CDP, + EXTCON_CHG_USB_DCP, EXTCON_NONE, }; @@ -192,18 +192,18 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) dev_dbg(info->dev, "sdp cable is connecetd\n"); notify_otg = true; notify_charger = true; - cable = EXTCON_SLOW_CHARGER; + cable = EXTCON_CHG_USB_SDP; break; case DET_STAT_CDP: dev_dbg(info->dev, "cdp cable is connecetd\n"); notify_otg = true; notify_charger = true; - cable = EXTCON_CHARGE_DOWNSTREAM; + cable = EXTCON_CHG_USB_CDP; break; case DET_STAT_DCP: dev_dbg(info->dev, "dcp cable is connecetd\n"); notify_charger = true; - cable = EXTCON_FAST_CHARGER; + cable = EXTCON_CHG_USB_DCP; break; default: dev_warn(info->dev, diff --git a/drivers/extcon/extcon-max14577.c b/drivers/extcon/extcon-max14577.c index df0659d98e5a..601dbd996487 100644 --- a/drivers/extcon/extcon-max14577.c +++ b/drivers/extcon/extcon-max14577.c @@ -150,10 +150,10 @@ enum max14577_muic_acc_type { static const unsigned int max14577_extcon_cable[] = { EXTCON_USB, - EXTCON_TA, - EXTCON_FAST_CHARGER, - EXTCON_SLOW_CHARGER, - EXTCON_CHARGE_DOWNSTREAM, + EXTCON_CHG_USB_DCP, + EXTCON_CHG_USB_FAST, + EXTCON_CHG_USB_SLOW, + EXTCON_CHG_USB_CDP, EXTCON_JIG, EXTCON_NONE, }; @@ -456,18 +456,19 @@ static int max14577_muic_chg_handler(struct max14577_muic_info *info) extcon_set_cable_state_(info->edev, EXTCON_USB, attached); break; case MAX14577_CHARGER_TYPE_DEDICATED_CHG: - extcon_set_cable_state_(info->edev, EXTCON_TA, attached); + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, + attached); break; case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT: - extcon_set_cable_state_(info->edev, EXTCON_CHARGE_DOWNSTREAM, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_CDP, attached); break; case MAX14577_CHARGER_TYPE_SPECIAL_500MA: - extcon_set_cable_state_(info->edev, EXTCON_SLOW_CHARGER, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SLOW, attached); break; case MAX14577_CHARGER_TYPE_SPECIAL_1A: - extcon_set_cable_state_(info->edev, EXTCON_FAST_CHARGER, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_FAST, attached); break; case MAX14577_CHARGER_TYPE_NONE: diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 35b9e118b2fb..44c499e1beee 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -204,11 +204,11 @@ enum max77693_muic_acc_type { static const unsigned int max77693_extcon_cable[] = { EXTCON_USB, EXTCON_USB_HOST, - EXTCON_TA, - EXTCON_FAST_CHARGER, - EXTCON_SLOW_CHARGER, - EXTCON_CHARGE_DOWNSTREAM, - EXTCON_MHL, + EXTCON_CHG_USB_DCP, + EXTCON_CHG_USB_FAST, + EXTCON_CHG_USB_SLOW, + EXTCON_CHG_USB_CDP, + EXTCON_DISP_MHL, EXTCON_JIG, EXTCON_DOCK, EXTCON_NONE, @@ -505,7 +505,7 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info, return ret; extcon_set_cable_state_(info->edev, EXTCON_DOCK, attached); - extcon_set_cable_state_(info->edev, EXTCON_MHL, attached); + extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, attached); goto out; case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: /* Dock-Desk */ dock_id = EXTCON_DOCK; @@ -605,7 +605,7 @@ static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info) case MAX77693_MUIC_GND_MHL: case MAX77693_MUIC_GND_MHL_VB: /* MHL or MHL with USB/TA cable */ - extcon_set_cable_state_(info->edev, EXTCON_MHL, attached); + extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, attached); break; default: dev_err(info->dev, "failed to detect %s cable of gnd type\n", @@ -801,10 +801,11 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) * - Support charging through micro-usb port without * data connection */ - extcon_set_cable_state_(info->edev, EXTCON_TA, attached); + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, + attached); if (!cable_attached) - extcon_set_cable_state_(info->edev, EXTCON_MHL, - cable_attached); + extcon_set_cable_state_(info->edev, + EXTCON_DISP_MHL, cable_attached); break; } @@ -862,7 +863,7 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) extcon_set_cable_state_(info->edev, EXTCON_DOCK, attached); - extcon_set_cable_state_(info->edev, EXTCON_MHL, + extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, attached); break; } @@ -901,20 +902,21 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) break; case MAX77693_CHARGER_TYPE_DEDICATED_CHG: /* Only TA cable */ - extcon_set_cable_state_(info->edev, EXTCON_TA, attached); + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, + attached); break; } break; case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT: - extcon_set_cable_state_(info->edev, EXTCON_CHARGE_DOWNSTREAM, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_CDP, attached); break; case MAX77693_CHARGER_TYPE_APPLE_500MA: - extcon_set_cable_state_(info->edev, EXTCON_SLOW_CHARGER, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SLOW, attached); break; case MAX77693_CHARGER_TYPE_APPLE_1A_2A: - extcon_set_cable_state_(info->edev, EXTCON_FAST_CHARGER, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_FAST, attached); break; case MAX77693_CHARGER_TYPE_DEAD_BATTERY: diff --git a/drivers/extcon/extcon-max77843.c b/drivers/extcon/extcon-max77843.c index fdd928542c19..9f9ea334399c 100644 --- a/drivers/extcon/extcon-max77843.c +++ b/drivers/extcon/extcon-max77843.c @@ -122,11 +122,11 @@ enum max77843_muic_charger_type { static const unsigned int max77843_extcon_cable[] = { EXTCON_USB, EXTCON_USB_HOST, - EXTCON_TA, - EXTCON_CHARGE_DOWNSTREAM, - EXTCON_FAST_CHARGER, - EXTCON_SLOW_CHARGER, - EXTCON_MHL, + EXTCON_CHG_USB_DCP, + EXTCON_CHG_USB_CDP, + EXTCON_CHG_USB_FAST, + EXTCON_CHG_USB_SLOW, + EXTCON_DISP_MHL, EXTCON_JIG, EXTCON_NONE, }; @@ -355,7 +355,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info) if (ret < 0) return ret; - extcon_set_cable_state_(info->edev, EXTCON_MHL, attached); + extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, attached); break; default: dev_err(info->dev, "failed to detect %s accessory(gnd:0x%x)\n", @@ -494,7 +494,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) if (ret < 0) return ret; - extcon_set_cable_state_(info->edev, EXTCON_CHARGE_DOWNSTREAM, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_CDP, attached); break; case MAX77843_MUIC_CHG_DEDICATED: @@ -504,7 +504,8 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) if (ret < 0) return ret; - extcon_set_cable_state_(info->edev, EXTCON_TA, attached); + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, + attached); break; case MAX77843_MUIC_CHG_SPECIAL_500MA: ret = max77843_muic_set_path(info, @@ -513,7 +514,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) if (ret < 0) return ret; - extcon_set_cable_state_(info->edev, EXTCON_SLOW_CHARGER, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SLOW, attached); break; case MAX77843_MUIC_CHG_SPECIAL_1A: @@ -523,7 +524,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) if (ret < 0) return ret; - extcon_set_cable_state_(info->edev, EXTCON_FAST_CHARGER, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_FAST, attached); break; case MAX77843_MUIC_CHG_GND: @@ -532,9 +533,11 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) /* Charger cable on MHL accessory is attach or detach */ if (gnd_type == MAX77843_MUIC_GND_MHL_VB) - extcon_set_cable_state_(info->edev, EXTCON_TA, true); + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, + true); else if (gnd_type == MAX77843_MUIC_GND_MHL) - extcon_set_cable_state_(info->edev, EXTCON_TA, false); + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, + false); break; case MAX77843_MUIC_CHG_NONE: break; diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 7b1ef200b121..b2b13b3dce14 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -148,11 +148,11 @@ struct max8997_muic_info { static const unsigned int max8997_extcon_cable[] = { EXTCON_USB, EXTCON_USB_HOST, - EXTCON_TA, - EXTCON_FAST_CHARGER, - EXTCON_SLOW_CHARGER, - EXTCON_CHARGE_DOWNSTREAM, - EXTCON_MHL, + EXTCON_CHG_USB_DCP, + EXTCON_CHG_USB_FAST, + EXTCON_CHG_USB_SLOW, + EXTCON_CHG_USB_CDP, + EXTCON_DISP_MHL, EXTCON_DOCK, EXTCON_JIG, EXTCON_NONE, @@ -403,7 +403,7 @@ static int max8997_muic_adc_handler(struct max8997_muic_info *info) return ret; break; case MAX8997_MUIC_ADC_MHL: - extcon_set_cable_state_(info->edev, EXTCON_MHL, attached); + extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, attached); break; case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF: case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON: @@ -486,18 +486,19 @@ static int max8997_muic_chg_handler(struct max8997_muic_info *info) } break; case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: - extcon_set_cable_state_(info->edev, EXTCON_CHARGE_DOWNSTREAM, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_CDP, attached); break; case MAX8997_CHARGER_TYPE_DEDICATED_CHG: - extcon_set_cable_state_(info->edev, EXTCON_TA, attached); + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, + attached); break; case MAX8997_CHARGER_TYPE_500MA: - extcon_set_cable_state_(info->edev, EXTCON_SLOW_CHARGER, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SLOW, attached); break; case MAX8997_CHARGER_TYPE_1A: - extcon_set_cable_state_(info->edev, EXTCON_FAST_CHARGER, + extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_FAST, attached); break; default: diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c index 1bc3737ea01c..36bf1d63791c 100644 --- a/drivers/extcon/extcon-rt8973a.c +++ b/drivers/extcon/extcon-rt8973a.c @@ -93,7 +93,7 @@ static struct reg_data rt8973a_reg_data[] = { static const unsigned int rt8973a_extcon_cable[] = { EXTCON_USB, EXTCON_USB_HOST, - EXTCON_TA, + EXTCON_CHG_USB_DCP, EXTCON_JIG, EXTCON_NONE, }; @@ -333,7 +333,7 @@ static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info, con_sw = DM_DP_SWITCH_USB; break; case RT8973A_MUIC_ADC_TA: - id = EXTCON_TA; + id = EXTCON_CHG_USB_DCP; con_sw = DM_DP_SWITCH_OPEN; break; case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB: diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index 2945091bfd0e..7aac3cc7efd7 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -95,7 +95,7 @@ static struct reg_data sm5502_reg_data[] = { static const unsigned int sm5502_extcon_cable[] = { EXTCON_USB, EXTCON_USB_HOST, - EXTCON_TA, + EXTCON_CHG_USB_DCP, EXTCON_NONE, }; @@ -389,7 +389,7 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info, vbus_sw = VBUSIN_SWITCH_VBUSOUT_WITH_USB; break; case SM5502_MUIC_ADC_OPEN_TA: - id = EXTCON_TA; + id = EXTCON_CHG_USB_DCP; con_sw = DM_DP_SWITCH_OPEN; vbus_sw = VBUSIN_SWITCH_VBUSOUT; break; diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 8dd0af1d50bc..21a123cadf78 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -39,37 +39,40 @@ #define CABLE_NAME_MAX 30 static const char *extcon_name[] = { - [EXTCON_NONE] = "NONE", + [EXTCON_NONE] = "NONE", /* USB external connector */ - [EXTCON_USB] = "USB", - [EXTCON_USB_HOST] = "USB-HOST", + [EXTCON_USB] = "USB", + [EXTCON_USB_HOST] = "USB-HOST", - /* Charger external connector */ - [EXTCON_TA] = "TA", - [EXTCON_FAST_CHARGER] = "FAST-CHARGER", - [EXTCON_SLOW_CHARGER] = "SLOW-CHARGER", - [EXTCON_CHARGE_DOWNSTREAM] = "CHARGE-DOWNSTREAM", + /* Charging external connector */ + [EXTCON_CHG_USB_SDP] = "SDP", + [EXTCON_CHG_USB_DCP] = "DCP", + [EXTCON_CHG_USB_CDP] = "CDP", + [EXTCON_CHG_USB_ACA] = "ACA", + [EXTCON_CHG_USB_FAST] = "FAST-CHARGER", + [EXTCON_CHG_USB_SLOW] = "SLOW-CHARGER", - /* Audio/Video external connector */ - [EXTCON_LINE_IN] = "LINE-IN", - [EXTCON_LINE_OUT] = "LINE-OUT", - [EXTCON_MICROPHONE] = "MICROPHONE", - [EXTCON_HEADPHONE] = "HEADPHONE", + /* Jack external connector */ + [EXTCON_JACK_MICROPHONE] = "MICROPHONE", + [EXTCON_JACK_HEADPHONE] = "HEADPHONE", + [EXTCON_JACK_LINE_IN] = "LINE-IN", + [EXTCON_JACK_LINE_OUT] = "LINE-OUT", + [EXTCON_JACK_VIDEO_IN] = "VIDEO-IN", + [EXTCON_JACK_VIDEO_OUT] = "VIDEO-OUT", + [EXTCON_JACK_SPDIF_IN] = "SPDIF-IN", + [EXTCON_JACK_SPDIF_OUT] = "SPDIF-OUT", - [EXTCON_HDMI] = "HDMI", - [EXTCON_MHL] = "MHL", - [EXTCON_DVI] = "DVI", - [EXTCON_VGA] = "VGA", - [EXTCON_SPDIF_IN] = "SPDIF-IN", - [EXTCON_SPDIF_OUT] = "SPDIF-OUT", - [EXTCON_VIDEO_IN] = "VIDEO-IN", - [EXTCON_VIDEO_OUT] = "VIDEO-OUT", + /* Display external connector */ + [EXTCON_DISP_HDMI] = "HDMI", + [EXTCON_DISP_MHL] = "MHL", + [EXTCON_DISP_DVI] = "DVI", + [EXTCON_DISP_VGA] = "VGA", - /* Etc external connector */ - [EXTCON_DOCK] = "DOCK", - [EXTCON_JIG] = "JIG", - [EXTCON_MECHANICAL] = "MECHANICAL", + /* Miscellaneous external connector */ + [EXTCON_DOCK] = "DOCK", + [EXTCON_JIG] = "JIG", + [EXTCON_MECHANICAL] = "MECHANICAL", NULL, }; diff --git a/include/linux/extcon.h b/include/linux/extcon.h index c0f8c4fc5d45..7abf674c388c 100644 --- a/include/linux/extcon.h +++ b/include/linux/extcon.h @@ -31,32 +31,42 @@ /* * Define the unique id of supported external connectors */ -#define EXTCON_NONE 0 +#define EXTCON_NONE 0 -#define EXTCON_USB 1 /* USB connector */ -#define EXTCON_USB_HOST 2 +/* USB external connector */ +#define EXTCON_USB 1 +#define EXTCON_USB_HOST 2 -#define EXTCON_TA 3 /* Charger connector */ -#define EXTCON_FAST_CHARGER 4 -#define EXTCON_SLOW_CHARGER 5 -#define EXTCON_CHARGE_DOWNSTREAM 6 +/* Charging external connector */ +#define EXTCON_CHG_USB_SDP 5 /* Standard Downstream Port */ +#define EXTCON_CHG_USB_DCP 6 /* Dedicated Charging Port */ +#define EXTCON_CHG_USB_CDP 7 /* Charging Downstream Port */ +#define EXTCON_CHG_USB_ACA 8 /* Accessory Charger Adapter */ +#define EXTCON_CHG_USB_FAST 9 +#define EXTCON_CHG_USB_SLOW 10 -#define EXTCON_LINE_IN 7 /* Audio/Video connector */ -#define EXTCON_LINE_OUT 8 -#define EXTCON_MICROPHONE 9 -#define EXTCON_HEADPHONE 10 -#define EXTCON_HDMI 11 -#define EXTCON_MHL 12 -#define EXTCON_DVI 13 -#define EXTCON_VGA 14 -#define EXTCON_SPDIF_IN 15 -#define EXTCON_SPDIF_OUT 16 -#define EXTCON_VIDEO_IN 17 -#define EXTCON_VIDEO_OUT 18 +/* Jack external connector */ +#define EXTCON_JACK_MICROPHONE 20 +#define EXTCON_JACK_HEADPHONE 21 +#define EXTCON_JACK_LINE_IN 22 +#define EXTCON_JACK_LINE_OUT 23 +#define EXTCON_JACK_VIDEO_IN 24 +#define EXTCON_JACK_VIDEO_OUT 25 +#define EXTCON_JACK_SPDIF_IN 26 /* Sony Philips Digital InterFace */ +#define EXTCON_JACK_SPDIF_OUT 27 -#define EXTCON_DOCK 19 /* Misc connector */ -#define EXTCON_JIG 20 -#define EXTCON_MECHANICAL 21 +/* Display external connector */ +#define EXTCON_DISP_HDMI 40 /* High-Definition Multimedia Interface */ +#define EXTCON_DISP_MHL 41 /* Mobile High-Definition Link */ +#define EXTCON_DISP_DVI 42 /* Digital Visual Interface */ +#define EXTCON_DISP_VGA 43 /* Video Graphics Array */ + +/* Miscellaneous external connector */ +#define EXTCON_DOCK 60 +#define EXTCON_JIG 61 +#define EXTCON_MECHANICAL 62 + +#define EXTCON_NUM 63 struct extcon_cable;