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