diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2017-09-29 09:38:19 +0200 |
---|---|---|
committer | Marek Szyprowski <m.szyprowski@samsung.com> | 2017-10-10 08:30:09 +0200 |
commit | 6cb0d84ac8066c890a6caa10a9a0673922a272ea (patch) | |
tree | 1ae359c2ce96838ceabf9d2ee5cbb599c00c919f | |
parent | d6d3c16b12e159df43bbbef159e9282afe369dd1 (diff) | |
download | linux-exynos-submit/tizen/20171011.043021.tar.gz linux-exynos-submit/tizen/20171011.043021.tar.bz2 linux-exynos-submit/tizen/20171011.043021.zip |
extcon: max88743: add support for SmartDock accessorytizen_4.0.IoT.p1_releasesubmit/tizen_4.0/20171011.042941submit/tizen/20171011.043021accepted/tizen/unified/20171011.070207accepted/tizen/4.0/unified/20171011.071839
SmartDock uses ADC_RESERVED_ACC_3 (0x10) ADC ID type and provides following
features:
1. USB host with embedded USB hub (2-4 ports) for mice, keyboard, etc,
2. MHL for video output,
3. charging.
Tested with Unitek Y-2165 MHL+OTG Hub Smart Phone Dock.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Change-Id: I64565a6dc04a16c12bbab20b439eddeff215dc94
-rw-r--r-- | drivers/extcon/extcon-max77843.c | 94 | ||||
-rw-r--r-- | include/linux/mfd/max77843-private.h | 2 |
2 files changed, 79 insertions, 17 deletions
diff --git a/drivers/extcon/extcon-max77843.c b/drivers/extcon/extcon-max77843.c index 904fb5287b37..230a209a2f82 100644 --- a/drivers/extcon/extcon-max77843.c +++ b/drivers/extcon/extcon-max77843.c @@ -80,7 +80,7 @@ enum max77843_muic_accessory_type { MAX77843_MUIC_ADC_REMOTE_S12_BUTTON, MAX77843_MUIC_ADC_RESERVED_ACC_1, MAX77843_MUIC_ADC_RESERVED_ACC_2, - MAX77843_MUIC_ADC_RESERVED_ACC_3, + MAX77843_MUIC_ADC_RESERVED_ACC_3, /* SmartDock */ MAX77843_MUIC_ADC_RESERVED_ACC_4, MAX77843_MUIC_ADC_RESERVED_ACC_5, MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2, @@ -117,6 +117,7 @@ enum max77843_muic_charger_type { MAX77843_MUIC_CHG_SPECIAL_BIAS, MAX77843_MUIC_CHG_RESERVED, MAX77843_MUIC_CHG_GND, + MAX77843_MUIC_CHG_DOCK, }; enum { @@ -127,6 +128,7 @@ enum { MAX77843_CABLE_FAST_CHARGER, MAX77843_CABLE_SLOW_CHARGER, MAX77843_CABLE_MHL, + MAX77843_CABLE_DOCK, MAX77843_CABLE_JIG_USB_ON, MAX77843_CABLE_JIG_USB_OFF, MAX77843_CABLE_JIG_UART_ON, @@ -143,6 +145,7 @@ static const char *max77843_extcon_cable[] = { [MAX77843_CABLE_FAST_CHARGER] = "FAST-CHARGER", [MAX77843_CABLE_SLOW_CHARGER] = "SLOW-CHARGER", [MAX77843_CABLE_MHL] = "MHL", + [MAX77843_CABLE_DOCK] = "DOCK", [MAX77843_CABLE_JIG_USB_ON] = "JIG-USB-ON", [MAX77843_CABLE_JIG_USB_OFF] = "JIG-USB-OFF", [MAX77843_CABLE_JIG_UART_ON] = "JIG-UART-ON", @@ -216,7 +219,7 @@ static const struct regmap_irq_chip max77843_muic_irq_chip = { }; static int max77843_muic_set_path(struct max77843_muic_info *info, - u8 val, bool attached) + u8 val, bool attached, bool nobccomp) { struct max77843 *max77843 = info->max77843; int ret = 0; @@ -227,9 +230,15 @@ static int max77843_muic_set_path(struct max77843_muic_info *info, else ctrl1 = CONTROL1_SW_OPEN; + if (nobccomp) { + /* Disable BC1.2 protocol and force manual switch control */ + ctrl1 |= MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK; + } + ret = regmap_update_bits(max77843->regmap_muic, MAX77843_MUIC_REG_CONTROL1, - CONTROL1_COM_SW, ctrl1); + CONTROL1_COM_SW | MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK, + ctrl1); if (ret < 0) { dev_err(info->dev, "Cannot switch MUIC port\n"); return ret; @@ -320,6 +329,19 @@ static int max77843_muic_get_cable_type(struct max77843_muic_info *info, break; } + if (adc == MAX77843_MUIC_ADC_RESERVED_ACC_3) { /* SmartDock */ + if (chg_type == MAX77843_MUIC_CHG_NONE) { + *attached = false; + cable_type = info->prev_chg_type; + info->prev_chg_type = MAX77843_MUIC_CHG_NONE; + } else { + *attached = true; + cable_type = MAX77843_MUIC_CHG_DOCK; + info->prev_chg_type = MAX77843_MUIC_CHG_DOCK; + } + break; + } + if (adc == MAX77843_MUIC_ADC_RESERVED_ACC_4) { if (chg_type == MAX77843_MUIC_CHG_NONE) { *attached = false; @@ -391,7 +413,8 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info) switch (gnd_cable_type) { case MAX77843_MUIC_GND_USB_HOST: case MAX77843_MUIC_GND_USB_HOST_VB: - ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached, + false); if (ret < 0) return ret; @@ -400,7 +423,8 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info) break; case MAX77843_MUIC_GND_MHL_VB: case MAX77843_MUIC_GND_MHL: - ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached, + false); if (ret < 0) return ret; @@ -425,25 +449,29 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info, switch (cable_type) { case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF: - ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached, + false); if (ret < 0) return ret; extcon_set_cable_state(info->edev, "JIG-USB-OFF", attached); break; case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON: - ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached, + false); if (ret < 0) return ret; extcon_set_cable_state(info->edev, "JIG-USB-ON", attached); break; case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF: - ret = max77843_muic_set_path(info, CONTROL1_SW_UART, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_UART, attached, + false); if (ret < 0) return ret; extcon_set_cable_state(info->edev, "JIG-UART-OFF", attached); break; default: - ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached, + false); if (ret < 0) return ret; break; @@ -452,6 +480,26 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info, return 0; } +static int max77843_muic_dock_handler(struct max77843_muic_info *info, + bool attached) +{ + int ret; + + dev_dbg(info->dev, "external connector is %s (adc: 0x10)\n", + attached ? "attached" : "detached"); + + ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached, + attached); + if (ret < 0) + return ret; + + extcon_set_cable_state(info->edev, "MHL", attached); + extcon_set_cable_state(info->edev, "USB-HOST", attached); + extcon_set_cable_state(info->edev, "DOCK", attached); + + return 0; +} + static int max77843_muic_adc_handler(struct max77843_muic_info *info) { int ret, cable_type; @@ -466,6 +514,11 @@ static int max77843_muic_adc_handler(struct max77843_muic_info *info) info->prev_cable_type); switch (cable_type) { + case MAX77843_MUIC_ADC_RESERVED_ACC_3: /* SmartDock */ + ret = max77843_muic_dock_handler(info, attached); + if (ret < 0) + return ret; + break; case MAX77843_MUIC_ADC_GROUND: case MAX77843_MUIC_ADC_RESERVED_ACC_4: ret = max77843_muic_adc_gnd_handler(info); @@ -494,7 +547,6 @@ static int max77843_muic_adc_handler(struct max77843_muic_info *info) case MAX77843_MUIC_ADC_REMOTE_S12_BUTTON: case MAX77843_MUIC_ADC_RESERVED_ACC_1: case MAX77843_MUIC_ADC_RESERVED_ACC_2: - case MAX77843_MUIC_ADC_RESERVED_ACC_3: case MAX77843_MUIC_ADC_RESERVED_ACC_5: case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2: case MAX77843_MUIC_ADC_PHONE_POWERED_DEV: @@ -535,14 +587,16 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) switch (chg_type) { case MAX77843_MUIC_CHG_USB: - ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached, + false); if (ret < 0) return ret; extcon_set_cable_state(info->edev, "USB", attached); break; case MAX77843_MUIC_CHG_DOWNSTREAM: - ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached, + false); if (ret < 0) return ret; @@ -550,21 +604,24 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) "CHARGER-DOWNSTREAM", attached); break; case MAX77843_MUIC_CHG_DEDICATED: - ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached, + false); if (ret < 0) return ret; extcon_set_cable_state(info->edev, "TA", attached); break; case MAX77843_MUIC_CHG_SPECIAL_500MA: - ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached, + false); if (ret < 0) return ret; extcon_set_cable_state(info->edev, "SLOW-CHAREGER", attached); break; case MAX77843_MUIC_CHG_SPECIAL_1A: - ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); + ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached, + false); if (ret < 0) return ret; @@ -580,6 +637,9 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) else if (gnd_type == MAX77843_MUIC_GND_MHL) extcon_set_cable_state(info->edev, "TA", false); break; + case MAX77843_MUIC_CHG_DOCK: + extcon_set_cable_state(info->edev, "TA", attached); + break; case MAX77843_MUIC_CHG_NONE: break; default: @@ -587,7 +647,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) "failed to detect %s accessory (chg_type:0x%x)\n", attached ? "attached" : "detached", chg_type); - max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); + max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached, false); return -EINVAL; } @@ -836,7 +896,7 @@ static int max77843_muic_probe(struct platform_device *pdev) max77843_muic_set_debounce_time(info, MAX77843_DEBOUNCE_TIME_25MS); /* Set initial path for UART */ - max77843_muic_set_path(info, CONTROL1_SW_UART, true); + max77843_muic_set_path(info, CONTROL1_SW_UART, true, false); /* Check revision number of MUIC device */ ret = regmap_read(max77843->regmap_muic, MAX77843_MUIC_REG_ID, &id); diff --git a/include/linux/mfd/max77843-private.h b/include/linux/mfd/max77843-private.h index a56e096eb206..d243cc3c38bf 100644 --- a/include/linux/mfd/max77843-private.h +++ b/include/linux/mfd/max77843-private.h @@ -384,6 +384,7 @@ enum max77843_irq_muic { #define CONTROL1_COMP1SW_SHIFT 0 #define CONTROL1_COMP2SW_SHIFT 3 #define CONTROL1_IDBEN_SHIFT 7 +#define CONTROL1_NOBCCOMP_SHIFT 6 #define CONTROL2_LOWPWR_SHIFT 0 #define CONTROL2_ADCEN_SHIFT 1 #define CONTROL2_CPEN_SHIFT 2 @@ -399,6 +400,7 @@ enum max77843_irq_muic { #define MAX77843_MUIC_CONTROL1_COMP1SW_MASK (0x7 << CONTROL1_COMP1SW_SHIFT) #define MAX77843_MUIC_CONTROL1_COMP2SW_MASK (0x7 << CONTROL1_COMP2SW_SHIFT) #define MAX77843_MUIC_CONTROL1_IDBEN_MASK BIT(CONTROL1_IDBEN_SHIFT) +#define MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK BIT(CONTROL1_NOBCCOMP_SHIFT) #define MAX77843_MUIC_CONTROL2_LOWPWR_MASK BIT(CONTROL2_LOWPWR_SHIFT) #define MAX77843_MUIC_CONTROL2_ADCEN_MASK BIT(CONTROL2_ADCEN_SHIFT) #define MAX77843_MUIC_CONTROL2_CPEN_MASK BIT(CONTROL2_CPEN_SHIFT) |