Merge branch 'master' into topic/rg/cc100_dali
This commit is contained in:
commit
6f507e81b6
@ -37,6 +37,12 @@ properties:
|
||||
GPIO pin (output) used to control VBUS. If skipped, no such control
|
||||
takes place.
|
||||
|
||||
vbus-supply:
|
||||
maxItems: 1
|
||||
description:
|
||||
VBUS regulator used to control VBUS. If skipped, no such control
|
||||
takes place.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- interrupts
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include <linux/extcon-provider.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/usb/role.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
/* PTN5150 registers */
|
||||
#define PTN5150_REG_DEVICE_ID 0x01
|
||||
@ -54,6 +55,7 @@ struct ptn5150_info {
|
||||
struct work_struct irq_work;
|
||||
struct mutex mutex;
|
||||
struct usb_role_switch *role_sw;
|
||||
struct regulator *vbus_reg;
|
||||
};
|
||||
|
||||
/* List of detectable cables */
|
||||
@ -69,10 +71,43 @@ static const struct regmap_config ptn5150_regmap_config = {
|
||||
.max_register = PTN5150_REG_END,
|
||||
};
|
||||
|
||||
static void ptn5150_vbus_off(struct ptn5150_info *info)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
gpiod_set_value_cansleep(info->vbus_gpiod, 0);
|
||||
if (info->vbus_reg) {
|
||||
dev_info(info->dev, "Disable VBUS regulator\n");
|
||||
|
||||
if (regulator_is_enabled(info->vbus_reg))
|
||||
ret = regulator_disable(info->vbus_reg);
|
||||
|
||||
if (ret)
|
||||
dev_err(info->dev, "VBUS regulator disable failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void ptn5150_vbus_on(struct ptn5150_info *info)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
gpiod_set_value_cansleep(info->vbus_gpiod, 1);
|
||||
if (info->vbus_reg) {
|
||||
dev_info(info->dev, "Enable VBUS regulator\n");
|
||||
|
||||
if (!regulator_is_enabled(info->vbus_reg))
|
||||
ret = regulator_enable(info->vbus_reg);
|
||||
|
||||
if (ret)
|
||||
dev_err(info->dev, "VBUS regulator enable failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void ptn5150_check_state(struct ptn5150_info *info)
|
||||
{
|
||||
unsigned int port_status, reg_data, vbus;
|
||||
enum usb_role usb_role = USB_ROLE_NONE;
|
||||
bool vbus_reg_enable = false;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(info->regmap, PTN5150_REG_CC_STATUS, ®_data);
|
||||
@ -86,17 +121,14 @@ static void ptn5150_check_state(struct ptn5150_info *info)
|
||||
switch (port_status) {
|
||||
case PTN5150_DFP_ATTACHED:
|
||||
extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false);
|
||||
gpiod_set_value_cansleep(info->vbus_gpiod, 0);
|
||||
extcon_set_state_sync(info->edev, EXTCON_USB, true);
|
||||
usb_role = USB_ROLE_DEVICE;
|
||||
break;
|
||||
case PTN5150_UFP_ATTACHED:
|
||||
extcon_set_state_sync(info->edev, EXTCON_USB, false);
|
||||
vbus = FIELD_GET(PTN5150_REG_CC_VBUS_DETECTION, reg_data);
|
||||
if (vbus)
|
||||
gpiod_set_value_cansleep(info->vbus_gpiod, 0);
|
||||
else
|
||||
gpiod_set_value_cansleep(info->vbus_gpiod, 1);
|
||||
if (!vbus)
|
||||
vbus_reg_enable = true;
|
||||
|
||||
extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true);
|
||||
usb_role = USB_ROLE_HOST;
|
||||
@ -105,6 +137,11 @@ static void ptn5150_check_state(struct ptn5150_info *info)
|
||||
break;
|
||||
}
|
||||
|
||||
if (vbus_reg_enable)
|
||||
ptn5150_vbus_on(info);
|
||||
else
|
||||
ptn5150_vbus_off(info);
|
||||
|
||||
if (usb_role) {
|
||||
ret = usb_role_switch_set_role(info->role_sw, usb_role);
|
||||
if (ret)
|
||||
@ -144,7 +181,7 @@ static void ptn5150_irq_work(struct work_struct *work)
|
||||
EXTCON_USB_HOST, false);
|
||||
extcon_set_state_sync(info->edev,
|
||||
EXTCON_USB, false);
|
||||
gpiod_set_value_cansleep(info->vbus_gpiod, 0);
|
||||
ptn5150_vbus_off(info);
|
||||
|
||||
ret = usb_role_switch_set_role(info->role_sw,
|
||||
USB_ROLE_NONE);
|
||||
@ -249,6 +286,19 @@ static int ptn5150_i2c_probe(struct i2c_client *i2c)
|
||||
}
|
||||
}
|
||||
|
||||
info->vbus_reg = NULL;
|
||||
if (of_find_property(np, "vbus-supply", NULL)) {
|
||||
struct regulator *vbus_reg;
|
||||
|
||||
vbus_reg = devm_regulator_get_exclusive(dev, "vbus");
|
||||
if (IS_ERR_OR_NULL(vbus_reg)) {
|
||||
return dev_err_probe(dev, PTR_ERR(vbus_reg),
|
||||
"Couldn't get the VBUS power regulator.\n");
|
||||
}
|
||||
|
||||
info->vbus_reg = vbus_reg;
|
||||
}
|
||||
|
||||
mutex_init(&info->mutex);
|
||||
|
||||
INIT_WORK(&info->irq_work, ptn5150_irq_work);
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 612ac8d4a9ce7b359342c6e89f5d08a1b02a1b87
|
||||
Subproject commit 017c12dae556738cc3124ae65b64a80bbf70af6d
|
||||
Loading…
Reference in New Issue
Block a user