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
63236f40
Commit
63236f40
authored
Mar 18, 2012
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/topic/drivers' into regulator-next
parents
16fbcc3b
ca61a7bf
Changes
35
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
3035 additions
and
894 deletions
+3035
-894
drivers/regulator/Kconfig
drivers/regulator/Kconfig
+169
-130
drivers/regulator/Makefile
drivers/regulator/Makefile
+25
-19
drivers/regulator/aat2870-regulator.c
drivers/regulator/aat2870-regulator.c
+7
-7
drivers/regulator/ab8500.c
drivers/regulator/ab8500.c
+4
-6
drivers/regulator/ad5398.c
drivers/regulator/ad5398.c
+2
-2
drivers/regulator/anatop-regulator.c
drivers/regulator/anatop-regulator.c
+241
-0
drivers/regulator/da903x.c
drivers/regulator/da903x.c
+6
-6
drivers/regulator/db8500-prcmu.c
drivers/regulator/db8500-prcmu.c
+32
-86
drivers/regulator/dbx500-prcmu.c
drivers/regulator/dbx500-prcmu.c
+241
-0
drivers/regulator/dbx500-prcmu.h
drivers/regulator/dbx500-prcmu.h
+63
-0
drivers/regulator/fixed.c
drivers/regulator/fixed.c
+3
-1
drivers/regulator/isl6271a-regulator.c
drivers/regulator/isl6271a-regulator.c
+3
-11
drivers/regulator/max1586.c
drivers/regulator/max1586.c
+2
-2
drivers/regulator/max8649.c
drivers/regulator/max8649.c
+2
-3
drivers/regulator/max8660.c
drivers/regulator/max8660.c
+9
-7
drivers/regulator/max8925-regulator.c
drivers/regulator/max8925-regulator.c
+2
-2
drivers/regulator/max8997.c
drivers/regulator/max8997.c
+16
-21
drivers/regulator/max8998.c
drivers/regulator/max8998.c
+5
-11
drivers/regulator/mc13783-regulator.c
drivers/regulator/mc13783-regulator.c
+3
-0
drivers/regulator/mc13xxx-regulator-core.c
drivers/regulator/mc13xxx-regulator-core.c
+2
-0
drivers/regulator/pcf50633-regulator.c
drivers/regulator/pcf50633-regulator.c
+13
-14
drivers/regulator/s5m8767.c
drivers/regulator/s5m8767.c
+790
-0
drivers/regulator/tps62360-regulator.c
drivers/regulator/tps62360-regulator.c
+472
-0
drivers/regulator/tps65023-regulator.c
drivers/regulator/tps65023-regulator.c
+0
-4
drivers/regulator/tps6507x-regulator.c
drivers/regulator/tps6507x-regulator.c
+64
-219
drivers/regulator/tps65217-regulator.c
drivers/regulator/tps65217-regulator.c
+378
-0
drivers/regulator/tps6524x-regulator.c
drivers/regulator/tps6524x-regulator.c
+1
-3
drivers/regulator/tps6586x-regulator.c
drivers/regulator/tps6586x-regulator.c
+1
-1
drivers/regulator/tps65910-regulator.c
drivers/regulator/tps65910-regulator.c
+344
-54
drivers/regulator/tps65912-regulator.c
drivers/regulator/tps65912-regulator.c
+64
-276
drivers/regulator/wm8350-regulator.c
drivers/regulator/wm8350-regulator.c
+3
-3
drivers/regulator/wm8400-regulator.c
drivers/regulator/wm8400-regulator.c
+3
-3
drivers/regulator/wm8994-regulator.c
drivers/regulator/wm8994-regulator.c
+1
-3
include/linux/mfd/tps65910.h
include/linux/mfd/tps65910.h
+7
-0
include/linux/regulator/tps62360.h
include/linux/regulator/tps62360.h
+57
-0
No files found.
drivers/regulator/Kconfig
View file @
63236f40
...
...
@@ -74,13 +74,72 @@ config REGULATOR_GPIO
and the platform has to provide a mapping of GPIO-states
to target volts/amps.
config REGULATOR_BQ24022
tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
config REGULATOR_AD5398
tristate "Analog Devices AD5398/AD5821 regulators"
depends on I2C
help
This driver controls a TI bq24022 Charger attached via
GPIOs. The provided current regulator can enable/disable
charging select between 100 mA and 500 mA charging current
limit.
This driver supports AD5398 and AD5821 current regulator chips.
If building into module, its name is ad5398.ko.
config REGULATOR_AAT2870
tristate "AnalogicTech AAT2870 Regulators"
depends on MFD_AAT2870_CORE
help
If you have a AnalogicTech AAT2870 say Y to enable the
regulator driver.
config REGULATOR_DA903X
tristate "Dialog Semiconductor DA9030/DA9034 regulators"
depends on PMIC_DA903X
help
Say y here to support the BUCKs and LDOs regulators found on
Dialog Semiconductor DA9030/DA9034 PMIC.
config REGULATOR_DA9052
tristate "Dialog Semiconductor DA9052/DA9053 regulators"
depends on PMIC_DA9052
help
This driver supports the voltage regulators of DA9052-BC and
DA9053-AA/Bx PMIC.
config REGULATOR_ANATOP
tristate "Freescale i.MX on-chip ANATOP LDO regulators"
depends on MFD_ANATOP
help
Say y here to support Freescale i.MX on-chip ANATOP LDOs
regulators. It is recommended that this option be
enabled on i.MX6 platform.
config REGULATOR_MC13XXX_CORE
tristate
config REGULATOR_MC13783
tristate "Freescale MC13783 regulator driver"
depends on MFD_MC13783
select REGULATOR_MC13XXX_CORE
help
Say y here to support the regulators found on the Freescale MC13783
PMIC.
config REGULATOR_MC13892
tristate "Freescale MC13892 regulator driver"
depends on MFD_MC13XXX
select REGULATOR_MC13XXX_CORE
help
Say y here to support the regulators found on the Freescale MC13892
PMIC.
config REGULATOR_ISL6271A
tristate "Intersil ISL6271A Power regulator"
depends on I2C
help
This driver supports ISL6271A voltage regulator chip.
config REGULATOR_88PM8607
bool "Marvell 88PM8607 Power regulators"
depends on MFD_88PM860X=y
help
This driver supports 88PM8607 voltage regulator chips.
config REGULATOR_MAX1586
tristate "Maxim 1586/1587 voltage regulator"
...
...
@@ -136,61 +195,12 @@ config REGULATOR_MAX8998
via I2C bus. The provided regulator is suitable for S3C6410
and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages.
config REGULATOR_TWL4030
bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC"
depends on TWL4030_CORE
help
This driver supports the voltage regulators provided by
this family of companion chips.
config REGULATOR_WM831X
tristate "Wolfson Microelcronics WM831x PMIC regulators"
depends on MFD_WM831X
help
Support the voltage and current regulators of the WM831x series
of PMIC devices.
config REGULATOR_WM8350
tristate "Wolfson Microelectronics WM8350 AudioPlus PMIC"
depends on MFD_WM8350
help
This driver provides support for the voltage and current regulators
of the WM8350 AudioPlus PMIC.
config REGULATOR_WM8400
tristate "Wolfson Microelectronics WM8400 AudioPlus PMIC"
depends on MFD_WM8400
help
This driver provides support for the voltage regulators of the
WM8400 AudioPlus PMIC.
config REGULATOR_WM8994
tristate "Wolfson Microelectronics WM8994 CODEC"
depends on MFD_WM8994
help
This driver provides support for the voltage regulators on the
WM8994 CODEC.
config REGULATOR_DA903X
tristate "Support regulators on Dialog Semiconductor DA9030/DA9034 PMIC"
depends on PMIC_DA903X
help
Say y here to support the BUCKs and LDOs regulators found on
Dialog Semiconductor DA9030/DA9034 PMIC.
config REGULATOR_DA9052
tristate "Dialog DA9052/DA9053 regulators"
depends on PMIC_DA9052
help
This driver supports the voltage regulators of DA9052-BC and
DA9053-AA/Bx PMIC.
config REGULATOR_PCF50633
tristate "PCF50633 regulator driver"
depends on MFD_PCF50633
config REGULATOR_PCAP
tristate "Motorola PCAP2 regulator driver"
depends on EZX_PCAP
help
Say Y here to support the voltage regulators and convertors
on PCF50633
This driver provides support for the voltage regulators of the
PCAP2 PMIC.
config REGULATOR_LP3971
tristate "National Semiconductors LP3971 PMIC regulator driver"
...
...
@@ -206,31 +216,20 @@ config REGULATOR_LP3972
Say Y here to support the voltage regulators and convertors
on National Semiconductors LP3972 PMIC
config REGULATOR_PCAP
tristate "PCAP2 regulator driver"
depends on EZX_PCAP
help
This driver provides support for the voltage regulators of the
PCAP2 PMIC.
config REGULATOR_MC13XXX_CORE
tristate
config REGULATOR_MC13783
tristate "Support regulators on Freescale MC13783 PMIC"
depends on MFD_MC13783
select REGULATOR_MC13XXX_CORE
config REGULATOR_PCF50633
tristate "NXP PCF50633 regulator driver"
depends on MFD_PCF50633
help
Say y here to support the regulators found on the Freescale MC13783
PMIC.
Say Y here to support the voltage regulators and convertors
on PCF50633
config REGULATOR_MC13892
tristate "Support regulators on Freescale MC13892 PMIC"
depends on MFD_MC13XXX
select REGULATOR_MC13XXX_CORE
config REGULATOR_S5M8767
tristate "Samsung S5M8767A voltage regulator"
depends on MFD_S5M_CORE
help
Say y here to support the regulators found on the Freescale MC13892
PMIC.
This driver supports a Samsung S5M8767A voltage output regulator
via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and
supports DVS mode with 8bits of output voltage control.
config REGULATOR_AB3100
tristate "ST-Ericsson AB3100 Regulator functions"
...
...
@@ -241,6 +240,32 @@ config REGULATOR_AB3100
AB3100 analog baseband dealing with power regulators
for the system.
config REGULATOR_AB8500
bool "ST-Ericsson AB8500 Power Regulators"
depends on AB8500_CORE
help
This driver supports the regulators found on the ST-Ericsson mixed
signal AB8500 PMIC
config REGULATOR_DBX500_PRCMU
bool
config REGULATOR_DB8500_PRCMU
bool "ST-Ericsson DB8500 Voltage Domain Regulators"
depends on MFD_DB8500_PRCMU
select REGULATOR_DBX500_PRCMU
help
This driver supports the voltage domain regulators controlled by the
DB8500 PRCMU
config REGULATOR_BQ24022
tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
help
This driver controls a TI bq24022 Charger attached via
GPIOs. The provided current regulator can enable/disable
charging select between 100 mA and 500 mA charging current
limit.
config REGULATOR_TPS6105X
tristate "TI TPS6105X Power regulators"
depends on TPS6105X
...
...
@@ -250,6 +275,16 @@ config REGULATOR_TPS6105X
It is a single boost converter primarily for white LEDs and
audio amplifiers.
config REGULATOR_TPS62360
tristate "TI TPS62360 Power Regulator"
depends on I2C
select REGMAP_I2C
help
This driver supports TPS62360 voltage regulator chip. This
regulator is meant for processor core supply. This chip is
high-frequency synchronous step down dc-dc converter optimized
for battery-powered portable applications.
config REGULATOR_TPS65023
tristate "TI TPS65023 Power regulators"
depends on I2C
...
...
@@ -267,73 +302,77 @@ config REGULATOR_TPS6507X
three step-down converters and two general-purpose LDO voltage regulators.
It supports TI's software based Class-2 SmartReflex implementation.
config REGULATOR_TPS65
912
tristate "TI TPS65
912 Power regulator
"
depends on
(MFD_TPS65912_I2C || MFD_TPS65912_SPI)
config REGULATOR_TPS65
217
tristate "TI TPS65
217 Power regulators
"
depends on
MFD_TPS65217
help
This driver supports TPS65912 voltage regulator chip.
This driver supports TPS65217 voltage regulator chips. TPS65217
provides three step-down converters and four general-purpose LDO
voltage regulators. It supports software based voltage control
for different voltage domains
config REGULATOR_
88PM8607
bool "Marvell 88PM8607
Power regulators"
depends on
MFD_88PM860X=y
config REGULATOR_
TPS6524X
tristate "TI TPS6524X
Power regulators"
depends on
SPI
help
This driver supports 88PM8607 voltage regulator chips.
This driver supports TPS6524X voltage regulator chips. TPS6524X
provides three step-down converters and two general-purpose LDO
voltage regulators. This device is interfaced using a customized
serial interface currently supported on the sequencer serial
port controller.
config REGULATOR_
ISL6271A
tristate "
Intersil ISL6271A Power regulator
"
depends on
I2C
config REGULATOR_
TPS6586X
tristate "
TI TPS6586X Power regulators
"
depends on
MFD_TPS6586X
help
This driver supports
ISL6271A voltage regulator chip
.
This driver supports
TPS6586X voltage regulator chips
.
config REGULATOR_
AD5398
tristate "
Analog Devices AD5398/AD5821 r
egulators"
depends on
I2C
config REGULATOR_
TPS65910
tristate "
TI TPS65910/TPS65911 Power R
egulators"
depends on
MFD_TPS65910
help
This driver supports AD5398 and AD5821 current regulator chips.
If building into module, its name is ad5398.ko.
This driver supports TPS65910/TPS65911 voltage regulator chips.
config REGULATOR_
AB8500
bool "ST-Ericsson AB8500 Power Regulators
"
depends on
AB8500_CORE
config REGULATOR_
TPS65912
tristate "TI TPS65912 Power regulator
"
depends on
(MFD_TPS65912_I2C || MFD_TPS65912_SPI)
help
This driver supports the regulators found on the ST-Ericsson mixed
signal AB8500 PMIC
This driver supports TPS65912 voltage regulator chip.
config REGULATOR_
DB8500_PRCMU
bool "
ST-Ericsson DB8500 Voltage Domain Regulators
"
depends on
MFD_DB8500_PRCMU
config REGULATOR_
TWL4030
bool "
TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC
"
depends on
TWL4030_CORE
help
This driver supports the voltage
domain regulators controlled by the
DB8500 PRCMU
This driver supports the voltage
regulators provided by
this family of companion chips.
config REGULATOR_
TPS6586
X
tristate "
TI TPS6586X Power
regulators"
depends on MFD_
TPS6586
X
config REGULATOR_
WM831
X
tristate "
Wolfson Microelectronics WM831x PMIC
regulators"
depends on MFD_
WM831
X
help
This driver supports TPS6586X voltage regulator chips.
Support the voltage and current regulators of the WM831x series
of PMIC devices.
config REGULATOR_
TPS6524X
tristate "
TI TPS6524X Power regulators
"
depends on
SPI
config REGULATOR_
WM8350
tristate "
Wolfson Microelectronics WM8350 AudioPlus PMIC
"
depends on
MFD_WM8350
help
This driver supports TPS6524X voltage regulator chips. TPS6524X
provides three step-down converters and two general-purpose LDO
voltage regulators. This device is interfaced using a customized
serial interface currently supported on the sequencer serial
port controller.
This driver provides support for the voltage and current regulators
of the WM8350 AudioPlus PMIC.
config REGULATOR_
TPS6591
0
tristate "
TI TPS65910 Power Regulator
"
depends on MFD_
TPS6591
0
config REGULATOR_
WM840
0
tristate "
Wolfson Microelectronics WM8400 AudioPlus PMIC
"
depends on MFD_
WM840
0
help
This driver supports TPS65910 voltage regulator chips.
This driver provides support for the voltage regulators of the
WM8400 AudioPlus PMIC.
config REGULATOR_
AAT2870
tristate "
AnalogicTech AAT2870 Regulators
"
depends on MFD_
AAT2870_CORE
config REGULATOR_
WM8994
tristate "
Wolfson Microelectronics WM8994 CODEC
"
depends on MFD_
WM8994
help
If you have a AnalogicTech AAT2870 say Y to enable
the
regulator driver
.
This driver provides support for the voltage regulators on
the
WM8994 CODEC
.
endif
drivers/regulator/Makefile
View file @
63236f40
...
...
@@ -10,43 +10,49 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER)
+=
userspace-consumer.o
obj-$(CONFIG_REGULATOR_GPIO)
+=
gpio-regulator.o
obj-$(CONFIG_REGULATOR_88PM8607)
+=
88pm8607.o
obj-$(CONFIG_REGULATOR_AAT2870)
+=
aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB3100)
+=
ab3100.o
obj-$(CONFIG_REGULATOR_AB8500)
+=
ab8500.o
obj-$(CONFIG_REGULATOR_AD5398)
+=
ad5398.o
obj-$(CONFIG_REGULATOR_ANATOP)
+=
anatop-regulator.o
obj-$(CONFIG_REGULATOR_BQ24022)
+=
bq24022.o
obj-$(CONFIG_REGULATOR_DA903X)
+=
da903x.o
obj-$(CONFIG_REGULATOR_DA9052)
+=
da9052-regulator.o
obj-$(CONFIG_REGULATOR_DBX500_PRCMU)
+=
dbx500-prcmu.o
obj-$(CONFIG_REGULATOR_DB8500_PRCMU)
+=
db8500-prcmu.o
obj-$(CONFIG_REGULATOR_ISL6271A)
+=
isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_LP3971)
+=
lp3971.o
obj-$(CONFIG_REGULATOR_LP3972)
+=
lp3972.o
obj-$(CONFIG_REGULATOR_MAX1586)
+=
max1586.o
obj-$(CONFIG_REGULATOR_TWL4030)
+=
twl-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649)
+=
max8649.o
obj-$(CONFIG_REGULATOR_MAX8660)
+=
max8660.o
obj-$(CONFIG_REGULATOR_MAX8925)
+=
max8925-regulator.o
obj-$(CONFIG_REGULATOR_MAX8952)
+=
max8952.o
obj-$(CONFIG_REGULATOR_MAX8997)
+=
max8997.o
obj-$(CONFIG_REGULATOR_MAX8998)
+=
max8998.o
obj-$(CONFIG_REGULATOR_WM831X)
+=
wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X)
+=
wm831x-isink.o
obj-$(CONFIG_REGULATOR_WM831X)
+=
wm831x-ldo.o
obj-$(CONFIG_REGULATOR_WM8350)
+=
wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400)
+=
wm8400-regulator.o
obj-$(CONFIG_REGULATOR_WM8994)
+=
wm8994-regulator.o
obj-$(CONFIG_REGULATOR_TPS6586X)
+=
tps6586x-regulator.o
obj-$(CONFIG_REGULATOR_DA903X)
+=
da903x.o
obj-$(CONFIG_REGULATOR_DA9052)
+=
da9052-regulator.o
obj-$(CONFIG_REGULATOR_PCF50633)
+=
pcf50633-regulator.o
obj-$(CONFIG_REGULATOR_PCAP)
+=
pcap-regulator.o
obj-$(CONFIG_REGULATOR_MC13783)
+=
mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892)
+=
mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE)
+=
mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_AB3100)
+=
ab3100.o
obj-$(CONFIG_REGULATOR_PCAP)
+=
pcap-regulator.o
obj-$(CONFIG_REGULATOR_PCF50633)
+=
pcf50633-regulator.o
obj-$(CONFIG_REGULATOR_S5M8767)
+=
s5m8767.o
obj-$(CONFIG_REGULATOR_TPS6105X)
+=
tps6105x-regulator.o
obj-$(CONFIG_REGULATOR_TPS62360)
+=
tps62360-regulator.o
obj-$(CONFIG_REGULATOR_TPS65023)
+=
tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X)
+=
tps6507x-regulator.o
obj-$(CONFIG_REGULATOR_TPS65217)
+=
tps65217-regulator.o
obj-$(CONFIG_REGULATOR_TPS6524X)
+=
tps6524x-regulator.o
obj-$(CONFIG_REGULATOR_TPS65912)
+=
tps65912-regulator.o
obj-$(CONFIG_REGULATOR_88PM8607)
+=
88pm8607.o
obj-$(CONFIG_REGULATOR_ISL6271A)
+=
isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_AB8500)
+=
ab8500.o
obj-$(CONFIG_REGULATOR_DB8500_PRCMU)
+=
db8500-prcmu.o
obj-$(CONFIG_REGULATOR_TPS6586X)
+=
tps6586x-regulator.o
obj-$(CONFIG_REGULATOR_TPS65910)
+=
tps65910-regulator.o
obj-$(CONFIG_REGULATOR_AAT2870)
+=
aat2870-regulator.o
obj-$(CONFIG_REGULATOR_TPS65912)
+=
tps65912-regulator.o
obj-$(CONFIG_REGULATOR_TWL4030)
+=
twl-regulator.o
obj-$(CONFIG_REGULATOR_WM831X)
+=
wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X)
+=
wm831x-isink.o
obj-$(CONFIG_REGULATOR_WM831X)
+=
wm831x-ldo.o
obj-$(CONFIG_REGULATOR_WM8350)
+=
wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400)
+=
wm8400-regulator.o
obj-$(CONFIG_REGULATOR_WM8994)
+=
wm8994-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG)
+=
-DDEBUG
drivers/regulator/aat2870-regulator.c
View file @
63236f40
...
...
@@ -31,7 +31,7 @@
#include <linux/mfd/aat2870.h>
struct
aat2870_regulator
{
struct
platform_device
*
pdev
;
struct
aat2870_data
*
aat2870
;
struct
regulator_desc
desc
;
const
int
*
voltages
;
/* uV */
...
...
@@ -60,7 +60,7 @@ static int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev,
unsigned
selector
)
{
struct
aat2870_regulator
*
ri
=
rdev_get_drvdata
(
rdev
);
struct
aat2870_data
*
aat2870
=
dev_get_drvdata
(
ri
->
pdev
->
dev
.
parent
)
;
struct
aat2870_data
*
aat2870
=
ri
->
aat2870
;
return
aat2870
->
update
(
aat2870
,
ri
->
voltage_addr
,
ri
->
voltage_mask
,
selector
<<
ri
->
voltage_shift
);
...
...
@@ -69,7 +69,7 @@ static int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev,
static
int
aat2870_ldo_get_voltage_sel
(
struct
regulator_dev
*
rdev
)
{
struct
aat2870_regulator
*
ri
=
rdev_get_drvdata
(
rdev
);
struct
aat2870_data
*
aat2870
=
dev_get_drvdata
(
ri
->
pdev
->
dev
.
parent
)
;
struct
aat2870_data
*
aat2870
=
ri
->
aat2870
;
u8
val
;
int
ret
;
...
...
@@ -83,7 +83,7 @@ static int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev)
static
int
aat2870_ldo_enable
(
struct
regulator_dev
*
rdev
)
{
struct
aat2870_regulator
*
ri
=
rdev_get_drvdata
(
rdev
);
struct
aat2870_data
*
aat2870
=
dev_get_drvdata
(
ri
->
pdev
->
dev
.
parent
)
;
struct
aat2870_data
*
aat2870
=
ri
->
aat2870
;
return
aat2870
->
update
(
aat2870
,
ri
->
enable_addr
,
ri
->
enable_mask
,
ri
->
enable_mask
);
...
...
@@ -92,7 +92,7 @@ static int aat2870_ldo_enable(struct regulator_dev *rdev)
static
int
aat2870_ldo_disable
(
struct
regulator_dev
*
rdev
)
{
struct
aat2870_regulator
*
ri
=
rdev_get_drvdata
(
rdev
);
struct
aat2870_data
*
aat2870
=
dev_get_drvdata
(
ri
->
pdev
->
dev
.
parent
)
;
struct
aat2870_data
*
aat2870
=
ri
->
aat2870
;
return
aat2870
->
update
(
aat2870
,
ri
->
enable_addr
,
ri
->
enable_mask
,
0
);
}
...
...
@@ -100,7 +100,7 @@ static int aat2870_ldo_disable(struct regulator_dev *rdev)
static
int
aat2870_ldo_is_enabled
(
struct
regulator_dev
*
rdev
)
{
struct
aat2870_regulator
*
ri
=
rdev_get_drvdata
(
rdev
);
struct
aat2870_data
*
aat2870
=
dev_get_drvdata
(
ri
->
pdev
->
dev
.
parent
)
;
struct
aat2870_data
*
aat2870
=
ri
->
aat2870
;
u8
val
;
int
ret
;
...
...
@@ -185,7 +185,7 @@ static int aat2870_regulator_probe(struct platform_device *pdev)
dev_err
(
&
pdev
->
dev
,
"Invalid device ID, %d
\n
"
,
pdev
->
id
);
return
-
EINVAL
;
}
ri
->
pdev
=
pdev
;
ri
->
aat2870
=
dev_get_drvdata
(
pdev
->
dev
.
parent
)
;
rdev
=
regulator_register
(
&
ri
->
desc
,
&
pdev
->
dev
,
pdev
->
dev
.
platform_data
,
ri
,
NULL
);
...
...
drivers/regulator/ab8500.c
View file @
63236f40
...
...
@@ -201,7 +201,7 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector)
return
info
->
voltages
[
selector
];
}
static
int
ab8500_regulator_get_voltage
(
struct
regulator_dev
*
rdev
)
static
int
ab8500_regulator_get_voltage
_sel
(
struct
regulator_dev
*
rdev
)
{
int
ret
,
val
;
struct
ab8500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
...
...
@@ -229,11 +229,9 @@ static int ab8500_regulator_get_voltage(struct regulator_dev *rdev)
/* vintcore has a different layout */
val
=
regval
&
info
->
voltage_mask
;
if
(
info
->
desc
.
id
==
AB8500_LDO_INTCORE
)
ret
=
info
->
voltages
[
val
>>
0x3
]
;
ret
urn
val
>>
0x3
;
else
ret
=
info
->
voltages
[
val
];
return
ret
;
return
val
;
}
static
int
ab8500_get_best_voltage_index
(
struct
regulator_dev
*
rdev
,
...
...
@@ -320,7 +318,7 @@ static struct regulator_ops ab8500_regulator_ops = {
.
enable
=
ab8500_regulator_enable
,
.
disable
=
ab8500_regulator_disable
,
.
is_enabled
=
ab8500_regulator_is_enabled
,
.
get_voltage
=
ab8500_regulator_get_voltage
,
.
get_voltage
_sel
=
ab8500_regulator_get_voltage_sel
,
.
set_voltage
=
ab8500_regulator_set_voltage
,
.
list_voltage
=
ab8500_list_voltage
,
.
enable_time
=
ab8500_regulator_enable_time
,
...
...
drivers/regulator/ad5398.c
View file @
63236f40
...
...
@@ -94,8 +94,8 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int
if
(
max_uA
>
chip
->
max_uA
||
max_uA
<
chip
->
min_uA
)
return
-
EINVAL
;
selector
=
((
min_uA
-
chip
->
min_uA
)
*
chip
->
current_level
+
range_uA
-
1
)
/
range_uA
;
selector
=
DIV_ROUND_UP
((
min_uA
-
chip
->
min_uA
)
*
chip
->
current_level
,
range_uA
)
;
if
(
ad5398_calc_current
(
chip
,
selector
)
>
max_uA
)
return
-
EINVAL
;
...
...
drivers/regulator/anatop-regulator.c
0 → 100644
View file @
63236f40
/*
* Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/mfd/anatop.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
struct
anatop_regulator
{
const
char
*
name
;
u32
control_reg
;
struct
anatop
*
mfd
;
int
vol_bit_shift
;
int
vol_bit_width
;
int
min_bit_val
;
int
min_voltage
;
int
max_voltage
;
struct
regulator_desc
rdesc
;
struct
regulator_init_data
*
initdata
;
};
static
int
anatop_set_voltage
(
struct
regulator_dev
*
reg
,
int
min_uV
,
int
max_uV
,
unsigned
*
selector
)
{
struct
anatop_regulator
*
anatop_reg
=
rdev_get_drvdata
(
reg
);
u32
val
,
sel
;
int
uv
;
uv
=
min_uV
;
dev_dbg
(
&
reg
->
dev
,
"%s: uv %d, min %d, max %d
\n
"
,
__func__
,
uv
,
anatop_reg
->
min_voltage
,
anatop_reg
->
max_voltage
);
if
(
uv
<
anatop_reg
->
min_voltage
)
{
if
(
max_uV
>
anatop_reg
->
min_voltage
)
uv
=
anatop_reg
->
min_voltage
;
else
return
-
EINVAL
;
}
if
(
!
anatop_reg
->
control_reg
)
return
-
ENOTSUPP
;
sel
=
DIV_ROUND_UP
(
uv
-
anatop_reg
->
min_voltage
,
25000
);
if
(
sel
*
25000
+
anatop_reg
->
min_voltage
>
anatop_reg
->
max_voltage
)
return
-
EINVAL
;
val
=
anatop_reg
->
min_bit_val
+
sel
;
*
selector
=
sel
;
dev_dbg
(
&
reg
->
dev
,
"%s: calculated val %d
\n
"
,
__func__
,
val
);
anatop_set_bits
(
anatop_reg
->
mfd
,
anatop_reg
->
control_reg
,
anatop_reg
->
vol_bit_shift
,
anatop_reg
->
vol_bit_width
,
val
);
return
0
;
}
static
int
anatop_get_voltage_sel
(
struct
regulator_dev
*
reg
)
{
struct
anatop_regulator
*
anatop_reg
=
rdev_get_drvdata
(
reg
);
u32
val
;
if
(
!
anatop_reg
->
control_reg
)
return
-
ENOTSUPP
;
val
=
anatop_get_bits
(
anatop_reg
->
mfd
,
anatop_reg
->
control_reg
,
anatop_reg
->
vol_bit_shift
,
anatop_reg
->
vol_bit_width
);
return
val
-
anatop_reg
->
min_bit_val
;
}
static
int
anatop_list_voltage
(
struct
regulator_dev
*
reg
,
unsigned
selector
)
{
struct
anatop_regulator
*
anatop_reg
=
rdev_get_drvdata
(
reg
);
int
uv
;
uv
=
anatop_reg
->
min_voltage
+
selector
*
25000
;
dev_dbg
(
&
reg
->
dev
,
"vddio = %d, selector = %u
\n
"
,
uv
,
selector
);
return
uv
;
}
static
struct
regulator_ops
anatop_rops
=
{
.
set_voltage
=
anatop_set_voltage
,
.
get_voltage_sel
=
anatop_get_voltage_sel
,
.
list_voltage
=
anatop_list_voltage
,
};
static
int
__devinit
anatop_regulator_probe
(
struct
platform_device
*
pdev
)
{
struct
device
*
dev
=
&
pdev
->
dev
;
struct
device_node
*
np
=
dev
->
of_node
;
struct
regulator_desc
*
rdesc
;
struct
regulator_dev
*
rdev
;
struct
anatop_regulator
*
sreg
;
struct
regulator_init_data
*
initdata
;
struct
anatop
*
anatopmfd
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
int
ret
=
0
;
initdata
=
of_get_regulator_init_data
(
dev
,
np
);
sreg
=
devm_kzalloc
(
dev
,
sizeof
(
*
sreg
),
GFP_KERNEL
);
if
(
!
sreg
)
return
-
ENOMEM
;
sreg
->
initdata
=
initdata
;
sreg
->
name
=
kstrdup
(
of_get_property
(
np
,
"regulator-name"
,
NULL
),
GFP_KERNEL
);
rdesc
=
&
sreg
->
rdesc
;
memset
(
rdesc
,
0
,
sizeof
(
*
rdesc
));
rdesc
->
name
=
sreg
->
name
;
rdesc
->
ops
=
&
anatop_rops
;
rdesc
->
type
=
REGULATOR_VOLTAGE
;
rdesc
->
owner
=
THIS_MODULE
;
sreg
->
mfd
=
anatopmfd
;
ret
=
of_property_read_u32
(
np
,
"reg"
,
&
sreg
->
control_reg
);
if
(
ret
)
{
dev_err
(
dev
,
"no reg property set
\n
"
);
goto
anatop_probe_end
;
}
ret
=
of_property_read_u32
(
np
,
"anatop-vol-bit-width"
,
&
sreg
->
vol_bit_width
);
if
(
ret
)
{
dev_err
(
dev
,
"no anatop-vol-bit-width property set
\n
"
);
goto
anatop_probe_end
;
}
ret
=
of_property_read_u32
(
np
,
"anatop-vol-bit-shift"
,
&
sreg
->
vol_bit_shift
);
if
(
ret
)
{
dev_err
(
dev
,
"no anatop-vol-bit-shift property set
\n
"
);
goto
anatop_probe_end
;
}
ret
=
of_property_read_u32
(
np
,
"anatop-min-bit-val"
,
&
sreg
->
min_bit_val
);
if
(
ret
)
{
dev_err
(
dev
,
"no anatop-min-bit-val property set
\n
"
);
goto
anatop_probe_end
;
}
ret
=
of_property_read_u32
(
np
,
"anatop-min-voltage"
,
&
sreg
->
min_voltage
);
if
(
ret
)
{
dev_err
(
dev
,
"no anatop-min-voltage property set
\n
"
);
goto
anatop_probe_end
;
}
ret
=
of_property_read_u32
(
np
,
"anatop-max-voltage"
,
&
sreg
->
max_voltage
);
if
(
ret
)
{
dev_err
(
dev
,
"no anatop-max-voltage property set
\n
"
);
goto
anatop_probe_end
;
}
rdesc
->
n_voltages
=
(
sreg
->
max_voltage
-
sreg
->
min_voltage
)
/
25000
+
1
;
/* register regulator */
rdev
=
regulator_register
(
rdesc
,
dev
,
initdata
,
sreg
,
pdev
->
dev
.
of_node
);
if
(
IS_ERR
(
rdev
))
{
dev_err
(
dev
,
"failed to register %s
\n
"
,
rdesc
->
name
);
ret
=
PTR_ERR
(
rdev
);
goto
anatop_probe_end
;
}
platform_set_drvdata
(
pdev
,
rdev
);
anatop_probe_end:
if
(
ret
)
kfree
(
sreg
->
name
);
return
ret
;
}
static
int
__devexit
anatop_regulator_remove
(
struct
platform_device
*
pdev
)
{
struct
regulator_dev
*
rdev
=
platform_get_drvdata
(
pdev
);
struct
anatop_regulator
*
sreg
=
rdev_get_drvdata
(
rdev
);
const
char
*
name
=
sreg
->
name
;
regulator_unregister
(
rdev
);
kfree
(
name
);
return
0
;
}
static
struct
of_device_id
__devinitdata
of_anatop_regulator_match_tbl
[]
=
{
{
.
compatible
=
"fsl,anatop-regulator"
,
},
{
/* end */
}
};
static
struct
platform_driver
anatop_regulator
=
{
.
driver
=
{
.
name
=
"anatop_regulator"
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
of_anatop_regulator_match_tbl
,
},
.
probe
=
anatop_regulator_probe
,
.
remove
=
anatop_regulator_remove
,
};
static
int
__init
anatop_regulator_init
(
void
)
{
return
platform_driver_register
(
&
anatop_regulator
);
}
postcore_initcall
(
anatop_regulator_init
);
static
void
__exit
anatop_regulator_exit
(
void
)
{
platform_driver_unregister
(
&
anatop_regulator
);
}
module_exit
(
anatop_regulator_exit
);
MODULE_AUTHOR
(
"Nancy Chen <Nancy.Chen@freescale.com>, "
"Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>"
);
MODULE_DESCRIPTION
(
"ANATOP Regulator driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/regulator/da903x.c
View file @
63236f40
...
...
@@ -119,7 +119,7 @@ static int da903x_set_ldo_voltage(struct regulator_dev *rdev,
return
-
EINVAL
;
}
val
=
(
min_uV
-
info
->
min_uV
+
info
->
step_uV
-
1
)
/
info
->
step_uV
;
val
=
DIV_ROUND_UP
(
min_uV
-
info
->
min_uV
,
info
->
step_uV
)
;
*
selector
=
val
;
val
<<=
info
->
vol_shift
;
mask
=
((
1
<<
info
->
vol_nbits
)
-
1
)
<<
info
->
vol_shift
;
...
...
@@ -202,7 +202,7 @@ static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev,
return
-
EINVAL
;
}
val
=
(
min_uV
-
info
->
min_uV
+
info
->
step_uV
-
1
)
/
info
->
step_uV
;
val
=
DIV_ROUND_UP
(
min_uV
-
info
->
min_uV
,
info
->
step_uV
)
;
*
selector
=
val
;
val
<<=
info
->
vol_shift
;
mask
=
((
1
<<
info
->
vol_nbits
)
-
1
)
<<
info
->
vol_shift
;
...
...
@@ -233,10 +233,10 @@ static int da9030_set_ldo14_voltage(struct regulator_dev *rdev,
thresh
=
(
info
->
max_uV
+
info
->
min_uV
)
/
2
;
if
(
min_uV
<
thresh
)
{
val
=
(
thresh
-
min_uV
+
info
->
step_uV
-
1
)
/
info
->
step_uV
;
val
=
DIV_ROUND_UP
(
thresh
-
min_uV
,
info
->
step_uV
)
;
val
|=
0x4
;
}
else
{
val
=
(
min_uV
-
thresh
+
info
->
step_uV
-
1
)
/
info
->
step_uV
;
val
=
DIV_ROUND_UP
(
min_uV
-
thresh
,
info
->
step_uV
)
;
}
*
selector
=
val
;
...
...
@@ -281,7 +281,7 @@ static int da9034_set_dvc_voltage(struct regulator_dev *rdev,
return
-
EINVAL
;
}
val
=
(
min_uV
-
info
->
min_uV
+
info
->
step_uV
-
1
)
/
info
->
step_uV
;
val
=
DIV_ROUND_UP
(
min_uV
-
info
->
min_uV
,
info
->
step_uV
)
;
*
selector
=
val
;
val
<<=
info
->
vol_shift
;
mask
=
((
1
<<
info
->
vol_nbits
)
-
1
)
<<
info
->
vol_shift
;
...
...
@@ -307,7 +307,7 @@ static int da9034_set_ldo12_voltage(struct regulator_dev *rdev,
return
-
EINVAL
;
}
val
=
(
min_uV
-
info
->
min_uV
+
info
->
step_uV
-
1
)
/
info
->
step_uV
;
val
=
DIV_ROUND_UP
(
min_uV
-
info
->
min_uV
,
info
->
step_uV
)
;
val
=
(
val
>=
20
)
?
val
-
12
:
((
val
>
7
)
?
8
:
val
);
*
selector
=
val
;
val
<<=
info
->
vol_shift
;
...
...
drivers/regulator/db8500-prcmu.c
View file @
63236f40
...
...
@@ -18,74 +18,11 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/db8500-prcmu.h>
#include <linux/module.h>
/*
* power state reference count
*/
static
int
power_state_active_cnt
;
/* will initialize to zero */
static
DEFINE_SPINLOCK
(
power_state_active_lock
);
static
void
power_state_active_enable
(
void
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
power_state_active_lock
,
flags
);
power_state_active_cnt
++
;
spin_unlock_irqrestore
(
&
power_state_active_lock
,
flags
);
}
static
int
power_state_active_disable
(
void
)
{
int
ret
=
0
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
power_state_active_lock
,
flags
);
if
(
power_state_active_cnt
<=
0
)
{
pr_err
(
"power state: unbalanced enable/disable calls
\n
"
);
ret
=
-
EINVAL
;
goto
out
;
}
power_state_active_cnt
--
;
out:
spin_unlock_irqrestore
(
&
power_state_active_lock
,
flags
);
return
ret
;
}
/*
* Exported interface for CPUIdle only. This function is called when interrupts
* are turned off. Hence, no locking.
*/
int
power_state_active_is_enabled
(
void
)
{
return
(
power_state_active_cnt
>
0
);
}
/**
* struct db8500_regulator_info - db8500 regulator information
* @dev: device pointer
* @desc: regulator description
* @rdev: regulator device pointer
* @is_enabled: status of the regulator
* @epod_id: id for EPOD (power domain)
* @is_ramret: RAM retention switch for EPOD (power domain)
* @operating_point: operating point (only for vape, to be removed)
*
*/
struct
db8500_regulator_info
{
struct
device
*
dev
;
struct
regulator_desc
desc
;
struct
regulator_dev
*
rdev
;
bool
is_enabled
;
u16
epod_id
;
bool
is_ramret
;
bool
exclude_from_power_state
;
unsigned
int
operating_point
;
};
#include "dbx500-prcmu.h"
static
int
db8500_regulator_enable
(
struct
regulator_dev
*
rdev
)
{
struct
db
8
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
struct
db
x
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
if
(
info
==
NULL
)
return
-
EINVAL
;
...
...
@@ -93,16 +30,18 @@ static int db8500_regulator_enable(struct regulator_dev *rdev)
dev_vdbg
(
rdev_get_dev
(
rdev
),
"regulator-%s-enable
\n
"
,
info
->
desc
.
name
);
info
->
is_enabled
=
true
;
if
(
!
info
->
exclude_from_power_state
)
power_state_active_enable
();
if
(
!
info
->
is_enabled
)
{
info
->
is_enabled
=
true
;
if
(
!
info
->
exclude_from_power_state
)
power_state_active_enable
();
}
return
0
;
}
static
int
db8500_regulator_disable
(
struct
regulator_dev
*
rdev
)
{
struct
db
8
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
struct
db
x
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
int
ret
=
0
;
if
(
info
==
NULL
)
...
...
@@ -111,16 +50,18 @@ static int db8500_regulator_disable(struct regulator_dev *rdev)
dev_vdbg
(
rdev_get_dev
(
rdev
),
"regulator-%s-disable
\n
"
,
info
->
desc
.
name
);
info
->
is_enabled
=
false
;
if
(
!
info
->
exclude_from_power_state
)
ret
=
power_state_active_disable
();
if
(
info
->
is_enabled
)
{
info
->
is_enabled
=
false
;
if
(
!
info
->
exclude_from_power_state
)
ret
=
power_state_active_disable
();
}
return
ret
;
}
static
int
db8500_regulator_is_enabled
(
struct
regulator_dev
*
rdev
)
{
struct
db
8
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
struct
db
x
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
if
(
info
==
NULL
)
return
-
EINVAL
;
...
...
@@ -197,7 +138,7 @@ static int disable_epod(u16 epod_id, bool ramret)
*/
static
int
db8500_regulator_switch_enable
(
struct
regulator_dev
*
rdev
)
{
struct
db
8
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
struct
db
x
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
int
ret
;
if
(
info
==
NULL
)
...
...
@@ -221,7 +162,7 @@ static int db8500_regulator_switch_enable(struct regulator_dev *rdev)
static
int
db8500_regulator_switch_disable
(
struct
regulator_dev
*
rdev
)
{
struct
db
8
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
struct
db
x
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
int
ret
;
if
(
info
==
NULL
)
...
...
@@ -245,7 +186,7 @@ static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
static
int
db8500_regulator_switch_is_enabled
(
struct
regulator_dev
*
rdev
)
{
struct
db
8
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
struct
db
x
500_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
if
(
info
==
NULL
)
return
-
EINVAL
;
...
...
@@ -266,8 +207,8 @@ static struct regulator_ops db8500_regulator_switch_ops = {
/*
* Regulator information
*/
static
struct
db
8
500_regulator_info
db
8
500_regulator_info
[
DB8500_NUM_REGULATORS
]
=
{
static
struct
db
x
500_regulator_info
db
x
500_regulator_info
[
DB8500_NUM_REGULATORS
]
=
{
[
DB8500_REGULATOR_VAPE
]
=
{
.
desc
=
{
.
name
=
"db8500-vape"
,
...
...
@@ -476,12 +417,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
int
i
,
err
;
/* register all regulators */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
db
8
500_regulator_info
);
i
++
)
{
struct
db
8
500_regulator_info
*
info
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
db
x
500_regulator_info
);
i
++
)
{
struct
db
x
500_regulator_info
*
info
;
struct
regulator_init_data
*
init_data
=
&
db8500_init_data
[
i
];
/* assign per-regulator data */
info
=
&
db
8
500_regulator_info
[
i
];
info
=
&
db
x
500_regulator_info
[
i
];
info
->
dev
=
&
pdev
->
dev
;
/* register with the regulator framework */
...
...
@@ -494,7 +435,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
/* if failing, unregister all earlier regulators */
while
(
--
i
>=
0
)
{
info
=
&
db
8
500_regulator_info
[
i
];
info
=
&
db
x
500_regulator_info
[
i
];
regulator_unregister
(
info
->
rdev
);
}
return
err
;
...
...
@@ -503,17 +444,22 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
dev_dbg
(
rdev_get_dev
(
info
->
rdev
),
"regulator-%s-probed
\n
"
,
info
->
desc
.
name
);
}
err
=
ux500_regulator_debug_init
(
pdev
,
dbx500_regulator_info
,
ARRAY_SIZE
(
dbx500_regulator_info
));
return
0
;
return
err
;
}
static
int
__exit
db8500_regulator_remove
(
struct
platform_device
*
pdev
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
db8500_regulator_info
);
i
++
)
{
struct
db8500_regulator_info
*
info
;
info
=
&
db8500_regulator_info
[
i
];
ux500_regulator_debug_exit
();
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
dbx500_regulator_info
);
i
++
)
{
struct
dbx500_regulator_info
*
info
;
info
=
&
dbx500_regulator_info
[
i
];
dev_vdbg
(
rdev_get_dev
(
info
->
rdev
),
"regulator-%s-remove
\n
"
,
info
->
desc
.
name
);
...
...
drivers/regulator/dbx500-prcmu.c
0 → 100644
View file @
63236f40
/*
* Copyright (C) ST-Ericsson SA 2010
*
* License Terms: GNU General Public License v2
* Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
* Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
*
* UX500 common part of Power domain regulators
*/
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/regulator/driver.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include "dbx500-prcmu.h"
/*
* power state reference count
*/
static
int
power_state_active_cnt
;
/* will initialize to zero */
static
DEFINE_SPINLOCK
(
power_state_active_lock
);
int
power_state_active_get
(
void
)
{
unsigned
long
flags
;
int
cnt
;
spin_lock_irqsave
(
&
power_state_active_lock
,
flags
);
cnt
=
power_state_active_cnt
;
spin_unlock_irqrestore
(
&
power_state_active_lock
,
flags
);
return
cnt
;
}
void
power_state_active_enable
(
void
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
power_state_active_lock
,
flags
);
power_state_active_cnt
++
;
spin_unlock_irqrestore
(
&
power_state_active_lock
,
flags
);
}
int
power_state_active_disable
(
void
)
{
int
ret
=
0
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
power_state_active_lock
,
flags
);
if
(
power_state_active_cnt
<=
0
)
{
pr_err
(
"power state: unbalanced enable/disable calls
\n
"
);
ret
=
-
EINVAL
;
goto
out
;
}
power_state_active_cnt
--
;
out:
spin_unlock_irqrestore
(
&
power_state_active_lock
,
flags
);
return
ret
;
}
#ifdef CONFIG_REGULATOR_DEBUG
static
struct
ux500_regulator_debug
{
struct
dentry
*
dir
;
struct
dentry
*
status_file
;
struct
dentry
*
power_state_cnt_file
;
struct
dbx500_regulator_info
*
regulator_array
;
int
num_regulators
;
u8
*
state_before_suspend
;
u8
*
state_after_suspend
;
}
rdebug
;
void
ux500_regulator_suspend_debug
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
rdebug
.
num_regulators
;
i
++
)
rdebug
.
state_before_suspend
[
i
]
=
rdebug
.
regulator_array
[
i
].
is_enabled
;
}
void
ux500_regulator_resume_debug
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
rdebug
.
num_regulators
;
i
++
)
rdebug
.
state_after_suspend
[
i
]
=
rdebug
.
regulator_array
[
i
].
is_enabled
;
}
static
int
ux500_regulator_power_state_cnt_print
(
struct
seq_file
*
s
,
void
*
p
)
{
struct
device
*
dev
=
s
->
private
;
int
err
;
/* print power state count */
err
=
seq_printf
(
s
,
"ux500-regulator power state count: %i
\n
"
,
power_state_active_get
());
if
(
err
<
0
)
dev_err
(
dev
,
"seq_printf overflow
\n
"
);
return
0
;
}
static
int
ux500_regulator_power_state_cnt_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
ux500_regulator_power_state_cnt_print
,
inode
->
i_private
);
}
static
const
struct
file_operations
ux500_regulator_power_state_cnt_fops
=
{
.
open
=
ux500_regulator_power_state_cnt_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
.
owner
=
THIS_MODULE
,
};
static
int
ux500_regulator_status_print
(
struct
seq_file
*
s
,
void
*
p
)
{
struct
device
*
dev
=
s
->
private
;
int
err
;
int
i
;
/* print dump header */
err
=
seq_printf
(
s
,
"ux500-regulator status:
\n
"
);
if
(
err
<
0
)
dev_err
(
dev
,
"seq_printf overflow
\n
"
);
err
=
seq_printf
(
s
,
"%31s : %8s : %8s
\n
"
,
"current"
,
"before"
,
"after"
);
if
(
err
<
0
)
dev_err
(
dev
,
"seq_printf overflow
\n
"
);
for
(
i
=
0
;
i
<
rdebug
.
num_regulators
;
i
++
)
{
struct
dbx500_regulator_info
*
info
;
/* Access per-regulator data */
info
=
&
rdebug
.
regulator_array
[
i
];
/* print status */
err
=
seq_printf
(
s
,
"%20s : %8s : %8s : %8s
\n
"
,
info
->
desc
.
name
,
info
->
is_enabled
?
"enabled"
:
"disabled"
,
rdebug
.
state_before_suspend
[
i
]
?
"enabled"
:
"disabled"
,
rdebug
.
state_after_suspend
[
i
]
?
"enabled"
:
"disabled"
);
if
(
err
<
0
)
dev_err
(
dev
,
"seq_printf overflow
\n
"
);
}
return
0
;
}
static
int
ux500_regulator_status_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
ux500_regulator_status_print
,
inode
->
i_private
);
}
static
const
struct
file_operations
ux500_regulator_status_fops
=
{
.
open
=
ux500_regulator_status_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
.
owner
=
THIS_MODULE
,
};
int
__attribute__
((
weak
))
dbx500_regulator_testcase
(
struct
dbx500_regulator_info
*
regulator_info
,
int
num_regulators
)
{
return
0
;
}
int
__devinit
ux500_regulator_debug_init
(
struct
platform_device
*
pdev
,
struct
dbx500_regulator_info
*
regulator_info
,
int
num_regulators
)
{
/* create directory */
rdebug
.
dir
=
debugfs_create_dir
(
"ux500-regulator"
,
NULL
);
if
(
!
rdebug
.
dir
)
goto
exit_no_debugfs
;
/* create "status" file */
rdebug
.
status_file
=
debugfs_create_file
(
"status"
,
S_IRUGO
,
rdebug
.
dir
,
&
pdev
->
dev
,
&
ux500_regulator_status_fops
);
if
(
!
rdebug
.
status_file
)
goto
exit_destroy_dir
;
/* create "power-state-count" file */
rdebug
.
power_state_cnt_file
=
debugfs_create_file
(
"power-state-count"
,
S_IRUGO
,
rdebug
.
dir
,
&
pdev
->
dev
,
&
ux500_regulator_power_state_cnt_fops
);
if
(
!
rdebug
.
power_state_cnt_file
)
goto
exit_destroy_status
;
rdebug
.
regulator_array
=
regulator_info
;
rdebug
.
num_regulators
=
num_regulators
;
rdebug
.
state_before_suspend
=
kzalloc
(
num_regulators
,
GFP_KERNEL
);
if
(
!
rdebug
.
state_before_suspend
)
{
dev_err
(
&
pdev
->
dev
,
"could not allocate memory for saving state
\n
"
);
goto
exit_destroy_power_state
;
}
rdebug
.
state_after_suspend
=
kzalloc
(
num_regulators
,
GFP_KERNEL
);
if
(
!
rdebug
.
state_after_suspend
)
{
dev_err
(
&
pdev
->
dev
,
"could not allocate memory for saving state
\n
"
);
goto
exit_free
;
}
dbx500_regulator_testcase
(
regulator_info
,
num_regulators
);
return
0
;
exit_free:
kfree
(
rdebug
.
state_before_suspend
);
exit_destroy_power_state:
debugfs_remove
(
rdebug
.
power_state_cnt_file
);
exit_destroy_status:
debugfs_remove
(
rdebug
.
status_file
);
exit_destroy_dir:
debugfs_remove
(
rdebug
.
dir
);
exit_no_debugfs:
dev_err
(
&
pdev
->
dev
,
"failed to create debugfs entries.
\n
"
);
return
-
ENOMEM
;
}
int
__devexit
ux500_regulator_debug_exit
(
void
)
{
debugfs_remove_recursive
(
rdebug
.
dir
);
kfree
(
rdebug
.
state_after_suspend
);
kfree
(
rdebug
.
state_before_suspend
);
return
0
;
}
#endif
drivers/regulator/dbx500-prcmu.h
0 → 100644
View file @
63236f40
/*
* Copyright (C) ST-Ericsson SA 2010
*
* Author: Bengt Jonsson <bengt.jonsson@stericsson.com> for ST-Ericsson,
* Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
*
* License Terms: GNU General Public License v2
*
*/
#ifndef DBX500_REGULATOR_H
#define DBX500_REGULATOR_H
#include <linux/platform_device.h>
/**
* struct dbx500_regulator_info - dbx500 regulator information
* @dev: device pointer
* @desc: regulator description
* @rdev: regulator device pointer
* @is_enabled: status of the regulator
* @epod_id: id for EPOD (power domain)
* @is_ramret: RAM retention switch for EPOD (power domain)
* @operating_point: operating point (only for vape, to be removed)
*
*/
struct
dbx500_regulator_info
{
struct
device
*
dev
;
struct
regulator_desc
desc
;
struct
regulator_dev
*
rdev
;
bool
is_enabled
;
u16
epod_id
;
bool
is_ramret
;
bool
exclude_from_power_state
;
unsigned
int
operating_point
;
};
void
power_state_active_enable
(
void
);
int
power_state_active_disable
(
void
);
#ifdef CONFIG_REGULATOR_DEBUG
int
ux500_regulator_debug_init
(
struct
platform_device
*
pdev
,
struct
dbx500_regulator_info
*
regulator_info
,
int
num_regulators
);
int
ux500_regulator_debug_exit
(
void
);
#else
static
inline
int
ux500_regulator_debug_init
(
struct
platform_device
*
pdev
,
struct
dbx500_regulator_info
*
regulator_info
,
int
num_regulators
)
{
return
0
;
}
static
inline
int
ux500_regulator_debug_exit
(
void
)
{
return
0
;
}
#endif
#endif
drivers/regulator/fixed.c
View file @
63236f40
...
...
@@ -192,7 +192,9 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
drvdata
->
desc
.
type
=
REGULATOR_VOLTAGE
;
drvdata
->
desc
.
owner
=
THIS_MODULE
;
drvdata
->
desc
.
ops
=
&
fixed_voltage_ops
;
drvdata
->
desc
.
n_voltages
=
1
;
if
(
config
->
microvolts
)
drvdata
->
desc
.
n_voltages
=
1
;
drvdata
->
microvolts
=
config
->
microvolts
;
drvdata
->
gpio
=
config
->
gpio
;
...
...
drivers/regulator/isl6271a-regulator.c
View file @
63236f40
...
...
@@ -63,23 +63,15 @@ static int isl6271a_set_voltage(struct regulator_dev *dev,
unsigned
*
selector
)
{
struct
isl_pmic
*
pmic
=
rdev_get_drvdata
(
dev
);
int
vsel
,
err
,
data
;
int
err
,
data
;
if
(
minuV
<
ISL6271A_VOLTAGE_MIN
||
minuV
>
ISL6271A_VOLTAGE_MAX
)
return
-
EINVAL
;
if
(
maxuV
<
ISL6271A_VOLTAGE_MIN
||
maxuV
>
ISL6271A_VOLTAGE_MAX
)
return
-
EINVAL
;
/* Align to 50000 mV */
vsel
=
minuV
-
(
minuV
%
ISL6271A_VOLTAGE_STEP
);
/* If the result fell out of [minuV,maxuV] range, put it back */
if
(
vsel
<
minuV
)
vsel
+=
ISL6271A_VOLTAGE_STEP
;
/* Convert the microvolts to data for the chip */
data
=
(
vsel
-
ISL6271A_VOLTAGE_MIN
)
/
ISL6271A_VOLTAGE_STEP
;
data
=
DIV_ROUND_UP
(
minuV
-
ISL6271A_VOLTAGE_MIN
,
ISL6271A_VOLTAGE_STEP
);
*
selector
=
data
;
mutex_lock
(
&
pmic
->
mtx
);
...
...
drivers/regulator/max1586.c
View file @
63236f40
...
...
@@ -76,8 +76,8 @@ static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV,
if
(
min_uV
<
max1586
->
min_uV
)
min_uV
=
max1586
->
min_uV
;
*
selector
=
((
min_uV
-
max1586
->
min_uV
)
*
MAX1586_V3_MAX_VSEL
+
range_uV
-
1
)
/
range_uV
;
*
selector
=
DIV_ROUND_UP
((
min_uV
-
max1586
->
min_uV
)
*
MAX1586_V3_MAX_VSEL
,
range_uV
)
;
if
(
max1586_v3_calc_voltage
(
max1586
,
*
selector
)
>
max_uV
)
return
-
EINVAL
;
...
...
drivers/regulator/max8649.c
View file @
63236f40
...
...
@@ -101,8 +101,7 @@ static int max8649_set_voltage(struct regulator_dev *rdev,
min_uV
,
max_uV
);
return
-
EINVAL
;
}
data
=
(
min_uV
-
MAX8649_DCDC_VMIN
+
MAX8649_DCDC_STEP
-
1
)
/
MAX8649_DCDC_STEP
;
data
=
DIV_ROUND_UP
(
min_uV
-
MAX8649_DCDC_VMIN
,
MAX8649_DCDC_STEP
);
mask
=
MAX8649_VOL_MASK
;
*
selector
=
data
&
mask
;
...
...
@@ -270,7 +269,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
ret
);
goto
out
;
}
dev_info
(
info
->
dev
,
"Detected MAX8649 (ID:%x)
\n
"
,
ret
);
dev_info
(
info
->
dev
,
"Detected MAX8649 (ID:%x)
\n
"
,
val
);
/* enable VID0 & VID1 */
regmap_update_bits
(
info
->
regmap
,
MAX8649_CONTROL
,
MAX8649_VID_MASK
,
0
);
...
...
drivers/regulator/max8660.c
View file @
63236f40
...
...
@@ -153,14 +153,15 @@ static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV,
if
(
max_uV
<
MAX8660_DCDC_MIN_UV
||
max_uV
>
MAX8660_DCDC_MAX_UV
)
return
-
EINVAL
;
selector
=
(
min_uV
-
(
MAX8660_DCDC_MIN_UV
-
MAX8660_DCDC_STEP
+
1
))
/
MAX8660_DCDC_STEP
;
*
s
=
selector
;
selector
=
DIV_ROUND_UP
(
min_uV
-
MAX8660_DCDC_MIN_UV
,
MAX8660_DCDC_STEP
);
ret
=
max8660_dcdc_list
(
rdev
,
selector
);
if
(
ret
<
0
||
ret
>
max_uV
)
return
-
EINVAL
;
*
s
=
selector
;
reg
=
(
rdev_get_id
(
rdev
)
==
MAX8660_V3
)
?
MAX8660_ADTV2
:
MAX8660_SDTV2
;
ret
=
max8660_write
(
max8660
,
reg
,
0
,
selector
);
if
(
ret
)
...
...
@@ -210,8 +211,9 @@ static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV,
if
(
max_uV
<
MAX8660_LDO5_MIN_UV
||
max_uV
>
MAX8660_LDO5_MAX_UV
)
return
-
EINVAL
;
selector
=
(
min_uV
-
(
MAX8660_LDO5_MIN_UV
-
MAX8660_LDO5_STEP
+
1
))
/
MAX8660_LDO5_STEP
;
selector
=
DIV_ROUND_UP
(
min_uV
-
MAX8660_LDO5_MIN_UV
,
MAX8660_LDO5_STEP
);
ret
=
max8660_ldo5_list
(
rdev
,
selector
);
if
(
ret
<
0
||
ret
>
max_uV
)
return
-
EINVAL
;
...
...
@@ -287,8 +289,8 @@ static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV,
if
(
max_uV
<
MAX8660_LDO67_MIN_UV
||
max_uV
>
MAX8660_LDO67_MAX_UV
)
return
-
EINVAL
;
selector
=
(
min_uV
-
(
MAX8660_LDO67_MIN_UV
-
MAX8660_LDO67_STEP
+
1
))
/
MAX8660_LDO67_STEP
;
selector
=
DIV_ROUND_UP
(
min_uV
-
MAX8660_LDO67_MIN_UV
,
MAX8660_LDO67_STEP
)
;
ret
=
max8660_ldo67_list
(
rdev
,
selector
);
if
(
ret
<
0
||
ret
>
max_uV
)
...
...
drivers/regulator/max8925-regulator.c
View file @
63236f40
...
...
@@ -73,7 +73,7 @@ static int max8925_set_voltage(struct regulator_dev *rdev,
min_uV
,
max_uV
);
return
-
EINVAL
;
}
data
=
(
min_uV
-
info
->
min_uV
+
info
->
step_uV
-
1
)
/
info
->
step_uV
;
data
=
DIV_ROUND_UP
(
min_uV
-
info
->
min_uV
,
info
->
step_uV
)
;
*
selector
=
data
;
data
<<=
info
->
vol_shift
;
mask
=
((
1
<<
info
->
vol_nbits
)
-
1
)
<<
info
->
vol_shift
;
...
...
@@ -140,7 +140,7 @@ static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV)
if
(
uV
<
SD1_DVM_VMIN
||
uV
>
SD1_DVM_VMAX
)
return
-
EINVAL
;
data
=
(
uV
-
SD1_DVM_VMIN
+
SD1_DVM_STEP
-
1
)
/
SD1_DVM_STEP
;
data
=
DIV_ROUND_UP
(
uV
-
SD1_DVM_VMIN
,
SD1_DVM_STEP
)
;
data
<<=
SD1_DVM_SHIFT
;
mask
=
3
<<
SD1_DVM_SHIFT
;
...
...
drivers/regulator/max8997.c
View file @
63236f40
...
...
@@ -130,15 +130,10 @@ static const struct voltage_map_desc *reg_voltage_map[] = {
[
MAX8997_CHARGER_TOPOFF
]
=
&
topoff_current_map_desc
,
};
static
inline
int
max8997_get_rid
(
struct
regulator_dev
*
rdev
)
{
return
rdev_get_id
(
rdev
);
}
static
int
max8997_list_voltage_safeout
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
if
(
rid
==
MAX8997_ESAFEOUT1
||
rid
==
MAX8997_ESAFEOUT2
)
{
switch
(
selector
)
{
...
...
@@ -161,7 +156,7 @@ static int max8997_list_voltage_safeout(struct regulator_dev *rdev,
static
int
max8997_list_voltage_charger_cv
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
if
(
rid
!=
MAX8997_CHARGER_CV
)
goto
err
;
...
...
@@ -184,7 +179,7 @@ static int max8997_list_voltage(struct regulator_dev *rdev,
unsigned
int
selector
)
{
const
struct
voltage_map_desc
*
desc
;
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
int
val
;
if
(
rid
>=
ARRAY_SIZE
(
reg_voltage_map
)
||
...
...
@@ -205,7 +200,7 @@ static int max8997_list_voltage(struct regulator_dev *rdev,
static
int
max8997_get_enable_register
(
struct
regulator_dev
*
rdev
,
int
*
reg
,
int
*
mask
,
int
*
pattern
)
{
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
switch
(
rid
)
{
case
MAX8997_LDO1
...
MAX8997_LDO21
:
...
...
@@ -325,7 +320,7 @@ static int max8997_reg_disable(struct regulator_dev *rdev)
static
int
max8997_get_voltage_register
(
struct
regulator_dev
*
rdev
,
int
*
_reg
,
int
*
_shift
,
int
*
_mask
)
{
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
int
reg
,
shift
=
0
,
mask
=
0x3f
;
switch
(
rid
)
{
...
...
@@ -386,7 +381,7 @@ static int max8997_get_voltage(struct regulator_dev *rdev)
struct
max8997_data
*
max8997
=
rdev_get_drvdata
(
rdev
);
struct
i2c_client
*
i2c
=
max8997
->
iodev
->
i2c
;
int
reg
,
shift
,
mask
,
ret
;
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
u8
val
;
ret
=
max8997_get_voltage_register
(
rdev
,
&
reg
,
&
shift
,
&
mask
);
...
...
@@ -446,7 +441,7 @@ static int max8997_set_voltage_charger_cv(struct regulator_dev *rdev,
{
struct
max8997_data
*
max8997
=
rdev_get_drvdata
(
rdev
);
struct
i2c_client
*
i2c
=
max8997
->
iodev
->
i2c
;
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
int
lb
,
ub
;
int
reg
,
shift
=
0
,
mask
,
ret
=
0
;
u8
val
=
0x0
;
...
...
@@ -503,7 +498,7 @@ static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev,
struct
i2c_client
*
i2c
=
max8997
->
iodev
->
i2c
;
int
min_vol
=
min_uV
/
1000
,
max_vol
=
max_uV
/
1000
;
const
struct
voltage_map_desc
*
desc
;
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
int
reg
,
shift
=
0
,
mask
,
ret
;
int
i
;
u8
org
;
...
...
@@ -564,7 +559,7 @@ static int max8997_assess_side_effect(struct regulator_dev *rdev,
u8
new_val
,
int
*
best
)
{
struct
max8997_data
*
max8997
=
rdev_get_drvdata
(
rdev
);
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
u8
*
buckx_val
[
3
];
bool
buckx_gpiodvs
[
3
];
int
side_effect
[
8
];
...
...
@@ -641,7 +636,7 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev,
int
min_uV
,
int
max_uV
,
unsigned
*
selector
)
{
struct
max8997_data
*
max8997
=
rdev_get_drvdata
(
rdev
);
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
const
struct
voltage_map_desc
*
desc
;
int
new_val
,
new_idx
,
damage
,
tmp_val
,
tmp_idx
,
tmp_dmg
;
bool
gpio_dvs_mode
=
false
;
...
...
@@ -724,7 +719,7 @@ static int max8997_set_voltage_safeout(struct regulator_dev *rdev,
{
struct
max8997_data
*
max8997
=
rdev_get_drvdata
(
rdev
);
struct
i2c_client
*
i2c
=
max8997
->
iodev
->
i2c
;
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
int
reg
,
shift
=
0
,
mask
,
ret
;
int
i
=
0
;
u8
val
;
...
...
@@ -766,7 +761,7 @@ static int max8997_reg_disable_suspend(struct regulator_dev *rdev)
struct
max8997_data
*
max8997
=
rdev_get_drvdata
(
rdev
);
struct
i2c_client
*
i2c
=
max8997
->
iodev
->
i2c
;
int
ret
,
reg
,
mask
,
pattern
;
int
rid
=
max8997_get_r
id
(
rdev
);
int
rid
=
rdev_get_
id
(
rdev
);
ret
=
max8997_get_enable_register
(
rdev
,
&
reg
,
&
mask
,
&
pattern
);
if
(
ret
)
...
...
@@ -908,13 +903,13 @@ static struct regulator_desc regulators[] = {
},
regulator_desc_buck
(
7
),
{
.
name
=
"EN32KHz
AP"
,
.
name
=
"EN32KHz
_
AP"
,
.
id
=
MAX8997_EN32KHZ_AP
,
.
ops
=
&
max8997_fixedvolt_ops
,
.
type
=
REGULATOR_VOLTAGE
,
.
owner
=
THIS_MODULE
,
},
{
.
name
=
"EN32KHz
CP"
,
.
name
=
"EN32KHz
_
CP"
,
.
id
=
MAX8997_EN32KHZ_CP
,
.
ops
=
&
max8997_fixedvolt_ops
,
.
type
=
REGULATOR_VOLTAGE
,
...
...
@@ -938,7 +933,7 @@ static struct regulator_desc regulators[] = {
.
type
=
REGULATOR_VOLTAGE
,
.
owner
=
THIS_MODULE
,
},
{
.
name
=
"CHARGER
CV"
,
.
name
=
"CHARGER
_
CV"
,
.
id
=
MAX8997_CHARGER_CV
,
.
ops
=
&
max8997_fixedstate_ops
,
.
type
=
REGULATOR_VOLTAGE
,
...
...
@@ -950,7 +945,7 @@ static struct regulator_desc regulators[] = {
.
type
=
REGULATOR_CURRENT
,
.
owner
=
THIS_MODULE
,
},
{
.
name
=
"CHARGER
TOPOFF"
,
.
name
=
"CHARGER
_
TOPOFF"
,
.
id
=
MAX8997_CHARGER_TOPOFF
,
.
ops
=
&
max8997_charger_fixedstate_ops
,
.
type
=
REGULATOR_CURRENT
,
...
...
drivers/regulator/max8998.c
View file @
63236f40
...
...
@@ -112,16 +112,11 @@ static const struct voltage_map_desc *ldo_voltage_map[] = {
&
buck4_voltage_map_desc
,
/* BUCK4 */
};
static
inline
int
max8998_get_ldo
(
struct
regulator_dev
*
rdev
)
{
return
rdev_get_id
(
rdev
);
}
static
int
max8998_list_voltage
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
const
struct
voltage_map_desc
*
desc
;
int
ldo
=
max8998_get_ldo
(
rdev
);
int
ldo
=
rdev_get_id
(
rdev
);
int
val
;
if
(
ldo
>=
ARRAY_SIZE
(
ldo_voltage_map
))
...
...
@@ -141,7 +136,7 @@ static int max8998_list_voltage(struct regulator_dev *rdev,
static
int
max8998_get_enable_register
(
struct
regulator_dev
*
rdev
,
int
*
reg
,
int
*
shift
)
{
int
ldo
=
max8998_get_ldo
(
rdev
);
int
ldo
=
rdev_get_id
(
rdev
);
switch
(
ldo
)
{
case
MAX8998_LDO2
...
MAX8998_LDO5
:
...
...
@@ -222,7 +217,7 @@ static int max8998_ldo_disable(struct regulator_dev *rdev)
static
int
max8998_get_voltage_register
(
struct
regulator_dev
*
rdev
,
int
*
_reg
,
int
*
_shift
,
int
*
_mask
)
{
int
ldo
=
max8998_get_ldo
(
rdev
);
int
ldo
=
rdev_get_id
(
rdev
);
struct
max8998_data
*
max8998
=
rdev_get_drvdata
(
rdev
);
int
reg
,
shift
=
0
,
mask
=
0xff
;
...
...
@@ -310,7 +305,7 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
struct
i2c_client
*
i2c
=
max8998
->
iodev
->
i2c
;
int
min_vol
=
min_uV
/
1000
,
max_vol
=
max_uV
/
1000
;
const
struct
voltage_map_desc
*
desc
;
int
ldo
=
max8998_get_ldo
(
rdev
);
int
ldo
=
rdev_get_id
(
rdev
);
int
reg
,
shift
=
0
,
mask
,
ret
;
int
i
=
0
;
...
...
@@ -362,7 +357,7 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
struct
i2c_client
*
i2c
=
max8998
->
iodev
->
i2c
;
int
min_vol
=
min_uV
/
1000
,
max_vol
=
max_uV
/
1000
;
const
struct
voltage_map_desc
*
desc
;
int
buck
=
max8998_get_ldo
(
rdev
);
int
buck
=
rdev_get_id
(
rdev
);
int
reg
,
shift
=
0
,
mask
,
ret
;
int
difference
=
0
,
i
=
0
,
j
=
0
,
previous_vol
=
0
;
u8
val
=
0
;
...
...
@@ -829,7 +824,6 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
buck12_voltage_map_desc
.
step
*
i
<
(
pdata
->
buck2_voltage2
/
1000
))
i
++
;
printk
(
KERN_ERR
"i2:%d, buck2_idx:%d
\n
"
,
i
,
max8998
->
buck2_idx
);
max8998
->
buck2_vol
[
1
]
=
i
;
ret
=
max8998_write_reg
(
i2c
,
MAX8998_REG_BUCK2_VOLTAGE2
,
i
);
if
(
ret
)
...
...
drivers/regulator/mc13783-regulator.c
View file @
63236f40
...
...
@@ -344,6 +344,9 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
dev_dbg
(
&
pdev
->
dev
,
"%s id %d
\n
"
,
__func__
,
pdev
->
id
);
if
(
!
pdata
)
return
-
EINVAL
;
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
priv
)
+
pdata
->
num_regulators
*
sizeof
(
priv
->
regulators
[
0
]),
GFP_KERNEL
);
...
...
drivers/regulator/mc13xxx-regulator-core.c
View file @
63236f40
...
...
@@ -254,6 +254,7 @@ int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
return
num
;
}
EXPORT_SYMBOL_GPL
(
mc13xxx_get_num_regulators_dt
);
struct
mc13xxx_regulator_init_data
*
__devinit
mc13xxx_parse_regulators_dt
(
struct
platform_device
*
pdev
,
struct
mc13xxx_regulator
*
regulators
,
...
...
@@ -291,6 +292,7 @@ struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt(
return
data
;
}
EXPORT_SYMBOL_GPL
(
mc13xxx_parse_regulators_dt
);
#endif
MODULE_LICENSE
(
"GPL v2"
);
...
...
drivers/regulator/pcf50633-regulator.c
View file @
63236f40
...
...
@@ -142,6 +142,7 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
case
PCF50633_REGULATOR_LDO5
:
case
PCF50633_REGULATOR_LDO6
:
case
PCF50633_REGULATOR_HCLDO
:
case
PCF50633_REGULATOR_MEMLDO
:
volt_bits
=
ldo_voltage_bits
(
millivolts
);
break
;
default:
...
...
@@ -175,6 +176,7 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
case
PCF50633_REGULATOR_LDO5
:
case
PCF50633_REGULATOR_LDO6
:
case
PCF50633_REGULATOR_HCLDO
:
case
PCF50633_REGULATOR_MEMLDO
:
millivolts
=
ldo_voltage_value
(
bits
);
break
;
default:
...
...
@@ -217,9 +219,6 @@ static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
case
PCF50633_REGULATOR_AUTO
:
index
+=
0x2f
;
break
;
case
PCF50633_REGULATOR_HCLDO
:
index
+=
0x01
;
break
;
default:
break
;
}
...
...
@@ -288,27 +287,27 @@ static struct regulator_ops pcf50633_regulator_ops = {
static
struct
regulator_desc
regulators
[]
=
{
[
PCF50633_REGULATOR_AUTO
]
=
PCF50633_REGULATOR
(
"auto"
,
PCF50633_REGULATOR_AUTO
,
8
0
),
PCF50633_REGULATOR
(
"auto"
,
PCF50633_REGULATOR_AUTO
,
8
1
),
[
PCF50633_REGULATOR_DOWN1
]
=
PCF50633_REGULATOR
(
"down1"
,
PCF50633_REGULATOR_DOWN1
,
9
5
),
PCF50633_REGULATOR
(
"down1"
,
PCF50633_REGULATOR_DOWN1
,
9
6
),
[
PCF50633_REGULATOR_DOWN2
]
=
PCF50633_REGULATOR
(
"down2"
,
PCF50633_REGULATOR_DOWN2
,
9
5
),
PCF50633_REGULATOR
(
"down2"
,
PCF50633_REGULATOR_DOWN2
,
9
6
),
[
PCF50633_REGULATOR_LDO1
]
=
PCF50633_REGULATOR
(
"ldo1"
,
PCF50633_REGULATOR_LDO1
,
2
7
),
PCF50633_REGULATOR
(
"ldo1"
,
PCF50633_REGULATOR_LDO1
,
2
8
),
[
PCF50633_REGULATOR_LDO2
]
=
PCF50633_REGULATOR
(
"ldo2"
,
PCF50633_REGULATOR_LDO2
,
2
7
),
PCF50633_REGULATOR
(
"ldo2"
,
PCF50633_REGULATOR_LDO2
,
2
8
),
[
PCF50633_REGULATOR_LDO3
]
=
PCF50633_REGULATOR
(
"ldo3"
,
PCF50633_REGULATOR_LDO3
,
2
7
),
PCF50633_REGULATOR
(
"ldo3"
,
PCF50633_REGULATOR_LDO3
,
2
8
),
[
PCF50633_REGULATOR_LDO4
]
=
PCF50633_REGULATOR
(
"ldo4"
,
PCF50633_REGULATOR_LDO4
,
2
7
),
PCF50633_REGULATOR
(
"ldo4"
,
PCF50633_REGULATOR_LDO4
,
2
8
),
[
PCF50633_REGULATOR_LDO5
]
=
PCF50633_REGULATOR
(
"ldo5"
,
PCF50633_REGULATOR_LDO5
,
2
7
),
PCF50633_REGULATOR
(
"ldo5"
,
PCF50633_REGULATOR_LDO5
,
2
8
),
[
PCF50633_REGULATOR_LDO6
]
=
PCF50633_REGULATOR
(
"ldo6"
,
PCF50633_REGULATOR_LDO6
,
2
7
),
PCF50633_REGULATOR
(
"ldo6"
,
PCF50633_REGULATOR_LDO6
,
2
8
),
[
PCF50633_REGULATOR_HCLDO
]
=
PCF50633_REGULATOR
(
"hcldo"
,
PCF50633_REGULATOR_HCLDO
,
2
6
),
PCF50633_REGULATOR
(
"hcldo"
,
PCF50633_REGULATOR_HCLDO
,
2
8
),
[
PCF50633_REGULATOR_MEMLDO
]
=
PCF50633_REGULATOR
(
"memldo"
,
PCF50633_REGULATOR_MEMLDO
,
0
),
PCF50633_REGULATOR
(
"memldo"
,
PCF50633_REGULATOR_MEMLDO
,
28
),
};
static
int
__devinit
pcf50633_regulator_probe
(
struct
platform_device
*
pdev
)
...
...
drivers/regulator/s5m8767.c
0 → 100644
View file @
63236f40
/*
* s5m8767.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd
* http://www.samsung.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/s5m87xx/s5m-core.h>
#include <linux/mfd/s5m87xx/s5m-pmic.h>
struct
s5m8767_info
{
struct
device
*
dev
;
struct
s5m87xx_dev
*
iodev
;
int
num_regulators
;
struct
regulator_dev
**
rdev
;
int
ramp_delay
;
bool
buck2_ramp
;
bool
buck3_ramp
;
bool
buck4_ramp
;
bool
buck2_gpiodvs
;
bool
buck3_gpiodvs
;
bool
buck4_gpiodvs
;
u8
buck2_vol
[
8
];
u8
buck3_vol
[
8
];
u8
buck4_vol
[
8
];
int
buck_gpios
[
3
];
int
buck_gpioindex
;
};
struct
s5m_voltage_desc
{
int
max
;
int
min
;
int
step
;
};
static
const
struct
s5m_voltage_desc
buck_voltage_val1
=
{
.
max
=
2225000
,
.
min
=
650000
,
.
step
=
6250
,
};
static
const
struct
s5m_voltage_desc
buck_voltage_val2
=
{
.
max
=
1600000
,
.
min
=
600000
,
.
step
=
6250
,
};
static
const
struct
s5m_voltage_desc
buck_voltage_val3
=
{
.
max
=
3000000
,
.
min
=
750000
,
.
step
=
12500
,
};
static
const
struct
s5m_voltage_desc
ldo_voltage_val1
=
{
.
max
=
3950000
,
.
min
=
800000
,
.
step
=
50000
,
};
static
const
struct
s5m_voltage_desc
ldo_voltage_val2
=
{
.
max
=
2375000
,
.
min
=
800000
,
.
step
=
25000
,
};
static
const
struct
s5m_voltage_desc
*
reg_voltage_map
[]
=
{
[
S5M8767_LDO1
]
=
&
ldo_voltage_val2
,
[
S5M8767_LDO2
]
=
&
ldo_voltage_val2
,
[
S5M8767_LDO3
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO4
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO5
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO6
]
=
&
ldo_voltage_val2
,
[
S5M8767_LDO7
]
=
&
ldo_voltage_val2
,
[
S5M8767_LDO8
]
=
&
ldo_voltage_val2
,
[
S5M8767_LDO9
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO10
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO11
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO12
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO13
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO14
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO15
]
=
&
ldo_voltage_val2
,
[
S5M8767_LDO16
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO17
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO18
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO19
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO20
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO21
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO22
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO23
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO24
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO25
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO26
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO27
]
=
&
ldo_voltage_val1
,
[
S5M8767_LDO28
]
=
&
ldo_voltage_val1
,
[
S5M8767_BUCK1
]
=
&
buck_voltage_val1
,
[
S5M8767_BUCK2
]
=
&
buck_voltage_val2
,
[
S5M8767_BUCK3
]
=
&
buck_voltage_val2
,
[
S5M8767_BUCK4
]
=
&
buck_voltage_val2
,
[
S5M8767_BUCK5
]
=
&
buck_voltage_val1
,
[
S5M8767_BUCK6
]
=
&
buck_voltage_val1
,
[
S5M8767_BUCK7
]
=
NULL
,
[
S5M8767_BUCK8
]
=
NULL
,
[
S5M8767_BUCK9
]
=
&
buck_voltage_val3
,
};
static
int
s5m8767_list_voltage
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
const
struct
s5m_voltage_desc
*
desc
;
int
reg_id
=
rdev_get_id
(
rdev
);
int
val
;
if
(
reg_id
>=
ARRAY_SIZE
(
reg_voltage_map
)
||
reg_id
<
0
)
return
-
EINVAL
;
desc
=
reg_voltage_map
[
reg_id
];
if
(
desc
==
NULL
)
return
-
EINVAL
;
val
=
desc
->
min
+
desc
->
step
*
selector
;
if
(
val
>
desc
->
max
)
return
-
EINVAL
;
return
val
;
}
static
int
s5m8767_get_register
(
struct
regulator_dev
*
rdev
,
int
*
reg
)
{
int
reg_id
=
rdev_get_id
(
rdev
);
switch
(
reg_id
)
{
case
S5M8767_LDO1
...
S5M8767_LDO2
:
*
reg
=
S5M8767_REG_LDO1CTRL
+
(
reg_id
-
S5M8767_LDO1
);
break
;
case
S5M8767_LDO3
...
S5M8767_LDO28
:
*
reg
=
S5M8767_REG_LDO3CTRL
+
(
reg_id
-
S5M8767_LDO3
);
break
;
case
S5M8767_BUCK1
:
*
reg
=
S5M8767_REG_BUCK1CTRL1
;
break
;
case
S5M8767_BUCK2
...
S5M8767_BUCK4
:
*
reg
=
S5M8767_REG_BUCK2CTRL
+
(
reg_id
-
S5M8767_BUCK2
)
*
9
;
break
;
case
S5M8767_BUCK5
:
*
reg
=
S5M8767_REG_BUCK5CTRL1
;
break
;
case
S5M8767_BUCK6
...
S5M8767_BUCK9
:
*
reg
=
S5M8767_REG_BUCK6CTRL1
+
(
reg_id
-
S5M8767_BUCK6
)
*
2
;
break
;
default:
return
-
EINVAL
;
}
return
0
;
}
static
int
s5m8767_reg_is_enabled
(
struct
regulator_dev
*
rdev
)
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
int
ret
,
reg
;
int
mask
=
0xc0
,
pattern
=
0xc0
;
u8
val
;
ret
=
s5m8767_get_register
(
rdev
,
&
reg
);
if
(
ret
==
-
EINVAL
)
return
1
;
else
if
(
ret
)
return
ret
;
ret
=
s5m_reg_read
(
s5m8767
->
iodev
,
reg
,
&
val
);
if
(
ret
)
return
ret
;
return
(
val
&
mask
)
==
pattern
;
}
static
int
s5m8767_reg_enable
(
struct
regulator_dev
*
rdev
)
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
int
ret
,
reg
;
int
mask
=
0xc0
,
pattern
=
0xc0
;
ret
=
s5m8767_get_register
(
rdev
,
&
reg
);
if
(
ret
)
return
ret
;
return
s5m_reg_update
(
s5m8767
->
iodev
,
reg
,
pattern
,
mask
);
}
static
int
s5m8767_reg_disable
(
struct
regulator_dev
*
rdev
)
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
int
ret
,
reg
;
int
mask
=
0xc0
,
pattern
=
0xc0
;
ret
=
s5m8767_get_register
(
rdev
,
&
reg
);
if
(
ret
)
return
ret
;
return
s5m_reg_update
(
s5m8767
->
iodev
,
reg
,
~
pattern
,
mask
);
}
static
int
s5m8767_get_voltage_register
(
struct
regulator_dev
*
rdev
,
int
*
_reg
)
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
int
reg_id
=
rdev_get_id
(
rdev
);
int
reg
;
switch
(
reg_id
)
{
case
S5M8767_LDO1
...
S5M8767_LDO2
:
reg
=
S5M8767_REG_LDO1CTRL
+
(
reg_id
-
S5M8767_LDO1
);
break
;
case
S5M8767_LDO3
...
S5M8767_LDO28
:
reg
=
S5M8767_REG_LDO3CTRL
+
(
reg_id
-
S5M8767_LDO3
);
break
;
case
S5M8767_BUCK1
:
reg
=
S5M8767_REG_BUCK1CTRL2
;
break
;
case
S5M8767_BUCK2
:
reg
=
S5M8767_REG_BUCK2DVS1
;
if
(
s5m8767
->
buck2_gpiodvs
)
reg
+=
s5m8767
->
buck_gpioindex
;
break
;
case
S5M8767_BUCK3
:
reg
=
S5M8767_REG_BUCK3DVS1
;
if
(
s5m8767
->
buck3_gpiodvs
)
reg
+=
s5m8767
->
buck_gpioindex
;
break
;
case
S5M8767_BUCK4
:
reg
=
S5M8767_REG_BUCK4DVS1
;
if
(
s5m8767
->
buck4_gpiodvs
)
reg
+=
s5m8767
->
buck_gpioindex
;
break
;
case
S5M8767_BUCK5
:
reg
=
S5M8767_REG_BUCK5CTRL2
;
break
;
case
S5M8767_BUCK6
...
S5M8767_BUCK9
:
reg
=
S5M8767_REG_BUCK6CTRL2
+
(
reg_id
-
S5M8767_BUCK6
)
*
2
;
break
;
default:
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
);
u8
val
;
ret
=
s5m8767_get_voltage_register
(
rdev
,
&
reg
);
if
(
ret
)
return
ret
;
mask
=
(
reg_id
<
S5M8767_BUCK1
)
?
0x3f
:
0xff
;
ret
=
s5m_reg_read
(
s5m8767
->
iodev
,
reg
,
&
val
);
if
(
ret
)
return
ret
;
val
&=
mask
;
return
val
;
}
static
int
s5m8767_convert_voltage_to_sel
(
const
struct
s5m_voltage_desc
*
desc
,
int
min_vol
,
int
max_vol
)
{
int
selector
=
0
;
if
(
desc
==
NULL
)
return
-
EINVAL
;
if
(
max_vol
<
desc
->
min
||
min_vol
>
desc
->
max
)
return
-
EINVAL
;
selector
=
(
min_vol
-
desc
->
min
)
/
desc
->
step
;
if
(
desc
->
min
+
desc
->
step
*
selector
>
max_vol
)
return
-
EINVAL
;
return
selector
;
}
static
int
s5m8767_set_voltage
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
,
unsigned
*
selector
)
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
const
struct
s5m_voltage_desc
*
desc
;
int
reg_id
=
rdev_get_id
(
rdev
);
int
reg
,
mask
,
ret
;
int
i
;
u8
val
;
switch
(
reg_id
)
{
case
S5M8767_LDO1
...
S5M8767_LDO28
:
mask
=
0x3f
;
break
;
case
S5M8767_BUCK1
...
S5M8767_BUCK6
:
mask
=
0xff
;
break
;
case
S5M8767_BUCK7
...
S5M8767_BUCK8
:
return
-
EINVAL
;
case
S5M8767_BUCK9
:
mask
=
0xff
;
break
;
default:
return
-
EINVAL
;
}
desc
=
reg_voltage_map
[
reg_id
];
i
=
s5m8767_convert_voltage_to_sel
(
desc
,
min_uV
,
max_uV
);
if
(
i
<
0
)
return
i
;
ret
=
s5m8767_get_voltage_register
(
rdev
,
&
reg
);
if
(
ret
)
return
ret
;
s5m_reg_read
(
s5m8767
->
iodev
,
reg
,
&
val
);
val
=
val
&
mask
;
ret
=
s5m_reg_write
(
s5m8767
->
iodev
,
reg
,
val
);
*
selector
=
i
;
return
ret
;
}
static
inline
void
s5m8767_set_high
(
struct
s5m8767_info
*
s5m8767
)
{
int
temp_index
=
s5m8767
->
buck_gpioindex
;
gpio_set_value
(
s5m8767
->
buck_gpios
[
0
],
(
temp_index
>>
2
)
&
0x1
);
gpio_set_value
(
s5m8767
->
buck_gpios
[
1
],
(
temp_index
>>
1
)
&
0x1
);
gpio_set_value
(
s5m8767
->
buck_gpios
[
2
],
temp_index
&
0x1
);
}
static
inline
void
s5m8767_set_low
(
struct
s5m8767_info
*
s5m8767
)
{
int
temp_index
=
s5m8767
->
buck_gpioindex
;
gpio_set_value
(
s5m8767
->
buck_gpios
[
2
],
temp_index
&
0x1
);
gpio_set_value
(
s5m8767
->
buck_gpios
[
1
],
(
temp_index
>>
1
)
&
0x1
);
gpio_set_value
(
s5m8767
->
buck_gpios
[
0
],
(
temp_index
>>
2
)
&
0x1
);
}
static
int
s5m8767_set_voltage_buck
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
,
unsigned
*
selector
)
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
int
reg_id
=
rdev_get_id
(
rdev
);
const
struct
s5m_voltage_desc
*
desc
;
int
new_val
,
old_val
,
i
=
0
;
if
(
reg_id
<
S5M8767_BUCK1
||
reg_id
>
S5M8767_BUCK6
)
return
-
EINVAL
;
switch
(
reg_id
)
{
case
S5M8767_BUCK1
:
return
s5m8767_set_voltage
(
rdev
,
min_uV
,
max_uV
,
selector
);
case
S5M8767_BUCK2
...
S5M8767_BUCK4
:
break
;
case
S5M8767_BUCK5
...
S5M8767_BUCK6
:
return
s5m8767_set_voltage
(
rdev
,
min_uV
,
max_uV
,
selector
);
case
S5M8767_BUCK9
:
return
s5m8767_set_voltage
(
rdev
,
min_uV
,
max_uV
,
selector
);
}
desc
=
reg_voltage_map
[
reg_id
];
new_val
=
s5m8767_convert_voltage_to_sel
(
desc
,
min_uV
,
max_uV
);
if
(
new_val
<
0
)
return
new_val
;
switch
(
reg_id
)
{
case
S5M8767_BUCK2
:
if
(
s5m8767
->
buck2_gpiodvs
)
{
while
(
s5m8767
->
buck2_vol
[
i
]
!=
new_val
)
i
++
;
}
else
return
s5m8767_set_voltage
(
rdev
,
min_uV
,
max_uV
,
selector
);
break
;
case
S5M8767_BUCK3
:
if
(
s5m8767
->
buck3_gpiodvs
)
{
while
(
s5m8767
->
buck3_vol
[
i
]
!=
new_val
)
i
++
;
}
else
return
s5m8767_set_voltage
(
rdev
,
min_uV
,
max_uV
,
selector
);
break
;
case
S5M8767_BUCK4
:
if
(
s5m8767
->
buck3_gpiodvs
)
{
while
(
s5m8767
->
buck4_vol
[
i
]
!=
new_val
)
i
++
;
}
else
return
s5m8767_set_voltage
(
rdev
,
min_uV
,
max_uV
,
selector
);
break
;
}
old_val
=
s5m8767
->
buck_gpioindex
;
s5m8767
->
buck_gpioindex
=
i
;
if
(
i
>
old_val
)
s5m8767_set_high
(
s5m8767
);
else
s5m8767_set_low
(
s5m8767
);
*
selector
=
new_val
;
return
0
;
}
static
int
s5m8767_set_voltage_time_sel
(
struct
regulator_dev
*
rdev
,
unsigned
int
old_sel
,
unsigned
int
new_sel
)
{
struct
s5m8767_info
*
s5m8767
=
rdev_get_drvdata
(
rdev
);
const
struct
s5m_voltage_desc
*
desc
;
int
reg_id
=
rdev_get_id
(
rdev
);
desc
=
reg_voltage_map
[
reg_id
];
if
(
old_sel
<
new_sel
)
return
DIV_ROUND_UP
(
desc
->
step
*
(
new_sel
-
old_sel
),
s5m8767
->
ramp_delay
*
1000
);
return
0
;
}
static
struct
regulator_ops
s5m8767_ldo_ops
=
{
.
list_voltage
=
s5m8767_list_voltage
,
.
is_enabled
=
s5m8767_reg_is_enabled
,
.
enable
=
s5m8767_reg_enable
,
.
disable
=
s5m8767_reg_disable
,
.
get_voltage_sel
=
s5m8767_get_voltage_sel
,
.
set_voltage
=
s5m8767_set_voltage
,
.
set_voltage_time_sel
=
s5m8767_set_voltage_time_sel
,
};
static
struct
regulator_ops
s5m8767_buck_ops
=
{
.
list_voltage
=
s5m8767_list_voltage
,
.
is_enabled
=
s5m8767_reg_is_enabled
,
.
enable
=
s5m8767_reg_enable
,
.
disable
=
s5m8767_reg_disable
,
.
get_voltage_sel
=
s5m8767_get_voltage_sel
,
.
set_voltage
=
s5m8767_set_voltage_buck
,
.
set_voltage_time_sel
=
s5m8767_set_voltage_time_sel
,
};
#define regulator_desc_ldo(num) { \
.name = "LDO"#num, \
.id = S5M8767_LDO##num, \
.ops = &s5m8767_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
#define regulator_desc_buck(num) { \
.name = "BUCK"#num, \
.id = S5M8767_BUCK##num, \
.ops = &s5m8767_buck_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
static
struct
regulator_desc
regulators
[]
=
{
regulator_desc_ldo
(
1
),
regulator_desc_ldo
(
2
),
regulator_desc_ldo
(
3
),
regulator_desc_ldo
(
4
),
regulator_desc_ldo
(
5
),
regulator_desc_ldo
(
6
),
regulator_desc_ldo
(
7
),
regulator_desc_ldo
(
8
),
regulator_desc_ldo
(
9
),
regulator_desc_ldo
(
10
),
regulator_desc_ldo
(
11
),
regulator_desc_ldo
(
12
),
regulator_desc_ldo
(
13
),
regulator_desc_ldo
(
14
),
regulator_desc_ldo
(
15
),
regulator_desc_ldo
(
16
),
regulator_desc_ldo
(
17
),
regulator_desc_ldo
(
18
),
regulator_desc_ldo
(
19
),
regulator_desc_ldo
(
20
),
regulator_desc_ldo
(
21
),
regulator_desc_ldo
(
22
),
regulator_desc_ldo
(
23
),
regulator_desc_ldo
(
24
),
regulator_desc_ldo
(
25
),
regulator_desc_ldo
(
26
),
regulator_desc_ldo
(
27
),
regulator_desc_ldo
(
28
),
regulator_desc_buck
(
1
),
regulator_desc_buck
(
2
),
regulator_desc_buck
(
3
),
regulator_desc_buck
(
4
),
regulator_desc_buck
(
5
),
regulator_desc_buck
(
6
),
regulator_desc_buck
(
7
),
regulator_desc_buck
(
8
),
regulator_desc_buck
(
9
),
};
static
__devinit
int
s5m8767_pmic_probe
(
struct
platform_device
*
pdev
)
{
struct
s5m87xx_dev
*
iodev
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
s5m_platform_data
*
pdata
=
dev_get_platdata
(
iodev
->
dev
);
struct
regulator_dev
**
rdev
;
struct
s5m8767_info
*
s5m8767
;
int
i
,
ret
,
size
;
if
(
!
pdata
)
{
dev_err
(
pdev
->
dev
.
parent
,
"Platform data not supplied
\n
"
);
return
-
ENODEV
;
}
if
(
pdata
->
buck2_gpiodvs
)
{
if
(
pdata
->
buck3_gpiodvs
||
pdata
->
buck4_gpiodvs
)
{
dev_err
(
&
pdev
->
dev
,
"S5M8767 GPIO DVS NOT VALID
\n
"
);
return
-
EINVAL
;
}
}
if
(
pdata
->
buck3_gpiodvs
)
{
if
(
pdata
->
buck2_gpiodvs
||
pdata
->
buck4_gpiodvs
)
{
dev_err
(
&
pdev
->
dev
,
"S5M8767 GPIO DVS NOT VALID
\n
"
);
return
-
EINVAL
;
}
}
if
(
pdata
->
buck4_gpiodvs
)
{
if
(
pdata
->
buck2_gpiodvs
||
pdata
->
buck3_gpiodvs
)
{
dev_err
(
&
pdev
->
dev
,
"S5M8767 GPIO DVS NOT VALID
\n
"
);
return
-
EINVAL
;
}
}
s5m8767
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
s5m8767_info
),
GFP_KERNEL
);
if
(
!
s5m8767
)
return
-
ENOMEM
;
size
=
sizeof
(
struct
regulator_dev
*
)
*
(
S5M8767_REG_MAX
-
2
);
s5m8767
->
rdev
=
devm_kzalloc
(
&
pdev
->
dev
,
size
,
GFP_KERNEL
);
if
(
!
s5m8767
->
rdev
)
return
-
ENOMEM
;
rdev
=
s5m8767
->
rdev
;
s5m8767
->
dev
=
&
pdev
->
dev
;
s5m8767
->
iodev
=
iodev
;
s5m8767
->
num_regulators
=
S5M8767_REG_MAX
-
2
;
platform_set_drvdata
(
pdev
,
s5m8767
);
s5m8767
->
buck_gpioindex
=
pdata
->
buck_default_idx
;
s5m8767
->
buck2_gpiodvs
=
pdata
->
buck2_gpiodvs
;
s5m8767
->
buck3_gpiodvs
=
pdata
->
buck3_gpiodvs
;
s5m8767
->
buck4_gpiodvs
=
pdata
->
buck4_gpiodvs
;
s5m8767
->
buck_gpios
[
0
]
=
pdata
->
buck_gpios
[
0
];
s5m8767
->
buck_gpios
[
1
]
=
pdata
->
buck_gpios
[
1
];
s5m8767
->
buck_gpios
[
2
]
=
pdata
->
buck_gpios
[
2
];
s5m8767
->
ramp_delay
=
pdata
->
buck_ramp_delay
;
s5m8767
->
buck2_ramp
=
pdata
->
buck2_ramp_enable
;
s5m8767
->
buck3_ramp
=
pdata
->
buck3_ramp_enable
;
s5m8767
->
buck4_ramp
=
pdata
->
buck4_ramp_enable
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
if
(
s5m8767
->
buck2_gpiodvs
)
{
s5m8767
->
buck2_vol
[
i
]
=
s5m8767_convert_voltage_to_sel
(
&
buck_voltage_val2
,
pdata
->
buck2_voltage
[
i
],
pdata
->
buck2_voltage
[
i
]
+
buck_voltage_val2
.
step
);
}
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
);
}
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
);
}
}
if
(
pdata
->
buck2_gpiodvs
||
pdata
->
buck3_gpiodvs
||
pdata
->
buck4_gpiodvs
)
{
if
(
gpio_is_valid
(
pdata
->
buck_gpios
[
0
])
&&
gpio_is_valid
(
pdata
->
buck_gpios
[
1
])
&&
gpio_is_valid
(
pdata
->
buck_gpios
[
2
]))
{
ret
=
gpio_request
(
pdata
->
buck_gpios
[
0
],
"S5M8767 SET1"
);
if
(
ret
==
-
EBUSY
)
dev_warn
(
&
pdev
->
dev
,
"Duplicated gpio request for SET1
\n
"
);
ret
=
gpio_request
(
pdata
->
buck_gpios
[
1
],
"S5M8767 SET2"
);
if
(
ret
==
-
EBUSY
)
dev_warn
(
&
pdev
->
dev
,
"Duplicated gpio request for SET2
\n
"
);
ret
=
gpio_request
(
pdata
->
buck_gpios
[
2
],
"S5M8767 SET3"
);
if
(
ret
==
-
EBUSY
)
dev_warn
(
&
pdev
->
dev
,
"Duplicated gpio request for SET3
\n
"
);
/* SET1 GPIO */
gpio_direction_output
(
pdata
->
buck_gpios
[
0
],
(
s5m8767
->
buck_gpioindex
>>
2
)
&
0x1
);
/* SET2 GPIO */
gpio_direction_output
(
pdata
->
buck_gpios
[
1
],
(
s5m8767
->
buck_gpioindex
>>
1
)
&
0x1
);
/* SET3 GPIO */
gpio_direction_output
(
pdata
->
buck_gpios
[
2
],
(
s5m8767
->
buck_gpioindex
>>
0
)
&
0x1
);
ret
=
0
;
}
else
{
dev_err
(
&
pdev
->
dev
,
"GPIO NOT VALID
\n
"
);
ret
=
-
EINVAL
;
return
ret
;
}
}
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK2CTRL
,
(
pdata
->
buck2_gpiodvs
)
?
(
1
<<
1
)
:
(
0
<<
1
),
1
<<
1
);
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK3CTRL
,
(
pdata
->
buck3_gpiodvs
)
?
(
1
<<
1
)
:
(
0
<<
1
),
1
<<
1
);
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK4CTRL
,
(
pdata
->
buck4_gpiodvs
)
?
(
1
<<
1
)
:
(
0
<<
1
),
1
<<
1
);
/* Initialize GPIO DVS registers */
for
(
i
=
0
;
i
<
8
;
i
++
)
{
if
(
s5m8767
->
buck2_gpiodvs
)
{
s5m_reg_write
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK2DVS1
+
i
,
s5m8767
->
buck2_vol
[
i
]);
}
if
(
s5m8767
->
buck3_gpiodvs
)
{
s5m_reg_write
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK3DVS1
+
i
,
s5m8767
->
buck3_vol
[
i
]);
}
if
(
s5m8767
->
buck4_gpiodvs
)
{
s5m_reg_write
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK4DVS1
+
i
,
s5m8767
->
buck4_vol
[
i
]);
}
}
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK2CTRL
,
0x78
,
0xff
);
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK3CTRL
,
0x58
,
0xff
);
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_BUCK4CTRL
,
0x78
,
0xff
);
if
(
s5m8767
->
buck2_ramp
)
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_DVSRAMP
,
0x08
,
0x08
);
if
(
s5m8767
->
buck3_ramp
)
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_DVSRAMP
,
0x04
,
0x04
);
if
(
s5m8767
->
buck4_ramp
)
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_DVSRAMP
,
0x02
,
0x02
);
if
(
s5m8767
->
buck2_ramp
||
s5m8767
->
buck3_ramp
||
s5m8767
->
buck4_ramp
)
{
switch
(
s5m8767
->
ramp_delay
)
{
case
15
:
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_DVSRAMP
,
0xc0
,
0xf0
);
break
;
case
25
:
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_DVSRAMP
,
0xd0
,
0xf0
);
break
;
case
50
:
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_DVSRAMP
,
0xe0
,
0xf0
);
break
;
case
100
:
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_DVSRAMP
,
0xf0
,
0xf0
);
break
;
default:
s5m_reg_update
(
s5m8767
->
iodev
,
S5M8767_REG_DVSRAMP
,
0x90
,
0xf0
);
}
}
for
(
i
=
0
;
i
<
pdata
->
num_regulators
;
i
++
)
{
const
struct
s5m_voltage_desc
*
desc
;
int
id
=
pdata
->
regulators
[
i
].
id
;
desc
=
reg_voltage_map
[
id
];
if
(
desc
)
regulators
[
id
].
n_voltages
=
(
desc
->
max
-
desc
->
min
)
/
desc
->
step
+
1
;
rdev
[
i
]
=
regulator_register
(
&
regulators
[
id
],
s5m8767
->
dev
,
pdata
->
regulators
[
i
].
initdata
,
s5m8767
,
NULL
);
if
(
IS_ERR
(
rdev
[
i
]))
{
ret
=
PTR_ERR
(
rdev
[
i
]);
dev_err
(
s5m8767
->
dev
,
"regulator init failed for %d
\n
"
,
id
);
rdev
[
i
]
=
NULL
;
goto
err
;
}
}
return
0
;
err:
for
(
i
=
0
;
i
<
s5m8767
->
num_regulators
;
i
++
)
if
(
rdev
[
i
])
regulator_unregister
(
rdev
[
i
]);
return
ret
;
}
static
int
__devexit
s5m8767_pmic_remove
(
struct
platform_device
*
pdev
)
{
struct
s5m8767_info
*
s5m8767
=
platform_get_drvdata
(
pdev
);
struct
regulator_dev
**
rdev
=
s5m8767
->
rdev
;
int
i
;
for
(
i
=
0
;
i
<
s5m8767
->
num_regulators
;
i
++
)
if
(
rdev
[
i
])
regulator_unregister
(
rdev
[
i
]);
return
0
;
}
static
const
struct
platform_device_id
s5m8767_pmic_id
[]
=
{
{
"s5m8767-pmic"
,
0
},
{
},
};
MODULE_DEVICE_TABLE
(
platform
,
s5m8767_pmic_id
);
static
struct
platform_driver
s5m8767_pmic_driver
=
{
.
driver
=
{
.
name
=
"s5m8767-pmic"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
s5m8767_pmic_probe
,
.
remove
=
__devexit_p
(
s5m8767_pmic_remove
),
.
id_table
=
s5m8767_pmic_id
,
};
static
int
__init
s5m8767_pmic_init
(
void
)
{
return
platform_driver_register
(
&
s5m8767_pmic_driver
);
}
subsys_initcall
(
s5m8767_pmic_init
);
static
void
__exit
s5m8767_pmic_exit
(
void
)
{
platform_driver_unregister
(
&
s5m8767_pmic_driver
);
}
module_exit
(
s5m8767_pmic_exit
);
/* Module information */
MODULE_AUTHOR
(
"Sangbeom Kim <sbkim73@samsung.com>"
);
MODULE_DESCRIPTION
(
"SAMSUNG S5M8767 Regulator Driver"
);
MODULE_LICENSE
(
"GPL"
);
drivers/regulator/tps62360-regulator.c
0 → 100644
View file @
63236f40
/*
* tps62360.c -- TI tps62360
*
* Driver for processor core supply tps62360 and tps62361B
*
* Copyright (c) 2012, NVIDIA Corporation.
*
* Author: Laxman Dewangan <ldewangan@nvidia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
* whether express or implied; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307, USA
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/tps62360.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/regmap.h>
/* Register definitions */
#define REG_VSET0 0
#define REG_VSET1 1
#define REG_VSET2 2
#define REG_VSET3 3
#define REG_CONTROL 4
#define REG_TEMP 5
#define REG_RAMPCTRL 6
#define REG_CHIPID 8
enum
chips
{
TPS62360
,
TPS62361
};
#define TPS62360_BASE_VOLTAGE 770
#define TPS62360_N_VOLTAGES 64
#define TPS62361_BASE_VOLTAGE 500
#define TPS62361_N_VOLTAGES 128
/* tps 62360 chip information */
struct
tps62360_chip
{
const
char
*
name
;
struct
device
*
dev
;
struct
regulator_desc
desc
;
struct
i2c_client
*
client
;
struct
regulator_dev
*
rdev
;
struct
regmap
*
regmap
;
int
chip_id
;
int
vsel0_gpio
;
int
vsel1_gpio
;
int
voltage_base
;
u8
voltage_reg_mask
;
bool
en_internal_pulldn
;
bool
en_force_pwm
;
bool
en_discharge
;
bool
valid_gpios
;
int
lru_index
[
4
];
int
curr_vset_vsel
[
4
];
int
curr_vset_id
;
};
/*
* find_voltage_set_register: Find new voltage configuration register
* (VSET) id.
* The finding of the new VSET register will be based on the LRU mechanism.
* Each VSET register will have different voltage configured . This
* Function will look if any of the VSET register have requested voltage set
* or not.
* - If it is already there then it will make that register as most
* recently used and return as found so that caller need not to set
* the VSET register but need to set the proper gpios to select this
* VSET register.
* - If requested voltage is not found then it will use the least
* recently mechanism to get new VSET register for new configuration
* and will return not_found so that caller need to set new VSET
* register and then gpios (both).
*/
static
bool
find_voltage_set_register
(
struct
tps62360_chip
*
tps
,
int
req_vsel
,
int
*
vset_reg_id
)
{
int
i
;
bool
found
=
false
;
int
new_vset_reg
=
tps
->
lru_index
[
3
];
int
found_index
=
3
;
for
(
i
=
0
;
i
<
4
;
++
i
)
{
if
(
tps
->
curr_vset_vsel
[
tps
->
lru_index
[
i
]]
==
req_vsel
)
{
new_vset_reg
=
tps
->
lru_index
[
i
];
found_index
=
i
;
found
=
true
;
goto
update_lru_index
;
}
}
update_lru_index:
for
(
i
=
found_index
;
i
>
0
;
i
--
)
tps
->
lru_index
[
i
]
=
tps
->
lru_index
[
i
-
1
];
tps
->
lru_index
[
0
]
=
new_vset_reg
;
*
vset_reg_id
=
new_vset_reg
;
return
found
;
}
static
int
tps62360_dcdc_get_voltage
(
struct
regulator_dev
*
dev
)
{
struct
tps62360_chip
*
tps
=
rdev_get_drvdata
(
dev
);
int
vsel
;
unsigned
int
data
;
int
ret
;
ret
=
regmap_read
(
tps
->
regmap
,
REG_VSET0
+
tps
->
curr_vset_id
,
&
data
);
if
(
ret
<
0
)
{
dev_err
(
tps
->
dev
,
"%s: Error in reading register %d
\n
"
,
__func__
,
REG_VSET0
+
tps
->
curr_vset_id
);
return
ret
;
}
vsel
=
(
int
)
data
&
tps
->
voltage_reg_mask
;
return
(
tps
->
voltage_base
+
vsel
*
10
)
*
1000
;
}
static
int
tps62360_dcdc_set_voltage
(
struct
regulator_dev
*
dev
,
int
min_uV
,
int
max_uV
,
unsigned
*
selector
)
{
struct
tps62360_chip
*
tps
=
rdev_get_drvdata
(
dev
);
int
vsel
;
int
ret
;
bool
found
=
false
;
int
new_vset_id
=
tps
->
curr_vset_id
;
if
(
max_uV
<
min_uV
)
return
-
EINVAL
;
if
(
min_uV
>
((
tps
->
voltage_base
+
(
tps
->
desc
.
n_voltages
-
1
)
*
10
)
*
1000
))
return
-
EINVAL
;
if
(
max_uV
<
tps
->
voltage_base
*
1000
)
return
-
EINVAL
;
vsel
=
DIV_ROUND_UP
(
min_uV
-
(
tps
->
voltage_base
*
1000
),
10000
);
if
(
selector
)
*
selector
=
(
vsel
&
tps
->
voltage_reg_mask
);
/*
* If gpios are available to select the VSET register then least
* recently used register for new configuration.
*/
if
(
tps
->
valid_gpios
)
found
=
find_voltage_set_register
(
tps
,
vsel
,
&
new_vset_id
);
if
(
!
found
)
{
ret
=
regmap_update_bits
(
tps
->
regmap
,
REG_VSET0
+
new_vset_id
,
tps
->
voltage_reg_mask
,
vsel
);
if
(
ret
<
0
)
{
dev_err
(
tps
->
dev
,
"%s: Error in updating register %d
\n
"
,
__func__
,
REG_VSET0
+
new_vset_id
);
return
ret
;
}
tps
->
curr_vset_id
=
new_vset_id
;
tps
->
curr_vset_vsel
[
new_vset_id
]
=
vsel
;
}
/* Select proper VSET register vio gpios */
if
(
tps
->
valid_gpios
)
{
gpio_set_value_cansleep
(
tps
->
vsel0_gpio
,
new_vset_id
&
0x1
);
gpio_set_value_cansleep
(
tps
->
vsel1_gpio
,
(
new_vset_id
>>
1
)
&
0x1
);
}
return
0
;
}
static
int
tps62360_dcdc_list_voltage
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps62360_chip
*
tps
=
rdev_get_drvdata
(
dev
);
if
(
selector
>=
tps
->
desc
.
n_voltages
)
return
-
EINVAL
;
return
(
tps
->
voltage_base
+
selector
*
10
)
*
1000
;
}
static
struct
regulator_ops
tps62360_dcdc_ops
=
{
.
get_voltage
=
tps62360_dcdc_get_voltage
,
.
set_voltage
=
tps62360_dcdc_set_voltage
,
.
list_voltage
=
tps62360_dcdc_list_voltage
,
};
static
int
tps62360_init_force_pwm
(
struct
tps62360_chip
*
tps
,
struct
tps62360_regulator_platform_data
*
pdata
,
int
vset_id
)
{
unsigned
int
data
;
int
ret
;
ret
=
regmap_read
(
tps
->
regmap
,
REG_VSET0
+
vset_id
,
&
data
);
if
(
ret
<
0
)
{
dev_err
(
tps
->
dev
,
"%s() fails in writing reg %d
\n
"
,
__func__
,
REG_VSET0
+
vset_id
);
return
ret
;
}
tps
->
curr_vset_vsel
[
vset_id
]
=
data
&
tps
->
voltage_reg_mask
;
if
(
pdata
->
en_force_pwm
)
data
|=
BIT
(
7
);
else
data
&=
~
BIT
(
7
);
ret
=
regmap_write
(
tps
->
regmap
,
REG_VSET0
+
vset_id
,
data
);
if
(
ret
<
0
)
dev_err
(
tps
->
dev
,
"%s() fails in writing reg %d
\n
"
,
__func__
,
REG_VSET0
+
vset_id
);
return
ret
;
}
static
int
tps62360_init_dcdc
(
struct
tps62360_chip
*
tps
,
struct
tps62360_regulator_platform_data
*
pdata
)
{
int
ret
;
int
i
;
/* Initailize internal pull up/down control */
if
(
tps
->
en_internal_pulldn
)
ret
=
regmap_write
(
tps
->
regmap
,
REG_CONTROL
,
0xE0
);
else
ret
=
regmap_write
(
tps
->
regmap
,
REG_CONTROL
,
0x0
);
if
(
ret
<
0
)
{
dev_err
(
tps
->
dev
,
"%s() fails in writing reg %d
\n
"
,
__func__
,
REG_CONTROL
);
return
ret
;
}
/* Initailize force PWM mode */
if
(
tps
->
valid_gpios
)
{
for
(
i
=
0
;
i
<
4
;
++
i
)
{
ret
=
tps62360_init_force_pwm
(
tps
,
pdata
,
i
);
if
(
ret
<
0
)
return
ret
;
}
}
else
{
ret
=
tps62360_init_force_pwm
(
tps
,
pdata
,
tps
->
curr_vset_id
);
if
(
ret
<
0
)
return
ret
;
}
/* Reset output discharge path to reduce power consumption */
ret
=
regmap_update_bits
(
tps
->
regmap
,
REG_RAMPCTRL
,
BIT
(
2
),
0
);
if
(
ret
<
0
)
dev_err
(
tps
->
dev
,
"%s() fails in updating reg %d
\n
"
,
__func__
,
REG_RAMPCTRL
);
return
ret
;
}
static
const
struct
regmap_config
tps62360_regmap_config
=
{
.
reg_bits
=
8
,
.
val_bits
=
8
,
};
static
int
__devinit
tps62360_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
{
struct
tps62360_regulator_platform_data
*
pdata
;
struct
regulator_dev
*
rdev
;
struct
tps62360_chip
*
tps
;
int
ret
;
int
i
;
pdata
=
client
->
dev
.
platform_data
;
if
(
!
pdata
)
{
dev_err
(
&
client
->
dev
,
"%s() Err: Platform data not found
\n
"
,
__func__
);
return
-
EIO
;
}
tps
=
devm_kzalloc
(
&
client
->
dev
,
sizeof
(
*
tps
),
GFP_KERNEL
);
if
(
!
tps
)
{
dev_err
(
&
client
->
dev
,
"%s() Err: Memory allocation fails
\n
"
,
__func__
);
return
-
ENOMEM
;
}
tps
->
en_force_pwm
=
pdata
->
en_force_pwm
;
tps
->
en_discharge
=
pdata
->
en_discharge
;
tps
->
en_internal_pulldn
=
pdata
->
en_internal_pulldn
;
tps
->
vsel0_gpio
=
pdata
->
vsel0_gpio
;
tps
->
vsel1_gpio
=
pdata
->
vsel1_gpio
;
tps
->
client
=
client
;
tps
->
dev
=
&
client
->
dev
;
tps
->
name
=
id
->
name
;
tps
->
voltage_base
=
(
id
->
driver_data
==
TPS62360
)
?
TPS62360_BASE_VOLTAGE
:
TPS62361_BASE_VOLTAGE
;
tps
->
voltage_reg_mask
=
(
id
->
driver_data
==
TPS62360
)
?
0x3F
:
0x7F
;
tps
->
desc
.
name
=
id
->
name
;
tps
->
desc
.
id
=
0
;
tps
->
desc
.
n_voltages
=
(
id
->
driver_data
==
TPS62360
)
?
TPS62360_N_VOLTAGES
:
TPS62361_N_VOLTAGES
;
tps
->
desc
.
ops
=
&
tps62360_dcdc_ops
;
tps
->
desc
.
type
=
REGULATOR_VOLTAGE
;
tps
->
desc
.
owner
=
THIS_MODULE
;
tps
->
regmap
=
regmap_init_i2c
(
client
,
&
tps62360_regmap_config
);
if
(
IS_ERR
(
tps
->
regmap
))
{
ret
=
PTR_ERR
(
tps
->
regmap
);
dev_err
(
&
client
->
dev
,
"%s() Err: Failed to allocate register"
"map: %d
\n
"
,
__func__
,
ret
);
return
ret
;
}
i2c_set_clientdata
(
client
,
tps
);
tps
->
curr_vset_id
=
(
pdata
->
vsel1_def_state
&
1
)
*
2
+
(
pdata
->
vsel0_def_state
&
1
);
tps
->
lru_index
[
0
]
=
tps
->
curr_vset_id
;
tps
->
valid_gpios
=
false
;
if
(
gpio_is_valid
(
tps
->
vsel0_gpio
)
&&
gpio_is_valid
(
tps
->
vsel1_gpio
))
{
ret
=
gpio_request
(
tps
->
vsel0_gpio
,
"tps62360-vsel0"
);
if
(
ret
)
{
dev_err
(
&
client
->
dev
,
"Err: Could not obtain vsel0 GPIO %d: %d
\n
"
,
tps
->
vsel0_gpio
,
ret
);
goto
err_gpio0
;
}
ret
=
gpio_direction_output
(
tps
->
vsel0_gpio
,
pdata
->
vsel0_def_state
);
if
(
ret
)
{
dev_err
(
&
client
->
dev
,
"Err: Could not set direction of"
"vsel0 GPIO %d: %d
\n
"
,
tps
->
vsel0_gpio
,
ret
);
gpio_free
(
tps
->
vsel0_gpio
);
goto
err_gpio0
;
}
ret
=
gpio_request
(
tps
->
vsel1_gpio
,
"tps62360-vsel1"
);
if
(
ret
)
{
dev_err
(
&
client
->
dev
,
"Err: Could not obtain vsel1 GPIO %d: %d
\n
"
,
tps
->
vsel1_gpio
,
ret
);
goto
err_gpio1
;
}
ret
=
gpio_direction_output
(
tps
->
vsel1_gpio
,
pdata
->
vsel1_def_state
);
if
(
ret
)
{
dev_err
(
&
client
->
dev
,
"Err: Could not set direction of"
"vsel1 GPIO %d: %d
\n
"
,
tps
->
vsel1_gpio
,
ret
);
gpio_free
(
tps
->
vsel1_gpio
);
goto
err_gpio1
;
}
tps
->
valid_gpios
=
true
;
/*
* Initialize the lru index with vset_reg id
* The index 0 will be most recently used and
* set with the tps->curr_vset_id */
for
(
i
=
0
;
i
<
4
;
++
i
)
tps
->
lru_index
[
i
]
=
i
;
tps
->
lru_index
[
0
]
=
tps
->
curr_vset_id
;
tps
->
lru_index
[
tps
->
curr_vset_id
]
=
0
;
}
ret
=
tps62360_init_dcdc
(
tps
,
pdata
);
if
(
ret
<
0
)
{
dev_err
(
tps
->
dev
,
"%s() Err: Init fails with = %d
\n
"
,
__func__
,
ret
);
goto
err_init
;
}
/* Register the regulators */
rdev
=
regulator_register
(
&
tps
->
desc
,
&
client
->
dev
,
&
pdata
->
reg_init_data
,
tps
,
NULL
);
if
(
IS_ERR
(
rdev
))
{
dev_err
(
tps
->
dev
,
"%s() Err: Failed to register %s
\n
"
,
__func__
,
id
->
name
);
ret
=
PTR_ERR
(
rdev
);
goto
err_init
;
}
tps
->
rdev
=
rdev
;
return
0
;
err_init:
if
(
gpio_is_valid
(
tps
->
vsel1_gpio
))
gpio_free
(
tps
->
vsel1_gpio
);
err_gpio1:
if
(
gpio_is_valid
(
tps
->
vsel0_gpio
))
gpio_free
(
tps
->
vsel0_gpio
);
err_gpio0:
regmap_exit
(
tps
->
regmap
);
return
ret
;
}
/**
* tps62360_remove - tps62360 driver i2c remove handler
* @client: i2c driver client device structure
*
* Unregister TPS driver as an i2c client device driver
*/
static
int
__devexit
tps62360_remove
(
struct
i2c_client
*
client
)
{
struct
tps62360_chip
*
tps
=
i2c_get_clientdata
(
client
);
if
(
gpio_is_valid
(
tps
->
vsel1_gpio
))
gpio_free
(
tps
->
vsel1_gpio
);
if
(
gpio_is_valid
(
tps
->
vsel0_gpio
))
gpio_free
(
tps
->
vsel0_gpio
);
regulator_unregister
(
tps
->
rdev
);
regmap_exit
(
tps
->
regmap
);
return
0
;
}
static
void
tps62360_shutdown
(
struct
i2c_client
*
client
)
{
struct
tps62360_chip
*
tps
=
i2c_get_clientdata
(
client
);
int
st
;
if
(
!
tps
->
en_discharge
)
return
;
/* Configure the output discharge path */
st
=
regmap_update_bits
(
tps
->
regmap
,
REG_RAMPCTRL
,
BIT
(
2
),
BIT
(
2
));
if
(
st
<
0
)
dev_err
(
tps
->
dev
,
"%s() fails in updating reg %d
\n
"
,
__func__
,
REG_RAMPCTRL
);
}
static
const
struct
i2c_device_id
tps62360_id
[]
=
{
{.
name
=
"tps62360"
,
.
driver_data
=
TPS62360
},
{.
name
=
"tps62361"
,
.
driver_data
=
TPS62361
},
{},
};
MODULE_DEVICE_TABLE
(
i2c
,
tps62360_id
);
static
struct
i2c_driver
tps62360_i2c_driver
=
{
.
driver
=
{
.
name
=
"tps62360"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
tps62360_probe
,
.
remove
=
__devexit_p
(
tps62360_remove
),
.
shutdown
=
tps62360_shutdown
,
.
id_table
=
tps62360_id
,
};
static
int
__init
tps62360_init
(
void
)
{
return
i2c_add_driver
(
&
tps62360_i2c_driver
);
}
subsys_initcall
(
tps62360_init
);
static
void
__exit
tps62360_cleanup
(
void
)
{
i2c_del_driver
(
&
tps62360_i2c_driver
);
}
module_exit
(
tps62360_cleanup
);
MODULE_AUTHOR
(
"Laxman Dewangan <ldewangan@nvidia.com>"
);
MODULE_DESCRIPTION
(
"TPS62360 voltage regulator driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/regulator/tps65023-regulator.c
View file @
63236f40
...
...
@@ -487,10 +487,6 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
i2c_set_clientdata
(
client
,
tps
);
/* Enable setting output voltage by I2C */
regmap_update_bits
(
tps
->
regmap
,
TPS65023_REG_CON_CTRL2
,
TPS65023_REG_CTRL2_CORE_ADJ
,
TPS65023_REG_CTRL2_CORE_ADJ
);
/* Enable setting output voltage by I2C */
regmap_update_bits
(
tps
->
regmap
,
TPS65023_REG_CON_CTRL2
,
TPS65023_REG_CTRL2_CORE_ADJ
,
TPS65023_REG_CTRL2_CORE_ADJ
);
...
...
drivers/regulator/tps6507x-regulator.c
View file @
63236f40
...
...
@@ -238,16 +238,16 @@ static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val)
return
err
;
}
static
int
tps6507x_pmic_
dcdc_
is_enabled
(
struct
regulator_dev
*
dev
)
static
int
tps6507x_pmic_is_enabled
(
struct
regulator_dev
*
dev
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
data
,
dcdc
=
rdev_get_id
(
dev
);
int
data
,
rid
=
rdev_get_id
(
dev
);
u8
shift
;
if
(
dcdc
<
TPS6507X_DCDC_1
||
dcdc
>
TPS6507X_DCDC_3
)
if
(
rid
<
TPS6507X_DCDC_1
||
rid
>
TPS6507X_LDO_2
)
return
-
EINVAL
;
shift
=
TPS6507X_MAX_REG_ID
-
dcdc
;
shift
=
TPS6507X_MAX_REG_ID
-
rid
;
data
=
tps6507x_pmic_reg_read
(
tps
,
TPS6507X_REG_CON_CTRL1
);
if
(
data
<
0
)
...
...
@@ -256,99 +256,65 @@ static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev)
return
(
data
&
1
<<
shift
)
?
1
:
0
;
}
static
int
tps6507x_pmic_
ldo_is_enabled
(
struct
regulator_dev
*
dev
)
static
int
tps6507x_pmic_
enable
(
struct
regulator_dev
*
dev
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
data
,
ldo
=
rdev_get_id
(
dev
);
int
rid
=
rdev_get_id
(
dev
);
u8
shift
;
if
(
ldo
<
TPS6507X_LDO_1
||
ldo
>
TPS6507X_LDO_2
)
if
(
rid
<
TPS6507X_DCDC_1
||
rid
>
TPS6507X_LDO_2
)
return
-
EINVAL
;
shift
=
TPS6507X_MAX_REG_ID
-
ldo
;
data
=
tps6507x_pmic_reg_read
(
tps
,
TPS6507X_REG_CON_CTRL1
);
if
(
data
<
0
)
return
data
;
else
return
(
data
&
1
<<
shift
)
?
1
:
0
;
}
static
int
tps6507x_pmic_dcdc_enable
(
struct
regulator_dev
*
dev
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
dcdc
=
rdev_get_id
(
dev
);
u8
shift
;
if
(
dcdc
<
TPS6507X_DCDC_1
||
dcdc
>
TPS6507X_DCDC_3
)
return
-
EINVAL
;
shift
=
TPS6507X_MAX_REG_ID
-
dcdc
;
return
tps6507x_pmic_set_bits
(
tps
,
TPS6507X_REG_CON_CTRL1
,
1
<<
shift
);
}
static
int
tps6507x_pmic_dcdc_disable
(
struct
regulator_dev
*
dev
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
dcdc
=
rdev_get_id
(
dev
);
u8
shift
;
if
(
dcdc
<
TPS6507X_DCDC_1
||
dcdc
>
TPS6507X_DCDC_3
)
return
-
EINVAL
;
shift
=
TPS6507X_MAX_REG_ID
-
dcdc
;
return
tps6507x_pmic_clear_bits
(
tps
,
TPS6507X_REG_CON_CTRL1
,
1
<<
shift
);
}
static
int
tps6507x_pmic_ldo_enable
(
struct
regulator_dev
*
dev
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
ldo
=
rdev_get_id
(
dev
);
u8
shift
;
if
(
ldo
<
TPS6507X_LDO_1
||
ldo
>
TPS6507X_LDO_2
)
return
-
EINVAL
;
shift
=
TPS6507X_MAX_REG_ID
-
ldo
;
shift
=
TPS6507X_MAX_REG_ID
-
rid
;
return
tps6507x_pmic_set_bits
(
tps
,
TPS6507X_REG_CON_CTRL1
,
1
<<
shift
);
}
static
int
tps6507x_pmic_
ldo_
disable
(
struct
regulator_dev
*
dev
)
static
int
tps6507x_pmic_disable
(
struct
regulator_dev
*
dev
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
ldo
=
rdev_get_id
(
dev
);
int
rid
=
rdev_get_id
(
dev
);
u8
shift
;
if
(
ldo
<
TPS6507X_LDO_1
||
ldo
>
TPS6507X_LDO_2
)
if
(
rid
<
TPS6507X_DCDC_1
||
rid
>
TPS6507X_LDO_2
)
return
-
EINVAL
;
shift
=
TPS6507X_MAX_REG_ID
-
ldo
;
shift
=
TPS6507X_MAX_REG_ID
-
rid
;
return
tps6507x_pmic_clear_bits
(
tps
,
TPS6507X_REG_CON_CTRL1
,
1
<<
shift
);
}
static
int
tps6507x_pmic_
dcdc_
get_voltage
(
struct
regulator_dev
*
dev
)
static
int
tps6507x_pmic_get_voltage
(
struct
regulator_dev
*
dev
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
data
,
dcdc
=
rdev_get_id
(
dev
);
u8
reg
;
int
data
,
rid
=
rdev_get_id
(
dev
);
u8
reg
,
mask
;
switch
(
dcdc
)
{
switch
(
rid
)
{
case
TPS6507X_DCDC_1
:
reg
=
TPS6507X_REG_DEFDCDC1
;
mask
=
TPS6507X_DEFDCDCX_DCDC_MASK
;
break
;
case
TPS6507X_DCDC_2
:
if
(
tps
->
info
[
dcdc
]
->
defdcdc_default
)
if
(
tps
->
info
[
rid
]
->
defdcdc_default
)
reg
=
TPS6507X_REG_DEFDCDC2_HIGH
;
else
reg
=
TPS6507X_REG_DEFDCDC2_LOW
;
mask
=
TPS6507X_DEFDCDCX_DCDC_MASK
;
break
;
case
TPS6507X_DCDC_3
:
if
(
tps
->
info
[
dcdc
]
->
defdcdc_default
)
if
(
tps
->
info
[
rid
]
->
defdcdc_default
)
reg
=
TPS6507X_REG_DEFDCDC3_HIGH
;
else
reg
=
TPS6507X_REG_DEFDCDC3_LOW
;
mask
=
TPS6507X_DEFDCDCX_DCDC_MASK
;
break
;
case
TPS6507X_LDO_1
:
reg
=
TPS6507X_REG_LDO_CTRL1
;
mask
=
TPS6507X_REG_LDO_CTRL1_LDO1_MASK
;
break
;
case
TPS6507X_LDO_2
:
reg
=
TPS6507X_REG_DEFLDO2
;
mask
=
TPS6507X_REG_DEFLDO2_LDO2_MASK
;
break
;
default:
return
-
EINVAL
;
...
...
@@ -358,193 +324,83 @@ static int tps6507x_pmic_dcdc_get_voltage(struct regulator_dev *dev)
if
(
data
<
0
)
return
data
;
data
&=
TPS6507X_DEFDCDCX_DCDC_MASK
;
return
tps
->
info
[
dcdc
]
->
table
[
data
]
*
1000
;
data
&=
mask
;
return
tps
->
info
[
rid
]
->
table
[
data
]
*
1000
;
}
static
int
tps6507x_pmic_dcdc_set_voltage
(
struct
regulator_dev
*
dev
,
int
min_uV
,
int
max_uV
,
unsigned
*
selector
)
static
int
tps6507x_pmic_set_voltage_sel
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
data
,
vsel
,
dcdc
=
rdev_get_id
(
dev
);
u8
reg
;
int
data
,
rid
=
rdev_get_id
(
dev
);
u8
reg
,
mask
;
switch
(
dcdc
)
{
switch
(
rid
)
{
case
TPS6507X_DCDC_1
:
reg
=
TPS6507X_REG_DEFDCDC1
;
mask
=
TPS6507X_DEFDCDCX_DCDC_MASK
;
break
;
case
TPS6507X_DCDC_2
:
if
(
tps
->
info
[
dcdc
]
->
defdcdc_default
)
if
(
tps
->
info
[
rid
]
->
defdcdc_default
)
reg
=
TPS6507X_REG_DEFDCDC2_HIGH
;
else
reg
=
TPS6507X_REG_DEFDCDC2_LOW
;
mask
=
TPS6507X_DEFDCDCX_DCDC_MASK
;
break
;
case
TPS6507X_DCDC_3
:
if
(
tps
->
info
[
dcdc
]
->
defdcdc_default
)
if
(
tps
->
info
[
rid
]
->
defdcdc_default
)
reg
=
TPS6507X_REG_DEFDCDC3_HIGH
;
else
reg
=
TPS6507X_REG_DEFDCDC3_LOW
;
mask
=
TPS6507X_DEFDCDCX_DCDC_MASK
;
break
;
case
TPS6507X_LDO_1
:
reg
=
TPS6507X_REG_LDO_CTRL1
;
mask
=
TPS6507X_REG_LDO_CTRL1_LDO1_MASK
;
break
;
case
TPS6507X_LDO_2
:
reg
=
TPS6507X_REG_DEFLDO2
;
mask
=
TPS6507X_REG_DEFLDO2_LDO2_MASK
;
break
;
default:
return
-
EINVAL
;
}
if
(
min_uV
<
tps
->
info
[
dcdc
]
->
min_uV
||
min_uV
>
tps
->
info
[
dcdc
]
->
max_uV
)
return
-
EINVAL
;
if
(
max_uV
<
tps
->
info
[
dcdc
]
->
min_uV
||
max_uV
>
tps
->
info
[
dcdc
]
->
max_uV
)
return
-
EINVAL
;
for
(
vsel
=
0
;
vsel
<
tps
->
info
[
dcdc
]
->
table_len
;
vsel
++
)
{
int
mV
=
tps
->
info
[
dcdc
]
->
table
[
vsel
];
int
uV
=
mV
*
1000
;
/* Break at the first in-range value */
if
(
min_uV
<=
uV
&&
uV
<=
max_uV
)
break
;
}
/* write to the register in case we found a match */
if
(
vsel
==
tps
->
info
[
dcdc
]
->
table_len
)
return
-
EINVAL
;
*
selector
=
vsel
;
data
=
tps6507x_pmic_reg_read
(
tps
,
reg
);
if
(
data
<
0
)
return
data
;
data
&=
~
TPS6507X_DEFDCDCX_DCDC_MASK
;
data
|=
vsel
;
return
tps6507x_pmic_reg_write
(
tps
,
reg
,
data
);
}
static
int
tps6507x_pmic_ldo_get_voltage
(
struct
regulator_dev
*
dev
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
data
,
ldo
=
rdev_get_id
(
dev
);
u8
reg
,
mask
;
if
(
ldo
<
TPS6507X_LDO_1
||
ldo
>
TPS6507X_LDO_2
)
return
-
EINVAL
;
else
{
reg
=
(
ldo
==
TPS6507X_LDO_1
?
TPS6507X_REG_LDO_CTRL1
:
TPS6507X_REG_DEFLDO2
);
mask
=
(
ldo
==
TPS6507X_LDO_1
?
TPS6507X_REG_LDO_CTRL1_LDO1_MASK
:
TPS6507X_REG_DEFLDO2_LDO2_MASK
);
}
data
=
tps6507x_pmic_reg_read
(
tps
,
reg
);
if
(
data
<
0
)
return
data
;
data
&=
mask
;
return
tps
->
info
[
ldo
]
->
table
[
data
]
*
1000
;
}
static
int
tps6507x_pmic_ldo_set_voltage
(
struct
regulator_dev
*
dev
,
int
min_uV
,
int
max_uV
,
unsigned
*
selector
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
data
,
vsel
,
ldo
=
rdev_get_id
(
dev
);
u8
reg
,
mask
;
if
(
ldo
<
TPS6507X_LDO_1
||
ldo
>
TPS6507X_LDO_2
)
return
-
EINVAL
;
else
{
reg
=
(
ldo
==
TPS6507X_LDO_1
?
TPS6507X_REG_LDO_CTRL1
:
TPS6507X_REG_DEFLDO2
);
mask
=
(
ldo
==
TPS6507X_LDO_1
?
TPS6507X_REG_LDO_CTRL1_LDO1_MASK
:
TPS6507X_REG_DEFLDO2_LDO2_MASK
);
}
if
(
min_uV
<
tps
->
info
[
ldo
]
->
min_uV
||
min_uV
>
tps
->
info
[
ldo
]
->
max_uV
)
return
-
EINVAL
;
if
(
max_uV
<
tps
->
info
[
ldo
]
->
min_uV
||
max_uV
>
tps
->
info
[
ldo
]
->
max_uV
)
return
-
EINVAL
;
for
(
vsel
=
0
;
vsel
<
tps
->
info
[
ldo
]
->
table_len
;
vsel
++
)
{
int
mV
=
tps
->
info
[
ldo
]
->
table
[
vsel
];
int
uV
=
mV
*
1000
;
/* Break at the first in-range value */
if
(
min_uV
<=
uV
&&
uV
<=
max_uV
)
break
;
}
if
(
vsel
==
tps
->
info
[
ldo
]
->
table_len
)
return
-
EINVAL
;
*
selector
=
vsel
;
data
=
tps6507x_pmic_reg_read
(
tps
,
reg
);
if
(
data
<
0
)
return
data
;
data
&=
~
mask
;
data
|=
vsel
;
data
|=
selector
;
return
tps6507x_pmic_reg_write
(
tps
,
reg
,
data
);
}
static
int
tps6507x_pmic_
dcdc_
list_voltage
(
struct
regulator_dev
*
dev
,
static
int
tps6507x_pmic_list_voltage
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
dcdc
=
rdev_get_id
(
dev
);
int
rid
=
rdev_get_id
(
dev
);
if
(
dcdc
<
TPS6507X_DCDC_1
||
dcdc
>
TPS6507X_DCDC_3
)
if
(
rid
<
TPS6507X_DCDC_1
||
rid
>
TPS6507X_LDO_2
)
return
-
EINVAL
;
if
(
selector
>=
tps
->
info
[
dcdc
]
->
table_len
)
if
(
selector
>=
tps
->
info
[
rid
]
->
table_len
)
return
-
EINVAL
;
else
return
tps
->
info
[
dcdc
]
->
table
[
selector
]
*
1000
;
return
tps
->
info
[
rid
]
->
table
[
selector
]
*
1000
;
}
static
int
tps6507x_pmic_ldo_list_voltage
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps6507x_pmic
*
tps
=
rdev_get_drvdata
(
dev
);
int
ldo
=
rdev_get_id
(
dev
);
if
(
ldo
<
TPS6507X_LDO_1
||
ldo
>
TPS6507X_LDO_2
)
return
-
EINVAL
;
if
(
selector
>=
tps
->
info
[
ldo
]
->
table_len
)
return
-
EINVAL
;
else
return
tps
->
info
[
ldo
]
->
table
[
selector
]
*
1000
;
}
/* Operations permitted on VDCDCx */
static
struct
regulator_ops
tps6507x_pmic_dcdc_ops
=
{
.
is_enabled
=
tps6507x_pmic_dcdc_is_enabled
,
.
enable
=
tps6507x_pmic_dcdc_enable
,
.
disable
=
tps6507x_pmic_dcdc_disable
,
.
get_voltage
=
tps6507x_pmic_dcdc_get_voltage
,
.
set_voltage
=
tps6507x_pmic_dcdc_set_voltage
,
.
list_voltage
=
tps6507x_pmic_dcdc_list_voltage
,
static
struct
regulator_ops
tps6507x_pmic_ops
=
{
.
is_enabled
=
tps6507x_pmic_is_enabled
,
.
enable
=
tps6507x_pmic_enable
,
.
disable
=
tps6507x_pmic_disable
,
.
get_voltage
=
tps6507x_pmic_get_voltage
,
.
set_voltage_sel
=
tps6507x_pmic_set_voltage_sel
,
.
list_voltage
=
tps6507x_pmic_list_voltage
,
};
/* Operations permitted on LDOx */
static
struct
regulator_ops
tps6507x_pmic_ldo_ops
=
{
.
is_enabled
=
tps6507x_pmic_ldo_is_enabled
,
.
enable
=
tps6507x_pmic_ldo_enable
,
.
disable
=
tps6507x_pmic_ldo_disable
,
.
get_voltage
=
tps6507x_pmic_ldo_get_voltage
,
.
set_voltage
=
tps6507x_pmic_ldo_set_voltage
,
.
list_voltage
=
tps6507x_pmic_ldo_list_voltage
,
};
static
__devinit
int
tps6507x_pmic_probe
(
struct
platform_device
*
pdev
)
static
__devinit
int
tps6507x_pmic_probe
(
struct
platform_device
*
pdev
)
{
struct
tps6507x_dev
*
tps6507x_dev
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
tps_info
*
info
=
&
tps6507x_pmic_regs
[
0
];
...
...
@@ -593,8 +449,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev)
tps
->
desc
[
i
].
name
=
info
->
name
;
tps
->
desc
[
i
].
id
=
i
;
tps
->
desc
[
i
].
n_voltages
=
info
->
table_len
;
tps
->
desc
[
i
].
ops
=
(
i
>
TPS6507X_DCDC_3
?
&
tps6507x_pmic_ldo_ops
:
&
tps6507x_pmic_dcdc_ops
);
tps
->
desc
[
i
].
ops
=
&
tps6507x_pmic_ops
;
tps
->
desc
[
i
].
type
=
REGULATOR_VOLTAGE
;
tps
->
desc
[
i
].
owner
=
THIS_MODULE
;
...
...
@@ -648,22 +503,12 @@ static struct platform_driver tps6507x_pmic_driver = {
.
remove
=
__devexit_p
(
tps6507x_pmic_remove
),
};
/**
* tps6507x_pmic_init
*
* Module init function
*/
static
int
__init
tps6507x_pmic_init
(
void
)
{
return
platform_driver_register
(
&
tps6507x_pmic_driver
);
}
subsys_initcall
(
tps6507x_pmic_init
);
/**
* tps6507x_pmic_cleanup
*
* Module exit function
*/
static
void
__exit
tps6507x_pmic_cleanup
(
void
)
{
platform_driver_unregister
(
&
tps6507x_pmic_driver
);
...
...
drivers/regulator/tps65217-regulator.c
0 → 100644
View file @
63236f40
/*
* tps65217-regulator.c
*
* Regulator driver for TPS65217 PMIC
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/tps65217.h>
#define TPS65217_REGULATOR(_name, _id, _ops, _n) \
{ \
.name = _name, \
.id = _id, \
.ops = &_ops, \
.n_voltages = _n, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
} \
#define TPS65217_INFO(_nm, _min, _max, _f1, _f2, _t, _n, _em, _vr, _vm) \
{ \
.name = _nm, \
.min_uV = _min, \
.max_uV = _max, \
.vsel_to_uv = _f1, \
.uv_to_vsel = _f2, \
.table = _t, \
.table_len = _n, \
.enable_mask = _em, \
.set_vout_reg = _vr, \
.set_vout_mask = _vm, \
}
static
const
int
LDO1_VSEL_table
[]
=
{
1000000
,
1100000
,
1200000
,
1250000
,
1300000
,
1350000
,
1400000
,
1500000
,
1600000
,
1800000
,
2500000
,
2750000
,
2800000
,
3000000
,
3100000
,
3300000
,
};
static
int
tps65217_vsel_to_uv1
(
unsigned
int
vsel
)
{
int
uV
=
0
;
if
(
vsel
>
63
)
return
-
EINVAL
;
if
(
vsel
<=
24
)
uV
=
vsel
*
25000
+
900000
;
else
if
(
vsel
<=
52
)
uV
=
(
vsel
-
24
)
*
50000
+
1500000
;
else
if
(
vsel
<
56
)
uV
=
(
vsel
-
52
)
*
100000
+
2900000
;
else
uV
=
3300000
;
return
uV
;
}
static
int
tps65217_uv_to_vsel1
(
int
uV
,
unsigned
int
*
vsel
)
{
if
((
uV
<
0
)
&&
(
uV
>
3300000
))
return
-
EINVAL
;
if
(
uV
<=
1500000
)
*
vsel
=
DIV_ROUND_UP
(
uV
-
900000
,
25000
);
else
if
(
uV
<=
2900000
)
*
vsel
=
24
+
DIV_ROUND_UP
(
uV
-
1500000
,
50000
);
else
if
(
uV
<
3300000
)
*
vsel
=
52
+
DIV_ROUND_UP
(
uV
-
2900000
,
100000
);
else
*
vsel
=
56
;
return
0
;
}
static
int
tps65217_vsel_to_uv2
(
unsigned
int
vsel
)
{
int
uV
=
0
;
if
(
vsel
>
31
)
return
-
EINVAL
;
if
(
vsel
<=
8
)
uV
=
vsel
*
50000
+
1500000
;
else
if
(
vsel
<=
13
)
uV
=
(
vsel
-
8
)
*
100000
+
1900000
;
else
uV
=
(
vsel
-
13
)
*
50000
+
2400000
;
return
uV
;
}
static
int
tps65217_uv_to_vsel2
(
int
uV
,
unsigned
int
*
vsel
)
{
if
((
uV
<
0
)
&&
(
uV
>
3300000
))
return
-
EINVAL
;
if
(
uV
<=
1900000
)
*
vsel
=
DIV_ROUND_UP
(
uV
-
1500000
,
50000
);
else
if
(
uV
<=
2400000
)
*
vsel
=
8
+
DIV_ROUND_UP
(
uV
-
1900000
,
100000
);
else
*
vsel
=
13
+
DIV_ROUND_UP
(
uV
-
2400000
,
50000
);
return
0
;
}
static
struct
tps_info
tps65217_pmic_regs
[]
=
{
TPS65217_INFO
(
"DCDC1"
,
900000
,
1800000
,
tps65217_vsel_to_uv1
,
tps65217_uv_to_vsel1
,
NULL
,
64
,
TPS65217_ENABLE_DC1_EN
,
TPS65217_REG_DEFDCDC1
,
TPS65217_DEFDCDCX_DCDC_MASK
),
TPS65217_INFO
(
"DCDC2"
,
900000
,
3300000
,
tps65217_vsel_to_uv1
,
tps65217_uv_to_vsel1
,
NULL
,
64
,
TPS65217_ENABLE_DC2_EN
,
TPS65217_REG_DEFDCDC2
,
TPS65217_DEFDCDCX_DCDC_MASK
),
TPS65217_INFO
(
"DCDC3"
,
900000
,
1500000
,
tps65217_vsel_to_uv1
,
tps65217_uv_to_vsel1
,
NULL
,
64
,
TPS65217_ENABLE_DC3_EN
,
TPS65217_REG_DEFDCDC3
,
TPS65217_DEFDCDCX_DCDC_MASK
),
TPS65217_INFO
(
"LDO1"
,
1000000
,
3300000
,
NULL
,
NULL
,
LDO1_VSEL_table
,
16
,
TPS65217_ENABLE_LDO1_EN
,
TPS65217_REG_DEFLDO1
,
TPS65217_DEFLDO1_LDO1_MASK
),
TPS65217_INFO
(
"LDO2"
,
900000
,
3300000
,
tps65217_vsel_to_uv1
,
tps65217_uv_to_vsel1
,
NULL
,
64
,
TPS65217_ENABLE_LDO2_EN
,
TPS65217_REG_DEFLDO2
,
TPS65217_DEFLDO2_LDO2_MASK
),
TPS65217_INFO
(
"LDO3"
,
1800000
,
3300000
,
tps65217_vsel_to_uv2
,
tps65217_uv_to_vsel2
,
NULL
,
32
,
TPS65217_ENABLE_LS1_EN
|
TPS65217_DEFLDO3_LDO3_EN
,
TPS65217_REG_DEFLS1
,
TPS65217_DEFLDO3_LDO3_MASK
),
TPS65217_INFO
(
"LDO4"
,
1800000
,
3300000
,
tps65217_vsel_to_uv2
,
tps65217_uv_to_vsel2
,
NULL
,
32
,
TPS65217_ENABLE_LS2_EN
|
TPS65217_DEFLDO4_LDO4_EN
,
TPS65217_REG_DEFLS2
,
TPS65217_DEFLDO4_LDO4_MASK
),
};
static
int
tps65217_pmic_is_enabled
(
struct
regulator_dev
*
dev
)
{
int
ret
;
struct
tps65217
*
tps
=
rdev_get_drvdata
(
dev
);
unsigned
int
data
,
rid
=
rdev_get_id
(
dev
);
if
(
rid
<
TPS65217_DCDC_1
||
rid
>
TPS65217_LDO_4
)
return
-
EINVAL
;
ret
=
tps65217_reg_read
(
tps
,
TPS65217_REG_ENABLE
,
&
data
);
if
(
ret
)
return
ret
;
return
(
data
&
tps
->
info
[
rid
]
->
enable_mask
)
?
1
:
0
;
}
static
int
tps65217_pmic_enable
(
struct
regulator_dev
*
dev
)
{
struct
tps65217
*
tps
=
rdev_get_drvdata
(
dev
);
unsigned
int
rid
=
rdev_get_id
(
dev
);
if
(
rid
<
TPS65217_DCDC_1
||
rid
>
TPS65217_LDO_4
)
return
-
EINVAL
;
/* Enable the regulator and password protection is level 1 */
return
tps65217_set_bits
(
tps
,
TPS65217_REG_ENABLE
,
tps
->
info
[
rid
]
->
enable_mask
,
tps
->
info
[
rid
]
->
enable_mask
,
TPS65217_PROTECT_L1
);
}
static
int
tps65217_pmic_disable
(
struct
regulator_dev
*
dev
)
{
struct
tps65217
*
tps
=
rdev_get_drvdata
(
dev
);
unsigned
int
rid
=
rdev_get_id
(
dev
);
if
(
rid
<
TPS65217_DCDC_1
||
rid
>
TPS65217_LDO_4
)
return
-
EINVAL
;
/* Disable the regulator and password protection is level 1 */
return
tps65217_clear_bits
(
tps
,
TPS65217_REG_ENABLE
,
tps
->
info
[
rid
]
->
enable_mask
,
TPS65217_PROTECT_L1
);
}
static
int
tps65217_pmic_get_voltage_sel
(
struct
regulator_dev
*
dev
)
{
int
ret
;
struct
tps65217
*
tps
=
rdev_get_drvdata
(
dev
);
unsigned
int
selector
,
rid
=
rdev_get_id
(
dev
);
if
(
rid
<
TPS65217_DCDC_1
||
rid
>
TPS65217_LDO_4
)
return
-
EINVAL
;
ret
=
tps65217_reg_read
(
tps
,
tps
->
info
[
rid
]
->
set_vout_reg
,
&
selector
);
if
(
ret
)
return
ret
;
selector
&=
tps
->
info
[
rid
]
->
set_vout_mask
;
return
selector
;
}
static
int
tps65217_pmic_ldo1_set_voltage_sel
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps65217
*
tps
=
rdev_get_drvdata
(
dev
);
int
ldo
=
rdev_get_id
(
dev
);
if
(
ldo
!=
TPS65217_LDO_1
)
return
-
EINVAL
;
if
(
selector
>=
tps
->
info
[
ldo
]
->
table_len
)
return
-
EINVAL
;
/* Set the voltage based on vsel value and write protect level is 2 */
return
tps65217_set_bits
(
tps
,
tps
->
info
[
ldo
]
->
set_vout_reg
,
tps
->
info
[
ldo
]
->
set_vout_mask
,
selector
,
TPS65217_PROTECT_L2
);
}
static
int
tps65217_pmic_set_voltage
(
struct
regulator_dev
*
dev
,
int
min_uV
,
int
max_uV
,
unsigned
*
selector
)
{
int
ret
;
struct
tps65217
*
tps
=
rdev_get_drvdata
(
dev
);
unsigned
int
rid
=
rdev_get_id
(
dev
);
/* LDO1 implements set_voltage_sel callback */
if
(
rid
==
TPS65217_LDO_1
)
return
-
EINVAL
;
if
(
rid
<
TPS65217_DCDC_1
||
rid
>
TPS65217_LDO_4
)
return
-
EINVAL
;
if
(
min_uV
<
tps
->
info
[
rid
]
->
min_uV
||
min_uV
>
tps
->
info
[
rid
]
->
max_uV
)
return
-
EINVAL
;
if
(
max_uV
<
tps
->
info
[
rid
]
->
min_uV
||
max_uV
>
tps
->
info
[
rid
]
->
max_uV
)
return
-
EINVAL
;
ret
=
tps
->
info
[
rid
]
->
uv_to_vsel
(
min_uV
,
selector
);
if
(
ret
)
return
ret
;
/* Set the voltage based on vsel value and write protect level is 2 */
ret
=
tps65217_set_bits
(
tps
,
tps
->
info
[
rid
]
->
set_vout_reg
,
tps
->
info
[
rid
]
->
set_vout_mask
,
*
selector
,
TPS65217_PROTECT_L2
);
/* Set GO bit for DCDCx to initiate voltage transistion */
switch
(
rid
)
{
case
TPS65217_DCDC_1
...
TPS65217_DCDC_3
:
ret
=
tps65217_set_bits
(
tps
,
TPS65217_REG_DEFSLEW
,
TPS65217_DEFSLEW_GO
,
TPS65217_DEFSLEW_GO
,
TPS65217_PROTECT_L2
);
break
;
}
return
ret
;
}
static
int
tps65217_pmic_list_voltage
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps65217
*
tps
=
rdev_get_drvdata
(
dev
);
unsigned
int
rid
=
rdev_get_id
(
dev
);
if
(
rid
<
TPS65217_DCDC_1
||
rid
>
TPS65217_LDO_4
)
return
-
EINVAL
;
if
(
selector
>=
tps
->
info
[
rid
]
->
table_len
)
return
-
EINVAL
;
if
(
tps
->
info
[
rid
]
->
table
)
return
tps
->
info
[
rid
]
->
table
[
selector
];
return
tps
->
info
[
rid
]
->
vsel_to_uv
(
selector
);
}
/* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */
static
struct
regulator_ops
tps65217_pmic_ops
=
{
.
is_enabled
=
tps65217_pmic_is_enabled
,
.
enable
=
tps65217_pmic_enable
,
.
disable
=
tps65217_pmic_disable
,
.
get_voltage_sel
=
tps65217_pmic_get_voltage_sel
,
.
set_voltage
=
tps65217_pmic_set_voltage
,
.
list_voltage
=
tps65217_pmic_list_voltage
,
};
/* Operations permitted on LDO1 */
static
struct
regulator_ops
tps65217_pmic_ldo1_ops
=
{
.
is_enabled
=
tps65217_pmic_is_enabled
,
.
enable
=
tps65217_pmic_enable
,
.
disable
=
tps65217_pmic_disable
,
.
get_voltage_sel
=
tps65217_pmic_get_voltage_sel
,
.
set_voltage_sel
=
tps65217_pmic_ldo1_set_voltage_sel
,
.
list_voltage
=
tps65217_pmic_list_voltage
,
};
static
struct
regulator_desc
regulators
[]
=
{
TPS65217_REGULATOR
(
"DCDC1"
,
TPS65217_DCDC_1
,
tps65217_pmic_ops
,
64
),
TPS65217_REGULATOR
(
"DCDC2"
,
TPS65217_DCDC_2
,
tps65217_pmic_ops
,
64
),
TPS65217_REGULATOR
(
"DCDC3"
,
TPS65217_DCDC_3
,
tps65217_pmic_ops
,
64
),
TPS65217_REGULATOR
(
"LDO1"
,
TPS65217_LDO_1
,
tps65217_pmic_ldo1_ops
,
16
),
TPS65217_REGULATOR
(
"LDO2"
,
TPS65217_LDO_2
,
tps65217_pmic_ops
,
64
),
TPS65217_REGULATOR
(
"LDO3"
,
TPS65217_LDO_3
,
tps65217_pmic_ops
,
32
),
TPS65217_REGULATOR
(
"LDO4"
,
TPS65217_LDO_4
,
tps65217_pmic_ops
,
32
),
};
static
int
__devinit
tps65217_regulator_probe
(
struct
platform_device
*
pdev
)
{
struct
regulator_dev
*
rdev
;
struct
tps65217
*
tps
;
struct
tps_info
*
info
=
&
tps65217_pmic_regs
[
pdev
->
id
];
/* Already set by core driver */
tps
=
dev_to_tps65217
(
pdev
->
dev
.
parent
);
tps
->
info
[
pdev
->
id
]
=
info
;
rdev
=
regulator_register
(
&
regulators
[
pdev
->
id
],
&
pdev
->
dev
,
pdev
->
dev
.
platform_data
,
tps
,
NULL
);
if
(
IS_ERR
(
rdev
))
return
PTR_ERR
(
rdev
);
platform_set_drvdata
(
pdev
,
rdev
);
return
0
;
}
static
int
__devexit
tps65217_regulator_remove
(
struct
platform_device
*
pdev
)
{
struct
regulator_dev
*
rdev
=
platform_get_drvdata
(
pdev
);
platform_set_drvdata
(
pdev
,
NULL
);
regulator_unregister
(
rdev
);
return
0
;
}
static
struct
platform_driver
tps65217_regulator_driver
=
{
.
driver
=
{
.
name
=
"tps65217-pmic"
,
},
.
probe
=
tps65217_regulator_probe
,
.
remove
=
__devexit_p
(
tps65217_regulator_remove
),
};
static
int
__init
tps65217_regulator_init
(
void
)
{
return
platform_driver_register
(
&
tps65217_regulator_driver
);
}
subsys_initcall
(
tps65217_regulator_init
);
static
void
__exit
tps65217_regulator_exit
(
void
)
{
platform_driver_unregister
(
&
tps65217_regulator_driver
);
}
module_exit
(
tps65217_regulator_exit
);
MODULE_AUTHOR
(
"AnilKumar Ch <anilkumar@ti.com>"
);
MODULE_DESCRIPTION
(
"TPS65217 voltage regulator driver"
);
MODULE_ALIAS
(
"platform:tps65217-pmic"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/regulator/tps6524x-regulator.c
View file @
63236f40
...
...
@@ -108,9 +108,7 @@
#define N_DCDC 3
#define N_LDO 2
#define N_SWITCH 2
#define N_REGULATORS (3
/* DCDC */
+ \
2
/* LDO */
+ \
2
/* switch */
)
#define N_REGULATORS (N_DCDC + N_LDO + N_SWITCH)
#define FIXED_ILIMSEL BIT(0)
#define FIXED_VOLTAGE BIT(1)
...
...
drivers/regulator/tps6586x-regulator.c
View file @
63236f40
...
...
@@ -383,7 +383,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
int
id
=
pdev
->
id
;
int
err
;
dev_dbg
(
&
pdev
->
dev
,
"Probing reulator %d
\n
"
,
id
);
dev_dbg
(
&
pdev
->
dev
,
"Probing re
g
ulator %d
\n
"
,
id
);
ri
=
find_regulator_info
(
id
);
if
(
ri
==
NULL
)
{
...
...
drivers/regulator/tps65910-regulator.c
View file @
63236f40
...
...
@@ -26,6 +26,10 @@
#include <linux/mfd/tps65910.h>
#define TPS65910_SUPPLY_STATE_ENABLED 0x1
#define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 | \
TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP)
/* supported VIO voltages in milivolts */
static
const
u16
VIO_VSEL_table
[]
=
{
...
...
@@ -83,161 +87,235 @@ struct tps_info {
const
char
*
name
;
unsigned
min_uV
;
unsigned
max_uV
;
u8
table_len
;
const
u16
*
table
;
u8
n_voltages
;
const
u16
*
voltage_table
;
int
enable_time_us
;
};
static
struct
tps_info
tps65910_regs
[]
=
{
{
.
name
=
"VRTC"
,
.
enable_time_us
=
2200
,
},
{
.
name
=
"VIO"
,
.
min_uV
=
1500000
,
.
max_uV
=
3300000
,
.
table_len
=
ARRAY_SIZE
(
VIO_VSEL_table
),
.
table
=
VIO_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VIO_VSEL_table
),
.
voltage_table
=
VIO_VSEL_table
,
.
enable_time_us
=
350
,
},
{
.
name
=
"VDD1"
,
.
min_uV
=
600000
,
.
max_uV
=
4500000
,
.
enable_time_us
=
350
,
},
{
.
name
=
"VDD2"
,
.
min_uV
=
600000
,
.
max_uV
=
4500000
,
.
enable_time_us
=
350
,
},
{
.
name
=
"VDD3"
,
.
min_uV
=
5000000
,
.
max_uV
=
5000000
,
.
table_len
=
ARRAY_SIZE
(
VDD3_VSEL_table
),
.
table
=
VDD3_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VDD3_VSEL_table
),
.
voltage_table
=
VDD3_VSEL_table
,
.
enable_time_us
=
200
,
},
{
.
name
=
"VDIG1"
,
.
min_uV
=
1200000
,
.
max_uV
=
2700000
,
.
table_len
=
ARRAY_SIZE
(
VDIG1_VSEL_table
),
.
table
=
VDIG1_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VDIG1_VSEL_table
),
.
voltage_table
=
VDIG1_VSEL_table
,
.
enable_time_us
=
100
,
},
{
.
name
=
"VDIG2"
,
.
min_uV
=
1000000
,
.
max_uV
=
1800000
,
.
table_len
=
ARRAY_SIZE
(
VDIG2_VSEL_table
),
.
table
=
VDIG2_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VDIG2_VSEL_table
),
.
voltage_table
=
VDIG2_VSEL_table
,
.
enable_time_us
=
100
,
},
{
.
name
=
"VPLL"
,
.
min_uV
=
1000000
,
.
max_uV
=
2500000
,
.
table_len
=
ARRAY_SIZE
(
VPLL_VSEL_table
),
.
table
=
VPLL_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VPLL_VSEL_table
),
.
voltage_table
=
VPLL_VSEL_table
,
.
enable_time_us
=
100
,
},
{
.
name
=
"VDAC"
,
.
min_uV
=
1800000
,
.
max_uV
=
2850000
,
.
table_len
=
ARRAY_SIZE
(
VDAC_VSEL_table
),
.
table
=
VDAC_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VDAC_VSEL_table
),
.
voltage_table
=
VDAC_VSEL_table
,
.
enable_time_us
=
100
,
},
{
.
name
=
"VAUX1"
,
.
min_uV
=
1800000
,
.
max_uV
=
2850000
,
.
table_len
=
ARRAY_SIZE
(
VAUX1_VSEL_table
),
.
table
=
VAUX1_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VAUX1_VSEL_table
),
.
voltage_table
=
VAUX1_VSEL_table
,
.
enable_time_us
=
100
,
},
{
.
name
=
"VAUX2"
,
.
min_uV
=
1800000
,
.
max_uV
=
3300000
,
.
table_len
=
ARRAY_SIZE
(
VAUX2_VSEL_table
),
.
table
=
VAUX2_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VAUX2_VSEL_table
),
.
voltage_table
=
VAUX2_VSEL_table
,
.
enable_time_us
=
100
,
},
{
.
name
=
"VAUX33"
,
.
min_uV
=
1800000
,
.
max_uV
=
3300000
,
.
table_len
=
ARRAY_SIZE
(
VAUX33_VSEL_table
),
.
table
=
VAUX33_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VAUX33_VSEL_table
),
.
voltage_table
=
VAUX33_VSEL_table
,
.
enable_time_us
=
100
,
},
{
.
name
=
"VMMC"
,
.
min_uV
=
1800000
,
.
max_uV
=
3300000
,
.
table_len
=
ARRAY_SIZE
(
VMMC_VSEL_table
),
.
table
=
VMMC_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VMMC_VSEL_table
),
.
voltage_table
=
VMMC_VSEL_table
,
.
enable_time_us
=
100
,
},
};
static
struct
tps_info
tps65911_regs
[]
=
{
{
.
name
=
"VRTC"
,
.
enable_time_us
=
2200
,
},
{
.
name
=
"VIO"
,
.
min_uV
=
1500000
,
.
max_uV
=
3300000
,
.
table_len
=
ARRAY_SIZE
(
VIO_VSEL_table
),
.
table
=
VIO_VSEL_table
,
.
n_voltages
=
ARRAY_SIZE
(
VIO_VSEL_table
),
.
voltage_table
=
VIO_VSEL_table
,
.
enable_time_us
=
350
,
},
{
.
name
=
"VDD1"
,
.
min_uV
=
600000
,
.
max_uV
=
4500000
,
.
n_voltages
=
73
,
.
enable_time_us
=
350
,
},
{
.
name
=
"VDD2"
,
.
min_uV
=
600000
,
.
max_uV
=
4500000
,
.
n_voltages
=
73
,
.
enable_time_us
=
350
,
},
{
.
name
=
"VDDCTRL"
,
.
min_uV
=
600000
,
.
max_uV
=
1400000
,
.
n_voltages
=
65
,
.
enable_time_us
=
900
,
},
{
.
name
=
"LDO1"
,
.
min_uV
=
1000000
,
.
max_uV
=
3300000
,
.
n_voltages
=
47
,
.
enable_time_us
=
420
,
},
{
.
name
=
"LDO2"
,
.
min_uV
=
1000000
,
.
max_uV
=
3300000
,
.
n_voltages
=
47
,
.
enable_time_us
=
420
,
},
{
.
name
=
"LDO3"
,
.
min_uV
=
1000000
,
.
max_uV
=
3300000
,
.
n_voltages
=
24
,
.
enable_time_us
=
230
,
},
{
.
name
=
"LDO4"
,
.
min_uV
=
1000000
,
.
max_uV
=
3300000
,
.
n_voltages
=
47
,
.
enable_time_us
=
230
,
},
{
.
name
=
"LDO5"
,
.
min_uV
=
1000000
,
.
max_uV
=
3300000
,
.
n_voltages
=
24
,
.
enable_time_us
=
230
,
},
{
.
name
=
"LDO6"
,
.
min_uV
=
1000000
,
.
max_uV
=
3300000
,
.
n_voltages
=
24
,
.
enable_time_us
=
230
,
},
{
.
name
=
"LDO7"
,
.
min_uV
=
1000000
,
.
max_uV
=
3300000
,
.
n_voltages
=
24
,
.
enable_time_us
=
230
,
},
{
.
name
=
"LDO8"
,
.
min_uV
=
1000000
,
.
max_uV
=
3300000
,
.
n_voltages
=
24
,
.
enable_time_us
=
230
,
},
};
#define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits))
static
unsigned
int
tps65910_ext_sleep_control
[]
=
{
0
,
EXT_CONTROL_REG_BITS
(
VIO
,
1
,
0
),
EXT_CONTROL_REG_BITS
(
VDD1
,
1
,
1
),
EXT_CONTROL_REG_BITS
(
VDD2
,
1
,
2
),
EXT_CONTROL_REG_BITS
(
VDD3
,
1
,
3
),
EXT_CONTROL_REG_BITS
(
VDIG1
,
0
,
1
),
EXT_CONTROL_REG_BITS
(
VDIG2
,
0
,
2
),
EXT_CONTROL_REG_BITS
(
VPLL
,
0
,
6
),
EXT_CONTROL_REG_BITS
(
VDAC
,
0
,
7
),
EXT_CONTROL_REG_BITS
(
VAUX1
,
0
,
3
),
EXT_CONTROL_REG_BITS
(
VAUX2
,
0
,
4
),
EXT_CONTROL_REG_BITS
(
VAUX33
,
0
,
5
),
EXT_CONTROL_REG_BITS
(
VMMC
,
0
,
0
),
};
static
unsigned
int
tps65911_ext_sleep_control
[]
=
{
0
,
EXT_CONTROL_REG_BITS
(
VIO
,
1
,
0
),
EXT_CONTROL_REG_BITS
(
VDD1
,
1
,
1
),
EXT_CONTROL_REG_BITS
(
VDD2
,
1
,
2
),
EXT_CONTROL_REG_BITS
(
VDDCTRL
,
1
,
3
),
EXT_CONTROL_REG_BITS
(
LDO1
,
0
,
1
),
EXT_CONTROL_REG_BITS
(
LDO2
,
0
,
2
),
EXT_CONTROL_REG_BITS
(
LDO3
,
0
,
7
),
EXT_CONTROL_REG_BITS
(
LDO4
,
0
,
6
),
EXT_CONTROL_REG_BITS
(
LDO5
,
0
,
3
),
EXT_CONTROL_REG_BITS
(
LDO6
,
0
,
0
),
EXT_CONTROL_REG_BITS
(
LDO7
,
0
,
5
),
EXT_CONTROL_REG_BITS
(
LDO8
,
0
,
4
),
};
struct
tps65910_reg
{
struct
regulator_desc
*
desc
;
struct
tps65910
*
mfd
;
...
...
@@ -247,6 +325,8 @@ struct tps65910_reg {
int
num_regulators
;
int
mode
;
int
(
*
get_ctrl_reg
)(
int
);
unsigned
int
*
ext_sleep_control
;
unsigned
int
board_ext_control
[
TPS65910_NUM_REGS
];
};
static
inline
int
tps65910_read
(
struct
tps65910_reg
*
pmic
,
u8
reg
)
...
...
@@ -429,6 +509,12 @@ static int tps65910_disable(struct regulator_dev *dev)
return
tps65910_clear_bits
(
mfd
,
reg
,
TPS65910_SUPPLY_STATE_ENABLED
);
}
static
int
tps65910_enable_time
(
struct
regulator_dev
*
dev
)
{
struct
tps65910_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
int
id
=
rdev_get_id
(
dev
);
return
pmic
->
info
[
id
]
->
enable_time_us
;
}
static
int
tps65910_set_mode
(
struct
regulator_dev
*
dev
,
unsigned
int
mode
)
{
...
...
@@ -467,7 +553,7 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev)
if
(
value
<
0
)
return
value
;
if
(
value
&
LDO_ST_ON_BIT
)
if
(
!
(
value
&
LDO_ST_ON_BIT
)
)
return
REGULATOR_MODE_STANDBY
;
else
if
(
value
&
LDO_ST_MODE_BIT
)
return
REGULATOR_MODE_IDLE
;
...
...
@@ -475,10 +561,10 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev)
return
REGULATOR_MODE_NORMAL
;
}
static
int
tps65910_get_voltage_dcdc
(
struct
regulator_dev
*
dev
)
static
int
tps65910_get_voltage_dcdc
_sel
(
struct
regulator_dev
*
dev
)
{
struct
tps65910_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
int
id
=
rdev_get_id
(
dev
)
,
voltage
=
0
;
int
id
=
rdev_get_id
(
dev
);
int
opvsel
=
0
,
srvsel
=
0
,
vselmax
=
0
,
mult
=
0
,
sr
=
0
;
switch
(
id
)
{
...
...
@@ -522,9 +608,7 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
srvsel
=
3
;
if
(
srvsel
>
vselmax
)
srvsel
=
vselmax
;
srvsel
-=
3
;
voltage
=
(
srvsel
*
VDD1_2_OFFSET
+
VDD1_2_MIN_VOLT
)
*
100
;
return
srvsel
-
3
;
}
else
{
/* normalise to valid range*/
...
...
@@ -532,14 +616,9 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
opvsel
=
3
;
if
(
opvsel
>
vselmax
)
opvsel
=
vselmax
;
opvsel
-=
3
;
voltage
=
(
opvsel
*
VDD1_2_OFFSET
+
VDD1_2_MIN_VOLT
)
*
100
;
return
opvsel
-
3
;
}
voltage
*=
mult
;
return
voltage
;
return
-
EINVAL
;
}
static
int
tps65910_get_voltage
(
struct
regulator_dev
*
dev
)
...
...
@@ -572,7 +651,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev)
return
-
EINVAL
;
}
voltage
=
pmic
->
info
[
id
]
->
table
[
value
]
*
1000
;
voltage
=
pmic
->
info
[
id
]
->
voltage_
table
[
value
]
*
1000
;
return
voltage
;
}
...
...
@@ -622,8 +701,9 @@ static int tps65911_get_voltage(struct regulator_dev *dev)
step_mv
=
100
;
break
;
case
TPS65910_REG_VIO
:
return
pmic
->
info
[
id
]
->
table
[
value
]
*
1000
;
break
;
value
&=
LDO_SEL_MASK
;
value
>>=
LDO_SEL_SHIFT
;
return
pmic
->
info
[
id
]
->
voltage_table
[
value
]
*
1000
;
default:
return
-
EINVAL
;
}
...
...
@@ -631,8 +711,8 @@ static int tps65911_get_voltage(struct regulator_dev *dev)
return
(
LDO_MIN_VOLT
+
value
*
step_mv
)
*
1000
;
}
static
int
tps65910_set_voltage_dcdc
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
static
int
tps65910_set_voltage_dcdc
_sel
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps65910_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
int
id
=
rdev_get_id
(
dev
),
vsel
;
...
...
@@ -669,7 +749,8 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,
return
0
;
}
static
int
tps65910_set_voltage
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
static
int
tps65910_set_voltage_sel
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps65910_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
int
reg
,
id
=
rdev_get_id
(
dev
);
...
...
@@ -695,7 +776,8 @@ static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector)
return
-
EINVAL
;
}
static
int
tps65911_set_voltage
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
static
int
tps65911_set_voltage_sel
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps65910_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
int
reg
,
id
=
rdev_get_id
(
dev
);
...
...
@@ -715,9 +797,11 @@ static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector)
case
TPS65911_REG_LDO6
:
case
TPS65911_REG_LDO7
:
case
TPS65911_REG_LDO8
:
case
TPS65910_REG_VIO
:
return
tps65910_modify_bits
(
pmic
,
reg
,
(
selector
<<
LDO_SEL_SHIFT
),
LDO3_SEL_MASK
);
case
TPS65910_REG_VIO
:
return
tps65910_modify_bits
(
pmic
,
reg
,
(
selector
<<
LDO_SEL_SHIFT
),
LDO_SEL_MASK
);
}
return
-
EINVAL
;
...
...
@@ -756,10 +840,10 @@ static int tps65910_list_voltage(struct regulator_dev *dev,
if
(
id
<
TPS65910_REG_VIO
||
id
>
TPS65910_REG_VMMC
)
return
-
EINVAL
;
if
(
selector
>=
pmic
->
info
[
id
]
->
table_len
)
if
(
selector
>=
pmic
->
info
[
id
]
->
n_voltages
)
return
-
EINVAL
;
else
voltage
=
pmic
->
info
[
id
]
->
table
[
selector
]
*
1000
;
voltage
=
pmic
->
info
[
id
]
->
voltage_
table
[
selector
]
*
1000
;
return
voltage
;
}
...
...
@@ -795,7 +879,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
step_mv
=
100
;
break
;
case
TPS65910_REG_VIO
:
return
pmic
->
info
[
id
]
->
table
[
selector
]
*
1000
;
return
pmic
->
info
[
id
]
->
voltage_
table
[
selector
]
*
1000
;
default:
return
-
EINVAL
;
}
...
...
@@ -803,15 +887,42 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
return
(
LDO_MIN_VOLT
+
selector
*
step_mv
)
*
1000
;
}
static
int
tps65910_set_voltage_dcdc_time_sel
(
struct
regulator_dev
*
dev
,
unsigned
int
old_selector
,
unsigned
int
new_selector
)
{
int
id
=
rdev_get_id
(
dev
);
int
old_volt
,
new_volt
;
old_volt
=
tps65910_list_voltage_dcdc
(
dev
,
old_selector
);
if
(
old_volt
<
0
)
return
old_volt
;
new_volt
=
tps65910_list_voltage_dcdc
(
dev
,
new_selector
);
if
(
new_volt
<
0
)
return
new_volt
;
/* VDD1 and VDD2 are 12.5mV/us, VDDCTRL is 100mV/20us */
switch
(
id
)
{
case
TPS65910_REG_VDD1
:
case
TPS65910_REG_VDD2
:
return
DIV_ROUND_UP
(
abs
(
old_volt
-
new_volt
),
12500
);
case
TPS65911_REG_VDDCTRL
:
return
DIV_ROUND_UP
(
abs
(
old_volt
-
new_volt
),
5000
);
}
return
-
EINVAL
;
}
/* Regulator ops (except VRTC) */
static
struct
regulator_ops
tps65910_ops_dcdc
=
{
.
is_enabled
=
tps65910_is_enabled
,
.
enable
=
tps65910_enable
,
.
disable
=
tps65910_disable
,
.
enable_time
=
tps65910_enable_time
,
.
set_mode
=
tps65910_set_mode
,
.
get_mode
=
tps65910_get_mode
,
.
get_voltage
=
tps65910_get_voltage_dcdc
,
.
set_voltage_sel
=
tps65910_set_voltage_dcdc
,
.
get_voltage_sel
=
tps65910_get_voltage_dcdc_sel
,
.
set_voltage_sel
=
tps65910_set_voltage_dcdc_sel
,
.
set_voltage_time_sel
=
tps65910_set_voltage_dcdc_time_sel
,
.
list_voltage
=
tps65910_list_voltage_dcdc
,
};
...
...
@@ -819,6 +930,7 @@ static struct regulator_ops tps65910_ops_vdd3 = {
.
is_enabled
=
tps65910_is_enabled
,
.
enable
=
tps65910_enable
,
.
disable
=
tps65910_disable
,
.
enable_time
=
tps65910_enable_time
,
.
set_mode
=
tps65910_set_mode
,
.
get_mode
=
tps65910_get_mode
,
.
get_voltage
=
tps65910_get_voltage_vdd3
,
...
...
@@ -829,10 +941,11 @@ static struct regulator_ops tps65910_ops = {
.
is_enabled
=
tps65910_is_enabled
,
.
enable
=
tps65910_enable
,
.
disable
=
tps65910_disable
,
.
enable_time
=
tps65910_enable_time
,
.
set_mode
=
tps65910_set_mode
,
.
get_mode
=
tps65910_get_mode
,
.
get_voltage
=
tps65910_get_voltage
,
.
set_voltage_sel
=
tps65910_set_voltage
,
.
set_voltage_sel
=
tps65910_set_voltage
_sel
,
.
list_voltage
=
tps65910_list_voltage
,
};
...
...
@@ -840,13 +953,147 @@ static struct regulator_ops tps65911_ops = {
.
is_enabled
=
tps65910_is_enabled
,
.
enable
=
tps65910_enable
,
.
disable
=
tps65910_disable
,
.
enable_time
=
tps65910_enable_time
,
.
set_mode
=
tps65910_set_mode
,
.
get_mode
=
tps65910_get_mode
,
.
get_voltage
=
tps65911_get_voltage
,
.
set_voltage_sel
=
tps65911_set_voltage
,
.
set_voltage_sel
=
tps65911_set_voltage
_sel
,
.
list_voltage
=
tps65911_list_voltage
,
};
static
int
tps65910_set_ext_sleep_config
(
struct
tps65910_reg
*
pmic
,
int
id
,
int
ext_sleep_config
)
{
struct
tps65910
*
mfd
=
pmic
->
mfd
;
u8
regoffs
=
(
pmic
->
ext_sleep_control
[
id
]
>>
8
)
&
0xFF
;
u8
bit_pos
=
(
1
<<
pmic
->
ext_sleep_control
[
id
]
&
0xFF
);
int
ret
;
/*
* Regulator can not be control from multiple external input EN1, EN2
* and EN3 together.
*/
if
(
ext_sleep_config
&
EXT_SLEEP_CONTROL
)
{
int
en_count
;
en_count
=
((
ext_sleep_config
&
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1
)
!=
0
);
en_count
+=
((
ext_sleep_config
&
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2
)
!=
0
);
en_count
+=
((
ext_sleep_config
&
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3
)
!=
0
);
en_count
+=
((
ext_sleep_config
&
TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP
)
!=
0
);
if
(
en_count
>
1
)
{
dev_err
(
mfd
->
dev
,
"External sleep control flag is not proper
\n
"
);
return
-
EINVAL
;
}
}
pmic
->
board_ext_control
[
id
]
=
ext_sleep_config
;
/* External EN1 control */
if
(
ext_sleep_config
&
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1
)
ret
=
tps65910_set_bits
(
mfd
,
TPS65910_EN1_LDO_ASS
+
regoffs
,
bit_pos
);
else
ret
=
tps65910_clear_bits
(
mfd
,
TPS65910_EN1_LDO_ASS
+
regoffs
,
bit_pos
);
if
(
ret
<
0
)
{
dev_err
(
mfd
->
dev
,
"Error in configuring external control EN1
\n
"
);
return
ret
;
}
/* External EN2 control */
if
(
ext_sleep_config
&
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2
)
ret
=
tps65910_set_bits
(
mfd
,
TPS65910_EN2_LDO_ASS
+
regoffs
,
bit_pos
);
else
ret
=
tps65910_clear_bits
(
mfd
,
TPS65910_EN2_LDO_ASS
+
regoffs
,
bit_pos
);
if
(
ret
<
0
)
{
dev_err
(
mfd
->
dev
,
"Error in configuring external control EN2
\n
"
);
return
ret
;
}
/* External EN3 control for TPS65910 LDO only */
if
((
tps65910_chip_id
(
mfd
)
==
TPS65910
)
&&
(
id
>=
TPS65910_REG_VDIG1
))
{
if
(
ext_sleep_config
&
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3
)
ret
=
tps65910_set_bits
(
mfd
,
TPS65910_EN3_LDO_ASS
+
regoffs
,
bit_pos
);
else
ret
=
tps65910_clear_bits
(
mfd
,
TPS65910_EN3_LDO_ASS
+
regoffs
,
bit_pos
);
if
(
ret
<
0
)
{
dev_err
(
mfd
->
dev
,
"Error in configuring external control EN3
\n
"
);
return
ret
;
}
}
/* Return if no external control is selected */
if
(
!
(
ext_sleep_config
&
EXT_SLEEP_CONTROL
))
{
/* Clear all sleep controls */
ret
=
tps65910_clear_bits
(
mfd
,
TPS65910_SLEEP_KEEP_LDO_ON
+
regoffs
,
bit_pos
);
if
(
!
ret
)
ret
=
tps65910_clear_bits
(
mfd
,
TPS65910_SLEEP_SET_LDO_OFF
+
regoffs
,
bit_pos
);
if
(
ret
<
0
)
dev_err
(
mfd
->
dev
,
"Error in configuring SLEEP register
\n
"
);
return
ret
;
}
/*
* For regulator that has separate operational and sleep register make
* sure that operational is used and clear sleep register to turn
* regulator off when external control is inactive
*/
if
((
id
==
TPS65910_REG_VDD1
)
||
(
id
==
TPS65910_REG_VDD2
)
||
((
id
==
TPS65911_REG_VDDCTRL
)
&&
(
tps65910_chip_id
(
mfd
)
==
TPS65911
)))
{
int
op_reg_add
=
pmic
->
get_ctrl_reg
(
id
)
+
1
;
int
sr_reg_add
=
pmic
->
get_ctrl_reg
(
id
)
+
2
;
int
opvsel
=
tps65910_reg_read
(
pmic
,
op_reg_add
);
int
srvsel
=
tps65910_reg_read
(
pmic
,
sr_reg_add
);
if
(
opvsel
&
VDD1_OP_CMD_MASK
)
{
u8
reg_val
=
srvsel
&
VDD1_OP_SEL_MASK
;
ret
=
tps65910_reg_write
(
pmic
,
op_reg_add
,
reg_val
);
if
(
ret
<
0
)
{
dev_err
(
mfd
->
dev
,
"Error in configuring op register
\n
"
);
return
ret
;
}
}
ret
=
tps65910_reg_write
(
pmic
,
sr_reg_add
,
0
);
if
(
ret
<
0
)
{
dev_err
(
mfd
->
dev
,
"Error in settting sr register
\n
"
);
return
ret
;
}
}
ret
=
tps65910_clear_bits
(
mfd
,
TPS65910_SLEEP_KEEP_LDO_ON
+
regoffs
,
bit_pos
);
if
(
!
ret
)
{
if
(
ext_sleep_config
&
TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP
)
ret
=
tps65910_set_bits
(
mfd
,
TPS65910_SLEEP_SET_LDO_OFF
+
regoffs
,
bit_pos
);
else
ret
=
tps65910_clear_bits
(
mfd
,
TPS65910_SLEEP_SET_LDO_OFF
+
regoffs
,
bit_pos
);
}
if
(
ret
<
0
)
dev_err
(
mfd
->
dev
,
"Error in configuring SLEEP register
\n
"
);
return
ret
;
}
static
__devinit
int
tps65910_probe
(
struct
platform_device
*
pdev
)
{
struct
tps65910
*
tps65910
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
...
...
@@ -877,11 +1124,13 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
case
TPS65910
:
pmic
->
get_ctrl_reg
=
&
tps65910_get_ctrl_register
;
pmic
->
num_regulators
=
ARRAY_SIZE
(
tps65910_regs
);
pmic
->
ext_sleep_control
=
tps65910_ext_sleep_control
;
info
=
tps65910_regs
;
break
;
case
TPS65911
:
pmic
->
get_ctrl_reg
=
&
tps65911_get_ctrl_register
;
pmic
->
num_regulators
=
ARRAY_SIZE
(
tps65911_regs
);
pmic
->
ext_sleep_control
=
tps65911_ext_sleep_control
;
info
=
tps65911_regs
;
break
;
default:
...
...
@@ -926,7 +1175,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
pmic
->
desc
[
i
].
name
=
info
->
name
;
pmic
->
desc
[
i
].
id
=
i
;
pmic
->
desc
[
i
].
n_voltages
=
info
->
table_len
;
pmic
->
desc
[
i
].
n_voltages
=
info
->
n_voltages
;
if
(
i
==
TPS65910_REG_VDD1
||
i
==
TPS65910_REG_VDD2
)
{
pmic
->
desc
[
i
].
ops
=
&
tps65910_ops_dcdc
;
...
...
@@ -944,6 +1193,16 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
pmic
->
desc
[
i
].
ops
=
&
tps65911_ops
;
}
err
=
tps65910_set_ext_sleep_config
(
pmic
,
i
,
pmic_plat_data
->
regulator_ext_sleep_control
[
i
]);
/*
* Failing on regulator for configuring externally control
* is not a serious issue, just throw warning.
*/
if
(
err
<
0
)
dev_warn
(
tps65910
->
dev
,
"Failed to initialise ext control config
\n
"
);
pmic
->
desc
[
i
].
type
=
REGULATOR_VOLTAGE
;
pmic
->
desc
[
i
].
owner
=
THIS_MODULE
;
...
...
@@ -990,6 +1249,36 @@ static int __devexit tps65910_remove(struct platform_device *pdev)
return
0
;
}
static
void
tps65910_shutdown
(
struct
platform_device
*
pdev
)
{
struct
tps65910_reg
*
pmic
=
platform_get_drvdata
(
pdev
);
int
i
;
/*
* Before bootloader jumps to kernel, it makes sure that required
* external control signals are in desired state so that given rails
* can be configure accordingly.
* If rails are configured to be controlled from external control
* then before shutting down/rebooting the system, the external
* control configuration need to be remove from the rails so that
* its output will be available as per register programming even
* if external controls are removed. This is require when the POR
* value of the control signals are not in active state and before
* bootloader initializes it, the system requires the rail output
* to be active for booting.
*/
for
(
i
=
0
;
i
<
pmic
->
num_regulators
;
i
++
)
{
int
err
;
if
(
!
pmic
->
rdev
[
i
])
continue
;
err
=
tps65910_set_ext_sleep_config
(
pmic
,
i
,
0
);
if
(
err
<
0
)
dev_err
(
&
pdev
->
dev
,
"Error in clearing external control
\n
"
);
}
}
static
struct
platform_driver
tps65910_driver
=
{
.
driver
=
{
.
name
=
"tps65910-pmic"
,
...
...
@@ -997,6 +1286,7 @@ static struct platform_driver tps65910_driver = {
},
.
probe
=
tps65910_probe
,
.
remove
=
__devexit_p
(
tps65910_remove
),
.
shutdown
=
tps65910_shutdown
,
};
static
int
__init
tps65910_init
(
void
)
...
...
@@ -1012,6 +1302,6 @@ static void __exit tps65910_cleanup(void)
module_exit
(
tps65910_cleanup
);
MODULE_AUTHOR
(
"Graeme Gregory <gg@slimlogic.co.uk>"
);
MODULE_DESCRIPTION
(
"TPS65
07x
voltage regulator driver"
);
MODULE_DESCRIPTION
(
"TPS65
910/TPS65911
voltage regulator driver"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_ALIAS
(
"platform:tps65910-pmic"
);
drivers/regulator/tps65912-regulator.c
View file @
63236f40
...
...
@@ -114,10 +114,7 @@ struct tps65912_reg {
struct
mutex
io_lock
;
int
mode
;
int
(
*
get_ctrl_reg
)(
int
);
int
dcdc1_range
;
int
dcdc2_range
;
int
dcdc3_range
;
int
dcdc4_range
;
int
dcdc_range
[
TPS65912_NUM_DCDC
];
int
pwm_mode_reg
;
int
eco_reg
;
};
...
...
@@ -125,46 +122,31 @@ struct tps65912_reg {
static
int
tps65912_get_range
(
struct
tps65912_reg
*
pmic
,
int
id
)
{
struct
tps65912
*
mfd
=
pmic
->
mfd
;
if
(
id
>
TPS65912_REG_DCDC4
)
return
0
;
int
range
;
switch
(
id
)
{
case
TPS65912_REG_DCDC1
:
pmic
->
dcdc1_range
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC1_LIMIT
);
if
(
pmic
->
dcdc1_range
<
0
)
return
pmic
->
dcdc1_range
;
pmic
->
dcdc1_range
=
(
pmic
->
dcdc1_range
&
DCDC_LIMIT_RANGE_MASK
)
>>
DCDC_LIMIT_RANGE_SHIFT
;
return
pmic
->
dcdc1_range
;
range
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC1_LIMIT
);
break
;
case
TPS65912_REG_DCDC2
:
pmic
->
dcdc2_range
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC2_LIMIT
);
if
(
pmic
->
dcdc2_range
<
0
)
return
pmic
->
dcdc2_range
;
pmic
->
dcdc2_range
=
(
pmic
->
dcdc2_range
&
DCDC_LIMIT_RANGE_MASK
)
>>
DCDC_LIMIT_RANGE_SHIFT
;
return
pmic
->
dcdc2_range
;
range
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC2_LIMIT
);
break
;
case
TPS65912_REG_DCDC3
:
pmic
->
dcdc3_range
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC3_LIMIT
);
if
(
pmic
->
dcdc3_range
<
0
)
return
pmic
->
dcdc3_range
;
pmic
->
dcdc3_range
=
(
pmic
->
dcdc3_range
&
DCDC_LIMIT_RANGE_MASK
)
>>
DCDC_LIMIT_RANGE_SHIFT
;
return
pmic
->
dcdc3_range
;
range
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC3_LIMIT
);
break
;
case
TPS65912_REG_DCDC4
:
pmic
->
dcdc4_range
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC4_LIMIT
);
if
(
pmic
->
dcdc4_range
<
0
)
return
pmic
->
dcdc4_range
;
pmic
->
dcdc4_range
=
(
pmic
->
dcdc4_range
&
DCDC_LIMIT_RANGE_MASK
)
>>
DCDC_LIMIT_RANGE_SHIFT
;
return
pmic
->
dcdc4_range
;
range
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC4_LIMIT
);
break
;
default:
return
0
;
}
if
(
range
>=
0
)
range
=
(
range
&
DCDC_LIMIT_RANGE_MASK
)
>>
DCDC_LIMIT_RANGE_SHIFT
;
pmic
->
dcdc_range
[
id
]
=
range
;
return
range
;
}
static
unsigned
long
tps65912_vsel_to_uv_range0
(
u8
vsel
)
...
...
@@ -219,146 +201,30 @@ static unsigned long tps65912_vsel_to_uv_ldo(u8 vsel)
static
int
tps65912_get_ctrl_register
(
int
id
)
{
switch
(
id
)
{
case
TPS65912_REG_DCDC1
:
return
TPS65912_DCDC1_AVS
;
case
TPS65912_REG_DCDC2
:
return
TPS65912_DCDC2_AVS
;
case
TPS65912_REG_DCDC3
:
return
TPS65912_DCDC3_AVS
;
case
TPS65912_REG_DCDC4
:
return
TPS65912_DCDC4_AVS
;
case
TPS65912_REG_LDO1
:
return
TPS65912_LDO1_AVS
;
case
TPS65912_REG_LDO2
:
return
TPS65912_LDO2_AVS
;
case
TPS65912_REG_LDO3
:
return
TPS65912_LDO3_AVS
;
case
TPS65912_REG_LDO4
:
return
TPS65912_LDO4_AVS
;
case
TPS65912_REG_LDO5
:
return
TPS65912_LDO5
;
case
TPS65912_REG_LDO6
:
return
TPS65912_LDO6
;
case
TPS65912_REG_LDO7
:
return
TPS65912_LDO7
;
case
TPS65912_REG_LDO8
:
return
TPS65912_LDO8
;
case
TPS65912_REG_LDO9
:
return
TPS65912_LDO9
;
case
TPS65912_REG_LDO10
:
return
TPS65912_LDO10
;
default:
if
(
id
>=
TPS65912_REG_DCDC1
&&
id
<=
TPS65912_REG_LDO4
)
return
id
*
3
+
TPS65912_DCDC1_AVS
;
else
if
(
id
>=
TPS65912_REG_LDO5
&&
id
<=
TPS65912_REG_LDO10
)
return
id
-
TPS65912_REG_LDO5
+
TPS65912_LDO5
;
else
return
-
EINVAL
;
}
}
static
int
tps65912_get_
dcdc_
sel_register
(
struct
tps65912_reg
*
pmic
,
int
id
)
static
int
tps65912_get_sel_register
(
struct
tps65912_reg
*
pmic
,
int
id
)
{
struct
tps65912
*
mfd
=
pmic
->
mfd
;
int
opvsel
=
0
,
sr
=
0
;
int
opvsel
;
u8
reg
=
0
;
if
(
id
<
TPS65912_REG_DCDC1
||
id
>
TPS65912_REG_DCDC4
)
return
-
EINVAL
;
switch
(
id
)
{
case
TPS65912_REG_DCDC1
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC1_OP
);
sr
=
((
opvsel
&
OP_SELREG_MASK
)
>>
OP_SELREG_SHIFT
);
if
(
sr
)
reg
=
TPS65912_DCDC1_AVS
;
else
reg
=
TPS65912_DCDC1_OP
;
break
;
case
TPS65912_REG_DCDC2
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC2_OP
);
sr
=
(
opvsel
&
OP_SELREG_MASK
)
>>
OP_SELREG_SHIFT
;
if
(
sr
)
reg
=
TPS65912_DCDC2_AVS
;
else
reg
=
TPS65912_DCDC2_OP
;
break
;
case
TPS65912_REG_DCDC3
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC3_OP
);
sr
=
(
opvsel
&
OP_SELREG_MASK
)
>>
OP_SELREG_SHIFT
;
if
(
sr
)
reg
=
TPS65912_DCDC3_AVS
;
else
reg
=
TPS65912_DCDC3_OP
;
break
;
case
TPS65912_REG_DCDC4
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC4_OP
);
sr
=
(
opvsel
&
OP_SELREG_MASK
)
>>
OP_SELREG_SHIFT
;
if
(
sr
)
reg
=
TPS65912_DCDC4_AVS
;
if
(
id
>=
TPS65912_REG_DCDC1
&&
id
<=
TPS65912_REG_LDO4
)
{
opvsel
=
tps65912_reg_read
(
mfd
,
id
*
3
+
TPS65912_DCDC1_OP
);
if
(
opvsel
&
OP_SELREG_MASK
)
reg
=
id
*
3
+
TPS65912_DCDC1_AVS
;
else
reg
=
TPS65912_DCDC4_OP
;
break
;
}
return
reg
;
}
static
int
tps65912_get_ldo_sel_register
(
struct
tps65912_reg
*
pmic
,
int
id
)
{
struct
tps65912
*
mfd
=
pmic
->
mfd
;
int
opvsel
=
0
,
sr
=
0
;
u8
reg
=
0
;
if
(
id
<
TPS65912_REG_LDO1
||
id
>
TPS65912_REG_LDO10
)
reg
=
id
*
3
+
TPS65912_DCDC1_OP
;
}
else
if
(
id
>=
TPS65912_REG_LDO5
&&
id
<=
TPS65912_REG_LDO10
)
{
reg
=
id
-
TPS65912_REG_LDO5
+
TPS65912_LDO5
;
}
else
{
return
-
EINVAL
;
switch
(
id
)
{
case
TPS65912_REG_LDO1
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_LDO1_OP
);
sr
=
(
opvsel
&
OP_SELREG_MASK
)
>>
OP_SELREG_SHIFT
;
if
(
sr
)
reg
=
TPS65912_LDO1_AVS
;
else
reg
=
TPS65912_LDO1_OP
;
break
;
case
TPS65912_REG_LDO2
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_LDO2_OP
);
sr
=
(
opvsel
&
OP_SELREG_MASK
)
>>
OP_SELREG_SHIFT
;
if
(
sr
)
reg
=
TPS65912_LDO2_AVS
;
else
reg
=
TPS65912_LDO2_OP
;
break
;
case
TPS65912_REG_LDO3
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_LDO3_OP
);
sr
=
(
opvsel
&
OP_SELREG_MASK
)
>>
OP_SELREG_SHIFT
;
if
(
sr
)
reg
=
TPS65912_LDO3_AVS
;
else
reg
=
TPS65912_LDO3_OP
;
break
;
case
TPS65912_REG_LDO4
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_LDO4_OP
);
sr
=
(
opvsel
&
OP_SELREG_MASK
)
>>
OP_SELREG_SHIFT
;
if
(
sr
)
reg
=
TPS65912_LDO4_AVS
;
else
reg
=
TPS65912_LDO4_OP
;
break
;
case
TPS65912_REG_LDO5
:
reg
=
TPS65912_LDO5
;
break
;
case
TPS65912_REG_LDO6
:
reg
=
TPS65912_LDO6
;
break
;
case
TPS65912_REG_LDO7
:
reg
=
TPS65912_LDO7
;
break
;
case
TPS65912_REG_LDO8
:
reg
=
TPS65912_LDO8
;
break
;
case
TPS65912_REG_LDO9
:
reg
=
TPS65912_LDO9
;
break
;
case
TPS65912_REG_LDO10
:
reg
=
TPS65912_LDO10
;
break
;
}
return
reg
;
...
...
@@ -506,151 +372,83 @@ static unsigned int tps65912_get_mode(struct regulator_dev *dev)
return
mode
;
}
static
int
tps65912_get_voltage_dcdc
(
struct
regulator_dev
*
dev
)
static
int
tps65912_list_voltage_dcdc
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps65912_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
struct
tps65912
*
mfd
=
pmic
->
mfd
;
int
id
=
rdev_get_id
(
dev
),
voltage
=
0
,
range
;
int
opvsel
=
0
,
avsel
=
0
,
sr
,
vsel
;
int
range
,
voltage
=
0
,
id
=
rdev_get_id
(
dev
);
switch
(
id
)
{
case
TPS65912_REG_DCDC1
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC1_OP
);
avsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC1_AVS
);
range
=
pmic
->
dcdc1_range
;
break
;
case
TPS65912_REG_DCDC2
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC2_OP
);
avsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC2_AVS
);
range
=
pmic
->
dcdc2_range
;
break
;
case
TPS65912_REG_DCDC3
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC3_OP
);
avsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC3_AVS
);
range
=
pmic
->
dcdc3_range
;
break
;
case
TPS65912_REG_DCDC4
:
opvsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC4_OP
);
avsel
=
tps65912_reg_read
(
mfd
,
TPS65912_DCDC4_AVS
);
range
=
pmic
->
dcdc4_range
;
break
;
default:
if
(
id
>
TPS65912_REG_DCDC4
)
return
-
EINVAL
;
}
sr
=
(
opvsel
&
OP_SELREG_MASK
)
>>
OP_SELREG_SHIFT
;
if
(
sr
)
vsel
=
avsel
;
else
vsel
=
opvsel
;
vsel
&=
0x3F
;
range
=
pmic
->
dcdc_range
[
id
];
switch
(
range
)
{
case
0
:
/* 0.5 - 1.2875V in 12.5mV steps */
voltage
=
tps65912_vsel_to_uv_range0
(
vsel
);
voltage
=
tps65912_vsel_to_uv_range0
(
selector
);
break
;
case
1
:
/* 0.7 - 1.4875V in 12.5mV steps */
voltage
=
tps65912_vsel_to_uv_range1
(
vsel
);
voltage
=
tps65912_vsel_to_uv_range1
(
selector
);
break
;
case
2
:
/* 0.5 - 2.075V in 25mV steps */
voltage
=
tps65912_vsel_to_uv_range2
(
vsel
);
voltage
=
tps65912_vsel_to_uv_range2
(
selector
);
break
;
case
3
:
/* 0.5 - 3.8V in 50mV steps */
voltage
=
tps65912_vsel_to_uv_range3
(
vsel
);
voltage
=
tps65912_vsel_to_uv_range3
(
selector
);
break
;
}
return
voltage
;
}
static
int
tps65912_set_voltage_dcdc
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
static
int
tps65912_get_voltage_dcdc
(
struct
regulator_dev
*
dev
)
{
struct
tps65912_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
struct
tps65912
*
mfd
=
pmic
->
mfd
;
int
id
=
rdev_get_id
(
dev
);
int
value
;
u8
reg
;
reg
=
tps65912_get_dcdc_sel_register
(
pmic
,
id
);
value
=
tps65912_reg_read
(
mfd
,
reg
);
value
&=
0xC0
;
return
tps65912_reg_write
(
mfd
,
reg
,
selector
|
value
);
}
int
reg
,
vsel
;
static
int
tps65912_get_voltage_ldo
(
struct
regulator_dev
*
dev
)
{
struct
tps65912_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
struct
tps65912
*
mfd
=
pmic
->
mfd
;
int
id
=
rdev_get_id
(
dev
);
int
vsel
=
0
;
u8
reg
;
reg
=
tps65912_get_sel_register
(
pmic
,
id
);
if
(
reg
<
0
)
return
reg
;
reg
=
tps65912_get_ldo_sel_register
(
pmic
,
id
);
vsel
=
tps65912_reg_read
(
mfd
,
reg
);
vsel
&=
0x3F
;
return
tps65912_
vsel_to_uv_ldo
(
vsel
);
return
tps65912_
list_voltage_dcdc
(
dev
,
vsel
);
}
static
int
tps65912_set_voltage_
ldo
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
static
int
tps65912_set_voltage_
sel
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
{
struct
tps65912_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
struct
tps65912
*
mfd
=
pmic
->
mfd
;
int
id
=
rdev_get_id
(
dev
),
reg
,
value
;
int
id
=
rdev_get_id
(
dev
);
int
value
;
u8
reg
;
reg
=
tps65912_get_
ldo_
sel_register
(
pmic
,
id
);
reg
=
tps65912_get_sel_register
(
pmic
,
id
);
value
=
tps65912_reg_read
(
mfd
,
reg
);
value
&=
0xC0
;
return
tps65912_reg_write
(
mfd
,
reg
,
selector
|
value
);
}
static
int
tps65912_list_voltage_dcdc
(
struct
regulator_dev
*
dev
,
unsigned
selector
)
static
int
tps65912_get_voltage_ldo
(
struct
regulator_dev
*
dev
)
{
struct
tps65912_reg
*
pmic
=
rdev_get_drvdata
(
dev
);
int
range
,
voltage
=
0
,
id
=
rdev_get_id
(
dev
);
struct
tps65912
*
mfd
=
pmic
->
mfd
;
int
id
=
rdev_get_id
(
dev
);
int
vsel
=
0
;
u8
reg
;
switch
(
id
)
{
case
TPS65912_REG_DCDC1
:
range
=
pmic
->
dcdc1_range
;
break
;
case
TPS65912_REG_DCDC2
:
range
=
pmic
->
dcdc2_range
;
break
;
case
TPS65912_REG_DCDC3
:
range
=
pmic
->
dcdc3_range
;
break
;
case
TPS65912_REG_DCDC4
:
range
=
pmic
->
dcdc4_range
;
break
;
default:
return
-
EINVAL
;
}
reg
=
tps65912_get_sel_register
(
pmic
,
id
);
vsel
=
tps65912_reg_read
(
mfd
,
reg
);
vsel
&=
0x3F
;
switch
(
range
)
{
case
0
:
/* 0.5 - 1.2875V in 12.5mV steps */
voltage
=
tps65912_vsel_to_uv_range0
(
selector
);
break
;
case
1
:
/* 0.7 - 1.4875V in 12.5mV steps */
voltage
=
tps65912_vsel_to_uv_range1
(
selector
);
break
;
case
2
:
/* 0.5 - 2.075V in 25mV steps */
voltage
=
tps65912_vsel_to_uv_range2
(
selector
);
break
;
case
3
:
/* 0.5 - 3.8V in 50mV steps */
voltage
=
tps65912_vsel_to_uv_range3
(
selector
);
break
;
}
return
voltage
;
return
tps65912_vsel_to_uv_ldo
(
vsel
);
}
static
int
tps65912_list_voltage_ldo
(
struct
regulator_dev
*
dev
,
...
...
@@ -672,7 +470,7 @@ static struct regulator_ops tps65912_ops_dcdc = {
.
set_mode
=
tps65912_set_mode
,
.
get_mode
=
tps65912_get_mode
,
.
get_voltage
=
tps65912_get_voltage_dcdc
,
.
set_voltage_sel
=
tps65912_set_voltage_
dcdc
,
.
set_voltage_sel
=
tps65912_set_voltage_
sel
,
.
list_voltage
=
tps65912_list_voltage_dcdc
,
};
...
...
@@ -682,7 +480,7 @@ static struct regulator_ops tps65912_ops_ldo = {
.
enable
=
tps65912_reg_enable
,
.
disable
=
tps65912_reg_disable
,
.
get_voltage
=
tps65912_get_voltage_ldo
,
.
set_voltage_sel
=
tps65912_set_voltage_
ldo
,
.
set_voltage_sel
=
tps65912_set_voltage_
sel
,
.
list_voltage
=
tps65912_list_voltage_ldo
,
};
...
...
@@ -770,22 +568,12 @@ static struct platform_driver tps65912_driver = {
.
remove
=
__devexit_p
(
tps65912_remove
),
};
/**
* tps65912_init
*
* Module init function
*/
static
int
__init
tps65912_init
(
void
)
{
return
platform_driver_register
(
&
tps65912_driver
);
}
subsys_initcall
(
tps65912_init
);
/**
* tps65912_cleanup
*
* Module exit function
*/
static
void
__exit
tps65912_cleanup
(
void
)
{
platform_driver_unregister
(
&
tps65912_driver
);
...
...
drivers/regulator/wm8350-regulator.c
View file @
63236f40
...
...
@@ -186,7 +186,7 @@ static int wm8350_isink_get_current(struct regulator_dev *rdev)
return
0
;
}
return
(
isink_cur
[
val
]
+
50
)
/
100
;
return
DIV_ROUND_CLOSEST
(
isink_cur
[
val
],
100
)
;
}
/* turn on ISINK followed by DCDC */
...
...
@@ -1544,7 +1544,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
return
-
ENOMEM
;
}
led
->
isink_consumer
.
dev
=
&
pdev
->
dev
;
led
->
isink_consumer
.
dev
_name
=
dev_name
(
&
pdev
->
dev
)
;
led
->
isink_consumer
.
supply
=
"led_isink"
;
led
->
isink_init
.
num_consumer_supplies
=
1
;
led
->
isink_init
.
consumer_supplies
=
&
led
->
isink_consumer
;
...
...
@@ -1559,7 +1559,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
return
ret
;
}
led
->
dcdc_consumer
.
dev
=
&
pdev
->
dev
;
led
->
dcdc_consumer
.
dev
_name
=
dev_name
(
&
pdev
->
dev
)
;
led
->
dcdc_consumer
.
supply
=
"led_vcc"
;
led
->
dcdc_init
.
num_consumer_supplies
=
1
;
led
->
dcdc_init
.
consumer_supplies
=
&
led
->
dcdc_consumer
;
...
...
drivers/regulator/wm8400-regulator.c
View file @
63236f40
...
...
@@ -78,14 +78,14 @@ static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
if
(
min_uV
<
1700000
)
{
/* Steps of 50mV from 900mV; */
val
=
(
min_uV
-
850001
)
/
50000
;
val
=
DIV_ROUND_UP
(
min_uV
-
900000
,
50000
)
;
if
((
val
*
50000
)
+
900000
>
max_uV
)
return
-
EINVAL
;
BUG_ON
((
val
*
50000
)
+
900000
<
min_uV
);
}
else
{
/* Steps of 100mV from 1700mV */
val
=
((
min_uV
-
1600001
)
/
100000
);
val
=
DIV_ROUND_UP
(
min_uV
-
1700000
,
100000
);
if
((
val
*
100000
)
+
1700000
>
max_uV
)
return
-
EINVAL
;
...
...
@@ -168,7 +168,7 @@ static int wm8400_dcdc_set_voltage(struct regulator_dev *dev,
if
(
min_uV
<
850000
)
return
-
EINVAL
;
val
=
(
min_uV
-
825001
)
/
25000
;
val
=
DIV_ROUND_UP
(
min_uV
-
850000
,
25000
)
;
if
(
850000
+
(
25000
*
val
)
>
max_uV
)
return
-
EINVAL
;
...
...
drivers/regulator/wm8994-regulator.c
View file @
63236f40
...
...
@@ -241,7 +241,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
if
(
!
pdata
)
return
-
ENODEV
;
ldo
=
kzalloc
(
sizeof
(
struct
wm8994_ldo
),
GFP_KERNEL
);
ldo
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
wm8994_ldo
),
GFP_KERNEL
);
if
(
ldo
==
NULL
)
{
dev_err
(
&
pdev
->
dev
,
"Unable to allocate private data
\n
"
);
return
-
ENOMEM
;
...
...
@@ -285,7 +285,6 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
if
(
gpio_is_valid
(
ldo
->
enable
))
gpio_free
(
ldo
->
enable
);
err:
kfree
(
ldo
);
return
ret
;
}
...
...
@@ -298,7 +297,6 @@ static __devexit int wm8994_ldo_remove(struct platform_device *pdev)
regulator_unregister
(
ldo
->
regulator
);
if
(
gpio_is_valid
(
ldo
->
enable
))
gpio_free
(
ldo
->
enable
);
kfree
(
ldo
);
return
0
;
}
...
...
include/linux/mfd/tps65910.h
View file @
63236f40
...
...
@@ -768,6 +768,12 @@
/* Max number of TPS65910/11 regulators */
#define TPS65910_NUM_REGS 13
/* External sleep controls through EN1/EN2/EN3/SLEEP inputs */
#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 0x1
#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 0x2
#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 0x4
#define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP 0x8
/**
* struct tps65910_board
* Board platform data may be used to initialize regulators.
...
...
@@ -779,6 +785,7 @@ struct tps65910_board {
int
irq_base
;
int
vmbch_threshold
;
int
vmbch2_threshold
;
unsigned
long
regulator_ext_sleep_control
[
TPS65910_NUM_REGS
];
struct
regulator_init_data
*
tps65910_pmic_init_data
[
TPS65910_NUM_REGS
];
};
...
...
include/linux/regulator/tps62360.h
0 → 100644
View file @
63236f40
/*
* tps62360.h -- TI tps62360
*
* Interface for regulator driver for TI TPS62360 Processor core supply
*
* Copyright (C) 2012 NVIDIA Corporation
* Author: Laxman Dewangan <ldewangan@nvidia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef __LINUX_REGULATOR_TPS62360_H
#define __LINUX_REGULATOR_TPS62360_H
#include <linux/regulator/machine.h>
/*
* struct tps62360_regulator_platform_data - tps62360 regulator platform data.
*
* @reg_init_data: The regulator init data.
* @en_force_pwm: Enable force pwm or not.
* @en_discharge: Enable discharge the output capacitor via internal
* register.
* @en_internal_pulldn: internal pull down enable or not.
* @vsel0_gpio: Gpio number for vsel0. It should be -1 if this is tied with
* fixed logic.
* @vsel1_gpio: Gpio number for vsel1. It should be -1 if this is tied with
* fixed logic.
* @vsel0_def_state: Default state of vsel0. 1 if it is high else 0.
* @vsel1_def_state: Default state of vsel1. 1 if it is high else 0.
*/
struct
tps62360_regulator_platform_data
{
struct
regulator_init_data
reg_init_data
;
bool
en_force_pwm
;
bool
en_discharge
;
bool
en_internal_pulldn
;
int
vsel0_gpio
;
int
vsel1_gpio
;
int
vsel0_def_state
;
int
vsel1_def_state
;
};
#endif
/* __LINUX_REGULATOR_TPS62360_H */
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