Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
240fbe23
Commit
240fbe23
authored
Jan 05, 2013
by
Anton Vorontsov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-anton' of
git://git.linaro.org/people/ljones/linux-3.0-ux500
parents
2fbb520d
215cf5c9
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
594 additions
and
519 deletions
+594
-519
drivers/mfd/ab8500-core.c
drivers/mfd/ab8500-core.c
+0
-8
drivers/power/Makefile
drivers/power/Makefile
+1
-1
drivers/power/ab8500_bmdata.c
drivers/power/ab8500_bmdata.c
+254
-269
drivers/power/ab8500_btemp.c
drivers/power/ab8500_btemp.c
+51
-45
drivers/power/ab8500_charger.c
drivers/power/ab8500_charger.c
+158
-64
drivers/power/ab8500_fg.c
drivers/power/ab8500_fg.c
+61
-62
drivers/power/abx500_chargalg.c
drivers/power/abx500_chargalg.c
+66
-67
include/linux/mfd/abx500.h
include/linux/mfd/abx500.h
+3
-3
No files found.
drivers/mfd/ab8500-core.c
View file @
240fbe23
...
...
@@ -1011,40 +1011,32 @@ static struct mfd_cell ab8500_bm_devs[] = {
.
of_compatible
=
"stericsson,ab8500-charger"
,
.
num_resources
=
ARRAY_SIZE
(
ab8500_charger_resources
),
.
resources
=
ab8500_charger_resources
,
#ifndef CONFIG_OF
.
platform_data
=
&
ab8500_bm_data
,
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
#endif
},
{
.
name
=
"ab8500-btemp"
,
.
of_compatible
=
"stericsson,ab8500-btemp"
,
.
num_resources
=
ARRAY_SIZE
(
ab8500_btemp_resources
),
.
resources
=
ab8500_btemp_resources
,
#ifndef CONFIG_OF
.
platform_data
=
&
ab8500_bm_data
,
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
#endif
},
{
.
name
=
"ab8500-fg"
,
.
of_compatible
=
"stericsson,ab8500-fg"
,
.
num_resources
=
ARRAY_SIZE
(
ab8500_fg_resources
),
.
resources
=
ab8500_fg_resources
,
#ifndef CONFIG_OF
.
platform_data
=
&
ab8500_bm_data
,
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
#endif
},
{
.
name
=
"ab8500-chargalg"
,
.
of_compatible
=
"stericsson,ab8500-chargalg"
,
.
num_resources
=
ARRAY_SIZE
(
ab8500_chargalg_resources
),
.
resources
=
ab8500_chargalg_resources
,
#ifndef CONFIG_OF
.
platform_data
=
&
ab8500_bm_data
,
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
#endif
},
};
...
...
drivers/power/Makefile
View file @
240fbe23
...
...
@@ -38,7 +38,7 @@ obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_JZ4740)
+=
jz4740-battery.o
obj-$(CONFIG_BATTERY_INTEL_MID)
+=
intel_mid_battery.o
obj-$(CONFIG_BATTERY_RX51)
+=
rx51_battery.o
obj-$(CONFIG_AB8500_BM)
+=
ab8500_bmdata.o ab8500_charger.o ab8500_
btemp.o ab8500_fg
.o abx500_chargalg.o
obj-$(CONFIG_AB8500_BM)
+=
ab8500_bmdata.o ab8500_charger.o ab8500_
fg.o ab8500_btemp
.o abx500_chargalg.o
obj-$(CONFIG_CHARGER_ISP1704)
+=
isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903)
+=
max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030)
+=
twl4030_charger.o
...
...
drivers/power/ab8500_bmdata.c
View file @
240fbe23
...
...
@@ -182,206 +182,206 @@ static struct batres_vs_temp temp_to_batres_tbl_9100[] = {
};
static
struct
abx500_battery_type
bat_type_thermistor
[]
=
{
[
BATTERY_UNKNOWN
]
=
{
/* First element always represent the UNKNOWN battery */
.
name
=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
.
resis_high
=
0
,
.
resis_low
=
0
,
.
battery_resistance
=
300
,
.
charge_full_design
=
612
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4050
,
.
termination_curr
=
200
,
.
recharge_vol
=
3990
,
.
normal_cur_lvl
=
400
,
.
normal_vol_lvl
=
4100
,
.
maint_a_cur_lvl
=
400
,
.
maint_a_vol_lvl
=
4050
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
400
,
.
maint_b_vol_lvl
=
4000
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
,
},
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
resis_high
=
53407
,
.
resis_low
=
12500
,
.
battery_resistance
=
300
,
.
charge_full_design
=
900
,
.
nominal_voltage
=
3600
,
.
termination_vol
=
4150
,
.
termination_curr
=
80
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl_A_thermistor
),
.
r_to_t_tbl
=
temp_tbl_A_thermistor
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl_A_thermistor
),
.
v_to_cap_tbl
=
cap_tbl_A_thermistor
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
[
BATTERY_UNKNOWN
]
=
{
/* First element always represent the UNKNOWN battery */
.
name
=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
.
resis_high
=
0
,
.
resis_low
=
0
,
.
battery_resistance
=
300
,
.
charge_full_design
=
612
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4050
,
.
termination_curr
=
200
,
.
recharge_vol
=
3990
,
.
normal_cur_lvl
=
400
,
.
normal_vol_lvl
=
4100
,
.
maint_a_cur_lvl
=
400
,
.
maint_a_vol_lvl
=
4050
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
400
,
.
maint_b_vol_lvl
=
4000
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
,
},
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
resis_high
=
53407
,
.
resis_low
=
12500
,
.
battery_resistance
=
300
,
.
charge_full_design
=
900
,
.
nominal_voltage
=
3600
,
.
termination_vol
=
4150
,
.
termination_curr
=
80
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl_A_thermistor
),
.
r_to_t_tbl
=
temp_tbl_A_thermistor
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl_A_thermistor
),
.
v_to_cap_tbl
=
cap_tbl_A_thermistor
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
},
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
resis_high
=
200000
,
.
resis_low
=
82869
,
.
battery_resistance
=
300
,
.
charge_full_design
=
900
,
.
nominal_voltage
=
3600
,
.
termination_vol
=
4150
,
.
termination_curr
=
80
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl_B_thermistor
),
.
r_to_t_tbl
=
temp_tbl_B_thermistor
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl_B_thermistor
),
.
v_to_cap_tbl
=
cap_tbl_B_thermistor
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
},
},
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
resis_high
=
200000
,
.
resis_low
=
82869
,
.
battery_resistance
=
300
,
.
charge_full_design
=
900
,
.
nominal_voltage
=
3600
,
.
termination_vol
=
4150
,
.
termination_curr
=
80
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl_B_thermistor
),
.
r_to_t_tbl
=
temp_tbl_B_thermistor
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl_B_thermistor
),
.
v_to_cap_tbl
=
cap_tbl_B_thermistor
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
},
};
static
struct
abx500_battery_type
bat_type_ext_thermistor
[]
=
{
[
BATTERY_UNKNOWN
]
=
{
/* First element always represent the UNKNOWN battery */
.
name
=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
.
resis_high
=
0
,
.
resis_low
=
0
,
.
battery_resistance
=
300
,
.
charge_full_design
=
612
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4050
,
.
termination_curr
=
200
,
.
recharge_vol
=
3990
,
.
normal_cur_lvl
=
400
,
.
normal_vol_lvl
=
4100
,
.
maint_a_cur_lvl
=
400
,
.
maint_a_vol_lvl
=
4050
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
400
,
.
maint_b_vol_lvl
=
4000
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
,
},
[
BATTERY_UNKNOWN
]
=
{
/* First element always represent the UNKNOWN battery */
.
name
=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
.
resis_high
=
0
,
.
resis_low
=
0
,
.
battery_resistance
=
300
,
.
charge_full_design
=
612
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4050
,
.
termination_curr
=
200
,
.
recharge_vol
=
3990
,
.
normal_cur_lvl
=
400
,
.
normal_vol_lvl
=
4100
,
.
maint_a_cur_lvl
=
400
,
.
maint_a_vol_lvl
=
4050
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
400
,
.
maint_b_vol_lvl
=
4000
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
,
},
/*
* These are the batteries that doesn't have an internal NTC resistor to measure
* its temperature. The temperature in this case is measure with a NTC placed
* near the battery but on the PCB.
*/
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
resis_high
=
76000
,
.
resis_low
=
53000
,
.
battery_resistance
=
300
,
.
charge_full_design
=
900
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4150
,
.
termination_curr
=
100
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
,
},
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LION
,
.
resis_high
=
30000
,
.
resis_low
=
10000
,
.
battery_resistance
=
300
,
.
charge_full_design
=
950
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4150
,
.
termination_curr
=
100
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
,
},
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LION
,
.
resis_high
=
95000
,
.
resis_low
=
76001
,
.
battery_resistance
=
300
,
.
charge_full_design
=
950
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4150
,
.
termination_curr
=
100
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
,
},
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
resis_high
=
76000
,
.
resis_low
=
53000
,
.
battery_resistance
=
300
,
.
charge_full_design
=
900
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4150
,
.
termination_curr
=
100
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
,
},
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LION
,
.
resis_high
=
30000
,
.
resis_low
=
10000
,
.
battery_resistance
=
300
,
.
charge_full_design
=
950
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4150
,
.
termination_curr
=
100
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
,
},
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LION
,
.
resis_high
=
95000
,
.
resis_low
=
76001
,
.
battery_resistance
=
300
,
.
charge_full_design
=
950
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4150
,
.
termination_curr
=
100
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
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
abx500_bm_capacity_levels
cap_levels
=
{
...
...
@@ -424,98 +424,83 @@ static const struct abx500_bm_charger_parameters chg = {
};
struct
abx500_bm_data
ab8500_bm_data
=
{
.
temp_under
=
3
,
.
temp_low
=
8
,
.
temp_high
=
43
,
.
temp_over
=
48
,
.
main_safety_tmr_h
=
4
,
.
temp_interval_chg
=
20
,
.
temp_interval_nochg
=
120
,
.
usb_safety_tmr_h
=
4
,
.
bkup_bat_v
=
BUP_VCH_SEL_2P6V
,
.
bkup_bat_i
=
BUP_ICH_SEL_150UA
,
.
no_maintenance
=
false
,
.
adc_therm
=
ABx500_ADC_THERM_BATCTRL
,
.
chg_unknown_bat
=
false
,
.
enable_overshoot
=
false
,
.
fg_res
=
100
,
.
cap_levels
=
&
cap_levels
,
.
bat_type
=
bat_type_thermistor
,
.
n_btypes
=
3
,
.
batt_id
=
0
,
.
interval_charging
=
5
,
.
interval_not_charging
=
120
,
.
temp_hysteresis
=
3
,
.
gnd_lift_resistance
=
34
,
.
maxi
=
&
maxi_params
,
.
chg_params
=
&
chg
,
.
fg_params
=
&
fg
,
.
temp_under
=
3
,
.
temp_low
=
8
,
.
temp_high
=
43
,
.
temp_over
=
48
,
.
main_safety_tmr_h
=
4
,
.
temp_interval_chg
=
20
,
.
temp_interval_nochg
=
120
,
.
usb_safety_tmr_h
=
4
,
.
bkup_bat_v
=
BUP_VCH_SEL_2P6V
,
.
bkup_bat_i
=
BUP_ICH_SEL_150UA
,
.
no_maintenance
=
false
,
.
adc_therm
=
ABx500_ADC_THERM_BATCTRL
,
.
chg_unknown_bat
=
false
,
.
enable_overshoot
=
false
,
.
fg_res
=
100
,
.
cap_levels
=
&
cap_levels
,
.
bat_type
=
bat_type_thermistor
,
.
n_btypes
=
3
,
.
batt_id
=
0
,
.
interval_charging
=
5
,
.
interval_not_charging
=
120
,
.
temp_hysteresis
=
3
,
.
gnd_lift_resistance
=
34
,
.
maxi
=
&
maxi_params
,
.
chg_params
=
&
chg
,
.
fg_params
=
&
fg
,
};
int
__devinit
bmdevs_of_probe
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
abx500_bm_data
**
battery
)
int
__devinit
ab8500_bm_of_probe
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
abx500_bm_data
*
bm
)
{
struct
abx500_battery_type
*
btype
;
struct
device_node
*
np_bat_supply
;
struct
abx500_bm_data
*
bat
;
struct
batres_vs_temp
*
tmp_batres_tbl
;
struct
device_node
*
battery_node
;
const
char
*
btech
;
char
bat_tech
[
8
];
int
i
,
thermistor
;
*
battery
=
&
ab8500_bm_data
;
int
i
;
/* get phandle to 'battery-info' node */
np_bat_supply
=
of_parse_phandle
(
np
,
"battery"
,
0
);
if
(
!
np_bat_supply
)
{
dev_err
(
dev
,
"
missing property battery
\n
"
);
battery_node
=
of_parse_phandle
(
np
,
"battery"
,
0
);
if
(
!
battery_node
)
{
dev_err
(
dev
,
"
battery node or reference missing
\n
"
);
return
-
EINVAL
;
}
if
(
of_property_read_bool
(
np_bat_supply
,
"thermistor-on-batctrl"
))
thermistor
=
NTC_INTERNAL
;
else
thermistor
=
NTC_EXTERNAL
;
bat
=
*
battery
;
if
(
thermistor
==
NTC_EXTERNAL
)
{
bat
->
n_btypes
=
4
;
bat
->
bat_type
=
bat_type_ext_thermistor
;
bat
->
adc_therm
=
ABx500_ADC_THERM_BATTEMP
;
}
btech
=
of_get_property
(
np_bat_supply
,
"stericsson,battery-type"
,
NULL
);
btech
=
of_get_property
(
battery_node
,
"stericsson,battery-type"
,
NULL
);
if
(
!
btech
)
{
dev_warn
(
dev
,
"missing property battery-name/type
\n
"
);
strcpy
(
bat_tech
,
"UNKNOWN"
);
}
else
{
strcpy
(
bat_tech
,
btech
);
return
-
EINVAL
;
}
if
(
strncmp
(
b
at_
tech
,
"LION"
,
4
)
==
0
)
{
b
at
->
no_maintenance
=
true
;
b
at
->
chg_unknown_bat
=
true
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
charge_full_design
=
2600
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
termination_vol
=
4150
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
recharge_vol
=
4130
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
normal_cur_lvl
=
520
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
normal_vol_lvl
=
4200
;
if
(
strncmp
(
btech
,
"LION"
,
4
)
==
0
)
{
b
m
->
no_maintenance
=
true
;
b
m
->
chg_unknown_bat
=
true
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
charge_full_design
=
2600
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
termination_vol
=
4150
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
recharge_vol
=
4130
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
normal_cur_lvl
=
520
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
normal_vol_lvl
=
4200
;
}
/* select the battery resolution table */
for
(
i
=
0
;
i
<
bat
->
n_btypes
;
++
i
)
{
btype
=
(
bat
->
bat_type
+
i
);
if
(
thermistor
==
NTC_EXTERNAL
)
{
btype
->
batres_tbl
=
temp_to_batres_tbl_ext_thermistor
;
}
else
if
(
strncmp
(
bat_tech
,
"LION"
,
4
)
==
0
)
{
btype
->
batres_tbl
=
temp_to_batres_tbl_9100
;
}
else
{
btype
->
batres_tbl
=
temp_to_batres_tbl_thermistor
;
}
if
(
of_property_read_bool
(
battery_node
,
"thermistor-on-batctrl"
))
{
if
(
strncmp
(
btech
,
"LION"
,
4
)
==
0
)
tmp_batres_tbl
=
temp_to_batres_tbl_9100
;
else
tmp_batres_tbl
=
temp_to_batres_tbl_thermistor
;
}
else
{
bm
->
n_btypes
=
4
;
bm
->
bat_type
=
bat_type_ext_thermistor
;
bm
->
adc_therm
=
ABx500_ADC_THERM_BATTEMP
;
tmp_batres_tbl
=
temp_to_batres_tbl_ext_thermistor
;
}
of_node_put
(
np_bat_supply
);
/* select the battery resolution table */
for
(
i
=
0
;
i
<
bm
->
n_btypes
;
++
i
)
bm
->
bat_type
[
i
].
batres_tbl
=
tmp_batres_tbl
;
of_node_put
(
battery_node
);
return
0
;
}
drivers/power/ab8500_btemp.c
View file @
240fbe23
...
...
@@ -78,12 +78,13 @@ struct ab8500_btemp_ranges {
* @parent: Pointer to the struct ab8500
* @gpadc: Pointer to the struct gpadc
* @fg: Pointer to the struct fg
* @b
at: Pointer to the abx500_bm platform data
* @b
m: Platform specific battery management information
* @btemp_psy: Structure for BTEMP specific battery properties
* @events: Structure for information about events triggered
* @btemp_ranges: Battery temperature range structure
* @btemp_wq: Work queue for measuring the temperature periodically
* @btemp_periodic_work: Work for measuring the temperature periodically
* @initialized: True if battery id read.
*/
struct
ab8500_btemp
{
struct
device
*
dev
;
...
...
@@ -94,12 +95,13 @@ struct ab8500_btemp {
struct
ab8500
*
parent
;
struct
ab8500_gpadc
*
gpadc
;
struct
ab8500_fg
*
fg
;
struct
abx500_bm_data
*
b
at
;
struct
abx500_bm_data
*
b
m
;
struct
power_supply
btemp_psy
;
struct
ab8500_btemp_events
events
;
struct
ab8500_btemp_ranges
btemp_ranges
;
struct
workqueue_struct
*
btemp_wq
;
struct
delayed_work
btemp_periodic_work
;
bool
initialized
;
};
/* BTEMP power supply properties */
...
...
@@ -147,13 +149,13 @@ static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di,
return
(
450000
*
(
v_batctrl
))
/
(
1800
-
v_batctrl
);
}
if
(
di
->
b
at
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
)
{
if
(
di
->
b
m
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
)
{
/*
* If the battery has internal NTC, we use the current
* source to calculate the resistance, 7uA or 20uA
*/
rbs
=
(
v_batctrl
*
1000
-
di
->
b
at
->
gnd_lift_resistance
*
inst_curr
)
-
di
->
b
m
->
gnd_lift_resistance
*
inst_curr
)
/
di
->
curr_source
;
}
else
{
/*
...
...
@@ -209,7 +211,7 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di,
return
0
;
/* Only do this for batteries with internal NTC */
if
(
di
->
b
at
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
enable
)
{
if
(
di
->
b
m
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
enable
)
{
if
(
di
->
curr_source
==
BTEMP_BATCTRL_CURR_SRC_7UA
)
curr
=
BAT_CTRL_7U_ENA
;
else
...
...
@@ -241,7 +243,7 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di,
__func__
);
goto
disable_curr_source
;
}
}
else
if
(
di
->
b
at
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
!
enable
)
{
}
else
if
(
di
->
b
m
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
!
enable
)
{
dev_dbg
(
di
->
dev
,
"Disable BATCTRL curr source
\n
"
);
/* Write 0 to the curr bits */
...
...
@@ -457,9 +459,9 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
int
rbat
,
rntc
,
vntc
;
u8
id
;
id
=
di
->
b
at
->
batt_id
;
id
=
di
->
b
m
->
batt_id
;
if
(
di
->
b
at
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
if
(
di
->
b
m
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
id
!=
BATTERY_UNKNOWN
)
{
rbat
=
ab8500_btemp_get_batctrl_res
(
di
);
...
...
@@ -474,8 +476,8 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
}
temp
=
ab8500_btemp_res_to_temp
(
di
,
di
->
b
at
->
bat_type
[
id
].
r_to_t_tbl
,
di
->
b
at
->
bat_type
[
id
].
n_temp_tbl_elements
,
rbat
);
di
->
b
m
->
bat_type
[
id
].
r_to_t_tbl
,
di
->
b
m
->
bat_type
[
id
].
n_temp_tbl_elements
,
rbat
);
}
else
{
vntc
=
ab8500_gpadc_convert
(
di
->
gpadc
,
BTEMP_BALL
);
if
(
vntc
<
0
)
{
...
...
@@ -491,8 +493,8 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
rntc
=
230000
*
vntc
/
(
VTVOUT_V
-
vntc
);
temp
=
ab8500_btemp_res_to_temp
(
di
,
di
->
b
at
->
bat_type
[
id
].
r_to_t_tbl
,
di
->
b
at
->
bat_type
[
id
].
n_temp_tbl_elements
,
rntc
);
di
->
b
m
->
bat_type
[
id
].
r_to_t_tbl
,
di
->
b
m
->
bat_type
[
id
].
n_temp_tbl_elements
,
rntc
);
prev
=
temp
;
}
dev_dbg
(
di
->
dev
,
"Battery temperature is %d
\n
"
,
temp
);
...
...
@@ -513,7 +515,7 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
u8
i
;
di
->
curr_source
=
BTEMP_BATCTRL_CURR_SRC_7UA
;
di
->
b
at
->
batt_id
=
BATTERY_UNKNOWN
;
di
->
b
m
->
batt_id
=
BATTERY_UNKNOWN
;
res
=
ab8500_btemp_get_batctrl_res
(
di
);
if
(
res
<
0
)
{
...
...
@@ -522,23 +524,23 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
}
/* BATTERY_UNKNOWN is defined on position 0, skip it! */
for
(
i
=
BATTERY_UNKNOWN
+
1
;
i
<
di
->
b
at
->
n_btypes
;
i
++
)
{
if
((
res
<=
di
->
b
at
->
bat_type
[
i
].
resis_high
)
&&
(
res
>=
di
->
b
at
->
bat_type
[
i
].
resis_low
))
{
for
(
i
=
BATTERY_UNKNOWN
+
1
;
i
<
di
->
b
m
->
n_btypes
;
i
++
)
{
if
((
res
<=
di
->
b
m
->
bat_type
[
i
].
resis_high
)
&&
(
res
>=
di
->
b
m
->
bat_type
[
i
].
resis_low
))
{
dev_dbg
(
di
->
dev
,
"Battery detected on %s"
" low %d < res %d < high: %d"
" index: %d
\n
"
,
di
->
b
at
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
?
di
->
b
m
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
?
"BATCTRL"
:
"BATTEMP"
,
di
->
b
at
->
bat_type
[
i
].
resis_low
,
res
,
di
->
b
at
->
bat_type
[
i
].
resis_high
,
i
);
di
->
b
m
->
bat_type
[
i
].
resis_low
,
res
,
di
->
b
m
->
bat_type
[
i
].
resis_high
,
i
);
di
->
b
at
->
batt_id
=
i
;
di
->
b
m
->
batt_id
=
i
;
break
;
}
}
if
(
di
->
b
at
->
batt_id
==
BATTERY_UNKNOWN
)
{
if
(
di
->
b
m
->
batt_id
==
BATTERY_UNKNOWN
)
{
dev_warn
(
di
->
dev
,
"Battery identified as unknown"
", resistance %d Ohm
\n
"
,
res
);
return
-
ENXIO
;
...
...
@@ -548,13 +550,13 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
* We only have to change current source if the
* detected type is Type 1, else we use the 7uA source
*/
if
(
di
->
b
at
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
di
->
b
at
->
batt_id
==
1
)
{
if
(
di
->
b
m
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
di
->
b
m
->
batt_id
==
1
)
{
dev_dbg
(
di
->
dev
,
"Set BATCTRL current source to 20uA
\n
"
);
di
->
curr_source
=
BTEMP_BATCTRL_CURR_SRC_20UA
;
}
return
di
->
b
at
->
batt_id
;
return
di
->
b
m
->
batt_id
;
}
/**
...
...
@@ -569,6 +571,13 @@ static void ab8500_btemp_periodic_work(struct work_struct *work)
struct
ab8500_btemp
*
di
=
container_of
(
work
,
struct
ab8500_btemp
,
btemp_periodic_work
.
work
);
if
(
!
di
->
initialized
)
{
di
->
initialized
=
true
;
/* Identify the battery */
if
(
ab8500_btemp_id
(
di
)
<
0
)
dev_warn
(
di
->
dev
,
"failed to identify the battery
\n
"
);
}
di
->
bat_temp
=
ab8500_btemp_measure_temp
(
di
);
if
(
di
->
bat_temp
!=
di
->
prev_bat_temp
)
{
...
...
@@ -577,9 +586,9 @@ static void ab8500_btemp_periodic_work(struct work_struct *work)
}
if
(
di
->
events
.
ac_conn
||
di
->
events
.
usb_conn
)
interval
=
di
->
b
at
->
temp_interval_chg
;
interval
=
di
->
b
m
->
temp_interval_chg
;
else
interval
=
di
->
b
at
->
temp_interval_nochg
;
interval
=
di
->
b
m
->
temp_interval_nochg
;
/* Schedule a new measurement */
queue_delayed_work
(
di
->
btemp_wq
,
...
...
@@ -806,7 +815,7 @@ static int ab8500_btemp_get_property(struct power_supply *psy,
val
->
intval
=
1
;
break
;
case
POWER_SUPPLY_PROP_TECHNOLOGY
:
val
->
intval
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
name
;
val
->
intval
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
name
;
break
;
case
POWER_SUPPLY_PROP_TEMP
:
val
->
intval
=
ab8500_btemp_get_temp
(
di
);
...
...
@@ -967,6 +976,7 @@ static char *supply_interface[] = {
static
int
ab8500_btemp_probe
(
struct
platform_device
*
pdev
)
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
abx500_bm_data
*
plat
=
pdev
->
dev
.
platform_data
;
struct
ab8500_btemp
*
di
;
int
irq
,
i
,
ret
=
0
;
u8
val
;
...
...
@@ -976,21 +986,19 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
dev_err
(
&
pdev
->
dev
,
"%s no mem for ab8500_btemp
\n
"
,
__func__
);
return
-
ENOMEM
;
}
di
->
bat
=
pdev
->
mfd_cell
->
platform_data
;
if
(
!
di
->
b
at
)
{
if
(
np
)
{
ret
=
bmdevs_of_probe
(
&
pdev
->
dev
,
np
,
&
di
->
bat
)
;
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get battery information
\n
"
);
return
ret
;
}
}
else
{
dev_err
(
&
pdev
->
dev
,
"
missing dt node for ab8500_btemp
\n
"
);
return
-
EINVAL
;
if
(
!
pl
at
)
{
dev_err
(
&
pdev
->
dev
,
"no battery management data supplied
\n
"
);
return
-
EINVAL
;
}
di
->
bm
=
plat
;
if
(
np
)
{
ret
=
ab8500_bm_of_probe
(
&
pdev
->
dev
,
np
,
di
->
bm
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"
failed to get battery information
\n
"
);
return
ret
;
}
}
else
{
dev_info
(
&
pdev
->
dev
,
"falling back to legacy platform data
\n
"
);
}
/* get parent data */
...
...
@@ -998,6 +1006,8 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
di
->
parent
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
di
->
gpadc
=
ab8500_gpadc_get
(
"ab8500-gpadc.0"
);
di
->
initialized
=
false
;
/* BTEMP supply */
di
->
btemp_psy
.
name
=
"ab8500_btemp"
;
di
->
btemp_psy
.
type
=
POWER_SUPPLY_TYPE_BATTERY
;
...
...
@@ -1022,10 +1032,6 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
INIT_DEFERRABLE_WORK
(
&
di
->
btemp_periodic_work
,
ab8500_btemp_periodic_work
);
/* Identify the battery */
if
(
ab8500_btemp_id
(
di
)
<
0
)
dev_warn
(
di
->
dev
,
"failed to identify the battery
\n
"
);
/* Set BTEMP thermal limits. Low and Med are fixed */
di
->
btemp_ranges
.
btemp_low_limit
=
BTEMP_THERMAL_LOW_LIMIT
;
di
->
btemp_ranges
.
btemp_med_limit
=
BTEMP_THERMAL_MED_LIMIT
;
...
...
drivers/power/ab8500_charger.c
View file @
240fbe23
...
...
@@ -79,6 +79,9 @@
/* Lowest charger voltage is 3.39V -> 0x4E */
#define LOW_VOLT_REG 0x4E
/* Step up/down delay in us */
#define STEP_UDELAY 1000
/* UsbLineStatus register - usb types */
enum
ab8500_charger_link_status
{
USB_STAT_NOT_CONFIGURED
,
...
...
@@ -186,7 +189,7 @@ struct ab8500_charger_usb_state {
* @autopower_cfg platform specific power config support for "pwron after pwrloss"
* @parent: Pointer to the struct ab8500
* @gpadc: Pointer to the struct gpadc
* @b
at: Pointer to the abx500_bm platform data
* @b
m: Platform specific battery management information
* @flags: Structure for information about events triggered
* @usb_state: Structure for usb stack information
* @ac_chg: AC charger power supply
...
...
@@ -223,7 +226,7 @@ struct ab8500_charger {
bool
autopower_cfg
;
struct
ab8500
*
parent
;
struct
ab8500_gpadc
*
gpadc
;
struct
abx500_bm_data
*
b
at
;
struct
abx500_bm_data
*
b
m
;
struct
ab8500_charger_event_flags
flags
;
struct
ab8500_charger_usb_state
usb_state
;
struct
ux500_charger
ac_chg
;
...
...
@@ -935,6 +938,88 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
return
0
;
}
/**
* ab8500_charger_set_current() - set charger current
* @di: pointer to the ab8500_charger structure
* @ich: charger current, in mA
* @reg: select what charger register to set
*
* Set charger current.
* There is no state machine in the AB to step up/down the charger
* current to avoid dips and spikes on MAIN, VBUS and VBAT when
* charging is started. Instead we need to implement
* this charger current step-up/down here.
* Returns error code in case of failure else 0(on success)
*/
static
int
ab8500_charger_set_current
(
struct
ab8500_charger
*
di
,
int
ich
,
int
reg
)
{
int
ret
,
i
;
int
curr_index
,
prev_curr_index
,
shift_value
;
u8
reg_value
;
switch
(
reg
)
{
case
AB8500_MCH_IPT_CURLVL_REG
:
shift_value
=
MAIN_CH_INPUT_CURR_SHIFT
;
curr_index
=
ab8500_current_to_regval
(
ich
);
break
;
case
AB8500_USBCH_IPT_CRNTLVL_REG
:
shift_value
=
VBUS_IN_CURR_LIM_SHIFT
;
curr_index
=
ab8500_vbus_in_curr_to_regval
(
ich
);
break
;
case
AB8500_CH_OPT_CRNTLVL_REG
:
shift_value
=
0
;
curr_index
=
ab8500_current_to_regval
(
ich
);
break
;
default:
dev_err
(
di
->
dev
,
"%s current register not valid
\n
"
,
__func__
);
return
-
ENXIO
;
}
if
(
curr_index
<
0
)
{
dev_err
(
di
->
dev
,
"requested current limit out-of-range
\n
"
);
return
-
ENXIO
;
}
ret
=
abx500_get_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
reg
,
&
reg_value
);
if
(
ret
<
0
)
{
dev_err
(
di
->
dev
,
"%s read failed
\n
"
,
__func__
);
return
ret
;
}
prev_curr_index
=
(
reg_value
>>
shift_value
);
/* only update current if it's been changed */
if
(
prev_curr_index
==
curr_index
)
return
0
;
dev_dbg
(
di
->
dev
,
"%s set charger current: %d mA for reg: 0x%02x
\n
"
,
__func__
,
ich
,
reg
);
if
(
prev_curr_index
>
curr_index
)
{
for
(
i
=
prev_curr_index
-
1
;
i
>=
curr_index
;
i
--
)
{
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
reg
,
(
u8
)
i
<<
shift_value
);
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
return
ret
;
}
usleep_range
(
STEP_UDELAY
,
STEP_UDELAY
*
2
);
}
}
else
{
for
(
i
=
prev_curr_index
+
1
;
i
<=
curr_index
;
i
++
)
{
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
reg
,
(
u8
)
i
<<
shift_value
);
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
return
ret
;
}
usleep_range
(
STEP_UDELAY
,
STEP_UDELAY
*
2
);
}
}
return
ret
;
}
/**
* ab8500_charger_set_vbus_in_curr() - set VBUS input current limit
* @di: pointer to the ab8500_charger structure
...
...
@@ -946,12 +1031,10 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
static
int
ab8500_charger_set_vbus_in_curr
(
struct
ab8500_charger
*
di
,
int
ich_in
)
{
int
ret
;
int
input_curr_index
;
int
min_value
;
/* We should always use to lowest current limit */
min_value
=
min
(
di
->
b
at
->
chg_params
->
usb_curr_max
,
ich_in
);
min_value
=
min
(
di
->
b
m
->
chg_params
->
usb_curr_max
,
ich_in
);
switch
(
min_value
)
{
case
100
:
...
...
@@ -966,19 +1049,38 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di,
break
;
}
input_curr_index
=
ab8500_vbus_in_curr_to_regval
(
min_value
);
if
(
input_curr_index
<
0
)
{
dev_err
(
di
->
dev
,
"VBUS input current limit too high
\n
"
);
return
-
ENXIO
;
}
return
ab8500_charger_set_current
(
di
,
min_value
,
AB8500_USBCH_IPT_CRNTLVL_REG
);
}
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
AB8500_USBCH_IPT_CRNTLVL_REG
,
input_curr_index
<<
VBUS_IN_CURR_LIM_SHIFT
);
if
(
ret
)
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
/**
* ab8500_charger_set_main_in_curr() - set main charger input current
* @di: pointer to the ab8500_charger structure
* @ich_in: input charger current, in mA
*
* Set main charger input current.
* Returns error code in case of failure else 0(on success)
*/
static
int
ab8500_charger_set_main_in_curr
(
struct
ab8500_charger
*
di
,
int
ich_in
)
{
return
ab8500_charger_set_current
(
di
,
ich_in
,
AB8500_MCH_IPT_CURLVL_REG
);
}
return
ret
;
/**
* ab8500_charger_set_output_curr() - set charger output current
* @di: pointer to the ab8500_charger structure
* @ich_out: output charger current, in mA
*
* Set charger output current.
* Returns error code in case of failure else 0(on success)
*/
static
int
ab8500_charger_set_output_curr
(
struct
ab8500_charger
*
di
,
int
ich_out
)
{
return
ab8500_charger_set_current
(
di
,
ich_out
,
AB8500_CH_OPT_CRNTLVL_REG
);
}
/**
...
...
@@ -1074,7 +1176,7 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
volt_index
=
ab8500_voltage_to_regval
(
vset
);
curr_index
=
ab8500_current_to_regval
(
iset
);
input_curr_index
=
ab8500_current_to_regval
(
di
->
b
at
->
chg_params
->
ac_curr_max
);
di
->
b
m
->
chg_params
->
ac_curr_max
);
if
(
volt_index
<
0
||
curr_index
<
0
||
input_curr_index
<
0
)
{
dev_err
(
di
->
dev
,
"Charger voltage or current too high, "
...
...
@@ -1090,23 +1192,24 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
return
ret
;
}
/* MainChInputCurr: current that can be drawn from the charger*/
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
AB8500_MCH_IPT_CURLVL_REG
,
input_curr_index
<<
MAIN_CH_INPUT_CURR_SHIFT
);
ret
=
ab8500_charger_set_main_in_curr
(
di
,
di
->
bm
->
chg_params
->
ac_curr_max
);
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s Failed to set MainChInputCurr
\n
"
,
__func__
);
return
ret
;
}
/* ChOutputCurentLevel: protected output current */
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
AB8500_CH_OPT_CRNTLVL_REG
,
(
u8
)
curr_index
);
ret
=
ab8500_charger_set_output_curr
(
di
,
iset
);
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s "
"Failed to set ChOutputCurentLevel
\n
"
,
__func__
);
return
ret
;
}
/* Check if VBAT overshoot control should be enabled */
if
(
!
di
->
b
at
->
enable_overshoot
)
if
(
!
di
->
b
m
->
enable_overshoot
)
overshoot
=
MAIN_CH_NO_OVERSHOOT_ENA_N
;
/* Enable Main Charger */
...
...
@@ -1158,12 +1261,11 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
return
ret
;
}
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
AB8500_CH_OPT_CRNTLVL_REG
,
CH_OP_CUR_LVL_0P1
);
ret
=
ab8500_charger_set_output_curr
(
di
,
0
);
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s "
"Failed to set ChOutputCurentLevel
\n
"
,
__func__
);
return
ret
;
}
}
else
{
...
...
@@ -1266,14 +1368,15 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger,
return
ret
;
}
/* ChOutputCurentLevel: protected output current */
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
AB8500_CH_OPT_CRNTLVL_REG
,
(
u8
)
curr_index
);
ret
=
ab8500_charger_set_output_curr
(
di
,
ich_out
);
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s "
"Failed to set ChOutputCurentLevel
\n
"
,
__func__
);
return
ret
;
}
/* Check if VBAT overshoot control should be enabled */
if
(
!
di
->
b
at
->
enable_overshoot
)
if
(
!
di
->
b
m
->
enable_overshoot
)
overshoot
=
USB_CHG_NO_OVERSHOOT_ENA_N
;
/* Enable USB Charger */
...
...
@@ -1366,7 +1469,6 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
int
ich_out
)
{
int
ret
;
int
curr_index
;
struct
ab8500_charger
*
di
;
if
(
charger
->
psy
.
type
==
POWER_SUPPLY_TYPE_MAINS
)
...
...
@@ -1376,18 +1478,11 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
else
return
-
ENXIO
;
curr_index
=
ab8500_current_to_regval
(
ich_out
);
if
(
curr_index
<
0
)
{
dev_err
(
di
->
dev
,
"Charger current too high, "
"charging not started
\n
"
);
return
-
ENXIO
;
}
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
AB8500_CH_OPT_CRNTLVL_REG
,
(
u8
)
curr_index
);
ret
=
ab8500_charger_set_output_curr
(
di
,
ich_out
);
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s "
"Failed to set ChOutputCurentLevel
\n
"
,
__func__
);
return
ret
;
}
...
...
@@ -2359,8 +2454,8 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di)
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_RTC
,
AB8500_RTC_BACKUP_CHG_REG
,
di
->
b
at
->
bkup_bat_v
|
di
->
b
at
->
bkup_bat_i
);
di
->
b
m
->
bkup_bat_v
|
di
->
b
m
->
bkup_bat_i
);
if
(
ret
)
{
dev_err
(
di
->
dev
,
"failed to setup backup battery charging
\n
"
);
goto
out
;
...
...
@@ -2541,6 +2636,7 @@ static char *supply_interface[] = {
static
int
ab8500_charger_probe
(
struct
platform_device
*
pdev
)
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
abx500_bm_data
*
plat
=
pdev
->
dev
.
platform_data
;
struct
ab8500_charger
*
di
;
int
irq
,
i
,
charger_status
,
ret
=
0
;
...
...
@@ -2549,24 +2645,22 @@ static int ab8500_charger_probe(struct platform_device *pdev)
dev_err
(
&
pdev
->
dev
,
"%s no mem for ab8500_charger
\n
"
,
__func__
);
return
-
ENOMEM
;
}
di
->
bat
=
pdev
->
mfd_cell
->
platform_data
;
if
(
!
di
->
bat
)
{
if
(
np
)
{
ret
=
bmdevs_of_probe
(
&
pdev
->
dev
,
np
,
&
di
->
bat
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get battery information
\n
"
);
return
ret
;
}
di
->
autopower_cfg
=
of_property_read_bool
(
np
,
"autopower_cfg"
);
}
else
{
dev_err
(
&
pdev
->
dev
,
"missing dt node for ab8500_charger
\n
"
);
return
-
EINVAL
;
if
(
!
plat
)
{
dev_err
(
&
pdev
->
dev
,
"no battery management data supplied
\n
"
);
return
-
EINVAL
;
}
di
->
bm
=
plat
;
if
(
np
)
{
ret
=
ab8500_bm_of_probe
(
&
pdev
->
dev
,
np
,
di
->
bm
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get battery information
\n
"
);
return
ret
;
}
}
else
{
dev_info
(
&
pdev
->
dev
,
"falling back to legacy platform data
\n
"
);
di
->
autopower_cfg
=
of_property_read_bool
(
np
,
"autopower_cfg"
);
}
else
di
->
autopower_cfg
=
false
;
}
/* get parent data */
di
->
dev
=
&
pdev
->
dev
;
...
...
drivers/power/ab8500_fg.c
View file @
240fbe23
...
...
@@ -173,7 +173,7 @@ struct inst_curr_result_list {
* @avg_cap: Average capacity filter
* @parent: Pointer to the struct ab8500
* @gpadc: Pointer to the struct gpadc
* @b
at: Pointer to the abx500_bm platform data
* @b
m: Platform specific battery management information
* @fg_psy: Structure that holds the FG specific battery properties
* @fg_wq: Work queue for running the FG algorithm
* @fg_periodic_work: Work to run the FG algorithm periodically
...
...
@@ -212,7 +212,7 @@ struct ab8500_fg {
struct
ab8500_fg_avg_cap
avg_cap
;
struct
ab8500
*
parent
;
struct
ab8500_gpadc
*
gpadc
;
struct
abx500_bm_data
*
b
at
;
struct
abx500_bm_data
*
b
m
;
struct
power_supply
fg_psy
;
struct
workqueue_struct
*
fg_wq
;
struct
delayed_work
fg_periodic_work
;
...
...
@@ -355,7 +355,7 @@ static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr)
/*
* We want to know if we're in low current mode
*/
if
(
curr
>
-
di
->
b
at
->
fg_params
->
high_curr_threshold
)
if
(
curr
>
-
di
->
b
m
->
fg_params
->
high_curr_threshold
)
return
true
;
else
return
false
;
...
...
@@ -484,8 +484,9 @@ static int ab8500_fg_coulomb_counter(struct ab8500_fg *di, bool enable)
di
->
flags
.
fg_enabled
=
true
;
}
else
{
/* Clear any pending read requests */
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_GAS_GAUGE
,
AB8500_GASG_CC_CTRL_REG
,
0
);
ret
=
abx500_mask_and_set_register_interruptible
(
di
->
dev
,
AB8500_GAS_GAUGE
,
AB8500_GASG_CC_CTRL_REG
,
(
RESET_ACCU
|
READ_REQ
),
0
);
if
(
ret
)
goto
cc_err
;
...
...
@@ -647,7 +648,7 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res)
* 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm
*/
val
=
(
val
*
QLSB_NANO_AMP_HOURS_X10
*
36
*
4
)
/
(
1000
*
di
->
b
at
->
fg_res
);
(
1000
*
di
->
b
m
->
fg_res
);
if
(
di
->
turn_off_fg
)
{
dev_dbg
(
di
->
dev
,
"%s Disable FG
\n
"
,
__func__
);
...
...
@@ -750,7 +751,7 @@ static void ab8500_fg_acc_cur_work(struct work_struct *work)
* 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm
*/
di
->
accu_charge
=
(
val
*
QLSB_NANO_AMP_HOURS_X10
)
/
(
100
*
di
->
b
at
->
fg_res
);
(
100
*
di
->
b
m
->
fg_res
);
/*
* Convert to unit value in mA
...
...
@@ -762,7 +763,7 @@ static void ab8500_fg_acc_cur_work(struct work_struct *work)
* 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm
*/
di
->
avg_curr
=
(
val
*
QLSB_NANO_AMP_HOURS_X10
*
36
)
/
(
1000
*
di
->
b
at
->
fg_res
*
(
di
->
fg_samples
/
4
));
(
1000
*
di
->
b
m
->
fg_res
*
(
di
->
fg_samples
/
4
));
di
->
flags
.
conv_done
=
true
;
...
...
@@ -814,8 +815,8 @@ static int ab8500_fg_volt_to_capacity(struct ab8500_fg *di, int voltage)
struct
abx500_v_to_cap
*
tbl
;
int
cap
=
0
;
tbl
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
v_to_cap_tbl
,
tbl_size
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
n_v_cap_tbl_elements
;
tbl
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
v_to_cap_tbl
,
tbl_size
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
n_v_cap_tbl_elements
;
for
(
i
=
0
;
i
<
tbl_size
;
++
i
)
{
if
(
voltage
>
tbl
[
i
].
voltage
)
...
...
@@ -866,8 +867,8 @@ static int ab8500_fg_battery_resistance(struct ab8500_fg *di)
struct
batres_vs_temp
*
tbl
;
int
resist
=
0
;
tbl
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
batres_tbl
;
tbl_size
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
n_batres_tbl_elements
;
tbl
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
batres_tbl
;
tbl_size
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
n_batres_tbl_elements
;
for
(
i
=
0
;
i
<
tbl_size
;
++
i
)
{
if
(
di
->
bat_temp
/
10
>
tbl
[
i
].
temp
)
...
...
@@ -888,11 +889,11 @@ static int ab8500_fg_battery_resistance(struct ab8500_fg *di)
dev_dbg
(
di
->
dev
,
"%s Temp: %d battery internal resistance: %d"
" fg resistance %d, total: %d (mOhm)
\n
"
,
__func__
,
di
->
bat_temp
,
resist
,
di
->
b
at
->
fg_res
/
10
,
(
di
->
b
at
->
fg_res
/
10
)
+
resist
);
__func__
,
di
->
bat_temp
,
resist
,
di
->
b
m
->
fg_res
/
10
,
(
di
->
b
m
->
fg_res
/
10
)
+
resist
);
/* fg_res variable is in 0.1mOhm */
resist
+=
di
->
b
at
->
fg_res
/
10
;
resist
+=
di
->
b
m
->
fg_res
/
10
;
return
resist
;
}
...
...
@@ -1110,14 +1111,14 @@ static int ab8500_fg_capacity_level(struct ab8500_fg *di)
percent
=
di
->
bat_cap
.
permille
/
10
;
if
(
percent
<=
di
->
b
at
->
cap_levels
->
critical
||
if
(
percent
<=
di
->
b
m
->
cap_levels
->
critical
||
di
->
flags
.
low_bat
)
ret
=
POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL
;
else
if
(
percent
<=
di
->
b
at
->
cap_levels
->
low
)
else
if
(
percent
<=
di
->
b
m
->
cap_levels
->
low
)
ret
=
POWER_SUPPLY_CAPACITY_LEVEL_LOW
;
else
if
(
percent
<=
di
->
b
at
->
cap_levels
->
normal
)
else
if
(
percent
<=
di
->
b
m
->
cap_levels
->
normal
)
ret
=
POWER_SUPPLY_CAPACITY_LEVEL_NORMAL
;
else
if
(
percent
<=
di
->
b
at
->
cap_levels
->
high
)
else
if
(
percent
<=
di
->
b
m
->
cap_levels
->
high
)
ret
=
POWER_SUPPLY_CAPACITY_LEVEL_HIGH
;
else
ret
=
POWER_SUPPLY_CAPACITY_LEVEL_FULL
;
...
...
@@ -1182,7 +1183,7 @@ static void ab8500_fg_check_capacity_limits(struct ab8500_fg *di, bool init)
di
->
bat_cap
.
prev_percent
!=
(
di
->
bat_cap
.
permille
)
/
10
&&
(
di
->
bat_cap
.
permille
/
10
)
<
di
->
b
at
->
fg_params
->
maint_thres
)
{
di
->
b
m
->
fg_params
->
maint_thres
)
{
dev_dbg
(
di
->
dev
,
"battery reported full "
"but capacity dropping: %d
\n
"
,
...
...
@@ -1284,7 +1285,7 @@ static void ab8500_fg_algorithm_charging(struct ab8500_fg *di)
switch
(
di
->
charge_state
)
{
case
AB8500_FG_CHARGE_INIT
:
di
->
fg_samples
=
SEC_TO_SAMPLE
(
di
->
b
at
->
fg_params
->
accu_charging
);
di
->
b
m
->
fg_params
->
accu_charging
);
ab8500_fg_coulomb_counter
(
di
,
true
);
ab8500_fg_charge_state_to
(
di
,
AB8500_FG_CHARGE_READOUT
);
...
...
@@ -1346,8 +1347,8 @@ static bool check_sysfs_capacity(struct ab8500_fg *di)
cap_permille
=
ab8500_fg_convert_mah_to_permille
(
di
,
di
->
bat_cap
.
user_mah
);
lower
=
di
->
bat_cap
.
permille
-
di
->
b
at
->
fg_params
->
user_cap_limit
*
10
;
upper
=
di
->
bat_cap
.
permille
+
di
->
b
at
->
fg_params
->
user_cap_limit
*
10
;
lower
=
di
->
bat_cap
.
permille
-
di
->
b
m
->
fg_params
->
user_cap_limit
*
10
;
upper
=
di
->
bat_cap
.
permille
+
di
->
b
m
->
fg_params
->
user_cap_limit
*
10
;
if
(
lower
<
0
)
lower
=
0
;
...
...
@@ -1387,7 +1388,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
case
AB8500_FG_DISCHARGE_INIT
:
/* We use the FG IRQ to work on */
di
->
init_cnt
=
0
;
di
->
fg_samples
=
SEC_TO_SAMPLE
(
di
->
b
at
->
fg_params
->
init_timer
);
di
->
fg_samples
=
SEC_TO_SAMPLE
(
di
->
b
m
->
fg_params
->
init_timer
);
ab8500_fg_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_INITMEASURING
);
...
...
@@ -1400,18 +1401,17 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
* samples to get an initial capacity.
* Then go to READOUT
*/
sleep_time
=
di
->
b
at
->
fg_params
->
init_timer
;
sleep_time
=
di
->
b
m
->
fg_params
->
init_timer
;
/* Discard the first [x] seconds */
if
(
di
->
init_cnt
>
di
->
bat
->
fg_params
->
init_discard_time
)
{
if
(
di
->
init_cnt
>
di
->
bm
->
fg_params
->
init_discard_time
)
{
ab8500_fg_calc_cap_discharge_voltage
(
di
,
true
);
ab8500_fg_check_capacity_limits
(
di
,
true
);
}
di
->
init_cnt
+=
sleep_time
;
if
(
di
->
init_cnt
>
di
->
b
at
->
fg_params
->
init_total_time
)
if
(
di
->
init_cnt
>
di
->
b
m
->
fg_params
->
init_total_time
)
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT_INIT
);
...
...
@@ -1426,7 +1426,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
/* Intentional fallthrough */
case
AB8500_FG_DISCHARGE_RECOVERY
:
sleep_time
=
di
->
b
at
->
fg_params
->
recovery_sleep_timer
;
sleep_time
=
di
->
b
m
->
fg_params
->
recovery_sleep_timer
;
/*
* We should check the power consumption
...
...
@@ -1438,9 +1438,9 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
if
(
ab8500_fg_is_low_curr
(
di
,
di
->
inst_curr
))
{
if
(
di
->
recovery_cnt
>
di
->
b
at
->
fg_params
->
recovery_total_time
)
{
di
->
b
m
->
fg_params
->
recovery_total_time
)
{
di
->
fg_samples
=
SEC_TO_SAMPLE
(
di
->
b
at
->
fg_params
->
accu_high_curr
);
di
->
b
m
->
fg_params
->
accu_high_curr
);
ab8500_fg_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT
);
...
...
@@ -1453,7 +1453,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
di
->
recovery_cnt
+=
sleep_time
;
}
else
{
di
->
fg_samples
=
SEC_TO_SAMPLE
(
di
->
b
at
->
fg_params
->
accu_high_curr
);
di
->
b
m
->
fg_params
->
accu_high_curr
);
ab8500_fg_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT
);
...
...
@@ -1462,7 +1462,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
case
AB8500_FG_DISCHARGE_READOUT_INIT
:
di
->
fg_samples
=
SEC_TO_SAMPLE
(
di
->
b
at
->
fg_params
->
accu_high_curr
);
di
->
b
m
->
fg_params
->
accu_high_curr
);
ab8500_fg_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT
);
...
...
@@ -1509,9 +1509,9 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
}
di
->
high_curr_cnt
+=
di
->
b
at
->
fg_params
->
accu_high_curr
;
di
->
b
m
->
fg_params
->
accu_high_curr
;
if
(
di
->
high_curr_cnt
>
di
->
b
at
->
fg_params
->
high_curr_time
)
di
->
b
m
->
fg_params
->
high_curr_time
)
di
->
recovery_needed
=
true
;
ab8500_fg_calc_cap_discharge_fg
(
di
);
...
...
@@ -1528,7 +1528,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
ab8500_fg_calc_cap_discharge_voltage
(
di
,
true
);
di
->
fg_samples
=
SEC_TO_SAMPLE
(
di
->
b
at
->
fg_params
->
accu_high_curr
);
di
->
b
m
->
fg_params
->
accu_high_curr
);
ab8500_fg_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT
);
...
...
@@ -1721,7 +1721,7 @@ static void ab8500_fg_low_bat_work(struct work_struct *work)
vbat
=
ab8500_fg_bat_voltage
(
di
);
/* Check if LOW_BAT still fulfilled */
if
(
vbat
<
di
->
b
at
->
fg_params
->
lowbat_threshold
)
{
if
(
vbat
<
di
->
b
m
->
fg_params
->
lowbat_threshold
)
{
di
->
flags
.
low_bat
=
true
;
dev_warn
(
di
->
dev
,
"Battery voltage still LOW
\n
"
);
...
...
@@ -1779,8 +1779,8 @@ static int ab8500_fg_battok_init_hw_register(struct ab8500_fg *di)
int
ret
;
int
new_val
;
sel0
=
di
->
b
at
->
fg_params
->
battok_falling_th_sel0
;
sel1
=
di
->
b
at
->
fg_params
->
battok_raising_th_sel1
;
sel0
=
di
->
b
m
->
fg_params
->
battok_falling_th_sel0
;
sel1
=
di
->
b
m
->
fg_params
->
battok_raising_th_sel1
;
cbp_sel0
=
ab8500_fg_battok_calc
(
di
,
sel0
);
cbp_sel1
=
ab8500_fg_battok_calc
(
di
,
sel1
);
...
...
@@ -1963,7 +1963,7 @@ static int ab8500_fg_get_property(struct power_supply *psy,
di
->
bat_cap
.
max_mah
);
break
;
case
POWER_SUPPLY_PROP_ENERGY_NOW
:
if
(
di
->
flags
.
batt_unknown
&&
!
di
->
b
at
->
chg_unknown_bat
&&
if
(
di
->
flags
.
batt_unknown
&&
!
di
->
b
m
->
chg_unknown_bat
&&
di
->
flags
.
batt_id_received
)
val
->
intval
=
ab8500_fg_convert_mah_to_uwh
(
di
,
di
->
bat_cap
.
max_mah
);
...
...
@@ -1978,21 +1978,21 @@ static int ab8500_fg_get_property(struct power_supply *psy,
val
->
intval
=
di
->
bat_cap
.
max_mah
;
break
;
case
POWER_SUPPLY_PROP_CHARGE_NOW
:
if
(
di
->
flags
.
batt_unknown
&&
!
di
->
b
at
->
chg_unknown_bat
&&
if
(
di
->
flags
.
batt_unknown
&&
!
di
->
b
m
->
chg_unknown_bat
&&
di
->
flags
.
batt_id_received
)
val
->
intval
=
di
->
bat_cap
.
max_mah
;
else
val
->
intval
=
di
->
bat_cap
.
prev_mah
;
break
;
case
POWER_SUPPLY_PROP_CAPACITY
:
if
(
di
->
flags
.
batt_unknown
&&
!
di
->
b
at
->
chg_unknown_bat
&&
if
(
di
->
flags
.
batt_unknown
&&
!
di
->
b
m
->
chg_unknown_bat
&&
di
->
flags
.
batt_id_received
)
val
->
intval
=
100
;
else
val
->
intval
=
di
->
bat_cap
.
prev_percent
;
break
;
case
POWER_SUPPLY_PROP_CAPACITY_LEVEL
:
if
(
di
->
flags
.
batt_unknown
&&
!
di
->
b
at
->
chg_unknown_bat
&&
if
(
di
->
flags
.
batt_unknown
&&
!
di
->
b
m
->
chg_unknown_bat
&&
di
->
flags
.
batt_id_received
)
val
->
intval
=
POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN
;
else
...
...
@@ -2078,7 +2078,7 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data)
if
(
!
di
->
flags
.
batt_id_received
)
{
const
struct
abx500_battery_type
*
b
;
b
=
&
(
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
]);
b
=
&
(
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
]);
di
->
flags
.
batt_id_received
=
true
;
...
...
@@ -2155,7 +2155,7 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di)
AB8500_SYS_CTRL2_BLOCK
,
AB8500_LOW_BAT_REG
,
ab8500_volt_to_regval
(
di
->
b
at
->
fg_params
->
lowbat_threshold
)
<<
1
|
di
->
b
m
->
fg_params
->
lowbat_threshold
)
<<
1
|
LOW_BAT_ENABLE
);
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
...
...
@@ -2448,6 +2448,7 @@ static char *supply_interface[] = {
static
int
ab8500_fg_probe
(
struct
platform_device
*
pdev
)
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
abx500_bm_data
*
plat
=
pdev
->
dev
.
platform_data
;
struct
ab8500_fg
*
di
;
int
i
,
irq
;
int
ret
=
0
;
...
...
@@ -2457,21 +2458,19 @@ static int ab8500_fg_probe(struct platform_device *pdev)
dev_err
(
&
pdev
->
dev
,
"%s no mem for ab8500_fg
\n
"
,
__func__
);
return
-
ENOMEM
;
}
di
->
bat
=
pdev
->
mfd_cell
->
platform_data
;
if
(
!
di
->
b
at
)
{
if
(
np
)
{
ret
=
bmdevs_of_probe
(
&
pdev
->
dev
,
np
,
&
di
->
bat
)
;
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get battery information
\n
"
);
return
ret
;
}
}
else
{
dev_err
(
&
pdev
->
dev
,
"
missing dt node for ab8500_fg
\n
"
);
return
-
EINVAL
;
if
(
!
pl
at
)
{
dev_err
(
&
pdev
->
dev
,
"no battery management data supplied
\n
"
);
return
-
EINVAL
;
}
di
->
bm
=
plat
;
if
(
np
)
{
ret
=
ab8500_bm_of_probe
(
&
pdev
->
dev
,
np
,
di
->
bm
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"
failed to get battery information
\n
"
);
return
ret
;
}
}
else
{
dev_info
(
&
pdev
->
dev
,
"falling back to legacy platform data
\n
"
);
}
mutex_init
(
&
di
->
cc_lock
);
...
...
@@ -2491,11 +2490,11 @@ static int ab8500_fg_probe(struct platform_device *pdev)
di
->
fg_psy
.
external_power_changed
=
ab8500_fg_external_power_changed
;
di
->
bat_cap
.
max_mah_design
=
MILLI_TO_MICRO
*
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
charge_full_design
;
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
charge_full_design
;
di
->
bat_cap
.
max_mah
=
di
->
bat_cap
.
max_mah_design
;
di
->
vbat_nom
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
nominal_voltage
;
di
->
vbat_nom
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
nominal_voltage
;
di
->
init_capacity
=
true
;
...
...
@@ -2549,7 +2548,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
goto
free_inst_curr_wq
;
}
di
->
fg_samples
=
SEC_TO_SAMPLE
(
di
->
b
at
->
fg_params
->
init_timer
);
di
->
fg_samples
=
SEC_TO_SAMPLE
(
di
->
b
m
->
fg_params
->
init_timer
);
ab8500_fg_coulomb_counter
(
di
,
true
);
/* Initialize completion used to notify completion of inst current */
...
...
drivers/power/abx500_chargalg.c
View file @
240fbe23
...
...
@@ -207,7 +207,7 @@ enum maxim_ret {
* @chg_info: information about connected charger types
* @batt_data: data of the battery
* @susp_status: current charger suspension status
* @b
at: pointer to the abx500_bm platform data
* @b
m: Platform specific battery management information
* @chargalg_psy: structure that holds the battery properties exposed by
* the charging algorithm
* @events: structure for information about events triggered
...
...
@@ -232,7 +232,7 @@ struct abx500_chargalg {
struct
abx500_chargalg_charger_info
chg_info
;
struct
abx500_chargalg_battery_data
batt_data
;
struct
abx500_chargalg_suspension_status
susp_status
;
struct
abx500_bm_data
*
b
at
;
struct
abx500_bm_data
*
b
m
;
struct
power_supply
chargalg_psy
;
struct
ux500_charger
*
ac_chg
;
struct
ux500_charger
*
usb_chg
;
...
...
@@ -367,13 +367,13 @@ static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di)
case
AC_CHG
:
timer_expiration
=
round_jiffies
(
jiffies
+
(
di
->
b
at
->
main_safety_tmr_h
*
3600
*
HZ
));
(
di
->
b
m
->
main_safety_tmr_h
*
3600
*
HZ
));
break
;
case
USB_CHG
:
timer_expiration
=
round_jiffies
(
jiffies
+
(
di
->
b
at
->
usb_safety_tmr_h
*
3600
*
HZ
));
(
di
->
b
m
->
usb_safety_tmr_h
*
3600
*
HZ
));
break
;
default:
...
...
@@ -638,32 +638,32 @@ static void abx500_chargalg_start_charging(struct abx500_chargalg *di,
*/
static
void
abx500_chargalg_check_temp
(
struct
abx500_chargalg
*
di
)
{
if
(
di
->
batt_data
.
temp
>
(
di
->
b
at
->
temp_low
+
di
->
t_hyst_norm
)
&&
di
->
batt_data
.
temp
<
(
di
->
b
at
->
temp_high
-
di
->
t_hyst_norm
))
{
if
(
di
->
batt_data
.
temp
>
(
di
->
b
m
->
temp_low
+
di
->
t_hyst_norm
)
&&
di
->
batt_data
.
temp
<
(
di
->
b
m
->
temp_high
-
di
->
t_hyst_norm
))
{
/* Temp OK! */
di
->
events
.
btemp_underover
=
false
;
di
->
events
.
btemp_lowhigh
=
false
;
di
->
t_hyst_norm
=
0
;
di
->
t_hyst_lowhigh
=
0
;
}
else
{
if
(((
di
->
batt_data
.
temp
>=
di
->
b
at
->
temp_high
)
&&
if
(((
di
->
batt_data
.
temp
>=
di
->
b
m
->
temp_high
)
&&
(
di
->
batt_data
.
temp
<
(
di
->
b
at
->
temp_over
-
di
->
t_hyst_lowhigh
)))
||
(
di
->
b
m
->
temp_over
-
di
->
t_hyst_lowhigh
)))
||
((
di
->
batt_data
.
temp
>
(
di
->
b
at
->
temp_under
+
di
->
t_hyst_lowhigh
))
&&
(
di
->
batt_data
.
temp
<=
di
->
b
at
->
temp_low
)))
{
(
di
->
b
m
->
temp_under
+
di
->
t_hyst_lowhigh
))
&&
(
di
->
batt_data
.
temp
<=
di
->
b
m
->
temp_low
)))
{
/* TEMP minor!!!!! */
di
->
events
.
btemp_underover
=
false
;
di
->
events
.
btemp_lowhigh
=
true
;
di
->
t_hyst_norm
=
di
->
b
at
->
temp_hysteresis
;
di
->
t_hyst_norm
=
di
->
b
m
->
temp_hysteresis
;
di
->
t_hyst_lowhigh
=
0
;
}
else
if
(
di
->
batt_data
.
temp
<=
di
->
b
at
->
temp_under
||
di
->
batt_data
.
temp
>=
di
->
b
at
->
temp_over
)
{
}
else
if
(
di
->
batt_data
.
temp
<=
di
->
b
m
->
temp_under
||
di
->
batt_data
.
temp
>=
di
->
b
m
->
temp_over
)
{
/* TEMP major!!!!! */
di
->
events
.
btemp_underover
=
true
;
di
->
events
.
btemp_lowhigh
=
false
;
di
->
t_hyst_norm
=
0
;
di
->
t_hyst_lowhigh
=
di
->
b
at
->
temp_hysteresis
;
di
->
t_hyst_lowhigh
=
di
->
b
m
->
temp_hysteresis
;
}
else
{
/* Within hysteresis */
dev_dbg
(
di
->
dev
,
"Within hysteresis limit temp: %d "
...
...
@@ -682,12 +682,12 @@ static void abx500_chargalg_check_temp(struct abx500_chargalg *di)
*/
static
void
abx500_chargalg_check_charger_voltage
(
struct
abx500_chargalg
*
di
)
{
if
(
di
->
chg_info
.
usb_volt
>
di
->
b
at
->
chg_params
->
usb_volt_max
)
if
(
di
->
chg_info
.
usb_volt
>
di
->
b
m
->
chg_params
->
usb_volt_max
)
di
->
chg_info
.
usb_chg_ok
=
false
;
else
di
->
chg_info
.
usb_chg_ok
=
true
;
if
(
di
->
chg_info
.
ac_volt
>
di
->
b
at
->
chg_params
->
ac_volt_max
)
if
(
di
->
chg_info
.
ac_volt
>
di
->
b
m
->
chg_params
->
ac_volt_max
)
di
->
chg_info
.
ac_chg_ok
=
false
;
else
di
->
chg_info
.
ac_chg_ok
=
true
;
...
...
@@ -707,10 +707,10 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
if
(
di
->
charge_status
==
POWER_SUPPLY_STATUS_CHARGING
&&
di
->
charge_state
==
STATE_NORMAL
&&
!
di
->
maintenance_chg
&&
(
di
->
batt_data
.
volt
>=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
termination_vol
||
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
termination_vol
||
di
->
events
.
usb_cv_active
||
di
->
events
.
ac_cv_active
)
&&
di
->
batt_data
.
avg_curr
<
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
termination_curr
&&
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
termination_curr
&&
di
->
batt_data
.
avg_curr
>
0
)
{
if
(
++
di
->
eoc_cnt
>=
EOC_COND_CNT
)
{
di
->
eoc_cnt
=
0
;
...
...
@@ -733,12 +733,12 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
static
void
init_maxim_chg_curr
(
struct
abx500_chargalg
*
di
)
{
di
->
ccm
.
original_iset
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
normal_cur_lvl
;
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
normal_cur_lvl
;
di
->
ccm
.
current_iset
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
normal_cur_lvl
;
di
->
ccm
.
test_delta_i
=
di
->
b
at
->
maxi
->
charger_curr_step
;
di
->
ccm
.
max_current
=
di
->
b
at
->
maxi
->
chg_curr
;
di
->
ccm
.
condition_cnt
=
di
->
b
at
->
maxi
->
wait_cycles
;
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
normal_cur_lvl
;
di
->
ccm
.
test_delta_i
=
di
->
b
m
->
maxi
->
charger_curr_step
;
di
->
ccm
.
max_current
=
di
->
b
m
->
maxi
->
chg_curr
;
di
->
ccm
.
condition_cnt
=
di
->
b
m
->
maxi
->
wait_cycles
;
di
->
ccm
.
level
=
0
;
}
...
...
@@ -755,7 +755,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
{
int
delta_i
;
if
(
!
di
->
b
at
->
maxi
->
ena_maxi
)
if
(
!
di
->
b
m
->
maxi
->
ena_maxi
)
return
MAXIM_RET_NOACTION
;
delta_i
=
di
->
ccm
.
original_iset
-
di
->
batt_data
.
inst_curr
;
...
...
@@ -766,7 +766,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
if
(
di
->
ccm
.
wait_cnt
==
0
)
{
dev_dbg
(
di
->
dev
,
"lowering current
\n
"
);
di
->
ccm
.
wait_cnt
++
;
di
->
ccm
.
condition_cnt
=
di
->
b
at
->
maxi
->
wait_cycles
;
di
->
ccm
.
condition_cnt
=
di
->
b
m
->
maxi
->
wait_cycles
;
di
->
ccm
.
max_current
=
di
->
ccm
.
current_iset
-
di
->
ccm
.
test_delta_i
;
di
->
ccm
.
current_iset
=
di
->
ccm
.
max_current
;
...
...
@@ -791,7 +791,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
if
(
di
->
ccm
.
current_iset
==
di
->
ccm
.
original_iset
)
return
MAXIM_RET_NOACTION
;
di
->
ccm
.
condition_cnt
=
di
->
b
at
->
maxi
->
wait_cycles
;
di
->
ccm
.
condition_cnt
=
di
->
b
m
->
maxi
->
wait_cycles
;
di
->
ccm
.
current_iset
=
di
->
ccm
.
original_iset
;
di
->
ccm
.
level
=
0
;
...
...
@@ -803,7 +803,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
di
->
ccm
.
max_current
)
{
if
(
di
->
ccm
.
condition_cnt
--
==
0
)
{
/* Increse the iset with cco.test_delta_i */
di
->
ccm
.
condition_cnt
=
di
->
b
at
->
maxi
->
wait_cycles
;
di
->
ccm
.
condition_cnt
=
di
->
b
m
->
maxi
->
wait_cycles
;
di
->
ccm
.
current_iset
+=
di
->
ccm
.
test_delta_i
;
di
->
ccm
.
level
++
;
dev_dbg
(
di
->
dev
,
" Maximization needed, increase"
...
...
@@ -818,7 +818,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
return
MAXIM_RET_NOACTION
;
}
}
else
{
di
->
ccm
.
condition_cnt
=
di
->
b
at
->
maxi
->
wait_cycles
;
di
->
ccm
.
condition_cnt
=
di
->
b
m
->
maxi
->
wait_cycles
;
return
MAXIM_RET_NOACTION
;
}
}
...
...
@@ -838,7 +838,7 @@ static void handle_maxim_chg_curr(struct abx500_chargalg *di)
break
;
case
MAXIM_RET_IBAT_TOO_HIGH
:
result
=
abx500_chargalg_update_chg_curr
(
di
,
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
normal_cur_lvl
);
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
normal_cur_lvl
);
if
(
result
)
dev_err
(
di
->
dev
,
"failed to set chg curr
\n
"
);
break
;
...
...
@@ -1210,7 +1210,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
* this way
*/
if
(
!
charger_status
||
(
di
->
events
.
batt_unknown
&&
!
di
->
b
at
->
chg_unknown_bat
))
{
(
di
->
events
.
batt_unknown
&&
!
di
->
b
m
->
chg_unknown_bat
))
{
if
(
di
->
charge_state
!=
STATE_HANDHELD
)
{
di
->
events
.
safety_timer_expired
=
false
;
abx500_chargalg_state_to
(
di
,
STATE_HANDHELD_INIT
);
...
...
@@ -1394,8 +1394,8 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_NORMAL_INIT
:
abx500_chargalg_start_charging
(
di
,
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
normal_vol_lvl
,
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
normal_cur_lvl
);
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
normal_vol_lvl
,
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
normal_cur_lvl
);
abx500_chargalg_state_to
(
di
,
STATE_NORMAL
);
abx500_chargalg_start_safety_timer
(
di
);
abx500_chargalg_stop_maintenance_timer
(
di
);
...
...
@@ -1411,7 +1411,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
handle_maxim_chg_curr
(
di
);
if
(
di
->
charge_status
==
POWER_SUPPLY_STATUS_FULL
&&
di
->
maintenance_chg
)
{
if
(
di
->
b
at
->
no_maintenance
)
if
(
di
->
b
m
->
no_maintenance
)
abx500_chargalg_state_to
(
di
,
STATE_WAIT_FOR_RECHARGE_INIT
);
else
...
...
@@ -1429,7 +1429,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_WAIT_FOR_RECHARGE
:
if
(
di
->
batt_data
.
volt
<=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
recharge_vol
)
{
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
recharge_vol
)
{
if
(
di
->
rch_cnt
--
==
0
)
abx500_chargalg_state_to
(
di
,
STATE_NORMAL_INIT
);
}
else
...
...
@@ -1439,13 +1439,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_MAINTENANCE_A_INIT
:
abx500_chargalg_stop_safety_timer
(
di
);
abx500_chargalg_start_maintenance_timer
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_a_chg_timer_h
);
di
->
b
m
->
bat_type
[
di
->
b
m
->
batt_id
].
maint_a_chg_timer_h
);
abx500_chargalg_start_charging
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_a_vol_lvl
,
di
->
b
at
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_a_cur_lvl
);
di
->
b
m
->
bat_type
[
di
->
b
m
->
batt_id
].
maint_a_vol_lvl
,
di
->
b
m
->
bat_type
[
di
->
b
m
->
batt_id
].
maint_a_cur_lvl
);
abx500_chargalg_state_to
(
di
,
STATE_MAINTENANCE_A
);
power_supply_changed
(
&
di
->
chargalg_psy
);
/* Intentional fallthrough*/
...
...
@@ -1459,13 +1459,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_MAINTENANCE_B_INIT
:
abx500_chargalg_start_maintenance_timer
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_b_chg_timer_h
);
di
->
b
m
->
bat_type
[
di
->
b
m
->
batt_id
].
maint_b_chg_timer_h
);
abx500_chargalg_start_charging
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_b_vol_lvl
,
di
->
b
at
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_b_cur_lvl
);
di
->
b
m
->
bat_type
[
di
->
b
m
->
batt_id
].
maint_b_vol_lvl
,
di
->
b
m
->
bat_type
[
di
->
b
m
->
batt_id
].
maint_b_cur_lvl
);
abx500_chargalg_state_to
(
di
,
STATE_MAINTENANCE_B
);
power_supply_changed
(
&
di
->
chargalg_psy
);
/* Intentional fallthrough*/
...
...
@@ -1479,10 +1479,10 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_TEMP_LOWHIGH_INIT
:
abx500_chargalg_start_charging
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
at
->
batt_id
].
low_high_vol_lvl
,
di
->
b
at
->
bat_type
[
di
->
b
at
->
batt_id
].
low_high_cur_lvl
);
di
->
b
m
->
bat_type
[
di
->
b
m
->
batt_id
].
low_high_vol_lvl
,
di
->
b
m
->
bat_type
[
di
->
b
m
->
batt_id
].
low_high_cur_lvl
);
abx500_chargalg_stop_maintenance_timer
(
di
);
di
->
charge_status
=
POWER_SUPPLY_STATUS_CHARGING
;
abx500_chargalg_state_to
(
di
,
STATE_TEMP_LOWHIGH
);
...
...
@@ -1543,11 +1543,11 @@ static void abx500_chargalg_periodic_work(struct work_struct *work)
if
(
di
->
chg_info
.
conn_chg
)
queue_delayed_work
(
di
->
chargalg_wq
,
&
di
->
chargalg_periodic_work
,
di
->
b
at
->
interval_charging
*
HZ
);
di
->
b
m
->
interval_charging
*
HZ
);
else
queue_delayed_work
(
di
->
chargalg_wq
,
&
di
->
chargalg_periodic_work
,
di
->
b
at
->
interval_not_charging
*
HZ
);
di
->
b
m
->
interval_not_charging
*
HZ
);
}
/**
...
...
@@ -1614,7 +1614,7 @@ static int abx500_chargalg_get_property(struct power_supply *psy,
if
(
di
->
events
.
batt_ovv
)
{
val
->
intval
=
POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
}
else
if
(
di
->
events
.
btemp_underover
)
{
if
(
di
->
batt_data
.
temp
<=
di
->
b
at
->
temp_under
)
if
(
di
->
batt_data
.
temp
<=
di
->
b
m
->
temp_under
)
val
->
intval
=
POWER_SUPPLY_HEALTH_COLD
;
else
val
->
intval
=
POWER_SUPPLY_HEALTH_OVERHEAT
;
...
...
@@ -1806,6 +1806,7 @@ static char *supply_interface[] = {
static
int
abx500_chargalg_probe
(
struct
platform_device
*
pdev
)
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
abx500_bm_data
*
plat
=
pdev
->
dev
.
platform_data
;
struct
abx500_chargalg
*
di
;
int
ret
=
0
;
...
...
@@ -1814,21 +1815,19 @@ static int abx500_chargalg_probe(struct platform_device *pdev)
dev_err
(
&
pdev
->
dev
,
"%s no mem for ab8500_chargalg
\n
"
,
__func__
);
return
-
ENOMEM
;
}
di
->
bat
=
pdev
->
mfd_cell
->
platform_data
;
if
(
!
di
->
b
at
)
{
if
(
np
)
{
ret
=
bmdevs_of_probe
(
&
pdev
->
dev
,
np
,
&
di
->
bat
)
;
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get battery information
\n
"
);
return
ret
;
}
}
else
{
dev_err
(
&
pdev
->
dev
,
"
missing dt node for ab8500_chargalg
\n
"
);
return
-
EINVAL
;
if
(
!
pl
at
)
{
dev_err
(
&
pdev
->
dev
,
"no battery management data supplied
\n
"
);
return
-
EINVAL
;
}
di
->
bm
=
plat
;
if
(
np
)
{
ret
=
ab8500_bm_of_probe
(
&
pdev
->
dev
,
np
,
di
->
bm
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"
failed to get battery information
\n
"
);
return
ret
;
}
}
else
{
dev_info
(
&
pdev
->
dev
,
"falling back to legacy platform data
\n
"
);
}
/* get device struct */
...
...
include/linux/mfd/abx500.h
View file @
240fbe23
...
...
@@ -279,9 +279,9 @@ enum {
NTC_INTERNAL
,
};
int
bmdevs
_of_probe
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
abx500_bm_data
**
battery
);
int
ab8500_bm
_of_probe
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
abx500_bm_data
*
bm
);
int
abx500_set_register_interruptible
(
struct
device
*
dev
,
u8
bank
,
u8
reg
,
u8
value
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment