summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/power/supply/ab8500-bm.h12
-rw-r--r--drivers/power/supply/ab8500_bmdata.c14
-rw-r--r--drivers/power/supply/ab8500_btemp.c14
-rw-r--r--drivers/power/supply/ab8500_fg.c4
-rw-r--r--drivers/power/supply/power_supply_core.c26
-rw-r--r--include/linux/power_supply.h13
6 files changed, 51 insertions, 32 deletions
diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h
index 91ef9d4a5222..180a016b3662 100644
--- a/drivers/power/supply/ab8500-bm.h
+++ b/drivers/power/supply/ab8500-bm.h
@@ -328,16 +328,6 @@ struct ab8500_maxim_parameters {
};
/**
- * struct ab8500_battery_type - different batteries supported
- * @resis_high: battery upper resistance limit
- * @resis_low: battery lower resistance limit
- */
-struct ab8500_battery_type {
- int resis_high;
- int resis_low;
-};
-
-/**
* struct ab8500_bm_capacity_levels - ab8500 capacity level data
* @critical: critical capacity level in percent
* @low: low capacity level in percent
@@ -387,7 +377,6 @@ struct ab8500_bm_charger_parameters {
* @temp_hysteresis temperature hysteresis
* @maxi maximization parameters
* @cap_levels capacity in percent for the different capacity levels
- * @bat_type table of supported battery types
* @chg_params charger parameters
* @fg_params fuel gauge parameters
*/
@@ -410,7 +399,6 @@ struct ab8500_bm_data {
int temp_hysteresis;
const struct ab8500_maxim_parameters *maxi;
const struct ab8500_bm_capacity_levels *cap_levels;
- struct ab8500_battery_type *bat_type;
const struct ab8500_bm_charger_parameters *chg_params;
const struct ab8500_fg_parameters *fg_params;
};
diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c
index bf0b74773eee..3e6ea22372b2 100644
--- a/drivers/power/supply/ab8500_bmdata.c
+++ b/drivers/power/supply/ab8500_bmdata.c
@@ -73,12 +73,6 @@ static struct power_supply_maintenance_charge_table ab8500_maint_charg_table[] =
}
};
-/* Default battery type for reference designs is the unknown type */
-static struct ab8500_battery_type bat_type_thermistor_unknown = {
- .resis_high = 0,
- .resis_low = 0,
-};
-
static const struct ab8500_bm_capacity_levels cap_levels = {
.critical = 2,
.low = 10,
@@ -136,7 +130,6 @@ struct ab8500_bm_data ab8500_bm_data = {
.enable_overshoot = false,
.fg_res = 100,
.cap_levels = &cap_levels,
- .bat_type = &bat_type_thermistor_unknown,
.interval_charging = 5,
.interval_not_charging = 120,
.maxi = &ab8500_maxi_params,
@@ -214,6 +207,13 @@ int ab8500_bm_of_probe(struct power_supply *psy,
bi->resist_table_size = ARRAY_SIZE(temp_to_batres_tbl_thermistor);
}
+ /* The default battery is emulated by a resistor at 7K */
+ if (bi->bti_resistance_ohm < 0 ||
+ bi->bti_resistance_tolerance < 0) {
+ bi->bti_resistance_ohm = 7000;
+ bi->bti_resistance_tolerance = 20;
+ }
+
if (!bi->ocv_table[0]) {
/* Default capacity table at say 25 degrees Celsius */
bi->ocv_temp[0] = 25;
diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c
index 2a6fc151210c..b7e842dff567 100644
--- a/drivers/power/supply/ab8500_btemp.c
+++ b/drivers/power/supply/ab8500_btemp.c
@@ -237,8 +237,8 @@ static int ab8500_btemp_get_batctrl_res(struct ab8500_btemp *di)
*/
static int ab8500_btemp_id(struct ab8500_btemp *di)
{
+ struct power_supply_battery_info *bi = di->bm->bi;
int res;
- u8 i;
di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA;
@@ -248,13 +248,11 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
return -ENXIO;
}
- if ((res <= di->bm->bat_type->resis_high) &&
- (res >= di->bm->bat_type->resis_low)) {
- dev_info(di->dev, "Battery detected on BATTEMP"
- " low %d < res %d < high: %d"
- " index: %d\n",
- di->bm->bat_type->resis_low, res,
- di->bm->bat_type->resis_high, i);
+ if (power_supply_battery_bti_in_range(bi, res)) {
+ dev_info(di->dev, "Battery detected on BATCTRL (pin C3)"
+ " resistance %d Ohm = %d Ohm +/- %d%%\n",
+ res, bi->bti_resistance_ohm,
+ bi->bti_resistance_tolerance);
} else {
dev_warn(di->dev, "Battery identified as unknown"
", resistance %d Ohm\n", res);
diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c
index 0227e800c58d..f2ff3103e0d0 100644
--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -2241,10 +2241,6 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data)
if (!di->flags.batt_id_received &&
(bi && (bi->technology !=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN))) {
- const struct ab8500_battery_type *b;
-
- b = di->bm->bat_type;
-
di->flags.batt_id_received = true;
di->bat_cap.max_mah_design =
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index e3d6d3ff492a..3d5047d3fe99 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -607,7 +607,9 @@ int power_supply_get_battery_info(struct power_supply *psy,
info->temp_min = INT_MIN;
info->temp_max = INT_MAX;
info->factory_internal_resistance_uohm = -EINVAL;
- info->resist_table = NULL;
+ info->resist_table = NULL;
+ info->bti_resistance_ohm = -EINVAL;
+ info->bti_resistance_tolerance = -EINVAL;
for (index = 0; index < POWER_SUPPLY_OCV_TEMP_MAX; index++) {
info->ocv_table[index] = NULL;
@@ -938,6 +940,28 @@ int power_supply_batinfo_ocv2cap(struct power_supply_battery_info *info,
}
EXPORT_SYMBOL_GPL(power_supply_batinfo_ocv2cap);
+bool power_supply_battery_bti_in_range(struct power_supply_battery_info *info,
+ int resistance)
+{
+ int low, high;
+
+ /* Nothing like this can be checked */
+ if (info->bti_resistance_ohm <= 0)
+ return false;
+
+ /* This will be extremely strict and unlikely to work */
+ if (info->bti_resistance_tolerance <= 0)
+ return (info->bti_resistance_ohm == resistance);
+
+ low = info->bti_resistance_ohm -
+ (info->bti_resistance_ohm * info->bti_resistance_tolerance) / 100;
+ high = info->bti_resistance_ohm +
+ (info->bti_resistance_ohm * info->bti_resistance_tolerance) / 100;
+
+ return ((resistance >= low) && (resistance <= high));
+}
+EXPORT_SYMBOL_GPL(power_supply_battery_bti_in_range);
+
int power_supply_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index f8601598d3d3..7fdc03cf2285 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -498,6 +498,14 @@ struct power_supply_maintenance_charge_table {
* by temperature: highest temperature with lowest resistance first, lowest
* temperature with highest resistance last.
* @resist_table_size: the number of items in the resist_table.
+ * @bti_resistance_ohm: The Battery Type Indicator (BIT) nominal resistance
+ * in ohms for this battery, if an identification resistor is mounted
+ * between a third battery terminal and ground. This scheme is used by a lot
+ * of mobile device batteries.
+ * @bti_resistance_tolerance: The tolerance in percent of the BTI resistance,
+ * for example 10 for +/- 10%, if the bti_resistance is set to 7000 and the
+ * tolerance is 10% we will detect a proper battery if the BTI resistance
+ * is between 6300 and 7700 Ohm.
*
* This is the recommended struct to manage static battery parameters,
* populated by power_supply_get_battery_info(). Most platform drivers should
@@ -624,6 +632,8 @@ struct power_supply_battery_info {
int ocv_table_size[POWER_SUPPLY_OCV_TEMP_MAX];
struct power_supply_resistance_temp_table *resist_table;
int resist_table_size;
+ int bti_resistance_ohm;
+ int bti_resistance_tolerance;
};
extern struct atomic_notifier_head power_supply_notifier;
@@ -667,6 +677,8 @@ power_supply_temp2resist_simple(struct power_supply_resistance_temp_table *table
int table_len, int temp);
extern struct power_supply_maintenance_charge_table *
power_supply_get_maintenance_charging_setting(struct power_supply_battery_info *info, int index);
+extern bool power_supply_battery_bti_in_range(struct power_supply_battery_info *info,
+ int resistance);
extern void power_supply_changed(struct power_supply *psy);
extern int power_supply_am_i_supplied(struct power_supply *psy);
int power_supply_get_property_from_supplier(struct power_supply *psy,
@@ -684,6 +696,7 @@ power_supply_supports_maintenance_charging(struct power_supply_battery_info *inf
return (mt != NULL);
}
+
#ifdef CONFIG_POWER_SUPPLY
extern int power_supply_is_system_supplied(void);
#else