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/workqueue.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/extcon-provider.h>
|
#include <linux/extcon-provider.h>
|
||||||
|
#include <linux/usb/role.h>
|
||||||
|
|
||||||
#define BQ24190_MANUFACTURER "Texas Instruments"
|
#define BQ24190_MANUFACTURER "Texas Instruments"
|
||||||
|
|
||||||
@@ -242,6 +243,7 @@ struct bq24190_dev_info {
|
|||||||
u8 ss_reg;
|
u8 ss_reg;
|
||||||
u8 watchdog;
|
u8 watchdog;
|
||||||
const struct bq24190_chip_info *info;
|
const struct bq24190_chip_info *info;
|
||||||
|
struct usb_role_switch *role_sw;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bq24190_chip_info {
|
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)
|
static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
|
||||||
{
|
{
|
||||||
bool otg_enabled;
|
bool otg_enabled;
|
||||||
|
enum usb_role usb_role;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
otg_enabled = !!(ss_reg & BQ24190_REG_SS_VBUS_STAT_MASK);
|
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",
|
dev_err(bdi->dev, "Can't set extcon state to %d: %d\n",
|
||||||
otg_enabled, ret);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2128,6 +2136,7 @@ static int bq24190_probe(struct i2c_client *client)
|
|||||||
struct device *dev = &client->dev;
|
struct device *dev = &client->dev;
|
||||||
struct power_supply_config charger_cfg = {}, battery_cfg = {};
|
struct power_supply_config charger_cfg = {}, battery_cfg = {};
|
||||||
struct bq24190_dev_info *bdi;
|
struct bq24190_dev_info *bdi;
|
||||||
|
struct fwnode_handle *connector;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
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_enable(dev);
|
||||||
pm_runtime_use_autosuspend(dev);
|
pm_runtime_use_autosuspend(dev);
|
||||||
pm_runtime_set_autosuspend_delay(dev, 600);
|
pm_runtime_set_autosuspend_delay(dev, 600);
|
||||||
@@ -2257,6 +2276,10 @@ out_pmrt:
|
|||||||
pm_runtime_put_sync(dev);
|
pm_runtime_put_sync(dev);
|
||||||
pm_runtime_dont_use_autosuspend(dev);
|
pm_runtime_dont_use_autosuspend(dev);
|
||||||
pm_runtime_disable(dev);
|
pm_runtime_disable(dev);
|
||||||
|
|
||||||
|
out_put:
|
||||||
|
if (connector)
|
||||||
|
fwnode_handle_put(connector);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2265,6 +2288,9 @@ static void bq24190_remove(struct i2c_client *client)
|
|||||||
struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
|
struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
if (bdi->role_sw)
|
||||||
|
usb_role_switch_put(bdi->role_sw);
|
||||||
|
|
||||||
cancel_delayed_work_sync(&bdi->input_current_limit_work);
|
cancel_delayed_work_sync(&bdi->input_current_limit_work);
|
||||||
error = pm_runtime_resume_and_get(bdi->dev);
|
error = pm_runtime_resume_and_get(bdi->dev);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user