power: supply: bq256xx: Support to disable charger
Commit Message
To be able to control the charging process flexible, we need to able to
disable the charger. This commit will allow to disable the charger by
"echo 1 > /sys/class/power_supply/bq256xx-charger/charge_type"
(1 = POWER_SUPPLY_CHARGE_TYPE_NONE) and enable the charger by set it to
2/3 (POWER_SUPPLY_CHARGE_TYPE_TRICKLE/POWER_SUPPLY_CHARGE_TYPE_FAST)
Signed-off-by: Hermes Zhang <chenhuiz@axis.com>
---
drivers/power/supply/bq256xx_charger.c | 40 ++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
Comments
Hi,
On Thu, Mar 09, 2023 at 02:41:03PM +0800, Hermes Zhang wrote:
> To be able to control the charging process flexible, we need to able to
> disable the charger. This commit will allow to disable the charger by
> "echo 1 > /sys/class/power_supply/bq256xx-charger/charge_type"
> (1 = POWER_SUPPLY_CHARGE_TYPE_NONE) and enable the charger by set it to
> 2/3 (POWER_SUPPLY_CHARGE_TYPE_TRICKLE/POWER_SUPPLY_CHARGE_TYPE_FAST)
>
> Signed-off-by: Hermes Zhang <chenhuiz@axis.com>
> ---
Thanks, queued.
-- Sebastian
> drivers/power/supply/bq256xx_charger.c | 40 ++++++++++++++++++++++++++
> 1 file changed, 40 insertions(+)
>
> diff --git a/drivers/power/supply/bq256xx_charger.c b/drivers/power/supply/bq256xx_charger.c
> index 9cf4936440c9..e624834ae66c 100644
> --- a/drivers/power/supply/bq256xx_charger.c
> +++ b/drivers/power/supply/bq256xx_charger.c
> @@ -70,6 +70,9 @@
> #define BQ25611D_VBATREG_THRESH_uV 4290000
> #define BQ25618_VBATREG_THRESH_uV 4300000
>
> +#define BQ256XX_CHG_CONFIG_MASK BIT(4)
> +#define BQ256XX_CHG_CONFIG_BIT_SHIFT 4
> +
> #define BQ256XX_ITERM_MASK GENMASK(3, 0)
> #define BQ256XX_ITERM_STEP_uA 60000
> #define BQ256XX_ITERM_OFFSET_uA 60000
> @@ -259,6 +262,7 @@ struct bq256xx_device {
> * @bq256xx_set_iterm: pointer to instance specific set_iterm function
> * @bq256xx_set_iprechg: pointer to instance specific set_iprechg function
> * @bq256xx_set_vindpm: pointer to instance specific set_vindpm function
> + * @bq256xx_set_charge_type: pointer to instance specific set_charge_type function
> *
> * @bq256xx_def_ichg: default ichg value in microamps
> * @bq256xx_def_iindpm: default iindpm value in microamps
> @@ -290,6 +294,7 @@ struct bq256xx_chip_info {
> int (*bq256xx_set_iterm)(struct bq256xx_device *bq, int iterm);
> int (*bq256xx_set_iprechg)(struct bq256xx_device *bq, int iprechg);
> int (*bq256xx_set_vindpm)(struct bq256xx_device *bq, int vindpm);
> + int (*bq256xx_set_charge_type)(struct bq256xx_device *bq, int type);
>
> int bq256xx_def_ichg;
> int bq256xx_def_iindpm;
> @@ -449,6 +454,27 @@ static int bq256xx_get_state(struct bq256xx_device *bq,
> return 0;
> }
>
> +static int bq256xx_set_charge_type(struct bq256xx_device *bq, int type)
> +{
> + int chg_config = 0;
> +
> + switch (type) {
> + case POWER_SUPPLY_CHARGE_TYPE_NONE:
> + chg_config = 0x0;
> + break;
> + case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
> + case POWER_SUPPLY_CHARGE_TYPE_FAST:
> + chg_config = 0x1;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + return regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_0,
> + BQ256XX_CHG_CONFIG_MASK,
> + (chg_config ? 1 : 0) << BQ256XX_CHG_CONFIG_BIT_SHIFT);
> +}
> +
> static int bq256xx_get_ichg_curr(struct bq256xx_device *bq)
> {
> unsigned int charge_current_limit;
> @@ -915,6 +941,12 @@ static int bq256xx_set_charger_property(struct power_supply *psy,
> return ret;
> break;
>
> + case POWER_SUPPLY_PROP_CHARGE_TYPE:
> + ret = bq->chip_info->bq256xx_set_charge_type(bq, val->intval);
> + if (ret)
> + return ret;
> + break;
> +
> default:
> break;
> }
> @@ -1197,6 +1229,7 @@ static int bq256xx_property_is_writeable(struct power_supply *psy,
> case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
> case POWER_SUPPLY_PROP_STATUS:
> case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
> + case POWER_SUPPLY_PROP_CHARGE_TYPE:
> return true;
> default:
> return false;
> @@ -1286,6 +1319,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
> .bq256xx_set_iterm = bq256xx_set_term_curr,
> .bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
> .bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
> + .bq256xx_set_charge_type = bq256xx_set_charge_type,
>
> .bq256xx_def_ichg = BQ2560X_ICHG_DEF_uA,
> .bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
> @@ -1316,6 +1350,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
> .bq256xx_set_iterm = bq256xx_set_term_curr,
> .bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
> .bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
> + .bq256xx_set_charge_type = bq256xx_set_charge_type,
>
> .bq256xx_def_ichg = BQ2560X_ICHG_DEF_uA,
> .bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
> @@ -1346,6 +1381,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
> .bq256xx_set_iterm = bq256xx_set_term_curr,
> .bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
> .bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
> + .bq256xx_set_charge_type = bq256xx_set_charge_type,
>
> .bq256xx_def_ichg = BQ2560X_ICHG_DEF_uA,
> .bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
> @@ -1376,6 +1412,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
> .bq256xx_set_iterm = bq256xx_set_term_curr,
> .bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
> .bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
> + .bq256xx_set_charge_type = bq256xx_set_charge_type,
>
> .bq256xx_def_ichg = BQ2560X_ICHG_DEF_uA,
> .bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
> @@ -1406,6 +1443,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
> .bq256xx_set_iterm = bq256xx_set_term_curr,
> .bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
> .bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
> + .bq256xx_set_charge_type = bq256xx_set_charge_type,
>
> .bq256xx_def_ichg = BQ25611D_ICHG_DEF_uA,
> .bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
> @@ -1436,6 +1474,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
> .bq256xx_set_iterm = bq25618_619_set_term_curr,
> .bq256xx_set_iprechg = bq25618_619_set_prechrg_curr,
> .bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
> + .bq256xx_set_charge_type = bq256xx_set_charge_type,
>
> .bq256xx_def_ichg = BQ25618_ICHG_DEF_uA,
> .bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
> @@ -1466,6 +1505,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
> .bq256xx_set_iterm = bq25618_619_set_term_curr,
> .bq256xx_set_iprechg = bq25618_619_set_prechrg_curr,
> .bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
> + .bq256xx_set_charge_type = bq256xx_set_charge_type,
>
> .bq256xx_def_ichg = BQ25618_ICHG_DEF_uA,
> .bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
> --
> 2.30.2
>
Sebastian Reichel <sebastian.reichel@collabora.com> 于2023年3月13日周一 06:31写道:
>
> Hi,
>
> On Sun, Mar 12, 2023 at 01:46:50AM +0800, Zheng Wang wrote:
> > In da9150_charger_probe, &charger->otg_work is bound with
> > da9150_charger_otg_work. da9150_charger_otg_ncb may be
> > called to start the work.
> >
> > If we remove the module which will call da9150_charger_remove
> > to make cleanup, there may be a unfinished work. The possible
> > sequence is as follows:
> >
> > Fix it by canceling the work before cleanup in the da9150_charger_remove
> >
> > CPU0 CPUc1
> >
> > |da9150_charger_otg_work
> > da9150_charger_remove |
> > power_supply_unregister |
> > device_unregister |
> > power_supply_dev_release|
> > kfree(psy) |
> > |
> > | power_supply_changed(charger->usb);
> > | //use
> >
> > Fixes: c1a281e34dae ("power: Add support for DA9150 Charger")
> > Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
> > ---
> > v2:
> > - fix wrong description in commit message and mov cancel_work_sync
> > after usb_unregister_notifier suggested by Sebastian Reichel
> > ---
>
> Thanks, queued to power-supply's fixes branch. Please make sure you
> send your patches to the correct destination next time (linux-scsi
> should be linux-pm).
Thanks for your effort. I'll keep that in mind :)
Best regards,
Zheng
>
> > drivers/power/supply/da9150-charger.c | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/power/supply/da9150-charger.c b/drivers/power/supply/da9150-charger.c
> > index 14da5c595dd9..a87aeaea38e1 100644
> > --- a/drivers/power/supply/da9150-charger.c
> > +++ b/drivers/power/supply/da9150-charger.c
> > @@ -657,6 +657,7 @@ static int da9150_charger_remove(struct platform_device *pdev)
> >
> > if (!IS_ERR_OR_NULL(charger->usb_phy))
> > usb_unregister_notifier(charger->usb_phy, &charger->otg_nb);
> > + cancel_work_sync(&charger->otg_work);
> >
> > power_supply_unregister(charger->battery);
> > power_supply_unregister(charger->usb);
> > --
> > 2.25.1
> >
@@ -70,6 +70,9 @@
#define BQ25611D_VBATREG_THRESH_uV 4290000
#define BQ25618_VBATREG_THRESH_uV 4300000
+#define BQ256XX_CHG_CONFIG_MASK BIT(4)
+#define BQ256XX_CHG_CONFIG_BIT_SHIFT 4
+
#define BQ256XX_ITERM_MASK GENMASK(3, 0)
#define BQ256XX_ITERM_STEP_uA 60000
#define BQ256XX_ITERM_OFFSET_uA 60000
@@ -259,6 +262,7 @@ struct bq256xx_device {
* @bq256xx_set_iterm: pointer to instance specific set_iterm function
* @bq256xx_set_iprechg: pointer to instance specific set_iprechg function
* @bq256xx_set_vindpm: pointer to instance specific set_vindpm function
+ * @bq256xx_set_charge_type: pointer to instance specific set_charge_type function
*
* @bq256xx_def_ichg: default ichg value in microamps
* @bq256xx_def_iindpm: default iindpm value in microamps
@@ -290,6 +294,7 @@ struct bq256xx_chip_info {
int (*bq256xx_set_iterm)(struct bq256xx_device *bq, int iterm);
int (*bq256xx_set_iprechg)(struct bq256xx_device *bq, int iprechg);
int (*bq256xx_set_vindpm)(struct bq256xx_device *bq, int vindpm);
+ int (*bq256xx_set_charge_type)(struct bq256xx_device *bq, int type);
int bq256xx_def_ichg;
int bq256xx_def_iindpm;
@@ -449,6 +454,27 @@ static int bq256xx_get_state(struct bq256xx_device *bq,
return 0;
}
+static int bq256xx_set_charge_type(struct bq256xx_device *bq, int type)
+{
+ int chg_config = 0;
+
+ switch (type) {
+ case POWER_SUPPLY_CHARGE_TYPE_NONE:
+ chg_config = 0x0;
+ break;
+ case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
+ case POWER_SUPPLY_CHARGE_TYPE_FAST:
+ chg_config = 0x1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_0,
+ BQ256XX_CHG_CONFIG_MASK,
+ (chg_config ? 1 : 0) << BQ256XX_CHG_CONFIG_BIT_SHIFT);
+}
+
static int bq256xx_get_ichg_curr(struct bq256xx_device *bq)
{
unsigned int charge_current_limit;
@@ -915,6 +941,12 @@ static int bq256xx_set_charger_property(struct power_supply *psy,
return ret;
break;
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ ret = bq->chip_info->bq256xx_set_charge_type(bq, val->intval);
+ if (ret)
+ return ret;
+ break;
+
default:
break;
}
@@ -1197,6 +1229,7 @@ static int bq256xx_property_is_writeable(struct power_supply *psy,
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
case POWER_SUPPLY_PROP_STATUS:
case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
return true;
default:
return false;
@@ -1286,6 +1319,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
.bq256xx_set_iterm = bq256xx_set_term_curr,
.bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
.bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
+ .bq256xx_set_charge_type = bq256xx_set_charge_type,
.bq256xx_def_ichg = BQ2560X_ICHG_DEF_uA,
.bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
@@ -1316,6 +1350,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
.bq256xx_set_iterm = bq256xx_set_term_curr,
.bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
.bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
+ .bq256xx_set_charge_type = bq256xx_set_charge_type,
.bq256xx_def_ichg = BQ2560X_ICHG_DEF_uA,
.bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
@@ -1346,6 +1381,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
.bq256xx_set_iterm = bq256xx_set_term_curr,
.bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
.bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
+ .bq256xx_set_charge_type = bq256xx_set_charge_type,
.bq256xx_def_ichg = BQ2560X_ICHG_DEF_uA,
.bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
@@ -1376,6 +1412,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
.bq256xx_set_iterm = bq256xx_set_term_curr,
.bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
.bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
+ .bq256xx_set_charge_type = bq256xx_set_charge_type,
.bq256xx_def_ichg = BQ2560X_ICHG_DEF_uA,
.bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
@@ -1406,6 +1443,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
.bq256xx_set_iterm = bq256xx_set_term_curr,
.bq256xx_set_iprechg = bq256xx_set_prechrg_curr,
.bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
+ .bq256xx_set_charge_type = bq256xx_set_charge_type,
.bq256xx_def_ichg = BQ25611D_ICHG_DEF_uA,
.bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
@@ -1436,6 +1474,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
.bq256xx_set_iterm = bq25618_619_set_term_curr,
.bq256xx_set_iprechg = bq25618_619_set_prechrg_curr,
.bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
+ .bq256xx_set_charge_type = bq256xx_set_charge_type,
.bq256xx_def_ichg = BQ25618_ICHG_DEF_uA,
.bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,
@@ -1466,6 +1505,7 @@ static const struct bq256xx_chip_info bq256xx_chip_info_tbl[] = {
.bq256xx_set_iterm = bq25618_619_set_term_curr,
.bq256xx_set_iprechg = bq25618_619_set_prechrg_curr,
.bq256xx_set_vindpm = bq256xx_set_input_volt_lim,
+ .bq256xx_set_charge_type = bq256xx_set_charge_type,
.bq256xx_def_ichg = BQ25618_ICHG_DEF_uA,
.bq256xx_def_iindpm = BQ256XX_IINDPM_DEF_uA,