Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
ae5f5203
Commit
ae5f5203
authored
Apr 28, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/topic/palmas' into v3.9-rc8
parents
75f01f94
0ea34b57
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
316 additions
and
73 deletions
+316
-73
drivers/regulator/palmas-regulator.c
drivers/regulator/palmas-regulator.c
+305
-60
include/linux/mfd/palmas.h
include/linux/mfd/palmas.h
+11
-13
No files found.
drivers/regulator/palmas-regulator.c
View file @
ae5f5203
/*
* Driver for Regulator part of Palmas PMIC Chips
*
* Copyright 2011-201
2
Texas Instruments Inc.
* Copyright 2011-201
3
Texas Instruments Inc.
*
* Author: Graeme Gregory <gg@slimlogic.co.uk>
* Author: Ian Lartey <ian@slimlogic.co.uk>
...
...
@@ -29,6 +29,7 @@
struct
regs_info
{
char
*
name
;
char
*
sname
;
u8
vsel_addr
;
u8
ctrl_addr
;
u8
tstep_addr
;
...
...
@@ -37,115 +38,159 @@ struct regs_info {
static
const
struct
regs_info
palmas_regs_info
[]
=
{
{
.
name
=
"SMPS12"
,
.
sname
=
"smps1-in"
,
.
vsel_addr
=
PALMAS_SMPS12_VOLTAGE
,
.
ctrl_addr
=
PALMAS_SMPS12_CTRL
,
.
tstep_addr
=
PALMAS_SMPS12_TSTEP
,
},
{
.
name
=
"SMPS123"
,
.
sname
=
"smps1-in"
,
.
vsel_addr
=
PALMAS_SMPS12_VOLTAGE
,
.
ctrl_addr
=
PALMAS_SMPS12_CTRL
,
.
tstep_addr
=
PALMAS_SMPS12_TSTEP
,
},
{
.
name
=
"SMPS3"
,
.
sname
=
"smps3-in"
,
.
vsel_addr
=
PALMAS_SMPS3_VOLTAGE
,
.
ctrl_addr
=
PALMAS_SMPS3_CTRL
,
},
{
.
name
=
"SMPS45"
,
.
sname
=
"smps4-in"
,
.
vsel_addr
=
PALMAS_SMPS45_VOLTAGE
,
.
ctrl_addr
=
PALMAS_SMPS45_CTRL
,
.
tstep_addr
=
PALMAS_SMPS45_TSTEP
,
},
{
.
name
=
"SMPS457"
,
.
sname
=
"smps4-in"
,
.
vsel_addr
=
PALMAS_SMPS45_VOLTAGE
,
.
ctrl_addr
=
PALMAS_SMPS45_CTRL
,
.
tstep_addr
=
PALMAS_SMPS45_TSTEP
,
},
{
.
name
=
"SMPS6"
,
.
sname
=
"smps6-in"
,
.
vsel_addr
=
PALMAS_SMPS6_VOLTAGE
,
.
ctrl_addr
=
PALMAS_SMPS6_CTRL
,
.
tstep_addr
=
PALMAS_SMPS6_TSTEP
,
},
{
.
name
=
"SMPS7"
,
.
sname
=
"smps7-in"
,
.
vsel_addr
=
PALMAS_SMPS7_VOLTAGE
,
.
ctrl_addr
=
PALMAS_SMPS7_CTRL
,
},
{
.
name
=
"SMPS8"
,
.
sname
=
"smps8-in"
,
.
vsel_addr
=
PALMAS_SMPS8_VOLTAGE
,
.
ctrl_addr
=
PALMAS_SMPS8_CTRL
,
.
tstep_addr
=
PALMAS_SMPS8_TSTEP
,
},
{
.
name
=
"SMPS9"
,
.
sname
=
"smps9-in"
,
.
vsel_addr
=
PALMAS_SMPS9_VOLTAGE
,
.
ctrl_addr
=
PALMAS_SMPS9_CTRL
,
},
{
.
name
=
"SMPS10"
,
.
sname
=
"smps10-in"
,
.
ctrl_addr
=
PALMAS_SMPS10_CTRL
,
},
{
.
name
=
"LDO1"
,
.
sname
=
"ldo1-in"
,
.
vsel_addr
=
PALMAS_LDO1_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDO1_CTRL
,
},
{
.
name
=
"LDO2"
,
.
sname
=
"ldo2-in"
,
.
vsel_addr
=
PALMAS_LDO2_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDO2_CTRL
,
},
{
.
name
=
"LDO3"
,
.
sname
=
"ldo3-in"
,
.
vsel_addr
=
PALMAS_LDO3_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDO3_CTRL
,
},
{
.
name
=
"LDO4"
,
.
sname
=
"ldo4-in"
,
.
vsel_addr
=
PALMAS_LDO4_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDO4_CTRL
,
},
{
.
name
=
"LDO5"
,
.
sname
=
"ldo5-in"
,
.
vsel_addr
=
PALMAS_LDO5_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDO5_CTRL
,
},
{
.
name
=
"LDO6"
,
.
sname
=
"ldo6-in"
,
.
vsel_addr
=
PALMAS_LDO6_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDO6_CTRL
,
},
{
.
name
=
"LDO7"
,
.
sname
=
"ldo7-in"
,
.
vsel_addr
=
PALMAS_LDO7_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDO7_CTRL
,
},
{
.
name
=
"LDO8"
,
.
sname
=
"ldo8-in"
,
.
vsel_addr
=
PALMAS_LDO8_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDO8_CTRL
,
},
{
.
name
=
"LDO9"
,
.
sname
=
"ldo9-in"
,
.
vsel_addr
=
PALMAS_LDO9_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDO9_CTRL
,
},
{
.
name
=
"LDOLN"
,
.
sname
=
"ldoln-in"
,
.
vsel_addr
=
PALMAS_LDOLN_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDOLN_CTRL
,
},
{
.
name
=
"LDOUSB"
,
.
sname
=
"ldousb-in"
,
.
vsel_addr
=
PALMAS_LDOUSB_VOLTAGE
,
.
ctrl_addr
=
PALMAS_LDOUSB_CTRL
,
},
{
.
name
=
"REGEN1"
,
.
ctrl_addr
=
PALMAS_REGEN1_CTRL
,
},
{
.
name
=
"REGEN2"
,
.
ctrl_addr
=
PALMAS_REGEN2_CTRL
,
},
{
.
name
=
"REGEN3"
,
.
ctrl_addr
=
PALMAS_REGEN3_CTRL
,
},
{
.
name
=
"SYSEN1"
,
.
ctrl_addr
=
PALMAS_SYSEN1_CTRL
,
},
{
.
name
=
"SYSEN2"
,
.
ctrl_addr
=
PALMAS_SYSEN2_CTRL
,
},
};
static
unsigned
int
palmas_smps_ramp_delay
[
4
]
=
{
0
,
10000
,
5000
,
2500
};
#define SMPS_CTRL_MODE_OFF 0x00
#define SMPS_CTRL_MODE_ON 0x01
#define SMPS_CTRL_MODE_ECO 0x02
...
...
@@ -231,6 +276,9 @@ static int palmas_enable_smps(struct regulator_dev *dev)
palmas_smps_read
(
pmic
->
palmas
,
palmas_regs_info
[
id
].
ctrl_addr
,
&
reg
);
reg
&=
~
PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK
;
if
(
pmic
->
current_reg_mode
[
id
])
reg
|=
pmic
->
current_reg_mode
[
id
];
else
reg
|=
SMPS_CTRL_MODE_ON
;
palmas_smps_write
(
pmic
->
palmas
,
palmas_regs_info
[
id
].
ctrl_addr
,
reg
);
...
...
@@ -253,16 +301,19 @@ static int palmas_disable_smps(struct regulator_dev *dev)
return
0
;
}
static
int
palmas_set_mode_smps
(
struct
regulator_dev
*
dev
,
unsigned
int
mode
)
{
struct
palmas_pmic
*
pmic
=
rdev_get_drvdata
(
dev
);
int
id
=
rdev_get_id
(
dev
);
unsigned
int
reg
;
bool
rail_enable
=
true
;
palmas_smps_read
(
pmic
->
palmas
,
palmas_regs_info
[
id
].
ctrl_addr
,
&
reg
);
reg
&=
~
PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK
;
if
(
reg
==
SMPS_CTRL_MODE_OFF
)
rail_enable
=
false
;
switch
(
mode
)
{
case
REGULATOR_MODE_NORMAL
:
reg
|=
SMPS_CTRL_MODE_ON
;
...
...
@@ -276,8 +327,11 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
default:
return
-
EINVAL
;
}
palmas_smps_write
(
pmic
->
palmas
,
palmas_regs_info
[
id
].
ctrl_addr
,
reg
);
pmic
->
current_reg_mode
[
id
]
=
reg
&
PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK
;
if
(
rail_enable
)
palmas_smps_write
(
pmic
->
palmas
,
palmas_regs_info
[
id
].
ctrl_addr
,
reg
);
return
0
;
}
...
...
@@ -287,9 +341,7 @@ static unsigned int palmas_get_mode_smps(struct regulator_dev *dev)
int
id
=
rdev_get_id
(
dev
);
unsigned
int
reg
;
palmas_smps_read
(
pmic
->
palmas
,
palmas_regs_info
[
id
].
ctrl_addr
,
&
reg
);
reg
&=
PALMAS_SMPS12_CTRL_STATUS_MASK
;
reg
>>=
PALMAS_SMPS12_CTRL_STATUS_SHIFT
;
reg
=
pmic
->
current_reg_mode
[
id
]
&
PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK
;
switch
(
reg
)
{
case
SMPS_CTRL_MODE_ON
:
...
...
@@ -356,6 +408,63 @@ static int palmas_map_voltage_smps(struct regulator_dev *rdev,
return
ret
;
}
static
int
palma_smps_set_voltage_smps_time_sel
(
struct
regulator_dev
*
rdev
,
unsigned
int
old_selector
,
unsigned
int
new_selector
)
{
struct
palmas_pmic
*
pmic
=
rdev_get_drvdata
(
rdev
);
int
id
=
rdev_get_id
(
rdev
);
int
old_uv
,
new_uv
;
unsigned
int
ramp_delay
=
pmic
->
ramp_delay
[
id
];
if
(
!
ramp_delay
)
return
0
;
old_uv
=
palmas_list_voltage_smps
(
rdev
,
old_selector
);
if
(
old_uv
<
0
)
return
old_uv
;
new_uv
=
palmas_list_voltage_smps
(
rdev
,
new_selector
);
if
(
new_uv
<
0
)
return
new_uv
;
return
DIV_ROUND_UP
(
abs
(
old_uv
-
new_uv
),
ramp_delay
);
}
static
int
palmas_smps_set_ramp_delay
(
struct
regulator_dev
*
rdev
,
int
ramp_delay
)
{
struct
palmas_pmic
*
pmic
=
rdev_get_drvdata
(
rdev
);
int
id
=
rdev_get_id
(
rdev
);
unsigned
int
reg
=
0
;
unsigned
int
addr
=
palmas_regs_info
[
id
].
tstep_addr
;
int
ret
;
/* SMPS3 and SMPS7 do not have tstep_addr setting */
switch
(
id
)
{
case
PALMAS_REG_SMPS3
:
case
PALMAS_REG_SMPS7
:
return
0
;
}
if
(
ramp_delay
<=
0
)
reg
=
0
;
else
if
(
ramp_delay
<=
2500
)
reg
=
3
;
else
if
(
ramp_delay
<=
5000
)
reg
=
2
;
else
reg
=
1
;
ret
=
palmas_smps_write
(
pmic
->
palmas
,
addr
,
reg
);
if
(
ret
<
0
)
{
dev_err
(
pmic
->
palmas
->
dev
,
"TSTEP write failed: %d
\n
"
,
ret
);
return
ret
;
}
pmic
->
ramp_delay
[
id
]
=
palmas_smps_ramp_delay
[
reg
];
return
ret
;
}
static
struct
regulator_ops
palmas_ops_smps
=
{
.
is_enabled
=
palmas_is_enabled_smps
,
.
enable
=
palmas_enable_smps
,
...
...
@@ -366,6 +475,8 @@ static struct regulator_ops palmas_ops_smps = {
.
set_voltage_sel
=
regulator_set_voltage_sel_regmap
,
.
list_voltage
=
palmas_list_voltage_smps
,
.
map_voltage
=
palmas_map_voltage_smps
,
.
set_voltage_time_sel
=
palma_smps_set_voltage_smps_time_sel
,
.
set_ramp_delay
=
palmas_smps_set_ramp_delay
,
};
static
struct
regulator_ops
palmas_ops_smps10
=
{
...
...
@@ -401,6 +512,12 @@ static struct regulator_ops palmas_ops_ldo = {
.
map_voltage
=
regulator_map_voltage_linear
,
};
static
struct
regulator_ops
palmas_ops_extreg
=
{
.
is_enabled
=
regulator_is_enabled_regmap
,
.
enable
=
regulator_enable_regmap
,
.
disable
=
regulator_disable_regmap
,
};
/*
* setup the hardware based sleep configuration of the SMPS/LDO regulators
* from the platform data. This is different to the software based control
...
...
@@ -422,39 +539,31 @@ static int palmas_smps_init(struct palmas *palmas, int id,
switch
(
id
)
{
case
PALMAS_REG_SMPS10
:
if
(
reg_init
->
mode_sleep
)
{
reg
&=
~
PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK
;
if
(
reg_init
->
mode_sleep
)
reg
|=
reg_init
->
mode_sleep
<<
PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT
;
}
break
;
default:
if
(
reg_init
->
warm_reset
)
reg
|=
PALMAS_SMPS12_CTRL_WR_S
;
else
reg
&=
~
PALMAS_SMPS12_CTRL_WR_S
;
if
(
reg_init
->
roof_floor
)
reg
|=
PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN
;
else
reg
&=
~
PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN
;
if
(
reg_init
->
mode_sleep
)
{
reg
&=
~
PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK
;
if
(
reg_init
->
mode_sleep
)
reg
|=
reg_init
->
mode_sleep
<<
PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT
;
}
}
ret
=
palmas_smps_write
(
palmas
,
addr
,
reg
);
if
(
ret
)
return
ret
;
if
(
palmas_regs_info
[
id
].
tstep_addr
&&
reg_init
->
tstep
)
{
addr
=
palmas_regs_info
[
id
].
tstep_addr
;
reg
=
reg_init
->
tstep
&
PALMAS_SMPS12_TSTEP_TSTEP_MASK
;
ret
=
palmas_smps_write
(
palmas
,
addr
,
reg
);
if
(
ret
)
return
ret
;
}
if
(
palmas_regs_info
[
id
].
vsel_addr
&&
reg_init
->
vsel
)
{
addr
=
palmas_regs_info
[
id
].
vsel_addr
;
...
...
@@ -485,9 +594,13 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
if
(
reg_init
->
warm_reset
)
reg
|=
PALMAS_LDO1_CTRL_WR_S
;
else
reg
&=
~
PALMAS_LDO1_CTRL_WR_S
;
if
(
reg_init
->
mode_sleep
)
reg
|=
PALMAS_LDO1_CTRL_MODE_SLEEP
;
else
reg
&=
~
PALMAS_LDO1_CTRL_MODE_SLEEP
;
ret
=
palmas_ldo_write
(
palmas
,
addr
,
reg
);
if
(
ret
)
...
...
@@ -496,6 +609,68 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
return
0
;
}
static
int
palmas_extreg_init
(
struct
palmas
*
palmas
,
int
id
,
struct
palmas_reg_init
*
reg_init
)
{
unsigned
int
addr
;
int
ret
;
unsigned
int
val
=
0
;
addr
=
palmas_regs_info
[
id
].
ctrl_addr
;
if
(
reg_init
->
mode_sleep
)
val
=
PALMAS_REGEN1_CTRL_MODE_SLEEP
;
ret
=
palmas_update_bits
(
palmas
,
PALMAS_RESOURCE_BASE
,
addr
,
PALMAS_REGEN1_CTRL_MODE_SLEEP
,
val
);
if
(
ret
<
0
)
{
dev_err
(
palmas
->
dev
,
"Resource reg 0x%02x update failed %d
\n
"
,
addr
,
ret
);
return
ret
;
}
return
0
;
}
static
void
palmas_enable_ldo8_track
(
struct
palmas
*
palmas
)
{
unsigned
int
reg
;
unsigned
int
addr
;
int
ret
;
addr
=
palmas_regs_info
[
PALMAS_REG_LDO8
].
ctrl_addr
;
ret
=
palmas_ldo_read
(
palmas
,
addr
,
&
reg
);
if
(
ret
)
{
dev_err
(
palmas
->
dev
,
"Error in reading ldo8 control reg
\n
"
);
return
;
}
reg
|=
PALMAS_LDO8_CTRL_LDO_TRACKING_EN
;
ret
=
palmas_ldo_write
(
palmas
,
addr
,
reg
);
if
(
ret
<
0
)
{
dev_err
(
palmas
->
dev
,
"Error in enabling tracking mode
\n
"
);
return
;
}
/*
* When SMPS45 is set to off and LDO8 tracking is enabled, the LDO8
* output is defined by the LDO8_VOLTAGE.VSEL register divided by two,
* and can be set from 0.45 to 1.65 V.
*/
addr
=
palmas_regs_info
[
PALMAS_REG_LDO8
].
vsel_addr
;
ret
=
palmas_ldo_read
(
palmas
,
addr
,
&
reg
);
if
(
ret
)
{
dev_err
(
palmas
->
dev
,
"Error in reading ldo8 voltage reg
\n
"
);
return
;
}
reg
=
(
reg
<<
1
)
&
PALMAS_LDO8_VOLTAGE_VSEL_MASK
;
ret
=
palmas_ldo_write
(
palmas
,
addr
,
reg
);
if
(
ret
<
0
)
dev_err
(
palmas
->
dev
,
"Error in setting ldo8 voltage reg
\n
"
);
return
;
}
static
struct
of_regulator_match
palmas_matches
[]
=
{
{
.
name
=
"smps12"
,
},
{
.
name
=
"smps123"
,
},
...
...
@@ -518,6 +693,11 @@ static struct of_regulator_match palmas_matches[] = {
{
.
name
=
"ldo9"
,
},
{
.
name
=
"ldoln"
,
},
{
.
name
=
"ldousb"
,
},
{
.
name
=
"regen1"
,
},
{
.
name
=
"regen2"
,
},
{
.
name
=
"regen3"
,
},
{
.
name
=
"sysen1"
,
},
{
.
name
=
"sysen2"
,
},
};
static
void
palmas_dt_to_pdata
(
struct
device
*
dev
,
...
...
@@ -553,39 +733,36 @@ static void palmas_dt_to_pdata(struct device *dev,
pdata
->
reg_init
[
idx
]
=
devm_kzalloc
(
dev
,
sizeof
(
struct
palmas_reg_init
),
GFP_KERNEL
);
ret
=
of_property_read_u32
(
palmas_matches
[
idx
].
of_node
,
"ti,warm_reset"
,
&
prop
);
if
(
!
ret
)
pdata
->
reg_init
[
idx
]
->
warm_reset
=
prop
;
pdata
->
reg_init
[
idx
]
->
warm_reset
=
of_property_read_bool
(
palmas_matches
[
idx
].
of_node
,
"ti,warm-reset"
);
ret
=
of_property_read_u32
(
palmas_matches
[
idx
].
of_node
,
"ti,roof_floor"
,
&
prop
);
if
(
!
ret
)
pdata
->
reg_init
[
idx
]
->
roof_floor
=
prop
;
pdata
->
reg_init
[
idx
]
->
roof_floor
=
of_property_read_bool
(
palmas_matches
[
idx
].
of_node
,
"ti,roof-floor"
);
ret
=
of_property_read_u32
(
palmas_matches
[
idx
].
of_node
,
"ti,mode
_
sleep"
,
&
prop
);
"ti,mode
-
sleep"
,
&
prop
);
if
(
!
ret
)
pdata
->
reg_init
[
idx
]
->
mode_sleep
=
prop
;
ret
=
of_property_read_u32
(
palmas_matches
[
idx
].
of_node
,
"ti,tstep"
,
&
prop
);
if
(
!
ret
)
pdata
->
reg_init
[
idx
]
->
tstep
=
prop
;
ret
=
of_property_read_bool
(
palmas_matches
[
idx
].
of_node
,
"ti,smps-range"
);
if
(
ret
)
pdata
->
reg_init
[
idx
]
->
vsel
=
PALMAS_SMPS12_VOLTAGE_RANGE
;
ret
=
of_property_read_u32
(
palmas_matches
[
idx
].
of_node
,
"ti,vsel"
,
&
prop
);
if
(
!
ret
)
pdata
->
reg_init
[
idx
]
->
vsel
=
prop
;
if
(
idx
==
PALMAS_REG_LDO8
)
pdata
->
enable_ldo8_tracking
=
of_property_read_bool
(
palmas_matches
[
idx
].
of_node
,
"ti,enable-ldo8-tracking"
)
;
}
ret
=
of_property_read_u32
(
node
,
"ti,ldo6_vibrator"
,
&
prop
);
if
(
!
ret
)
pdata
->
ldo6_vibrator
=
prop
;
pdata
->
ldo6_vibrator
=
of_property_read_bool
(
node
,
"ti,ldo6-vibrator"
);
}
static
int
palmas_probe
(
struct
platform_device
*
pdev
)
static
int
palmas_
regulators_
probe
(
struct
platform_device
*
pdev
)
{
struct
palmas
*
palmas
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
palmas_pmic_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
...
...
@@ -630,6 +807,7 @@ static int palmas_probe(struct platform_device *pdev)
config
.
driver_data
=
pmic
;
for
(
id
=
0
;
id
<
PALMAS_REG_LDO1
;
id
++
)
{
bool
ramp_delay_support
=
false
;
/*
* Miss out regulators which are not available due
...
...
@@ -640,19 +818,42 @@ static int palmas_probe(struct platform_device *pdev)
case
PALMAS_REG_SMPS3
:
if
(
pmic
->
smps123
)
continue
;
if
(
id
==
PALMAS_REG_SMPS12
)
ramp_delay_support
=
true
;
break
;
case
PALMAS_REG_SMPS123
:
if
(
!
pmic
->
smps123
)
continue
;
ramp_delay_support
=
true
;
break
;
case
PALMAS_REG_SMPS45
:
case
PALMAS_REG_SMPS7
:
if
(
pmic
->
smps457
)
continue
;
if
(
id
==
PALMAS_REG_SMPS45
)
ramp_delay_support
=
true
;
break
;
case
PALMAS_REG_SMPS457
:
if
(
!
pmic
->
smps457
)
continue
;
ramp_delay_support
=
true
;
break
;
}
if
((
id
==
PALMAS_REG_SMPS6
)
&&
(
id
==
PALMAS_REG_SMPS8
))
ramp_delay_support
=
true
;
if
(
ramp_delay_support
)
{
addr
=
palmas_regs_info
[
id
].
tstep_addr
;
ret
=
palmas_smps_read
(
pmic
->
palmas
,
addr
,
&
reg
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"reading TSTEP reg failed: %d
\n
"
,
ret
);
goto
err_unregister_regulator
;
}
pmic
->
desc
[
id
].
ramp_delay
=
palmas_smps_ramp_delay
[
reg
&
0x3
];
pmic
->
ramp_delay
[
id
]
=
pmic
->
desc
[
id
].
ramp_delay
;
}
/* Initialise sleep/init values from platform data */
...
...
@@ -686,7 +887,8 @@ static int palmas_probe(struct platform_device *pdev)
/*
* Read and store the RANGE bit for later use
* This must be done before regulator is probed,
* otherwise we error in probe with unsupportable ranges.
* otherwise we error in probe with unsupportable
* ranges. Read the current smps mode for later use.
*/
addr
=
palmas_regs_info
[
id
].
vsel_addr
;
...
...
@@ -703,6 +905,14 @@ static int palmas_probe(struct platform_device *pdev)
palmas_regs_info
[
id
].
vsel_addr
);
pmic
->
desc
[
id
].
vsel_mask
=
PALMAS_SMPS12_VOLTAGE_VSEL_MASK
;
/* Read the smps mode for later use. */
addr
=
palmas_regs_info
[
id
].
ctrl_addr
;
ret
=
palmas_smps_read
(
pmic
->
palmas
,
addr
,
&
reg
);
if
(
ret
)
goto
err_unregister_regulator
;
pmic
->
current_reg_mode
[
id
]
=
reg
&
PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK
;
}
pmic
->
desc
[
id
].
type
=
REGULATOR_VOLTAGE
;
...
...
@@ -713,6 +923,7 @@ static int palmas_probe(struct platform_device *pdev)
else
config
.
init_data
=
NULL
;
pmic
->
desc
[
id
].
supply_name
=
palmas_regs_info
[
id
].
sname
;
config
.
of_node
=
palmas_matches
[
id
].
of_node
;
rdev
=
regulator_register
(
&
pmic
->
desc
[
id
],
&
config
);
...
...
@@ -738,27 +949,49 @@ static int palmas_probe(struct platform_device *pdev)
/* Register the regulators */
pmic
->
desc
[
id
].
name
=
palmas_regs_info
[
id
].
name
;
pmic
->
desc
[
id
].
id
=
id
;
pmic
->
desc
[
id
].
n_voltages
=
PALMAS_LDO_NUM_VOLTAGES
;
pmic
->
desc
[
id
].
ops
=
&
palmas_ops_ldo
;
pmic
->
desc
[
id
].
type
=
REGULATOR_VOLTAGE
;
pmic
->
desc
[
id
].
owner
=
THIS_MODULE
;
if
(
id
<
PALMAS_REG_REGEN1
)
{
pmic
->
desc
[
id
].
n_voltages
=
PALMAS_LDO_NUM_VOLTAGES
;
pmic
->
desc
[
id
].
ops
=
&
palmas_ops_ldo
;
pmic
->
desc
[
id
].
min_uV
=
900000
;
pmic
->
desc
[
id
].
uV_step
=
50000
;
pmic
->
desc
[
id
].
linear_min_sel
=
1
;
pmic
->
desc
[
id
].
vsel_reg
=
PALMAS_BASE_TO_REG
(
PALMAS_LDO_BASE
,
pmic
->
desc
[
id
].
vsel_reg
=
PALMAS_BASE_TO_REG
(
PALMAS_LDO_BASE
,
palmas_regs_info
[
id
].
vsel_addr
);
pmic
->
desc
[
id
].
vsel_mask
=
PALMAS_LDO1_VOLTAGE_VSEL_MASK
;
pmic
->
desc
[
id
].
enable_reg
=
PALMAS_BASE_TO_REG
(
PALMAS_LDO_BASE
,
pmic
->
desc
[
id
].
vsel_mask
=
PALMAS_LDO1_VOLTAGE_VSEL_MASK
;
pmic
->
desc
[
id
].
enable_reg
=
PALMAS_BASE_TO_REG
(
PALMAS_LDO_BASE
,
palmas_regs_info
[
id
].
ctrl_addr
);
pmic
->
desc
[
id
].
enable_mask
=
PALMAS_LDO1_CTRL_MODE_ACTIVE
;
pmic
->
desc
[
id
].
enable_mask
=
PALMAS_LDO1_CTRL_MODE_ACTIVE
;
/* Check if LDO8 is in tracking mode or not */
if
(
pdata
&&
(
id
==
PALMAS_REG_LDO8
)
&&
pdata
->
enable_ldo8_tracking
)
{
palmas_enable_ldo8_track
(
palmas
);
pmic
->
desc
[
id
].
min_uV
=
450000
;
pmic
->
desc
[
id
].
uV_step
=
25000
;
}
}
else
{
pmic
->
desc
[
id
].
n_voltages
=
1
;
pmic
->
desc
[
id
].
ops
=
&
palmas_ops_extreg
;
pmic
->
desc
[
id
].
enable_reg
=
PALMAS_BASE_TO_REG
(
PALMAS_RESOURCE_BASE
,
palmas_regs_info
[
id
].
ctrl_addr
);
pmic
->
desc
[
id
].
enable_mask
=
PALMAS_REGEN1_CTRL_MODE_ACTIVE
;
}
if
(
pdata
)
config
.
init_data
=
pdata
->
reg_data
[
id
];
else
config
.
init_data
=
NULL
;
pmic
->
desc
[
id
].
supply_name
=
palmas_regs_info
[
id
].
sname
;
config
.
of_node
=
palmas_matches
[
id
].
of_node
;
rdev
=
regulator_register
(
&
pmic
->
desc
[
id
],
&
config
);
...
...
@@ -777,7 +1010,12 @@ static int palmas_probe(struct platform_device *pdev)
if
(
pdata
)
{
reg_init
=
pdata
->
reg_init
[
id
];
if
(
reg_init
)
{
ret
=
palmas_ldo_init
(
palmas
,
id
,
reg_init
);
if
(
id
<
PALMAS_REG_REGEN1
)
ret
=
palmas_ldo_init
(
palmas
,
id
,
reg_init
);
else
ret
=
palmas_extreg_init
(
palmas
,
id
,
reg_init
);
if
(
ret
)
{
regulator_unregister
(
pmic
->
rdev
[
id
]);
goto
err_unregister_regulator
;
...
...
@@ -786,6 +1024,7 @@ static int palmas_probe(struct platform_device *pdev)
}
}
return
0
;
err_unregister_regulator:
...
...
@@ -794,7 +1033,7 @@ static int palmas_probe(struct platform_device *pdev)
return
ret
;
}
static
int
palmas_remove
(
struct
platform_device
*
pdev
)
static
int
palmas_re
gulators_re
move
(
struct
platform_device
*
pdev
)
{
struct
palmas_pmic
*
pmic
=
platform_get_drvdata
(
pdev
);
int
id
;
...
...
@@ -806,6 +1045,12 @@ static int palmas_remove(struct platform_device *pdev)
static
struct
of_device_id
of_palmas_match_tbl
[]
=
{
{
.
compatible
=
"ti,palmas-pmic"
,
},
{
.
compatible
=
"ti,twl6035-pmic"
,
},
{
.
compatible
=
"ti,twl6036-pmic"
,
},
{
.
compatible
=
"ti,twl6037-pmic"
,
},
{
.
compatible
=
"ti,tps65913-pmic"
,
},
{
.
compatible
=
"ti,tps65914-pmic"
,
},
{
.
compatible
=
"ti,tps80036-pmic"
,
},
{
/* end */
}
};
...
...
@@ -815,8 +1060,8 @@ static struct platform_driver palmas_driver = {
.
of_match_table
=
of_palmas_match_tbl
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
palmas_probe
,
.
remove
=
palmas_remove
,
.
probe
=
palmas_
regulators_
probe
,
.
remove
=
palmas_re
gulators_re
move
,
};
static
int
__init
palmas_init
(
void
)
...
...
include/linux/mfd/palmas.h
View file @
ae5f5203
...
...
@@ -109,19 +109,6 @@ struct palmas_reg_init {
*/
int
mode_sleep
;
/* tstep is the timestep loaded to the TSTEP register
*
* For SMPS
*
* 0: Jump (no slope control)
* 1: 10mV/us
* 2: 5mV/us
* 3: 2.5mV/us
*
* For LDO unused
*/
int
tstep
;
/* voltage_sel is the bitfield loaded onto the SMPSX_VOLTAGE
* register. Set this is the default voltage set in OTP needs
* to be overridden.
...
...
@@ -154,6 +141,12 @@ enum palmas_regulators {
PALMAS_REG_LDO9
,
PALMAS_REG_LDOLN
,
PALMAS_REG_LDOUSB
,
/* External regulators */
PALMAS_REG_REGEN1
,
PALMAS_REG_REGEN2
,
PALMAS_REG_REGEN3
,
PALMAS_REG_SYSEN1
,
PALMAS_REG_SYSEN2
,
/* Total number of regulators */
PALMAS_NUM_REGS
,
};
...
...
@@ -171,6 +164,9 @@ struct palmas_pmic_platform_data {
/* use LDO6 for vibrator control */
int
ldo6_vibrator
;
/* Enable tracking mode of LDO8 */
bool
enable_ldo8_tracking
;
};
struct
palmas_usb_platform_data
{
...
...
@@ -331,6 +327,8 @@ struct palmas_pmic {
int
smps457
;
int
range
[
PALMAS_REG_SMPS10
];
unsigned
int
ramp_delay
[
PALMAS_REG_SMPS10
];
unsigned
int
current_reg_mode
[
PALMAS_REG_SMPS10
];
};
struct
palmas_resource
{
...
...
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