From 412e4e172ec55b996f1ace1ff25bd3929af6eb56 Mon Sep 17 00:00:00 2001 From: Aaron Kling Date: Tue, 10 Jun 2025 02:45:03 -0500 Subject: [PATCH] power: supply: bq24190_charger: Support usb role switching Change-Id: Ia1e650f15ae55bb0972612b378d093a20d8a8a98 --- drivers/power/supply/bq24190_charger.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index a663c37db03a..968da287443a 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -17,6 +17,7 @@ #include #include #include +#include #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)