int charger_curr_step_ua;
};
-/**
- * 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
* @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
*/
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;
};
}
};
-/* 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,
.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,
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;
*/
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;
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);
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 =
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;
}
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)
* 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
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;
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,
return (mt != NULL);
}
+
#ifdef CONFIG_POWER_SUPPLY
extern int power_supply_is_system_supplied(void);
#else