Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a4a8714 authored by Marek Szyprowski's avatar Marek Szyprowski Committed by Chanwoo Choi
Browse files

extcon: max77843: Add support for SmartDock accessory



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: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Acked-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Acked-by: default avatarLee Jones <lee.jones@linaro.org>
Signed-off-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
parent 7b965110
Loading
Loading
Loading
Loading
+63 −14
Original line number Diff line number Diff line
@@ -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,
@@ -119,6 +119,7 @@ enum max77843_muic_charger_type {
	MAX77843_MUIC_CHG_SPECIAL_BIAS,
	MAX77843_MUIC_CHG_RESERVED,
	MAX77843_MUIC_CHG_GND,
	MAX77843_MUIC_CHG_DOCK,
};

static const unsigned int max77843_extcon_cable[] = {
@@ -130,6 +131,7 @@ static const unsigned int max77843_extcon_cable[] = {
	EXTCON_CHG_USB_FAST,
	EXTCON_CHG_USB_SLOW,
	EXTCON_DISP_MHL,
	EXTCON_DOCK,
	EXTCON_JIG,
	EXTCON_NONE,
};
@@ -200,7 +202,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 max77693_dev *max77843 = info->max77843;
	int ret = 0;
@@ -210,10 +212,16 @@ static int max77843_muic_set_path(struct max77843_muic_info *info,
		ctrl1 = val;
	else
		ctrl1 = MAX77843_MUIC_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,
			MAX77843_MUIC_CONTROL1_COM_SW, ctrl1);
			MAX77843_MUIC_CONTROL1_COM_SW |
				MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK,
			ctrl1);
	if (ret < 0) {
		dev_err(info->dev, "Cannot switch MUIC port\n");
		return ret;
@@ -303,6 +311,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 (chg_type == MAX77843_MUIC_CHG_NONE) {
			*attached = false;
			cable_type = info->prev_chg_type;
@@ -365,7 +386,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info)
	case MAX77843_MUIC_GND_USB_HOST_VB:
		ret = max77843_muic_set_path(info,
					     MAX77843_MUIC_CONTROL1_SW_USB,
					     attached);
					     attached, false);
		if (ret < 0)
			return ret;

@@ -376,7 +397,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info)
	case MAX77843_MUIC_GND_MHL:
		ret = max77843_muic_set_path(info,
					     MAX77843_MUIC_CONTROL1_SW_OPEN,
					     attached);
					     attached, false);
		if (ret < 0)
			return ret;

@@ -412,7 +433,7 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info,
		return -EINVAL;
	}

	ret = max77843_muic_set_path(info, path, attached);
	ret = max77843_muic_set_path(info, path, attached, false);
	if (ret < 0)
		return ret;

@@ -421,6 +442,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, MAX77843_MUIC_CONTROL1_SW_USB,
				     attached, attached);
	if (ret < 0)
		return ret;

	extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached);
	extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached);
	extcon_set_state_sync(info->edev, EXTCON_DOCK, attached);

	return 0;
}

static int max77843_muic_adc_handler(struct max77843_muic_info *info)
{
	int ret, cable_type;
@@ -435,6 +476,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:
		ret = max77843_muic_adc_gnd_handler(info);
		if (ret < 0)
@@ -462,7 +508,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_4:
	case MAX77843_MUIC_ADC_RESERVED_ACC_5:
	case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2:
@@ -506,7 +551,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
	case MAX77843_MUIC_CHG_USB:
		ret = max77843_muic_set_path(info,
					     MAX77843_MUIC_CONTROL1_SW_USB,
					     attached);
					     attached, false);
		if (ret < 0)
			return ret;

@@ -517,7 +562,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
	case MAX77843_MUIC_CHG_DOWNSTREAM:
		ret = max77843_muic_set_path(info,
					     MAX77843_MUIC_CONTROL1_SW_OPEN,
					     attached);
					     attached, false);
		if (ret < 0)
			return ret;

@@ -527,7 +572,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
	case MAX77843_MUIC_CHG_DEDICATED:
		ret = max77843_muic_set_path(info,
					     MAX77843_MUIC_CONTROL1_SW_OPEN,
					     attached);
					     attached, false);
		if (ret < 0)
			return ret;

@@ -537,7 +582,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
	case MAX77843_MUIC_CHG_SPECIAL_500MA:
		ret = max77843_muic_set_path(info,
					     MAX77843_MUIC_CONTROL1_SW_OPEN,
					     attached);
					     attached, false);
		if (ret < 0)
			return ret;

@@ -547,7 +592,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
	case MAX77843_MUIC_CHG_SPECIAL_1A:
		ret = max77843_muic_set_path(info,
					     MAX77843_MUIC_CONTROL1_SW_OPEN,
					     attached);
					     attached, false);
		if (ret < 0)
			return ret;

@@ -566,6 +611,9 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
			extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,
						false);
		break;
	case MAX77843_MUIC_CHG_DOCK:
		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, attached);
		break;
	case MAX77843_MUIC_CHG_NONE:
		break;
	default:
@@ -574,7 +622,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
			attached ? "attached" : "detached", chg_type);

		max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_OPEN,
				       attached);
				       attached, false);
		return -EINVAL;
	}

@@ -814,7 +862,8 @@ 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, MAX77843_MUIC_CONTROL1_SW_UART, true);
	max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_UART, true,
			       false);

	/* Check revision number of MUIC device */
	ret = regmap_read(max77843->regmap_muic, MAX77843_MUIC_REG_ID, &id);
+2 −0
Original line number Diff line number Diff line
@@ -350,6 +350,7 @@ enum max77843_irq_muic {
/* MAX77843 CONTROL register */
#define MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT	0
#define MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT	3
#define MAX77843_MUIC_CONTROL1_NOBCCOMP_SHIFT	6
#define MAX77843_MUIC_CONTROL1_IDBEN_SHIFT	7
#define MAX77843_MUIC_CONTROL2_LOWPWR_SHIFT	0
#define MAX77843_MUIC_CONTROL2_ADCEN_SHIFT	1
@@ -366,6 +367,7 @@ enum max77843_irq_muic {
#define MAX77843_MUIC_CONTROL1_COMP1SW_MASK	(0x7 << MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT)
#define MAX77843_MUIC_CONTROL1_COMP2SW_MASK	(0x7 << MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT)
#define MAX77843_MUIC_CONTROL1_IDBEN_MASK	BIT(MAX77843_MUIC_CONTROL1_IDBEN_SHIFT)
#define MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK	BIT(MAX77843_MUIC_CONTROL1_NOBCCOMP_SHIFT)
#define MAX77843_MUIC_CONTROL2_LOWPWR_MASK	BIT(MAX77843_MUIC_CONTROL2_LOWPWR_SHIFT)
#define MAX77843_MUIC_CONTROL2_ADCEN_MASK	BIT(MAX77843_MUIC_CONTROL2_ADCEN_SHIFT)
#define MAX77843_MUIC_CONTROL2_CPEN_MASK	BIT(MAX77843_MUIC_CONTROL2_CPEN_SHIFT)