Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
8bb17b6c
Commit
8bb17b6c
authored
Jan 04, 2017
by
Sebastian Reichel
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'psy-mfd-axp288-immutable' into psy-next
parents
feb583e3
888f9743
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
470 deletions
+96
-470
drivers/power/supply/axp288_charger.c
drivers/power/supply/axp288_charger.c
+63
-69
drivers/power/supply/axp288_fuel_gauge.c
drivers/power/supply/axp288_fuel_gauge.c
+33
-372
include/linux/mfd/axp20x.h
include/linux/mfd/axp20x.h
+0
-29
No files found.
drivers/power/supply/axp288_charger.c
View file @
8bb17b6c
...
...
@@ -143,7 +143,6 @@ enum {
struct
axp288_chrg_info
{
struct
platform_device
*
pdev
;
struct
axp20x_chrg_pdata
*
pdata
;
struct
regmap
*
regmap
;
struct
regmap_irq_chip_data
*
regmap_irqc
;
int
irq
[
CHRG_INTR_END
];
...
...
@@ -701,110 +700,112 @@ static int axp288_charger_handle_otg_evt(struct notifier_block *nb,
return
NOTIFY_OK
;
}
static
void
charger_init_hw_regs
(
struct
axp288_chrg_info
*
info
)
static
int
charger_init_hw_regs
(
struct
axp288_chrg_info
*
info
)
{
int
ret
,
cc
,
cv
;
unsigned
int
val
;
/* Program temperature thresholds */
ret
=
regmap_write
(
info
->
regmap
,
AXP20X_V_LTF_CHRG
,
CHRG_VLTFC_0C
);
if
(
ret
<
0
)
dev_
warn
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
if
(
ret
<
0
)
{
dev_
err
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
AXP20X_V_LTF_CHRG
,
ret
);
return
ret
;
}
ret
=
regmap_write
(
info
->
regmap
,
AXP20X_V_HTF_CHRG
,
CHRG_VHTFC_45C
);
if
(
ret
<
0
)
dev_
warn
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
if
(
ret
<
0
)
{
dev_
err
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
AXP20X_V_HTF_CHRG
,
ret
);
return
ret
;
}
/* Do not turn-off charger o/p after charge cycle ends */
ret
=
regmap_update_bits
(
info
->
regmap
,
AXP20X_CHRG_CTRL2
,
CNTL2_CHG_OUT_TURNON
,
1
);
if
(
ret
<
0
)
dev_
warn
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
if
(
ret
<
0
)
{
dev_
err
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
AXP20X_CHRG_CTRL2
,
ret
);
return
ret
;
}
/* Enable interrupts */
ret
=
regmap_update_bits
(
info
->
regmap
,
AXP20X_IRQ2_EN
,
BAT_IRQ_CFG_BAT_MASK
,
1
);
if
(
ret
<
0
)
dev_
warn
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
if
(
ret
<
0
)
{
dev_
err
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
AXP20X_IRQ2_EN
,
ret
);
return
ret
;
}
ret
=
regmap_update_bits
(
info
->
regmap
,
AXP20X_IRQ3_EN
,
TEMP_IRQ_CFG_MASK
,
1
);
if
(
ret
<
0
)
dev_
warn
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
if
(
ret
<
0
)
{
dev_
err
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
AXP20X_IRQ3_EN
,
ret
);
return
ret
;
}
/* Setup ending condition for charging to be 10% of I(chrg) */
ret
=
regmap_update_bits
(
info
->
regmap
,
AXP20X_CHRG_CTRL1
,
CHRG_CCCV_ITERM_20P
,
0
);
if
(
ret
<
0
)
dev_
warn
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
if
(
ret
<
0
)
{
dev_
err
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
AXP20X_CHRG_CTRL1
,
ret
);
return
ret
;
}
/* Disable OCV-SOC curve calibration */
ret
=
regmap_update_bits
(
info
->
regmap
,
AXP20X_CC_CTRL
,
FG_CNTL_OCV_ADJ_EN
,
0
);
if
(
ret
<
0
)
dev_
warn
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
if
(
ret
<
0
)
{
dev_
err
(
&
info
->
pdev
->
dev
,
"register(%x) write error(%d)
\n
"
,
AXP20X_CC_CTRL
,
ret
);
/* Init charging current and voltage */
info
->
max_cc
=
info
->
pdata
->
max_cc
;
info
->
max_cv
=
info
->
pdata
->
max_cv
;
return
ret
;
}
/* Read current charge voltage and current limit */
ret
=
regmap_read
(
info
->
regmap
,
AXP20X_CHRG_CTRL1
,
&
val
);
if
(
ret
<
0
)
{
/* Assume default if cannot read */
info
->
cc
=
info
->
pdata
->
def_cc
;
info
->
cv
=
info
->
pdata
->
def_cv
;
}
else
{
/* Determine charge voltage */
cv
=
(
val
&
CHRG_CCCV_CV_MASK
)
>>
CHRG_CCCV_CV_BIT_POS
;
switch
(
cv
)
{
case
CHRG_CCCV_CV_4100MV
:
info
->
cv
=
CV_4100MV
;
break
;
case
CHRG_CCCV_CV_4150MV
:
info
->
cv
=
CV_4150MV
;
break
;
case
CHRG_CCCV_CV_4200MV
:
info
->
cv
=
CV_4200MV
;
break
;
case
CHRG_CCCV_CV_4350MV
:
info
->
cv
=
CV_4350MV
;
break
;
default:
info
->
cv
=
INT_MAX
;
break
;
}
dev_err
(
&
info
->
pdev
->
dev
,
"register(%x) read error(%d)
\n
"
,
AXP20X_CHRG_CTRL1
,
ret
);
return
ret
;
}
/* Determine charge current limit */
cc
=
(
ret
&
CHRG_CCCV_CC_MASK
)
>>
CHRG_CCCV_CC_BIT_POS
;
cc
=
(
cc
*
CHRG_CCCV_CC_LSB_RES
)
+
CHRG_CCCV_CC_OFFSET
;
info
->
cc
=
cc
;
/* Determine charge voltage */
cv
=
(
val
&
CHRG_CCCV_CV_MASK
)
>>
CHRG_CCCV_CV_BIT_POS
;
switch
(
cv
)
{
case
CHRG_CCCV_CV_4100MV
:
info
->
cv
=
CV_4100MV
;
break
;
case
CHRG_CCCV_CV_4150MV
:
info
->
cv
=
CV_4150MV
;
break
;
case
CHRG_CCCV_CV_4200MV
:
info
->
cv
=
CV_4200MV
;
break
;
case
CHRG_CCCV_CV_4350MV
:
info
->
cv
=
CV_4350MV
;
break
;
}
/* Program default charging voltage and current */
cc
=
min
(
info
->
pdata
->
def_cc
,
info
->
max_cc
);
cv
=
min
(
info
->
pdata
->
def_cv
,
info
->
max_cv
);
/* Determine charge current limit */
cc
=
(
ret
&
CHRG_CCCV_CC_MASK
)
>>
CHRG_CCCV_CC_BIT_POS
;
cc
=
(
cc
*
CHRG_CCCV_CC_LSB_RES
)
+
CHRG_CCCV_CC_OFFSET
;
info
->
cc
=
cc
;
ret
=
axp288_charger_set_cc
(
info
,
cc
);
if
(
ret
<
0
)
dev_warn
(
&
info
->
pdev
->
dev
,
"error(%d) in setting CC
\n
"
,
ret
);
/*
* Do not allow the user to configure higher settings then those
* set by the firmware
*/
info
->
max_cv
=
info
->
cv
;
info
->
max_cc
=
info
->
cc
;
ret
=
axp288_charger_set_cv
(
info
,
cv
);
if
(
ret
<
0
)
dev_warn
(
&
info
->
pdev
->
dev
,
"error(%d) in setting CV
\n
"
,
ret
);
}
return
0
;
}
static
int
axp288_charger_probe
(
struct
platform_device
*
pdev
)
...
...
@@ -821,15 +822,6 @@ static int axp288_charger_probe(struct platform_device *pdev)
info
->
pdev
=
pdev
;
info
->
regmap
=
axp20x
->
regmap
;
info
->
regmap_irqc
=
axp20x
->
regmap_irqc
;
info
->
pdata
=
pdev
->
dev
.
platform_data
;
if
(
!
info
->
pdata
)
{
/* Try ACPI provided pdata via device properties */
if
(
!
device_property_present
(
&
pdev
->
dev
,
"axp288_charger_data
\n
"
))
dev_err
(
&
pdev
->
dev
,
"failed to get platform data
\n
"
);
return
-
ENODEV
;
}
info
->
cable
.
edev
=
extcon_get_extcon_dev
(
AXP288_EXTCON_DEV_NAME
);
if
(
info
->
cable
.
edev
==
NULL
)
{
...
...
@@ -910,7 +902,9 @@ static int axp288_charger_probe(struct platform_device *pdev)
}
}
charger_init_hw_regs
(
info
);
ret
=
charger_init_hw_regs
(
info
);
if
(
ret
)
goto
intr_reg_failed
;
return
0
;
...
...
drivers/power/supply/axp288_fuel_gauge.c
View file @
8bb17b6c
...
...
@@ -50,11 +50,6 @@
#define CHRG_CCCV_CV_4350MV 0x3
/* 4.35V */
#define CHRG_CCCV_CHG_EN (1 << 7)
#define CV_4100 4100
/* 4100mV */
#define CV_4150 4150
/* 4150mV */
#define CV_4200 4200
/* 4200mV */
#define CV_4350 4350
/* 4350mV */
#define TEMP_IRQ_CFG_QWBTU (1 << 0)
#define TEMP_IRQ_CFG_WBTU (1 << 1)
#define TEMP_IRQ_CFG_QWBTO (1 << 2)
...
...
@@ -103,9 +98,7 @@
/* 1.1mV per LSB expressed in uV */
#define VOLTAGE_FROM_ADC(a) ((a * 11) / 10)
/* properties converted to tenths of degrees, uV, uA, uW */
#define PROP_TEMP(a) ((a) * 10)
#define UNPROP_TEMP(a) ((a) / 10)
/* properties converted to uV, uA */
#define PROP_VOLT(a) ((a) * 1000)
#define PROP_CURR(a) ((a) * 1000)
...
...
@@ -121,13 +114,13 @@ enum {
struct
axp288_fg_info
{
struct
platform_device
*
pdev
;
struct
axp20x_fg_pdata
*
pdata
;
struct
regmap
*
regmap
;
struct
regmap_irq_chip_data
*
regmap_irqc
;
int
irq
[
AXP288_FG_INTR_NUM
];
struct
power_supply
*
bat
;
struct
mutex
lock
;
int
status
;
int
max_volt
;
struct
delayed_work
status_monitor
;
struct
dentry
*
debug_file
;
};
...
...
@@ -137,22 +130,14 @@ static enum power_supply_property fuel_gauge_props[] = {
POWER_SUPPLY_PROP_PRESENT
,
POWER_SUPPLY_PROP_HEALTH
,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN
,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN
,
POWER_SUPPLY_PROP_VOLTAGE_NOW
,
POWER_SUPPLY_PROP_VOLTAGE_OCV
,
POWER_SUPPLY_PROP_CURRENT_NOW
,
POWER_SUPPLY_PROP_CAPACITY
,
POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN
,
POWER_SUPPLY_PROP_TEMP
,
POWER_SUPPLY_PROP_TEMP_MAX
,
POWER_SUPPLY_PROP_TEMP_MIN
,
POWER_SUPPLY_PROP_TEMP_ALERT_MIN
,
POWER_SUPPLY_PROP_TEMP_ALERT_MAX
,
POWER_SUPPLY_PROP_TECHNOLOGY
,
POWER_SUPPLY_PROP_CHARGE_FULL
,
POWER_SUPPLY_PROP_CHARGE_NOW
,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN
,
POWER_SUPPLY_PROP_MODEL_NAME
,
};
static
int
fuel_gauge_reg_readb
(
struct
axp288_fg_info
*
info
,
int
reg
)
...
...
@@ -447,102 +432,6 @@ static int fuel_gauge_get_current(struct axp288_fg_info *info, int *cur)
return
ret
;
}
static
int
temp_to_adc
(
struct
axp288_fg_info
*
info
,
int
tval
)
{
int
rntc
=
0
,
i
,
ret
,
adc_val
;
int
rmin
,
rmax
,
tmin
,
tmax
;
int
tcsz
=
info
->
pdata
->
tcsz
;
/* get the Rntc resitance value for this temp */
if
(
tval
>
info
->
pdata
->
thermistor_curve
[
0
][
1
])
{
rntc
=
info
->
pdata
->
thermistor_curve
[
0
][
0
];
}
else
if
(
tval
<=
info
->
pdata
->
thermistor_curve
[
tcsz
-
1
][
1
])
{
rntc
=
info
->
pdata
->
thermistor_curve
[
tcsz
-
1
][
0
];
}
else
{
for
(
i
=
1
;
i
<
tcsz
;
i
++
)
{
if
(
tval
>
info
->
pdata
->
thermistor_curve
[
i
][
1
])
{
rmin
=
info
->
pdata
->
thermistor_curve
[
i
-
1
][
0
];
rmax
=
info
->
pdata
->
thermistor_curve
[
i
][
0
];
tmin
=
info
->
pdata
->
thermistor_curve
[
i
-
1
][
1
];
tmax
=
info
->
pdata
->
thermistor_curve
[
i
][
1
];
rntc
=
rmin
+
((
rmax
-
rmin
)
*
(
tval
-
tmin
)
/
(
tmax
-
tmin
));
break
;
}
}
}
/* we need the current to calculate the proper adc voltage */
ret
=
fuel_gauge_reg_readb
(
info
,
AXP20X_ADC_RATE
);
if
(
ret
<
0
)
{
dev_err
(
&
info
->
pdev
->
dev
,
"%s:read err:%d
\n
"
,
__func__
,
ret
);
ret
=
0x30
;
}
/*
* temperature is proportional to NTS thermistor resistance
* ADC_RATE[5-4] determines current, 00=20uA,01=40uA,10=60uA,11=80uA
* [12-bit ADC VAL] = R_NTC(Ω) * current / 800
*/
adc_val
=
rntc
*
(
20
+
(
20
*
((
ret
>>
4
)
&
0x3
)))
/
800
;
return
adc_val
;
}
static
int
adc_to_temp
(
struct
axp288_fg_info
*
info
,
int
adc_val
)
{
int
ret
,
r
,
i
,
tval
=
0
;
int
rmin
,
rmax
,
tmin
,
tmax
;
int
tcsz
=
info
->
pdata
->
tcsz
;
ret
=
fuel_gauge_reg_readb
(
info
,
AXP20X_ADC_RATE
);
if
(
ret
<
0
)
{
dev_err
(
&
info
->
pdev
->
dev
,
"%s:read err:%d
\n
"
,
__func__
,
ret
);
ret
=
0x30
;
}
/*
* temperature is proportional to NTS thermistor resistance
* ADC_RATE[5-4] determines current, 00=20uA,01=40uA,10=60uA,11=80uA
* R_NTC(Ω) = [12-bit ADC VAL] * 800 / current
*/
r
=
adc_val
*
800
/
(
20
+
(
20
*
((
ret
>>
4
)
&
0x3
)));
if
(
r
<
info
->
pdata
->
thermistor_curve
[
0
][
0
])
{
tval
=
info
->
pdata
->
thermistor_curve
[
0
][
1
];
}
else
if
(
r
>=
info
->
pdata
->
thermistor_curve
[
tcsz
-
1
][
0
])
{
tval
=
info
->
pdata
->
thermistor_curve
[
tcsz
-
1
][
1
];
}
else
{
for
(
i
=
1
;
i
<
tcsz
;
i
++
)
{
if
(
r
<
info
->
pdata
->
thermistor_curve
[
i
][
0
])
{
rmin
=
info
->
pdata
->
thermistor_curve
[
i
-
1
][
0
];
rmax
=
info
->
pdata
->
thermistor_curve
[
i
][
0
];
tmin
=
info
->
pdata
->
thermistor_curve
[
i
-
1
][
1
];
tmax
=
info
->
pdata
->
thermistor_curve
[
i
][
1
];
tval
=
tmin
+
((
tmax
-
tmin
)
*
(
r
-
rmin
)
/
(
rmax
-
rmin
));
break
;
}
}
}
return
tval
;
}
static
int
fuel_gauge_get_btemp
(
struct
axp288_fg_info
*
info
,
int
*
btemp
)
{
int
ret
,
raw_val
=
0
;
ret
=
pmic_read_adc_val
(
"axp288-batt-temp"
,
&
raw_val
,
info
);
if
(
ret
<
0
)
goto
temp_read_fail
;
*
btemp
=
adc_to_temp
(
info
,
raw_val
);
temp_read_fail:
return
ret
;
}
static
int
fuel_gauge_get_vocv
(
struct
axp288_fg_info
*
info
,
int
*
vocv
)
{
int
ret
;
...
...
@@ -556,25 +445,14 @@ static int fuel_gauge_get_vocv(struct axp288_fg_info *info, int *vocv)
static
int
fuel_gauge_battery_health
(
struct
axp288_fg_info
*
info
)
{
int
temp
,
vocv
;
int
ret
,
health
=
POWER_SUPPLY_HEALTH_UNKNOWN
;
ret
=
fuel_gauge_get_btemp
(
info
,
&
temp
);
if
(
ret
<
0
)
goto
health_read_fail
;
int
ret
,
vocv
,
health
=
POWER_SUPPLY_HEALTH_UNKNOWN
;
ret
=
fuel_gauge_get_vocv
(
info
,
&
vocv
);
if
(
ret
<
0
)
goto
health_read_fail
;
if
(
vocv
>
info
->
pdata
->
max_volt
)
if
(
vocv
>
info
->
max_volt
)
health
=
POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
else
if
(
temp
>
info
->
pdata
->
max_temp
)
health
=
POWER_SUPPLY_HEALTH_OVERHEAT
;
else
if
(
temp
<
info
->
pdata
->
min_temp
)
health
=
POWER_SUPPLY_HEALTH_COLD
;
else
if
(
vocv
<
info
->
pdata
->
min_volt
)
health
=
POWER_SUPPLY_HEALTH_DEAD
;
else
health
=
POWER_SUPPLY_HEALTH_GOOD
;
...
...
@@ -582,28 +460,6 @@ static int fuel_gauge_battery_health(struct axp288_fg_info *info)
return
health
;
}
static
int
fuel_gauge_set_high_btemp_alert
(
struct
axp288_fg_info
*
info
)
{
int
ret
,
adc_val
;
/* program temperature threshold as 1/16 ADC value */
adc_val
=
temp_to_adc
(
info
,
info
->
pdata
->
max_temp
);
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP20X_V_HTF_DISCHRG
,
adc_val
>>
4
);
return
ret
;
}
static
int
fuel_gauge_set_low_btemp_alert
(
struct
axp288_fg_info
*
info
)
{
int
ret
,
adc_val
;
/* program temperature threshold as 1/16 ADC value */
adc_val
=
temp_to_adc
(
info
,
info
->
pdata
->
min_temp
);
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP20X_V_LTF_DISCHRG
,
adc_val
>>
4
);
return
ret
;
}
static
int
fuel_gauge_get_property
(
struct
power_supply
*
ps
,
enum
power_supply_property
prop
,
union
power_supply_propval
*
val
)
...
...
@@ -664,20 +520,6 @@ static int fuel_gauge_get_property(struct power_supply *ps,
goto
fuel_gauge_read_err
;
val
->
intval
=
(
ret
&
0x0f
);
break
;
case
POWER_SUPPLY_PROP_TEMP
:
ret
=
fuel_gauge_get_btemp
(
info
,
&
value
);
if
(
ret
<
0
)
goto
fuel_gauge_read_err
;
val
->
intval
=
PROP_TEMP
(
value
);
break
;
case
POWER_SUPPLY_PROP_TEMP_MAX
:
case
POWER_SUPPLY_PROP_TEMP_ALERT_MAX
:
val
->
intval
=
PROP_TEMP
(
info
->
pdata
->
max_temp
);
break
;
case
POWER_SUPPLY_PROP_TEMP_MIN
:
case
POWER_SUPPLY_PROP_TEMP_ALERT_MIN
:
val
->
intval
=
PROP_TEMP
(
info
->
pdata
->
min_temp
);
break
;
case
POWER_SUPPLY_PROP_TECHNOLOGY
:
val
->
intval
=
POWER_SUPPLY_TECHNOLOGY_LION
;
break
;
...
...
@@ -695,17 +537,8 @@ static int fuel_gauge_get_property(struct power_supply *ps,
val
->
intval
=
ret
*
FG_DES_CAP_RES_LSB
;
break
;
case
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN
:
val
->
intval
=
PROP_CURR
(
info
->
pdata
->
design_cap
);
break
;
case
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN
:
val
->
intval
=
PROP_VOLT
(
info
->
pdata
->
max_volt
);
break
;
case
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN
:
val
->
intval
=
PROP_VOLT
(
info
->
pdata
->
min_volt
);
break
;
case
POWER_SUPPLY_PROP_MODEL_NAME
:
val
->
strval
=
info
->
pdata
->
battid
;
val
->
intval
=
PROP_VOLT
(
info
->
max_volt
);
break
;
default:
mutex_unlock
(
&
info
->
lock
);
...
...
@@ -729,35 +562,6 @@ static int fuel_gauge_set_property(struct power_supply *ps,
mutex_lock
(
&
info
->
lock
);
switch
(
prop
)
{
case
POWER_SUPPLY_PROP_STATUS
:
info
->
status
=
val
->
intval
;
break
;
case
POWER_SUPPLY_PROP_TEMP_MIN
:
case
POWER_SUPPLY_PROP_TEMP_ALERT_MIN
:
if
((
val
->
intval
<
PD_DEF_MIN_TEMP
)
||
(
val
->
intval
>
PD_DEF_MAX_TEMP
))
{
ret
=
-
EINVAL
;
break
;
}
info
->
pdata
->
min_temp
=
UNPROP_TEMP
(
val
->
intval
);
ret
=
fuel_gauge_set_low_btemp_alert
(
info
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"temp alert min set fail:%d
\n
"
,
ret
);
break
;
case
POWER_SUPPLY_PROP_TEMP_MAX
:
case
POWER_SUPPLY_PROP_TEMP_ALERT_MAX
:
if
((
val
->
intval
<
PD_DEF_MIN_TEMP
)
||
(
val
->
intval
>
PD_DEF_MAX_TEMP
))
{
ret
=
-
EINVAL
;
break
;
}
info
->
pdata
->
max_temp
=
UNPROP_TEMP
(
val
->
intval
);
ret
=
fuel_gauge_set_high_btemp_alert
(
info
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"temp alert max set fail:%d
\n
"
,
ret
);
break
;
case
POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN
:
if
((
val
->
intval
<
0
)
||
(
val
->
intval
>
15
))
{
ret
=
-
EINVAL
;
...
...
@@ -785,11 +589,6 @@ static int fuel_gauge_property_is_writeable(struct power_supply *psy,
int
ret
;
switch
(
psp
)
{
case
POWER_SUPPLY_PROP_STATUS
:
case
POWER_SUPPLY_PROP_TEMP_MIN
:
case
POWER_SUPPLY_PROP_TEMP_ALERT_MIN
:
case
POWER_SUPPLY_PROP_TEMP_MAX
:
case
POWER_SUPPLY_PROP_TEMP_ALERT_MAX
:
case
POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN
:
ret
=
1
;
break
;
...
...
@@ -874,158 +673,6 @@ static const struct power_supply_desc fuel_gauge_desc = {
.
external_power_changed
=
fuel_gauge_external_power_changed
,
};
static
int
fuel_gauge_set_lowbatt_thresholds
(
struct
axp288_fg_info
*
info
)
{
int
ret
;
u8
reg_val
;
ret
=
fuel_gauge_reg_readb
(
info
,
AXP20X_FG_RES
);
if
(
ret
<
0
)
{
dev_err
(
&
info
->
pdev
->
dev
,
"%s:read err:%d
\n
"
,
__func__
,
ret
);
return
ret
;
}
ret
=
(
ret
&
FG_REP_CAP_VAL_MASK
);
if
(
ret
>
FG_LOW_CAP_WARN_THR
)
reg_val
=
FG_LOW_CAP_WARN_THR
;
else
if
(
ret
>
FG_LOW_CAP_CRIT_THR
)
reg_val
=
FG_LOW_CAP_CRIT_THR
;
else
reg_val
=
FG_LOW_CAP_SHDN_THR
;
reg_val
|=
FG_LOW_CAP_THR1_VAL
;
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP288_FG_LOW_CAP_REG
,
reg_val
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"%s:write err:%d
\n
"
,
__func__
,
ret
);
return
ret
;
}
static
int
fuel_gauge_program_vbatt_full
(
struct
axp288_fg_info
*
info
)
{
int
ret
;
u8
val
;
ret
=
fuel_gauge_reg_readb
(
info
,
AXP20X_CHRG_CTRL1
);
if
(
ret
<
0
)
goto
fg_prog_ocv_fail
;
else
val
=
(
ret
&
~
CHRG_CCCV_CV_MASK
);
switch
(
info
->
pdata
->
max_volt
)
{
case
CV_4100
:
val
|=
(
CHRG_CCCV_CV_4100MV
<<
CHRG_CCCV_CV_BIT_POS
);
break
;
case
CV_4150
:
val
|=
(
CHRG_CCCV_CV_4150MV
<<
CHRG_CCCV_CV_BIT_POS
);
break
;
case
CV_4200
:
val
|=
(
CHRG_CCCV_CV_4200MV
<<
CHRG_CCCV_CV_BIT_POS
);
break
;
case
CV_4350
:
val
|=
(
CHRG_CCCV_CV_4350MV
<<
CHRG_CCCV_CV_BIT_POS
);
break
;
default:
val
|=
(
CHRG_CCCV_CV_4200MV
<<
CHRG_CCCV_CV_BIT_POS
);
break
;
}
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP20X_CHRG_CTRL1
,
val
);
fg_prog_ocv_fail:
return
ret
;
}
static
int
fuel_gauge_program_design_cap
(
struct
axp288_fg_info
*
info
)
{
int
ret
;
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP288_FG_DES_CAP1_REG
,
info
->
pdata
->
cap1
);
if
(
ret
<
0
)
goto
fg_prog_descap_fail
;
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP288_FG_DES_CAP0_REG
,
info
->
pdata
->
cap0
);
fg_prog_descap_fail:
return
ret
;
}
static
int
fuel_gauge_program_ocv_curve
(
struct
axp288_fg_info
*
info
)
{
int
ret
=
0
,
i
;
for
(
i
=
0
;
i
<
OCV_CURVE_SIZE
;
i
++
)
{
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP288_FG_OCV_CURVE_REG
+
i
,
info
->
pdata
->
ocv_curve
[
i
]);
if
(
ret
<
0
)
goto
fg_prog_ocv_fail
;
}
fg_prog_ocv_fail:
return
ret
;
}
static
int
fuel_gauge_program_rdc_vals
(
struct
axp288_fg_info
*
info
)
{
int
ret
;
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP288_FG_RDC1_REG
,
info
->
pdata
->
rdc1
);
if
(
ret
<
0
)
goto
fg_prog_ocv_fail
;
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP288_FG_RDC0_REG
,
info
->
pdata
->
rdc0
);
fg_prog_ocv_fail:
return
ret
;
}
static
void
fuel_gauge_init_config_regs
(
struct
axp288_fg_info
*
info
)
{
int
ret
;
/*
* check if the config data is already
* programmed and if so just return.
*/
ret
=
fuel_gauge_reg_readb
(
info
,
AXP288_FG_DES_CAP1_REG
);
if
(
ret
<
0
)
{
dev_warn
(
&
info
->
pdev
->
dev
,
"CAP1 reg read err!!
\n
"
);
}
else
if
(
!
(
ret
&
FG_DES_CAP1_VALID
))
{
dev_info
(
&
info
->
pdev
->
dev
,
"FG data needs to be initialized
\n
"
);
}
else
{
dev_info
(
&
info
->
pdev
->
dev
,
"FG data is already initialized
\n
"
);
return
;
}
ret
=
fuel_gauge_program_vbatt_full
(
info
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"set vbatt full fail:%d
\n
"
,
ret
);
ret
=
fuel_gauge_program_design_cap
(
info
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"set design cap fail:%d
\n
"
,
ret
);
ret
=
fuel_gauge_program_rdc_vals
(
info
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"set rdc fail:%d
\n
"
,
ret
);
ret
=
fuel_gauge_program_ocv_curve
(
info
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"set ocv curve fail:%d
\n
"
,
ret
);
ret
=
fuel_gauge_set_lowbatt_thresholds
(
info
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"lowbatt thr set fail:%d
\n
"
,
ret
);
ret
=
fuel_gauge_reg_writeb
(
info
,
AXP20X_CC_CTRL
,
0xef
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"gauge cntl set fail:%d
\n
"
,
ret
);
}
static
void
fuel_gauge_init_irq
(
struct
axp288_fg_info
*
info
)
{
int
ret
,
i
,
pirq
;
...
...
@@ -1065,17 +712,8 @@ static void fuel_gauge_init_irq(struct axp288_fg_info *info)
static
void
fuel_gauge_init_hw_regs
(
struct
axp288_fg_info
*
info
)
{
int
ret
;
unsigned
int
val
;
ret
=
fuel_gauge_set_high_btemp_alert
(
info
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"high batt temp set fail:%d
\n
"
,
ret
);
ret
=
fuel_gauge_set_low_btemp_alert
(
info
);
if
(
ret
<
0
)
dev_err
(
&
info
->
pdev
->
dev
,
"low batt temp set fail:%d
\n
"
,
ret
);
/* enable interrupts */
val
=
fuel_gauge_reg_readb
(
info
,
AXP20X_IRQ3_EN
);
val
|=
TEMP_IRQ_CFG_MASK
;
...
...
@@ -1101,15 +739,39 @@ static int axp288_fuel_gauge_probe(struct platform_device *pdev)
info
->
regmap
=
axp20x
->
regmap
;
info
->
regmap_irqc
=
axp20x
->
regmap_irqc
;
info
->
status
=
POWER_SUPPLY_STATUS_UNKNOWN
;
info
->
pdata
=
pdev
->
dev
.
platform_data
;
if
(
!
info
->
pdata
)
return
-
ENODEV
;
platform_set_drvdata
(
pdev
,
info
);
mutex_init
(
&
info
->
lock
);
INIT_DELAYED_WORK
(
&
info
->
status_monitor
,
fuel_gauge_status_monitor
);
ret
=
fuel_gauge_reg_readb
(
info
,
AXP288_FG_DES_CAP1_REG
);
if
(
ret
<
0
)
return
ret
;
if
(
!
(
ret
&
FG_DES_CAP1_VALID
))
{
dev_err
(
&
pdev
->
dev
,
"axp288 not configured by firmware
\n
"
);
return
-
ENODEV
;
}
ret
=
fuel_gauge_reg_readb
(
info
,
AXP20X_CHRG_CTRL1
);
if
(
ret
<
0
)
return
ret
;
switch
((
ret
&
CHRG_CCCV_CV_MASK
)
>>
CHRG_CCCV_CV_BIT_POS
)
{
case
CHRG_CCCV_CV_4100MV
:
info
->
max_volt
=
4100
;
break
;
case
CHRG_CCCV_CV_4150MV
:
info
->
max_volt
=
4150
;
break
;
case
CHRG_CCCV_CV_4200MV
:
info
->
max_volt
=
4200
;
break
;
case
CHRG_CCCV_CV_4350MV
:
info
->
max_volt
=
4350
;
break
;
}
psy_cfg
.
drv_data
=
info
;
info
->
bat
=
power_supply_register
(
&
pdev
->
dev
,
&
fuel_gauge_desc
,
&
psy_cfg
);
if
(
IS_ERR
(
info
->
bat
))
{
...
...
@@ -1119,12 +781,11 @@ static int axp288_fuel_gauge_probe(struct platform_device *pdev)
}
fuel_gauge_create_debugfs
(
info
);
fuel_gauge_init_config_regs
(
info
);
fuel_gauge_init_irq
(
info
);
fuel_gauge_init_hw_regs
(
info
);
schedule_delayed_work
(
&
info
->
status_monitor
,
STATUS_MON_DELAY_JIFFIES
);
return
ret
;
return
0
;
}
static
const
struct
platform_device_id
axp288_fg_id_table
[]
=
{
...
...
include/linux/mfd/axp20x.h
View file @
8bb17b6c
...
...
@@ -532,35 +532,6 @@ struct axp20x_dev {
const
struct
regmap_irq_chip
*
regmap_irq_chip
;
};
#define BATTID_LEN 64
#define OCV_CURVE_SIZE 32
#define MAX_THERM_CURVE_SIZE 25
#define PD_DEF_MIN_TEMP 0
#define PD_DEF_MAX_TEMP 55
struct
axp20x_fg_pdata
{
char
battid
[
BATTID_LEN
+
1
];
int
design_cap
;
int
min_volt
;
int
max_volt
;
int
max_temp
;
int
min_temp
;
int
cap1
;
int
cap0
;
int
rdc1
;
int
rdc0
;
int
ocv_curve
[
OCV_CURVE_SIZE
];
int
tcsz
;
int
thermistor_curve
[
MAX_THERM_CURVE_SIZE
][
2
];
};
struct
axp20x_chrg_pdata
{
int
max_cc
;
int
max_cv
;
int
def_cc
;
int
def_cv
;
};
struct
axp288_extcon_pdata
{
/* GPIO pin control to switch D+/D- lines b/w PMIC and SOC */
struct
gpio_desc
*
gpio_mux_cntl
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment