aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/Kconfig8
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/tps65132-regulator.c285
3 files changed, 294 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 936f7ccc9736..00150c21166d 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -781,6 +781,14 @@ config REGULATOR_TPS65090
781 This driver provides support for the voltage regulators on the 781 This driver provides support for the voltage regulators on the
782 TI TPS65090 PMIC. 782 TI TPS65090 PMIC.
783 783
784config REGULATOR_TPS65132
785 tristate "TI TPS65132 Dual Output Power regulators"
786 depends on I2C && GPIOLIB
787 select REGMAP_I2C
788 help
789 This driver supports TPS65132 single inductor - dual output
790 power supply specifcally designed for display panels.
791
784config REGULATOR_TPS65217 792config REGULATOR_TPS65217
785 tristate "TI TPS65217 Power regulators" 793 tristate "TI TPS65217 Power regulators"
786 depends on MFD_TPS65217 794 depends on MFD_TPS65217
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 14294692beb9..0e9275e78271 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
104obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o 104obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
105obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o 105obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
106obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o 106obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
107obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o
107obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o 108obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
108obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o 109obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
109obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 110obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
diff --git a/drivers/regulator/tps65132-regulator.c b/drivers/regulator/tps65132-regulator.c
new file mode 100644
index 000000000000..a949206065d4
--- /dev/null
+++ b/drivers/regulator/tps65132-regulator.c
@@ -0,0 +1,285 @@
1/*
2 * TI TPS65132 Regulator driver
3 *
4 * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
5 *
6 * Author: Venkat Reddy Talla <vreddytalla@nvidia.com>
7 * Laxman Dewangan <ldewangan@nvidia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
15 * whether express or implied; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19
20#include <linux/delay.h>
21#include <linux/err.h>
22#include <linux/gpio/consumer.h>
23#include <linux/i2c.h>
24#include <linux/module.h>
25#include <linux/regmap.h>
26#include <linux/regulator/driver.h>
27#include <linux/regulator/machine.h>
28
29#define TPS65132_REG_VPOS 0x00
30#define TPS65132_REG_VNEG 0x01
31#define TPS65132_REG_APPS_DISP_DISN 0x03
32#define TPS65132_REG_CONTROL 0x0FF
33
34#define TPS65132_VOUT_MASK 0x1F
35#define TPS65132_VOUT_N_VOLTAGE 0x15
36#define TPS65132_VOUT_VMIN 4000000
37#define TPS65132_VOUT_VMAX 6000000
38#define TPS65132_VOUT_STEP 100000
39
40#define TPS65132_REG_APPS_DIS_VPOS BIT(0)
41#define TPS65132_REG_APPS_DIS_VNEG BIT(1)
42
43#define TPS65132_REGULATOR_ID_VPOS 0
44#define TPS65132_REGULATOR_ID_VNEG 1
45#define TPS65132_MAX_REGULATORS 2
46
47#define TPS65132_ACT_DIS_TIME_SLACK 1000
48
49struct tps65132_reg_pdata {
50 struct gpio_desc *en_gpiod;
51 struct gpio_desc *act_dis_gpiod;
52 unsigned int act_dis_time_us;
53 int ena_gpio_state;
54};
55
56struct tps65132_regulator {
57 struct device *dev;
58 struct regmap *rmap;
59 struct regulator_desc *rdesc[TPS65132_MAX_REGULATORS];
60 struct tps65132_reg_pdata reg_pdata[TPS65132_MAX_REGULATORS];
61 struct regulator_dev *rdev[TPS65132_MAX_REGULATORS];
62};
63
64static int tps65132_regulator_enable(struct regulator_dev *rdev)
65{
66 struct tps65132_regulator *tps = rdev_get_drvdata(rdev);
67 int id = rdev_get_id(rdev);
68 struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[id];
69 int ret;
70
71 if (!IS_ERR(rpdata->en_gpiod)) {
72 gpiod_set_value_cansleep(rpdata->en_gpiod, 1);
73 rpdata->ena_gpio_state = 1;
74 }
75
76 /* Hardware automatically enable discharge bit in enable */
77 if (rdev->constraints->active_discharge ==
78 REGULATOR_ACTIVE_DISCHARGE_DISABLE) {
79 ret = regulator_set_active_discharge_regmap(rdev, false);
80 if (ret < 0) {
81 dev_err(tps->dev, "Failed to disable active discharge: %d\n",
82 ret);
83 return ret;
84 }
85 }
86
87 return 0;
88}
89
90static int tps65132_regulator_disable(struct regulator_dev *rdev)
91{
92 struct tps65132_regulator *tps = rdev_get_drvdata(rdev);
93 int id = rdev_get_id(rdev);
94 struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[id];
95
96 if (!IS_ERR(rpdata->en_gpiod)) {
97 gpiod_set_value_cansleep(rpdata->en_gpiod, 0);
98 rpdata->ena_gpio_state = 0;
99 }
100
101 if (!IS_ERR(rpdata->act_dis_gpiod)) {
102 gpiod_set_value_cansleep(rpdata->act_dis_gpiod, 1);
103 usleep_range(rpdata->act_dis_time_us, rpdata->act_dis_time_us +
104 TPS65132_ACT_DIS_TIME_SLACK);
105 gpiod_set_value_cansleep(rpdata->act_dis_gpiod, 0);
106 }
107
108 return 0;
109}
110
111static int tps65132_regulator_is_enabled(struct regulator_dev *rdev)
112{
113 struct tps65132_regulator *tps = rdev_get_drvdata(rdev);
114 int id = rdev_get_id(rdev);
115 struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[id];
116
117 if (!IS_ERR(rpdata->en_gpiod))
118 return rpdata->ena_gpio_state;
119
120 return 1;
121}
122
123static struct regulator_ops tps65132_regulator_ops = {
124 .enable = tps65132_regulator_enable,
125 .disable = tps65132_regulator_disable,
126 .is_enabled = tps65132_regulator_is_enabled,
127 .list_voltage = regulator_list_voltage_linear,
128 .map_voltage = regulator_map_voltage_linear,
129 .get_voltage_sel = regulator_get_voltage_sel_regmap,
130 .set_voltage_sel = regulator_set_voltage_sel_regmap,
131 .set_active_discharge = regulator_set_active_discharge_regmap,
132};
133
134static int tps65132_of_parse_cb(struct device_node *np,
135 const struct regulator_desc *desc,
136 struct regulator_config *config)
137{
138 struct tps65132_regulator *tps = config->driver_data;
139 struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[desc->id];
140 int ret;
141
142 rpdata->en_gpiod = devm_fwnode_get_index_gpiod_from_child(tps->dev,
143 "enable", 0, &np->fwnode, 0, "enable");
144 if (IS_ERR(rpdata->en_gpiod)) {
145 ret = PTR_ERR(rpdata->en_gpiod);
146
147 /* Ignore the error other than probe defer */
148 if (ret == -EPROBE_DEFER)
149 return ret;
150 return 0;
151 }
152
153 rpdata->act_dis_gpiod = devm_fwnode_get_index_gpiod_from_child(
154 tps->dev, "active-discharge", 0,
155 &np->fwnode, 0, "active-discharge");
156 if (IS_ERR(rpdata->act_dis_gpiod)) {
157 ret = PTR_ERR(rpdata->act_dis_gpiod);
158
159 /* Ignore the error other than probe defer */
160 if (ret == -EPROBE_DEFER)
161 return ret;
162
163 return 0;
164 }
165
166 ret = of_property_read_u32(np, "ti,active-discharge-time-us",
167 &rpdata->act_dis_time_us);
168 if (ret < 0) {
169 dev_err(tps->dev, "Failed to read active discharge time:%d\n",
170 ret);
171 return ret;
172 }
173
174 return 0;
175}
176
177#define TPS65132_REGULATOR_DESC(_id, _name) \
178 [TPS65132_REGULATOR_ID_##_id] = { \
179 .name = "tps65132-"#_name, \
180 .supply_name = "vin", \
181 .id = TPS65132_REGULATOR_ID_##_id, \
182 .of_match = of_match_ptr(#_name), \
183 .of_parse_cb = tps65132_of_parse_cb, \
184 .ops = &tps65132_regulator_ops, \
185 .n_voltages = TPS65132_VOUT_N_VOLTAGE, \
186 .min_uV = TPS65132_VOUT_VMIN, \
187 .uV_step = TPS65132_VOUT_STEP, \
188 .enable_time = 500, \
189 .vsel_mask = TPS65132_VOUT_MASK, \
190 .vsel_reg = TPS65132_REG_##_id, \
191 .active_discharge_off = 0, \
192 .active_discharge_on = TPS65132_REG_APPS_DIS_##_id, \
193 .active_discharge_mask = TPS65132_REG_APPS_DIS_##_id, \
194 .active_discharge_reg = TPS65132_REG_APPS_DISP_DISN, \
195 .type = REGULATOR_VOLTAGE, \
196 .owner = THIS_MODULE, \
197 }
198
199static struct regulator_desc tps_regs_desc[TPS65132_MAX_REGULATORS] = {
200 TPS65132_REGULATOR_DESC(VPOS, outp),
201 TPS65132_REGULATOR_DESC(VNEG, outn),
202};
203
204static const struct regmap_range tps65132_no_reg_ranges[] = {
205 regmap_reg_range(TPS65132_REG_APPS_DISP_DISN + 1,
206 TPS65132_REG_CONTROL - 1),
207};
208
209static const struct regmap_access_table tps65132_no_reg_table = {
210 .no_ranges = tps65132_no_reg_ranges,
211 .n_no_ranges = ARRAY_SIZE(tps65132_no_reg_ranges),
212};
213
214static const struct regmap_config tps65132_regmap_config = {
215 .reg_bits = 8,
216 .val_bits = 8,
217 .max_register = TPS65132_REG_CONTROL + 1,
218 .cache_type = REGCACHE_NONE,
219 .rd_table = &tps65132_no_reg_table,
220 .wr_table = &tps65132_no_reg_table,
221};
222
223static int tps65132_probe(struct i2c_client *client,
224 const struct i2c_device_id *client_id)
225{
226 struct device *dev = &client->dev;
227 struct tps65132_regulator *tps;
228 struct regulator_config config = { };
229 int id;
230 int ret;
231
232 tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
233 if (!tps)
234 return -ENOMEM;
235
236 tps->rmap = devm_regmap_init_i2c(client, &tps65132_regmap_config);
237 if (IS_ERR(tps->rmap)) {
238 ret = PTR_ERR(tps->rmap);
239 dev_err(dev, "regmap init failed: %d\n", ret);
240 return ret;
241 }
242
243 i2c_set_clientdata(client, tps);
244 tps->dev = dev;
245
246 for (id = 0; id < TPS65132_MAX_REGULATORS; ++id) {
247 tps->rdesc[id] = &tps_regs_desc[id];
248
249 config.regmap = tps->rmap;
250 config.dev = dev;
251 config.driver_data = tps;
252
253 tps->rdev[id] = devm_regulator_register(dev,
254 tps->rdesc[id], &config);
255 if (IS_ERR(tps->rdev[id])) {
256 ret = PTR_ERR(tps->rdev[id]);
257 dev_err(dev, "regulator %s register failed: %d\n",
258 tps->rdesc[id]->name, ret);
259 return ret;
260 }
261 }
262 return 0;
263}
264
265static const struct i2c_device_id tps65132_id[] = {
266 {.name = "tps65132",},
267 {},
268};
269MODULE_DEVICE_TABLE(i2c, tps65132_id);
270
271static struct i2c_driver tps65132_i2c_driver = {
272 .driver = {
273 .name = "tps65132",
274 .owner = THIS_MODULE,
275 },
276 .probe = tps65132_probe,
277 .id_table = tps65132_id,
278};
279
280module_i2c_driver(tps65132_i2c_driver);
281
282MODULE_DESCRIPTION("tps65132 regulator driver");
283MODULE_AUTHOR("Venkat Reddy Talla <vreddytalla@nvidia.com>");
284MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
285MODULE_LICENSE("GPL v2");