aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/s5m8767.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/s5m8767.c')
-rw-r--r--drivers/regulator/s5m8767.c175
1 files changed, 106 insertions, 69 deletions
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
index d7164bb75d3e..f05badabd69e 100644
--- a/drivers/regulator/s5m8767.c
+++ b/drivers/regulator/s5m8767.c
@@ -11,11 +11,8 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/bug.h>
15#include <linux/err.h> 14#include <linux/err.h>
16#include <linux/gpio.h>
17#include <linux/of_gpio.h> 15#include <linux/of_gpio.h>
18#include <linux/slab.h>
19#include <linux/module.h> 16#include <linux/module.h>
20#include <linux/platform_device.h> 17#include <linux/platform_device.h>
21#include <linux/regulator/driver.h> 18#include <linux/regulator/driver.h>
@@ -170,12 +167,11 @@ static unsigned int s5m8767_opmode_reg[][4] = {
170 {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */ 167 {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
171}; 168};
172 169
173static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, 170static int s5m8767_get_register(struct s5m8767_info *s5m8767, int reg_id,
174 int *enable_ctrl) 171 int *reg, int *enable_ctrl)
175{ 172{
176 int i, reg_id = rdev_get_id(rdev); 173 int i;
177 unsigned int mode; 174 unsigned int mode;
178 struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
179 175
180 switch (reg_id) { 176 switch (reg_id) {
181 case S5M8767_LDO1 ... S5M8767_LDO2: 177 case S5M8767_LDO1 ... S5M8767_LDO2:
@@ -214,53 +210,6 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
214 return 0; 210 return 0;
215} 211}
216 212
217static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
218{
219 struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
220 int ret, reg;
221 int enable_ctrl;
222 unsigned int val;
223
224 ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
225 if (ret == -EINVAL)
226 return 1;
227 else if (ret)
228 return ret;
229
230 ret = regmap_read(s5m8767->iodev->regmap_pmic, reg, &val);
231 if (ret)
232 return ret;
233
234 return (val & S5M8767_ENCTRL_MASK) == enable_ctrl;
235}
236
237static int s5m8767_reg_enable(struct regulator_dev *rdev)
238{
239 struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
240 int ret, reg;
241 int enable_ctrl;
242
243 ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
244 if (ret)
245 return ret;
246
247 return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg,
248 S5M8767_ENCTRL_MASK, enable_ctrl);
249}
250
251static int s5m8767_reg_disable(struct regulator_dev *rdev)
252{
253 struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
254 int ret, reg, enable_ctrl;
255
256 ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
257 if (ret)
258 return ret;
259
260 return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg,
261 S5M8767_ENCTRL_MASK, ~S5M8767_ENCTRL_MASK);
262}
263
264static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767) 213static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767)
265{ 214{
266 int reg; 215 int reg;
@@ -410,9 +359,9 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
410 359
411static struct regulator_ops s5m8767_ops = { 360static struct regulator_ops s5m8767_ops = {
412 .list_voltage = regulator_list_voltage_linear, 361 .list_voltage = regulator_list_voltage_linear,
413 .is_enabled = s5m8767_reg_is_enabled, 362 .is_enabled = regulator_is_enabled_regmap,
414 .enable = s5m8767_reg_enable, 363 .enable = regulator_enable_regmap,
415 .disable = s5m8767_reg_disable, 364 .disable = regulator_disable_regmap,
416 .get_voltage_sel = regulator_get_voltage_sel_regmap, 365 .get_voltage_sel = regulator_get_voltage_sel_regmap,
417 .set_voltage_sel = s5m8767_set_voltage_sel, 366 .set_voltage_sel = s5m8767_set_voltage_sel,
418 .set_voltage_time_sel = s5m8767_set_voltage_time_sel, 367 .set_voltage_time_sel = s5m8767_set_voltage_time_sel,
@@ -420,9 +369,9 @@ static struct regulator_ops s5m8767_ops = {
420 369
421static struct regulator_ops s5m8767_buck78_ops = { 370static struct regulator_ops s5m8767_buck78_ops = {
422 .list_voltage = regulator_list_voltage_linear, 371 .list_voltage = regulator_list_voltage_linear,
423 .is_enabled = s5m8767_reg_is_enabled, 372 .is_enabled = regulator_is_enabled_regmap,
424 .enable = s5m8767_reg_enable, 373 .enable = regulator_enable_regmap,
425 .disable = s5m8767_reg_disable, 374 .disable = regulator_disable_regmap,
426 .get_voltage_sel = regulator_get_voltage_sel_regmap, 375 .get_voltage_sel = regulator_get_voltage_sel_regmap,
427 .set_voltage_sel = regulator_set_voltage_sel_regmap, 376 .set_voltage_sel = regulator_set_voltage_sel_regmap,
428}; 377};
@@ -483,6 +432,66 @@ static struct regulator_desc regulators[] = {
483 s5m8767_regulator_desc(BUCK9), 432 s5m8767_regulator_desc(BUCK9),
484}; 433};
485 434
435/*
436 * Enable GPIO control over BUCK9 in regulator_config for that regulator.
437 */
438static void s5m8767_regulator_config_ext_control(struct s5m8767_info *s5m8767,
439 struct sec_regulator_data *rdata,
440 struct regulator_config *config)
441{
442 int i, mode = 0;
443
444 if (rdata->id != S5M8767_BUCK9)
445 return;
446
447 /* Check if opmode for regulator matches S5M8767_ENCTRL_USE_GPIO */
448 for (i = 0; i < s5m8767->num_regulators; i++) {
449 const struct sec_opmode_data *opmode = &s5m8767->opmode[i];
450 if (opmode->id == rdata->id) {
451 mode = s5m8767_opmode_reg[rdata->id][opmode->mode];
452 break;
453 }
454 }
455 if (mode != S5M8767_ENCTRL_USE_GPIO) {
456 dev_warn(s5m8767->dev,
457 "ext-control for %s: mismatched op_mode (%x), ignoring\n",
458 rdata->reg_node->name, mode);
459 return;
460 }
461
462 if (!gpio_is_valid(rdata->ext_control_gpio)) {
463 dev_warn(s5m8767->dev,
464 "ext-control for %s: GPIO not valid, ignoring\n",
465 rdata->reg_node->name);
466 return;
467 }
468
469 config->ena_gpio = rdata->ext_control_gpio;
470 config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH;
471}
472
473/*
474 * Turn on GPIO control over BUCK9.
475 */
476static int s5m8767_enable_ext_control(struct s5m8767_info *s5m8767,
477 struct regulator_dev *rdev)
478{
479 int id = rdev_get_id(rdev);
480 int ret, reg, enable_ctrl;
481
482 if (id != S5M8767_BUCK9)
483 return -EINVAL;
484
485 ret = s5m8767_get_register(s5m8767, id, &reg, &enable_ctrl);
486 if (ret)
487 return ret;
488
489 return regmap_update_bits(s5m8767->iodev->regmap_pmic,
490 reg, S5M8767_ENCTRL_MASK,
491 S5M8767_ENCTRL_USE_GPIO << S5M8767_ENCTRL_SHIFT);
492}
493
494
486#ifdef CONFIG_OF 495#ifdef CONFIG_OF
487static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev, 496static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev,
488 struct sec_platform_data *pdata, 497 struct sec_platform_data *pdata,
@@ -520,6 +529,16 @@ static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev,
520 return 0; 529 return 0;
521} 530}
522 531
532static void s5m8767_pmic_dt_parse_ext_control_gpio(struct sec_pmic_dev *iodev,
533 struct sec_regulator_data *rdata,
534 struct device_node *reg_np)
535{
536 rdata->ext_control_gpio = of_get_named_gpio(reg_np,
537 "s5m8767,pmic-ext-control-gpios", 0);
538 if (!gpio_is_valid(rdata->ext_control_gpio))
539 rdata->ext_control_gpio = 0;
540}
541
523static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, 542static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
524 struct sec_platform_data *pdata) 543 struct sec_platform_data *pdata)
525{ 544{
@@ -535,7 +554,7 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
535 return -ENODEV; 554 return -ENODEV;
536 } 555 }
537 556
538 regulators_np = of_find_node_by_name(pmic_np, "regulators"); 557 regulators_np = of_get_child_by_name(pmic_np, "regulators");
539 if (!regulators_np) { 558 if (!regulators_np) {
540 dev_err(iodev->dev, "could not find regulators sub-node\n"); 559 dev_err(iodev->dev, "could not find regulators sub-node\n");
541 return -EINVAL; 560 return -EINVAL;
@@ -546,19 +565,13 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
546 565
547 rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * 566 rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
548 pdata->num_regulators, GFP_KERNEL); 567 pdata->num_regulators, GFP_KERNEL);
549 if (!rdata) { 568 if (!rdata)
550 dev_err(iodev->dev,
551 "could not allocate memory for regulator data\n");
552 return -ENOMEM; 569 return -ENOMEM;
553 }
554 570
555 rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) * 571 rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) *
556 pdata->num_regulators, GFP_KERNEL); 572 pdata->num_regulators, GFP_KERNEL);
557 if (!rmode) { 573 if (!rmode)
558 dev_err(iodev->dev,
559 "could not allocate memory for regulator mode\n");
560 return -ENOMEM; 574 return -ENOMEM;
561 }
562 575
563 pdata->regulators = rdata; 576 pdata->regulators = rdata;
564 pdata->opmode = rmode; 577 pdata->opmode = rmode;
@@ -574,6 +587,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
574 continue; 587 continue;
575 } 588 }
576 589
590 s5m8767_pmic_dt_parse_ext_control_gpio(iodev, rdata, reg_np);
591
577 rdata->id = i; 592 rdata->id = i;
578 rdata->initdata = of_get_regulator_init_data( 593 rdata->initdata = of_get_regulator_init_data(
579 &pdev->dev, reg_np); 594 &pdev->dev, reg_np);
@@ -591,6 +606,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
591 rmode++; 606 rmode++;
592 } 607 }
593 608
609 of_node_put(regulators_np);
610
594 if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) { 611 if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) {
595 pdata->buck2_gpiodvs = true; 612 pdata->buck2_gpiodvs = true;
596 613
@@ -920,6 +937,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
920 for (i = 0; i < pdata->num_regulators; i++) { 937 for (i = 0; i < pdata->num_regulators; i++) {
921 const struct sec_voltage_desc *desc; 938 const struct sec_voltage_desc *desc;
922 int id = pdata->regulators[i].id; 939 int id = pdata->regulators[i].id;
940 int enable_reg, enable_val;
923 941
924 desc = reg_voltage_map[id]; 942 desc = reg_voltage_map[id];
925 if (desc) { 943 if (desc) {
@@ -933,6 +951,12 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
933 regulators[id].vsel_mask = 0x3f; 951 regulators[id].vsel_mask = 0x3f;
934 else 952 else
935 regulators[id].vsel_mask = 0xff; 953 regulators[id].vsel_mask = 0xff;
954
955 s5m8767_get_register(s5m8767, id, &enable_reg,
956 &enable_val);
957 regulators[id].enable_reg = enable_reg;
958 regulators[id].enable_mask = S5M8767_ENCTRL_MASK;
959 regulators[id].enable_val = enable_val;
936 } 960 }
937 961
938 config.dev = s5m8767->dev; 962 config.dev = s5m8767->dev;
@@ -940,6 +964,9 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
940 config.driver_data = s5m8767; 964 config.driver_data = s5m8767;
941 config.regmap = iodev->regmap_pmic; 965 config.regmap = iodev->regmap_pmic;
942 config.of_node = pdata->regulators[i].reg_node; 966 config.of_node = pdata->regulators[i].reg_node;
967 if (pdata->regulators[i].ext_control_gpio)
968 s5m8767_regulator_config_ext_control(s5m8767,
969 &pdata->regulators[i], &config);
943 970
944 rdev[i] = devm_regulator_register(&pdev->dev, &regulators[id], 971 rdev[i] = devm_regulator_register(&pdev->dev, &regulators[id],
945 &config); 972 &config);
@@ -949,6 +976,16 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
949 id); 976 id);
950 return ret; 977 return ret;
951 } 978 }
979
980 if (pdata->regulators[i].ext_control_gpio) {
981 ret = s5m8767_enable_ext_control(s5m8767, rdev[i]);
982 if (ret < 0) {
983 dev_err(s5m8767->dev,
984 "failed to enable gpio control over %s: %d\n",
985 rdev[i]->desc->name, ret);
986 return ret;
987 }
988 }
952 } 989 }
953 990
954 return 0; 991 return 0;