aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorGuodong Xu <guodong.xu@linaro.org>2014-08-13 07:33:42 -0400
committerMark Brown <broonie@linaro.org>2014-08-16 17:58:15 -0400
commit87ca186f7eb663fc5e52b65452a91fe0fec170a0 (patch)
treecaeb09468cf072bd94f6a78e58c18f50e065e348 /drivers/regulator
parent871f565055ed232e5751da18a331b73e8254adaf (diff)
regulator: add driver for hi6421 voltage regulator
Add driver support for HiSilicon Hi6421 voltage regulators. Two rules for regulator enabling are defined in hi6421 spec: 1) Between disable and enable of each regulator (LDOs or BUCKs), there must be a protection gap. Use @off_on_delay of regulator core to implement this. 2) No two regulators can be enabled at the same time. Use mutex in hi6421_regulator_pdata to ensure this. A protection gap of 100us is added into each LDO/BUCK's .enable_time. Signed-off-by: Guodong Xu <guodong.xu@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/Kconfig10
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/hi6421-regulator.c657
3 files changed, 668 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 2dc8289e5dba..e6b98ed4c12f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -240,6 +240,16 @@ config REGULATOR_GPIO
240 and the platform has to provide a mapping of GPIO-states 240 and the platform has to provide a mapping of GPIO-states
241 to target volts/amps. 241 to target volts/amps.
242 242
243config REGULATOR_HI6421
244 tristate "HiSilicon Hi6421 PMIC voltage regulator support"
245 depends on MFD_HI6421_PMIC && OF
246 help
247 This driver provides support for the voltage regulators on the
248 HiSilicon Hi6421 PMU / Codec IC.
249 Hi6421 is a multi-function device which, on regulator part, provides
250 21 general purpose LDOs, 3 dedicated LDOs, and 5 BUCKs. All
251 of them come with support to either ECO (idle) or sleep mode.
252
243config REGULATOR_ISL6271A 253config REGULATOR_ISL6271A
244 tristate "Intersil ISL6271A Power regulator" 254 tristate "Intersil ISL6271A Power regulator"
245 depends on I2C 255 depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index aa4a6aa7b558..5513e2c141b1 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
32obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o 32obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
33obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o 33obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
34obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o 34obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
35obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o
35obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o 36obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
36obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o 37obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
37obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o 38obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o
diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c
new file mode 100644
index 000000000000..b40851eb5466
--- /dev/null
+++ b/drivers/regulator/hi6421-regulator.c
@@ -0,0 +1,657 @@
1/*
2 * Device driver for regulators in Hi6421 IC
3 *
4 * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
5 * http://www.hisilicon.com
6 * Copyright (c) <2013-2014> Linaro Ltd.
7 * http://www.linaro.org
8 *
9 * Author: Guodong Xu <guodong.xu@linaro.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/slab.h>
17#include <linux/device.h>
18#include <linux/module.h>
19#include <linux/err.h>
20#include <linux/io.h>
21#include <linux/jiffies.h>
22#include <linux/platform_device.h>
23#include <linux/of.h>
24#include <linux/of_device.h>
25#include <linux/of_address.h>
26#include <linux/regmap.h>
27#include <linux/regulator/driver.h>
28#include <linux/regulator/machine.h>
29#include <linux/regulator/of_regulator.h>
30#include <linux/mfd/hi6421-pmic.h>
31#include <linux/delay.h>
32#include <linux/time.h>
33
34/*
35 * struct hi6421_regulator_pdata - Hi6421 regulator data of platform device
36 * @lock: mutex to serialize regulator enable
37 */
38struct hi6421_regulator_pdata {
39 struct mutex lock;
40};
41
42/*
43 * struct hi6421_regulator_info - hi6421 regulator information
44 * @dev: device pointer
45 * @desc: regulator description
46 * @regulator: regulator device
47 * @mode_mask: ECO mode bitmask of LDOs; for BUCKs, this masks sleep
48 * @eco_microamp: eco mode load upper limit (in mA), valid for LDOs only
49 * @valid_modes_mask: valid operating modes
50 */
51struct hi6421_regulator_info {
52 struct device *dev;
53 struct regulator_desc desc;
54 struct regulator_dev *regulator;
55 u8 mode_mask;
56 u32 eco_microamp;
57 unsigned int valid_modes_mask;
58};
59
60/* HI6421 regulators */
61enum hi6421_regulator_id {
62 HI6421_LDO0,
63 HI6421_LDO1,
64 HI6421_LDO2,
65 HI6421_LDO3,
66 HI6421_LDO4,
67 HI6421_LDO5,
68 HI6421_LDO6,
69 HI6421_LDO7,
70 HI6421_LDO8,
71 HI6421_LDO9,
72 HI6421_LDO10,
73 HI6421_LDO11,
74 HI6421_LDO12,
75 HI6421_LDO13,
76 HI6421_LDO14,
77 HI6421_LDO15,
78 HI6421_LDO16,
79 HI6421_LDO17,
80 HI6421_LDO18,
81 HI6421_LDO19,
82 HI6421_LDO20,
83 HI6421_LDOAUDIO,
84 HI6421_BUCK0,
85 HI6421_BUCK1,
86 HI6421_BUCK2,
87 HI6421_BUCK3,
88 HI6421_BUCK4,
89 HI6421_BUCK5,
90 HI6421_NUM_REGULATORS,
91};
92
93#define HI6421_REGULATOR_OF_MATCH(_name, id) \
94{ \
95 .name = #_name, \
96 .driver_data = (void *) HI6421_##id, \
97}
98
99static struct of_regulator_match hi6421_regulator_match[] = {
100 HI6421_REGULATOR_OF_MATCH(hi6421_vout0, LDO0),
101 HI6421_REGULATOR_OF_MATCH(hi6421_vout1, LDO1),
102 HI6421_REGULATOR_OF_MATCH(hi6421_vout2, LDO2),
103 HI6421_REGULATOR_OF_MATCH(hi6421_vout3, LDO3),
104 HI6421_REGULATOR_OF_MATCH(hi6421_vout4, LDO4),
105 HI6421_REGULATOR_OF_MATCH(hi6421_vout5, LDO5),
106 HI6421_REGULATOR_OF_MATCH(hi6421_vout6, LDO6),
107 HI6421_REGULATOR_OF_MATCH(hi6421_vout7, LDO7),
108 HI6421_REGULATOR_OF_MATCH(hi6421_vout8, LDO8),
109 HI6421_REGULATOR_OF_MATCH(hi6421_vout9, LDO9),
110 HI6421_REGULATOR_OF_MATCH(hi6421_vout10, LDO10),
111 HI6421_REGULATOR_OF_MATCH(hi6421_vout11, LDO11),
112 HI6421_REGULATOR_OF_MATCH(hi6421_vout12, LDO12),
113 HI6421_REGULATOR_OF_MATCH(hi6421_vout13, LDO13),
114 HI6421_REGULATOR_OF_MATCH(hi6421_vout14, LDO14),
115 HI6421_REGULATOR_OF_MATCH(hi6421_vout15, LDO15),
116 HI6421_REGULATOR_OF_MATCH(hi6421_vout16, LDO16),
117 HI6421_REGULATOR_OF_MATCH(hi6421_vout17, LDO17),
118 HI6421_REGULATOR_OF_MATCH(hi6421_vout18, LDO18),
119 HI6421_REGULATOR_OF_MATCH(hi6421_vout19, LDO19),
120 HI6421_REGULATOR_OF_MATCH(hi6421_vout20, LDO20),
121 HI6421_REGULATOR_OF_MATCH(hi6421_vout_audio, LDOAUDIO),
122 HI6421_REGULATOR_OF_MATCH(hi6421_buck0, BUCK0),
123 HI6421_REGULATOR_OF_MATCH(hi6421_buck1, BUCK1),
124 HI6421_REGULATOR_OF_MATCH(hi6421_buck2, BUCK2),
125 HI6421_REGULATOR_OF_MATCH(hi6421_buck3, BUCK3),
126 HI6421_REGULATOR_OF_MATCH(hi6421_buck4, BUCK4),
127 HI6421_REGULATOR_OF_MATCH(hi6421_buck5, BUCK5),
128};
129
130/* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */
131static const unsigned int ldo_0_voltages[] = {
132 1500000, 1800000, 2400000, 2500000,
133 2600000, 2700000, 2850000, 3000000,
134};
135
136/* LDO 8, 15 have same voltage table. */
137static const unsigned int ldo_8_voltages[] = {
138 1500000, 1800000, 2400000, 2600000,
139 2700000, 2850000, 3000000, 3300000,
140};
141
142/* Ranges are sorted in ascending order. */
143static const struct regulator_linear_range ldo_audio_volt_range[] = {
144 REGULATOR_LINEAR_RANGE(2800000, 0, 3, 50000),
145 REGULATOR_LINEAR_RANGE(3000000, 4, 7, 100000),
146};
147
148static const unsigned int buck_3_voltages[] = {