xref: /openbmc/linux/drivers/regulator/s2mpa01.c (revision fc2b10d1)
14f3fb287SKrzysztof Kozlowski // SPDX-License-Identifier: GPL-2.0+
24f3fb287SKrzysztof Kozlowski //
34f3fb287SKrzysztof Kozlowski // Copyright (c) 2013 Samsung Electronics Co., Ltd
44f3fb287SKrzysztof Kozlowski //		http://www.samsung.com
5f1879271SSachin Kamat 
6f1879271SSachin Kamat #include <linux/bug.h>
7f1879271SSachin Kamat #include <linux/err.h>
8f1879271SSachin Kamat #include <linux/gpio.h>
9f1879271SSachin Kamat #include <linux/slab.h>
10f1879271SSachin Kamat #include <linux/module.h>
11f1879271SSachin Kamat #include <linux/of.h>
12f1879271SSachin Kamat #include <linux/regmap.h>
13f1879271SSachin Kamat #include <linux/platform_device.h>
14f1879271SSachin Kamat #include <linux/regulator/driver.h>
15f1879271SSachin Kamat #include <linux/regulator/machine.h>
16f1879271SSachin Kamat #include <linux/regulator/of_regulator.h>
17f1879271SSachin Kamat #include <linux/mfd/samsung/core.h>
18f1879271SSachin Kamat #include <linux/mfd/samsung/s2mpa01.h>
19f1879271SSachin Kamat 
20f1879271SSachin Kamat struct s2mpa01_info {
21f1879271SSachin Kamat 	int ramp_delay24;
22f1879271SSachin Kamat 	int ramp_delay3;
23f1879271SSachin Kamat 	int ramp_delay5;
24f1879271SSachin Kamat 	int ramp_delay16;
25f1879271SSachin Kamat 	int ramp_delay7;
26f1879271SSachin Kamat 	int ramp_delay8910;
27f1879271SSachin Kamat };
28f1879271SSachin Kamat 
29f1879271SSachin Kamat static int get_ramp_delay(int ramp_delay)
30f1879271SSachin Kamat {
31f1879271SSachin Kamat 	unsigned char cnt = 0;
32f1879271SSachin Kamat 
33f1879271SSachin Kamat 	ramp_delay /= 6250;
34f1879271SSachin Kamat 
35f1879271SSachin Kamat 	while (true) {
36f1879271SSachin Kamat 		ramp_delay = ramp_delay >> 1;
37f1879271SSachin Kamat 		if (ramp_delay == 0)
38f1879271SSachin Kamat 			break;
39f1879271SSachin Kamat 		cnt++;
40f1879271SSachin Kamat 	}
41f1879271SSachin Kamat 
42f1879271SSachin Kamat 	if (cnt > 3)
43f1879271SSachin Kamat 		cnt = 3;
44f1879271SSachin Kamat 
45f1879271SSachin Kamat 	return cnt;
46f1879271SSachin Kamat }
47f1879271SSachin Kamat 
48f1879271SSachin Kamat static int s2mpa01_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
49f1879271SSachin Kamat 				   unsigned int old_selector,
50f1879271SSachin Kamat 				   unsigned int new_selector)
51f1879271SSachin Kamat {
52f1879271SSachin Kamat 	struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);
53f1879271SSachin Kamat 	unsigned int ramp_delay = 0;
54f1879271SSachin Kamat 	int old_volt, new_volt;
55f1879271SSachin Kamat 
560608032aSKrzysztof Kozlowski 	switch (rdev_get_id(rdev)) {
57f1879271SSachin Kamat 	case S2MPA01_BUCK2:
58f1879271SSachin Kamat 	case S2MPA01_BUCK4:
59f1879271SSachin Kamat 		ramp_delay = s2mpa01->ramp_delay24;
60f1879271SSachin Kamat 		break;
61f1879271SSachin Kamat 	case S2MPA01_BUCK3:
62f1879271SSachin Kamat 		ramp_delay = s2mpa01->ramp_delay3;
63f1879271SSachin Kamat 		break;
64f1879271SSachin Kamat 	case S2MPA01_BUCK5:
65f1879271SSachin Kamat 		ramp_delay = s2mpa01->ramp_delay5;
66f1879271SSachin Kamat 		break;
67f1879271SSachin Kamat 	case S2MPA01_BUCK1:
68f1879271SSachin Kamat 	case S2MPA01_BUCK6:
69f1879271SSachin Kamat 		ramp_delay = s2mpa01->ramp_delay16;
70f1879271SSachin Kamat 		break;
71f1879271SSachin Kamat 	case S2MPA01_BUCK7:
72f1879271SSachin Kamat 		ramp_delay = s2mpa01->ramp_delay7;
73f1879271SSachin Kamat 		break;
74f1879271SSachin Kamat 	case S2MPA01_BUCK8:
75f1879271SSachin Kamat 	case S2MPA01_BUCK9:
76f1879271SSachin Kamat 	case S2MPA01_BUCK10:
77f1879271SSachin Kamat 		ramp_delay = s2mpa01->ramp_delay8910;
78f1879271SSachin Kamat 		break;
79f1879271SSachin Kamat 	}
80f1879271SSachin Kamat 
81f1879271SSachin Kamat 	if (ramp_delay == 0)
82f1879271SSachin Kamat 		ramp_delay = rdev->desc->ramp_delay;
83f1879271SSachin Kamat 
84f1879271SSachin Kamat 	old_volt = rdev->desc->min_uV + (rdev->desc->uV_step * old_selector);
85f1879271SSachin Kamat 	new_volt = rdev->desc->min_uV + (rdev->desc->uV_step * new_selector);
86f1879271SSachin Kamat 
87f1879271SSachin Kamat 	return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay);
88f1879271SSachin Kamat }
89f1879271SSachin Kamat 
90f1879271SSachin Kamat static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
91f1879271SSachin Kamat {
92f1879271SSachin Kamat 	struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);
93f1879271SSachin Kamat 	unsigned int ramp_val, ramp_shift, ramp_reg = S2MPA01_REG_RAMP2;
94f1879271SSachin Kamat 	unsigned int ramp_enable = 1, enable_shift = 0;
95f1879271SSachin Kamat 	int ret;
96f1879271SSachin Kamat 
970608032aSKrzysztof Kozlowski 	switch (rdev_get_id(rdev)) {
98f1879271SSachin Kamat 	case S2MPA01_BUCK1:
99f1879271SSachin Kamat 		enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT;
100f1879271SSachin Kamat 		if (!ramp_delay) {
101f1879271SSachin Kamat 			ramp_enable = 0;
102f1879271SSachin Kamat 			break;
103f1879271SSachin Kamat 		}
104f1879271SSachin Kamat 
105f1879271SSachin Kamat 		if (ramp_delay > s2mpa01->ramp_delay16)
106f1879271SSachin Kamat 			s2mpa01->ramp_delay16 = ramp_delay;
107f1879271SSachin Kamat 		else
108f1879271SSachin Kamat 			ramp_delay = s2mpa01->ramp_delay16;
109f1879271SSachin Kamat 
110f1879271SSachin Kamat 		ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;
111f1879271SSachin Kamat 		break;
112f1879271SSachin Kamat 	case S2MPA01_BUCK2:
113f1879271SSachin Kamat 		enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT;
114f1879271SSachin Kamat 		if (!ramp_delay) {
115f1879271SSachin Kamat 			ramp_enable = 0;
116f1879271SSachin Kamat 			break;
117f1879271SSachin Kamat 		}
118f1879271SSachin Kamat 
119f1879271SSachin Kamat 		if (ramp_delay > s2mpa01->ramp_delay24)
120f1879271SSachin Kamat 			s2mpa01->ramp_delay24 = ramp_delay;
121f1879271SSachin Kamat 		else
122f1879271SSachin Kamat 			ramp_delay = s2mpa01->ramp_delay24;
123f1879271SSachin Kamat 
124f1879271SSachin Kamat 		ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;
125f1879271SSachin Kamat 		ramp_reg = S2MPA01_REG_RAMP1;
126f1879271SSachin Kamat 		break;
127f1879271SSachin Kamat 	case S2MPA01_BUCK3:
128f1879271SSachin Kamat 		enable_shift = S2MPA01_BUCK3_RAMP_EN_SHIFT;
129f1879271SSachin Kamat 		if (!ramp_delay) {
130f1879271SSachin Kamat 			ramp_enable = 0;
131f1879271SSachin Kamat 			break;
132f1879271SSachin Kamat 		}
133f1879271SSachin Kamat 
134f1879271SSachin Kamat 		s2mpa01->ramp_delay3 = ramp_delay;
135f1879271SSachin Kamat 		ramp_shift = S2MPA01_BUCK3_RAMP_SHIFT;
136f1879271SSachin Kamat 		ramp_reg = S2MPA01_REG_RAMP1;
137f1879271SSachin Kamat 		break;
138f1879271SSachin Kamat 	case S2MPA01_BUCK4:
139f1879271SSachin Kamat 		enable_shift = S2MPA01_BUCK4_RAMP_EN_SHIFT;
140f1879271SSachin Kamat 		if (!ramp_delay) {
141f1879271SSachin Kamat 			ramp_enable = 0;
142f1879271SSachin Kamat 			break;
143f1879271SSachin Kamat 		}
144f1879271SSachin Kamat 
145f1879271SSachin Kamat 		if (ramp_delay > s2mpa01->ramp_delay24)
146f1879271SSachin Kamat 			s2mpa01->ramp_delay24 = ramp_delay;
147f1879271SSachin Kamat 		else
148f1879271SSachin Kamat 			ramp_delay = s2mpa01->ramp_delay24;
149f1879271SSachin Kamat 
150f1879271SSachin Kamat 		ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;
151f1879271SSachin Kamat 		ramp_reg = S2MPA01_REG_RAMP1;
152f1879271SSachin Kamat 		break;
153f1879271SSachin Kamat 	case S2MPA01_BUCK5:
154f1879271SSachin Kamat 		s2mpa01->ramp_delay5 = ramp_delay;
155f1879271SSachin Kamat 		ramp_shift = S2MPA01_BUCK5_RAMP_SHIFT;
156f1879271SSachin Kamat 		break;
157f1879271SSachin Kamat 	case S2MPA01_BUCK6:
158f1879271SSachin Kamat 		if (ramp_delay > s2mpa01->ramp_delay16)
159f1879271SSachin Kamat 			s2mpa01->ramp_delay16 = ramp_delay;
160f1879271SSachin Kamat 		else
161f1879271SSachin Kamat 			ramp_delay = s2mpa01->ramp_delay16;
162f1879271SSachin Kamat 
163f1879271SSachin Kamat 		ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;
164f1879271SSachin Kamat 		break;
165f1879271SSachin Kamat 	case S2MPA01_BUCK7:
166f1879271SSachin Kamat 		s2mpa01->ramp_delay7 = ramp_delay;
167f1879271SSachin Kamat 		ramp_shift = S2MPA01_BUCK7_RAMP_SHIFT;
168f1879271SSachin Kamat 		break;
169f1879271SSachin Kamat 	case S2MPA01_BUCK8:
170f1879271SSachin Kamat 	case S2MPA01_BUCK9:
171f1879271SSachin Kamat 	case S2MPA01_BUCK10:
172f1879271SSachin Kamat 		if (ramp_delay > s2mpa01->ramp_delay8910)
173f1879271SSachin Kamat 			s2mpa01->ramp_delay8910 = ramp_delay;
174f1879271SSachin Kamat 		else
175f1879271SSachin Kamat 			ramp_delay = s2mpa01->ramp_delay8910;
176f1879271SSachin Kamat 
177f1879271SSachin Kamat 		ramp_shift = S2MPA01_BUCK8910_RAMP_SHIFT;
178f1879271SSachin Kamat 		break;
179f1879271SSachin Kamat 	default:
180f1879271SSachin Kamat 		return 0;
181f1879271SSachin Kamat 	}
182f1879271SSachin Kamat 
183f1879271SSachin Kamat 	if (!ramp_enable)
184f1879271SSachin Kamat 		goto ramp_disable;
185f1879271SSachin Kamat 
18651e2fc0aSKrzysztof Kozlowski 	/* Ramp delay can be enabled/disabled only for buck[1234] */
18751e2fc0aSKrzysztof Kozlowski 	if (rdev_get_id(rdev) >= S2MPA01_BUCK1 &&
18851e2fc0aSKrzysztof Kozlowski 			rdev_get_id(rdev) <= S2MPA01_BUCK4) {
189f1879271SSachin Kamat 		ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
190f1879271SSachin Kamat 					 1 << enable_shift, 1 << enable_shift);
191f1879271SSachin Kamat 		if (ret) {
192f1879271SSachin Kamat 			dev_err(&rdev->dev, "failed to enable ramp rate\n");
193f1879271SSachin Kamat 			return ret;
194f1879271SSachin Kamat 		}
19551e2fc0aSKrzysztof Kozlowski 	}
196f1879271SSachin Kamat 
197f1879271SSachin Kamat 	ramp_val = get_ramp_delay(ramp_delay);
198f1879271SSachin Kamat 
199f1879271SSachin Kamat 	return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift,
200f1879271SSachin Kamat 				  ramp_val << ramp_shift);
201f1879271SSachin Kamat 
202f1879271SSachin Kamat ramp_disable:
203f1879271SSachin Kamat 	return regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
204f1879271SSachin Kamat 				  1 << enable_shift, 0);
205f1879271SSachin Kamat }
206f1879271SSachin Kamat 
207f465bf9bSKrzysztof Kozlowski static const struct regulator_ops s2mpa01_ldo_ops = {
208f1879271SSachin Kamat 	.list_voltage		= regulator_list_voltage_linear,
209f1879271SSachin Kamat 	.map_voltage		= regulator_map_voltage_linear,
210f1879271SSachin Kamat 	.is_enabled		= regulator_is_enabled_regmap,
211f1879271SSachin Kamat 	.enable			= regulator_enable_regmap,
212f1879271SSachin Kamat 	.disable		= regulator_disable_regmap,
213f1879271SSachin Kamat 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
214f1879271SSachin Kamat 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
215f1879271SSachin Kamat 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
216f1879271SSachin Kamat };
217f1879271SSachin Kamat 
218f465bf9bSKrzysztof Kozlowski static const struct regulator_ops s2mpa01_buck_ops = {
219f1879271SSachin Kamat 	.list_voltage		= regulator_list_voltage_linear,
220f1879271SSachin Kamat 	.map_voltage		= regulator_map_voltage_linear,
221f1879271SSachin Kamat 	.is_enabled		= regulator_is_enabled_regmap,
222f1879271SSachin Kamat 	.enable			= regulator_enable_regmap,
223f1879271SSachin Kamat 	.disable		= regulator_disable_regmap,
224f1879271SSachin Kamat 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
225f1879271SSachin Kamat 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
226f1879271SSachin Kamat 	.set_voltage_time_sel	= s2mpa01_regulator_set_voltage_time_sel,
227f1879271SSachin Kamat 	.set_ramp_delay		= s2mpa01_set_ramp_delay,
228f1879271SSachin Kamat };
229f1879271SSachin Kamat 
230d264fd45SAmit Daniel Kachhap #define regulator_desc_ldo(num, step) {			\
231f1879271SSachin Kamat 	.name		= "LDO"#num,			\
2320677c3eaSAxel Lin 	.of_match	= of_match_ptr("LDO"#num),	\
2330677c3eaSAxel Lin 	.regulators_node = of_match_ptr("regulators"),	\
234f1879271SSachin Kamat 	.id		= S2MPA01_LDO##num,		\
235f1879271SSachin Kamat 	.ops		= &s2mpa01_ldo_ops,		\
236f1879271SSachin Kamat 	.type		= REGULATOR_VOLTAGE,		\
237f1879271SSachin Kamat 	.owner		= THIS_MODULE,			\
2380e4f4178SAmit Daniel Kachhap 	.min_uV		= MIN_800_MV,			\
239d264fd45SAmit Daniel Kachhap 	.uV_step	= step,				\
240f1879271SSachin Kamat 	.n_voltages	= S2MPA01_LDO_N_VOLTAGES,	\
241f1879271SSachin Kamat 	.vsel_reg	= S2MPA01_REG_L1CTRL + num - 1,	\
242f1879271SSachin Kamat 	.vsel_mask	= S2MPA01_LDO_VSEL_MASK,	\
243f1879271SSachin Kamat 	.enable_reg	= S2MPA01_REG_L1CTRL + num - 1,	\
244f1879271SSachin Kamat 	.enable_mask	= S2MPA01_ENABLE_MASK		\
245f1879271SSachin Kamat }
246f1879271SSachin Kamat 
247f1879271SSachin Kamat #define regulator_desc_buck1_4(num)	{			\
248f1879271SSachin Kamat 	.name		= "BUCK"#num,				\
2490677c3eaSAxel Lin 	.of_match	= of_match_ptr("BUCK"#num),		\
2500677c3eaSAxel Lin 	.regulators_node = of_match_ptr("regulators"),		\
251f1879271SSachin Kamat 	.id		= S2MPA01_BUCK##num,			\
252f1879271SSachin Kamat 	.ops		= &s2mpa01_buck_ops,			\
253f1879271SSachin Kamat 	.type		= REGULATOR_VOLTAGE,			\
254f1879271SSachin Kamat 	.owner		= THIS_MODULE,				\
2550e4f4178SAmit Daniel Kachhap 	.min_uV		= MIN_600_MV,				\
2560e4f4178SAmit Daniel Kachhap 	.uV_step	= STEP_6_25_MV,				\
257f1879271SSachin Kamat 	.n_voltages	= S2MPA01_BUCK_N_VOLTAGES,		\
258f1879271SSachin Kamat 	.ramp_delay	= S2MPA01_RAMP_DELAY,			\
259f1879271SSachin Kamat 	.vsel_reg	= S2MPA01_REG_B1CTRL2 + (num - 1) * 2,	\
260f1879271SSachin Kamat 	.vsel_mask	= S2MPA01_BUCK_VSEL_MASK,		\
261f1879271SSachin Kamat 	.enable_reg	= S2MPA01_REG_B1CTRL1 + (num - 1) * 2,	\
262f1879271SSachin Kamat 	.enable_mask	= S2MPA01_ENABLE_MASK			\
263f1879271SSachin Kamat }
264f1879271SSachin Kamat 
265f1879271SSachin Kamat #define regulator_desc_buck5	{				\
266f1879271SSachin Kamat 	.name		= "BUCK5",				\
2670677c3eaSAxel Lin 	.of_match	= of_match_ptr("BUCK5"),		\
2680677c3eaSAxel Lin 	.regulators_node = of_match_ptr("regulators"),		\
269f1879271SSachin Kamat 	.id		= S2MPA01_BUCK5,			\
270f1879271SSachin Kamat 	.ops		= &s2mpa01_buck_ops,			\
271f1879271SSachin Kamat 	.type		= REGULATOR_VOLTAGE,			\
272f1879271SSachin Kamat 	.owner		= THIS_MODULE,				\
2730e4f4178SAmit Daniel Kachhap 	.min_uV		= MIN_800_MV,				\
2740e4f4178SAmit Daniel Kachhap 	.uV_step	= STEP_6_25_MV,				\
275f1879271SSachin Kamat 	.n_voltages	= S2MPA01_BUCK_N_VOLTAGES,		\
276f1879271SSachin Kamat 	.ramp_delay	= S2MPA01_RAMP_DELAY,			\
277f1879271SSachin Kamat 	.vsel_reg	= S2MPA01_REG_B5CTRL2,			\
278f1879271SSachin Kamat 	.vsel_mask	= S2MPA01_BUCK_VSEL_MASK,		\
279f1879271SSachin Kamat 	.enable_reg	= S2MPA01_REG_B5CTRL1,			\
280f1879271SSachin Kamat 	.enable_mask	= S2MPA01_ENABLE_MASK			\
281f1879271SSachin Kamat }
282f1879271SSachin Kamat 
283d264fd45SAmit Daniel Kachhap #define regulator_desc_buck6_10(num, min, step) {			\
284f1879271SSachin Kamat 	.name		= "BUCK"#num,				\
2850677c3eaSAxel Lin 	.of_match	= of_match_ptr("BUCK"#num),		\
2860677c3eaSAxel Lin 	.regulators_node = of_match_ptr("regulators"),		\
287f1879271SSachin Kamat 	.id		= S2MPA01_BUCK##num,			\
288f1879271SSachin Kamat 	.ops		= &s2mpa01_buck_ops,			\
289f1879271SSachin Kamat 	.type		= REGULATOR_VOLTAGE,			\
290f1879271SSachin Kamat 	.owner		= THIS_MODULE,				\
291d264fd45SAmit Daniel Kachhap 	.min_uV		= min,					\
292d264fd45SAmit Daniel Kachhap 	.uV_step	= step,					\
293f1879271SSachin Kamat 	.n_voltages	= S2MPA01_BUCK_N_VOLTAGES,		\
294f1879271SSachin Kamat 	.ramp_delay	= S2MPA01_RAMP_DELAY,			\
295f1879271SSachin Kamat 	.vsel_reg	= S2MPA01_REG_B6CTRL2 + (num - 6) * 2,	\
296f1879271SSachin Kamat 	.vsel_mask	= S2MPA01_BUCK_VSEL_MASK,		\
297f1879271SSachin Kamat 	.enable_reg	= S2MPA01_REG_B6CTRL1 + (num - 6) * 2,	\
298f1879271SSachin Kamat 	.enable_mask	= S2MPA01_ENABLE_MASK			\
299f1879271SSachin Kamat }
300f1879271SSachin Kamat 
3014b8e43f2SKrzysztof Kozlowski static const struct regulator_desc regulators[] = {
302d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(1, STEP_25_MV),
303d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(2, STEP_50_MV),
304d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(3, STEP_50_MV),
305d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(4, STEP_50_MV),
30628c4f730SStuart Menefy 	regulator_desc_ldo(5, STEP_25_MV),
307d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(6, STEP_25_MV),
308d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(7, STEP_50_MV),
309d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(8, STEP_50_MV),
310d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(9, STEP_50_MV),
311d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(10, STEP_50_MV),
31228c4f730SStuart Menefy 	regulator_desc_ldo(11, STEP_50_MV),
313d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(12, STEP_50_MV),
314d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(13, STEP_50_MV),
315d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(14, STEP_50_MV),
316d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(15, STEP_50_MV),
317d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(16, STEP_50_MV),
318d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(17, STEP_50_MV),
319d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(18, STEP_50_MV),
320d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(19, STEP_50_MV),
321d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(20, STEP_50_MV),
322d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(21, STEP_50_MV),
32328c4f730SStuart Menefy 	regulator_desc_ldo(22, STEP_50_MV),
32428c4f730SStuart Menefy 	regulator_desc_ldo(23, STEP_50_MV),
325d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(24, STEP_50_MV),
326d264fd45SAmit Daniel Kachhap 	regulator_desc_ldo(25, STEP_50_MV),
32728c4f730SStuart Menefy 	regulator_desc_ldo(26, STEP_25_MV),
328f1879271SSachin Kamat 	regulator_desc_buck1_4(1),
329f1879271SSachin Kamat 	regulator_desc_buck1_4(2),
330f1879271SSachin Kamat 	regulator_desc_buck1_4(3),
331f1879271SSachin Kamat 	regulator_desc_buck1_4(4),
332f1879271SSachin Kamat 	regulator_desc_buck5,
333d264fd45SAmit Daniel Kachhap 	regulator_desc_buck6_10(6, MIN_600_MV, STEP_6_25_MV),
334d264fd45SAmit Daniel Kachhap 	regulator_desc_buck6_10(7, MIN_600_MV, STEP_6_25_MV),
335d264fd45SAmit Daniel Kachhap 	regulator_desc_buck6_10(8, MIN_800_MV, STEP_12_5_MV),
336d264fd45SAmit Daniel Kachhap 	regulator_desc_buck6_10(9, MIN_1500_MV, STEP_12_5_MV),
337d264fd45SAmit Daniel Kachhap 	regulator_desc_buck6_10(10, MIN_1000_MV, STEP_12_5_MV),
338f1879271SSachin Kamat };
339f1879271SSachin Kamat 
340f1879271SSachin Kamat static int s2mpa01_pmic_probe(struct platform_device *pdev)
341f1879271SSachin Kamat {
342f1879271SSachin Kamat 	struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
343f1879271SSachin Kamat 	struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
344f1879271SSachin Kamat 	struct regulator_config config = { };
345f1879271SSachin Kamat 	struct s2mpa01_info *s2mpa01;
346f1879271SSachin Kamat 	int i;
347f1879271SSachin Kamat 
348f1879271SSachin Kamat 	s2mpa01 = devm_kzalloc(&pdev->dev, sizeof(*s2mpa01), GFP_KERNEL);
349f1879271SSachin Kamat 	if (!s2mpa01)
350f1879271SSachin Kamat 		return -ENOMEM;
351f1879271SSachin Kamat 
3520677c3eaSAxel Lin 	config.dev = iodev->dev;
353f1879271SSachin Kamat 	config.regmap = iodev->regmap_pmic;
354f1879271SSachin Kamat 	config.driver_data = s2mpa01;
355f1879271SSachin Kamat 
356f1879271SSachin Kamat 	for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) {
357f1879271SSachin Kamat 		struct regulator_dev *rdev;
3580677c3eaSAxel Lin 
359f1879271SSachin Kamat 		if (pdata)
360f1879271SSachin Kamat 			config.init_data = pdata->regulators[i].initdata;
361f1879271SSachin Kamat 
362f1879271SSachin Kamat 		rdev = devm_regulator_register(&pdev->dev,
363f1879271SSachin Kamat 						&regulators[i], &config);
364f1879271SSachin Kamat 		if (IS_ERR(rdev)) {
365f1879271SSachin Kamat 			dev_err(&pdev->dev, "regulator init failed for %d\n",
366f1879271SSachin Kamat 				i);
367f1879271SSachin Kamat 			return PTR_ERR(rdev);
368f1879271SSachin Kamat 		}
369f1879271SSachin Kamat 	}
370f1879271SSachin Kamat 
371f1879271SSachin Kamat 	return 0;
372f1879271SSachin Kamat }
373f1879271SSachin Kamat 
374f1879271SSachin Kamat static const struct platform_device_id s2mpa01_pmic_id[] = {
375f1879271SSachin Kamat 	{ "s2mpa01-pmic", 0},
376f1879271SSachin Kamat 	{ },
377f1879271SSachin Kamat };
378f1879271SSachin Kamat MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id);
379f1879271SSachin Kamat 
380f1879271SSachin Kamat static struct platform_driver s2mpa01_pmic_driver = {
381f1879271SSachin Kamat 	.driver = {
382f1879271SSachin Kamat 		.name = "s2mpa01-pmic",
383f1879271SSachin Kamat 	},
384f1879271SSachin Kamat 	.probe = s2mpa01_pmic_probe,
385f1879271SSachin Kamat 	.id_table = s2mpa01_pmic_id,
386f1879271SSachin Kamat };
387f1879271SSachin Kamat 
388f1879271SSachin Kamat module_platform_driver(s2mpa01_pmic_driver);
389f1879271SSachin Kamat 
390f1879271SSachin Kamat /* Module information */
391f1879271SSachin Kamat MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
392f1879271SSachin Kamat MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>");
393fc2b10d1SKrzysztof Kozlowski MODULE_DESCRIPTION("Samsung S2MPA01 Regulator Driver");
394f1879271SSachin Kamat MODULE_LICENSE("GPL");
395