power: supply: bq24190_charger: Support usb role switching
Change-Id: Ia1e650f15ae55bb0972612b378d093a20d8a8a98
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/extcon-provider.h>
|
||||
#include <linux/usb/role.h>
|
||||
|
||||
#define BQ24190_MANUFACTURER "Texas Instruments"
|
||||
|
||||
@@ -242,6 +243,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 {
|
||||
@@ -1823,6 +1825,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);
|
||||
@@ -1831,6 +1834,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;
|
||||
}
|
||||
|
||||
@@ -2128,6 +2136,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 *connector;
|
||||
int ret;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||
@@ -2167,6 +2176,16 @@ static int bq24190_probe(struct i2c_client *client)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* The usb connector is optional */
|
||||
connector = device_get_named_child_node(dev, "connector");
|
||||
if (connector) {
|
||||
bdi->role_sw = fwnode_usb_role_switch_get(connector);
|
||||
if (IS_ERR(bdi->role_sw)) {
|
||||
ret = PTR_ERR(bdi->role_sw);
|
||||
goto out_put;
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_set_autosuspend_delay(dev, 600);
|
||||
@@ -2257,6 +2276,10 @@ out_pmrt:
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_dont_use_autosuspend(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
out_put:
|
||||
if (connector)
|
||||
fwnode_handle_put(connector);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2265,6 +2288,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);
|
||||
|
||||
cancel_delayed_work_sync(&bdi->input_current_limit_work);
|
||||
error = pm_runtime_resume_and_get(bdi->dev);
|
||||
if (error < 0)
|
||||
|
||||
Reference in New Issue
Block a user