Commit | Line | Data |
---|---|---|
bcc61f1c BG |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // | |
3 | // Copyright (C) 2018 BayLibre SAS | |
4 | // Author: Bartosz Golaszewski <bgolaszewski@baylibre.com> | |
5 | // | |
6 | // Regulator driver for MAXIM 77650/77651 charger/power-supply. | |
7 | ||
8 | #include <linux/i2c.h> | |
9 | #include <linux/mfd/max77650.h> | |
10 | #include <linux/module.h> | |
11 | #include <linux/platform_device.h> | |
12 | #include <linux/regmap.h> | |
13 | #include <linux/regulator/driver.h> | |
14 | ||
15 | #define MAX77650_REGULATOR_EN_CTRL_MASK GENMASK(3, 0) | |
16 | #define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \ | |
17 | ((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK) | |
18 | #define MAX77650_REGULATOR_ENABLED GENMASK(2, 1) | |
19 | #define MAX77650_REGULATOR_DISABLED BIT(2) | |
20 | ||
21 | #define MAX77650_REGULATOR_V_LDO_MASK GENMASK(6, 0) | |
22 | #define MAX77650_REGULATOR_V_SBB_MASK GENMASK(5, 0) | |
23 | ||
24 | #define MAX77650_REGULATOR_AD_MASK BIT(3) | |
25 | #define MAX77650_REGULATOR_AD_DISABLED 0x00 | |
26 | #define MAX77650_REGULATOR_AD_ENABLED BIT(3) | |
27 | ||
28 | #define MAX77650_REGULATOR_CURR_LIM_MASK GENMASK(7, 6) | |
29 | #define MAX77650_REGULATOR_CURR_LIM_BITS(_reg) \ | |
30 | (((_reg) & MAX77650_REGULATOR_CURR_LIM_MASK) >> 6) | |
31 | #define MAX77650_REGULATOR_CURR_LIM_SHIFT(_val) ((_val) << 6) | |
32 | ||
33 | enum { | |
34 | MAX77650_REGULATOR_ID_LDO = 0, | |
35 | MAX77650_REGULATOR_ID_SBB0, | |
36 | MAX77650_REGULATOR_ID_SBB1, | |
37 | MAX77650_REGULATOR_ID_SBB2, | |
38 | MAX77650_REGULATOR_NUM_REGULATORS, | |
39 | }; | |
40 | ||
41 | struct max77650_regulator_desc { | |
42 | struct regulator_desc desc; | |
43 | unsigned int regA; | |
44 | unsigned int regB; | |
45 | }; | |
46 | ||
47 | static const u32 max77651_sbb1_regulator_volt_table[] = { | |
48 | 2400000, 3200000, 4000000, 4800000, | |
49 | 2450000, 3250000, 4050000, 4850000, | |
50 | 2500000, 3300000, 4100000, 4900000, | |
51 | 2550000, 3350000, 4150000, 4950000, | |
52 | 2600000, 3400000, 4200000, 5000000, | |
53 | 2650000, 3450000, 4250000, 5050000, | |
54 | 2700000, 3500000, 4300000, 5100000, | |
55 | 2750000, 3550000, 4350000, 5150000, | |
56 | 2800000, 3600000, 4400000, 5200000, | |
57 | 2850000, 3650000, 4450000, 5250000, | |
58 | 2900000, 3700000, 4500000, 0, | |
59 | 2950000, 3750000, 4550000, 0, | |
60 | 3000000, 3800000, 4600000, 0, | |
61 | 3050000, 3850000, 4650000, 0, | |
62 | 3100000, 3900000, 4700000, 0, | |
63 | 3150000, 3950000, 4750000, 0, | |
64 | }; | |
65 | ||
66 | #define MAX77651_REGULATOR_SBB1_SEL_DEC(_val) \ | |
67 | (((_val & 0x3c) >> 2) | ((_val & 0x03) << 4)) | |
68 | #define MAX77651_REGULATOR_SBB1_SEL_ENC(_val) \ | |
69 | (((_val & 0x30) >> 4) | ((_val & 0x0f) << 2)) | |
70 | ||
71 | #define MAX77650_REGULATOR_SBB1_SEL_DECR(_val) \ | |
72 | do { \ | |
73 | _val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \ | |
74 | _val--; \ | |
75 | _val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \ | |
76 | } while (0) | |
77 | ||
78 | #define MAX77650_REGULATOR_SBB1_SEL_INCR(_val) \ | |
79 | do { \ | |
80 | _val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \ | |
81 | _val++; \ | |
82 | _val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \ | |
83 | } while (0) | |
84 | ||
85 | static const int max77650_current_limit_table[] = { | |
86 | 1000000, 866000, 707000, 500000, | |
87 | }; | |
88 | ||
89 | static int max77650_regulator_is_enabled(struct regulator_dev *rdev) | |
90 | { | |
91 | struct max77650_regulator_desc *rdesc; | |
92 | struct regmap *map; | |
93 | int val, rv, en; | |
94 | ||
95 | rdesc = rdev_get_drvdata(rdev); | |
96 | map = rdev_get_regmap(rdev); | |
97 | ||
98 | rv = regmap_read(map, rdesc->regB, &val); | |
99 | if (rv) | |
100 | return rv; | |
101 | ||
102 | en = MAX77650_REGULATOR_EN_CTRL_BITS(val); | |
103 | ||
104 | return en != MAX77650_REGULATOR_DISABLED; | |
105 | } | |
106 | ||
107 | static int max77650_regulator_enable(struct regulator_dev *rdev) | |
108 | { | |
109 | struct max77650_regulator_desc *rdesc; | |
110 | struct regmap *map; | |
111 | ||
112 | rdesc = rdev_get_drvdata(rdev); | |
113 | map = rdev_get_regmap(rdev); | |
114 | ||
115 | return regmap_update_bits(map, rdesc->regB, | |
116 | MAX77650_REGULATOR_EN_CTRL_MASK, | |
117 | MAX77650_REGULATOR_ENABLED); | |
118 | } | |
119 | ||
120 | static int max77650_regulator_disable(struct regulator_dev *rdev) | |
121 | { | |
122 | struct max77650_regulator_desc *rdesc; | |
123 | struct regmap *map; | |
124 | ||
125 | rdesc = rdev_get_drvdata(rdev); | |
126 | map = rdev_get_regmap(rdev); | |
127 | ||
128 | return regmap_update_bits(map, rdesc->regB, | |
129 | MAX77650_REGULATOR_EN_CTRL_MASK, | |
130 | MAX77650_REGULATOR_DISABLED); | |
131 | } | |
132 | ||
133 | static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, | |
134 | unsigned int sel) | |
135 | { | |
136 | int rv = 0, curr, diff; | |
137 | bool ascending; | |
138 | ||
139 | /* | |
140 | * If the regulator is disabled, we can program the desired | |
141 | * voltage right away. | |
142 | */ | |
143 | if (!max77650_regulator_is_enabled(rdev)) | |
144 | return regulator_set_voltage_sel_regmap(rdev, sel); | |
145 | ||
146 | /* | |
147 | * Otherwise we need to manually ramp the output voltage up/down | |
148 | * one step at a time. | |
149 | */ | |
150 | ||
151 | curr = regulator_get_voltage_sel_regmap(rdev); | |
152 | if (curr < 0) | |
153 | return curr; | |
154 | ||
155 | diff = curr - sel; | |
156 | if (diff == 0) | |
157 | return 0; /* Already there. */ | |
158 | else if (diff > 0) | |
159 | ascending = false; | |
160 | else | |
161 | ascending = true; | |
162 | ||
163 | /* | |
164 | * Make sure we'll get to the right voltage and break the loop even if | |
165 | * the selector equals 0. | |
166 | */ | |
167 | for (ascending ? curr++ : curr--;; ascending ? curr++ : curr--) { | |
168 | rv = regulator_set_voltage_sel_regmap(rdev, curr); | |
169 | if (rv) | |
170 | return rv; | |
171 | ||
172 | if (curr == sel) | |
173 | break; | |
174 | } | |
175 | ||
176 | return 0; | |
177 | } | |
178 | ||
179 | /* | |
180 | * Special case: non-linear voltage table for max77651 SBB1 - software | |
181 | * must ensure the voltage is ramped in 50mV increments. | |
182 | */ | |
183 | static int max77651_regulator_sbb1_set_voltage_sel(struct regulator_dev *rdev, | |
184 | unsigned int sel) | |
185 | { | |
186 | int rv = 0, curr, vcurr, vdest, vdiff; | |
187 | ||
188 | /* | |
189 | * If the regulator is disabled, we can program the desired | |
190 | * voltage right away. | |
191 | */ | |
192 | if (!max77650_regulator_is_enabled(rdev)) | |
193 | return regulator_set_voltage_sel_regmap(rdev, sel); | |
194 | ||
195 | curr = regulator_get_voltage_sel_regmap(rdev); | |
196 | if (curr < 0) | |
197 | return curr; | |
198 | ||
199 | if (curr == sel) | |
200 | return 0; /* Already there. */ | |
201 | ||
202 | vcurr = max77651_sbb1_regulator_volt_table[curr]; | |
203 | vdest = max77651_sbb1_regulator_volt_table[sel]; | |
204 | vdiff = vcurr - vdest; | |
205 | ||
206 | for (;;) { | |
207 | if (vdiff > 0) | |
208 | MAX77650_REGULATOR_SBB1_SEL_DECR(curr); | |
209 | else | |
210 | MAX77650_REGULATOR_SBB1_SEL_INCR(curr); | |
211 | ||
212 | rv = regulator_set_voltage_sel_regmap(rdev, curr); | |
213 | if (rv) | |
214 | return rv; | |
215 | ||
216 | if (curr == sel) | |
217 | break; | |
218 | }; | |
219 | ||
220 | return 0; | |
221 | } | |
222 | ||
223 | static int max77650_regulator_get_current_limit(struct regulator_dev *rdev) | |
224 | { | |
225 | struct max77650_regulator_desc *rdesc; | |
226 | struct regmap *map; | |
227 | int val, rv, limit; | |
228 | ||
229 | rdesc = rdev_get_drvdata(rdev); | |
230 | map = rdev_get_regmap(rdev); | |
231 | ||
232 | rv = regmap_read(map, rdesc->regA, &val); | |
233 | if (rv) | |
234 | return rv; | |
235 | ||
236 | limit = MAX77650_REGULATOR_CURR_LIM_BITS(val); | |
237 | ||
238 | return max77650_current_limit_table[limit]; | |
239 | } | |
240 | ||
241 | static int max77650_regulator_set_current_limit(struct regulator_dev *rdev, | |
242 | int min_uA, int max_uA) | |
243 | { | |
244 | struct max77650_regulator_desc *rdesc; | |
245 | struct regmap *map; | |
246 | int rv, i, limit; | |
247 | ||
248 | rdesc = rdev_get_drvdata(rdev); | |
249 | map = rdev_get_regmap(rdev); | |
250 | ||
251 | for (i = 0; i < ARRAY_SIZE(max77650_current_limit_table); i++) { | |
252 | limit = max77650_current_limit_table[i]; | |
253 | ||
254 | if (limit >= min_uA && limit <= max_uA) { | |
255 | rv = regmap_update_bits(map, rdesc->regA, | |
256 | MAX77650_REGULATOR_CURR_LIM_MASK, | |
257 | MAX77650_REGULATOR_CURR_LIM_SHIFT(i)); | |
258 | if (rv) | |
259 | return rv; | |
260 | } | |
261 | } | |
262 | ||
263 | return -EINVAL; | |
264 | } | |
265 | ||
266 | static const struct regulator_ops max77650_regulator_LDO_ops = { | |
267 | .is_enabled = max77650_regulator_is_enabled, | |
268 | .enable = max77650_regulator_enable, | |
269 | .disable = max77650_regulator_disable, | |
270 | .list_voltage = regulator_list_voltage_linear, | |
271 | .map_voltage = regulator_map_voltage_linear, | |
272 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | |
273 | .set_voltage_sel = max77650_regulator_set_voltage_sel, | |
274 | .set_active_discharge = regulator_set_active_discharge_regmap, | |
275 | }; | |
276 | ||
277 | static const struct regulator_ops max77650_regulator_SBB_ops = { | |
278 | .is_enabled = max77650_regulator_is_enabled, | |
279 | .enable = max77650_regulator_enable, | |
280 | .disable = max77650_regulator_disable, | |
281 | .list_voltage = regulator_list_voltage_linear, | |
282 | .map_voltage = regulator_map_voltage_linear, | |
283 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | |
284 | .set_voltage_sel = max77650_regulator_set_voltage_sel, | |
285 | .get_current_limit = max77650_regulator_get_current_limit, | |
286 | .set_current_limit = max77650_regulator_set_current_limit, | |
287 | .set_active_discharge = regulator_set_active_discharge_regmap, | |
288 | }; | |
289 | ||
290 | /* Special case for max77651 SBB1 - non-linear voltage mapping. */ | |
291 | static const struct regulator_ops max77651_SBB1_regulator_ops = { | |
292 | .is_enabled = max77650_regulator_is_enabled, | |
293 | .enable = max77650_regulator_enable, | |
294 | .disable = max77650_regulator_disable, | |
295 | .list_voltage = regulator_list_voltage_table, | |
296 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | |
297 | .set_voltage_sel = max77651_regulator_sbb1_set_voltage_sel, | |
298 | .get_current_limit = max77650_regulator_get_current_limit, | |
299 | .set_current_limit = max77650_regulator_set_current_limit, | |
300 | .set_active_discharge = regulator_set_active_discharge_regmap, | |
301 | }; | |
302 | ||
303 | static struct max77650_regulator_desc max77650_LDO_desc = { | |
304 | .desc = { | |
305 | .name = "ldo", | |
306 | .of_match = of_match_ptr("ldo"), | |
307 | .regulators_node = of_match_ptr("regulators"), | |
308 | .supply_name = "in-ldo", | |
309 | .id = MAX77650_REGULATOR_ID_LDO, | |
310 | .ops = &max77650_regulator_LDO_ops, | |
311 | .min_uV = 1350000, | |
312 | .uV_step = 12500, | |
313 | .n_voltages = 128, | |
314 | .vsel_mask = MAX77650_REGULATOR_V_LDO_MASK, | |
315 | .vsel_reg = MAX77650_REG_CNFG_LDO_A, | |
316 | .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, | |
317 | .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, | |
318 | .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, | |
319 | .active_discharge_reg = MAX77650_REG_CNFG_LDO_B, | |
320 | .enable_time = 100, | |
321 | .type = REGULATOR_VOLTAGE, | |
322 | }, | |
323 | .regA = MAX77650_REG_CNFG_LDO_A, | |
324 | .regB = MAX77650_REG_CNFG_LDO_B, | |
325 | }; | |
326 | ||
327 | static struct max77650_regulator_desc max77650_SBB0_desc = { | |
328 | .desc = { | |
329 | .name = "sbb0", | |
330 | .of_match = of_match_ptr("sbb0"), | |
331 | .regulators_node = of_match_ptr("regulators"), | |
332 | .supply_name = "in-sbb0", | |
333 | .id = MAX77650_REGULATOR_ID_SBB0, | |
334 | .ops = &max77650_regulator_SBB_ops, | |
335 | .min_uV = 800000, | |
336 | .uV_step = 25000, | |
337 | .n_voltages = 64, | |
338 | .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, | |
339 | .vsel_reg = MAX77650_REG_CNFG_SBB0_A, | |
340 | .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, | |
341 | .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, | |
342 | .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, | |
343 | .active_discharge_reg = MAX77650_REG_CNFG_SBB0_B, | |
344 | .enable_time = 100, | |
345 | .type = REGULATOR_VOLTAGE, | |
346 | }, | |
347 | .regA = MAX77650_REG_CNFG_SBB0_A, | |
348 | .regB = MAX77650_REG_CNFG_SBB0_B, | |
349 | }; | |
350 | ||
351 | static struct max77650_regulator_desc max77650_SBB1_desc = { | |
352 | .desc = { | |
353 | .name = "sbb1", | |
354 | .of_match = of_match_ptr("sbb1"), | |
355 | .regulators_node = of_match_ptr("regulators"), | |
356 | .supply_name = "in-sbb1", | |
357 | .id = MAX77650_REGULATOR_ID_SBB1, | |
358 | .ops = &max77650_regulator_SBB_ops, | |
359 | .min_uV = 800000, | |
360 | .uV_step = 12500, | |
361 | .n_voltages = 64, | |
362 | .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, | |
363 | .vsel_reg = MAX77650_REG_CNFG_SBB1_A, | |
364 | .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, | |
365 | .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, | |
366 | .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, | |
367 | .active_discharge_reg = MAX77650_REG_CNFG_SBB1_B, | |
368 | .enable_time = 100, | |
369 | .type = REGULATOR_VOLTAGE, | |
370 | }, | |
371 | .regA = MAX77650_REG_CNFG_SBB1_A, | |
372 | .regB = MAX77650_REG_CNFG_SBB1_B, | |
373 | }; | |
374 | ||
375 | static struct max77650_regulator_desc max77651_SBB1_desc = { | |
376 | .desc = { | |
377 | .name = "sbb1", | |
378 | .of_match = of_match_ptr("sbb1"), | |
379 | .regulators_node = of_match_ptr("regulators"), | |
380 | .supply_name = "in-sbb1", | |
381 | .id = MAX77650_REGULATOR_ID_SBB1, | |
382 | .ops = &max77651_SBB1_regulator_ops, | |
383 | .volt_table = max77651_sbb1_regulator_volt_table, | |
384 | .n_voltages = ARRAY_SIZE(max77651_sbb1_regulator_volt_table), | |
385 | .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, | |
386 | .vsel_reg = MAX77650_REG_CNFG_SBB1_A, | |
387 | .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, | |
388 | .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, | |
389 | .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, | |
390 | .active_discharge_reg = MAX77650_REG_CNFG_SBB1_B, | |
391 | .enable_time = 100, | |
392 | .type = REGULATOR_VOLTAGE, | |
393 | }, | |
394 | .regA = MAX77650_REG_CNFG_SBB1_A, | |
395 | .regB = MAX77650_REG_CNFG_SBB1_B, | |
396 | }; | |
397 | ||
398 | static struct max77650_regulator_desc max77650_SBB2_desc = { | |
399 | .desc = { | |
400 | .name = "sbb2", | |
401 | .of_match = of_match_ptr("sbb2"), | |
402 | .regulators_node = of_match_ptr("regulators"), | |
403 | .supply_name = "in-sbb0", | |
404 | .id = MAX77650_REGULATOR_ID_SBB2, | |
405 | .ops = &max77650_regulator_SBB_ops, | |
406 | .min_uV = 800000, | |
407 | .uV_step = 50000, | |
408 | .n_voltages = 64, | |
409 | .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, | |
410 | .vsel_reg = MAX77650_REG_CNFG_SBB2_A, | |
411 | .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, | |
412 | .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, | |
413 | .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, | |
414 | .active_discharge_reg = MAX77650_REG_CNFG_SBB2_B, | |
415 | .enable_time = 100, | |
416 | .type = REGULATOR_VOLTAGE, | |
417 | }, | |
418 | .regA = MAX77650_REG_CNFG_SBB2_A, | |
419 | .regB = MAX77650_REG_CNFG_SBB2_B, | |
420 | }; | |
421 | ||
422 | static struct max77650_regulator_desc max77651_SBB2_desc = { | |
423 | .desc = { | |
424 | .name = "sbb2", | |
425 | .of_match = of_match_ptr("sbb2"), | |
426 | .regulators_node = of_match_ptr("regulators"), | |
427 | .supply_name = "in-sbb0", | |
428 | .id = MAX77650_REGULATOR_ID_SBB2, | |
429 | .ops = &max77650_regulator_SBB_ops, | |
430 | .min_uV = 2400000, | |
431 | .uV_step = 50000, | |
432 | .n_voltages = 64, | |
433 | .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, | |
434 | .vsel_reg = MAX77650_REG_CNFG_SBB2_A, | |
435 | .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, | |
436 | .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, | |
437 | .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, | |
438 | .active_discharge_reg = MAX77650_REG_CNFG_SBB2_B, | |
439 | .enable_time = 100, | |
440 | .type = REGULATOR_VOLTAGE, | |
441 | }, | |
442 | .regA = MAX77650_REG_CNFG_SBB2_A, | |
443 | .regB = MAX77650_REG_CNFG_SBB2_B, | |
444 | }; | |
445 | ||
446 | static int max77650_regulator_probe(struct platform_device *pdev) | |
447 | { | |
448 | struct max77650_regulator_desc **rdescs; | |
449 | struct max77650_regulator_desc *rdesc; | |
450 | struct regulator_config config = { }; | |
451 | struct device *dev, *parent; | |
452 | struct regulator_dev *rdev; | |
453 | struct regmap *map; | |
454 | unsigned int val; | |
455 | int i, rv; | |
456 | ||
457 | dev = &pdev->dev; | |
458 | parent = dev->parent; | |
459 | ||
460 | if (!dev->of_node) | |
461 | dev->of_node = parent->of_node; | |
462 | ||
463 | rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS, | |
464 | sizeof(*rdescs), GFP_KERNEL); | |
465 | if (!rdescs) | |
466 | return -ENOMEM; | |
467 | ||
468 | map = dev_get_regmap(parent, NULL); | |
469 | if (!map) | |
470 | return -ENODEV; | |
471 | ||
472 | rv = regmap_read(map, MAX77650_REG_CID, &val); | |
473 | if (rv) | |
474 | return rv; | |
475 | ||
476 | rdescs[MAX77650_REGULATOR_ID_LDO] = &max77650_LDO_desc; | |
477 | rdescs[MAX77650_REGULATOR_ID_SBB0] = &max77650_SBB0_desc; | |
478 | ||
479 | switch (MAX77650_CID_BITS(val)) { | |
480 | case MAX77650_CID_77650A: | |
481 | case MAX77650_CID_77650C: | |
482 | rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77650_SBB1_desc; | |
483 | rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77650_SBB2_desc; | |
484 | break; | |
485 | case MAX77650_CID_77651A: | |
486 | case MAX77650_CID_77651B: | |
487 | rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77651_SBB1_desc; | |
488 | rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77651_SBB2_desc; | |
489 | break; | |
490 | default: | |
491 | return -ENODEV; | |
492 | } | |
493 | ||
494 | config.dev = parent; | |
495 | ||
496 | for (i = 0; i < MAX77650_REGULATOR_NUM_REGULATORS; i++) { | |
497 | rdesc = rdescs[i]; | |
498 | config.driver_data = rdesc; | |
499 | ||
500 | rdev = devm_regulator_register(dev, &rdesc->desc, &config); | |
501 | if (IS_ERR(rdev)) | |
502 | return PTR_ERR(rdev); | |
503 | } | |
504 | ||
505 | return 0; | |
506 | } | |
507 | ||
508 | static struct platform_driver max77650_regulator_driver = { | |
509 | .driver = { | |
510 | .name = "max77650-regulator", | |
511 | }, | |
512 | .probe = max77650_regulator_probe, | |
513 | }; | |
514 | module_platform_driver(max77650_regulator_driver); | |
515 | ||
516 | MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver"); | |
517 | MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>"); | |
518 | MODULE_LICENSE("GPL v2"); |