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:
Yuanjiang Yu 2019-12-09 11:56:23 +08:00 коммит произвёл Sebastian Reichel
Родитель 65dbad713d
Коммит 6af8288834
1 изменённых файлов: 30 добавлений и 2 удалений

Просмотреть файл

@ -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);