4 * Copyright (c) 2011 Samsung Electronics Co., Ltd
5 * http://www.samsung.com
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
14 #include <linux/bug.h>
15 #include <linux/err.h>
16 #include <linux/gpio.h>
17 #include <linux/slab.h>
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/regulator/driver.h>
21 #include <linux/regulator/machine.h>
22 #include <linux/mfd/s5m87xx/s5m-core.h>
23 #include <linux/mfd/s5m87xx/s5m-pmic.h>
27 struct s5m87xx_dev
*iodev
;
29 struct regulator_dev
**rdev
;
30 struct s5m_opmode_data
*opmode
;
47 struct s5m_voltage_desc
{
53 static const struct s5m_voltage_desc buck_voltage_val1
= {
59 static const struct s5m_voltage_desc buck_voltage_val2
= {
65 static const struct s5m_voltage_desc buck_voltage_val3
= {
71 static const struct s5m_voltage_desc ldo_voltage_val1
= {
77 static const struct s5m_voltage_desc ldo_voltage_val2
= {
83 static const struct s5m_voltage_desc
*reg_voltage_map
[] = {
84 [S5M8767_LDO1
] = &ldo_voltage_val2
,
85 [S5M8767_LDO2
] = &ldo_voltage_val2
,
86 [S5M8767_LDO3
] = &ldo_voltage_val1
,
87 [S5M8767_LDO4
] = &ldo_voltage_val1
,
88 [S5M8767_LDO5
] = &ldo_voltage_val1
,
89 [S5M8767_LDO6
] = &ldo_voltage_val2
,
90 [S5M8767_LDO7
] = &ldo_voltage_val2
,
91 [S5M8767_LDO8
] = &ldo_voltage_val2
,
92 [S5M8767_LDO9
] = &ldo_voltage_val1
,
93 [S5M8767_LDO10
] = &ldo_voltage_val1
,
94 [S5M8767_LDO11
] = &ldo_voltage_val1
,
95 [S5M8767_LDO12
] = &ldo_voltage_val1
,
96 [S5M8767_LDO13
] = &ldo_voltage_val1
,
97 [S5M8767_LDO14
] = &ldo_voltage_val1
,
98 [S5M8767_LDO15
] = &ldo_voltage_val2
,
99 [S5M8767_LDO16
] = &ldo_voltage_val1
,
100 [S5M8767_LDO17
] = &ldo_voltage_val1
,
101 [S5M8767_LDO18
] = &ldo_voltage_val1
,
102 [S5M8767_LDO19
] = &ldo_voltage_val1
,
103 [S5M8767_LDO20
] = &ldo_voltage_val1
,
104 [S5M8767_LDO21
] = &ldo_voltage_val1
,
105 [S5M8767_LDO22
] = &ldo_voltage_val1
,
106 [S5M8767_LDO23
] = &ldo_voltage_val1
,
107 [S5M8767_LDO24
] = &ldo_voltage_val1
,
108 [S5M8767_LDO25
] = &ldo_voltage_val1
,
109 [S5M8767_LDO26
] = &ldo_voltage_val1
,
110 [S5M8767_LDO27
] = &ldo_voltage_val1
,
111 [S5M8767_LDO28
] = &ldo_voltage_val1
,
112 [S5M8767_BUCK1
] = &buck_voltage_val1
,
113 [S5M8767_BUCK2
] = &buck_voltage_val2
,
114 [S5M8767_BUCK3
] = &buck_voltage_val2
,
115 [S5M8767_BUCK4
] = &buck_voltage_val2
,
116 [S5M8767_BUCK5
] = &buck_voltage_val1
,
117 [S5M8767_BUCK6
] = &buck_voltage_val1
,
118 [S5M8767_BUCK7
] = NULL
,
119 [S5M8767_BUCK8
] = NULL
,
120 [S5M8767_BUCK9
] = &buck_voltage_val3
,
123 static int s5m8767_list_voltage(struct regulator_dev
*rdev
,
124 unsigned int selector
)
126 const struct s5m_voltage_desc
*desc
;
127 int reg_id
= rdev_get_id(rdev
);
130 if (reg_id
>= ARRAY_SIZE(reg_voltage_map
) || reg_id
< 0)
133 desc
= reg_voltage_map
[reg_id
];
137 val
= desc
->min
+ desc
->step
* selector
;
144 static unsigned int s5m8767_opmode_reg
[][4] = {
145 /* {OFF, ON, LOWPOWER, SUSPEND} */
147 {0x0, 0x3, 0x2, 0x1}, /* LDO1 */
148 {0x0, 0x3, 0x2, 0x1},
149 {0x0, 0x3, 0x2, 0x1},
150 {0x0, 0x0, 0x0, 0x0},
151 {0x0, 0x3, 0x2, 0x1}, /* LDO5 */
152 {0x0, 0x3, 0x2, 0x1},
153 {0x0, 0x3, 0x2, 0x1},
154 {0x0, 0x3, 0x2, 0x1},
155 {0x0, 0x3, 0x2, 0x1},
156 {0x0, 0x3, 0x2, 0x1}, /* LDO10 */
157 {0x0, 0x3, 0x2, 0x1},
158 {0x0, 0x3, 0x2, 0x1},
159 {0x0, 0x3, 0x2, 0x1},
160 {0x0, 0x3, 0x2, 0x1},
161 {0x0, 0x3, 0x2, 0x1}, /* LDO15 */
162 {0x0, 0x3, 0x2, 0x1},
163 {0x0, 0x3, 0x2, 0x1},
164 {0x0, 0x0, 0x0, 0x0},
165 {0x0, 0x3, 0x2, 0x1},
166 {0x0, 0x3, 0x2, 0x1}, /* LDO20 */
167 {0x0, 0x3, 0x2, 0x1},
168 {0x0, 0x3, 0x2, 0x1},
169 {0x0, 0x0, 0x0, 0x0},
170 {0x0, 0x3, 0x2, 0x1},
171 {0x0, 0x3, 0x2, 0x1}, /* LDO25 */
172 {0x0, 0x3, 0x2, 0x1},
173 {0x0, 0x3, 0x2, 0x1},
174 {0x0, 0x3, 0x2, 0x1}, /* LDO28 */
176 /* BUCK1 ... BUCK9 */
177 {0x0, 0x3, 0x1, 0x1}, /* BUCK1 */
178 {0x0, 0x3, 0x1, 0x1},
179 {0x0, 0x3, 0x1, 0x1},
180 {0x0, 0x3, 0x1, 0x1},
181 {0x0, 0x3, 0x2, 0x1}, /* BUCK5 */
182 {0x0, 0x3, 0x1, 0x1},
183 {0x0, 0x3, 0x1, 0x1},
184 {0x0, 0x3, 0x1, 0x1},
185 {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
188 static int s5m8767_get_register(struct regulator_dev
*rdev
, int *reg
,
191 int reg_id
= rdev_get_id(rdev
);
193 struct s5m8767_info
*s5m8767
= rdev_get_drvdata(rdev
);
196 case S5M8767_LDO1
... S5M8767_LDO2
:
197 *reg
= S5M8767_REG_LDO1CTRL
+ (reg_id
- S5M8767_LDO1
);
199 case S5M8767_LDO3
... S5M8767_LDO28
:
200 *reg
= S5M8767_REG_LDO3CTRL
+ (reg_id
- S5M8767_LDO3
);
203 *reg
= S5M8767_REG_BUCK1CTRL1
;
205 case S5M8767_BUCK2
... S5M8767_BUCK4
:
206 *reg
= S5M8767_REG_BUCK2CTRL
+ (reg_id
- S5M8767_BUCK2
) * 9;
209 *reg
= S5M8767_REG_BUCK5CTRL1
;
211 case S5M8767_BUCK6
... S5M8767_BUCK9
:
212 *reg
= S5M8767_REG_BUCK6CTRL1
+ (reg_id
- S5M8767_BUCK6
) * 2;
218 mode
= s5m8767
->opmode
[reg_id
].mode
;
219 *enable_ctrl
= s5m8767_opmode_reg
[reg_id
][mode
] << S5M8767_ENCTRL_SHIFT
;
223 static int s5m8767_reg_is_enabled(struct regulator_dev
*rdev
)
225 struct s5m8767_info
*s5m8767
= rdev_get_drvdata(rdev
);
227 int mask
= 0xc0, enable_ctrl
;
230 ret
= s5m8767_get_register(rdev
, ®
, &enable_ctrl
);
236 ret
= s5m_reg_read(s5m8767
->iodev
, reg
, &val
);
240 return (val
& mask
) == enable_ctrl
;
243 static int s5m8767_reg_enable(struct regulator_dev
*rdev
)
245 struct s5m8767_info
*s5m8767
= rdev_get_drvdata(rdev
);
247 int mask
= 0xc0, enable_ctrl
;
249 ret
= s5m8767_get_register(rdev
, ®
, &enable_ctrl
);
253 return s5m_reg_update(s5m8767
->iodev
, reg
, enable_ctrl
, mask
);
256 static int s5m8767_reg_disable(struct regulator_dev
*rdev
)
258 struct s5m8767_info
*s5m8767
= rdev_get_drvdata(rdev
);
260 int mask
= 0xc0, enable_ctrl
;
262 ret
= s5m8767_get_register(rdev
, ®
, &enable_ctrl
);
266 return s5m_reg_update(s5m8767
->iodev
, reg
, ~mask
, mask
);
269 static int s5m8767_get_voltage_register(struct regulator_dev
*rdev
, int *_reg
)
271 struct s5m8767_info
*s5m8767
= rdev_get_drvdata(rdev
);
272 int reg_id
= rdev_get_id(rdev
);
276 case S5M8767_LDO1
... S5M8767_LDO2
:
277 reg
= S5M8767_REG_LDO1CTRL
+ (reg_id
- S5M8767_LDO1
);
279 case S5M8767_LDO3
... S5M8767_LDO28
:
280 reg
= S5M8767_REG_LDO3CTRL
+ (reg_id
- S5M8767_LDO3
);
283 reg
= S5M8767_REG_BUCK1CTRL2
;
286 reg
= S5M8767_REG_BUCK2DVS1
;
287 if (s5m8767
->buck2_gpiodvs
)
288 reg
+= s5m8767
->buck_gpioindex
;
291 reg
= S5M8767_REG_BUCK3DVS1
;
292 if (s5m8767
->buck3_gpiodvs
)
293 reg
+= s5m8767
->buck_gpioindex
;
296 reg
= S5M8767_REG_BUCK4DVS1
;
297 if (s5m8767
->buck4_gpiodvs
)
298 reg
+= s5m8767
->buck_gpioindex
;
301 reg
= S5M8767_REG_BUCK5CTRL2
;
303 case S5M8767_BUCK6
... S5M8767_BUCK9
:
304 reg
= S5M8767_REG_BUCK6CTRL2
+ (reg_id
- S5M8767_BUCK6
) * 2;
315 static int s5m8767_get_voltage_sel(struct regulator_dev
*rdev
)
317 struct s5m8767_info
*s5m8767
= rdev_get_drvdata(rdev
);
319 int reg_id
= rdev_get_id(rdev
);
322 ret
= s5m8767_get_voltage_register(rdev
, ®
);
326 mask
= (reg_id
< S5M8767_BUCK1
) ? 0x3f : 0xff;
328 ret
= s5m_reg_read(s5m8767
->iodev
, reg
, &val
);
337 static int s5m8767_convert_voltage_to_sel(
338 const struct s5m_voltage_desc
*desc
,
339 int min_vol
, int max_vol
)
346 if (max_vol
< desc
->min
|| min_vol
> desc
->max
)
349 if (min_vol
< desc
->min
)
352 selector
= DIV_ROUND_UP(min_vol
- desc
->min
, desc
->step
);
354 if (desc
->min
+ desc
->step
* selector
> max_vol
)
360 static inline void s5m8767_set_high(struct s5m8767_info
*s5m8767
)
362 int temp_index
= s5m8767
->buck_gpioindex
;
364 gpio_set_value(s5m8767
->buck_gpios
[0], (temp_index
>> 2) & 0x1);
365 gpio_set_value(s5m8767
->buck_gpios
[1], (temp_index
>> 1) & 0x1);
366 gpio_set_value(s5m8767
->buck_gpios
[2], temp_index
& 0x1);
369 static inline void s5m8767_set_low(struct s5m8767_info
*s5m8767
)
371 int temp_index
= s5m8767
->buck_gpioindex
;
373 gpio_set_value(s5m8767
->buck_gpios
[2], temp_index
& 0x1);
374 gpio_set_value(s5m8767
->buck_gpios
[1], (temp_index
>> 1) & 0x1);
375 gpio_set_value(s5m8767
->buck_gpios
[0], (temp_index
>> 2) & 0x1);
378 static int s5m8767_set_voltage(struct regulator_dev
*rdev
,
379 int min_uV
, int max_uV
, unsigned *selector
)
381 struct s5m8767_info
*s5m8767
= rdev_get_drvdata(rdev
);
382 const struct s5m_voltage_desc
*desc
;
383 int reg_id
= rdev_get_id(rdev
);
384 int sel
, reg
, mask
, ret
= 0, old_index
, index
= 0;
386 u8
*buck234_vol
= NULL
;
389 case S5M8767_LDO1
... S5M8767_LDO28
:
392 case S5M8767_BUCK1
... S5M8767_BUCK6
:
394 if (reg_id
== S5M8767_BUCK2
&& s5m8767
->buck2_gpiodvs
)
395 buck234_vol
= &s5m8767
->buck2_vol
[0];
396 else if (reg_id
== S5M8767_BUCK3
&& s5m8767
->buck3_gpiodvs
)
397 buck234_vol
= &s5m8767
->buck3_vol
[0];
398 else if (reg_id
== S5M8767_BUCK4
&& s5m8767
->buck4_gpiodvs
)
399 buck234_vol
= &s5m8767
->buck4_vol
[0];
401 case S5M8767_BUCK7
... S5M8767_BUCK8
:
410 desc
= reg_voltage_map
[reg_id
];
412 sel
= s5m8767_convert_voltage_to_sel(desc
, min_uV
, max_uV
);
416 /* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */
418 while (*buck234_vol
!= sel
) {
422 old_index
= s5m8767
->buck_gpioindex
;
423 s5m8767
->buck_gpioindex
= index
;
425 if (index
> old_index
)
426 s5m8767_set_high(s5m8767
);
428 s5m8767_set_low(s5m8767
);
430 ret
= s5m8767_get_voltage_register(rdev
, ®
);
434 s5m_reg_read(s5m8767
->iodev
, reg
, &val
);
435 val
= (val
& ~mask
) | sel
;
437 ret
= s5m_reg_write(s5m8767
->iodev
, reg
, val
);
444 static int s5m8767_set_voltage_time_sel(struct regulator_dev
*rdev
,
445 unsigned int old_sel
,
446 unsigned int new_sel
)
448 struct s5m8767_info
*s5m8767
= rdev_get_drvdata(rdev
);
449 const struct s5m_voltage_desc
*desc
;
450 int reg_id
= rdev_get_id(rdev
);
452 desc
= reg_voltage_map
[reg_id
];
454 if ((old_sel
< new_sel
) && s5m8767
->ramp_delay
)
455 return DIV_ROUND_UP(desc
->step
* (new_sel
- old_sel
),
456 s5m8767
->ramp_delay
* 1000);
460 static struct regulator_ops s5m8767_ops
= {
461 .list_voltage
= s5m8767_list_voltage
,
462 .is_enabled
= s5m8767_reg_is_enabled
,
463 .enable
= s5m8767_reg_enable
,
464 .disable
= s5m8767_reg_disable
,
465 .get_voltage_sel
= s5m8767_get_voltage_sel
,
466 .set_voltage
= s5m8767_set_voltage
,
467 .set_voltage_time_sel
= s5m8767_set_voltage_time_sel
,
470 #define s5m8767_regulator_desc(_name) { \
472 .id = S5M8767_##_name, \
473 .ops = &s5m8767_ops, \
474 .type = REGULATOR_VOLTAGE, \
475 .owner = THIS_MODULE, \
478 static struct regulator_desc regulators
[] = {
479 s5m8767_regulator_desc(LDO1
),
480 s5m8767_regulator_desc(LDO2
),
481 s5m8767_regulator_desc(LDO3
),
482 s5m8767_regulator_desc(LDO4
),
483 s5m8767_regulator_desc(LDO5
),
484 s5m8767_regulator_desc(LDO6
),
485 s5m8767_regulator_desc(LDO7
),
486 s5m8767_regulator_desc(LDO8
),
487 s5m8767_regulator_desc(LDO9
),
488 s5m8767_regulator_desc(LDO10
),
489 s5m8767_regulator_desc(LDO11
),
490 s5m8767_regulator_desc(LDO12
),
491 s5m8767_regulator_desc(LDO13
),
492 s5m8767_regulator_desc(LDO14
),
493 s5m8767_regulator_desc(LDO15
),
494 s5m8767_regulator_desc(LDO16
),
495 s5m8767_regulator_desc(LDO17
),
496 s5m8767_regulator_desc(LDO18
),
497 s5m8767_regulator_desc(LDO19
),
498 s5m8767_regulator_desc(LDO20
),
499 s5m8767_regulator_desc(LDO21
),
500 s5m8767_regulator_desc(LDO22
),
501 s5m8767_regulator_desc(LDO23
),
502 s5m8767_regulator_desc(LDO24
),
503 s5m8767_regulator_desc(LDO25
),
504 s5m8767_regulator_desc(LDO26
),
505 s5m8767_regulator_desc(LDO27
),
506 s5m8767_regulator_desc(LDO28
),
507 s5m8767_regulator_desc(BUCK1
),
508 s5m8767_regulator_desc(BUCK2
),
509 s5m8767_regulator_desc(BUCK3
),
510 s5m8767_regulator_desc(BUCK4
),
511 s5m8767_regulator_desc(BUCK5
),
512 s5m8767_regulator_desc(BUCK6
),
513 s5m8767_regulator_desc(BUCK7
),
514 s5m8767_regulator_desc(BUCK8
),
515 s5m8767_regulator_desc(BUCK9
),
518 static __devinit
int s5m8767_pmic_probe(struct platform_device
*pdev
)
520 struct s5m87xx_dev
*iodev
= dev_get_drvdata(pdev
->dev
.parent
);
521 struct s5m_platform_data
*pdata
= dev_get_platdata(iodev
->dev
);
522 struct regulator_config config
= { };
523 struct regulator_dev
**rdev
;
524 struct s5m8767_info
*s5m8767
;
528 dev_err(pdev
->dev
.parent
, "Platform data not supplied\n");
532 if (pdata
->buck2_gpiodvs
) {
533 if (pdata
->buck3_gpiodvs
|| pdata
->buck4_gpiodvs
) {
534 dev_err(&pdev
->dev
, "S5M8767 GPIO DVS NOT VALID\n");
539 if (pdata
->buck3_gpiodvs
) {
540 if (pdata
->buck2_gpiodvs
|| pdata
->buck4_gpiodvs
) {
541 dev_err(&pdev
->dev
, "S5M8767 GPIO DVS NOT VALID\n");
546 if (pdata
->buck4_gpiodvs
) {
547 if (pdata
->buck2_gpiodvs
|| pdata
->buck3_gpiodvs
) {
548 dev_err(&pdev
->dev
, "S5M8767 GPIO DVS NOT VALID\n");
553 s5m8767
= devm_kzalloc(&pdev
->dev
, sizeof(struct s5m8767_info
),
558 size
= sizeof(struct regulator_dev
*) * (S5M8767_REG_MAX
- 2);
559 s5m8767
->rdev
= devm_kzalloc(&pdev
->dev
, size
, GFP_KERNEL
);
563 rdev
= s5m8767
->rdev
;
564 s5m8767
->dev
= &pdev
->dev
;
565 s5m8767
->iodev
= iodev
;
566 s5m8767
->num_regulators
= S5M8767_REG_MAX
- 2;
567 platform_set_drvdata(pdev
, s5m8767
);
569 s5m8767
->buck_gpioindex
= pdata
->buck_default_idx
;
570 s5m8767
->buck2_gpiodvs
= pdata
->buck2_gpiodvs
;
571 s5m8767
->buck3_gpiodvs
= pdata
->buck3_gpiodvs
;
572 s5m8767
->buck4_gpiodvs
= pdata
->buck4_gpiodvs
;
573 s5m8767
->buck_gpios
[0] = pdata
->buck_gpios
[0];
574 s5m8767
->buck_gpios
[1] = pdata
->buck_gpios
[1];
575 s5m8767
->buck_gpios
[2] = pdata
->buck_gpios
[2];
576 s5m8767
->ramp_delay
= pdata
->buck_ramp_delay
;
577 s5m8767
->buck2_ramp
= pdata
->buck2_ramp_enable
;
578 s5m8767
->buck3_ramp
= pdata
->buck3_ramp_enable
;
579 s5m8767
->buck4_ramp
= pdata
->buck4_ramp_enable
;
580 s5m8767
->opmode
= pdata
->opmode
;
582 for (i
= 0; i
< 8; i
++) {
583 if (s5m8767
->buck2_gpiodvs
) {
584 s5m8767
->buck2_vol
[i
] =
585 s5m8767_convert_voltage_to_sel(
587 pdata
->buck2_voltage
[i
],
588 pdata
->buck2_voltage
[i
] +
589 buck_voltage_val2
.step
);
592 if (s5m8767
->buck3_gpiodvs
) {
593 s5m8767
->buck3_vol
[i
] =
594 s5m8767_convert_voltage_to_sel(
596 pdata
->buck3_voltage
[i
],
597 pdata
->buck3_voltage
[i
] +
598 buck_voltage_val2
.step
);
601 if (s5m8767
->buck4_gpiodvs
) {
602 s5m8767
->buck4_vol
[i
] =
603 s5m8767_convert_voltage_to_sel(
605 pdata
->buck4_voltage
[i
],
606 pdata
->buck4_voltage
[i
] +
607 buck_voltage_val2
.step
);
611 if (pdata
->buck2_gpiodvs
|| pdata
->buck3_gpiodvs
||
612 pdata
->buck4_gpiodvs
) {
613 if (gpio_is_valid(pdata
->buck_gpios
[0]) &&
614 gpio_is_valid(pdata
->buck_gpios
[1]) &&
615 gpio_is_valid(pdata
->buck_gpios
[2])) {
616 ret
= gpio_request(pdata
->buck_gpios
[0],
619 dev_warn(&pdev
->dev
, "Duplicated gpio request for SET1\n");
621 ret
= gpio_request(pdata
->buck_gpios
[1],
624 dev_warn(&pdev
->dev
, "Duplicated gpio request for SET2\n");
626 ret
= gpio_request(pdata
->buck_gpios
[2],
629 dev_warn(&pdev
->dev
, "Duplicated gpio request for SET3\n");
631 gpio_direction_output(pdata
->buck_gpios
[0],
632 (s5m8767
->buck_gpioindex
>> 2) & 0x1);
634 gpio_direction_output(pdata
->buck_gpios
[1],
635 (s5m8767
->buck_gpioindex
>> 1) & 0x1);
637 gpio_direction_output(pdata
->buck_gpios
[2],
638 (s5m8767
->buck_gpioindex
>> 0) & 0x1);
641 dev_err(&pdev
->dev
, "GPIO NOT VALID\n");
647 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_BUCK2CTRL
,
648 (pdata
->buck2_gpiodvs
) ? (1 << 1) : (0 << 1), 1 << 1);
649 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_BUCK3CTRL
,
650 (pdata
->buck3_gpiodvs
) ? (1 << 1) : (0 << 1), 1 << 1);
651 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_BUCK4CTRL
,
652 (pdata
->buck4_gpiodvs
) ? (1 << 1) : (0 << 1), 1 << 1);
654 /* Initialize GPIO DVS registers */
655 for (i
= 0; i
< 8; i
++) {
656 if (s5m8767
->buck2_gpiodvs
) {
657 s5m_reg_write(s5m8767
->iodev
, S5M8767_REG_BUCK2DVS1
+ i
,
658 s5m8767
->buck2_vol
[i
]);
661 if (s5m8767
->buck3_gpiodvs
) {
662 s5m_reg_write(s5m8767
->iodev
, S5M8767_REG_BUCK3DVS1
+ i
,
663 s5m8767
->buck3_vol
[i
]);
666 if (s5m8767
->buck4_gpiodvs
) {
667 s5m_reg_write(s5m8767
->iodev
, S5M8767_REG_BUCK4DVS1
+ i
,
668 s5m8767
->buck4_vol
[i
]);
671 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_BUCK2CTRL
, 0x78, 0xff);
672 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_BUCK3CTRL
, 0x58, 0xff);
673 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_BUCK4CTRL
, 0x78, 0xff);
675 if (s5m8767
->buck2_ramp
)
676 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_DVSRAMP
, 0x08, 0x08);
678 if (s5m8767
->buck3_ramp
)
679 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_DVSRAMP
, 0x04, 0x04);
681 if (s5m8767
->buck4_ramp
)
682 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_DVSRAMP
, 0x02, 0x02);
684 if (s5m8767
->buck2_ramp
|| s5m8767
->buck3_ramp
685 || s5m8767
->buck4_ramp
) {
686 switch (s5m8767
->ramp_delay
) {
688 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_DVSRAMP
,
692 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_DVSRAMP
,
696 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_DVSRAMP
,
700 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_DVSRAMP
,
704 s5m_reg_update(s5m8767
->iodev
, S5M8767_REG_DVSRAMP
,
709 for (i
= 0; i
< pdata
->num_regulators
; i
++) {
710 const struct s5m_voltage_desc
*desc
;
711 int id
= pdata
->regulators
[i
].id
;
713 desc
= reg_voltage_map
[id
];
715 regulators
[id
].n_voltages
=
716 (desc
->max
- desc
->min
) / desc
->step
+ 1;
718 config
.dev
= s5m8767
->dev
;
719 config
.init_data
= pdata
->regulators
[i
].initdata
;
720 config
.driver_data
= s5m8767
;
722 rdev
[i
] = regulator_register(®ulators
[id
], &config
);
723 if (IS_ERR(rdev
[i
])) {
724 ret
= PTR_ERR(rdev
[i
]);
725 dev_err(s5m8767
->dev
, "regulator init failed for %d\n",
734 for (i
= 0; i
< s5m8767
->num_regulators
; i
++)
736 regulator_unregister(rdev
[i
]);
741 static int __devexit
s5m8767_pmic_remove(struct platform_device
*pdev
)
743 struct s5m8767_info
*s5m8767
= platform_get_drvdata(pdev
);
744 struct regulator_dev
**rdev
= s5m8767
->rdev
;
747 for (i
= 0; i
< s5m8767
->num_regulators
; i
++)
749 regulator_unregister(rdev
[i
]);
754 static const struct platform_device_id s5m8767_pmic_id
[] = {
755 { "s5m8767-pmic", 0},
758 MODULE_DEVICE_TABLE(platform
, s5m8767_pmic_id
);
760 static struct platform_driver s5m8767_pmic_driver
= {
762 .name
= "s5m8767-pmic",
763 .owner
= THIS_MODULE
,
765 .probe
= s5m8767_pmic_probe
,
766 .remove
= __devexit_p(s5m8767_pmic_remove
),
767 .id_table
= s5m8767_pmic_id
,
770 static int __init
s5m8767_pmic_init(void)
772 return platform_driver_register(&s5m8767_pmic_driver
);
774 subsys_initcall(s5m8767_pmic_init
);
776 static void __exit
s5m8767_pmic_exit(void)
778 platform_driver_unregister(&s5m8767_pmic_driver
);
780 module_exit(s5m8767_pmic_exit
);
782 /* Module information */
783 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
784 MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver");
785 MODULE_LICENSE("GPL");