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
c99f21c2
Commit
c99f21c2
authored
Feb 19, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/topic/mc13892' into regulator-next
parents
e11c4515
2c8a5dca
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
103 additions
and
22 deletions
+103
-22
drivers/regulator/mc13892-regulator.c
drivers/regulator/mc13892-regulator.c
+93
-18
drivers/regulator/mc13xxx-regulator-core.c
drivers/regulator/mc13xxx-regulator-core.c
+8
-2
drivers/regulator/mc13xxx.h
drivers/regulator/mc13xxx.h
+2
-2
No files found.
drivers/regulator/mc13892-regulator.c
View file @
c99f21c2
...
...
@@ -164,6 +164,14 @@ static const unsigned int mc13892_sw1[] = {
1350000
,
1375000
};
/*
* Note: this table is used to derive SWxVSEL by index into
* the array. Offset the values by the index of 1100000uV
* to get the actual register value for that voltage selector
* if the HI bit is to be set as well.
*/
#define MC13892_SWxHI_SEL_OFFSET 20
static
const
unsigned
int
mc13892_sw
[]
=
{
600000
,
625000
,
650000
,
675000
,
700000
,
725000
,
750000
,
775000
,
800000
,
825000
,
850000
,
875000
,
...
...
@@ -239,7 +247,6 @@ static const unsigned int mc13892_pwgtdrv[] = {
};
static
struct
regulator_ops
mc13892_gpo_regulator_ops
;
/* sw regulators need special care due to the "hi bit" */
static
struct
regulator_ops
mc13892_sw_regulator_ops
;
...
...
@@ -396,7 +403,7 @@ static int mc13892_sw_regulator_get_voltage_sel(struct regulator_dev *rdev)
{
struct
mc13xxx_regulator_priv
*
priv
=
rdev_get_drvdata
(
rdev
);
int
ret
,
id
=
rdev_get_id
(
rdev
);
unsigned
int
val
;
unsigned
int
val
,
selector
;
dev_dbg
(
rdev_get_dev
(
rdev
),
"%s id: %d
\n
"
,
__func__
,
id
);
...
...
@@ -407,12 +414,28 @@ static int mc13892_sw_regulator_get_voltage_sel(struct regulator_dev *rdev)
if
(
ret
)
return
ret
;
val
=
(
val
&
mc13892_regulators
[
id
].
vsel_mask
)
>>
mc13892_regulators
[
id
].
vsel_shift
;
/*
* Figure out if the HI bit is set inside the switcher mode register
* since this means the selector value we return is at a different
* offset into the selector table.
*
* According to the MC13892 documentation note 59 (Table 47) the SW1
* buck switcher does not support output range programming therefore
* the HI bit must always remain 0. So do not do anything strange if
* our register is MC13892_SWITCHERS0.
*/
selector
=
val
&
mc13892_regulators
[
id
].
vsel_mask
;
if
((
mc13892_regulators
[
id
].
vsel_reg
!=
MC13892_SWITCHERS0
)
&&
(
val
&
MC13892_SWITCHERS0_SWxHI
))
{
selector
+=
MC13892_SWxHI_SEL_OFFSET
;
}
dev_dbg
(
rdev_get_dev
(
rdev
),
"%s id: %d val: %d
\n
"
,
__func__
,
id
,
val
);
dev_dbg
(
rdev_get_dev
(
rdev
),
"%s id: %d val: 0x%08x selector: %d
\n
"
,
__func__
,
id
,
val
,
selector
);
return
val
;
return
selector
;
}
static
int
mc13892_sw_regulator_set_voltage_sel
(
struct
regulator_dev
*
rdev
,
...
...
@@ -425,18 +448,35 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev,
volt
=
rdev
->
desc
->
volt_table
[
selector
];
mask
=
mc13892_regulators
[
id
].
vsel_mask
;
reg_value
=
selector
<<
mc13892_regulators
[
id
].
vsel_shift
;
if
(
volt
>
1375000
)
{
mask
|=
MC13892_SWITCHERS0_SWxHI
;
reg_value
|=
MC13892_SWITCHERS0_SWxHI
;
}
else
if
(
volt
<
1100000
)
{
mask
|=
MC13892_SWITCHERS0_SWxHI
;
reg_value
&=
~
MC13892_SWITCHERS0_SWxHI
;
reg_value
=
selector
;
/*
* Don't mess with the HI bit or support HI voltage offsets for SW1.
*
* Since the get_voltage_sel callback has given a fudged value for
* the selector offset, we need to back out that offset if HI is
* to be set so we write the correct value to the register.
*
* The HI bit addition and selector offset handling COULD be more
* complicated by shifting and masking off the voltage selector part
* of the register then logical OR it back in, but since the selector
* is at bits 4:0 there is very little point. This makes the whole
* thing more readable and we do far less work.
*/
if
(
mc13892_regulators
[
id
].
vsel_reg
!=
MC13892_SWITCHERS0
)
{
if
(
volt
>
1375000
)
{
reg_value
-=
MC13892_SWxHI_SEL_OFFSET
;
reg_value
|=
MC13892_SWITCHERS0_SWxHI
;
mask
|=
MC13892_SWITCHERS0_SWxHI
;
}
else
if
(
volt
<
1100000
)
{
reg_value
&=
~
MC13892_SWITCHERS0_SWxHI
;
mask
|=
MC13892_SWITCHERS0_SWxHI
;
}
}
mc13xxx_lock
(
priv
->
mc13xxx
);
ret
=
mc13xxx_reg_rmw
(
priv
->
mc13xxx
,
mc13892_regulators
[
id
].
reg
,
mask
,
ret
=
mc13xxx_reg_rmw
(
priv
->
mc13xxx
,
mc13892_regulators
[
id
].
vsel_
reg
,
mask
,
reg_value
);
mc13xxx_unlock
(
priv
->
mc13xxx
);
...
...
@@ -495,15 +535,18 @@ static int mc13892_regulator_probe(struct platform_device *pdev)
struct
mc13xxx_regulator_init_data
*
mc13xxx_data
;
struct
regulator_config
config
=
{
};
int
i
,
ret
;
int
num_regulators
=
0
;
int
num_regulators
=
0
,
num_parsed
;
u32
val
;
num_regulators
=
mc13xxx_get_num_regulators_dt
(
pdev
);
if
(
num_regulators
<=
0
&&
pdata
)
num_regulators
=
pdata
->
num_regulators
;
if
(
num_regulators
<=
0
)
return
-
EINVAL
;
num_parsed
=
num_regulators
;
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
priv
)
+
num_regulators
*
sizeof
(
priv
->
regulators
[
0
]),
GFP_KERNEL
);
...
...
@@ -520,7 +563,7 @@ static int mc13892_regulator_probe(struct platform_device *pdev)
if
(
ret
)
goto
err_unlock
;
/* enable switch auto mode */
/* enable switch auto mode
(on 2.0A silicon only)
*/
if
((
val
&
0x0000FFFF
)
==
0x45d0
)
{
ret
=
mc13xxx_reg_rmw
(
mc13892
,
MC13892_SWITCHERS4
,
MC13892_SWITCHERS4_SW1MODE_M
|
...
...
@@ -546,7 +589,39 @@ static int mc13892_regulator_probe(struct platform_device *pdev)
=
mc13892_vcam_get_mode
;
mc13xxx_data
=
mc13xxx_parse_regulators_dt
(
pdev
,
mc13892_regulators
,
ARRAY_SIZE
(
mc13892_regulators
));
ARRAY_SIZE
(
mc13892_regulators
),
&
num_parsed
);
/*
* Perform a little sanity check on the regulator tree - if we found
* a number of regulators from mc13xxx_get_num_regulators_dt and
* then parsed a smaller number in mc13xxx_parse_regulators_dt then
* there is a regulator defined in the regulators node which has
* not matched any usable regulator in the driver. In this case,
* there is one missing and what will happen is the first regulator
* will get registered again.
*
* Fix this by basically making our number of registerable regulators
* equal to the number of regulators we parsed. We are allocating
* too much memory for priv, but this is unavoidable at this point.
*
* As an example of how this can happen, try making a typo in your
* regulators node (vviohi {} instead of viohi {}) so that the name
* does not match..
*
* The check will basically pass for platform data (non-DT) because
* mc13xxx_parse_regulators_dt for !CONFIG_OF will not touch num_parsed.
*
*/
if
(
num_parsed
!=
num_regulators
)
{
dev_warn
(
&
pdev
->
dev
,
"parsed %d != regulators %d - check your device tree!
\n
"
,
num_parsed
,
num_regulators
);
num_regulators
=
num_parsed
;
priv
->
num_regulators
=
num_regulators
;
}
for
(
i
=
0
;
i
<
num_regulators
;
i
++
)
{
struct
regulator_init_data
*
init_data
;
struct
regulator_desc
*
desc
;
...
...
drivers/regulator/mc13xxx-regulator-core.c
View file @
c99f21c2
...
...
@@ -181,12 +181,14 @@ EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt);
struct
mc13xxx_regulator_init_data
*
mc13xxx_parse_regulators_dt
(
struct
platform_device
*
pdev
,
struct
mc13xxx_regulator
*
regulators
,
int
num_regulators
)
int
num_regulators
,
int
*
num_parsed
)
{
struct
mc13xxx_regulator_priv
*
priv
=
platform_get_drvdata
(
pdev
);
struct
mc13xxx_regulator_init_data
*
data
,
*
p
;
struct
device_node
*
parent
,
*
child
;
int
i
;
int
i
,
parsed
=
0
;
*
num_parsed
=
0
;
of_node_get
(
pdev
->
dev
.
parent
->
of_node
);
parent
=
of_find_node_by_name
(
pdev
->
dev
.
parent
->
of_node
,
"regulators"
);
...
...
@@ -203,16 +205,20 @@ struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
for
(
i
=
0
;
i
<
num_regulators
;
i
++
)
{
if
(
!
of_node_cmp
(
child
->
name
,
regulators
[
i
].
desc
.
name
))
{
p
->
id
=
i
;
p
->
init_data
=
of_get_regulator_init_data
(
&
pdev
->
dev
,
child
);
p
->
node
=
child
;
p
++
;
parsed
++
;
break
;
}
}
}
*
num_parsed
=
parsed
;
return
data
;
}
EXPORT_SYMBOL_GPL
(
mc13xxx_parse_regulators_dt
);
...
...
drivers/regulator/mc13xxx.h
View file @
c99f21c2
...
...
@@ -39,7 +39,7 @@ extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
extern
int
mc13xxx_get_num_regulators_dt
(
struct
platform_device
*
pdev
);
extern
struct
mc13xxx_regulator_init_data
*
mc13xxx_parse_regulators_dt
(
struct
platform_device
*
pdev
,
struct
mc13xxx_regulator
*
regulators
,
int
num_regulators
);
int
num_regulators
,
int
*
num_parsed
);
#else
static
inline
int
mc13xxx_get_num_regulators_dt
(
struct
platform_device
*
pdev
)
{
...
...
@@ -48,7 +48,7 @@ static inline int mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
static
inline
struct
mc13xxx_regulator_init_data
*
mc13xxx_parse_regulators_dt
(
struct
platform_device
*
pdev
,
struct
mc13xxx_regulator
*
regulators
,
int
num_regulators
)
int
num_regulators
,
int
*
num_parsed
)
{
return
NULL
;
}
...
...
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