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