#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>
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;
}
}
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)
#define ADC_BAT_HELPER_MOV_AVG_WINDOW_SIZE 8
struct power_supply;
+struct gpio_desc;
/*
* The adc battery helper code needs voltage- and current-now to be sampled as
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;
#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