Skip to content

Commit

Permalink
extcon: intel-cht-wc: Enable external charger
Browse files Browse the repository at this point in the history
In some configuration external charger "#charge enable" signal is
connected to PMIC. Enable it at device probing to allow charging.

Save CHGRCTRL0 and CHGDISCTR registers at driver probing and restore
them at driver unbind to re-enable hardware charging control if it was
enabled before.

Tested at Lenovo Yoga Book (YB1-X91L).

Signed-off-by: Yauhen Kharuzhy <[email protected]>
Reviewed-by: Andy Shevchenko <[email protected]>
Reviewed-by: Hans de Goede <[email protected]>
Tested-by: Hans de Goede <[email protected]>
Signed-off-by: Chanwoo Choi <[email protected]>
  • Loading branch information
jekhor authored and andy-shev committed May 17, 2019
1 parent 346949a commit 65138fd
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion drivers/extcon/extcon-intel-cht-wc.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@
#define CHT_WC_USBSRC_TYPE_OTHER 8
#define CHT_WC_USBSRC_TYPE_DCP_EXTPHY 9

#define CHT_WC_CHGDISCTRL 0x5e2f
#define CHT_WC_CHGDISCTRL_OUT BIT(0)
/* 0 - open drain, 1 - regular push-pull output */
#define CHT_WC_CHGDISCTRL_DRV BIT(4)
/* 0 - pin is controlled by SW, 1 - by HW */
#define CHT_WC_CHGDISCTRL_FN BIT(6)

#define CHT_WC_PWRSRC_IRQ 0x6e03
#define CHT_WC_PWRSRC_IRQ_MASK 0x6e0f
#define CHT_WC_PWRSRC_STS 0x6e1e
Expand Down Expand Up @@ -218,6 +225,18 @@ static void cht_wc_extcon_set_otgmode(struct cht_wc_extcon_data *ext,
dev_err(ext->dev, "Error updating CHGRCTRL1 reg: %d\n", ret);
}

static void cht_wc_extcon_enable_charging(struct cht_wc_extcon_data *ext,
bool enable)
{
unsigned int val = enable ? 0 : CHT_WC_CHGDISCTRL_OUT;
int ret;

ret = regmap_update_bits(ext->regmap, CHT_WC_CHGDISCTRL,
CHT_WC_CHGDISCTRL_OUT, val);
if (ret)
dev_err(ext->dev, "Error updating CHGDISCTRL reg: %d\n", ret);
}

/* Small helper to sync EXTCON_CHG_USB_SDP and EXTCON_USB state */
static void cht_wc_extcon_set_state(struct cht_wc_extcon_data *ext,
unsigned int cable, bool state)
Expand All @@ -242,13 +261,15 @@ static void cht_wc_extcon_pwrsrc_event(struct cht_wc_extcon_data *ext)

id = cht_wc_extcon_get_id(ext, pwrsrc_sts);
if (id == USB_ID_GND) {
cht_wc_extcon_enable_charging(ext, false);
cht_wc_extcon_set_otgmode(ext, true);

/* The 5v boost causes a false VBUS / SDP detect, skip */
goto charger_det_done;
}

cht_wc_extcon_set_otgmode(ext, false);
cht_wc_extcon_enable_charging(ext, true);

/* Plugged into a host/charger or not connected? */
if (!(pwrsrc_sts & CHT_WC_PWRSRC_VBUS)) {
Expand Down Expand Up @@ -302,6 +323,14 @@ static int cht_wc_extcon_sw_control(struct cht_wc_extcon_data *ext, bool enable)
{
int ret, mask, val;

val = enable ? 0 : CHT_WC_CHGDISCTRL_FN;
ret = regmap_update_bits(ext->regmap, CHT_WC_CHGDISCTRL,
CHT_WC_CHGDISCTRL_FN, val);
if (ret)
dev_err(ext->dev,
"Error setting sw control for CHGDIS pin: %d\n",
ret);

mask = CHT_WC_CHGRCTRL0_SWCONTROL | CHT_WC_CHGRCTRL0_CCSM_OFF;
val = enable ? mask : 0;
ret = regmap_update_bits(ext->regmap, CHT_WC_CHGRCTRL0, mask, val);
Expand Down Expand Up @@ -353,7 +382,10 @@ static int cht_wc_extcon_probe(struct platform_device *pdev)
/* Enable sw control */
ret = cht_wc_extcon_sw_control(ext, true);
if (ret)
return ret;
goto disable_sw_control;

/* Disable charging by external battery charger */
cht_wc_extcon_enable_charging(ext, false);

/* Register extcon device */
ret = devm_extcon_dev_register(ext->dev, ext->edev);
Expand Down

0 comments on commit 65138fd

Please sign in to comment.