mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-15 08:56:48 +07:00
power: supply: sc27xx: Optimize the battery resistance with measuring temperature
Optimize the battery internal resistance in a certain temerature to get a accurate battery internal resistance. Signed-off-by: Yuanjiang Yu <yuanjiang.yu@unisoc.com> Signed-off-by: Baolin Wang <baolin.wang@linaro.org> Signed-off-by: Baolin Wang <baolin.wang7@gmail.com> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
This commit is contained in:
parent
65dbad713d
commit
6af8288834
@ -81,9 +81,11 @@
|
||||
* @max_volt: the maximum constant input voltage in millivolt
|
||||
* @min_volt: the minimum drained battery voltage in microvolt
|
||||
* @table_len: the capacity table length
|
||||
* @resist_table_len: the resistance table length
|
||||
* @cur_1000ma_adc: ADC value corresponding to 1000 mA
|
||||
* @vol_1000mv_adc: ADC value corresponding to 1000 mV
|
||||
* @cap_table: capacity table with corresponding ocv
|
||||
* @resist_table: resistance percent table with corresponding temperature
|
||||
*/
|
||||
struct sc27xx_fgu_data {
|
||||
struct regmap *regmap;
|
||||
@ -103,15 +105,18 @@ struct sc27xx_fgu_data {
|
||||
int max_volt;
|
||||
int min_volt;
|
||||
int table_len;
|
||||
int resist_table_len;
|
||||
int cur_1000ma_adc;
|
||||
int vol_1000mv_adc;
|
||||
struct power_supply_battery_ocv_table *cap_table;
|
||||
struct power_supply_resistance_temp_table *resist_table;
|
||||
};
|
||||
|
||||
static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity);
|
||||
static void sc27xx_fgu_capacity_calibration(struct sc27xx_fgu_data *data,
|
||||
int cap, bool int_mode);
|
||||
static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap);
|
||||
static int sc27xx_fgu_get_temp(struct sc27xx_fgu_data *data, int *temp);
|
||||
|
||||
static const char * const sc27xx_charger_supply_name[] = {
|
||||
"sc2731_charger",
|
||||
@ -434,7 +439,7 @@ static int sc27xx_fgu_get_current(struct sc27xx_fgu_data *data, int *val)
|
||||
|
||||
static int sc27xx_fgu_get_vbat_ocv(struct sc27xx_fgu_data *data, int *val)
|
||||
{
|
||||
int vol, cur, ret;
|
||||
int vol, cur, ret, temp, resistance;
|
||||
|
||||
ret = sc27xx_fgu_get_vbat_vol(data, &vol);
|
||||
if (ret)
|
||||
@ -444,8 +449,19 @@ static int sc27xx_fgu_get_vbat_ocv(struct sc27xx_fgu_data *data, int *val)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
resistance = data->internal_resist;
|
||||
if (data->resist_table_len > 0) {
|
||||
ret = sc27xx_fgu_get_temp(data, &temp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
resistance = power_supply_temp2resist_simple(data->resist_table,
|
||||
data->resist_table_len, temp);
|
||||
resistance = data->internal_resist * resistance / 100;
|
||||
}
|
||||
|
||||
/* Return the battery OCV in micro volts. */
|
||||
*val = vol * 1000 - cur * data->internal_resist;
|
||||
*val = vol * 1000 - cur * resistance;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -929,6 +945,18 @@ static int sc27xx_fgu_hw_init(struct sc27xx_fgu_data *data)
|
||||
if (!data->alarm_cap)
|
||||
data->alarm_cap += 1;
|
||||
|
||||
data->resist_table_len = info.resist_table_size;
|
||||
if (data->resist_table_len > 0) {
|
||||
data->resist_table = devm_kmemdup(data->dev, info.resist_table,
|
||||
data->resist_table_len *
|
||||
sizeof(struct power_supply_resistance_temp_table),
|
||||
GFP_KERNEL);
|
||||
if (!data->resist_table) {
|
||||
power_supply_put_battery_info(data->battery, &info);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
power_supply_put_battery_info(data->battery, &info);
|
||||
|
||||
ret = sc27xx_fgu_calibration(data);
|
||||
|
Loading…
Reference in New Issue
Block a user