diff options
-rw-r--r-- | drivers/power/supply/bq24190_charger.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index dcbfd97a55be..aa1a589eb9f2 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -163,6 +163,8 @@ struct bq24190_dev_info { char model_name[I2C_NAME_SIZE]; bool initialized; bool irq_event; + bool otg_vbus_enabled; + int charge_type; u16 sys_min; u16 iprechg; u16 iterm; @@ -176,6 +178,9 @@ struct bq24190_dev_info { u8 watchdog; }; +static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi, + const union power_supply_propval *val); + static const unsigned int bq24190_usb_extcon_cable[] = { EXTCON_USB, EXTCON_NONE, @@ -502,8 +507,9 @@ static ssize_t bq24190_sysfs_store(struct device *dev, } #endif -static int bq24190_set_charge_mode(struct bq24190_dev_info *bdi, u8 val) +static int bq24190_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable) { + union power_supply_propval val = { .intval = bdi->charge_type }; int ret; ret = pm_runtime_get_sync(bdi->dev); @@ -513,9 +519,14 @@ static int bq24190_set_charge_mode(struct bq24190_dev_info *bdi, u8 val) return ret; } - ret = bq24190_write_mask(bdi, BQ24190_REG_POC, - BQ24190_REG_POC_CHG_CONFIG_MASK, - BQ24190_REG_POC_CHG_CONFIG_SHIFT, val); + bdi->otg_vbus_enabled = enable; + if (enable) + ret = bq24190_write_mask(bdi, BQ24190_REG_POC, + BQ24190_REG_POC_CHG_CONFIG_MASK, + BQ24190_REG_POC_CHG_CONFIG_SHIFT, + BQ24190_REG_POC_CHG_CONFIG_OTG); + else + ret = bq24190_charger_set_charge_type(bdi, &val); pm_runtime_mark_last_busy(bdi->dev); pm_runtime_put_autosuspend(bdi->dev); @@ -526,14 +537,12 @@ static int bq24190_set_charge_mode(struct bq24190_dev_info *bdi, u8 val) #ifdef CONFIG_REGULATOR static int bq24190_vbus_enable(struct regulator_dev *dev) { - return bq24190_set_charge_mode(rdev_get_drvdata(dev), - BQ24190_REG_POC_CHG_CONFIG_OTG); + return bq24190_set_otg_vbus(rdev_get_drvdata(dev), true); } static int bq24190_vbus_disable(struct regulator_dev *dev) { - return bq24190_set_charge_mode(rdev_get_drvdata(dev), - BQ24190_REG_POC_CHG_CONFIG_CHARGE); + return bq24190_set_otg_vbus(rdev_get_drvdata(dev), false); } static int bq24190_vbus_is_enabled(struct regulator_dev *dev) @@ -559,8 +568,9 @@ static int bq24190_vbus_is_enabled(struct regulator_dev *dev) if (ret) return ret; - return (val == BQ24190_REG_POC_CHG_CONFIG_OTG || - val == BQ24190_REG_POC_CHG_CONFIG_OTG_ALT); + bdi->otg_vbus_enabled = (val == BQ24190_REG_POC_CHG_CONFIG_OTG || + val == BQ24190_REG_POC_CHG_CONFIG_OTG_ALT); + return bdi->otg_vbus_enabled; } static const struct regulator_ops bq24190_vbus_ops = { @@ -807,6 +817,14 @@ static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi, return -EINVAL; } + bdi->charge_type = val->intval; + /* + * If the 5V Vbus boost regulator is enabled delay setting + * the charge-type until its gets disabled. + */ + if (bdi->otg_vbus_enabled) + return 0; + if (chg_config) { /* Enabling the charger */ ret = bq24190_write_mask(bdi, BQ24190_REG_CCC, BQ24190_REG_CCC_FORCE_20PCT_MASK, @@ -1788,6 +1806,7 @@ static int bq24190_probe(struct i2c_client *client, bdi->dev = dev; strncpy(bdi->model_name, id->name, I2C_NAME_SIZE); mutex_init(&bdi->f_reg_lock); + bdi->charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST; bdi->f_reg = 0; bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ INIT_DELAYED_WORK(&bdi->input_current_limit_work, @@ -1925,7 +1944,7 @@ static void bq24190_shutdown(struct i2c_client *client) struct bq24190_dev_info *bdi = i2c_get_clientdata(client); /* Turn off 5V boost regulator on shutdown */ - bq24190_set_charge_mode(bdi, BQ24190_REG_POC_CHG_CONFIG_CHARGE); + bq24190_set_otg_vbus(bdi, false); } static __maybe_unused int bq24190_runtime_suspend(struct device *dev) |