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 ®ulators[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