1 /*
2  * Voltage regulator support for AMS AS3722 PMIC
3  *
4  * Copyright (C) 2013 ams
5  *
6  * Author: Florian Lobmaier <florian.lobmaier@ams.com>
7  * Author: Laxman Dewangan <ldewangan@nvidia.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22  *
23  */
24 
25 #include <linux/err.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/mfd/as3722.h>
29 #include <linux/of.h>
30 #include <linux/of_platform.h>
31 #include <linux/platform_device.h>
32 #include <linux/regulator/driver.h>
33 #include <linux/regulator/machine.h>
34 #include <linux/regulator/of_regulator.h>
35 #include <linux/slab.h>
36 
37 /* Regulator IDs */
38 enum as3722_regulators_id {
39 	AS3722_REGULATOR_ID_SD0,
40 	AS3722_REGULATOR_ID_SD1,
41 	AS3722_REGULATOR_ID_SD2,
42 	AS3722_REGULATOR_ID_SD3,
43 	AS3722_REGULATOR_ID_SD4,
44 	AS3722_REGULATOR_ID_SD5,
45 	AS3722_REGULATOR_ID_SD6,
46 	AS3722_REGULATOR_ID_LDO0,
47 	AS3722_REGULATOR_ID_LDO1,
48 	AS3722_REGULATOR_ID_LDO2,
49 	AS3722_REGULATOR_ID_LDO3,
50 	AS3722_REGULATOR_ID_LDO4,
51 	AS3722_REGULATOR_ID_LDO5,
52 	AS3722_REGULATOR_ID_LDO6,
53 	AS3722_REGULATOR_ID_LDO7,
54 	AS3722_REGULATOR_ID_LDO9,
55 	AS3722_REGULATOR_ID_LDO10,
56 	AS3722_REGULATOR_ID_LDO11,
57 	AS3722_REGULATOR_ID_MAX,
58 };
59 
60 struct as3722_register_mapping {
61 	u8 regulator_id;
62 	const char *name;
63 	const char *sname;
64 	u8 vsel_reg;
65 	u8 vsel_mask;
66 	int n_voltages;
67 	u32 enable_reg;
68 	u8 enable_mask;
69 	u32 control_reg;
70 	u8 mode_mask;
71 	u32 sleep_ctrl_reg;
72 	u8 sleep_ctrl_mask;
73 };
74 
75 struct as3722_regulator_config_data {
76 	struct regulator_init_data *reg_init;
77 	bool enable_tracking;
78 	int ext_control;
79 };
80 
81 struct as3722_regulators {
82 	struct device *dev;
83 	struct as3722 *as3722;
84 	struct regulator_dev *rdevs[AS3722_REGULATOR_ID_MAX];
85 	struct regulator_desc desc[AS3722_REGULATOR_ID_MAX];
86 	struct as3722_regulator_config_data
87 			reg_config_data[AS3722_REGULATOR_ID_MAX];
88 };
89 
90 static const struct as3722_register_mapping as3722_reg_lookup[] = {
91 	{
92 		.regulator_id = AS3722_REGULATOR_ID_SD0,
93 		.name = "as3722-sd0",
94 		.vsel_reg = AS3722_SD0_VOLTAGE_REG,
95 		.vsel_mask = AS3722_SD_VSEL_MASK,
96 		.enable_reg = AS3722_SD_CONTROL_REG,
97 		.enable_mask = AS3722_SDn_CTRL(0),
98 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
99 		.sleep_ctrl_mask = AS3722_SD0_EXT_ENABLE_MASK,
100 		.control_reg = AS3722_SD0_CONTROL_REG,
101 		.mode_mask = AS3722_SD0_MODE_FAST,
102 		.n_voltages = AS3722_SD0_VSEL_MAX + 1,
103 	},
104 	{
105 		.regulator_id = AS3722_REGULATOR_ID_SD1,
106 		.name = "as3722-sd1",
107 		.vsel_reg = AS3722_SD1_VOLTAGE_REG,
108 		.vsel_mask = AS3722_SD_VSEL_MASK,
109 		.enable_reg = AS3722_SD_CONTROL_REG,
110 		.enable_mask = AS3722_SDn_CTRL(1),
111 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
112 		.sleep_ctrl_mask = AS3722_SD1_EXT_ENABLE_MASK,
113 		.control_reg = AS3722_SD1_CONTROL_REG,
114 		.mode_mask = AS3722_SD1_MODE_FAST,
115 		.n_voltages = AS3722_SD0_VSEL_MAX + 1,
116 	},
117 	{
118 		.regulator_id = AS3722_REGULATOR_ID_SD2,
119 		.name = "as3722-sd2",
120 		.sname = "vsup-sd2",
121 		.vsel_reg = AS3722_SD2_VOLTAGE_REG,
122 		.vsel_mask = AS3722_SD_VSEL_MASK,
123 		.enable_reg = AS3722_SD_CONTROL_REG,
124 		.enable_mask = AS3722_SDn_CTRL(2),
125 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
126 		.sleep_ctrl_mask = AS3722_SD2_EXT_ENABLE_MASK,
127 		.control_reg = AS3722_SD23_CONTROL_REG,
128 		.mode_mask = AS3722_SD2_MODE_FAST,
129 		.n_voltages = AS3722_SD2_VSEL_MAX + 1,
130 	},
131 	{
132 		.regulator_id = AS3722_REGULATOR_ID_SD3,
133 		.name = "as3722-sd3",
134 		.sname = "vsup-sd3",
135 		.vsel_reg = AS3722_SD3_VOLTAGE_REG,
136 		.vsel_mask = AS3722_SD_VSEL_MASK,
137 		.enable_reg = AS3722_SD_CONTROL_REG,
138 		.enable_mask = AS3722_SDn_CTRL(3),
139 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
140 		.sleep_ctrl_mask = AS3722_SD3_EXT_ENABLE_MASK,
141 		.control_reg = AS3722_SD23_CONTROL_REG,
142 		.mode_mask = AS3722_SD3_MODE_FAST,
143 		.n_voltages = AS3722_SD2_VSEL_MAX + 1,
144 	},
145 	{
146 		.regulator_id = AS3722_REGULATOR_ID_SD4,
147 		.name = "as3722-sd4",
148 		.sname = "vsup-sd4",
149 		.vsel_reg = AS3722_SD4_VOLTAGE_REG,
150 		.vsel_mask = AS3722_SD_VSEL_MASK,
151 		.enable_reg = AS3722_SD_CONTROL_REG,
152 		.enable_mask = AS3722_SDn_CTRL(4),
153 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
154 		.sleep_ctrl_mask = AS3722_SD4_EXT_ENABLE_MASK,
155 		.control_reg = AS3722_SD4_CONTROL_REG,
156 		.mode_mask = AS3722_SD4_MODE_FAST,
157 		.n_voltages = AS3722_SD2_VSEL_MAX + 1,
158 	},
159 	{
160 		.regulator_id = AS3722_REGULATOR_ID_SD5,
161 		.name = "as3722-sd5",
162 		.sname = "vsup-sd5",
163 		.vsel_reg = AS3722_SD5_VOLTAGE_REG,
164 		.vsel_mask = AS3722_SD_VSEL_MASK,
165 		.enable_reg = AS3722_SD_CONTROL_REG,
166 		.enable_mask = AS3722_SDn_CTRL(5),
167 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
168 		.sleep_ctrl_mask = AS3722_SD5_EXT_ENABLE_MASK,
169 		.control_reg = AS3722_SD5_CONTROL_REG,
170 		.mode_mask = AS3722_SD5_MODE_FAST,
171 		.n_voltages = AS3722_SD2_VSEL_MAX + 1,
172 	},
173 	{
174 		.regulator_id = AS3722_REGULATOR_ID_SD6,
175 		.name = "as3722-sd6",
176 		.vsel_reg = AS3722_SD6_VOLTAGE_REG,
177 		.vsel_mask = AS3722_SD_VSEL_MASK,
178 		.enable_reg = AS3722_SD_CONTROL_REG,
179 		.enable_mask = AS3722_SDn_CTRL(6),
180 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
181 		.sleep_ctrl_mask = AS3722_SD6_EXT_ENABLE_MASK,
182 		.control_reg = AS3722_SD6_CONTROL_REG,
183 		.mode_mask = AS3722_SD6_MODE_FAST,
184 		.n_voltages = AS3722_SD0_VSEL_MAX + 1,
185 	},
186 	{
187 		.regulator_id = AS3722_REGULATOR_ID_LDO0,
188 		.name = "as3722-ldo0",
189 		.sname = "vin-ldo0",
190 		.vsel_reg = AS3722_LDO0_VOLTAGE_REG,
191 		.vsel_mask = AS3722_LDO0_VSEL_MASK,
192 		.enable_reg = AS3722_LDOCONTROL0_REG,
193 		.enable_mask = AS3722_LDO0_CTRL,
194 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
195 		.sleep_ctrl_mask = AS3722_LDO0_EXT_ENABLE_MASK,
196 		.n_voltages = AS3722_LDO0_NUM_VOLT,
197 	},
198 	{
199 		.regulator_id = AS3722_REGULATOR_ID_LDO1,
200 		.name = "as3722-ldo1",
201 		.sname = "vin-ldo1-6",
202 		.vsel_reg = AS3722_LDO1_VOLTAGE_REG,
203 		.vsel_mask = AS3722_LDO_VSEL_MASK,
204 		.enable_reg = AS3722_LDOCONTROL0_REG,
205 		.enable_mask = AS3722_LDO1_CTRL,
206 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
207 		.sleep_ctrl_mask = AS3722_LDO1_EXT_ENABLE_MASK,
208 		.n_voltages = AS3722_LDO_NUM_VOLT,
209 	},
210 	{
211 		.regulator_id = AS3722_REGULATOR_ID_LDO2,
212 		.name = "as3722-ldo2",
213 		.sname = "vin-ldo2-5-7",
214 		.vsel_reg = AS3722_LDO2_VOLTAGE_REG,
215 		.vsel_mask = AS3722_LDO_VSEL_MASK,
216 		.enable_reg = AS3722_LDOCONTROL0_REG,
217 		.enable_mask = AS3722_LDO2_CTRL,
218 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
219 		.sleep_ctrl_mask = AS3722_LDO2_EXT_ENABLE_MASK,
220 		.n_voltages = AS3722_LDO_NUM_VOLT,
221 	},
222 	{
223 		.regulator_id = AS3722_REGULATOR_ID_LDO3,
224 		.name = "as3722-ldo3",
225 		.name = "vin-ldo3-4",
226 		.vsel_reg = AS3722_LDO3_VOLTAGE_REG,
227 		.vsel_mask = AS3722_LDO3_VSEL_MASK,
228 		.enable_reg = AS3722_LDOCONTROL0_REG,
229 		.enable_mask = AS3722_LDO3_CTRL,
230 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
231 		.sleep_ctrl_mask = AS3722_LDO3_EXT_ENABLE_MASK,
232 		.n_voltages = AS3722_LDO3_NUM_VOLT,
233 	},
234 	{
235 		.regulator_id = AS3722_REGULATOR_ID_LDO4,
236 		.name = "as3722-ldo4",
237 		.name = "vin-ldo3-4",
238 		.vsel_reg = AS3722_LDO4_VOLTAGE_REG,
239 		.vsel_mask = AS3722_LDO_VSEL_MASK,
240 		.enable_reg = AS3722_LDOCONTROL0_REG,
241 		.enable_mask = AS3722_LDO4_CTRL,
242 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
243 		.sleep_ctrl_mask = AS3722_LDO4_EXT_ENABLE_MASK,
244 		.n_voltages = AS3722_LDO_NUM_VOLT,
245 	},
246 	{
247 		.regulator_id = AS3722_REGULATOR_ID_LDO5,
248 		.name = "as3722-ldo5",
249 		.sname = "vin-ldo2-5-7",
250 		.vsel_reg = AS3722_LDO5_VOLTAGE_REG,
251 		.vsel_mask = AS3722_LDO_VSEL_MASK,
252 		.enable_reg = AS3722_LDOCONTROL0_REG,
253 		.enable_mask = AS3722_LDO5_CTRL,
254 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
255 		.sleep_ctrl_mask = AS3722_LDO5_EXT_ENABLE_MASK,
256 		.n_voltages = AS3722_LDO_NUM_VOLT,
257 	},
258 	{
259 		.regulator_id = AS3722_REGULATOR_ID_LDO6,
260 		.name = "as3722-ldo6",
261 		.sname = "vin-ldo1-6",
262 		.vsel_reg = AS3722_LDO6_VOLTAGE_REG,
263 		.vsel_mask = AS3722_LDO_VSEL_MASK,
264 		.enable_reg = AS3722_LDOCONTROL0_REG,
265 		.enable_mask = AS3722_LDO6_CTRL,
266 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
267 		.sleep_ctrl_mask = AS3722_LDO6_EXT_ENABLE_MASK,
268 		.n_voltages = AS3722_LDO_NUM_VOLT,
269 	},
270 	{
271 		.regulator_id = AS3722_REGULATOR_ID_LDO7,
272 		.name = "as3722-ldo7",
273 		.sname = "vin-ldo2-5-7",
274 		.vsel_reg = AS3722_LDO7_VOLTAGE_REG,
275 		.vsel_mask = AS3722_LDO_VSEL_MASK,
276 		.enable_reg = AS3722_LDOCONTROL0_REG,
277 		.enable_mask = AS3722_LDO7_CTRL,
278 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
279 		.sleep_ctrl_mask = AS3722_LDO7_EXT_ENABLE_MASK,
280 		.n_voltages = AS3722_LDO_NUM_VOLT,
281 	},
282 	{
283 		.regulator_id = AS3722_REGULATOR_ID_LDO9,
284 		.name = "as3722-ldo9",
285 		.sname = "vin-ldo9-10",
286 		.vsel_reg = AS3722_LDO9_VOLTAGE_REG,
287 		.vsel_mask = AS3722_LDO_VSEL_MASK,
288 		.enable_reg = AS3722_LDOCONTROL1_REG,
289 		.enable_mask = AS3722_LDO9_CTRL,
290 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG,
291 		.sleep_ctrl_mask = AS3722_LDO9_EXT_ENABLE_MASK,
292 		.n_voltages = AS3722_LDO_NUM_VOLT,
293 	},
294 	{
295 		.regulator_id = AS3722_REGULATOR_ID_LDO10,
296 		.name = "as3722-ldo10",
297 		.sname = "vin-ldo9-10",
298 		.vsel_reg = AS3722_LDO10_VOLTAGE_REG,
299 		.vsel_mask = AS3722_LDO_VSEL_MASK,
300 		.enable_reg = AS3722_LDOCONTROL1_REG,
301 		.enable_mask = AS3722_LDO10_CTRL,
302 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG,
303 		.sleep_ctrl_mask = AS3722_LDO10_EXT_ENABLE_MASK,
304 		.n_voltages = AS3722_LDO_NUM_VOLT,
305 	},
306 	{
307 		.regulator_id = AS3722_REGULATOR_ID_LDO11,
308 		.name = "as3722-ldo11",
309 		.sname = "vin-ldo11",
310 		.vsel_reg = AS3722_LDO11_VOLTAGE_REG,
311 		.vsel_mask = AS3722_LDO_VSEL_MASK,
312 		.enable_reg = AS3722_LDOCONTROL1_REG,
313 		.enable_mask = AS3722_LDO11_CTRL,
314 		.sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG,
315 		.sleep_ctrl_mask = AS3722_LDO11_EXT_ENABLE_MASK,
316 		.n_voltages = AS3722_LDO_NUM_VOLT,
317 	},
318 };
319 
320 
321 static const int as3722_ldo_current[] = { 150000, 300000 };
322 static const int as3722_sd016_current[] = { 2500000, 3000000, 3500000 };
323 
324 static int as3722_current_to_index(int min_uA, int max_uA,
325 		const int *curr_table, int n_currents)
326 {
327 	int i;
328 
329 	for (i = n_currents - 1; i >= 0; i--) {
330 		if ((min_uA <= curr_table[i]) && (curr_table[i] <= max_uA))
331 			return i;
332 	}
333 	return -EINVAL;
334 }
335 
336 static int as3722_ldo_get_current_limit(struct regulator_dev *rdev)
337 {
338 	struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
339 	struct as3722 *as3722 = as3722_regs->as3722;
340 	int id = rdev_get_id(rdev);
341 	u32 val;
342 	int ret;
343 
344 	ret = as3722_read(as3722, as3722_reg_lookup[id].vsel_reg, &val);
345 	if (ret < 0) {
346 		dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
347 			as3722_reg_lookup[id].vsel_reg, ret);
348 		return ret;
349 	}
350 	if (val & AS3722_LDO_ILIMIT_MASK)
351 		return 300000;
352 	return 150000;
353 }
354 
355 static int as3722_ldo_set_current_limit(struct regulator_dev *rdev,
356 		int min_uA, int max_uA)
357 {
358 	struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
359 	struct as3722 *as3722 = as3722_regs->as3722;
360 	int id = rdev_get_id(rdev);
361 	int ret;
362 	u32 reg = 0;
363 
364 	ret = as3722_current_to_index(min_uA, max_uA, as3722_ldo_current,
365 				ARRAY_SIZE(as3722_ldo_current));
366 	if (ret < 0) {
367 		dev_err(as3722_regs->dev,
368 			"Current range min:max = %d:%d does not support\n",
369 			min_uA, max_uA);
370 		return ret;
371 	}
372 	if (ret)
373 		reg = AS3722_LDO_ILIMIT_BIT;
374 	return as3722_update_bits(as3722, as3722_reg_lookup[id].vsel_reg,
375 			AS3722_LDO_ILIMIT_MASK, reg);
376 }
377 
378 static struct regulator_ops as3722_ldo0_ops = {
379 	.is_enabled = regulator_is_enabled_regmap,
380 	.enable = regulator_enable_regmap,
381 	.disable = regulator_disable_regmap,
382 	.list_voltage = regulator_list_voltage_linear,
383 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
384 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
385 	.get_current_limit = as3722_ldo_get_current_limit,
386 	.set_current_limit = as3722_ldo_set_current_limit,
387 };
388 
389 static struct regulator_ops as3722_ldo0_extcntrl_ops = {
390 	.list_voltage = regulator_list_voltage_linear,
391 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
392 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
393 	.get_current_limit = as3722_ldo_get_current_limit,
394 	.set_current_limit = as3722_ldo_set_current_limit,
395 };
396 
397 static int as3722_ldo3_set_tracking_mode(struct as3722_regulators *as3722_reg,
398 		int id, u8 mode)
399 {
400 	struct as3722 *as3722 = as3722_reg->as3722;
401 
402 	switch (mode) {
403 	case AS3722_LDO3_MODE_PMOS:
404 	case AS3722_LDO3_MODE_PMOS_TRACKING:
405 	case AS3722_LDO3_MODE_NMOS:
406 	case AS3722_LDO3_MODE_SWITCH:
407 		return as3722_update_bits(as3722,
408 			as3722_reg_lookup[id].vsel_reg,
409 			AS3722_LDO3_MODE_MASK, mode);
410 
411 	default:
412 		return -EINVAL;
413 	}
414 }
415 
416 static int as3722_ldo3_get_current_limit(struct regulator_dev *rdev)
417 {
418 	return 150000;
419 }
420 
421 static struct regulator_ops as3722_ldo3_ops = {
422 	.is_enabled = regulator_is_enabled_regmap,
423 	.enable = regulator_enable_regmap,
424 	.disable = regulator_disable_regmap,
425 	.list_voltage = regulator_list_voltage_linear,
426 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
427 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
428 	.get_current_limit = as3722_ldo3_get_current_limit,
429 };
430 
431 static struct regulator_ops as3722_ldo3_extcntrl_ops = {
432 	.list_voltage = regulator_list_voltage_linear,
433 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
434 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
435 	.get_current_limit = as3722_ldo3_get_current_limit,
436 };
437 
438 static const struct regulator_linear_range as3722_ldo_ranges[] = {
439 	REGULATOR_LINEAR_RANGE(825000, 0x01, 0x24, 25000),
440 	REGULATOR_LINEAR_RANGE(1725000, 0x40, 0x7F, 25000),
441 };
442 
443 static struct regulator_ops as3722_ldo_ops = {
444 	.is_enabled = regulator_is_enabled_regmap,
445 	.enable = regulator_enable_regmap,
446 	.disable = regulator_disable_regmap,
447 	.map_voltage = regulator_map_voltage_linear_range,
448 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
449 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
450 	.list_voltage = regulator_list_voltage_linear_range,
451 	.get_current_limit = as3722_ldo_get_current_limit,
452 	.set_current_limit = as3722_ldo_set_current_limit,
453 };
454 
455 static struct regulator_ops as3722_ldo_extcntrl_ops = {
456 	.map_voltage = regulator_map_voltage_linear_range,
457 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
458 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
459 	.list_voltage = regulator_list_voltage_linear_range,
460 	.get_current_limit = as3722_ldo_get_current_limit,
461 	.set_current_limit = as3722_ldo_set_current_limit,
462 };
463 
464 static unsigned int as3722_sd_get_mode(struct regulator_dev *rdev)
465 {
466 	struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
467 	struct as3722 *as3722 = as3722_regs->as3722;
468 	int id = rdev_get_id(rdev);
469 	u32 val;
470 	int ret;
471 
472 	if (!as3722_reg_lookup[id].control_reg)
473 		return -ENOTSUPP;
474 
475 	ret = as3722_read(as3722, as3722_reg_lookup[id].control_reg, &val);
476 	if (ret < 0) {
477 		dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
478 			as3722_reg_lookup[id].control_reg, ret);
479 		return ret;
480 	}
481 
482 	if (val & as3722_reg_lookup[id].mode_mask)
483 		return REGULATOR_MODE_FAST;
484 	else
485 		return REGULATOR_MODE_NORMAL;
486 }
487 
488 static int as3722_sd_set_mode(struct regulator_dev *rdev,
489 		unsigned int mode)
490 {
491 	struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
492 	struct as3722 *as3722 = as3722_regs->as3722;
493 	u8 id = rdev_get_id(rdev);
494 	u8 val = 0;
495 	int ret;
496 
497 	if (!as3722_reg_lookup[id].control_reg)
498 		return -ERANGE;
499 
500 	switch (mode) {
501 	case REGULATOR_MODE_FAST:
502 		val = as3722_reg_lookup[id].mode_mask;
503 	case REGULATOR_MODE_NORMAL: /* fall down */
504 		break;
505 	default:
506 		return -EINVAL;
507 	}
508 
509 	ret = as3722_update_bits(as3722, as3722_reg_lookup[id].control_reg,
510 			as3722_reg_lookup[id].mode_mask, val);
511 	if (ret < 0) {
512 		dev_err(as3722_regs->dev, "Reg 0x%02x update failed: %d\n",
513 			as3722_reg_lookup[id].control_reg, ret);
514 		return ret;
515 	}
516 	return ret;
517 }
518 
519 static int as3722_sd016_get_current_limit(struct regulator_dev *rdev)
520 {
521 	struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
522 	struct as3722 *as3722 = as3722_regs->as3722;
523 	int id = rdev_get_id(rdev);
524 	u32 val, reg;
525 	int mask;
526 	int ret;
527 
528 	switch (id) {
529 	case AS3722_REGULATOR_ID_SD0:
530 		reg = AS3722_OVCURRENT_REG;
531 		mask = AS3722_OVCURRENT_SD0_TRIP_MASK;
532 		break;
533 	case AS3722_REGULATOR_ID_SD1:
534 		reg = AS3722_OVCURRENT_REG;
535 		mask = AS3722_OVCURRENT_SD1_TRIP_MASK;
536 		break;
537 	case AS3722_REGULATOR_ID_SD6:
538 		reg = AS3722_OVCURRENT_DEB_REG;
539 		mask = AS3722_OVCURRENT_SD6_TRIP_MASK;
540 		break;
541 	default:
542 		return -EINVAL;
543 	}
544 	ret = as3722_read(as3722, reg, &val);
545 	if (ret < 0) {
546 		dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
547 			reg, ret);
548 		return ret;
549 	}
550 	val &= mask;
551 	val >>= ffs(mask) - 1;
552 	if (val == 3)
553 		return -EINVAL;
554 	return as3722_sd016_current[val];
555 }
556 
557 static int as3722_sd016_set_current_limit(struct regulator_dev *rdev,
558 		int min_uA, int max_uA)
559 {
560 	struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
561 	struct as3722 *as3722 = as3722_regs->as3722;
562 	int id = rdev_get_id(rdev);
563 	int ret;
564 	int val;
565 	int mask;
566 	u32 reg;
567 
568 	ret = as3722_current_to_index(min_uA, max_uA, as3722_sd016_current,
569 				ARRAY_SIZE(as3722_sd016_current));
570 	if (ret < 0) {
571 		dev_err(as3722_regs->dev,
572 			"Current range min:max = %d:%d does not support\n",
573 			min_uA, max_uA);
574 		return ret;
575 	}
576 
577 	switch (id) {
578 	case AS3722_REGULATOR_ID_SD0:
579 		reg = AS3722_OVCURRENT_REG;
580 		mask = AS3722_OVCURRENT_SD0_TRIP_MASK;
581 		break;
582 	case AS3722_REGULATOR_ID_SD1:
583 		reg = AS3722_OVCURRENT_REG;
584 		mask = AS3722_OVCURRENT_SD1_TRIP_MASK;
585 		break;
586 	case AS3722_REGULATOR_ID_SD6:
587 		reg = AS3722_OVCURRENT_DEB_REG;
588 		mask = AS3722_OVCURRENT_SD6_TRIP_MASK;
589 		break;
590 	default:
591 		return -EINVAL;
592 	}
593 	ret <<= ffs(mask) - 1;
594 	val = ret & mask;
595 	return as3722_update_bits(as3722, reg, mask, val);
596 }
597 
598 static const struct regulator_linear_range as3722_sd2345_ranges[] = {
599 	REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500),
600 	REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000),
601 	REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7F, 50000),
602 };
603 
604 static struct regulator_ops as3722_sd016_ops = {
605 	.is_enabled = regulator_is_enabled_regmap,
606 	.enable = regulator_enable_regmap,
607 	.disable = regulator_disable_regmap,
608 	.list_voltage = regulator_list_voltage_linear,
609 	.map_voltage = regulator_map_voltage_linear,
610 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
611 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
612 	.get_current_limit = as3722_sd016_get_current_limit,
613 	.set_current_limit = as3722_sd016_set_current_limit,
614 	.get_mode = as3722_sd_get_mode,
615 	.set_mode = as3722_sd_set_mode,
616 };
617 
618 static struct regulator_ops as3722_sd016_extcntrl_ops = {
619 	.list_voltage = regulator_list_voltage_linear,
620 	.map_voltage = regulator_map_voltage_linear,
621 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
622 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
623 	.get_current_limit = as3722_sd016_get_current_limit,
624 	.set_current_limit = as3722_sd016_set_current_limit,
625 	.get_mode = as3722_sd_get_mode,
626 	.set_mode = as3722_sd_set_mode,
627 };
628 
629 static struct regulator_ops as3722_sd2345_ops = {
630 	.is_enabled = regulator_is_enabled_regmap,
631 	.enable = regulator_enable_regmap,
632 	.disable = regulator_disable_regmap,
633 	.list_voltage = regulator_list_voltage_linear_range,
634 	.map_voltage = regulator_map_voltage_linear_range,
635 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
636 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
637 	.get_mode = as3722_sd_get_mode,
638 	.set_mode = as3722_sd_set_mode,
639 };
640 
641 static struct regulator_ops as3722_sd2345_extcntrl_ops = {
642 	.list_voltage = regulator_list_voltage_linear_range,
643 	.map_voltage = regulator_map_voltage_linear_range,
644 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
645 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
646 	.get_mode = as3722_sd_get_mode,
647 	.set_mode = as3722_sd_set_mode,
648 };
649 
650 static int as3722_extreg_init(struct as3722_regulators *as3722_regs, int id,
651 		int ext_pwr_ctrl)
652 {
653 	int ret;
654 	unsigned int val;
655 
656 	if ((ext_pwr_ctrl < AS3722_EXT_CONTROL_ENABLE1) ||
657 		(ext_pwr_ctrl > AS3722_EXT_CONTROL_ENABLE3))
658 		return -EINVAL;
659 
660 	val =  ext_pwr_ctrl << (ffs(as3722_reg_lookup[id].sleep_ctrl_mask) - 1);
661 	ret = as3722_update_bits(as3722_regs->as3722,
662 			as3722_reg_lookup[id].sleep_ctrl_reg,
663 			as3722_reg_lookup[id].sleep_ctrl_mask, val);
664 	if (ret < 0)
665 		dev_err(as3722_regs->dev, "Reg 0x%02x update failed: %d\n",
666 			as3722_reg_lookup[id].sleep_ctrl_reg, ret);
667 	return ret;
668 }
669 
670 static struct of_regulator_match as3722_regulator_matches[] = {
671 	{ .name = "sd0", },
672 	{ .name = "sd1", },
673 	{ .name = "sd2", },
674 	{ .name = "sd3", },
675 	{ .name = "sd4", },
676 	{ .name = "sd5", },
677 	{ .name = "sd6", },
678 	{ .name = "ldo0", },
679 	{ .name = "ldo1", },
680 	{ .name = "ldo2", },
681 	{ .name = "ldo3", },
682 	{ .name = "ldo4", },
683 	{ .name = "ldo5", },
684 	{ .name = "ldo6", },
685 	{ .name = "ldo7", },
686 	{ .name = "ldo9", },
687 	{ .name = "ldo10", },
688 	{ .name = "ldo11", },
689 };
690 
691 static int as3722_get_regulator_dt_data(struct platform_device *pdev,
692 		struct as3722_regulators *as3722_regs)
693 {
694 	struct device_node *np;
695 	struct as3722_regulator_config_data *reg_config;
696 	u32 prop;
697 	int id;
698 	int ret;
699 
700 	np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
701 	if (!np) {
702 		dev_err(&pdev->dev, "Device is not having regulators node\n");
703 		return -ENODEV;
704 	}
705 	pdev->dev.of_node = np;
706 
707 	ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches,
708 			ARRAY_SIZE(as3722_regulator_matches));
709 	if (ret < 0) {
710 		dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n",
711 			ret);
712 		return ret;
713 	}
714 
715 	for (id = 0; id < ARRAY_SIZE(as3722_regulator_matches); ++id) {
716 		struct device_node *reg_node;
717 
718 		reg_config = &as3722_regs->reg_config_data[id];
719 		reg_config->reg_init = as3722_regulator_matches[id].init_data;
720 		reg_node = as3722_regulator_matches[id].of_node;
721 
722 		if (!reg_config->reg_init || !reg_node)
723 			continue;
724 
725 		ret = of_property_read_u32(reg_node, "ams,ext-control", &prop);
726 		if (!ret) {
727 			if (prop < 3)
728 				reg_config->ext_control = prop;
729 			else
730 				dev_warn(&pdev->dev,
731 					"ext-control have invalid option: %u\n",
732 					prop);
733 		}
734 		reg_config->enable_tracking =
735 			of_property_read_bool(reg_node, "ams,enable-tracking");
736 	}
737 	return 0;
738 }
739 
740 static int as3722_regulator_probe(struct platform_device *pdev)
741 {
742 	struct as3722 *as3722 = dev_get_drvdata(pdev->dev.parent);
743 	struct as3722_regulators *as3722_regs;
744 	struct as3722_regulator_config_data *reg_config;
745 	struct regulator_dev *rdev;
746 	struct regulator_config config = { };
747 	struct regulator_ops *ops;
748 	int id;
749 	int ret;
750 
751 	as3722_regs = devm_kzalloc(&pdev->dev, sizeof(*as3722_regs),
752 				GFP_KERNEL);
753 	if (!as3722_regs)
754 		return -ENOMEM;
755 
756 	as3722_regs->dev = &pdev->dev;
757 	as3722_regs->as3722 = as3722;
758 	platform_set_drvdata(pdev, as3722_regs);
759 
760 	ret = as3722_get_regulator_dt_data(pdev, as3722_regs);
761 	if (ret < 0)
762 		return ret;
763 
764 	config.dev = &pdev->dev;
765 	config.driver_data = as3722_regs;
766 	config.regmap = as3722->regmap;
767 
768 	for (id = 0; id < AS3722_REGULATOR_ID_MAX; id++) {
769 		reg_config = &as3722_regs->reg_config_data[id];
770 
771 		as3722_regs->desc[id].name = as3722_reg_lookup[id].name;
772 		as3722_regs->desc[id].supply_name = as3722_reg_lookup[id].sname;
773 		as3722_regs->desc[id].id = as3722_reg_lookup[id].regulator_id;
774 		as3722_regs->desc[id].n_voltages =
775 					as3722_reg_lookup[id].n_voltages;
776 		as3722_regs->desc[id].type = REGULATOR_VOLTAGE;
777 		as3722_regs->desc[id].owner = THIS_MODULE;
778 		as3722_regs->desc[id].enable_reg =
779 					as3722_reg_lookup[id].enable_reg;
780 		as3722_regs->desc[id].enable_mask =
781 					as3722_reg_lookup[id].enable_mask;
782 		as3722_regs->desc[id].vsel_reg = as3722_reg_lookup[id].vsel_reg;
783 		as3722_regs->desc[id].vsel_mask =
784 					as3722_reg_lookup[id].vsel_mask;
785 		switch (id) {
786 		case AS3722_REGULATOR_ID_LDO0:
787 			if (reg_config->ext_control)
788 				ops = &as3722_ldo0_extcntrl_ops;
789 			else
790 				ops = &as3722_ldo0_ops;
791 			as3722_regs->desc[id].min_uV = 825000;
792 			as3722_regs->desc[id].uV_step = 25000;
793 			as3722_regs->desc[id].linear_min_sel = 1;
794 			as3722_regs->desc[id].enable_time = 500;
795 			break;
796 		case AS3722_REGULATOR_ID_LDO3:
797 			if (reg_config->ext_control)
798 				ops = &as3722_ldo3_extcntrl_ops;
799 			else
800 				ops = &as3722_ldo3_ops;
801 			as3722_regs->desc[id].min_uV = 620000;
802 			as3722_regs->desc[id].uV_step = 20000;
803 			as3722_regs->desc[id].linear_min_sel = 1;
804 			as3722_regs->desc[id].enable_time = 500;
805 			if (reg_config->enable_tracking) {
806 				ret = as3722_ldo3_set_tracking_mode(as3722_regs,
807 					id, AS3722_LDO3_MODE_PMOS_TRACKING);
808 				if (ret < 0) {
809 					dev_err(&pdev->dev,
810 						"LDO3 tracking failed: %d\n",
811 						ret);
812 					return ret;
813 				}
814 			}
815 			break;
816 		case AS3722_REGULATOR_ID_SD0:
817 		case AS3722_REGULATOR_ID_SD1:
818 		case AS3722_REGULATOR_ID_SD6:
819 			if (reg_config->ext_control)
820 				ops = &as3722_sd016_extcntrl_ops;
821 			else
822 				ops = &as3722_sd016_ops;
823 			as3722_regs->desc[id].min_uV = 610000;
824 			as3722_regs->desc[id].uV_step = 10000;
825 			as3722_regs->desc[id].linear_min_sel = 1;
826 			break;
827 		case AS3722_REGULATOR_ID_SD2:
828 		case AS3722_REGULATOR_ID_SD3:
829 		case AS3722_REGULATOR_ID_SD4:
830 		case AS3722_REGULATOR_ID_SD5:
831 			if (reg_config->ext_control)
832 				ops = &as3722_sd2345_extcntrl_ops;
833 			else
834 				ops = &as3722_sd2345_ops;
835 			as3722_regs->desc[id].linear_ranges =
836 						as3722_sd2345_ranges;
837 			as3722_regs->desc[id].n_linear_ranges =
838 					ARRAY_SIZE(as3722_sd2345_ranges);
839 			break;
840 		default:
841 			if (reg_config->ext_control)
842 				ops = &as3722_ldo_extcntrl_ops;
843 			else
844 				ops = &as3722_ldo_ops;
845 			as3722_regs->desc[id].min_uV = 825000;
846 			as3722_regs->desc[id].uV_step = 25000;
847 			as3722_regs->desc[id].linear_min_sel = 1;
848 			as3722_regs->desc[id].enable_time = 500;
849 			as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges;
850 			as3722_regs->desc[id].n_linear_ranges =
851 						ARRAY_SIZE(as3722_ldo_ranges);
852 			break;
853 		}
854 		as3722_regs->desc[id].ops = ops;
855 		config.init_data = reg_config->reg_init;
856 		config.of_node = as3722_regulator_matches[id].of_node;
857 		rdev = devm_regulator_register(&pdev->dev,
858 					&as3722_regs->desc[id], &config);
859 		if (IS_ERR(rdev)) {
860 			ret = PTR_ERR(rdev);
861 			dev_err(&pdev->dev, "regulator %d register failed %d\n",
862 				id, ret);
863 			return ret;
864 		}
865 
866 		as3722_regs->rdevs[id] = rdev;
867 		if (reg_config->ext_control) {
868 			ret = regulator_enable_regmap(rdev);
869 			if (ret < 0) {
870 				dev_err(&pdev->dev,
871 					"Regulator %d enable failed: %d\n",
872 					id, ret);
873 				return ret;
874 			}
875 			ret = as3722_extreg_init(as3722_regs, id,
876 					reg_config->ext_control);
877 			if (ret < 0) {
878 				dev_err(&pdev->dev,
879 					"AS3722 ext control failed: %d", ret);
880 				return ret;
881 			}
882 		}
883 	}
884 	return 0;
885 }
886 
887 static const struct of_device_id of_as3722_regulator_match[] = {
888 	{ .compatible = "ams,as3722-regulator", },
889 	{},
890 };
891 MODULE_DEVICE_TABLE(of, of_as3722_regulator_match);
892 
893 static struct platform_driver as3722_regulator_driver = {
894 	.driver = {
895 		.name = "as3722-regulator",
896 		.owner = THIS_MODULE,
897 		.of_match_table = of_as3722_regulator_match,
898 	},
899 	.probe = as3722_regulator_probe,
900 };
901 
902 module_platform_driver(as3722_regulator_driver);
903 
904 MODULE_ALIAS("platform:as3722-regulator");
905 MODULE_DESCRIPTION("AS3722 regulator driver");
906 MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>");
907 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
908 MODULE_LICENSE("GPL");
909