Commit 67acb291 authored by Linus Walleij's avatar Linus Walleij Committed by Sebastian Reichel
Browse files

power: supply: ab8500: Standardize temp res lookup



The lookup from battery temperature to internal resistance was
using its own format. Rewrite this to use the table inside
struct power_supply_battery_info:s resist_table.

The supplied resistance table has to be rewritten to express
the resistance in percent of the factory resistance as a
side effect.

We can then rely on the library function
power_supply_temp2resist_simple() to interpolate the internal
resistance percent from the temperature.

Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
parent bc6e0287
Loading
Loading
Loading
Loading
+0 −15
Original line number Diff line number Diff line
@@ -379,8 +379,6 @@ struct ab8500_maxim_parameters {
 * @r_to_t_tbl:			table containing resistance to temp points
 * @n_v_cap_tbl_elements:	number of elements in v_to_cap_tbl
 * @v_to_cap_tbl:		Voltage to capacity (in %) table
 * @n_batres_tbl_elements	number of elements in the batres_tbl
 * @batres_tbl			battery internal resistance vs temperature table
 */
struct ab8500_battery_type {
	int resis_high;
@@ -397,8 +395,6 @@ struct ab8500_battery_type {
	const struct ab8500_res_to_temp *r_to_t_tbl;
	int n_v_cap_tbl_elements;
	const struct ab8500_v_to_cap *v_to_cap_tbl;
	int n_batres_tbl_elements;
	const struct batres_vs_temp *batres_tbl;
};

/**
@@ -502,17 +498,6 @@ struct res_to_temp {
	int resist;
};

/**
 * struct batres_vs_temp - defines one point in a temp vs battery internal
 * resistance curve.
 * @temp:			battery pack temperature in Celsius
 * @resist:			battery internal reistance in mOhm
 */
struct batres_vs_temp {
	int temp;
	int resist;
};

/* Forward declaration */
struct ab8500_fg;

+19 −12
Original line number Diff line number Diff line
@@ -67,16 +67,17 @@ static const struct ab8500_res_to_temp temp_tbl[] = {

/*
 * Note that the batres_vs_temp table must be strictly sorted by falling
 * temperature values to work.
 * temperature values to work. Factory resistance is 300 mOhm and the
 * resistance values to the right are percentages of 300 mOhm.
 */
static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {
	{ 40, 120},
	{ 30, 135},
	{ 20, 165},
	{ 10, 230},
	{ 00, 325},
	{-10, 445},
	{-20, 595},
static struct power_supply_resistance_temp_table temp_to_batres_tbl_thermistor[] = {
	{ .temp = 40, .resistance = 40 /* 120 mOhm */ },
	{ .temp = 30, .resistance = 45 /* 135 mOhm */ },
	{ .temp = 20, .resistance = 55 /* 165 mOhm */ },
	{ .temp = 10, .resistance = 77 /* 230 mOhm */ },
	{ .temp = 00, .resistance = 108 /* 325 mOhm */ },
	{ .temp = -10, .resistance = 158 /* 445 mOhm */ },
	{ .temp = -20, .resistance = 198 /* 595 mOhm */ },
};

/* Default battery type for reference designs is the unknown type */
@@ -95,8 +96,6 @@ static struct ab8500_battery_type bat_type_thermistor_unknown = {
	.r_to_t_tbl = temp_tbl,
	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
	.v_to_cap_tbl = cap_tbl,
	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
	.batres_tbl = temp_to_batres_tbl_thermistor,
};

static const struct ab8500_bm_capacity_levels cap_levels = {
@@ -209,8 +208,16 @@ int ab8500_bm_of_probe(struct power_supply *psy,
		/* Charging stops when we drop below this current */
		bi->charge_term_current_ua = 200000;

	if (bi->factory_internal_resistance_uohm < 0)
	/*
	 * Internal resistance and factory resistance are tightly coupled
	 * so both MUST be defined or we fall back to defaults.
	 */
	if ((bi->factory_internal_resistance_uohm < 0) ||
	    !bi->resist_table) {
		bi->factory_internal_resistance_uohm = 300000;
		bi->resist_table = temp_to_batres_tbl_thermistor;
		bi->resist_table_size = ARRAY_SIZE(temp_to_batres_tbl_thermistor);
	}

	if (bi->temp_min == INT_MIN)
		bi->temp_min = AB8500_TEMP_UNDER;
+19 −28
Original line number Diff line number Diff line
@@ -901,44 +901,35 @@ static int ab8500_fg_uncomp_volt_to_capacity(struct ab8500_fg *di)
 * @di:		pointer to the ab8500_fg structure
 *
 * Returns battery inner resistance added with the fuel gauge resistor value
 * to get the total resistance in the whole link from gnd to bat+ node.
 * to get the total resistance in the whole link from gnd to bat+ node
 * in milliohm.
 */
static int ab8500_fg_battery_resistance(struct ab8500_fg *di)
{
	int i, tbl_size;
	const struct batres_vs_temp *tbl;
	int resist = 0;

	tbl = di->bm->bat_type->batres_tbl;
	tbl_size = di->bm->bat_type->n_batres_tbl_elements;

	for (i = 0; i < tbl_size; ++i) {
		if (di->bat_temp / 10 > tbl[i].temp)
			break;
	}
	struct power_supply_battery_info *bi = &di->bm->bi;
	int resistance_percent = 0;
	int resistance;

	if ((i > 0) && (i < tbl_size)) {
		resist = fixp_linear_interpolate(
			tbl[i].temp,
			tbl[i].resist,
			tbl[i-1].temp,
			tbl[i-1].resist,
	resistance_percent = power_supply_temp2resist_simple(bi->resist_table,
						 bi->resist_table_size,
						 di->bat_temp / 10);
	} else if (i == 0) {
		resist = tbl[0].resist;
	} else {
		resist = tbl[tbl_size - 1].resist;
	}
	/*
	 * We get a percentage of factory resistance here so first get
	 * the factory resistance in milliohms then calculate how much
	 * resistance we have at this temperature.
	 */
	resistance = (bi->factory_internal_resistance_uohm / 1000);
	resistance = resistance * resistance_percent / 100;

	dev_dbg(di->dev, "%s Temp: %d battery internal resistance: %d"
	    " fg resistance %d, total: %d (mOhm)\n",
		__func__, di->bat_temp, resist, di->bm->fg_res / 10,
		(di->bm->fg_res / 10) + resist);
		__func__, di->bat_temp, resistance, di->bm->fg_res / 10,
		(di->bm->fg_res / 10) + resistance);

	/* fg_res variable is in 0.1mOhm */
	resist += di->bm->fg_res / 10;
	resistance += di->bm->fg_res / 10;

	return resist;
	return resistance;
}

/**