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
178a097d
Commit
178a097d
authored
Feb 19, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/topic/s5m8767' into regulator-next
parents
72808887
e81d7bc8
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
438 additions
and
68 deletions
+438
-68
Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt
...ation/devicetree/bindings/regulator/s5m8767-regulator.txt
+152
-0
drivers/mfd/sec-core.c
drivers/mfd/sec-core.c
+73
-2
drivers/regulator/s5m8767.c
drivers/regulator/s5m8767.c
+206
-62
include/linux/mfd/samsung/core.h
include/linux/mfd/samsung/core.h
+7
-4
No files found.
Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt
0 → 100644
View file @
178a097d
* Samsung S5M8767 Voltage and Current Regulator
The Samsung S5M8767 is a multi-function device which includes volatage and
current regulators, rtc, charger controller and other sub-blocks. It is
interfaced to the host controller using a i2c interface. Each sub-block is
addressed by the host system using different i2c slave address. This document
describes the bindings for 'pmic' sub-block of s5m8767.
Required properties:
- compatible: Should be "samsung,s5m8767-pmic".
- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
- s5m8767,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
units for buck2 when changing voltage using gpio dvs. Refer to [1] below
for additional information.
- s5m8767,pmic-buck3-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
units for buck3 when changing voltage using gpio dvs. Refer to [1] below
for additional information.
- s5m8767,pmic-buck4-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
units for buck4 when changing voltage using gpio dvs. Refer to [1] below
for additional information.
- s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used
for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines.
[1] If none of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional
property is specified, the 's5m8767,pmic-buck[2/3/4]-dvs-voltage'
property should specify atleast one voltage level (which would be a
safe operating voltage).
If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional
property is specified, then all the eight voltage values for the
's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified.
Optional properties:
- interrupt-parent: Specifies the phandle of the interrupt controller to which
the interrupts from s5m8767 are delivered to.
- interrupts: Interrupt specifiers for two interrupt sources.
- First interrupt specifier is for 'irq1' interrupt.
- Second interrupt specifier is for 'alert' interrupt.
- s5m8767,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
- s5m8767,pmic-buck3-uses-gpio-dvs: 'buck3' can be controlled by gpio dvs.
- s5m8767,pmic-buck4-uses-gpio-dvs: 'buck4' can be controlled by gpio dvs.
Additional properties required if either of the optional properties are used:
- s5m8767,pmic-buck234-default-dvs-idx: Default voltage setting selected from
the possible 8 options selectable by the dvs gpios. The value of this
property should be between 0 and 7. If not specified or if out of range, the
default value of this property is set to 0.
- s5m8767,pmic-buck-dvs-gpios: GPIO specifiers for three host gpio's used
for dvs. The format of the gpio specifier depends in the gpio controller.
Regulators: The regulators of s5m8767 that have to be instantiated should be
included in a sub-node named 'regulators'. Regulator nodes included in this
sub-node should be of the format as listed below.
regulator_name {
ldo1_reg: LDO1 {
regulator-name = "VDD_ALIVE_1.0V";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
regulator-boot-on;
op_mode = <1>; /* Normal Mode */
};
};
The above regulator entries are defined in regulator bindings documentation
except op_mode description.
- op_mode: describes the different operating modes of the LDO's with
power mode change in SOC. The different possible values are,
0 - always off mode
1 - on in normal mode
2 - low power mode
3 - suspend mode
The following are the names of the regulators that the s5m8767 pmic block
supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
as per the datasheet of s5m8767.
- LDOn
- valid values for n are 1 to 28
- Example: LDO0, LD01, LDO28
- BUCKn
- valid values for n are 1 to 9.
- Example: BUCK1, BUCK2, BUCK9
The bindings inside the regulator nodes use the standard regulator bindings
which are documented elsewhere.
Example:
s5m8767_pmic@66 {
compatible = "samsung,s5m8767-pmic";
reg = <0x66>;
s5m8767,pmic-buck2-uses-gpio-dvs;
s5m8767,pmic-buck3-uses-gpio-dvs;
s5m8767,pmic-buck4-uses-gpio-dvs;
s5m8767,pmic-buck-default-dvs-idx = <0>;
s5m8767,pmic-buck-dvs-gpios = <&gpx0 0 1 0 0>, /* DVS1 */
<&gpx0 1 1 0 0>, /* DVS2 */
<&gpx0 2 1 0 0>; /* DVS3 */
s5m8767,pmic-buck-ds-gpios = <&gpx2 3 1 0 0>, /* SET1 */
<&gpx2 4 1 0 0>, /* SET2 */
<&gpx2 5 1 0 0>; /* SET3 */
s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>,
<1250000>, <1200000>,
<1150000>, <1100000>,
<1000000>, <950000>;
s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>,
<1100000>, <1100000>,
<1000000>, <1000000>,
<1000000>, <1000000>;
s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>,
<1200000>, <1200000>,
<1200000>, <1200000>,
<1200000>, <1200000>;
regulators {
ldo1_reg: LDO1 {
regulator-name = "VDD_ABB_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
op_mode = <1>; /* Normal Mode */
};
ldo2_reg: LDO2 {
regulator-name = "VDD_ALIVE_1.1V";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "VDD_MIF_1.2V";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
};
};
drivers/mfd/sec-core.c
View file @
178a097d
...
...
@@ -17,6 +17,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include <linux/mutex.h>
...
...
@@ -60,6 +61,15 @@ static struct mfd_cell s2mps11_devs[] = {
},
};
#ifdef CONFIG_OF
static
struct
of_device_id
sec_dt_match
[]
=
{
{
.
compatible
=
"samsung,s5m8767-pmic"
,
.
data
=
(
void
*
)
S5M8767X
,
},
{},
};
#endif
int
sec_reg_read
(
struct
sec_pmic_dev
*
sec_pmic
,
u8
reg
,
void
*
dest
)
{
return
regmap_read
(
sec_pmic
->
regmap
,
reg
,
dest
);
...
...
@@ -95,6 +105,57 @@ static struct regmap_config sec_regmap_config = {
.
val_bits
=
8
,
};
#ifdef CONFIG_OF
/*
* Only the common platform data elements for s5m8767 are parsed here from the
* device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and
* others have to parse their own platform data elements from device tree.
*
* The s5m8767 platform data structure is instantiated here and the drivers for
* the sub-modules need not instantiate another instance while parsing their
* platform data.
*/
static
struct
sec_platform_data
*
sec_pmic_i2c_parse_dt_pdata
(
struct
device
*
dev
)
{
struct
sec_platform_data
*
pd
;
pd
=
devm_kzalloc
(
dev
,
sizeof
(
*
pd
),
GFP_KERNEL
);
if
(
!
pd
)
{
dev_err
(
dev
,
"could not allocate memory for pdata
\n
"
);
return
ERR_PTR
(
-
ENOMEM
);
}
/*
* ToDo: the 'wakeup' member in the platform data is more of a linux
* specfic information. Hence, there is no binding for that yet and
* not parsed here.
*/
return
pd
;
}
#else
static
struct
sec_platform_data
*
sec_pmic_i2c_parse_dt_pdata
(
struct
device
*
dev
)
{
return
0
;
}
#endif
static
inline
int
sec_i2c_get_driver_data
(
struct
i2c_client
*
i2c
,
const
struct
i2c_device_id
*
id
)
{
#ifdef CONFIG_OF
if
(
i2c
->
dev
.
of_node
)
{
const
struct
of_device_id
*
match
;
match
=
of_match_node
(
sec_dt_match
,
i2c
->
dev
.
of_node
);
return
(
int
)
match
->
data
;
}
#endif
return
(
int
)
id
->
driver_data
;
}
static
int
sec_pmic_probe
(
struct
i2c_client
*
i2c
,
const
struct
i2c_device_id
*
id
)
{
...
...
@@ -111,13 +172,22 @@ static int sec_pmic_probe(struct i2c_client *i2c,
sec_pmic
->
dev
=
&
i2c
->
dev
;
sec_pmic
->
i2c
=
i2c
;
sec_pmic
->
irq
=
i2c
->
irq
;
sec_pmic
->
type
=
id
->
driver_data
;
sec_pmic
->
type
=
sec_i2c_get_driver_data
(
i2c
,
id
);
if
(
sec_pmic
->
dev
->
of_node
)
{
pdata
=
sec_pmic_i2c_parse_dt_pdata
(
sec_pmic
->
dev
);
if
(
IS_ERR
(
pdata
))
{
ret
=
PTR_ERR
(
pdata
);
return
ret
;
}
pdata
->
device_type
=
sec_pmic
->
type
;
}
if
(
pdata
)
{
sec_pmic
->
device_type
=
pdata
->
device_type
;
sec_pmic
->
ono
=
pdata
->
ono
;
sec_pmic
->
irq_base
=
pdata
->
irq_base
;
sec_pmic
->
wakeup
=
pdata
->
wakeup
;
sec_pmic
->
pdata
=
pdata
;
}
sec_pmic
->
regmap
=
devm_regmap_init_i2c
(
i2c
,
&
sec_regmap_config
);
...
...
@@ -192,6 +262,7 @@ static struct i2c_driver sec_pmic_driver = {
.
driver
=
{
.
name
=
"sec_pmic"
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
of_match_ptr
(
sec_dt_match
),
},
.
probe
=
sec_pmic_probe
,
.
remove
=
sec_pmic_remove
,
...
...
drivers/regulator/s5m8767.c
View file @
178a097d
...
...
@@ -14,6 +14,7 @@
#include <linux/bug.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
...
...
@@ -21,6 +22,9 @@
#include <linux/regulator/machine.h>
#include <linux/mfd/samsung/core.h>
#include <linux/mfd/samsung/s5m8767.h>
#include <linux/regulator/of_regulator.h>
#define S5M8767_OPMODE_NORMAL_MODE 0x1
struct
s5m8767_info
{
struct
device
*
dev
;
...
...
@@ -255,10 +259,8 @@ static int s5m8767_reg_disable(struct regulator_dev *rdev)
return
sec_reg_update
(
s5m8767
->
iodev
,
reg
,
~
mask
,
mask
);
}
static
int
s5m8767_get_v
oltage_register
(
struct
regulator_dev
*
rdev
,
int
*
_reg
)
static
int
s5m8767_get_v
sel_reg
(
int
reg_id
,
struct
s5m8767_info
*
s5m8767
)
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
int
reg_id
=
rdev_get_id
(
rdev
);
int
reg
;
switch
(
reg_id
)
{
...
...
@@ -296,43 +298,18 @@ static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg)
return
-
EINVAL
;
}
*
_reg
=
reg
;
return
0
;
}
static
int
s5m8767_get_voltage_sel
(
struct
regulator_dev
*
rdev
)
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
int
reg
,
mask
,
ret
;
int
reg_id
=
rdev_get_id
(
rdev
);
unsigned
int
val
;
ret
=
s5m8767_get_voltage_register
(
rdev
,
&
reg
);
if
(
ret
)
return
ret
;
mask
=
(
reg_id
<
S5M8767_BUCK1
)
?
0x3f
:
0xff
;
ret
=
sec_reg_read
(
s5m8767
->
iodev
,
reg
,
&
val
);
if
(
ret
)
return
ret
;
val
&=
mask
;
return
val
;
return
reg
;
}
static
int
s5m8767_convert_voltage_to_sel
(
const
struct
sec_voltage_desc
*
desc
,
int
min_vol
,
int
max_vol
)
static
int
s5m8767_convert_voltage_to_sel
(
const
struct
sec_voltage_desc
*
desc
,
int
min_vol
)
{
int
selector
=
0
;
if
(
desc
==
NULL
)
return
-
EINVAL
;
if
(
m
ax_vol
<
desc
->
min
||
m
in_vol
>
desc
->
max
)
if
(
min_vol
>
desc
->
max
)
return
-
EINVAL
;
if
(
min_vol
<
desc
->
min
)
...
...
@@ -340,7 +317,7 @@ static int s5m8767_convert_voltage_to_sel(
selector
=
DIV_ROUND_UP
(
min_vol
-
desc
->
min
,
desc
->
step
);
if
(
desc
->
min
+
desc
->
step
*
selector
>
max_vol
)
if
(
desc
->
min
+
desc
->
step
*
selector
>
desc
->
max
)
return
-
EINVAL
;
return
selector
;
...
...
@@ -373,15 +350,13 @@ static int s5m8767_set_voltage_sel(struct regulator_dev *rdev,
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
int
reg_id
=
rdev_get_id
(
rdev
);
int
reg
,
mask
,
ret
=
0
,
old_index
,
index
=
0
;
int
old_index
,
index
=
0
;
u8
*
buck234_vol
=
NULL
;
switch
(
reg_id
)
{
case
S5M8767_LDO1
...
S5M8767_LDO28
:
mask
=
0x3f
;
break
;
case
S5M8767_BUCK1
...
S5M8767_BUCK6
:
mask
=
0xff
;
if
(
reg_id
==
S5M8767_BUCK2
&&
s5m8767
->
buck2_gpiodvs
)
buck234_vol
=
&
s5m8767
->
buck2_vol
[
0
];
else
if
(
reg_id
==
S5M8767_BUCK3
&&
s5m8767
->
buck3_gpiodvs
)
...
...
@@ -392,7 +367,6 @@ static int s5m8767_set_voltage_sel(struct regulator_dev *rdev,
case
S5M8767_BUCK7
...
S5M8767_BUCK8
:
return
-
EINVAL
;
case
S5M8767_BUCK9
:
mask
=
0xff
;
break
;
default:
return
-
EINVAL
;
...
...
@@ -412,11 +386,7 @@ static int s5m8767_set_voltage_sel(struct regulator_dev *rdev,
else
return
s5m8767_set_low
(
s5m8767
);
}
else
{
ret
=
s5m8767_get_voltage_register
(
rdev
,
&
reg
);
if
(
ret
)
return
ret
;
return
sec_reg_update
(
s5m8767
->
iodev
,
reg
,
selector
,
mask
);
return
regulator_set_voltage_sel_regmap
(
rdev
,
selector
);
}
}
...
...
@@ -441,7 +411,7 @@ static struct regulator_ops s5m8767_ops = {
.
is_enabled
=
s5m8767_reg_is_enabled
,
.
enable
=
s5m8767_reg_enable
,
.
disable
=
s5m8767_reg_disable
,
.
get_voltage_sel
=
s5m8767_get_voltage_sel
,
.
get_voltage_sel
=
regulator_get_voltage_sel_regmap
,
.
set_voltage_sel
=
s5m8767_set_voltage_sel
,
.
set_voltage_time_sel
=
s5m8767_set_voltage_time_sel
,
};
...
...
@@ -508,10 +478,182 @@ static struct regulator_desc regulators[] = {
s5m8767_regulator_desc
(
BUCK9
),
};
#ifdef CONFIG_OF
static
int
s5m8767_pmic_dt_parse_dvs_gpio
(
struct
sec_pmic_dev
*
iodev
,
struct
sec_platform_data
*
pdata
,
struct
device_node
*
pmic_np
)
{
int
i
,
gpio
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
gpio
=
of_get_named_gpio
(
pmic_np
,
"s5m8767,pmic-buck-dvs-gpios"
,
i
);
if
(
!
gpio_is_valid
(
gpio
))
{
dev_err
(
iodev
->
dev
,
"invalid gpio[%d]: %d
\n
"
,
i
,
gpio
);
return
-
EINVAL
;
}
pdata
->
buck_gpios
[
i
]
=
gpio
;
}
return
0
;
}
static
int
s5m8767_pmic_dt_parse_ds_gpio
(
struct
sec_pmic_dev
*
iodev
,
struct
sec_platform_data
*
pdata
,
struct
device_node
*
pmic_np
)
{
int
i
,
gpio
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
gpio
=
of_get_named_gpio
(
pmic_np
,
"s5m8767,pmic-buck-ds-gpios"
,
i
);
if
(
!
gpio_is_valid
(
gpio
))
{
dev_err
(
iodev
->
dev
,
"invalid gpio[%d]: %d
\n
"
,
i
,
gpio
);
return
-
EINVAL
;
}
pdata
->
buck_ds
[
i
]
=
gpio
;
}
return
0
;
}
static
int
s5m8767_pmic_dt_parse_pdata
(
struct
platform_device
*
pdev
,
struct
sec_platform_data
*
pdata
)
{
struct
sec_pmic_dev
*
iodev
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
device_node
*
pmic_np
,
*
regulators_np
,
*
reg_np
;
struct
sec_regulator_data
*
rdata
;
struct
sec_opmode_data
*
rmode
;
unsigned
int
i
,
dvs_voltage_nr
=
1
,
ret
;
pmic_np
=
iodev
->
dev
->
of_node
;
if
(
!
pmic_np
)
{
dev_err
(
iodev
->
dev
,
"could not find pmic sub-node
\n
"
);
return
-
ENODEV
;
}
regulators_np
=
of_find_node_by_name
(
pmic_np
,
"regulators"
);
if
(
!
regulators_np
)
{
dev_err
(
iodev
->
dev
,
"could not find regulators sub-node
\n
"
);
return
-
EINVAL
;
}
/* count the number of regulators to be supported in pmic */
pdata
->
num_regulators
=
of_get_child_count
(
regulators_np
);
rdata
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
rdata
)
*
pdata
->
num_regulators
,
GFP_KERNEL
);
if
(
!
rdata
)
{
dev_err
(
iodev
->
dev
,
"could not allocate memory for regulator data
\n
"
);
return
-
ENOMEM
;
}
rmode
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
rmode
)
*
pdata
->
num_regulators
,
GFP_KERNEL
);
if
(
!
rdata
)
{
dev_err
(
iodev
->
dev
,
"could not allocate memory for regulator mode
\n
"
);
return
-
ENOMEM
;
}
pdata
->
regulators
=
rdata
;
pdata
->
opmode
=
rmode
;
for_each_child_of_node
(
regulators_np
,
reg_np
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
regulators
);
i
++
)
if
(
!
of_node_cmp
(
reg_np
->
name
,
regulators
[
i
].
name
))
break
;
if
(
i
==
ARRAY_SIZE
(
regulators
))
{
dev_warn
(
iodev
->
dev
,
"don't know how to configure regulator %s
\n
"
,
reg_np
->
name
);
continue
;
}
rdata
->
id
=
i
;
rdata
->
initdata
=
of_get_regulator_init_data
(
&
pdev
->
dev
,
reg_np
);
rdata
->
reg_node
=
reg_np
;
rdata
++
;
rmode
->
id
=
i
;
if
(
of_property_read_u32
(
reg_np
,
"op_mode"
,
&
rmode
->
mode
))
{
dev_warn
(
iodev
->
dev
,
"no op_mode property property at %s
\n
"
,
reg_np
->
full_name
);
rmode
->
mode
=
S5M8767_OPMODE_NORMAL_MODE
;
}
rmode
++
;
}
if
(
of_get_property
(
pmic_np
,
"s5m8767,pmic-buck2-uses-gpio-dvs"
,
NULL
))
pdata
->
buck2_gpiodvs
=
true
;
if
(
of_get_property
(
pmic_np
,
"s5m8767,pmic-buck3-uses-gpio-dvs"
,
NULL
))
pdata
->
buck3_gpiodvs
=
true
;
if
(
of_get_property
(
pmic_np
,
"s5m8767,pmic-buck4-uses-gpio-dvs"
,
NULL
))
pdata
->
buck4_gpiodvs
=
true
;
if
(
pdata
->
buck2_gpiodvs
||
pdata
->
buck3_gpiodvs
||
pdata
->
buck4_gpiodvs
)
{
ret
=
s5m8767_pmic_dt_parse_dvs_gpio
(
iodev
,
pdata
,
pmic_np
);
if
(
ret
)
return
-
EINVAL
;
if
(
of_property_read_u32
(
pmic_np
,
"s5m8767,pmic-buck-default-dvs-idx"
,
&
pdata
->
buck_default_idx
))
{
pdata
->
buck_default_idx
=
0
;
}
else
{
if
(
pdata
->
buck_default_idx
>=
8
)
{
pdata
->
buck_default_idx
=
0
;
dev_info
(
iodev
->
dev
,
"invalid value for default dvs index, use 0
\n
"
);
}
}
dvs_voltage_nr
=
8
;
}
ret
=
s5m8767_pmic_dt_parse_ds_gpio
(
iodev
,
pdata
,
pmic_np
);
if
(
ret
)
return
-
EINVAL
;
if
(
of_property_read_u32_array
(
pmic_np
,
"s5m8767,pmic-buck2-dvs-voltage"
,
pdata
->
buck2_voltage
,
dvs_voltage_nr
))
{
dev_err
(
iodev
->
dev
,
"buck2 voltages not specified
\n
"
);
return
-
EINVAL
;
}
if
(
of_property_read_u32_array
(
pmic_np
,
"s5m8767,pmic-buck3-dvs-voltage"
,
pdata
->
buck3_voltage
,
dvs_voltage_nr
))
{
dev_err
(
iodev
->
dev
,
"buck3 voltages not specified
\n
"
);
return
-
EINVAL
;
}
if
(
of_property_read_u32_array
(
pmic_np
,
"s5m8767,pmic-buck4-dvs-voltage"
,
pdata
->
buck4_voltage
,
dvs_voltage_nr
))
{
dev_err
(
iodev
->
dev
,
"buck4 voltages not specified
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
#else
static
int
s5m8767_pmic_dt_parse_pdata
(
struct
platform_device
*
pdev
,
struct
sec_platform_data
*
pdata
)
{
return
0
;
}
#endif
/* CONFIG_OF */
static
int
s5m8767_pmic_probe
(
struct
platform_device
*
pdev
)
{
struct
sec_pmic_dev
*
iodev
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
sec_platform_data
*
pdata
=
dev_get_platdata
(
iodev
->
dev
)
;
struct
sec_platform_data
*
pdata
=
iodev
->
pdata
;
struct
regulator_config
config
=
{
};
struct
regulator_dev
**
rdev
;
struct
s5m8767_info
*
s5m8767
;
...
...
@@ -522,6 +664,12 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
return
-
ENODEV
;
}
if
(
iodev
->
dev
->
of_node
)
{
ret
=
s5m8767_pmic_dt_parse_pdata
(
pdev
,
pdata
);
if
(
ret
)
return
ret
;
}
if
(
pdata
->
buck2_gpiodvs
)
{
if
(
pdata
->
buck3_gpiodvs
||
pdata
->
buck4_gpiodvs
)
{
dev_err
(
&
pdev
->
dev
,
"S5M8767 GPIO DVS NOT VALID
\n
"
);
...
...
@@ -577,23 +725,17 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
s5m8767
->
opmode
=
pdata
->
opmode
;
buck_init
=
s5m8767_convert_voltage_to_sel
(
&
buck_voltage_val2
,
pdata
->
buck2_init
,
pdata
->
buck2_init
+
buck_voltage_val2
.
step
);
pdata
->
buck2_init
);
sec_reg_write
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK2DVS2
,
buck_init
);
buck_init
=
s5m8767_convert_voltage_to_sel
(
&
buck_voltage_val2
,
pdata
->
buck3_init
,
pdata
->
buck3_init
+
buck_voltage_val2
.
step
);
pdata
->
buck3_init
);
sec_reg_write
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK3DVS2
,
buck_init
);
buck_init
=
s5m8767_convert_voltage_to_sel
(
&
buck_voltage_val2
,
pdata
->
buck4_init
,
pdata
->
buck4_init
+
buck_voltage_val2
.
step
);
pdata
->
buck4_init
);
sec_reg_write
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK4DVS2
,
buck_init
);
...
...
@@ -602,27 +744,21 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
s5m8767
->
buck2_vol
[
i
]
=
s5m8767_convert_voltage_to_sel
(
&
buck_voltage_val2
,
pdata
->
buck2_voltage
[
i
],
pdata
->
buck2_voltage
[
i
]
+
buck_voltage_val2
.
step
);
pdata
->
buck2_voltage
[
i
]);
}
if
(
s5m8767
->
buck3_gpiodvs
)
{
s5m8767
->
buck3_vol
[
i
]
=
s5m8767_convert_voltage_to_sel
(
&
buck_voltage_val2
,
pdata
->
buck3_voltage
[
i
],
pdata
->
buck3_voltage
[
i
]
+
buck_voltage_val2
.
step
);
pdata
->
buck3_voltage
[
i
]);
}
if
(
s5m8767
->
buck4_gpiodvs
)
{
s5m8767
->
buck4_vol
[
i
]
=
s5m8767_convert_voltage_to_sel
(
&
buck_voltage_val2
,
pdata
->
buck4_voltage
[
i
],
pdata
->
buck4_voltage
[
i
]
+
buck_voltage_val2
.
step
);
pdata
->
buck4_voltage
[
i
]);
}
}
...
...
@@ -760,11 +896,19 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
(
desc
->
max
-
desc
->
min
)
/
desc
->
step
+
1
;
regulators
[
id
].
min_uV
=
desc
->
min
;
regulators
[
id
].
uV_step
=
desc
->
step
;
regulators
[
id
].
vsel_reg
=
s5m8767_get_vsel_reg
(
id
,
s5m8767
);
if
(
id
<
S5M8767_BUCK1
)
regulators
[
id
].
vsel_mask
=
0x3f
;
else
regulators
[
id
].
vsel_mask
=
0xff
;
}
config
.
dev
=
s5m8767
->
dev
;
config
.
init_data
=
pdata
->
regulators
[
i
].
initdata
;
config
.
driver_data
=
s5m8767
;
config
.
regmap
=
iodev
->
regmap
;
config
.
of_node
=
pdata
->
regulators
[
i
].
reg_node
;
rdev
[
i
]
=
regulator_register
(
&
regulators
[
id
],
&
config
);
if
(
IS_ERR
(
rdev
[
i
]))
{
...
...
include/linux/mfd/samsung/core.h
View file @
178a097d
...
...
@@ -26,6 +26,7 @@ enum sec_device_type {
/**
* struct sec_pmic_dev - s5m87xx master device for sub-drivers
* @dev: master device of the chip (can be used to access platform data)
* @pdata: pointer to private data used to pass platform data to child
* @i2c: i2c client private data for regulator
* @rtc: i2c client private data for rtc
* @iolock: mutex for serializing io access
...
...
@@ -39,6 +40,7 @@ enum sec_device_type {
*/
struct
sec_pmic_dev
{
struct
device
*
dev
;
struct
sec_platform_data
*
pdata
;
struct
regmap
*
regmap
;
struct
i2c_client
*
i2c
;
struct
i2c_client
*
rtc
;
...
...
@@ -82,11 +84,11 @@ struct sec_platform_data {
int
buck_gpios
[
3
];
int
buck_ds
[
3
];
int
buck2_voltage
[
8
];
unsigned
int
buck2_voltage
[
8
];
bool
buck2_gpiodvs
;
int
buck3_voltage
[
8
];
unsigned
int
buck3_voltage
[
8
];
bool
buck3_gpiodvs
;
int
buck4_voltage
[
8
];
unsigned
int
buck4_voltage
[
8
];
bool
buck4_gpiodvs
;
int
buck_set1
;
...
...
@@ -127,6 +129,7 @@ struct sec_platform_data {
struct
sec_regulator_data
{
int
id
;
struct
regulator_init_data
*
initdata
;
struct
device_node
*
reg_node
;
};
/*
...
...
@@ -136,7 +139,7 @@ struct sec_regulator_data {
*/
struct
sec_opmode_data
{
int
id
;
int
mode
;
unsigned
int
mode
;
};
/*
...
...
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