1 #include <linux/export.h>
2 #include <linux/power_supply.h>
4 #include <linux/mfd/abx500.h>
5 #include <linux/mfd/abx500/ab8500.h>
6 #include <linux/mfd/abx500/ab8500-bm.h>
9 * These are the defined batteries that uses a NTC and ID resistor placed
10 * inside of the battery pack.
11 * Note that the res_to_temp table must be strictly sorted by falling resistance
14 static struct abx500_res_to_temp temp_tbl_A_thermistor
[] = {
32 static struct abx500_res_to_temp temp_tbl_B_thermistor
[] = {
50 static struct abx500_v_to_cap cap_tbl_A_thermistor
[] = {
73 static struct abx500_v_to_cap cap_tbl_B_thermistor
[] = {
96 static struct abx500_v_to_cap cap_tbl
[] = {
124 * Note that the res_to_temp table must be strictly sorted by falling
125 * resistance values to work.
127 static struct abx500_res_to_temp temp_tbl
[] = {
146 * Note that the batres_vs_temp table must be strictly sorted by falling
147 * temperature values to work.
149 static struct batres_vs_temp temp_to_batres_tbl_thermistor
[] = {
160 * Note that the batres_vs_temp table must be strictly sorted by falling
161 * temperature values to work.
163 static struct batres_vs_temp temp_to_batres_tbl_ext_thermistor
[] = {
173 /* battery resistance table for LI ION 9100 battery */
174 static struct batres_vs_temp temp_to_batres_tbl_9100
[] = {
184 static struct abx500_battery_type bat_type_thermistor
[] = {
185 [BATTERY_UNKNOWN
] = {
186 /* First element always represent the UNKNOWN battery */
187 .name
= POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
190 .battery_resistance
= 300,
191 .charge_full_design
= 612,
192 .nominal_voltage
= 3700,
193 .termination_vol
= 4050,
194 .termination_curr
= 200,
195 .recharge_vol
= 3990,
196 .normal_cur_lvl
= 400,
197 .normal_vol_lvl
= 4100,
198 .maint_a_cur_lvl
= 400,
199 .maint_a_vol_lvl
= 4050,
200 .maint_a_chg_timer_h
= 60,
201 .maint_b_cur_lvl
= 400,
202 .maint_b_vol_lvl
= 4000,
203 .maint_b_chg_timer_h
= 200,
204 .low_high_cur_lvl
= 300,
205 .low_high_vol_lvl
= 4000,
206 .n_temp_tbl_elements
= ARRAY_SIZE(temp_tbl
),
207 .r_to_t_tbl
= temp_tbl
,
208 .n_v_cap_tbl_elements
= ARRAY_SIZE(cap_tbl
),
209 .v_to_cap_tbl
= cap_tbl
,
210 .n_batres_tbl_elements
= ARRAY_SIZE(temp_to_batres_tbl_thermistor
),
211 .batres_tbl
= temp_to_batres_tbl_thermistor
,
214 .name
= POWER_SUPPLY_TECHNOLOGY_LIPO
,
217 .battery_resistance
= 300,
218 .charge_full_design
= 900,
219 .nominal_voltage
= 3600,
220 .termination_vol
= 4150,
221 .termination_curr
= 80,
222 .recharge_vol
= 4130,
223 .normal_cur_lvl
= 700,
224 .normal_vol_lvl
= 4200,
225 .maint_a_cur_lvl
= 600,
226 .maint_a_vol_lvl
= 4150,
227 .maint_a_chg_timer_h
= 60,
228 .maint_b_cur_lvl
= 600,
229 .maint_b_vol_lvl
= 4100,
230 .maint_b_chg_timer_h
= 200,
231 .low_high_cur_lvl
= 300,
232 .low_high_vol_lvl
= 4000,
233 .n_temp_tbl_elements
= ARRAY_SIZE(temp_tbl_A_thermistor
),
234 .r_to_t_tbl
= temp_tbl_A_thermistor
,
235 .n_v_cap_tbl_elements
= ARRAY_SIZE(cap_tbl_A_thermistor
),
236 .v_to_cap_tbl
= cap_tbl_A_thermistor
,
237 .n_batres_tbl_elements
= ARRAY_SIZE(temp_to_batres_tbl_thermistor
),
238 .batres_tbl
= temp_to_batres_tbl_thermistor
,
242 .name
= POWER_SUPPLY_TECHNOLOGY_LIPO
,
243 .resis_high
= 200000,
245 .battery_resistance
= 300,
246 .charge_full_design
= 900,
247 .nominal_voltage
= 3600,
248 .termination_vol
= 4150,
249 .termination_curr
= 80,
250 .recharge_vol
= 4130,
251 .normal_cur_lvl
= 700,
252 .normal_vol_lvl
= 4200,
253 .maint_a_cur_lvl
= 600,
254 .maint_a_vol_lvl
= 4150,
255 .maint_a_chg_timer_h
= 60,
256 .maint_b_cur_lvl
= 600,
257 .maint_b_vol_lvl
= 4100,
258 .maint_b_chg_timer_h
= 200,
259 .low_high_cur_lvl
= 300,
260 .low_high_vol_lvl
= 4000,
261 .n_temp_tbl_elements
= ARRAY_SIZE(temp_tbl_B_thermistor
),
262 .r_to_t_tbl
= temp_tbl_B_thermistor
,
263 .n_v_cap_tbl_elements
= ARRAY_SIZE(cap_tbl_B_thermistor
),
264 .v_to_cap_tbl
= cap_tbl_B_thermistor
,
265 .n_batres_tbl_elements
= ARRAY_SIZE(temp_to_batres_tbl_thermistor
),
266 .batres_tbl
= temp_to_batres_tbl_thermistor
,
270 static struct abx500_battery_type bat_type_ext_thermistor
[] = {
271 [BATTERY_UNKNOWN
] = {
272 /* First element always represent the UNKNOWN battery */
273 .name
= POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
276 .battery_resistance
= 300,
277 .charge_full_design
= 612,
278 .nominal_voltage
= 3700,
279 .termination_vol
= 4050,
280 .termination_curr
= 200,
281 .recharge_vol
= 3990,
282 .normal_cur_lvl
= 400,
283 .normal_vol_lvl
= 4100,
284 .maint_a_cur_lvl
= 400,
285 .maint_a_vol_lvl
= 4050,
286 .maint_a_chg_timer_h
= 60,
287 .maint_b_cur_lvl
= 400,
288 .maint_b_vol_lvl
= 4000,
289 .maint_b_chg_timer_h
= 200,
290 .low_high_cur_lvl
= 300,
291 .low_high_vol_lvl
= 4000,
292 .n_temp_tbl_elements
= ARRAY_SIZE(temp_tbl
),
293 .r_to_t_tbl
= temp_tbl
,
294 .n_v_cap_tbl_elements
= ARRAY_SIZE(cap_tbl
),
295 .v_to_cap_tbl
= cap_tbl
,
296 .n_batres_tbl_elements
= ARRAY_SIZE(temp_to_batres_tbl_thermistor
),
297 .batres_tbl
= temp_to_batres_tbl_thermistor
,
300 * These are the batteries that doesn't have an internal NTC resistor to measure
301 * its temperature. The temperature in this case is measure with a NTC placed
302 * near the battery but on the PCB.
305 .name
= POWER_SUPPLY_TECHNOLOGY_LIPO
,
308 .battery_resistance
= 300,
309 .charge_full_design
= 900,
310 .nominal_voltage
= 3700,
311 .termination_vol
= 4150,
312 .termination_curr
= 100,
313 .recharge_vol
= 4130,
314 .normal_cur_lvl
= 700,
315 .normal_vol_lvl
= 4200,
316 .maint_a_cur_lvl
= 600,
317 .maint_a_vol_lvl
= 4150,
318 .maint_a_chg_timer_h
= 60,
319 .maint_b_cur_lvl
= 600,
320 .maint_b_vol_lvl
= 4100,
321 .maint_b_chg_timer_h
= 200,
322 .low_high_cur_lvl
= 300,
323 .low_high_vol_lvl
= 4000,
324 .n_temp_tbl_elements
= ARRAY_SIZE(temp_tbl
),
325 .r_to_t_tbl
= temp_tbl
,
326 .n_v_cap_tbl_elements
= ARRAY_SIZE(cap_tbl
),
327 .v_to_cap_tbl
= cap_tbl
,
328 .n_batres_tbl_elements
= ARRAY_SIZE(temp_to_batres_tbl_thermistor
),
329 .batres_tbl
= temp_to_batres_tbl_thermistor
,
332 .name
= POWER_SUPPLY_TECHNOLOGY_LION
,
335 .battery_resistance
= 300,
336 .charge_full_design
= 950,
337 .nominal_voltage
= 3700,
338 .termination_vol
= 4150,
339 .termination_curr
= 100,
340 .recharge_vol
= 4130,
341 .normal_cur_lvl
= 700,
342 .normal_vol_lvl
= 4200,
343 .maint_a_cur_lvl
= 600,
344 .maint_a_vol_lvl
= 4150,
345 .maint_a_chg_timer_h
= 60,
346 .maint_b_cur_lvl
= 600,
347 .maint_b_vol_lvl
= 4100,
348 .maint_b_chg_timer_h
= 200,
349 .low_high_cur_lvl
= 300,
350 .low_high_vol_lvl
= 4000,
351 .n_temp_tbl_elements
= ARRAY_SIZE(temp_tbl
),
352 .r_to_t_tbl
= temp_tbl
,
353 .n_v_cap_tbl_elements
= ARRAY_SIZE(cap_tbl
),
354 .v_to_cap_tbl
= cap_tbl
,
355 .n_batres_tbl_elements
= ARRAY_SIZE(temp_to_batres_tbl_thermistor
),
356 .batres_tbl
= temp_to_batres_tbl_thermistor
,
359 .name
= POWER_SUPPLY_TECHNOLOGY_LION
,
362 .battery_resistance
= 300,
363 .charge_full_design
= 950,
364 .nominal_voltage
= 3700,
365 .termination_vol
= 4150,
366 .termination_curr
= 100,
367 .recharge_vol
= 4130,
368 .normal_cur_lvl
= 700,
369 .normal_vol_lvl
= 4200,
370 .maint_a_cur_lvl
= 600,
371 .maint_a_vol_lvl
= 4150,
372 .maint_a_chg_timer_h
= 60,
373 .maint_b_cur_lvl
= 600,
374 .maint_b_vol_lvl
= 4100,
375 .maint_b_chg_timer_h
= 200,
376 .low_high_cur_lvl
= 300,
377 .low_high_vol_lvl
= 4000,
378 .n_temp_tbl_elements
= ARRAY_SIZE(temp_tbl
),
379 .r_to_t_tbl
= temp_tbl
,
380 .n_v_cap_tbl_elements
= ARRAY_SIZE(cap_tbl
),
381 .v_to_cap_tbl
= cap_tbl
,
382 .n_batres_tbl_elements
= ARRAY_SIZE(temp_to_batres_tbl_thermistor
),
383 .batres_tbl
= temp_to_batres_tbl_thermistor
,
387 static const struct abx500_bm_capacity_levels cap_levels
= {
395 static const struct abx500_fg_parameters fg
= {
396 .recovery_sleep_timer
= 10,
397 .recovery_total_time
= 100,
399 .init_discard_time
= 5,
400 .init_total_time
= 40,
401 .high_curr_time
= 60,
403 .accu_high_curr
= 30,
404 .high_curr_threshold
= 50,
405 .lowbat_threshold
= 3100,
406 .battok_falling_th_sel0
= 2860,
407 .battok_raising_th_sel1
= 2860,
408 .user_cap_limit
= 15,
412 static const struct abx500_maxim_parameters maxi_params
= {
416 .charger_curr_step
= 100,
419 static const struct abx500_bm_charger_parameters chg
= {
420 .usb_volt_max
= 5500,
421 .usb_curr_max
= 1500,
426 struct abx500_bm_data ab8500_bm_data
= {
431 .main_safety_tmr_h
= 4,
432 .temp_interval_chg
= 20,
433 .temp_interval_nochg
= 120,
434 .usb_safety_tmr_h
= 4,
435 .bkup_bat_v
= BUP_VCH_SEL_2P6V
,
436 .bkup_bat_i
= BUP_ICH_SEL_150UA
,
437 .no_maintenance
= false,
438 .adc_therm
= ABx500_ADC_THERM_BATCTRL
,
439 .chg_unknown_bat
= false,
440 .enable_overshoot
= false,
442 .cap_levels
= &cap_levels
,
443 .bat_type
= bat_type_thermistor
,
446 .interval_charging
= 5,
447 .interval_not_charging
= 120,
448 .temp_hysteresis
= 3,
449 .gnd_lift_resistance
= 34,
450 .maxi
= &maxi_params
,
455 int bmdevs_of_probe(struct device
*dev
, struct device_node
*np
,
456 struct abx500_bm_data
**battery
)
458 struct abx500_battery_type
*btype
;
459 struct device_node
*np_bat_supply
;
460 struct abx500_bm_data
*bat
;
465 *battery
= &ab8500_bm_data
;
467 /* get phandle to 'battery-info' node */
468 np_bat_supply
= of_parse_phandle(np
, "battery", 0);
469 if (!np_bat_supply
) {
470 dev_err(dev
, "missing property battery\n");
473 if (of_property_read_bool(np_bat_supply
,
474 "thermistor-on-batctrl"))
475 thermistor
= NTC_INTERNAL
;
477 thermistor
= NTC_EXTERNAL
;
480 if (thermistor
== NTC_EXTERNAL
) {
482 bat
->bat_type
= bat_type_ext_thermistor
;
483 bat
->adc_therm
= ABx500_ADC_THERM_BATTEMP
;
485 btech
= of_get_property(np_bat_supply
,
486 "stericsson,battery-type", NULL
);
488 dev_warn(dev
, "missing property battery-name/type\n");
489 strcpy(bat_tech
, "UNKNOWN");
491 strcpy(bat_tech
, btech
);
494 if (strncmp(bat_tech
, "LION", 4) == 0) {
495 bat
->no_maintenance
= true;
496 bat
->chg_unknown_bat
= true;
497 bat
->bat_type
[BATTERY_UNKNOWN
].charge_full_design
= 2600;
498 bat
->bat_type
[BATTERY_UNKNOWN
].termination_vol
= 4150;
499 bat
->bat_type
[BATTERY_UNKNOWN
].recharge_vol
= 4130;
500 bat
->bat_type
[BATTERY_UNKNOWN
].normal_cur_lvl
= 520;
501 bat
->bat_type
[BATTERY_UNKNOWN
].normal_vol_lvl
= 4200;
503 /* select the battery resolution table */
504 for (i
= 0; i
< bat
->n_btypes
; ++i
) {
505 btype
= (bat
->bat_type
+ i
);
506 if (thermistor
== NTC_EXTERNAL
) {
508 temp_to_batres_tbl_ext_thermistor
;
509 } else if (strncmp(bat_tech
, "LION", 4) == 0) {
511 temp_to_batres_tbl_9100
;
514 temp_to_batres_tbl_thermistor
;
517 of_node_put(np_bat_supply
);