Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
240fbe23
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
170
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
240fbe23
编写于
1月 05, 2013
作者:
A
Anton Vorontsov
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-anton' of
git://git.linaro.org/people/ljones/linux-3.0-ux500
上级
2fbb520d
215cf5c9
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
594 addition
and
519 deletion
+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
未找到文件。
drivers/mfd/ab8500-core.c
浏览文件 @
240fbe23
...
@@ -1011,40 +1011,32 @@ static struct mfd_cell ab8500_bm_devs[] = {
...
@@ -1011,40 +1011,32 @@ static struct mfd_cell ab8500_bm_devs[] = {
.
of_compatible
=
"stericsson,ab8500-charger"
,
.
of_compatible
=
"stericsson,ab8500-charger"
,
.
num_resources
=
ARRAY_SIZE
(
ab8500_charger_resources
),
.
num_resources
=
ARRAY_SIZE
(
ab8500_charger_resources
),
.
resources
=
ab8500_charger_resources
,
.
resources
=
ab8500_charger_resources
,
#ifndef CONFIG_OF
.
platform_data
=
&
ab8500_bm_data
,
.
platform_data
=
&
ab8500_bm_data
,
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
#endif
},
},
{
{
.
name
=
"ab8500-btemp"
,
.
name
=
"ab8500-btemp"
,
.
of_compatible
=
"stericsson,ab8500-btemp"
,
.
of_compatible
=
"stericsson,ab8500-btemp"
,
.
num_resources
=
ARRAY_SIZE
(
ab8500_btemp_resources
),
.
num_resources
=
ARRAY_SIZE
(
ab8500_btemp_resources
),
.
resources
=
ab8500_btemp_resources
,
.
resources
=
ab8500_btemp_resources
,
#ifndef CONFIG_OF
.
platform_data
=
&
ab8500_bm_data
,
.
platform_data
=
&
ab8500_bm_data
,
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
#endif
},
},
{
{
.
name
=
"ab8500-fg"
,
.
name
=
"ab8500-fg"
,
.
of_compatible
=
"stericsson,ab8500-fg"
,
.
of_compatible
=
"stericsson,ab8500-fg"
,
.
num_resources
=
ARRAY_SIZE
(
ab8500_fg_resources
),
.
num_resources
=
ARRAY_SIZE
(
ab8500_fg_resources
),
.
resources
=
ab8500_fg_resources
,
.
resources
=
ab8500_fg_resources
,
#ifndef CONFIG_OF
.
platform_data
=
&
ab8500_bm_data
,
.
platform_data
=
&
ab8500_bm_data
,
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
#endif
},
},
{
{
.
name
=
"ab8500-chargalg"
,
.
name
=
"ab8500-chargalg"
,
.
of_compatible
=
"stericsson,ab8500-chargalg"
,
.
of_compatible
=
"stericsson,ab8500-chargalg"
,
.
num_resources
=
ARRAY_SIZE
(
ab8500_chargalg_resources
),
.
num_resources
=
ARRAY_SIZE
(
ab8500_chargalg_resources
),
.
resources
=
ab8500_chargalg_resources
,
.
resources
=
ab8500_chargalg_resources
,
#ifndef CONFIG_OF
.
platform_data
=
&
ab8500_bm_data
,
.
platform_data
=
&
ab8500_bm_data
,
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
.
pdata_size
=
sizeof
(
ab8500_bm_data
),
#endif
},
},
};
};
...
...
drivers/power/Makefile
浏览文件 @
240fbe23
...
@@ -38,7 +38,7 @@ obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
...
@@ -38,7 +38,7 @@ obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_JZ4740)
+=
jz4740-battery.o
obj-$(CONFIG_BATTERY_JZ4740)
+=
jz4740-battery.o
obj-$(CONFIG_BATTERY_INTEL_MID)
+=
intel_mid_battery.o
obj-$(CONFIG_BATTERY_INTEL_MID)
+=
intel_mid_battery.o
obj-$(CONFIG_BATTERY_RX51)
+=
rx51_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_ISP1704)
+=
isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903)
+=
max8903_charger.o
obj-$(CONFIG_CHARGER_MAX8903)
+=
max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030)
+=
twl4030_charger.o
obj-$(CONFIG_CHARGER_TWL4030)
+=
twl4030_charger.o
...
...
drivers/power/ab8500_bmdata.c
浏览文件 @
240fbe23
...
@@ -182,206 +182,206 @@ static struct batres_vs_temp temp_to_batres_tbl_9100[] = {
...
@@ -182,206 +182,206 @@ static struct batres_vs_temp temp_to_batres_tbl_9100[] = {
};
};
static
struct
abx500_battery_type
bat_type_thermistor
[]
=
{
static
struct
abx500_battery_type
bat_type_thermistor
[]
=
{
[
BATTERY_UNKNOWN
]
=
{
[
BATTERY_UNKNOWN
]
=
{
/* First element always represent the UNKNOWN battery */
/* First element always represent the UNKNOWN battery */
.
name
=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
.
name
=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
.
resis_high
=
0
,
.
resis_high
=
0
,
.
resis_low
=
0
,
.
resis_low
=
0
,
.
battery_resistance
=
300
,
.
battery_resistance
=
300
,
.
charge_full_design
=
612
,
.
charge_full_design
=
612
,
.
nominal_voltage
=
3700
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4050
,
.
termination_vol
=
4050
,
.
termination_curr
=
200
,
.
termination_curr
=
200
,
.
recharge_vol
=
3990
,
.
recharge_vol
=
3990
,
.
normal_cur_lvl
=
400
,
.
normal_cur_lvl
=
400
,
.
normal_vol_lvl
=
4100
,
.
normal_vol_lvl
=
4100
,
.
maint_a_cur_lvl
=
400
,
.
maint_a_cur_lvl
=
400
,
.
maint_a_vol_lvl
=
4050
,
.
maint_a_vol_lvl
=
4050
,
.
maint_a_chg_timer_h
=
60
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
400
,
.
maint_b_cur_lvl
=
400
,
.
maint_b_vol_lvl
=
4000
,
.
maint_b_vol_lvl
=
4000
,
.
maint_b_chg_timer_h
=
200
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
r_to_t_tbl
=
temp_tbl
,
.
r_to_t_tbl
=
temp_tbl
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
v_to_cap_tbl
=
cap_tbl
,
.
v_to_cap_tbl
=
cap_tbl
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
},
},
{
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
resis_high
=
53407
,
.
resis_high
=
53407
,
.
resis_low
=
12500
,
.
resis_low
=
12500
,
.
battery_resistance
=
300
,
.
battery_resistance
=
300
,
.
charge_full_design
=
900
,
.
charge_full_design
=
900
,
.
nominal_voltage
=
3600
,
.
nominal_voltage
=
3600
,
.
termination_vol
=
4150
,
.
termination_vol
=
4150
,
.
termination_curr
=
80
,
.
termination_curr
=
80
,
.
recharge_vol
=
4130
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl_A_thermistor
),
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl_A_thermistor
),
.
r_to_t_tbl
=
temp_tbl_A_thermistor
,
.
r_to_t_tbl
=
temp_tbl_A_thermistor
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl_A_thermistor
),
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl_A_thermistor
),
.
v_to_cap_tbl
=
cap_tbl_A_thermistor
,
.
v_to_cap_tbl
=
cap_tbl_A_thermistor
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
},
},
{
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
resis_high
=
200000
,
.
resis_high
=
200000
,
.
resis_low
=
82869
,
.
resis_low
=
82869
,
.
battery_resistance
=
300
,
.
battery_resistance
=
300
,
.
charge_full_design
=
900
,
.
charge_full_design
=
900
,
.
nominal_voltage
=
3600
,
.
nominal_voltage
=
3600
,
.
termination_vol
=
4150
,
.
termination_vol
=
4150
,
.
termination_curr
=
80
,
.
termination_curr
=
80
,
.
recharge_vol
=
4130
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl_B_thermistor
),
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl_B_thermistor
),
.
r_to_t_tbl
=
temp_tbl_B_thermistor
,
.
r_to_t_tbl
=
temp_tbl_B_thermistor
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl_B_thermistor
),
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl_B_thermistor
),
.
v_to_cap_tbl
=
cap_tbl_B_thermistor
,
.
v_to_cap_tbl
=
cap_tbl_B_thermistor
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
},
},
};
};
static
struct
abx500_battery_type
bat_type_ext_thermistor
[]
=
{
static
struct
abx500_battery_type
bat_type_ext_thermistor
[]
=
{
[
BATTERY_UNKNOWN
]
=
{
[
BATTERY_UNKNOWN
]
=
{
/* First element always represent the UNKNOWN battery */
/* First element always represent the UNKNOWN battery */
.
name
=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
.
name
=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN
,
.
resis_high
=
0
,
.
resis_high
=
0
,
.
resis_low
=
0
,
.
resis_low
=
0
,
.
battery_resistance
=
300
,
.
battery_resistance
=
300
,
.
charge_full_design
=
612
,
.
charge_full_design
=
612
,
.
nominal_voltage
=
3700
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4050
,
.
termination_vol
=
4050
,
.
termination_curr
=
200
,
.
termination_curr
=
200
,
.
recharge_vol
=
3990
,
.
recharge_vol
=
3990
,
.
normal_cur_lvl
=
400
,
.
normal_cur_lvl
=
400
,
.
normal_vol_lvl
=
4100
,
.
normal_vol_lvl
=
4100
,
.
maint_a_cur_lvl
=
400
,
.
maint_a_cur_lvl
=
400
,
.
maint_a_vol_lvl
=
4050
,
.
maint_a_vol_lvl
=
4050
,
.
maint_a_chg_timer_h
=
60
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
400
,
.
maint_b_cur_lvl
=
400
,
.
maint_b_vol_lvl
=
4000
,
.
maint_b_vol_lvl
=
4000
,
.
maint_b_chg_timer_h
=
200
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
r_to_t_tbl
=
temp_tbl
,
.
r_to_t_tbl
=
temp_tbl
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
v_to_cap_tbl
=
cap_tbl
,
.
v_to_cap_tbl
=
cap_tbl
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
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
* 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
* its temperature. The temperature in this case is measure with a NTC placed
* near the battery but on the PCB.
* near the battery but on the PCB.
*/
*/
{
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
name
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
resis_high
=
76000
,
.
resis_high
=
76000
,
.
resis_low
=
53000
,
.
resis_low
=
53000
,
.
battery_resistance
=
300
,
.
battery_resistance
=
300
,
.
charge_full_design
=
900
,
.
charge_full_design
=
900
,
.
nominal_voltage
=
3700
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4150
,
.
termination_vol
=
4150
,
.
termination_curr
=
100
,
.
termination_curr
=
100
,
.
recharge_vol
=
4130
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
r_to_t_tbl
=
temp_tbl
,
.
r_to_t_tbl
=
temp_tbl
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
v_to_cap_tbl
=
cap_tbl
,
.
v_to_cap_tbl
=
cap_tbl
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
},
},
{
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LION
,
.
name
=
POWER_SUPPLY_TECHNOLOGY_LION
,
.
resis_high
=
30000
,
.
resis_high
=
30000
,
.
resis_low
=
10000
,
.
resis_low
=
10000
,
.
battery_resistance
=
300
,
.
battery_resistance
=
300
,
.
charge_full_design
=
950
,
.
charge_full_design
=
950
,
.
nominal_voltage
=
3700
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4150
,
.
termination_vol
=
4150
,
.
termination_curr
=
100
,
.
termination_curr
=
100
,
.
recharge_vol
=
4130
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
r_to_t_tbl
=
temp_tbl
,
.
r_to_t_tbl
=
temp_tbl
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
v_to_cap_tbl
=
cap_tbl
,
.
v_to_cap_tbl
=
cap_tbl
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
},
},
{
{
.
name
=
POWER_SUPPLY_TECHNOLOGY_LION
,
.
name
=
POWER_SUPPLY_TECHNOLOGY_LION
,
.
resis_high
=
95000
,
.
resis_high
=
95000
,
.
resis_low
=
76001
,
.
resis_low
=
76001
,
.
battery_resistance
=
300
,
.
battery_resistance
=
300
,
.
charge_full_design
=
950
,
.
charge_full_design
=
950
,
.
nominal_voltage
=
3700
,
.
nominal_voltage
=
3700
,
.
termination_vol
=
4150
,
.
termination_vol
=
4150
,
.
termination_curr
=
100
,
.
termination_curr
=
100
,
.
recharge_vol
=
4130
,
.
recharge_vol
=
4130
,
.
normal_cur_lvl
=
700
,
.
normal_cur_lvl
=
700
,
.
normal_vol_lvl
=
4200
,
.
normal_vol_lvl
=
4200
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_cur_lvl
=
600
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_vol_lvl
=
4150
,
.
maint_a_chg_timer_h
=
60
,
.
maint_a_chg_timer_h
=
60
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_cur_lvl
=
600
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_vol_lvl
=
4100
,
.
maint_b_chg_timer_h
=
200
,
.
maint_b_chg_timer_h
=
200
,
.
low_high_cur_lvl
=
300
,
.
low_high_cur_lvl
=
300
,
.
low_high_vol_lvl
=
4000
,
.
low_high_vol_lvl
=
4000
,
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
n_temp_tbl_elements
=
ARRAY_SIZE
(
temp_tbl
),
.
r_to_t_tbl
=
temp_tbl
,
.
r_to_t_tbl
=
temp_tbl
,
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
n_v_cap_tbl_elements
=
ARRAY_SIZE
(
cap_tbl
),
.
v_to_cap_tbl
=
cap_tbl
,
.
v_to_cap_tbl
=
cap_tbl
,
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
n_batres_tbl_elements
=
ARRAY_SIZE
(
temp_to_batres_tbl_thermistor
),
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
.
batres_tbl
=
temp_to_batres_tbl_thermistor
,
},
},
};
};
static
const
struct
abx500_bm_capacity_levels
cap_levels
=
{
static
const
struct
abx500_bm_capacity_levels
cap_levels
=
{
...
@@ -424,98 +424,83 @@ static const struct abx500_bm_charger_parameters chg = {
...
@@ -424,98 +424,83 @@ static const struct abx500_bm_charger_parameters chg = {
};
};
struct
abx500_bm_data
ab8500_bm_data
=
{
struct
abx500_bm_data
ab8500_bm_data
=
{
.
temp_under
=
3
,
.
temp_under
=
3
,
.
temp_low
=
8
,
.
temp_low
=
8
,
.
temp_high
=
43
,
.
temp_high
=
43
,
.
temp_over
=
48
,
.
temp_over
=
48
,
.
main_safety_tmr_h
=
4
,
.
main_safety_tmr_h
=
4
,
.
temp_interval_chg
=
20
,
.
temp_interval_chg
=
20
,
.
temp_interval_nochg
=
120
,
.
temp_interval_nochg
=
120
,
.
usb_safety_tmr_h
=
4
,
.
usb_safety_tmr_h
=
4
,
.
bkup_bat_v
=
BUP_VCH_SEL_2P6V
,
.
bkup_bat_v
=
BUP_VCH_SEL_2P6V
,
.
bkup_bat_i
=
BUP_ICH_SEL_150UA
,
.
bkup_bat_i
=
BUP_ICH_SEL_150UA
,
.
no_maintenance
=
false
,
.
no_maintenance
=
false
,
.
adc_therm
=
ABx500_ADC_THERM_BATCTRL
,
.
adc_therm
=
ABx500_ADC_THERM_BATCTRL
,
.
chg_unknown_bat
=
false
,
.
chg_unknown_bat
=
false
,
.
enable_overshoot
=
false
,
.
enable_overshoot
=
false
,
.
fg_res
=
100
,
.
fg_res
=
100
,
.
cap_levels
=
&
cap_levels
,
.
cap_levels
=
&
cap_levels
,
.
bat_type
=
bat_type_thermistor
,
.
bat_type
=
bat_type_thermistor
,
.
n_btypes
=
3
,
.
n_btypes
=
3
,
.
batt_id
=
0
,
.
batt_id
=
0
,
.
interval_charging
=
5
,
.
interval_charging
=
5
,
.
interval_not_charging
=
120
,
.
interval_not_charging
=
120
,
.
temp_hysteresis
=
3
,
.
temp_hysteresis
=
3
,
.
gnd_lift_resistance
=
34
,
.
gnd_lift_resistance
=
34
,
.
maxi
=
&
maxi_params
,
.
maxi
=
&
maxi_params
,
.
chg_params
=
&
chg
,
.
chg_params
=
&
chg
,
.
fg_params
=
&
fg
,
.
fg_params
=
&
fg
,
};
};
int
__devinit
int
__devinit
ab8500_bm_of_probe
(
struct
device
*
dev
,
bmdevs_of_probe
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
device_node
*
np
,
struct
abx500_bm_data
*
bm
)
struct
abx500_bm_data
**
battery
)
{
{
struct
abx500_battery_type
*
btype
;
struct
batres_vs_temp
*
tmp_batres_tbl
;
struct
device_node
*
np_bat_supply
;
struct
device_node
*
battery_node
;
struct
abx500_bm_data
*
bat
;
const
char
*
btech
;
const
char
*
btech
;
char
bat_tech
[
8
];
int
i
;
int
i
,
thermistor
;
*
battery
=
&
ab8500_bm_data
;
/* get phandle to 'battery-info' node */
/* get phandle to 'battery-info' node */
np_bat_supply
=
of_parse_phandle
(
np
,
"battery"
,
0
);
battery_node
=
of_parse_phandle
(
np
,
"battery"
,
0
);
if
(
!
np_bat_supply
)
{
if
(
!
battery_node
)
{
dev_err
(
dev
,
"
missing property battery
\n
"
);
dev_err
(
dev
,
"
battery node or reference missing
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
(
of_property_read_bool
(
np_bat_supply
,
"thermistor-on-batctrl"
))
thermistor
=
NTC_INTERNAL
;
else
thermistor
=
NTC_EXTERNAL
;
bat
=
*
battery
;
btech
=
of_get_property
(
battery_node
,
"stericsson,battery-type"
,
NULL
);
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
);
if
(
!
btech
)
{
if
(
!
btech
)
{
dev_warn
(
dev
,
"missing property battery-name/type
\n
"
);
dev_warn
(
dev
,
"missing property battery-name/type
\n
"
);
strcpy
(
bat_tech
,
"UNKNOWN"
);
return
-
EINVAL
;
}
else
{
strcpy
(
bat_tech
,
btech
);
}
}
if
(
strncmp
(
b
at_
tech
,
"LION"
,
4
)
==
0
)
{
if
(
strncmp
(
btech
,
"LION"
,
4
)
==
0
)
{
b
at
->
no_maintenance
=
true
;
b
m
->
no_maintenance
=
true
;
b
at
->
chg_unknown_bat
=
true
;
b
m
->
chg_unknown_bat
=
true
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
charge_full_design
=
2600
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
charge_full_design
=
2600
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
termination_vol
=
4150
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
termination_vol
=
4150
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
recharge_vol
=
4130
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
recharge_vol
=
4130
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
normal_cur_lvl
=
520
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
normal_cur_lvl
=
520
;
b
at
->
bat_type
[
BATTERY_UNKNOWN
].
normal_vol_lvl
=
4200
;
b
m
->
bat_type
[
BATTERY_UNKNOWN
].
normal_vol_lvl
=
4200
;
}
}
/* select the battery resolution table */
for
(
i
=
0
;
i
<
bat
->
n_btypes
;
++
i
)
{
if
(
of_property_read_bool
(
battery_node
,
"thermistor-on-batctrl"
))
{
btype
=
(
bat
->
bat_type
+
i
);
if
(
strncmp
(
btech
,
"LION"
,
4
)
==
0
)
if
(
thermistor
==
NTC_EXTERNAL
)
{
tmp_batres_tbl
=
temp_to_batres_tbl_9100
;
btype
->
batres_tbl
=
else
temp_to_batres_tbl_ext_thermistor
;
tmp_batres_tbl
=
temp_to_batres_tbl_thermistor
;
}
else
if
(
strncmp
(
bat_tech
,
"LION"
,
4
)
==
0
)
{
}
else
{
btype
->
batres_tbl
=
bm
->
n_btypes
=
4
;
temp_to_batres_tbl_9100
;
bm
->
bat_type
=
bat_type_ext_thermistor
;
}
else
{
bm
->
adc_therm
=
ABx500_ADC_THERM_BATTEMP
;
btype
->
batres_tbl
=
tmp_batres_tbl
=
temp_to_batres_tbl_ext_thermistor
;
temp_to_batres_tbl_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
;
return
0
;
}
}
drivers/power/ab8500_btemp.c
浏览文件 @
240fbe23
...
@@ -78,12 +78,13 @@ struct ab8500_btemp_ranges {
...
@@ -78,12 +78,13 @@ struct ab8500_btemp_ranges {
* @parent: Pointer to the struct ab8500
* @parent: Pointer to the struct ab8500
* @gpadc: Pointer to the struct gpadc
* @gpadc: Pointer to the struct gpadc
* @fg: Pointer to the struct fg
* @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
* @btemp_psy: Structure for BTEMP specific battery properties
* @events: Structure for information about events triggered
* @events: Structure for information about events triggered
* @btemp_ranges: Battery temperature range structure
* @btemp_ranges: Battery temperature range structure
* @btemp_wq: Work queue for measuring the temperature periodically
* @btemp_wq: Work queue for measuring the temperature periodically
* @btemp_periodic_work: Work for measuring the temperature periodically
* @btemp_periodic_work: Work for measuring the temperature periodically
* @initialized: True if battery id read.
*/
*/
struct
ab8500_btemp
{
struct
ab8500_btemp
{
struct
device
*
dev
;
struct
device
*
dev
;
...
@@ -94,12 +95,13 @@ struct ab8500_btemp {
...
@@ -94,12 +95,13 @@ struct ab8500_btemp {
struct
ab8500
*
parent
;
struct
ab8500
*
parent
;
struct
ab8500_gpadc
*
gpadc
;
struct
ab8500_gpadc
*
gpadc
;
struct
ab8500_fg
*
fg
;
struct
ab8500_fg
*
fg
;
struct
abx500_bm_data
*
b
at
;
struct
abx500_bm_data
*
b
m
;
struct
power_supply
btemp_psy
;
struct
power_supply
btemp_psy
;
struct
ab8500_btemp_events
events
;
struct
ab8500_btemp_events
events
;
struct
ab8500_btemp_ranges
btemp_ranges
;
struct
ab8500_btemp_ranges
btemp_ranges
;
struct
workqueue_struct
*
btemp_wq
;
struct
workqueue_struct
*
btemp_wq
;
struct
delayed_work
btemp_periodic_work
;
struct
delayed_work
btemp_periodic_work
;
bool
initialized
;
};
};
/* BTEMP power supply properties */
/* BTEMP power supply properties */
...
@@ -147,13 +149,13 @@ static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di,
...
@@ -147,13 +149,13 @@ static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di,
return
(
450000
*
(
v_batctrl
))
/
(
1800
-
v_batctrl
);
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
* If the battery has internal NTC, we use the current
* source to calculate the resistance, 7uA or 20uA
* source to calculate the resistance, 7uA or 20uA
*/
*/
rbs
=
(
v_batctrl
*
1000
rbs
=
(
v_batctrl
*
1000
-
di
->
b
at
->
gnd_lift_resistance
*
inst_curr
)
-
di
->
b
m
->
gnd_lift_resistance
*
inst_curr
)
/
di
->
curr_source
;
/
di
->
curr_source
;
}
else
{
}
else
{
/*
/*
...
@@ -209,7 +211,7 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di,
...
@@ -209,7 +211,7 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di,
return
0
;
return
0
;
/* Only do this for batteries with internal NTC */
/* 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
)
if
(
di
->
curr_source
==
BTEMP_BATCTRL_CURR_SRC_7UA
)
curr
=
BAT_CTRL_7U_ENA
;
curr
=
BAT_CTRL_7U_ENA
;
else
else
...
@@ -241,7 +243,7 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di,
...
@@ -241,7 +243,7 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di,
__func__
);
__func__
);
goto
disable_curr_source
;
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
"
);
dev_dbg
(
di
->
dev
,
"Disable BATCTRL curr source
\n
"
);
/* Write 0 to the curr bits */
/* Write 0 to the curr bits */
...
@@ -457,9 +459,9 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
...
@@ -457,9 +459,9 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
int
rbat
,
rntc
,
vntc
;
int
rbat
,
rntc
,
vntc
;
u8
id
;
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
)
{
id
!=
BATTERY_UNKNOWN
)
{
rbat
=
ab8500_btemp_get_batctrl_res
(
di
);
rbat
=
ab8500_btemp_get_batctrl_res
(
di
);
...
@@ -474,8 +476,8 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
...
@@ -474,8 +476,8 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
}
}
temp
=
ab8500_btemp_res_to_temp
(
di
,
temp
=
ab8500_btemp_res_to_temp
(
di
,
di
->
b
at
->
bat_type
[
id
].
r_to_t_tbl
,
di
->
b
m
->
bat_type
[
id
].
r_to_t_tbl
,
di
->
b
at
->
bat_type
[
id
].
n_temp_tbl_elements
,
rbat
);
di
->
b
m
->
bat_type
[
id
].
n_temp_tbl_elements
,
rbat
);
}
else
{
}
else
{
vntc
=
ab8500_gpadc_convert
(
di
->
gpadc
,
BTEMP_BALL
);
vntc
=
ab8500_gpadc_convert
(
di
->
gpadc
,
BTEMP_BALL
);
if
(
vntc
<
0
)
{
if
(
vntc
<
0
)
{
...
@@ -491,8 +493,8 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
...
@@ -491,8 +493,8 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
rntc
=
230000
*
vntc
/
(
VTVOUT_V
-
vntc
);
rntc
=
230000
*
vntc
/
(
VTVOUT_V
-
vntc
);
temp
=
ab8500_btemp_res_to_temp
(
di
,
temp
=
ab8500_btemp_res_to_temp
(
di
,
di
->
b
at
->
bat_type
[
id
].
r_to_t_tbl
,
di
->
b
m
->
bat_type
[
id
].
r_to_t_tbl
,
di
->
b
at
->
bat_type
[
id
].
n_temp_tbl_elements
,
rntc
);
di
->
b
m
->
bat_type
[
id
].
n_temp_tbl_elements
,
rntc
);
prev
=
temp
;
prev
=
temp
;
}
}
dev_dbg
(
di
->
dev
,
"Battery temperature is %d
\n
"
,
temp
);
dev_dbg
(
di
->
dev
,
"Battery temperature is %d
\n
"
,
temp
);
...
@@ -513,7 +515,7 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
...
@@ -513,7 +515,7 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
u8
i
;
u8
i
;
di
->
curr_source
=
BTEMP_BATCTRL_CURR_SRC_7UA
;
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
);
res
=
ab8500_btemp_get_batctrl_res
(
di
);
if
(
res
<
0
)
{
if
(
res
<
0
)
{
...
@@ -522,23 +524,23 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
...
@@ -522,23 +524,23 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
}
}
/* BATTERY_UNKNOWN is defined on position 0, skip it! */
/* BATTERY_UNKNOWN is defined on position 0, skip it! */
for
(
i
=
BATTERY_UNKNOWN
+
1
;
i
<
di
->
b
at
->
n_btypes
;
i
++
)
{
for
(
i
=
BATTERY_UNKNOWN
+
1
;
i
<
di
->
b
m
->
n_btypes
;
i
++
)
{
if
((
res
<=
di
->
b
at
->
bat_type
[
i
].
resis_high
)
&&
if
((
res
<=
di
->
b
m
->
bat_type
[
i
].
resis_high
)
&&
(
res
>=
di
->
b
at
->
bat_type
[
i
].
resis_low
))
{
(
res
>=
di
->
b
m
->
bat_type
[
i
].
resis_low
))
{
dev_dbg
(
di
->
dev
,
"Battery detected on %s"
dev_dbg
(
di
->
dev
,
"Battery detected on %s"
" low %d < res %d < high: %d"
" low %d < res %d < high: %d"
" index: %d
\n
"
,
" index: %d
\n
"
,
di
->
b
at
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
?
di
->
b
m
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
?
"BATCTRL"
:
"BATTEMP"
,
"BATCTRL"
:
"BATTEMP"
,
di
->
b
at
->
bat_type
[
i
].
resis_low
,
res
,
di
->
b
m
->
bat_type
[
i
].
resis_low
,
res
,
di
->
b
at
->
bat_type
[
i
].
resis_high
,
i
);
di
->
b
m
->
bat_type
[
i
].
resis_high
,
i
);
di
->
b
at
->
batt_id
=
i
;
di
->
b
m
->
batt_id
=
i
;
break
;
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"
dev_warn
(
di
->
dev
,
"Battery identified as unknown"
", resistance %d Ohm
\n
"
,
res
);
", resistance %d Ohm
\n
"
,
res
);
return
-
ENXIO
;
return
-
ENXIO
;
...
@@ -548,13 +550,13 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
...
@@ -548,13 +550,13 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
* We only have to change current source if the
* We only have to change current source if the
* detected type is Type 1, else we use the 7uA source
* detected type is Type 1, else we use the 7uA source
*/
*/
if
(
di
->
b
at
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
if
(
di
->
b
m
->
adc_therm
==
ABx500_ADC_THERM_BATCTRL
&&
di
->
b
at
->
batt_id
==
1
)
{
di
->
b
m
->
batt_id
==
1
)
{
dev_dbg
(
di
->
dev
,
"Set BATCTRL current source to 20uA
\n
"
);
dev_dbg
(
di
->
dev
,
"Set BATCTRL current source to 20uA
\n
"
);
di
->
curr_source
=
BTEMP_BATCTRL_CURR_SRC_20UA
;
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)
...
@@ -569,6 +571,13 @@ static void ab8500_btemp_periodic_work(struct work_struct *work)
struct
ab8500_btemp
*
di
=
container_of
(
work
,
struct
ab8500_btemp
*
di
=
container_of
(
work
,
struct
ab8500_btemp
,
btemp_periodic_work
.
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
);
di
->
bat_temp
=
ab8500_btemp_measure_temp
(
di
);
if
(
di
->
bat_temp
!=
di
->
prev_bat_temp
)
{
if
(
di
->
bat_temp
!=
di
->
prev_bat_temp
)
{
...
@@ -577,9 +586,9 @@ static void ab8500_btemp_periodic_work(struct work_struct *work)
...
@@ -577,9 +586,9 @@ static void ab8500_btemp_periodic_work(struct work_struct *work)
}
}
if
(
di
->
events
.
ac_conn
||
di
->
events
.
usb_conn
)
if
(
di
->
events
.
ac_conn
||
di
->
events
.
usb_conn
)
interval
=
di
->
b
at
->
temp_interval_chg
;
interval
=
di
->
b
m
->
temp_interval_chg
;
else
else
interval
=
di
->
b
at
->
temp_interval_nochg
;
interval
=
di
->
b
m
->
temp_interval_nochg
;
/* Schedule a new measurement */
/* Schedule a new measurement */
queue_delayed_work
(
di
->
btemp_wq
,
queue_delayed_work
(
di
->
btemp_wq
,
...
@@ -806,7 +815,7 @@ static int ab8500_btemp_get_property(struct power_supply *psy,
...
@@ -806,7 +815,7 @@ static int ab8500_btemp_get_property(struct power_supply *psy,
val
->
intval
=
1
;
val
->
intval
=
1
;
break
;
break
;
case
POWER_SUPPLY_PROP_TECHNOLOGY
:
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
;
break
;
case
POWER_SUPPLY_PROP_TEMP
:
case
POWER_SUPPLY_PROP_TEMP
:
val
->
intval
=
ab8500_btemp_get_temp
(
di
);
val
->
intval
=
ab8500_btemp_get_temp
(
di
);
...
@@ -967,6 +976,7 @@ static char *supply_interface[] = {
...
@@ -967,6 +976,7 @@ static char *supply_interface[] = {
static
int
ab8500_btemp_probe
(
struct
platform_device
*
pdev
)
static
int
ab8500_btemp_probe
(
struct
platform_device
*
pdev
)
{
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
abx500_bm_data
*
plat
=
pdev
->
dev
.
platform_data
;
struct
ab8500_btemp
*
di
;
struct
ab8500_btemp
*
di
;
int
irq
,
i
,
ret
=
0
;
int
irq
,
i
,
ret
=
0
;
u8
val
;
u8
val
;
...
@@ -976,21 +986,19 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
...
@@ -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__
);
dev_err
(
&
pdev
->
dev
,
"%s no mem for ab8500_btemp
\n
"
,
__func__
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
di
->
bat
=
pdev
->
mfd_cell
->
platform_data
;
if
(
!
di
->
b
at
)
{
if
(
!
pl
at
)
{
if
(
np
)
{
dev_err
(
&
pdev
->
dev
,
"no battery management data supplied
\n
"
);
ret
=
bmdevs_of_probe
(
&
pdev
->
dev
,
np
,
&
di
->
bat
)
;
return
-
EINVAL
;
if
(
ret
)
{
}
dev_err
(
&
pdev
->
dev
,
di
->
bm
=
plat
;
"failed to get battery information
\n
"
);
return
ret
;
if
(
np
)
{
}
ret
=
ab8500_bm_of_probe
(
&
pdev
->
dev
,
np
,
di
->
bm
);
}
else
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"
missing dt node for ab8500_btemp
\n
"
);
dev_err
(
&
pdev
->
dev
,
"
failed to get battery information
\n
"
);
return
-
EINVAL
;
return
ret
;
}
}
}
else
{
dev_info
(
&
pdev
->
dev
,
"falling back to legacy platform data
\n
"
);
}
}
/* get parent data */
/* get parent data */
...
@@ -998,6 +1006,8 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
...
@@ -998,6 +1006,8 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
di
->
parent
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
di
->
parent
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
di
->
gpadc
=
ab8500_gpadc_get
(
"ab8500-gpadc.0"
);
di
->
gpadc
=
ab8500_gpadc_get
(
"ab8500-gpadc.0"
);
di
->
initialized
=
false
;
/* BTEMP supply */
/* BTEMP supply */
di
->
btemp_psy
.
name
=
"ab8500_btemp"
;
di
->
btemp_psy
.
name
=
"ab8500_btemp"
;
di
->
btemp_psy
.
type
=
POWER_SUPPLY_TYPE_BATTERY
;
di
->
btemp_psy
.
type
=
POWER_SUPPLY_TYPE_BATTERY
;
...
@@ -1022,10 +1032,6 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
...
@@ -1022,10 +1032,6 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
INIT_DEFERRABLE_WORK
(
&
di
->
btemp_periodic_work
,
INIT_DEFERRABLE_WORK
(
&
di
->
btemp_periodic_work
,
ab8500_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 */
/* Set BTEMP thermal limits. Low and Med are fixed */
di
->
btemp_ranges
.
btemp_low_limit
=
BTEMP_THERMAL_LOW_LIMIT
;
di
->
btemp_ranges
.
btemp_low_limit
=
BTEMP_THERMAL_LOW_LIMIT
;
di
->
btemp_ranges
.
btemp_med_limit
=
BTEMP_THERMAL_MED_LIMIT
;
di
->
btemp_ranges
.
btemp_med_limit
=
BTEMP_THERMAL_MED_LIMIT
;
...
...
drivers/power/ab8500_charger.c
浏览文件 @
240fbe23
...
@@ -79,6 +79,9 @@
...
@@ -79,6 +79,9 @@
/* Lowest charger voltage is 3.39V -> 0x4E */
/* Lowest charger voltage is 3.39V -> 0x4E */
#define LOW_VOLT_REG 0x4E
#define LOW_VOLT_REG 0x4E
/* Step up/down delay in us */
#define STEP_UDELAY 1000
/* UsbLineStatus register - usb types */
/* UsbLineStatus register - usb types */
enum
ab8500_charger_link_status
{
enum
ab8500_charger_link_status
{
USB_STAT_NOT_CONFIGURED
,
USB_STAT_NOT_CONFIGURED
,
...
@@ -186,7 +189,7 @@ struct ab8500_charger_usb_state {
...
@@ -186,7 +189,7 @@ struct ab8500_charger_usb_state {
* @autopower_cfg platform specific power config support for "pwron after pwrloss"
* @autopower_cfg platform specific power config support for "pwron after pwrloss"
* @parent: Pointer to the struct ab8500
* @parent: Pointer to the struct ab8500
* @gpadc: Pointer to the struct gpadc
* @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
* @flags: Structure for information about events triggered
* @usb_state: Structure for usb stack information
* @usb_state: Structure for usb stack information
* @ac_chg: AC charger power supply
* @ac_chg: AC charger power supply
...
@@ -223,7 +226,7 @@ struct ab8500_charger {
...
@@ -223,7 +226,7 @@ struct ab8500_charger {
bool
autopower_cfg
;
bool
autopower_cfg
;
struct
ab8500
*
parent
;
struct
ab8500
*
parent
;
struct
ab8500_gpadc
*
gpadc
;
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_event_flags
flags
;
struct
ab8500_charger_usb_state
usb_state
;
struct
ab8500_charger_usb_state
usb_state
;
struct
ux500_charger
ac_chg
;
struct
ux500_charger
ac_chg
;
...
@@ -935,6 +938,88 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
...
@@ -935,6 +938,88 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
return
0
;
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
* ab8500_charger_set_vbus_in_curr() - set VBUS input current limit
* @di: pointer to the ab8500_charger structure
* @di: pointer to the ab8500_charger structure
...
@@ -946,12 +1031,10 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
...
@@ -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
,
static
int
ab8500_charger_set_vbus_in_curr
(
struct
ab8500_charger
*
di
,
int
ich_in
)
int
ich_in
)
{
{
int
ret
;
int
input_curr_index
;
int
min_value
;
int
min_value
;
/* We should always use to lowest current limit */
/* 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
)
{
switch
(
min_value
)
{
case
100
:
case
100
:
...
@@ -966,19 +1049,38 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di,
...
@@ -966,19 +1049,38 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di,
break
;
break
;
}
}
input_curr_index
=
ab8500_vbus_in_curr_to_regval
(
min_value
);
return
ab8500_charger_set_current
(
di
,
min_value
,
if
(
input_curr_index
<
0
)
{
AB8500_USBCH_IPT_CRNTLVL_REG
);
dev_err
(
di
->
dev
,
"VBUS input current limit too high
\n
"
);
}
return
-
ENXIO
;
}
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
/**
AB8500_USBCH_IPT_CRNTLVL_REG
,
* ab8500_charger_set_main_in_curr() - set main charger input current
input_curr_index
<<
VBUS_IN_CURR_LIM_SHIFT
);
* @di: pointer to the ab8500_charger structure
if
(
ret
)
* @ich_in: input charger current, in mA
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
*
* 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,
...
@@ -1074,7 +1176,7 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
volt_index
=
ab8500_voltage_to_regval
(
vset
);
volt_index
=
ab8500_voltage_to_regval
(
vset
);
curr_index
=
ab8500_current_to_regval
(
iset
);
curr_index
=
ab8500_current_to_regval
(
iset
);
input_curr_index
=
ab8500_current_to_regval
(
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
)
{
if
(
volt_index
<
0
||
curr_index
<
0
||
input_curr_index
<
0
)
{
dev_err
(
di
->
dev
,
dev_err
(
di
->
dev
,
"Charger voltage or current too high, "
"Charger voltage or current too high, "
...
@@ -1090,23 +1192,24 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
...
@@ -1090,23 +1192,24 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
return
ret
;
return
ret
;
}
}
/* MainChInputCurr: current that can be drawn from the charger*/
/* MainChInputCurr: current that can be drawn from the charger*/
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
ret
=
ab8500_charger_set_main_in_curr
(
di
,
AB8500_MCH_IPT_CURLVL_REG
,
di
->
bm
->
chg_params
->
ac_curr_max
);
input_curr_index
<<
MAIN_CH_INPUT_CURR_SHIFT
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s Failed to set MainChInputCurr
\n
"
,
__func__
);
return
ret
;
return
ret
;
}
}
/* ChOutputCurentLevel: protected output current */
/* ChOutputCurentLevel: protected output current */
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
ret
=
ab8500_charger_set_output_curr
(
di
,
iset
);
AB8500_CH_OPT_CRNTLVL_REG
,
(
u8
)
curr_index
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s "
"Failed to set ChOutputCurentLevel
\n
"
,
__func__
);
return
ret
;
return
ret
;
}
}
/* Check if VBAT overshoot control should be enabled */
/* 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
;
overshoot
=
MAIN_CH_NO_OVERSHOOT_ENA_N
;
/* Enable Main Charger */
/* Enable Main Charger */
...
@@ -1158,12 +1261,11 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
...
@@ -1158,12 +1261,11 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
return
ret
;
return
ret
;
}
}
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
ret
=
ab8500_charger_set_output_curr
(
di
,
0
);
AB8500_CHARGER
,
AB8500_CH_OPT_CRNTLVL_REG
,
CH_OP_CUR_LVL_0P1
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
di
->
dev
,
dev_err
(
di
->
dev
,
"%s "
"%s write failed
\n
"
,
__func__
);
"Failed to set ChOutputCurentLevel
\n
"
,
__func__
);
return
ret
;
return
ret
;
}
}
}
else
{
}
else
{
...
@@ -1266,14 +1368,15 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger,
...
@@ -1266,14 +1368,15 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger,
return
ret
;
return
ret
;
}
}
/* ChOutputCurentLevel: protected output current */
/* ChOutputCurentLevel: protected output current */
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_CHARGER
,
ret
=
ab8500_charger_set_output_curr
(
di
,
ich_out
);
AB8500_CH_OPT_CRNTLVL_REG
,
(
u8
)
curr_index
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s "
"Failed to set ChOutputCurentLevel
\n
"
,
__func__
);
return
ret
;
return
ret
;
}
}
/* Check if VBAT overshoot control should be enabled */
/* 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
;
overshoot
=
USB_CHG_NO_OVERSHOOT_ENA_N
;
/* Enable USB Charger */
/* Enable USB Charger */
...
@@ -1366,7 +1469,6 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
...
@@ -1366,7 +1469,6 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
int
ich_out
)
int
ich_out
)
{
{
int
ret
;
int
ret
;
int
curr_index
;
struct
ab8500_charger
*
di
;
struct
ab8500_charger
*
di
;
if
(
charger
->
psy
.
type
==
POWER_SUPPLY_TYPE_MAINS
)
if
(
charger
->
psy
.
type
==
POWER_SUPPLY_TYPE_MAINS
)
...
@@ -1376,18 +1478,11 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
...
@@ -1376,18 +1478,11 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
else
else
return
-
ENXIO
;
return
-
ENXIO
;
curr_index
=
ab8500_current_to_regval
(
ich_out
);
ret
=
ab8500_charger_set_output_curr
(
di
,
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
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s "
"Failed to set ChOutputCurentLevel
\n
"
,
__func__
);
return
ret
;
return
ret
;
}
}
...
@@ -2359,8 +2454,8 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di)
...
@@ -2359,8 +2454,8 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di)
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
AB8500_RTC
,
AB8500_RTC
,
AB8500_RTC_BACKUP_CHG_REG
,
AB8500_RTC_BACKUP_CHG_REG
,
di
->
b
at
->
bkup_bat_v
|
di
->
b
m
->
bkup_bat_v
|
di
->
b
at
->
bkup_bat_i
);
di
->
b
m
->
bkup_bat_i
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
di
->
dev
,
"failed to setup backup battery charging
\n
"
);
dev_err
(
di
->
dev
,
"failed to setup backup battery charging
\n
"
);
goto
out
;
goto
out
;
...
@@ -2541,6 +2636,7 @@ static char *supply_interface[] = {
...
@@ -2541,6 +2636,7 @@ static char *supply_interface[] = {
static
int
ab8500_charger_probe
(
struct
platform_device
*
pdev
)
static
int
ab8500_charger_probe
(
struct
platform_device
*
pdev
)
{
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
abx500_bm_data
*
plat
=
pdev
->
dev
.
platform_data
;
struct
ab8500_charger
*
di
;
struct
ab8500_charger
*
di
;
int
irq
,
i
,
charger_status
,
ret
=
0
;
int
irq
,
i
,
charger_status
,
ret
=
0
;
...
@@ -2549,24 +2645,22 @@ static int ab8500_charger_probe(struct platform_device *pdev)
...
@@ -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__
);
dev_err
(
&
pdev
->
dev
,
"%s no mem for ab8500_charger
\n
"
,
__func__
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
di
->
bat
=
pdev
->
mfd_cell
->
platform_data
;
if
(
!
di
->
bat
)
{
if
(
!
plat
)
{
if
(
np
)
{
dev_err
(
&
pdev
->
dev
,
"no battery management data supplied
\n
"
);
ret
=
bmdevs_of_probe
(
&
pdev
->
dev
,
np
,
&
di
->
bat
);
return
-
EINVAL
;
if
(
ret
)
{
}
dev_err
(
&
pdev
->
dev
,
di
->
bm
=
plat
;
"failed to get battery information
\n
"
);
return
ret
;
if
(
np
)
{
}
ret
=
ab8500_bm_of_probe
(
&
pdev
->
dev
,
np
,
di
->
bm
);
di
->
autopower_cfg
=
of_property_read_bool
(
np
,
"autopower_cfg"
);
if
(
ret
)
{
}
else
{
dev_err
(
&
pdev
->
dev
,
"failed to get battery information
\n
"
);
dev_err
(
&
pdev
->
dev
,
"missing dt node for ab8500_charger
\n
"
);
return
ret
;
return
-
EINVAL
;
}
}
}
else
{
di
->
autopower_cfg
=
of_property_read_bool
(
np
,
"autopower_cfg"
);
dev_info
(
&
pdev
->
dev
,
"falling back to legacy platform data
\n
"
);
}
else
di
->
autopower_cfg
=
false
;
di
->
autopower_cfg
=
false
;
}
/* get parent data */
/* get parent data */
di
->
dev
=
&
pdev
->
dev
;
di
->
dev
=
&
pdev
->
dev
;
...
...
drivers/power/ab8500_fg.c
浏览文件 @
240fbe23
...
@@ -173,7 +173,7 @@ struct inst_curr_result_list {
...
@@ -173,7 +173,7 @@ struct inst_curr_result_list {
* @avg_cap: Average capacity filter
* @avg_cap: Average capacity filter
* @parent: Pointer to the struct ab8500
* @parent: Pointer to the struct ab8500
* @gpadc: Pointer to the struct gpadc
* @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_psy: Structure that holds the FG specific battery properties
* @fg_wq: Work queue for running the FG algorithm
* @fg_wq: Work queue for running the FG algorithm
* @fg_periodic_work: Work to run the FG algorithm periodically
* @fg_periodic_work: Work to run the FG algorithm periodically
...
@@ -212,7 +212,7 @@ struct ab8500_fg {
...
@@ -212,7 +212,7 @@ struct ab8500_fg {
struct
ab8500_fg_avg_cap
avg_cap
;
struct
ab8500_fg_avg_cap
avg_cap
;
struct
ab8500
*
parent
;
struct
ab8500
*
parent
;
struct
ab8500_gpadc
*
gpadc
;
struct
ab8500_gpadc
*
gpadc
;
struct
abx500_bm_data
*
b
at
;
struct
abx500_bm_data
*
b
m
;
struct
power_supply
fg_psy
;
struct
power_supply
fg_psy
;
struct
workqueue_struct
*
fg_wq
;
struct
workqueue_struct
*
fg_wq
;
struct
delayed_work
fg_periodic_work
;
struct
delayed_work
fg_periodic_work
;
...
@@ -355,7 +355,7 @@ static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr)
...
@@ -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
* 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
;
return
true
;
else
else
return
false
;
return
false
;
...
@@ -484,8 +484,9 @@ static int ab8500_fg_coulomb_counter(struct ab8500_fg *di, bool enable)
...
@@ -484,8 +484,9 @@ static int ab8500_fg_coulomb_counter(struct ab8500_fg *di, bool enable)
di
->
flags
.
fg_enabled
=
true
;
di
->
flags
.
fg_enabled
=
true
;
}
else
{
}
else
{
/* Clear any pending read requests */
/* Clear any pending read requests */
ret
=
abx500_set_register_interruptible
(
di
->
dev
,
ret
=
abx500_mask_and_set_register_interruptible
(
di
->
dev
,
AB8500_GAS_GAUGE
,
AB8500_GASG_CC_CTRL_REG
,
0
);
AB8500_GAS_GAUGE
,
AB8500_GASG_CC_CTRL_REG
,
(
RESET_ACCU
|
READ_REQ
),
0
);
if
(
ret
)
if
(
ret
)
goto
cc_err
;
goto
cc_err
;
...
@@ -647,7 +648,7 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res)
...
@@ -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
* 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm
*/
*/
val
=
(
val
*
QLSB_NANO_AMP_HOURS_X10
*
36
*
4
)
/
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
)
{
if
(
di
->
turn_off_fg
)
{
dev_dbg
(
di
->
dev
,
"%s Disable FG
\n
"
,
__func__
);
dev_dbg
(
di
->
dev
,
"%s Disable FG
\n
"
,
__func__
);
...
@@ -750,7 +751,7 @@ static void ab8500_fg_acc_cur_work(struct work_struct *work)
...
@@ -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
* 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm
*/
*/
di
->
accu_charge
=
(
val
*
QLSB_NANO_AMP_HOURS_X10
)
/
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
* Convert to unit value in mA
...
@@ -762,7 +763,7 @@ static void ab8500_fg_acc_cur_work(struct work_struct *work)
...
@@ -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
* 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm
*/
*/
di
->
avg_curr
=
(
val
*
QLSB_NANO_AMP_HOURS_X10
*
36
)
/
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
;
di
->
flags
.
conv_done
=
true
;
...
@@ -814,8 +815,8 @@ static int ab8500_fg_volt_to_capacity(struct ab8500_fg *di, int voltage)
...
@@ -814,8 +815,8 @@ static int ab8500_fg_volt_to_capacity(struct ab8500_fg *di, int voltage)
struct
abx500_v_to_cap
*
tbl
;
struct
abx500_v_to_cap
*
tbl
;
int
cap
=
0
;
int
cap
=
0
;
tbl
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
v_to_cap_tbl
,
tbl
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
v_to_cap_tbl
,
tbl_size
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
n_v_cap_tbl_elements
;
tbl_size
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
n_v_cap_tbl_elements
;
for
(
i
=
0
;
i
<
tbl_size
;
++
i
)
{
for
(
i
=
0
;
i
<
tbl_size
;
++
i
)
{
if
(
voltage
>
tbl
[
i
].
voltage
)
if
(
voltage
>
tbl
[
i
].
voltage
)
...
@@ -866,8 +867,8 @@ static int ab8500_fg_battery_resistance(struct ab8500_fg *di)
...
@@ -866,8 +867,8 @@ static int ab8500_fg_battery_resistance(struct ab8500_fg *di)
struct
batres_vs_temp
*
tbl
;
struct
batres_vs_temp
*
tbl
;
int
resist
=
0
;
int
resist
=
0
;
tbl
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
batres_tbl
;
tbl
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
batres_tbl
;
tbl_size
=
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
n_batres_tbl_elements
;
tbl_size
=
di
->
b
m
->
bat_type
[
di
->
bm
->
batt_id
].
n_batres_tbl_elements
;
for
(
i
=
0
;
i
<
tbl_size
;
++
i
)
{
for
(
i
=
0
;
i
<
tbl_size
;
++
i
)
{
if
(
di
->
bat_temp
/
10
>
tbl
[
i
].
temp
)
if
(
di
->
bat_temp
/
10
>
tbl
[
i
].
temp
)
...
@@ -888,11 +889,11 @@ static int ab8500_fg_battery_resistance(struct ab8500_fg *di)
...
@@ -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"
dev_dbg
(
di
->
dev
,
"%s Temp: %d battery internal resistance: %d"
" fg resistance %d, total: %d (mOhm)
\n
"
,
" fg resistance %d, total: %d (mOhm)
\n
"
,
__func__
,
di
->
bat_temp
,
resist
,
di
->
b
at
->
fg_res
/
10
,
__func__
,
di
->
bat_temp
,
resist
,
di
->
b
m
->
fg_res
/
10
,
(
di
->
b
at
->
fg_res
/
10
)
+
resist
);
(
di
->
b
m
->
fg_res
/
10
)
+
resist
);
/* fg_res variable is in 0.1mOhm */
/* fg_res variable is in 0.1mOhm */
resist
+=
di
->
b
at
->
fg_res
/
10
;
resist
+=
di
->
b
m
->
fg_res
/
10
;
return
resist
;
return
resist
;
}
}
...
@@ -1110,14 +1111,14 @@ static int ab8500_fg_capacity_level(struct ab8500_fg *di)
...
@@ -1110,14 +1111,14 @@ static int ab8500_fg_capacity_level(struct ab8500_fg *di)
percent
=
di
->
bat_cap
.
permille
/
10
;
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
)
di
->
flags
.
low_bat
)
ret
=
POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL
;
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
;
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
;
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
;
ret
=
POWER_SUPPLY_CAPACITY_LEVEL_HIGH
;
else
else
ret
=
POWER_SUPPLY_CAPACITY_LEVEL_FULL
;
ret
=
POWER_SUPPLY_CAPACITY_LEVEL_FULL
;
...
@@ -1182,7 +1183,7 @@ static void ab8500_fg_check_capacity_limits(struct ab8500_fg *di, bool init)
...
@@ -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
.
prev_percent
!=
(
di
->
bat_cap
.
permille
)
/
10
&&
(
di
->
bat_cap
.
permille
)
/
10
&&
(
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
,
dev_dbg
(
di
->
dev
,
"battery reported full "
"battery reported full "
"but capacity dropping: %d
\n
"
,
"but capacity dropping: %d
\n
"
,
...
@@ -1284,7 +1285,7 @@ static void ab8500_fg_algorithm_charging(struct ab8500_fg *di)
...
@@ -1284,7 +1285,7 @@ static void ab8500_fg_algorithm_charging(struct ab8500_fg *di)
switch
(
di
->
charge_state
)
{
switch
(
di
->
charge_state
)
{
case
AB8500_FG_CHARGE_INIT
:
case
AB8500_FG_CHARGE_INIT
:
di
->
fg_samples
=
SEC_TO_SAMPLE
(
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_coulomb_counter
(
di
,
true
);
ab8500_fg_charge_state_to
(
di
,
AB8500_FG_CHARGE_READOUT
);
ab8500_fg_charge_state_to
(
di
,
AB8500_FG_CHARGE_READOUT
);
...
@@ -1346,8 +1347,8 @@ static bool check_sysfs_capacity(struct ab8500_fg *di)
...
@@ -1346,8 +1347,8 @@ static bool check_sysfs_capacity(struct ab8500_fg *di)
cap_permille
=
ab8500_fg_convert_mah_to_permille
(
di
,
cap_permille
=
ab8500_fg_convert_mah_to_permille
(
di
,
di
->
bat_cap
.
user_mah
);
di
->
bat_cap
.
user_mah
);
lower
=
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
at
->
fg_params
->
user_cap_limit
*
10
;
upper
=
di
->
bat_cap
.
permille
+
di
->
b
m
->
fg_params
->
user_cap_limit
*
10
;
if
(
lower
<
0
)
if
(
lower
<
0
)
lower
=
0
;
lower
=
0
;
...
@@ -1387,7 +1388,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
...
@@ -1387,7 +1388,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
case
AB8500_FG_DISCHARGE_INIT
:
case
AB8500_FG_DISCHARGE_INIT
:
/* We use the FG IRQ to work on */
/* We use the FG IRQ to work on */
di
->
init_cnt
=
0
;
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_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_INITMEASURING
);
AB8500_FG_DISCHARGE_INITMEASURING
);
...
@@ -1400,18 +1401,17 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
...
@@ -1400,18 +1401,17 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
* samples to get an initial capacity.
* samples to get an initial capacity.
* Then go to READOUT
* 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 */
/* Discard the first [x] seconds */
if
(
di
->
init_cnt
>
if
(
di
->
init_cnt
>
di
->
bm
->
fg_params
->
init_discard_time
)
{
di
->
bat
->
fg_params
->
init_discard_time
)
{
ab8500_fg_calc_cap_discharge_voltage
(
di
,
true
);
ab8500_fg_calc_cap_discharge_voltage
(
di
,
true
);
ab8500_fg_check_capacity_limits
(
di
,
true
);
ab8500_fg_check_capacity_limits
(
di
,
true
);
}
}
di
->
init_cnt
+=
sleep_time
;
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_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT_INIT
);
AB8500_FG_DISCHARGE_READOUT_INIT
);
...
@@ -1426,7 +1426,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
...
@@ -1426,7 +1426,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
/* Intentional fallthrough */
/* Intentional fallthrough */
case
AB8500_FG_DISCHARGE_RECOVERY
:
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
* We should check the power consumption
...
@@ -1438,9 +1438,9 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
...
@@ -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
(
ab8500_fg_is_low_curr
(
di
,
di
->
inst_curr
))
{
if
(
di
->
recovery_cnt
>
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
->
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_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT
);
AB8500_FG_DISCHARGE_READOUT
);
...
@@ -1453,7 +1453,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
...
@@ -1453,7 +1453,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
di
->
recovery_cnt
+=
sleep_time
;
di
->
recovery_cnt
+=
sleep_time
;
}
else
{
}
else
{
di
->
fg_samples
=
SEC_TO_SAMPLE
(
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_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT
);
AB8500_FG_DISCHARGE_READOUT
);
...
@@ -1462,7 +1462,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
...
@@ -1462,7 +1462,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
case
AB8500_FG_DISCHARGE_READOUT_INIT
:
case
AB8500_FG_DISCHARGE_READOUT_INIT
:
di
->
fg_samples
=
SEC_TO_SAMPLE
(
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_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT
);
AB8500_FG_DISCHARGE_READOUT
);
...
@@ -1509,9 +1509,9 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
...
@@ -1509,9 +1509,9 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
}
}
di
->
high_curr_cnt
+=
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
>
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
;
di
->
recovery_needed
=
true
;
ab8500_fg_calc_cap_discharge_fg
(
di
);
ab8500_fg_calc_cap_discharge_fg
(
di
);
...
@@ -1528,7 +1528,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
...
@@ -1528,7 +1528,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
ab8500_fg_calc_cap_discharge_voltage
(
di
,
true
);
ab8500_fg_calc_cap_discharge_voltage
(
di
,
true
);
di
->
fg_samples
=
SEC_TO_SAMPLE
(
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_coulomb_counter
(
di
,
true
);
ab8500_fg_discharge_state_to
(
di
,
ab8500_fg_discharge_state_to
(
di
,
AB8500_FG_DISCHARGE_READOUT
);
AB8500_FG_DISCHARGE_READOUT
);
...
@@ -1721,7 +1721,7 @@ static void ab8500_fg_low_bat_work(struct work_struct *work)
...
@@ -1721,7 +1721,7 @@ static void ab8500_fg_low_bat_work(struct work_struct *work)
vbat
=
ab8500_fg_bat_voltage
(
di
);
vbat
=
ab8500_fg_bat_voltage
(
di
);
/* Check if LOW_BAT still fulfilled */
/* 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
;
di
->
flags
.
low_bat
=
true
;
dev_warn
(
di
->
dev
,
"Battery voltage still LOW
\n
"
);
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)
...
@@ -1779,8 +1779,8 @@ static int ab8500_fg_battok_init_hw_register(struct ab8500_fg *di)
int
ret
;
int
ret
;
int
new_val
;
int
new_val
;
sel0
=
di
->
b
at
->
fg_params
->
battok_falling_th_sel0
;
sel0
=
di
->
b
m
->
fg_params
->
battok_falling_th_sel0
;
sel1
=
di
->
b
at
->
fg_params
->
battok_raising_th_sel1
;
sel1
=
di
->
b
m
->
fg_params
->
battok_raising_th_sel1
;
cbp_sel0
=
ab8500_fg_battok_calc
(
di
,
sel0
);
cbp_sel0
=
ab8500_fg_battok_calc
(
di
,
sel0
);
cbp_sel1
=
ab8500_fg_battok_calc
(
di
,
sel1
);
cbp_sel1
=
ab8500_fg_battok_calc
(
di
,
sel1
);
...
@@ -1963,7 +1963,7 @@ static int ab8500_fg_get_property(struct power_supply *psy,
...
@@ -1963,7 +1963,7 @@ static int ab8500_fg_get_property(struct power_supply *psy,
di
->
bat_cap
.
max_mah
);
di
->
bat_cap
.
max_mah
);
break
;
break
;
case
POWER_SUPPLY_PROP_ENERGY_NOW
:
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
)
di
->
flags
.
batt_id_received
)
val
->
intval
=
ab8500_fg_convert_mah_to_uwh
(
di
,
val
->
intval
=
ab8500_fg_convert_mah_to_uwh
(
di
,
di
->
bat_cap
.
max_mah
);
di
->
bat_cap
.
max_mah
);
...
@@ -1978,21 +1978,21 @@ static int ab8500_fg_get_property(struct power_supply *psy,
...
@@ -1978,21 +1978,21 @@ static int ab8500_fg_get_property(struct power_supply *psy,
val
->
intval
=
di
->
bat_cap
.
max_mah
;
val
->
intval
=
di
->
bat_cap
.
max_mah
;
break
;
break
;
case
POWER_SUPPLY_PROP_CHARGE_NOW
:
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
)
di
->
flags
.
batt_id_received
)
val
->
intval
=
di
->
bat_cap
.
max_mah
;
val
->
intval
=
di
->
bat_cap
.
max_mah
;
else
else
val
->
intval
=
di
->
bat_cap
.
prev_mah
;
val
->
intval
=
di
->
bat_cap
.
prev_mah
;
break
;
break
;
case
POWER_SUPPLY_PROP_CAPACITY
:
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
)
di
->
flags
.
batt_id_received
)
val
->
intval
=
100
;
val
->
intval
=
100
;
else
else
val
->
intval
=
di
->
bat_cap
.
prev_percent
;
val
->
intval
=
di
->
bat_cap
.
prev_percent
;
break
;
break
;
case
POWER_SUPPLY_PROP_CAPACITY_LEVEL
:
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
)
di
->
flags
.
batt_id_received
)
val
->
intval
=
POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN
;
val
->
intval
=
POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN
;
else
else
...
@@ -2078,7 +2078,7 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data)
...
@@ -2078,7 +2078,7 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data)
if
(
!
di
->
flags
.
batt_id_received
)
{
if
(
!
di
->
flags
.
batt_id_received
)
{
const
struct
abx500_battery_type
*
b
;
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
;
di
->
flags
.
batt_id_received
=
true
;
...
@@ -2155,7 +2155,7 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di)
...
@@ -2155,7 +2155,7 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di)
AB8500_SYS_CTRL2_BLOCK
,
AB8500_SYS_CTRL2_BLOCK
,
AB8500_LOW_BAT_REG
,
AB8500_LOW_BAT_REG
,
ab8500_volt_to_regval
(
ab8500_volt_to_regval
(
di
->
b
at
->
fg_params
->
lowbat_threshold
)
<<
1
|
di
->
b
m
->
fg_params
->
lowbat_threshold
)
<<
1
|
LOW_BAT_ENABLE
);
LOW_BAT_ENABLE
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
dev_err
(
di
->
dev
,
"%s write failed
\n
"
,
__func__
);
...
@@ -2448,6 +2448,7 @@ static char *supply_interface[] = {
...
@@ -2448,6 +2448,7 @@ static char *supply_interface[] = {
static
int
ab8500_fg_probe
(
struct
platform_device
*
pdev
)
static
int
ab8500_fg_probe
(
struct
platform_device
*
pdev
)
{
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
abx500_bm_data
*
plat
=
pdev
->
dev
.
platform_data
;
struct
ab8500_fg
*
di
;
struct
ab8500_fg
*
di
;
int
i
,
irq
;
int
i
,
irq
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -2457,21 +2458,19 @@ static int ab8500_fg_probe(struct platform_device *pdev)
...
@@ -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__
);
dev_err
(
&
pdev
->
dev
,
"%s no mem for ab8500_fg
\n
"
,
__func__
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
di
->
bat
=
pdev
->
mfd_cell
->
platform_data
;
if
(
!
di
->
b
at
)
{
if
(
!
pl
at
)
{
if
(
np
)
{
dev_err
(
&
pdev
->
dev
,
"no battery management data supplied
\n
"
);
ret
=
bmdevs_of_probe
(
&
pdev
->
dev
,
np
,
&
di
->
bat
)
;
return
-
EINVAL
;
if
(
ret
)
{
}
dev_err
(
&
pdev
->
dev
,
di
->
bm
=
plat
;
"failed to get battery information
\n
"
);
return
ret
;
if
(
np
)
{
}
ret
=
ab8500_bm_of_probe
(
&
pdev
->
dev
,
np
,
di
->
bm
);
}
else
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"
missing dt node for ab8500_fg
\n
"
);
dev_err
(
&
pdev
->
dev
,
"
failed to get battery information
\n
"
);
return
-
EINVAL
;
return
ret
;
}
}
}
else
{
dev_info
(
&
pdev
->
dev
,
"falling back to legacy platform data
\n
"
);
}
}
mutex_init
(
&
di
->
cc_lock
);
mutex_init
(
&
di
->
cc_lock
);
...
@@ -2491,11 +2490,11 @@ static int ab8500_fg_probe(struct platform_device *pdev)
...
@@ -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
->
fg_psy
.
external_power_changed
=
ab8500_fg_external_power_changed
;
di
->
bat_cap
.
max_mah_design
=
MILLI_TO_MICRO
*
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
->
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
;
di
->
init_capacity
=
true
;
...
@@ -2549,7 +2548,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
...
@@ -2549,7 +2548,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
goto
free_inst_curr_wq
;
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
);
ab8500_fg_coulomb_counter
(
di
,
true
);
/* Initialize completion used to notify completion of inst current */
/* Initialize completion used to notify completion of inst current */
...
...
drivers/power/abx500_chargalg.c
浏览文件 @
240fbe23
...
@@ -207,7 +207,7 @@ enum maxim_ret {
...
@@ -207,7 +207,7 @@ enum maxim_ret {
* @chg_info: information about connected charger types
* @chg_info: information about connected charger types
* @batt_data: data of the battery
* @batt_data: data of the battery
* @susp_status: current charger suspension status
* @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
* @chargalg_psy: structure that holds the battery properties exposed by
* the charging algorithm
* the charging algorithm
* @events: structure for information about events triggered
* @events: structure for information about events triggered
...
@@ -232,7 +232,7 @@ struct abx500_chargalg {
...
@@ -232,7 +232,7 @@ struct abx500_chargalg {
struct
abx500_chargalg_charger_info
chg_info
;
struct
abx500_chargalg_charger_info
chg_info
;
struct
abx500_chargalg_battery_data
batt_data
;
struct
abx500_chargalg_battery_data
batt_data
;
struct
abx500_chargalg_suspension_status
susp_status
;
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
power_supply
chargalg_psy
;
struct
ux500_charger
*
ac_chg
;
struct
ux500_charger
*
ac_chg
;
struct
ux500_charger
*
usb_chg
;
struct
ux500_charger
*
usb_chg
;
...
@@ -367,13 +367,13 @@ static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di)
...
@@ -367,13 +367,13 @@ static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di)
case
AC_CHG
:
case
AC_CHG
:
timer_expiration
=
timer_expiration
=
round_jiffies
(
jiffies
+
round_jiffies
(
jiffies
+
(
di
->
b
at
->
main_safety_tmr_h
*
3600
*
HZ
));
(
di
->
b
m
->
main_safety_tmr_h
*
3600
*
HZ
));
break
;
break
;
case
USB_CHG
:
case
USB_CHG
:
timer_expiration
=
timer_expiration
=
round_jiffies
(
jiffies
+
round_jiffies
(
jiffies
+
(
di
->
b
at
->
usb_safety_tmr_h
*
3600
*
HZ
));
(
di
->
b
m
->
usb_safety_tmr_h
*
3600
*
HZ
));
break
;
break
;
default:
default:
...
@@ -638,32 +638,32 @@ static void abx500_chargalg_start_charging(struct abx500_chargalg *di,
...
@@ -638,32 +638,32 @@ static void abx500_chargalg_start_charging(struct abx500_chargalg *di,
*/
*/
static
void
abx500_chargalg_check_temp
(
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
)
&&
if
(
di
->
batt_data
.
temp
>
(
di
->
b
m
->
temp_low
+
di
->
t_hyst_norm
)
&&
di
->
batt_data
.
temp
<
(
di
->
b
at
->
temp_high
-
di
->
t_hyst_norm
))
{
di
->
batt_data
.
temp
<
(
di
->
b
m
->
temp_high
-
di
->
t_hyst_norm
))
{
/* Temp OK! */
/* Temp OK! */
di
->
events
.
btemp_underover
=
false
;
di
->
events
.
btemp_underover
=
false
;
di
->
events
.
btemp_lowhigh
=
false
;
di
->
events
.
btemp_lowhigh
=
false
;
di
->
t_hyst_norm
=
0
;
di
->
t_hyst_norm
=
0
;
di
->
t_hyst_lowhigh
=
0
;
di
->
t_hyst_lowhigh
=
0
;
}
else
{
}
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
->
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
->
batt_data
.
temp
>
(
di
->
b
at
->
temp_under
+
di
->
t_hyst_lowhigh
))
&&
(
di
->
b
m
->
temp_under
+
di
->
t_hyst_lowhigh
))
&&
(
di
->
batt_data
.
temp
<=
di
->
b
at
->
temp_low
)))
{
(
di
->
batt_data
.
temp
<=
di
->
b
m
->
temp_low
)))
{
/* TEMP minor!!!!! */
/* TEMP minor!!!!! */
di
->
events
.
btemp_underover
=
false
;
di
->
events
.
btemp_underover
=
false
;
di
->
events
.
btemp_lowhigh
=
true
;
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
;
di
->
t_hyst_lowhigh
=
0
;
}
else
if
(
di
->
batt_data
.
temp
<=
di
->
b
at
->
temp_under
||
}
else
if
(
di
->
batt_data
.
temp
<=
di
->
b
m
->
temp_under
||
di
->
batt_data
.
temp
>=
di
->
b
at
->
temp_over
)
{
di
->
batt_data
.
temp
>=
di
->
b
m
->
temp_over
)
{
/* TEMP major!!!!! */
/* TEMP major!!!!! */
di
->
events
.
btemp_underover
=
true
;
di
->
events
.
btemp_underover
=
true
;
di
->
events
.
btemp_lowhigh
=
false
;
di
->
events
.
btemp_lowhigh
=
false
;
di
->
t_hyst_norm
=
0
;
di
->
t_hyst_norm
=
0
;
di
->
t_hyst_lowhigh
=
di
->
b
at
->
temp_hysteresis
;
di
->
t_hyst_lowhigh
=
di
->
b
m
->
temp_hysteresis
;
}
else
{
}
else
{
/* Within hysteresis */
/* Within hysteresis */
dev_dbg
(
di
->
dev
,
"Within hysteresis limit temp: %d "
dev_dbg
(
di
->
dev
,
"Within hysteresis limit temp: %d "
...
@@ -682,12 +682,12 @@ static void abx500_chargalg_check_temp(struct abx500_chargalg *di)
...
@@ -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
)
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
;
di
->
chg_info
.
usb_chg_ok
=
false
;
else
else
di
->
chg_info
.
usb_chg_ok
=
true
;
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
;
di
->
chg_info
.
ac_chg_ok
=
false
;
else
else
di
->
chg_info
.
ac_chg_ok
=
true
;
di
->
chg_info
.
ac_chg_ok
=
true
;
...
@@ -707,10 +707,10 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
...
@@ -707,10 +707,10 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
if
(
di
->
charge_status
==
POWER_SUPPLY_STATUS_CHARGING
&&
if
(
di
->
charge_status
==
POWER_SUPPLY_STATUS_CHARGING
&&
di
->
charge_state
==
STATE_NORMAL
&&
di
->
charge_state
==
STATE_NORMAL
&&
!
di
->
maintenance_chg
&&
(
di
->
batt_data
.
volt
>=
!
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
->
events
.
usb_cv_active
||
di
->
events
.
ac_cv_active
)
&&
di
->
batt_data
.
avg_curr
<
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
)
{
di
->
batt_data
.
avg_curr
>
0
)
{
if
(
++
di
->
eoc_cnt
>=
EOC_COND_CNT
)
{
if
(
++
di
->
eoc_cnt
>=
EOC_COND_CNT
)
{
di
->
eoc_cnt
=
0
;
di
->
eoc_cnt
=
0
;
...
@@ -733,12 +733,12 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
...
@@ -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
)
static
void
init_maxim_chg_curr
(
struct
abx500_chargalg
*
di
)
{
{
di
->
ccm
.
original_iset
=
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
->
ccm
.
current_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
.
test_delta_i
=
di
->
b
at
->
maxi
->
charger_curr_step
;
di
->
ccm
.
test_delta_i
=
di
->
b
m
->
maxi
->
charger_curr_step
;
di
->
ccm
.
max_current
=
di
->
b
at
->
maxi
->
chg_curr
;
di
->
ccm
.
max_current
=
di
->
b
m
->
maxi
->
chg_curr
;
di
->
ccm
.
condition_cnt
=
di
->
b
at
->
maxi
->
wait_cycles
;
di
->
ccm
.
condition_cnt
=
di
->
b
m
->
maxi
->
wait_cycles
;
di
->
ccm
.
level
=
0
;
di
->
ccm
.
level
=
0
;
}
}
...
@@ -755,7 +755,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
...
@@ -755,7 +755,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
{
{
int
delta_i
;
int
delta_i
;
if
(
!
di
->
b
at
->
maxi
->
ena_maxi
)
if
(
!
di
->
b
m
->
maxi
->
ena_maxi
)
return
MAXIM_RET_NOACTION
;
return
MAXIM_RET_NOACTION
;
delta_i
=
di
->
ccm
.
original_iset
-
di
->
batt_data
.
inst_curr
;
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)
...
@@ -766,7 +766,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
if
(
di
->
ccm
.
wait_cnt
==
0
)
{
if
(
di
->
ccm
.
wait_cnt
==
0
)
{
dev_dbg
(
di
->
dev
,
"lowering current
\n
"
);
dev_dbg
(
di
->
dev
,
"lowering current
\n
"
);
di
->
ccm
.
wait_cnt
++
;
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
.
max_current
=
di
->
ccm
.
current_iset
-
di
->
ccm
.
test_delta_i
;
di
->
ccm
.
current_iset
-
di
->
ccm
.
test_delta_i
;
di
->
ccm
.
current_iset
=
di
->
ccm
.
max_current
;
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)
...
@@ -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
)
if
(
di
->
ccm
.
current_iset
==
di
->
ccm
.
original_iset
)
return
MAXIM_RET_NOACTION
;
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
.
current_iset
=
di
->
ccm
.
original_iset
;
di
->
ccm
.
level
=
0
;
di
->
ccm
.
level
=
0
;
...
@@ -803,7 +803,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
...
@@ -803,7 +803,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
di
->
ccm
.
max_current
)
{
di
->
ccm
.
max_current
)
{
if
(
di
->
ccm
.
condition_cnt
--
==
0
)
{
if
(
di
->
ccm
.
condition_cnt
--
==
0
)
{
/* Increse the iset with cco.test_delta_i */
/* 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
.
current_iset
+=
di
->
ccm
.
test_delta_i
;
di
->
ccm
.
level
++
;
di
->
ccm
.
level
++
;
dev_dbg
(
di
->
dev
,
" Maximization needed, increase"
dev_dbg
(
di
->
dev
,
" Maximization needed, increase"
...
@@ -818,7 +818,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
...
@@ -818,7 +818,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
return
MAXIM_RET_NOACTION
;
return
MAXIM_RET_NOACTION
;
}
}
}
else
{
}
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
;
return
MAXIM_RET_NOACTION
;
}
}
}
}
...
@@ -838,7 +838,7 @@ static void handle_maxim_chg_curr(struct abx500_chargalg *di)
...
@@ -838,7 +838,7 @@ static void handle_maxim_chg_curr(struct abx500_chargalg *di)
break
;
break
;
case
MAXIM_RET_IBAT_TOO_HIGH
:
case
MAXIM_RET_IBAT_TOO_HIGH
:
result
=
abx500_chargalg_update_chg_curr
(
di
,
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
)
if
(
result
)
dev_err
(
di
->
dev
,
"failed to set chg curr
\n
"
);
dev_err
(
di
->
dev
,
"failed to set chg curr
\n
"
);
break
;
break
;
...
@@ -1210,7 +1210,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
...
@@ -1210,7 +1210,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
* this way
* this way
*/
*/
if
(
!
charger_status
||
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
)
{
if
(
di
->
charge_state
!=
STATE_HANDHELD
)
{
di
->
events
.
safety_timer_expired
=
false
;
di
->
events
.
safety_timer_expired
=
false
;
abx500_chargalg_state_to
(
di
,
STATE_HANDHELD_INIT
);
abx500_chargalg_state_to
(
di
,
STATE_HANDHELD_INIT
);
...
@@ -1394,8 +1394,8 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
...
@@ -1394,8 +1394,8 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_NORMAL_INIT
:
case
STATE_NORMAL_INIT
:
abx500_chargalg_start_charging
(
di
,
abx500_chargalg_start_charging
(
di
,
di
->
b
at
->
bat_type
[
di
->
bat
->
batt_id
].
normal_vol_lvl
,
di
->
b
m
->
bat_type
[
di
->
bm
->
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_cur_lvl
);
abx500_chargalg_state_to
(
di
,
STATE_NORMAL
);
abx500_chargalg_state_to
(
di
,
STATE_NORMAL
);
abx500_chargalg_start_safety_timer
(
di
);
abx500_chargalg_start_safety_timer
(
di
);
abx500_chargalg_stop_maintenance_timer
(
di
);
abx500_chargalg_stop_maintenance_timer
(
di
);
...
@@ -1411,7 +1411,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
...
@@ -1411,7 +1411,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
handle_maxim_chg_curr
(
di
);
handle_maxim_chg_curr
(
di
);
if
(
di
->
charge_status
==
POWER_SUPPLY_STATUS_FULL
&&
if
(
di
->
charge_status
==
POWER_SUPPLY_STATUS_FULL
&&
di
->
maintenance_chg
)
{
di
->
maintenance_chg
)
{
if
(
di
->
b
at
->
no_maintenance
)
if
(
di
->
b
m
->
no_maintenance
)
abx500_chargalg_state_to
(
di
,
abx500_chargalg_state_to
(
di
,
STATE_WAIT_FOR_RECHARGE_INIT
);
STATE_WAIT_FOR_RECHARGE_INIT
);
else
else
...
@@ -1429,7 +1429,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
...
@@ -1429,7 +1429,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_WAIT_FOR_RECHARGE
:
case
STATE_WAIT_FOR_RECHARGE
:
if
(
di
->
batt_data
.
volt
<=
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
)
if
(
di
->
rch_cnt
--
==
0
)
abx500_chargalg_state_to
(
di
,
STATE_NORMAL_INIT
);
abx500_chargalg_state_to
(
di
,
STATE_NORMAL_INIT
);
}
else
}
else
...
@@ -1439,13 +1439,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
...
@@ -1439,13 +1439,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_MAINTENANCE_A_INIT
:
case
STATE_MAINTENANCE_A_INIT
:
abx500_chargalg_stop_safety_timer
(
di
);
abx500_chargalg_stop_safety_timer
(
di
);
abx500_chargalg_start_maintenance_timer
(
di
,
abx500_chargalg_start_maintenance_timer
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
m
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_a_chg_timer_h
);
di
->
b
m
->
batt_id
].
maint_a_chg_timer_h
);
abx500_chargalg_start_charging
(
di
,
abx500_chargalg_start_charging
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
m
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_a_vol_lvl
,
di
->
b
m
->
batt_id
].
maint_a_vol_lvl
,
di
->
b
at
->
bat_type
[
di
->
b
m
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_a_cur_lvl
);
di
->
b
m
->
batt_id
].
maint_a_cur_lvl
);
abx500_chargalg_state_to
(
di
,
STATE_MAINTENANCE_A
);
abx500_chargalg_state_to
(
di
,
STATE_MAINTENANCE_A
);
power_supply_changed
(
&
di
->
chargalg_psy
);
power_supply_changed
(
&
di
->
chargalg_psy
);
/* Intentional fallthrough*/
/* Intentional fallthrough*/
...
@@ -1459,13 +1459,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
...
@@ -1459,13 +1459,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_MAINTENANCE_B_INIT
:
case
STATE_MAINTENANCE_B_INIT
:
abx500_chargalg_start_maintenance_timer
(
di
,
abx500_chargalg_start_maintenance_timer
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
m
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_b_chg_timer_h
);
di
->
b
m
->
batt_id
].
maint_b_chg_timer_h
);
abx500_chargalg_start_charging
(
di
,
abx500_chargalg_start_charging
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
m
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_b_vol_lvl
,
di
->
b
m
->
batt_id
].
maint_b_vol_lvl
,
di
->
b
at
->
bat_type
[
di
->
b
m
->
bat_type
[
di
->
b
at
->
batt_id
].
maint_b_cur_lvl
);
di
->
b
m
->
batt_id
].
maint_b_cur_lvl
);
abx500_chargalg_state_to
(
di
,
STATE_MAINTENANCE_B
);
abx500_chargalg_state_to
(
di
,
STATE_MAINTENANCE_B
);
power_supply_changed
(
&
di
->
chargalg_psy
);
power_supply_changed
(
&
di
->
chargalg_psy
);
/* Intentional fallthrough*/
/* Intentional fallthrough*/
...
@@ -1479,10 +1479,10 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
...
@@ -1479,10 +1479,10 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case
STATE_TEMP_LOWHIGH_INIT
:
case
STATE_TEMP_LOWHIGH_INIT
:
abx500_chargalg_start_charging
(
di
,
abx500_chargalg_start_charging
(
di
,
di
->
b
at
->
bat_type
[
di
->
b
m
->
bat_type
[
di
->
b
at
->
batt_id
].
low_high_vol_lvl
,
di
->
b
m
->
batt_id
].
low_high_vol_lvl
,
di
->
b
at
->
bat_type
[
di
->
b
m
->
bat_type
[
di
->
b
at
->
batt_id
].
low_high_cur_lvl
);
di
->
b
m
->
batt_id
].
low_high_cur_lvl
);
abx500_chargalg_stop_maintenance_timer
(
di
);
abx500_chargalg_stop_maintenance_timer
(
di
);
di
->
charge_status
=
POWER_SUPPLY_STATUS_CHARGING
;
di
->
charge_status
=
POWER_SUPPLY_STATUS_CHARGING
;
abx500_chargalg_state_to
(
di
,
STATE_TEMP_LOWHIGH
);
abx500_chargalg_state_to
(
di
,
STATE_TEMP_LOWHIGH
);
...
@@ -1543,11 +1543,11 @@ static void abx500_chargalg_periodic_work(struct work_struct *work)
...
@@ -1543,11 +1543,11 @@ static void abx500_chargalg_periodic_work(struct work_struct *work)
if
(
di
->
chg_info
.
conn_chg
)
if
(
di
->
chg_info
.
conn_chg
)
queue_delayed_work
(
di
->
chargalg_wq
,
queue_delayed_work
(
di
->
chargalg_wq
,
&
di
->
chargalg_periodic_work
,
&
di
->
chargalg_periodic_work
,
di
->
b
at
->
interval_charging
*
HZ
);
di
->
b
m
->
interval_charging
*
HZ
);
else
else
queue_delayed_work
(
di
->
chargalg_wq
,
queue_delayed_work
(
di
->
chargalg_wq
,
&
di
->
chargalg_periodic_work
,
&
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,
...
@@ -1614,7 +1614,7 @@ static int abx500_chargalg_get_property(struct power_supply *psy,
if
(
di
->
events
.
batt_ovv
)
{
if
(
di
->
events
.
batt_ovv
)
{
val
->
intval
=
POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
val
->
intval
=
POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
}
else
if
(
di
->
events
.
btemp_underover
)
{
}
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
;
val
->
intval
=
POWER_SUPPLY_HEALTH_COLD
;
else
else
val
->
intval
=
POWER_SUPPLY_HEALTH_OVERHEAT
;
val
->
intval
=
POWER_SUPPLY_HEALTH_OVERHEAT
;
...
@@ -1806,6 +1806,7 @@ static char *supply_interface[] = {
...
@@ -1806,6 +1806,7 @@ static char *supply_interface[] = {
static
int
abx500_chargalg_probe
(
struct
platform_device
*
pdev
)
static
int
abx500_chargalg_probe
(
struct
platform_device
*
pdev
)
{
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
abx500_bm_data
*
plat
=
pdev
->
dev
.
platform_data
;
struct
abx500_chargalg
*
di
;
struct
abx500_chargalg
*
di
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -1814,21 +1815,19 @@ static int abx500_chargalg_probe(struct platform_device *pdev)
...
@@ -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__
);
dev_err
(
&
pdev
->
dev
,
"%s no mem for ab8500_chargalg
\n
"
,
__func__
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
di
->
bat
=
pdev
->
mfd_cell
->
platform_data
;
if
(
!
di
->
b
at
)
{
if
(
!
pl
at
)
{
if
(
np
)
{
dev_err
(
&
pdev
->
dev
,
"no battery management data supplied
\n
"
);
ret
=
bmdevs_of_probe
(
&
pdev
->
dev
,
np
,
&
di
->
bat
)
;
return
-
EINVAL
;
if
(
ret
)
{
}
dev_err
(
&
pdev
->
dev
,
di
->
bm
=
plat
;
"failed to get battery information
\n
"
);
return
ret
;
if
(
np
)
{
}
ret
=
ab8500_bm_of_probe
(
&
pdev
->
dev
,
np
,
di
->
bm
);
}
else
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"
missing dt node for ab8500_chargalg
\n
"
);
dev_err
(
&
pdev
->
dev
,
"
failed to get battery information
\n
"
);
return
-
EINVAL
;
return
ret
;
}
}
}
else
{
dev_info
(
&
pdev
->
dev
,
"falling back to legacy platform data
\n
"
);
}
}
/* get device struct */
/* get device struct */
...
...
include/linux/mfd/abx500.h
浏览文件 @
240fbe23
...
@@ -279,9 +279,9 @@ enum {
...
@@ -279,9 +279,9 @@ enum {
NTC_INTERNAL
,
NTC_INTERNAL
,
};
};
int
bmdevs
_of_probe
(
struct
device
*
dev
,
int
ab8500_bm
_of_probe
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
device_node
*
np
,
struct
abx500_bm_data
**
battery
);
struct
abx500_bm_data
*
bm
);
int
abx500_set_register_interruptible
(
struct
device
*
dev
,
u8
bank
,
u8
reg
,
int
abx500_set_register_interruptible
(
struct
device
*
dev
,
u8
bank
,
u8
reg
,
u8
value
);
u8
value
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录