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
9e63d230
Commit
9e63d230
authored
Apr 28, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/topic/ab3100' into v3.9-rc8
parents
78da0218
018fd856
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
187 additions
and
50 deletions
+187
-50
drivers/mfd/ab3100-core.c
drivers/mfd/ab3100-core.c
+1
-0
drivers/regulator/ab3100.c
drivers/regulator/ab3100.c
+186
-50
No files found.
drivers/mfd/ab3100-core.c
View file @
9e63d230
...
...
@@ -753,6 +753,7 @@ static struct mfd_cell ab3100_devs[] = {
},
{
.
name
=
"ab3100-regulators"
,
.
of_compatible
=
"stericsson,ab3100-regulators"
,
.
id
=
-
1
,
},
{
...
...
drivers/regulator/ab3100.c
View file @
9e63d230
...
...
@@ -17,6 +17,8 @@
#include <linux/regulator/driver.h>
#include <linux/mfd/ab3100.h>
#include <linux/mfd/abx500.h>
#include <linux/of.h>
#include <linux/regulator/of_regulator.h>
/* LDO registers and some handy masking definitions for AB3100 */
#define AB3100_LDO_A 0x40
...
...
@@ -345,7 +347,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
{
struct
ab3100_regulator
*
abreg
=
rdev_get_drvdata
(
reg
);
return
abreg
->
plfdata
->
external_voltage
;
if
(
abreg
->
plfdata
)
return
abreg
->
plfdata
->
external_voltage
;
else
/* TODO: encode external voltage into device tree */
return
0
;
}
static
struct
regulator_ops
regulator_ops_fixed
=
{
...
...
@@ -488,16 +494,174 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
},
};
static
int
ab3100_regulator_register
(
struct
platform_device
*
pdev
,
struct
ab3100_platform_data
*
plfdata
,
struct
regulator_init_data
*
init_data
,
struct
device_node
*
np
,
int
id
)
{
struct
regulator_desc
*
desc
;
struct
ab3100_regulator
*
reg
;
struct
regulator_dev
*
rdev
;
struct
regulator_config
config
=
{
};
int
err
,
i
;
for
(
i
=
0
;
i
<
AB3100_NUM_REGULATORS
;
i
++
)
{
desc
=
&
ab3100_regulator_desc
[
i
];
if
(
desc
->
id
==
id
)
break
;
}
if
(
desc
->
id
!=
id
)
return
-
ENODEV
;
/* Same index used for this array */
reg
=
&
ab3100_regulators
[
i
];
/*
* Initialize per-regulator struct.
* Inherit platform data, this comes down from the
* i2c boarddata, from the machine. So if you want to
* see what it looks like for a certain machine, go
* into the machine I2C setup.
*/
reg
->
dev
=
&
pdev
->
dev
;
if
(
plfdata
)
{
reg
->
plfdata
=
plfdata
;
config
.
init_data
=
&
plfdata
->
reg_constraints
[
i
];
}
else
if
(
np
)
{
config
.
of_node
=
np
;
config
.
init_data
=
init_data
;
}
config
.
dev
=
&
pdev
->
dev
;
config
.
driver_data
=
reg
;
rdev
=
regulator_register
(
desc
,
&
config
);
if
(
IS_ERR
(
rdev
))
{
err
=
PTR_ERR
(
rdev
);
dev_err
(
&
pdev
->
dev
,
"%s: failed to register regulator %s err %d
\n
"
,
__func__
,
desc
->
name
,
err
);
return
err
;
}
/* Then set a pointer back to the registered regulator */
reg
->
rdev
=
rdev
;
return
0
;
}
static
struct
of_regulator_match
ab3100_regulator_matches
[]
=
{
{
.
name
=
"ab3100_ldo_a"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_A
,
},
{
.
name
=
"ab3100_ldo_c"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_C
,
},
{
.
name
=
"ab3100_ldo_d"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_D
,
},
{
.
name
=
"ab3100_ldo_e"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_E
,
},
{
.
name
=
"ab3100_ldo_f"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_F
},
{
.
name
=
"ab3100_ldo_g"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_G
},
{
.
name
=
"ab3100_ldo_h"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_H
},
{
.
name
=
"ab3100_ldo_k"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_K
},
{
.
name
=
"ab3100_ext"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_EXT
},
{
.
name
=
"ab3100_buck"
,
.
driver_data
=
(
void
*
)
AB3100_BUCK
},
};
/*
* NOTE: the following functions are regulators pluralis - it is the
* binding to the AB3100 core driver and the parent platform device
* for all the different regulators.
* Initial settings of ab3100 registers.
* Common for below LDO regulator settings are that
* bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0).
* Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode.
*/
/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */
#define LDO_A_SETTING 0x16
/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */
#define LDO_C_SETTING 0x10
/* LDO_D 0x10: 2.65V, ON, sleep mode not used */
#define LDO_D_SETTING 0x10
/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */
#define LDO_E_SETTING 0x10
/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */
#define LDO_E_SLEEP_SETTING 0x00
/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */
#define LDO_F_SETTING 0xD0
/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */
#define LDO_G_SETTING 0x00
/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */
#define LDO_H_SETTING 0x18
/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */
#define LDO_K_SETTING 0x00
/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */
#define LDO_EXT_SETTING 0x00
/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */
#define BUCK_SETTING 0x7D
/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */
#define BUCK_SLEEP_SETTING 0xAC
static
const
u8
ab3100_reg_initvals
[]
=
{
LDO_A_SETTING
,
LDO_C_SETTING
,
LDO_E_SETTING
,
LDO_E_SLEEP_SETTING
,
LDO_F_SETTING
,
LDO_G_SETTING
,
LDO_H_SETTING
,
LDO_K_SETTING
,
LDO_EXT_SETTING
,
BUCK_SETTING
,
BUCK_SLEEP_SETTING
,
LDO_D_SETTING
,
};
static
int
ab3100_regulators_remove
(
struct
platform_device
*
pdev
)
{
int
i
;
for
(
i
=
0
;
i
<
AB3100_NUM_REGULATORS
;
i
++
)
{
struct
ab3100_regulator
*
reg
=
&
ab3100_regulators
[
i
];
regulator_unregister
(
reg
->
rdev
);
reg
->
rdev
=
NULL
;
}
return
0
;
}
static
int
ab3100_regulator_of_probe
(
struct
platform_device
*
pdev
,
struct
device_node
*
np
)
{
int
err
,
i
;
/*
* Set up the regulator registers, as was previously done with
* platform data.
*/
/* Set up regulators */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ab3100_reg_init_order
);
i
++
)
{
err
=
abx500_set_register_interruptible
(
&
pdev
->
dev
,
0
,
ab3100_reg_init_order
[
i
],
ab3100_reg_initvals
[
i
]);
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"regulator initialization failed with error %d
\n
"
,
err
);
return
err
;
}
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ab3100_regulator_matches
);
i
++
)
{
err
=
ab3100_regulator_register
(
pdev
,
NULL
,
ab3100_regulator_matches
[
i
].
init_data
,
ab3100_regulator_matches
[
i
].
of_node
,
(
int
)
ab3100_regulator_matches
[
i
].
driver_data
);
if
(
err
)
{
ab3100_regulators_remove
(
pdev
);
return
err
;
}
}
return
0
;
}
static
int
ab3100_regulators_probe
(
struct
platform_device
*
pdev
)
{
struct
ab3100_platform_data
*
plfdata
=
pdev
->
dev
.
platform_data
;
struct
regulator_config
config
=
{
}
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
int
err
=
0
;
u8
data
;
int
i
;
...
...
@@ -516,6 +680,18 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
dev_notice
(
&
pdev
->
dev
,
"chip is in inactive mode (Cold start)
\n
"
);
if
(
np
)
{
err
=
of_regulator_match
(
&
pdev
->
dev
,
np
,
ab3100_regulator_matches
,
ARRAY_SIZE
(
ab3100_regulator_matches
));
if
(
err
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Error parsing regulator init data: %d
\n
"
,
err
);
return
err
;
}
return
ab3100_regulator_of_probe
(
pdev
,
np
);
}
/* Set up regulators */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ab3100_reg_init_order
);
i
++
)
{
err
=
abx500_set_register_interruptible
(
&
pdev
->
dev
,
0
,
...
...
@@ -530,59 +706,19 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
/* Register the regulators */
for
(
i
=
0
;
i
<
AB3100_NUM_REGULATORS
;
i
++
)
{
struct
ab3100_regulator
*
reg
=
&
ab3100_regulators
[
i
];
struct
regulator_dev
*
rdev
;
/*
* Initialize per-regulator struct.
* Inherit platform data, this comes down from the
* i2c boarddata, from the machine. So if you want to
* see what it looks like for a certain machine, go
* into the machine I2C setup.
*/
reg
->
dev
=
&
pdev
->
dev
;
reg
->
plfdata
=
plfdata
;
struct
regulator_desc
*
desc
=
&
ab3100_regulator_desc
[
i
];
config
.
dev
=
&
pdev
->
dev
;
config
.
driver_data
=
reg
;
config
.
init_data
=
&
plfdata
->
reg_constraints
[
i
];
/*
* Register the regulator, pass around
* the ab3100_regulator struct
*/
rdev
=
regulator_register
(
&
ab3100_regulator_desc
[
i
],
&
config
);
if
(
IS_ERR
(
rdev
))
{
err
=
PTR_ERR
(
rdev
);
dev_err
(
&
pdev
->
dev
,
"%s: failed to register regulator %s err %d
\n
"
,
__func__
,
ab3100_regulator_desc
[
i
].
name
,
err
);
/* remove the already registered regulators */
while
(
--
i
>=
0
)
regulator_unregister
(
ab3100_regulators
[
i
].
rdev
);
err
=
ab3100_regulator_register
(
pdev
,
plfdata
,
NULL
,
NULL
,
desc
->
id
);
if
(
err
)
{
ab3100_regulators_remove
(
pdev
);
return
err
;
}
/* Then set a pointer back to the registered regulator */
reg
->
rdev
=
rdev
;
}
return
0
;
}
static
int
ab3100_regulators_remove
(
struct
platform_device
*
pdev
)
{
int
i
;
for
(
i
=
0
;
i
<
AB3100_NUM_REGULATORS
;
i
++
)
{
struct
ab3100_regulator
*
reg
=
&
ab3100_regulators
[
i
];
regulator_unregister
(
reg
->
rdev
);
}
return
0
;
}
static
struct
platform_driver
ab3100_regulators_driver
=
{
.
driver
=
{
.
name
=
"ab3100-regulators"
,
...
...
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