power: supply: bq24190_charger: Support usb role switching
Change-Id: Ia1e650f15ae55bb0972612b378d093a20d8a8a98
This commit is contained in:
1 parent
98672e71bd
commit
59f8f7a811
1 file changed
+25
@@ -18,6 +18,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/extcon-provider.h>
|
||||
#include <linux/usb/role.h>
|
||||
|
||||
#define BQ24190_MANUFACTURER "Texas Instruments"
|
||||
|
||||
@@ -245,6 +246,7 @@ struct bq24190_dev_info {
|
||||
u8 ss_reg;
|
||||
u8 watchdog;
|
||||
const struct bq24190_chip_info *info;
|
||||
struct usb_role_switch *role_sw;
|
||||
};
|
||||
|
||||
struct bq24190_chip_info {
|
||||
@@ -1829,6 +1831,7 @@ static const struct power_supply_desc bq24190_battery_desc = {
|
||||
static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
|
||||
{
|
||||
bool otg_enabled;
|
||||
enum usb_role usb_role;
|
||||
int ret;
|
||||
|
||||
otg_enabled = !!(ss_reg & BQ24190_REG_SS_VBUS_STAT_MASK);
|
||||
@@ -1837,6 +1840,11 @@ static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
|
||||
dev_err(bdi->dev, "Can't set extcon state to %d: %d\n",
|
||||
otg_enabled, ret);
|
||||
|
||||
if (bdi->role_sw) {
|
||||
usb_role = otg_enabled ? USB_ROLE_DEVICE : USB_ROLE_NONE;
|
||||
usb_role_switch_set_role(bdi->role_sw, usb_role);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2147,6 +2155,7 @@ static int bq24190_probe(struct i2c_client *client)
|
||||
struct device *dev = &client->dev;
|
||||
struct power_supply_config charger_cfg = {}, battery_cfg = {};
|
||||
struct bq24190_dev_info *bdi;
|
||||
struct fwnode_handle *ep, *remote;
|
||||
int ret;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||
@@ -2189,6 +2198,19 @@ static int bq24190_probe(struct i2c_client *client)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Role switch is optional */
|
||||
ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
|
||||
if (ep) {
|
||||
remote = fwnode_graph_get_remote_endpoint(ep);
|
||||
if (remote) {
|
||||
bdi->role_sw = fwnode_usb_role_switch_get(remote);
|
||||
if (IS_ERR(bdi->role_sw)) {
|
||||
ret = PTR_ERR(bdi->role_sw);
|
||||
return dev_err_probe(dev, ret, "USB role switch handle not found\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_set_autosuspend_delay(dev, 600);
|
||||
@@ -2286,6 +2308,9 @@ static void bq24190_remove(struct i2c_client *client)
|
||||
struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
|
||||
int error;
|
||||
|
||||
if (bdi->role_sw)
|
||||
usb_role_switch_put(bdi->role_sw);
|
||||
|
||||
error = pm_runtime_resume_and_get(bdi->dev);
|
||||
if (error < 0)
|
||||
dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
|
||||
|
||||
Reference in new issue
Block a user