@@ -48,6 +48,7 @@
#include <linux/cleanup.h>
#include <linux/devm-helpers.h>
+#include <linux/gpio/consumer.h>
#include <linux/mutex.h>
#include <linux/power_supply.h>
#include <linux/workqueue.h>
@@ -77,8 +78,17 @@ static int adc_battery_helper_get_status(struct adc_battery_helper *help)
if (help->curr_ua < -CURR_HYST_UA)
return POWER_SUPPLY_STATUS_DISCHARGING;
- if (help->supplied && help->ocv_avg_uv > full_uv)
- return POWER_SUPPLY_STATUS_FULL;
+ if (help->supplied) {
+ bool full;
+
+ if (help->charge_finished)
+ full = gpiod_get_value_cansleep(help->charge_finished);
+ else
+ full = help->ocv_avg_uv > full_uv;
+
+ if (full)
+ return POWER_SUPPLY_STATUS_FULL;
+ }
return POWER_SUPPLY_STATUS_NOT_CHARGING;
}
@@ -310,13 +320,15 @@ static void adc_battery_helper_start_work(struct adc_battery_helper *help)
}
int adc_battery_helper_init(struct adc_battery_helper *help, struct power_supply *psy,
- adc_battery_helper_get_func get_voltage_and_current_now)
+ adc_battery_helper_get_func get_voltage_and_current_now,
+ struct gpio_desc *charge_finished_gpio)
{
struct device *dev = psy->dev.parent;
int ret;
help->psy = psy;
help->get_voltage_and_current_now = get_voltage_and_current_now;
+ help->charge_finished = charge_finished_gpio;
ret = devm_mutex_init(dev, &help->lock);
if (ret)
@@ -10,6 +10,7 @@
#define ADC_BAT_HELPER_MOV_AVG_WINDOW 8
struct power_supply;
+struct gpio_desc;
/*
* The adc battery helper code needs voltage- and current-now to be sampled as
@@ -20,6 +21,7 @@ typedef int (*adc_battery_helper_get_func)(struct power_supply *psy, int *volt,
struct adc_battery_helper {
struct power_supply *psy;
+ struct gpio_desc *charge_finished;
struct delayed_work work;
struct mutex lock;
adc_battery_helper_get_func get_voltage_and_current_now;
@@ -43,7 +45,8 @@ extern const enum power_supply_property adc_battery_helper_properties[];
#define ADC_HELPER_NUM_PROPERTIES 7
int adc_battery_helper_init(struct adc_battery_helper *help, struct power_supply *psy,
- adc_battery_helper_get_func get_voltage_and_current_now);
+ adc_battery_helper_get_func get_voltage_and_current_now,
+ struct gpio_desc *charge_finished_gpio);
/*
* The below functions can be directly used as power-supply / suspend-resume
* callbacks. They cast the power_supply_get_drvdata() / dev_get_drvdata() data
@@ -161,7 +161,7 @@ static int ug3105_probe(struct i2c_client *client)
}
ret = adc_battery_helper_init(&chip->helper, chip->psy,
- ug3105_get_voltage_and_current_now);
+ ug3105_get_voltage_and_current_now, NULL);
if (ret)
goto stop;
Charger ICs often have a status pin which indicates when the charger has finished charging the battery. Sometimes the status of this pin can be read over a GPIO. Add support for optionally reading a charge-finished GPIO and when available use this to determine when to return POWER_SUPPLY_STATUS_FULL. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/power/supply/adc-battery-helper.c | 18 +++++++++++++++--- drivers/power/supply/adc-battery-helper.h | 5 ++++- drivers/power/supply/ug3105_battery.c | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-)