]> git.ipfire.org Git - thirdparty/linux.git/blame - drivers/regulator/wm8350-regulator.c
Merge tag 'x86-fpu-2020-06-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[thirdparty/linux.git] / drivers / regulator / wm8350-regulator.c
CommitLineData
87dbc5eb
AL
1// SPDX-License-Identifier: GPL-2.0+
2//
3// wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC
4//
5// Copyright 2007, 2008 Wolfson Microelectronics PLC.
6//
7// Author: Liam Girdwood
8// linux@wolfsonmicro.com
da09155a
MB
9
10#include <linux/module.h>
11#include <linux/moduleparam.h>
12#include <linux/init.h>
13#include <linux/bitops.h>
14#include <linux/err.h>
15#include <linux/i2c.h>
16#include <linux/mfd/wm8350/core.h>
17#include <linux/mfd/wm8350/pmic.h>
18#include <linux/platform_device.h>
19#include <linux/regulator/driver.h>
20#include <linux/regulator/machine.h>
21
221a7c7c
MB
22/* Maximum value possible for VSEL */
23#define WM8350_DCDC_MAX_VSEL 0x66
24
da09155a 25/* Microamps */
dfeb7a93 26static const unsigned int isink_cur[] = {
da09155a
MB
27 4,
28 5,
29 6,
30 7,
31 8,
32 10,
33 11,
34 14,
35 16,
36 19,
37 23,
38 27,
39 32,
40 39,
41 46,
42 54,
43 65,
44 77,
45 92,
46 109,
47 130,
48 154,
49 183,
50 218,
51 259,
52 308,
53 367,
54 436,
55 518,
56 616,
57 733,
58 872,
59 1037,
60 1233,
61 1466,
62 1744,
63 2073,
64 2466,
65 2933,
66 3487,
67 4147,
68 4932,
69 5865,
70 6975,
71 8294,
72 9864,
73 11730,
74 13949,
75 16589,
76 19728,
77 23460,
78 27899,
79 33178,
80 39455,
81 46920,
82 55798,
83 66355,
84 78910,
85 93840,
86 111596,
87 132710,
88 157820,
89 187681,
90 223191
91};
92
da09155a
MB
93/* turn on ISINK followed by DCDC */
94static int wm8350_isink_enable(struct regulator_dev *rdev)
95{
96 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
97 int isink = rdev_get_id(rdev);
98
99 switch (isink) {
100 case WM8350_ISINK_A:
101 switch (wm8350->pmic.isink_A_dcdc) {
102 case WM8350_DCDC_2:
103 case WM8350_DCDC_5:
104 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,
105 WM8350_CS1_ENA);
106 wm8350_set_bits(wm8350, WM8350_CSA_FLASH_CONTROL,
107 WM8350_CS1_DRIVE);
108 wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
109 1 << (wm8350->pmic.isink_A_dcdc -
110 WM8350_DCDC_1));
111 break;
112 default:
113 return -EINVAL;
114 }
115 break;
116 case WM8350_ISINK_B:
117 switch (wm8350->pmic.isink_B_dcdc) {
118 case WM8350_DCDC_2:
119 case WM8350_DCDC_5:
120 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,
121 WM8350_CS2_ENA);
122 wm8350_set_bits(wm8350, WM8350_CSB_FLASH_CONTROL,
123 WM8350_CS2_DRIVE);
124 wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
125 1 << (wm8350->pmic.isink_B_dcdc -
126 WM8350_DCDC_1));
127 break;
128 default:
129 return -EINVAL;
130 }
131 break;
132 default:
133 return -EINVAL;
134 }
135 return 0;
136}
137
138static int wm8350_isink_disable(struct regulator_dev *rdev)
139{
140 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
141 int isink = rdev_get_id(rdev);
142
143 switch (isink) {
144 case WM8350_ISINK_A:
145 switch (wm8350->pmic.isink_A_dcdc) {
146 case WM8350_DCDC_2:
147 case WM8350_DCDC_5:
148 wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
149 1 << (wm8350->pmic.isink_A_dcdc -
150 WM8350_DCDC_1));
151 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7,
152 WM8350_CS1_ENA);
153 break;
154 default:
155 return -EINVAL;
156 }
157 break;
158 case WM8350_ISINK_B:
159 switch (wm8350->pmic.isink_B_dcdc) {
160 case WM8350_DCDC_2:
161 case WM8350_DCDC_5:
162 wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
163 1 << (wm8350->pmic.isink_B_dcdc -
164 WM8350_DCDC_1));
165 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7,
166 WM8350_CS2_ENA);
167 break;
168 default:
169 return -EINVAL;
170 }
171 break;
172 default:
173 return -EINVAL;
174 }
175 return 0;
176}
177
178static int wm8350_isink_is_enabled(struct regulator_dev *rdev)
179{
180 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
181 int isink = rdev_get_id(rdev);
182
183 switch (isink) {
184 case WM8350_ISINK_A:
185 return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) &
186 0x8000;
187 case WM8350_ISINK_B:
188 return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) &
189 0x8000;
190 }
191 return -EINVAL;
192}
193
75c8ac22
MB
194static int wm8350_isink_enable_time(struct regulator_dev *rdev)
195{
196 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
197 int isink = rdev_get_id(rdev);
198 int reg;
199
200 switch (isink) {
201 case WM8350_ISINK_A:
202 reg = wm8350_reg_read(wm8350, WM8350_CSA_FLASH_CONTROL);
203 break;
204 case WM8350_ISINK_B:
205 reg = wm8350_reg_read(wm8350, WM8350_CSB_FLASH_CONTROL);
206 break;
207 default:
208 return -EINVAL;
209 }
210
211 if (reg & WM8350_CS1_FLASH_MODE) {
212 switch (reg & WM8350_CS1_ON_RAMP_MASK) {
213 case 0:
214 return 0;
215 case 1:
216 return 1950;
217 case 2:
218 return 3910;
219 case 3:
220 return 7800;
221 }
222 } else {
223 switch (reg & WM8350_CS1_ON_RAMP_MASK) {
224 case 0:
225 return 0;
226 case 1:
227 return 250000;
228 case 2:
229 return 500000;
230 case 3:
231 return 1000000;
232 }
233 }
234
235 return -EINVAL;
236}
237
238
da09155a
MB
239int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode,
240 u16 trigger, u16 duration, u16 on_ramp, u16 off_ramp,
241 u16 drive)
242{
243 switch (isink) {
244 case WM8350_ISINK_A:
245 wm8350_reg_write(wm8350, WM8350_CSA_FLASH_CONTROL,
246 (mode ? WM8350_CS1_FLASH_MODE : 0) |
247 (trigger ? WM8350_CS1_TRIGSRC : 0) |
248 duration | on_ramp | off_ramp | drive);
249 break;
250 case WM8350_ISINK_B:
251 wm8350_reg_write(wm8350, WM8350_CSB_FLASH_CONTROL,
252 (mode ? WM8350_CS2_FLASH_MODE : 0) |
253 (trigger ? WM8350_CS2_TRIGSRC : 0) |
254 duration | on_ramp | off_ramp | drive);
255 break;
256 default:
257 return -EINVAL;
258 }
259 return 0;
260}
261EXPORT_SYMBOL_GPL(wm8350_isink_set_flash);
262
da09155a
MB
263static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
264{
265 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
c7057422 266 int sel, volt_reg, dcdc = rdev_get_id(rdev);
da09155a
MB
267 u16 val;
268
c7057422 269 dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, uV / 1000);
da09155a
MB
270
271 switch (dcdc) {
272 case WM8350_DCDC_1:
273 volt_reg = WM8350_DCDC1_LOW_POWER;
274 break;
275 case WM8350_DCDC_3:
276 volt_reg = WM8350_DCDC3_LOW_POWER;
277 break;
278 case WM8350_DCDC_4:
279 volt_reg = WM8350_DCDC4_LOW_POWER;
280 break;
281 case WM8350_DCDC_6:
282 volt_reg = WM8350_DCDC6_LOW_POWER;
283 break;
284 case WM8350_DCDC_2:
285 case WM8350_DCDC_5:
286 default:
287 return -EINVAL;
288 }
289
c7057422
AL
290 sel = regulator_map_voltage_linear(rdev, uV, uV);
291 if (sel < 0)
0b61ad1a 292 return sel;
c7057422 293
da09155a
MB
294 /* all DCDCs have same mV bits */
295 val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK;
c7057422 296 wm8350_reg_write(wm8350, volt_reg, val | sel);
da09155a
MB
297 return 0;
298}
299
300static int wm8350_dcdc_set_suspend_enable(struct regulator_dev *rdev)
301{
302 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
303 int dcdc = rdev_get_id(rdev);
304 u16 val;
305
306 switch (dcdc) {
307 case WM8350_DCDC_1:
308 val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER)
309 & ~WM8350_DCDC_HIB_MODE_MASK;
310 wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER,
eb416815 311 val | wm8350->pmic.dcdc1_hib_mode);
da09155a
MB
312 break;
313 case WM8350_DCDC_3:
314 val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER)
315 & ~WM8350_DCDC_HIB_MODE_MASK;
316 wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER,
eb416815 317 val | wm8350->pmic.dcdc3_hib_mode);
da09155a
MB
318 break;
319 case WM8350_DCDC_4:
320 val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER)
321 & ~WM8350_DCDC_HIB_MODE_MASK;
322 wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER,
eb416815 323 val | wm8350->pmic.dcdc4_hib_mode);
da09155a
MB
324 break;
325 case WM8350_DCDC_6:
326 val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER)
327 & ~WM8350_DCDC_HIB_MODE_MASK;
328 wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER,
eb416815 329 val | wm8350->pmic.dcdc6_hib_mode);
da09155a
MB
330 break;
331 case WM8350_DCDC_2:
332 case WM8350_DCDC_5:
333 default:
334 return -EINVAL;
335 }
336
337 return 0;
338}
339
340static int wm8350_dcdc_set_suspend_disable(struct regulator_dev *rdev)
341{
342 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
343 int dcdc = rdev_get_id(rdev);
344 u16 val;
345
346 switch (dcdc) {
347 case WM8350_DCDC_1:
348 val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER);
349 wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
350 wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER,
cee1a799 351 val | WM8350_DCDC_HIB_MODE_DIS);
da09155a
MB
352 break;
353 case WM8350_DCDC_3:
354 val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER);
355 wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
356 wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER,
cee1a799 357 val | WM8350_DCDC_HIB_MODE_DIS);
da09155a
MB
358 break;
359 case WM8350_DCDC_4:
360 val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER);
361 wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
362 wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER,
cee1a799 363 val | WM8350_DCDC_HIB_MODE_DIS);
da09155a
MB
364 break;
365 case WM8350_DCDC_6:
366 val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER);
367 wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
368 wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER,
cee1a799 369 val | WM8350_DCDC_HIB_MODE_DIS);
da09155a
MB
370 break;
371 case WM8350_DCDC_2:
372 case WM8350_DCDC_5:
373 default:
374 return -EINVAL;
375 }
376
377 return 0;
378}
379
380static int wm8350_dcdc25_set_suspend_enable(struct regulator_dev *rdev)
381{
382 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
383 int dcdc = rdev_get_id(rdev);
384 u16 val;
385
386 switch (dcdc) {
387 case WM8350_DCDC_2:
388 val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)
389 & ~WM8350_DC2_HIB_MODE_MASK;
390 wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |
93009286 391 (WM8350_DC2_HIB_MODE_ACTIVE << WM8350_DC2_HIB_MODE_SHIFT));
da09155a
MB
392 break;
393 case WM8350_DCDC_5:
394 val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)
93009286 395 & ~WM8350_DC5_HIB_MODE_MASK;
da09155a 396 wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |
93009286 397 (WM8350_DC5_HIB_MODE_ACTIVE << WM8350_DC5_HIB_MODE_SHIFT));
da09155a
MB
398 break;
399 default:
400 return -EINVAL;
401 }
402 return 0;
403}
404
405static int wm8350_dcdc25_set_suspend_disable(struct regulator_dev *rdev)
406{
407 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
408 int dcdc = rdev_get_id(rdev);
409 u16 val;
410
411 switch (dcdc) {
412 case WM8350_DCDC_2:
413 val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)
414 & ~WM8350_DC2_HIB_MODE_MASK;
415 wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |
93009286 416 (WM8350_DC2_HIB_MODE_DISABLE << WM8350_DC2_HIB_MODE_SHIFT));
da09155a
MB
417 break;
418 case WM8350_DCDC_5:
419 val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)
93009286 420 & ~WM8350_DC5_HIB_MODE_MASK;
da09155a 421 wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |
93009286 422 (WM8350_DC5_HIB_MODE_DISABLE << WM8350_DC5_HIB_MODE_SHIFT));
da09155a
MB
423 break;
424 default:
425 return -EINVAL;
426 }
427 return 0;
428}
429
430static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev,
431 unsigned int mode)
432{
433 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
434 int dcdc = rdev_get_id(rdev);
435 u16 *hib_mode;
436
437 switch (dcdc) {
438 case WM8350_DCDC_1:
439 hib_mode = &wm8350->pmic.dcdc1_hib_mode;
440 break;
441 case WM8350_DCDC_3:
442 hib_mode = &wm8350->pmic.dcdc3_hib_mode;
443 break;
444 case WM8350_DCDC_4:
445 hib_mode = &wm8350->pmic.dcdc4_hib_mode;
446 break;
447 case WM8350_DCDC_6:
448 hib_mode = &wm8350->pmic.dcdc6_hib_mode;
449 break;
450 case WM8350_DCDC_2:
451 case WM8350_DCDC_5:
452 default:
453 return -EINVAL;
454 }
455
456 switch (mode) {
457 case REGULATOR_MODE_NORMAL:
458 *hib_mode = WM8350_DCDC_HIB_MODE_IMAGE;
459 break;
460 case REGULATOR_MODE_IDLE:
461 *hib_mode = WM8350_DCDC_HIB_MODE_STANDBY;
462 break;
463 case REGULATOR_MODE_STANDBY:
464 *hib_mode = WM8350_DCDC_HIB_MODE_LDO_IM;
465 break;
466 default:
467 return -EINVAL;
468 }
469
470 return 0;
471}
472
60ab7f41 473static const struct linear_range wm8350_ldo_ranges[] = {
8828bae4
AL
474 REGULATOR_LINEAR_RANGE(900000, 0, 15, 50000),
475 REGULATOR_LINEAR_RANGE(1800000, 16, 31, 100000),
c36a1cdf 476};
c7057422 477
da09155a
MB
478static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV)
479{
480 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
c7057422 481 int sel, volt_reg, ldo = rdev_get_id(rdev);
da09155a
MB
482 u16 val;
483
c7057422 484 dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, uV / 1000);
da09155a
MB
485
486 switch (ldo) {
487 case WM8350_LDO_1:
488 volt_reg = WM8350_LDO1_LOW_POWER;
489 break;
490 case WM8350_LDO_2:
491 volt_reg = WM8350_LDO2_LOW_POWER;
492 break;
493 case WM8350_LDO_3:
494 volt_reg = WM8350_LDO3_LOW_POWER;
495 break;
496 case WM8350_LDO_4:
497 volt_reg = WM8350_LDO4_LOW_POWER;
498 break;
499 default:
500 return -EINVAL;
501 }
502
c36a1cdf 503 sel = regulator_map_voltage_linear_range(rdev, uV, uV);
c7057422 504 if (sel < 0)
0b61ad1a 505 return sel;
c7057422 506
da09155a
MB
507 /* all LDOs have same mV bits */
508 val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK;
c7057422 509 wm8350_reg_write(wm8350, volt_reg, val | sel);
da09155a
MB
510 return 0;
511}
512
513static int wm8350_ldo_set_suspend_enable(struct regulator_dev *rdev)
514{
515 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
516 int volt_reg, ldo = rdev_get_id(rdev);
517 u16 val;
518
519 switch (ldo) {
520 case WM8350_LDO_1:
521 volt_reg = WM8350_LDO1_LOW_POWER;
522 break;
523 case WM8350_LDO_2:
524 volt_reg = WM8350_LDO2_LOW_POWER;
525 break;
526 case WM8350_LDO_3:
527 volt_reg = WM8350_LDO3_LOW_POWER;
528 break;
529 case WM8350_LDO_4:
530 volt_reg = WM8350_LDO4_LOW_POWER;
531 break;
532 default:
533 return -EINVAL;
534 }
535
536 /* all LDOs have same mV bits */
537 val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK;
538 wm8350_reg_write(wm8350, volt_reg, val);
539 return 0;
540}
541
542static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev)
543{
544 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
545 int volt_reg, ldo = rdev_get_id(rdev);
546 u16 val;
547
548 switch (ldo) {
549 case WM8350_LDO_1:
550 volt_reg = WM8350_LDO1_LOW_POWER;
551 break;
552 case WM8350_LDO_2:
553 volt_reg = WM8350_LDO2_LOW_POWER;
554 break;
555 case WM8350_LDO_3:
556 volt_reg = WM8350_LDO3_LOW_POWER;
557 break;
558 case WM8350_LDO_4:
559 volt_reg = WM8350_LDO4_LOW_POWER;
560 break;
561 default:
562 return -EINVAL;
563 }
564
565 /* all LDOs have same mV bits */
566 val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK;
cee1a799 567 wm8350_reg_write(wm8350, volt_reg, val | WM8350_LDO1_HIB_MODE_DIS);
da09155a
MB
568 return 0;
569}
570
da09155a
MB
571int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
572 u16 stop, u16 fault)
573{
574 int slot_reg;
575 u16 val;
576
577 dev_dbg(wm8350->dev, "%s %d start %d stop %d\n",
578 __func__, dcdc, start, stop);
579
580 /* slot valid ? */
581 if (start > 15 || stop > 15)
582 return -EINVAL;
583
584 switch (dcdc) {
585 case WM8350_DCDC_1:
586 slot_reg = WM8350_DCDC1_TIMEOUTS;
587 break;
588 case WM8350_DCDC_2:
589 slot_reg = WM8350_DCDC2_TIMEOUTS;
590 break;
591 case WM8350_DCDC_3:
592 slot_reg = WM8350_DCDC3_TIMEOUTS;
593 break;
594 case WM8350_DCDC_4:
595 slot_reg = WM8350_DCDC4_TIMEOUTS;
596 break;
597 case WM8350_DCDC_5:
598 slot_reg = WM8350_DCDC5_TIMEOUTS;
599 break;
600 case WM8350_DCDC_6:
601 slot_reg = WM8350_DCDC6_TIMEOUTS;
602 break;
603 default:
604 return -EINVAL;
605 }
606
607 val = wm8350_reg_read(wm8350, slot_reg) &
608 ~(WM8350_DC1_ENSLOT_MASK | WM8350_DC1_SDSLOT_MASK |
609 WM8350_DC1_ERRACT_MASK);
610 wm8350_reg_write(wm8350, slot_reg,
611 val | (start << WM8350_DC1_ENSLOT_SHIFT) |
612 (stop << WM8350_DC1_SDSLOT_SHIFT) |
613 (fault << WM8350_DC1_ERRACT_SHIFT));
614
615 return 0;
616}
617EXPORT_SYMBOL_GPL(wm8350_dcdc_set_slot);
618
619int wm8350_ldo_set_slot(struct wm8350 *wm8350, int ldo, u16 start, u16 stop)
620{
621 int slot_reg;
622 u16 val;
623
624 dev_dbg(wm8350->dev, "%s %d start %d stop %d\n",
625 __func__, ldo, start, stop);
626
627 /* slot valid ? */
628 if (start > 15 || stop > 15)
629 return -EINVAL;
630
631 switch (ldo) {
632 case WM8350_LDO_1:
633 slot_reg = WM8350_LDO1_TIMEOUTS;
634 break;
635 case WM8350_LDO_2:
636 slot_reg = WM8350_LDO2_TIMEOUTS;
637 break;
638 case WM8350_LDO_3:
639 slot_reg = WM8350_LDO3_TIMEOUTS;
640 break;
641 case WM8350_LDO_4:
642 slot_reg = WM8350_LDO4_TIMEOUTS;
643 break;
644 default:
645 return -EINVAL;
646 }
647
648 val = wm8350_reg_read(wm8350, slot_reg) & ~WM8350_LDO1_SDSLOT_MASK;
649 wm8350_reg_write(wm8350, slot_reg, val | ((start << 10) | (stop << 6)));
650 return 0;
651}
652EXPORT_SYMBOL_GPL(wm8350_ldo_set_slot);
653
654int wm8350_dcdc25_set_mode(struct wm8350 *wm8350, int dcdc, u16 mode,
655 u16 ilim, u16 ramp, u16 feedback)
656{
657 u16 val;
658
659 dev_dbg(wm8350->dev, "%s %d mode: %s %s\n", __func__, dcdc,
660 mode ? "normal" : "boost", ilim ? "low" : "normal");
661
662 switch (dcdc) {
663 case WM8350_DCDC_2:
664 val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)
665 & ~(WM8350_DC2_MODE_MASK | WM8350_DC2_ILIM_MASK |
666 WM8350_DC2_RMP_MASK | WM8350_DC2_FBSRC_MASK);
667 wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |
668 (mode << WM8350_DC2_MODE_SHIFT) |
669 (ilim << WM8350_DC2_ILIM_SHIFT) |
670 (ramp << WM8350_DC2_RMP_SHIFT) |
671 (feedback << WM8350_DC2_FBSRC_SHIFT));
672 break;
673 case WM8350_DCDC_5:
674 val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)
675 & ~(WM8350_DC5_MODE_MASK | WM8350_DC5_ILIM_MASK |
676 WM8350_DC5_RMP_MASK | WM8350_DC5_FBSRC_MASK);
677 wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |
678 (mode << WM8350_DC5_MODE_SHIFT) |
679 (ilim << WM8350_DC5_ILIM_SHIFT) |
680 (ramp << WM8350_DC5_RMP_SHIFT) |
681 (feedback << WM8350_DC5_FBSRC_SHIFT));
682 break;
683 default:
684 return -EINVAL;
685 }
686
687 return 0;
688}
689EXPORT_SYMBOL_GPL(wm8350_dcdc25_set_mode);
690
da09155a
MB
691static int force_continuous_enable(struct wm8350 *wm8350, int dcdc, int enable)
692{
693 int reg = 0, ret;
694
695 switch (dcdc) {
696 case WM8350_DCDC_1:
697 reg = WM8350_DCDC1_FORCE_PWM;
698 break;
699 case WM8350_DCDC_3:
700 reg = WM8350_DCDC3_FORCE_PWM;
701 break;
702 case WM8350_DCDC_4:
703 reg = WM8350_DCDC4_FORCE_PWM;
704 break;
705 case WM8350_DCDC_6:
706 reg = WM8350_DCDC6_FORCE_PWM;
707 break;
708 default:
709 return -EINVAL;
710 }
711
712 if (enable)
713 ret = wm8350_set_bits(wm8350, reg,
714 WM8350_DCDC1_FORCE_PWM_ENA);
715 else
716 ret = wm8350_clear_bits(wm8350, reg,
717 WM8350_DCDC1_FORCE_PWM_ENA);
718 return ret;
719}
720
721static int wm8350_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
722{
723 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
724 int dcdc = rdev_get_id(rdev);
725 u16 val;
726
727 if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6)
728 return -EINVAL;
729
730 if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5)
731 return -EINVAL;
732
733 val = 1 << (dcdc - WM8350_DCDC_1);
734
735 switch (mode) {
736 case REGULATOR_MODE_FAST:
737 /* force continuous mode */
738 wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);
739 wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
740 force_continuous_enable(wm8350, dcdc, 1);
741 break;
742 case REGULATOR_MODE_NORMAL:
743 /* active / pulse skipping */
744 wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);
745 wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
746 force_continuous_enable(wm8350, dcdc, 0);
747 break;
748 case REGULATOR_MODE_IDLE:
749 /* standby mode */
750 force_continuous_enable(wm8350, dcdc, 0);
751 wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
752 wm8350_clear_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);
753 break;
754 case REGULATOR_MODE_STANDBY:
755 /* LDO mode */
756 force_continuous_enable(wm8350, dcdc, 0);
757 wm8350_set_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
758 break;
759 }
760
761 return 0;
762}
763
764static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)
765{
766 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
767 int dcdc = rdev_get_id(rdev);
768 u16 mask, sleep, active, force;
769 int mode = REGULATOR_MODE_NORMAL;
33f301af 770 int reg;
da09155a 771
33f301af
MB
772 switch (dcdc) {
773 case WM8350_DCDC_1:
774 reg = WM8350_DCDC1_FORCE_PWM;
775 break;
776 case WM8350_DCDC_3:
777 reg = WM8350_DCDC3_FORCE_PWM;
778 break;
779 case WM8350_DCDC_4:
780 reg = WM8350_DCDC4_FORCE_PWM;
781 break;
782 case WM8350_DCDC_6:
783 reg = WM8350_DCDC6_FORCE_PWM;
784 break;
785 default:
da09155a 786 return -EINVAL;
33f301af 787 }
da09155a
MB
788
789 mask = 1 << (dcdc - WM8350_DCDC_1);
790 active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;
33f301af 791 force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;
da09155a 792 sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;
33f301af 793
da09155a
MB
794 dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",
795 mask, active, sleep, force);
796
797 if (active && !sleep) {
798 if (force)
799 mode = REGULATOR_MODE_FAST;
800 else
801 mode = REGULATOR_MODE_NORMAL;
802 } else if (!active && !sleep)
803 mode = REGULATOR_MODE_IDLE;
8ecee36a 804 else if (sleep)
da09155a
MB
805 mode = REGULATOR_MODE_STANDBY;
806
807 return mode;
808}
809
810static unsigned int wm8350_ldo_get_mode(struct regulator_dev *rdev)
811{
812 return REGULATOR_MODE_NORMAL;
813}
814
815struct wm8350_dcdc_efficiency {
816 int uA_load_min;
817 int uA_load_max;
818 unsigned int mode;
819};
820
821static const struct wm8350_dcdc_efficiency dcdc1_6_efficiency[] = {
822 {0, 10000, REGULATOR_MODE_STANDBY}, /* 0 - 10mA - LDO */
823 {10000, 100000, REGULATOR_MODE_IDLE}, /* 10mA - 100mA - Standby */
824 {100000, 1000000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */
825 {-1, -1, REGULATOR_MODE_NORMAL},
826};
827
828static const struct wm8350_dcdc_efficiency dcdc3_4_efficiency[] = {
829 {0, 10000, REGULATOR_MODE_STANDBY}, /* 0 - 10mA - LDO */
830 {10000, 100000, REGULATOR_MODE_IDLE}, /* 10mA - 100mA - Standby */
831 {100000, 800000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */
832 {-1, -1, REGULATOR_MODE_NORMAL},
833};
834
835static unsigned int get_mode(int uA, const struct wm8350_dcdc_efficiency *eff)
836{
837 int i = 0;
838
839 while (eff[i].uA_load_min != -1) {
840 if (uA >= eff[i].uA_load_min && uA <= eff[i].uA_load_max)
841 return eff[i].mode;
f97a2368 842 i++;
da09155a
MB
843 }
844 return REGULATOR_MODE_NORMAL;
845}
846
847/* Query the regulator for it's most efficient mode @ uV,uA
848 * WM8350 regulator efficiency is pretty similar over
849 * different input and output uV.
850 */
851static unsigned int wm8350_dcdc_get_optimum_mode(struct regulator_dev *rdev,
852 int input_uV, int output_uV,
853 int output_uA)
854{
855 int dcdc = rdev_get_id(rdev), mode;
856
857 switch (dcdc) {
858 case WM8350_DCDC_1:
859 case WM8350_DCDC_6:
860 mode = get_mode(output_uA, dcdc1_6_efficiency);
861 break;
862 case WM8350_DCDC_3:
863 case WM8350_DCDC_4:
864 mode = get_mode(output_uA, dcdc3_4_efficiency);
865 break;
866 default:
867 mode = REGULATOR_MODE_NORMAL;
868 break;
869 }
870 return mode;
871}
872
b0d6dd3b 873static const struct regulator_ops wm8350_dcdc_ops = {
107a3967 874 .set_voltage_sel = regulator_set_voltage_sel_regmap,
b4ec87ae 875 .get_voltage_sel = regulator_get_voltage_sel_regmap,
107a3967 876 .list_voltage = regulator_list_voltage_linear,
fcbb71f6 877 .map_voltage = regulator_map_voltage_linear,
a540f682
MB
878 .enable = regulator_enable_regmap,
879 .disable = regulator_disable_regmap,
880 .is_enabled = regulator_is_enabled_regmap,
da09155a
MB
881 .get_mode = wm8350_dcdc_get_mode,
882 .set_mode = wm8350_dcdc_set_mode,
883 .get_optimum_mode = wm8350_dcdc_get_optimum_mode,
da09155a
MB
884 .set_suspend_voltage = wm8350_dcdc_set_suspend_voltage,
885 .set_suspend_enable = wm8350_dcdc_set_suspend_enable,
886 .set_suspend_disable = wm8350_dcdc_set_suspend_disable,
887 .set_suspend_mode = wm8350_dcdc_set_suspend_mode,
888};
889
b0d6dd3b 890static const struct regulator_ops wm8350_dcdc2_5_ops = {
a540f682
MB
891 .enable = regulator_enable_regmap,
892 .disable = regulator_disable_regmap,
893 .is_enabled = regulator_is_enabled_regmap,
da09155a
MB
894 .set_suspend_enable = wm8350_dcdc25_set_suspend_enable,
895 .set_suspend_disable = wm8350_dcdc25_set_suspend_disable,
896};
897
b0d6dd3b 898static const struct regulator_ops wm8350_ldo_ops = {
c36a1cdf 899 .map_voltage = regulator_map_voltage_linear_range,
fc492f9b 900 .set_voltage_sel = regulator_set_voltage_sel_regmap,
b4ec87ae 901 .get_voltage_sel = regulator_get_voltage_sel_regmap,
c36a1cdf 902 .list_voltage = regulator_list_voltage_linear_range,
a540f682
MB
903 .enable = regulator_enable_regmap,
904 .disable = regulator_disable_regmap,
905 .is_enabled = regulator_is_enabled_regmap,
da09155a
MB
906 .get_mode = wm8350_ldo_get_mode,
907 .set_suspend_voltage = wm8350_ldo_set_suspend_voltage,
908 .set_suspend_enable = wm8350_ldo_set_suspend_enable,
909 .set_suspend_disable = wm8350_ldo_set_suspend_disable,
910};
911
b0d6dd3b 912static const struct regulator_ops wm8350_isink_ops = {
dfeb7a93
AL
913 .set_current_limit = regulator_set_current_limit_regmap,
914 .get_current_limit = regulator_get_current_limit_regmap,
da09155a
MB
915 .enable = wm8350_isink_enable,
916 .disable = wm8350_isink_disable,
917 .is_enabled = wm8350_isink_is_enabled,
75c8ac22 918 .enable_time = wm8350_isink_enable_time,
da09155a
MB
919};
920
47924b6a 921static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
da09155a
MB
922 {
923 .name = "DCDC1",
924 .id = WM8350_DCDC_1,
925 .ops = &wm8350_dcdc_ops,
926 .irq = WM8350_IRQ_UV_DC1,
927 .type = REGULATOR_VOLTAGE,
221a7c7c 928 .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
107a3967
MB
929 .min_uV = 850000,
930 .uV_step = 25000,
b4ec87ae
MB
931 .vsel_reg = WM8350_DCDC1_CONTROL,
932 .vsel_mask = WM8350_DC1_VSEL_MASK,
a540f682
MB
933 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
934 .enable_mask = WM8350_DC1_ENA,
da09155a
MB
935 .owner = THIS_MODULE,
936 },
937 {
938 .name = "DCDC2",
939 .id = WM8350_DCDC_2,
940 .ops = &wm8350_dcdc2_5_ops,
941 .irq = WM8350_IRQ_UV_DC2,
942 .type = REGULATOR_VOLTAGE,
a540f682
MB
943 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
944 .enable_mask = WM8350_DC2_ENA,
da09155a
MB
945 .owner = THIS_MODULE,
946 },
947 {
948 .name = "DCDC3",
949 .id = WM8350_DCDC_3,
950 .ops = &wm8350_dcdc_ops,
951 .irq = WM8350_IRQ_UV_DC3,
952 .type = REGULATOR_VOLTAGE,
221a7c7c 953 .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
107a3967
MB
954 .min_uV = 850000,
955 .uV_step = 25000,
b4ec87ae
MB
956 .vsel_reg = WM8350_DCDC3_CONTROL,
957 .vsel_mask = WM8350_DC3_VSEL_MASK,
a540f682
MB
958 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
959 .enable_mask = WM8350_DC3_ENA,
da09155a
MB
960 .owner = THIS_MODULE,
961 },
962 {
963 .name = "DCDC4",
964 .id = WM8350_DCDC_4,
965 .ops = &wm8350_dcdc_ops,
966 .irq = WM8350_IRQ_UV_DC4,
967 .type = REGULATOR_VOLTAGE,
221a7c7c 968 .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
0ff47246
AL
969 .min_uV = 850000,
970 .uV_step = 25000,
b4ec87ae
MB
971 .vsel_reg = WM8350_DCDC4_CONTROL,
972 .vsel_mask = WM8350_DC4_VSEL_MASK,
a540f682
MB
973 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
974 .enable_mask = WM8350_DC4_ENA,
da09155a
MB
975 .owner = THIS_MODULE,
976 },
977 {
978 .name = "DCDC5",
979 .id = WM8350_DCDC_5,
980 .ops = &wm8350_dcdc2_5_ops,
981 .irq = WM8350_IRQ_UV_DC5,
982 .type = REGULATOR_VOLTAGE,
a540f682
MB
983 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
984 .enable_mask = WM8350_DC5_ENA,
da09155a
MB
985 .owner = THIS_MODULE,
986 },
987 {
988 .name = "DCDC6",
989 .id = WM8350_DCDC_6,
990 .ops = &wm8350_dcdc_ops,
991 .irq = WM8350_IRQ_UV_DC6,
992 .type = REGULATOR_VOLTAGE,
221a7c7c 993 .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
107a3967
MB
994 .min_uV = 850000,
995 .uV_step = 25000,
b4ec87ae
MB
996 .vsel_reg = WM8350_DCDC6_CONTROL,
997 .vsel_mask = WM8350_DC6_VSEL_MASK,
a540f682
MB
998 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
999 .enable_mask = WM8350_DC6_ENA,
da09155a
MB
1000 .owner = THIS_MODULE,
1001 },
1002 {
1003 .name = "LDO1",
1004 .id = WM8350_LDO_1,
1005 .ops = &wm8350_ldo_ops,
1006 .irq = WM8350_IRQ_UV_LDO1,
1007 .type = REGULATOR_VOLTAGE,
221a7c7c 1008 .n_voltages = WM8350_LDO1_VSEL_MASK + 1,
c36a1cdf
MB
1009 .linear_ranges = wm8350_ldo_ranges,
1010 .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
b4ec87ae
MB
1011 .vsel_reg = WM8350_LDO1_CONTROL,
1012 .vsel_mask = WM8350_LDO1_VSEL_MASK,
a540f682
MB
1013 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
1014 .enable_mask = WM8350_LDO1_ENA,
da09155a
MB
1015 .owner = THIS_MODULE,
1016 },
1017 {
1018 .name = "LDO2",
1019 .id = WM8350_LDO_2,
1020 .ops = &wm8350_ldo_ops,
1021 .irq = WM8350_IRQ_UV_LDO2,
1022 .type = REGULATOR_VOLTAGE,
221a7c7c 1023 .n_voltages = WM8350_LDO2_VSEL_MASK + 1,
c36a1cdf
MB
1024 .linear_ranges = wm8350_ldo_ranges,
1025 .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
b4ec87ae
MB
1026 .vsel_reg = WM8350_LDO2_CONTROL,
1027 .vsel_mask = WM8350_LDO2_VSEL_MASK,
a540f682
MB
1028 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
1029 .enable_mask = WM8350_LDO2_ENA,
da09155a
MB
1030 .owner = THIS_MODULE,
1031 },
1032 {
1033 .name = "LDO3",
1034 .id = WM8350_LDO_3,
1035 .ops = &wm8350_ldo_ops,
1036 .irq = WM8350_IRQ_UV_LDO3,
1037 .type = REGULATOR_VOLTAGE,
221a7c7c 1038 .n_voltages = WM8350_LDO3_VSEL_MASK + 1,
c36a1cdf
MB
1039 .linear_ranges = wm8350_ldo_ranges,
1040 .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
b4ec87ae
MB
1041 .vsel_reg = WM8350_LDO3_CONTROL,
1042 .vsel_mask = WM8350_LDO3_VSEL_MASK,
a540f682
MB
1043 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
1044 .enable_mask = WM8350_LDO3_ENA,
da09155a
MB
1045 .owner = THIS_MODULE,
1046 },
1047 {
1048 .name = "LDO4",
1049 .id = WM8350_LDO_4,
1050 .ops = &wm8350_ldo_ops,
1051 .irq = WM8350_IRQ_UV_LDO4,
1052 .type = REGULATOR_VOLTAGE,
221a7c7c 1053 .n_voltages = WM8350_LDO4_VSEL_MASK + 1,
c36a1cdf
MB
1054 .linear_ranges = wm8350_ldo_ranges,
1055 .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
b4ec87ae
MB
1056 .vsel_reg = WM8350_LDO4_CONTROL,
1057 .vsel_mask = WM8350_LDO4_VSEL_MASK,
a540f682
MB
1058 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
1059 .enable_mask = WM8350_LDO4_ENA,
da09155a
MB
1060 .owner = THIS_MODULE,
1061 },
1062 {
1063 .name = "ISINKA",
1064 .id = WM8350_ISINK_A,
1065 .ops = &wm8350_isink_ops,
1066 .irq = WM8350_IRQ_CS1,
1067 .type = REGULATOR_CURRENT,
1068 .owner = THIS_MODULE,
dfeb7a93
AL
1069 .curr_table = isink_cur,
1070 .n_current_limits = ARRAY_SIZE(isink_cur),
1071 .csel_reg = WM8350_CURRENT_SINK_DRIVER_A,
1072 .csel_mask = WM8350_CS1_ISEL_MASK,
da09155a
MB
1073 },
1074 {
1075 .name = "ISINKB",
1076 .id = WM8350_ISINK_B,
1077 .ops = &wm8350_isink_ops,
1078 .irq = WM8350_IRQ_CS2,
1079 .type = REGULATOR_CURRENT,
1080 .owner = THIS_MODULE,
dfeb7a93
AL
1081 .curr_table = isink_cur,
1082 .n_current_limits = ARRAY_SIZE(isink_cur),
1083 .csel_reg = WM8350_CURRENT_SINK_DRIVER_B,
1084 .csel_mask = WM8350_CS2_ISEL_MASK,
da09155a
MB
1085 },
1086};
1087
5a65edbc 1088static irqreturn_t pmic_uv_handler(int irq, void *data)
da09155a
MB
1089{
1090 struct regulator_dev *rdev = (struct regulator_dev *)data;
1091
f8702f9e 1092 regulator_lock(rdev);
da09155a
MB
1093 if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
1094 regulator_notifier_call_chain(rdev,
1095 REGULATOR_EVENT_REGULATION_OUT,
8f45acb5 1096 NULL);
da09155a
MB
1097 else
1098 regulator_notifier_call_chain(rdev,
1099 REGULATOR_EVENT_UNDER_VOLTAGE,
8f45acb5 1100 NULL);
f8702f9e 1101 regulator_unlock(rdev);
5a65edbc
MB
1102
1103 return IRQ_HANDLED;
da09155a
MB
1104}
1105
1106static int wm8350_regulator_probe(struct platform_device *pdev)
1107{
1108 struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
c172708d 1109 struct regulator_config config = { };
da09155a
MB
1110 struct regulator_dev *rdev;
1111 int ret;
1112 u16 val;
1113
1114 if (pdev->id < WM8350_DCDC_1 || pdev->id > WM8350_ISINK_B)
1115 return -ENODEV;
1116
1117 /* do any regulatior specific init */
1118 switch (pdev->id) {
1119 case WM8350_DCDC_1:
1120 val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER);
1121 wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
1122 break;
1123 case WM8350_DCDC_3:
1124 val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER);
1125 wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
1126 break;
1127 case WM8350_DCDC_4:
1128 val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER);
1129 wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
1130 break;
1131 case WM8350_DCDC_6:
1132 val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER);
1133 wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
1134 break;
1135 }
1136
c172708d 1137 config.dev = &pdev->dev;
dff91d0b 1138 config.init_data = dev_get_platdata(&pdev->dev);
c172708d 1139 config.driver_data = dev_get_drvdata(&pdev->dev);
b4ec87ae 1140 config.regmap = wm8350->regmap;
c172708d 1141
da09155a 1142 /* register regulator */
e57e5469
MB
1143 rdev = devm_regulator_register(&pdev->dev, &wm8350_reg[pdev->id],
1144 &config);
da09155a
MB
1145 if (IS_ERR(rdev)) {
1146 dev_err(&pdev->dev, "failed to register %s\n",
1147 wm8350_reg[pdev->id].name);
1148 return PTR_ERR(rdev);
1149 }
1150
1151 /* register regulator IRQ */
1152 ret = wm8350_register_irq(wm8350, wm8350_reg[pdev->id].irq,
5a65edbc 1153 pmic_uv_handler, 0, "UV", rdev);
da09155a 1154 if (ret < 0) {
da09155a
MB
1155 dev_err(&pdev->dev, "failed to register regulator %s IRQ\n",
1156 wm8350_reg[pdev->id].name);
1157 return ret;
1158 }
1159
da09155a
MB
1160 return 0;
1161}
1162
1163static int wm8350_regulator_remove(struct platform_device *pdev)
1164{
1165 struct regulator_dev *rdev = platform_get_drvdata(pdev);
1166 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
1167
f99344fc 1168 wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);
da09155a 1169
da09155a
MB
1170 return 0;
1171}
1172
1173int wm8350_register_regulator(struct wm8350 *wm8350, int reg,
1174 struct regulator_init_data *initdata)
1175{
1176 struct platform_device *pdev;
1177 int ret;
4dee4d44
RK
1178 if (reg < 0 || reg >= NUM_WM8350_REGULATORS)
1179 return -EINVAL;
da09155a
MB
1180
1181 if (wm8350->pmic.pdev[reg])
1182 return -EBUSY;
1183
645524a9
MB
1184 if (reg >= WM8350_DCDC_1 && reg <= WM8350_DCDC_6 &&
1185 reg > wm8350->pmic.max_dcdc)
1186 return -ENODEV;
1187 if (reg >= WM8350_ISINK_A && reg <= WM8350_ISINK_B &&
1188 reg > wm8350->pmic.max_isink)
1189 return -ENODEV;
1190
da09155a
MB
1191 pdev = platform_device_alloc("wm8350-regulator", reg);
1192 if (!pdev)
1193 return -ENOMEM;
1194
1195 wm8350->pmic.pdev[reg] = pdev;
1196
1197 initdata->driver_data = wm8350;
1198
1199 pdev->dev.platform_data = initdata;
1200 pdev->dev.parent = wm8350->dev;
1201 platform_set_drvdata(pdev, wm8350);
1202
1203 ret = platform_device_add(pdev);
1204
1205 if (ret != 0) {
1206 dev_err(wm8350->dev, "Failed to register regulator %d: %d\n",
1207 reg, ret);
e9a1c512 1208 platform_device_put(pdev);
da09155a
MB
1209 wm8350->pmic.pdev[reg] = NULL;
1210 }
1211
1212 return ret;
1213}
1214EXPORT_SYMBOL_GPL(wm8350_register_regulator);
1215
0081e802
MB
1216/**
1217 * wm8350_register_led - Register a WM8350 LED output
1218 *
1219 * @param wm8350 The WM8350 device to configure.
1220 * @param lednum LED device index to create.
1221 * @param dcdc The DCDC to use for the LED.
1222 * @param isink The ISINK to use for the LED.
1223 * @param pdata Configuration for the LED.
1224 *
1225 * The WM8350 supports the use of an ISINK together with a DCDC to
1226 * provide a power-efficient LED driver. This function registers the
1227 * regulators and instantiates the platform device for a LED. The
1228 * operating modes for the LED regulators must be configured using
1229 * wm8350_isink_set_flash(), wm8350_dcdc25_set_mode() and
1230 * wm8350_dcdc_set_slot() prior to calling this function.
1231 */
1232int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
1233 struct wm8350_led_platform_data *pdata)
1234{
1235 struct wm8350_led *led;
1236 struct platform_device *pdev;
1237 int ret;
1238
8dd2c9e3 1239 if (lednum >= ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {
0081e802
MB
1240 dev_err(wm8350->dev, "Invalid LED index %d\n", lednum);
1241 return -ENODEV;
1242 }
1243
1244 led = &wm8350->pmic.led[lednum];
1245
1246 if (led->pdev) {
1247 dev_err(wm8350->dev, "LED %d already allocated\n", lednum);
1248 return -EINVAL;
1249 }
1250
1251 pdev = platform_device_alloc("wm8350-led", lednum);
1252 if (pdev == NULL) {
1253 dev_err(wm8350->dev, "Failed to allocate LED %d\n", lednum);
1254 return -ENOMEM;
1255 }
1256
34ce8d07 1257 led->isink_consumer.dev_name = dev_name(&pdev->dev);
0081e802
MB
1258 led->isink_consumer.supply = "led_isink";
1259 led->isink_init.num_consumer_supplies = 1;
1260 led->isink_init.consumer_supplies = &led->isink_consumer;
1261 led->isink_init.constraints.min_uA = 0;
1262 led->isink_init.constraints.max_uA = pdata->max_uA;
a2fad9bf
MB
1263 led->isink_init.constraints.valid_ops_mask
1264 = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS;
0081e802
MB
1265 led->isink_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
1266 ret = wm8350_register_regulator(wm8350, isink, &led->isink_init);
1267 if (ret != 0) {
1268 platform_device_put(pdev);
1269 return ret;
1270 }
1271
34ce8d07 1272 led->dcdc_consumer.dev_name = dev_name(&pdev->dev);
0081e802
MB
1273 led->dcdc_consumer.supply = "led_vcc";
1274 led->dcdc_init.num_consumer_supplies = 1;
1275 led->dcdc_init.consumer_supplies = &led->dcdc_consumer;
1276 led->dcdc_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
a2fad9bf 1277 led->dcdc_init.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
0081e802
MB
1278 ret = wm8350_register_regulator(wm8350, dcdc, &led->dcdc_init);
1279 if (ret != 0) {
1280 platform_device_put(pdev);
1281 return ret;
1282 }
1283
1284 switch (isink) {
1285 case WM8350_ISINK_A:
1286 wm8350->pmic.isink_A_dcdc = dcdc;
1287 break;
1288 case WM8350_ISINK_B:
1289 wm8350->pmic.isink_B_dcdc = dcdc;
1290 break;
1291 }
1292
1293 pdev->dev.platform_data = pdata;
1294 pdev->dev.parent = wm8350->dev;
1295 ret = platform_device_add(pdev);
1296 if (ret != 0) {
1297 dev_err(wm8350->dev, "Failed to register LED %d: %d\n",
1298 lednum, ret);
1299 platform_device_put(pdev);
1300 return ret;
1301 }
1302
1303 led->pdev = pdev;
1304
1305 return 0;
1306}
1307EXPORT_SYMBOL_GPL(wm8350_register_led);
1308
da09155a
MB
1309static struct platform_driver wm8350_regulator_driver = {
1310 .probe = wm8350_regulator_probe,
1311 .remove = wm8350_regulator_remove,
1312 .driver = {
1313 .name = "wm8350-regulator",
1314 },
1315};
1316
1317static int __init wm8350_regulator_init(void)
1318{
1319 return platform_driver_register(&wm8350_regulator_driver);
1320}
1321subsys_initcall(wm8350_regulator_init);
1322
1323static void __exit wm8350_regulator_exit(void)
1324{
1325 platform_driver_unregister(&wm8350_regulator_driver);
1326}
1327module_exit(wm8350_regulator_exit);
1328
1329/* Module information */
1330MODULE_AUTHOR("Liam Girdwood");
1331MODULE_DESCRIPTION("WM8350 voltage and current regulator driver");
1332MODULE_LICENSE("GPL");
38c53c89 1333MODULE_ALIAS("platform:wm8350-regulator");