Commit 24ee65e4a50fcefa2a7197f45a330ee96ec84a4b
9 parents
7b836485d4
9c4c60554a
d8eb6fa7a9
8bad62cca3
ef4bcf88ea
33e63ba6c6
fe23ce0813
0ad91c69ab
94ee607c96
Exists in
master
and in
13 other branches
Merge remote-tracking branches 'regulator/topic/s5m8767', 'regulator/topic/st-pw…
…m', 'regulator/topic/ti-abb', 'regulator/topic/tps51632', 'regulator/topic/tps62360', 'regulator/topic/tps6507x', 'regulator/topic/tps65090' and 'regulator/topic/tps65217' into regulator-next
Showing 14 changed files Side-by-side Diff
- Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt
- Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt
- drivers/regulator/Kconfig
- drivers/regulator/Makefile
- drivers/regulator/s5m8767.c
- drivers/regulator/st-pwm.c
- drivers/regulator/ti-abb-regulator.c
- drivers/regulator/tps51632-regulator.c
- drivers/regulator/tps62360-regulator.c
- drivers/regulator/tps6507x-regulator.c
- drivers/regulator/tps65090-regulator.c
- drivers/regulator/tps65217-regulator.c
- include/linux/mfd/samsung/core.h
- include/linux/mfd/samsung/s5m8767.h
Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt
... | ... | @@ -69,13 +69,16 @@ |
69 | 69 | }; |
70 | 70 | }; |
71 | 71 | The above regulator entries are defined in regulator bindings documentation |
72 | -except op_mode description. | |
72 | +except these properties: | |
73 | 73 | - op_mode: describes the different operating modes of the LDO's with |
74 | 74 | power mode change in SOC. The different possible values are, |
75 | 75 | 0 - always off mode |
76 | 76 | 1 - on in normal mode |
77 | 77 | 2 - low power mode |
78 | 78 | 3 - suspend mode |
79 | + - s5m8767,pmic-ext-control-gpios: (optional) GPIO specifier for one | |
80 | + GPIO controlling this regulator (enable/disable); This is | |
81 | + valid only for buck9. | |
79 | 82 | |
80 | 83 | The following are the names of the regulators that the s5m8767 pmic block |
81 | 84 | supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number |
... | ... | @@ -147,6 +150,14 @@ |
147 | 150 | regulator-max-microvolt = <1350000>; |
148 | 151 | regulator-always-on; |
149 | 152 | regulator-boot-on; |
153 | + }; | |
154 | + | |
155 | + vemmc_reg: BUCK9 { | |
156 | + regulator-name = "VMEM_VDD_2.8V"; | |
157 | + regulator-min-microvolt = <2800000>; | |
158 | + regulator-max-microvolt = <2800000>; | |
159 | + op_mode = <3>; /* Standby Mode */ | |
160 | + s5m8767,pmic-ext-control-gpios = <&gpk0 2 0>; | |
150 | 161 | }; |
151 | 162 | }; |
152 | 163 | }; |
Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt
... | ... | @@ -4,10 +4,14 @@ |
4 | 4 | - compatible: Should be one of: |
5 | 5 | - "ti,abb-v1" for older SoCs like OMAP3 |
6 | 6 | - "ti,abb-v2" for newer SoCs like OMAP4, OMAP5 |
7 | + - "ti,abb-v3" for a generic definition where setup and control registers are | |
8 | + provided (example: DRA7) | |
7 | 9 | - reg: Address and length of the register set for the device. It contains |
8 | 10 | the information of registers in the same order as described by reg-names |
9 | 11 | - reg-names: Should contain the reg names |
10 | - - "base-address" - contains base address of ABB module | |
12 | + - "base-address" - contains base address of ABB module (ti,abb-v1,ti,abb-v2) | |
13 | + - "control-address" - contains control register address of ABB module (ti,abb-v3) | |
14 | + - "setup-address" - contains setup register address of ABB module (ti,abb-v3) | |
11 | 15 | - "int-address" - contains address of interrupt register for ABB module |
12 | 16 | (also see Optional properties) |
13 | 17 | - #address-cell: should be 0 |
drivers/regulator/Kconfig
... | ... | @@ -448,6 +448,12 @@ |
448 | 448 | via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and |
449 | 449 | supports DVS mode with 8bits of output voltage control. |
450 | 450 | |
451 | +config REGULATOR_ST_PWM | |
452 | + tristate "STMicroelectronics PWM voltage regulator" | |
453 | + depends on ARCH_STI | |
454 | + help | |
455 | + This driver supports ST's PWM controlled voltage regulators. | |
456 | + | |
451 | 457 | config REGULATOR_TI_ABB |
452 | 458 | tristate "TI Adaptive Body Bias on-chip LDO" |
453 | 459 | depends on ARCH_OMAP |
drivers/regulator/Makefile
... | ... | @@ -61,6 +61,7 @@ |
61 | 61 | obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o |
62 | 62 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o |
63 | 63 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o |
64 | +obj-$(CONFIG_REGULATOR_ST_PWM) += st-pwm.o | |
64 | 65 | obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o |
65 | 66 | obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o |
66 | 67 | obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o |
drivers/regulator/s5m8767.c
... | ... | @@ -11,11 +11,8 @@ |
11 | 11 | * |
12 | 12 | */ |
13 | 13 | |
14 | -#include <linux/bug.h> | |
15 | 14 | #include <linux/err.h> |
16 | -#include <linux/gpio.h> | |
17 | 15 | #include <linux/of_gpio.h> |
18 | -#include <linux/slab.h> | |
19 | 16 | #include <linux/module.h> |
20 | 17 | #include <linux/platform_device.h> |
21 | 18 | #include <linux/regulator/driver.h> |
22 | 19 | |
23 | 20 | |
... | ... | @@ -170,12 +167,11 @@ |
170 | 167 | {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */ |
171 | 168 | }; |
172 | 169 | |
173 | -static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, | |
174 | - int *enable_ctrl) | |
170 | +static int s5m8767_get_register(struct s5m8767_info *s5m8767, int reg_id, | |
171 | + int *reg, int *enable_ctrl) | |
175 | 172 | { |
176 | - int i, reg_id = rdev_get_id(rdev); | |
173 | + int i; | |
177 | 174 | unsigned int mode; |
178 | - struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | |
179 | 175 | |
180 | 176 | switch (reg_id) { |
181 | 177 | case S5M8767_LDO1 ... S5M8767_LDO2: |
... | ... | @@ -214,53 +210,6 @@ |
214 | 210 | return 0; |
215 | 211 | } |
216 | 212 | |
217 | -static 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, ®, &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 | - | |
237 | -static 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, ®, &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 | - | |
251 | -static 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, ®, &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 | - | |
264 | 213 | static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767) |
265 | 214 | { |
266 | 215 | int reg; |
... | ... | @@ -410,9 +359,9 @@ |
410 | 359 | |
411 | 360 | static struct regulator_ops s5m8767_ops = { |
412 | 361 | .list_voltage = regulator_list_voltage_linear, |
413 | - .is_enabled = s5m8767_reg_is_enabled, | |
414 | - .enable = s5m8767_reg_enable, | |
415 | - .disable = s5m8767_reg_disable, | |
362 | + .is_enabled = regulator_is_enabled_regmap, | |
363 | + .enable = regulator_enable_regmap, | |
364 | + .disable = regulator_disable_regmap, | |
416 | 365 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
417 | 366 | .set_voltage_sel = s5m8767_set_voltage_sel, |
418 | 367 | .set_voltage_time_sel = s5m8767_set_voltage_time_sel, |
... | ... | @@ -420,9 +369,9 @@ |
420 | 369 | |
421 | 370 | static struct regulator_ops s5m8767_buck78_ops = { |
422 | 371 | .list_voltage = regulator_list_voltage_linear, |
423 | - .is_enabled = s5m8767_reg_is_enabled, | |
424 | - .enable = s5m8767_reg_enable, | |
425 | - .disable = s5m8767_reg_disable, | |
372 | + .is_enabled = regulator_is_enabled_regmap, | |
373 | + .enable = regulator_enable_regmap, | |
374 | + .disable = regulator_disable_regmap, | |
426 | 375 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
427 | 376 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
428 | 377 | }; |
... | ... | @@ -483,6 +432,66 @@ |
483 | 432 | s5m8767_regulator_desc(BUCK9), |
484 | 433 | }; |
485 | 434 | |
435 | +/* | |
436 | + * Enable GPIO control over BUCK9 in regulator_config for that regulator. | |
437 | + */ | |
438 | +static 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 | + */ | |
476 | +static 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, ®, &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 | 495 | #ifdef CONFIG_OF |
487 | 496 | static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev, |
488 | 497 | struct sec_platform_data *pdata, |
... | ... | @@ -520,6 +529,16 @@ |
520 | 529 | return 0; |
521 | 530 | } |
522 | 531 | |
532 | +static 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 | + | |
523 | 542 | static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, |
524 | 543 | struct sec_platform_data *pdata) |
525 | 544 | { |
526 | 545 | |
527 | 546 | |
528 | 547 | |
... | ... | @@ -546,19 +565,13 @@ |
546 | 565 | |
547 | 566 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * |
548 | 567 | pdata->num_regulators, GFP_KERNEL); |
549 | - if (!rdata) { | |
550 | - dev_err(iodev->dev, | |
551 | - "could not allocate memory for regulator data\n"); | |
568 | + if (!rdata) | |
552 | 569 | return -ENOMEM; |
553 | - } | |
554 | 570 | |
555 | 571 | rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) * |
556 | 572 | pdata->num_regulators, GFP_KERNEL); |
557 | - if (!rmode) { | |
558 | - dev_err(iodev->dev, | |
559 | - "could not allocate memory for regulator mode\n"); | |
573 | + if (!rmode) | |
560 | 574 | return -ENOMEM; |
561 | - } | |
562 | 575 | |
563 | 576 | pdata->regulators = rdata; |
564 | 577 | pdata->opmode = rmode; |
... | ... | @@ -574,6 +587,8 @@ |
574 | 587 | continue; |
575 | 588 | } |
576 | 589 | |
590 | + s5m8767_pmic_dt_parse_ext_control_gpio(iodev, rdata, reg_np); | |
591 | + | |
577 | 592 | rdata->id = i; |
578 | 593 | rdata->initdata = of_get_regulator_init_data( |
579 | 594 | &pdev->dev, reg_np); |
... | ... | @@ -922,6 +937,7 @@ |
922 | 937 | for (i = 0; i < pdata->num_regulators; i++) { |
923 | 938 | const struct sec_voltage_desc *desc; |
924 | 939 | int id = pdata->regulators[i].id; |
940 | + int enable_reg, enable_val; | |
925 | 941 | |
926 | 942 | desc = reg_voltage_map[id]; |
927 | 943 | if (desc) { |
... | ... | @@ -935,6 +951,12 @@ |
935 | 951 | regulators[id].vsel_mask = 0x3f; |
936 | 952 | else |
937 | 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; | |
938 | 960 | } |
939 | 961 | |
940 | 962 | config.dev = s5m8767->dev; |
... | ... | @@ -942,6 +964,9 @@ |
942 | 964 | config.driver_data = s5m8767; |
943 | 965 | config.regmap = iodev->regmap_pmic; |
944 | 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); | |
945 | 970 | |
946 | 971 | rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], |
947 | 972 | &config); |
... | ... | @@ -950,6 +975,16 @@ |
950 | 975 | dev_err(s5m8767->dev, "regulator init failed for %d\n", |
951 | 976 | id); |
952 | 977 | return ret; |
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 | + } | |
953 | 988 | } |
954 | 989 | } |
955 | 990 |
drivers/regulator/st-pwm.c
1 | +/* | |
2 | + * Regulator driver for ST's PWM Regulators | |
3 | + * | |
4 | + * Copyright (C) 2014 - STMicroelectronics Inc. | |
5 | + * | |
6 | + * Author: Lee Jones <lee.jones@linaro.org> | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/module.h> | |
14 | +#include <linux/init.h> | |
15 | +#include <linux/err.h> | |
16 | +#include <linux/regulator/driver.h> | |
17 | +#include <linux/regulator/machine.h> | |
18 | +#include <linux/regulator/of_regulator.h> | |
19 | +#include <linux/of.h> | |
20 | +#include <linux/of_device.h> | |
21 | +#include <linux/pwm.h> | |
22 | + | |
23 | +#define ST_PWM_REG_PERIOD 8448 | |
24 | + | |
25 | +struct st_pwm_regulator_pdata { | |
26 | + const struct regulator_desc *desc; | |
27 | + struct st_pwm_voltages *duty_cycle_table; | |
28 | +}; | |
29 | + | |
30 | +struct st_pwm_regulator_data { | |
31 | + const struct st_pwm_regulator_pdata *pdata; | |
32 | + struct pwm_device *pwm; | |
33 | + bool enabled; | |
34 | + int state; | |
35 | +}; | |
36 | + | |
37 | +struct st_pwm_voltages { | |
38 | + unsigned int uV; | |
39 | + unsigned int dutycycle; | |
40 | +}; | |
41 | + | |
42 | +static int st_pwm_regulator_get_voltage_sel(struct regulator_dev *dev) | |
43 | +{ | |
44 | + struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | |
45 | + | |
46 | + return drvdata->state; | |
47 | +} | |
48 | + | |
49 | +static int st_pwm_regulator_set_voltage_sel(struct regulator_dev *dev, | |
50 | + unsigned selector) | |
51 | +{ | |
52 | + struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | |
53 | + int dutycycle; | |
54 | + int ret; | |
55 | + | |
56 | + dutycycle = (ST_PWM_REG_PERIOD / 100) * | |
57 | + drvdata->pdata->duty_cycle_table[selector].dutycycle; | |
58 | + | |
59 | + ret = pwm_config(drvdata->pwm, dutycycle, ST_PWM_REG_PERIOD); | |
60 | + if (ret) { | |
61 | + dev_err(&dev->dev, "Failed to configure PWM\n"); | |
62 | + return ret; | |
63 | + } | |
64 | + | |
65 | + drvdata->state = selector; | |
66 | + | |
67 | + if (!drvdata->enabled) { | |
68 | + ret = pwm_enable(drvdata->pwm); | |
69 | + if (ret) { | |
70 | + dev_err(&dev->dev, "Failed to enable PWM\n"); | |
71 | + return ret; | |
72 | + } | |
73 | + drvdata->enabled = true; | |
74 | + } | |
75 | + | |
76 | + return 0; | |
77 | +} | |
78 | + | |
79 | +static int st_pwm_regulator_list_voltage(struct regulator_dev *dev, | |
80 | + unsigned selector) | |
81 | +{ | |
82 | + struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | |
83 | + | |
84 | + if (selector >= dev->desc->n_voltages) | |
85 | + return -EINVAL; | |
86 | + | |
87 | + return drvdata->pdata->duty_cycle_table[selector].uV; | |
88 | +} | |
89 | + | |
90 | +static struct regulator_ops st_pwm_regulator_voltage_ops = { | |
91 | + .set_voltage_sel = st_pwm_regulator_set_voltage_sel, | |
92 | + .get_voltage_sel = st_pwm_regulator_get_voltage_sel, | |
93 | + .list_voltage = st_pwm_regulator_list_voltage, | |
94 | + .map_voltage = regulator_map_voltage_iterate, | |
95 | +}; | |
96 | + | |
97 | +static struct st_pwm_voltages b2105_duty_cycle_table[] = { | |
98 | + { .uV = 1114000, .dutycycle = 0, }, | |
99 | + { .uV = 1095000, .dutycycle = 10, }, | |
100 | + { .uV = 1076000, .dutycycle = 20, }, | |
101 | + { .uV = 1056000, .dutycycle = 30, }, | |
102 | + { .uV = 1036000, .dutycycle = 40, }, | |
103 | + { .uV = 1016000, .dutycycle = 50, }, | |
104 | + /* WARNING: Values above 50% duty-cycle cause boot failures. */ | |
105 | +}; | |
106 | + | |
107 | +static const struct regulator_desc b2105_desc = { | |
108 | + .name = "b2105-pwm-regulator", | |
109 | + .ops = &st_pwm_regulator_voltage_ops, | |
110 | + .type = REGULATOR_VOLTAGE, | |
111 | + .owner = THIS_MODULE, | |
112 | + .n_voltages = ARRAY_SIZE(b2105_duty_cycle_table), | |
113 | + .supply_name = "pwm", | |
114 | +}; | |
115 | + | |
116 | +static const struct st_pwm_regulator_pdata b2105_info = { | |
117 | + .desc = &b2105_desc, | |
118 | + .duty_cycle_table = b2105_duty_cycle_table, | |
119 | +}; | |
120 | + | |
121 | +static struct of_device_id st_pwm_of_match[] = { | |
122 | + { .compatible = "st,b2105-pwm-regulator", .data = &b2105_info, }, | |
123 | + { }, | |
124 | +}; | |
125 | +MODULE_DEVICE_TABLE(of, st_pwm_of_match); | |
126 | + | |
127 | +static int st_pwm_regulator_probe(struct platform_device *pdev) | |
128 | +{ | |
129 | + struct st_pwm_regulator_data *drvdata; | |
130 | + struct regulator_dev *regulator; | |
131 | + struct regulator_config config = { }; | |
132 | + struct device_node *np = pdev->dev.of_node; | |
133 | + const struct of_device_id *of_match; | |
134 | + | |
135 | + if (!np) { | |
136 | + dev_err(&pdev->dev, "Device Tree node missing\n"); | |
137 | + return -EINVAL; | |
138 | + } | |
139 | + | |
140 | + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); | |
141 | + if (!drvdata) | |
142 | + return -ENOMEM; | |
143 | + | |
144 | + of_match = of_match_device(st_pwm_of_match, &pdev->dev); | |
145 | + if (!of_match) { | |
146 | + dev_err(&pdev->dev, "failed to match of device\n"); | |
147 | + return -ENODEV; | |
148 | + } | |
149 | + drvdata->pdata = of_match->data; | |
150 | + | |
151 | + config.init_data = of_get_regulator_init_data(&pdev->dev, np); | |
152 | + if (!config.init_data) | |
153 | + return -ENOMEM; | |
154 | + | |
155 | + config.of_node = np; | |
156 | + config.dev = &pdev->dev; | |
157 | + config.driver_data = drvdata; | |
158 | + | |
159 | + drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); | |
160 | + if (IS_ERR(drvdata->pwm)) { | |
161 | + dev_err(&pdev->dev, "Failed to get PWM\n"); | |
162 | + return PTR_ERR(drvdata->pwm); | |
163 | + } | |
164 | + | |
165 | + regulator = devm_regulator_register(&pdev->dev, | |
166 | + drvdata->pdata->desc, &config); | |
167 | + if (IS_ERR(regulator)) { | |
168 | + dev_err(&pdev->dev, "Failed to register regulator %s\n", | |
169 | + drvdata->pdata->desc->name); | |
170 | + return PTR_ERR(regulator); | |
171 | + } | |
172 | + | |
173 | + return 0; | |
174 | +} | |
175 | + | |
176 | +static struct platform_driver st_pwm_regulator_driver = { | |
177 | + .driver = { | |
178 | + .name = "st-pwm-regulator", | |
179 | + .owner = THIS_MODULE, | |
180 | + .of_match_table = of_match_ptr(st_pwm_of_match), | |
181 | + }, | |
182 | + .probe = st_pwm_regulator_probe, | |
183 | +}; | |
184 | + | |
185 | +module_platform_driver(st_pwm_regulator_driver); | |
186 | + | |
187 | +MODULE_LICENSE("GPL"); | |
188 | +MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>"); | |
189 | +MODULE_DESCRIPTION("ST PWM Regulator Driver"); | |
190 | +MODULE_ALIAS("platform:st_pwm-regulator"); |
drivers/regulator/ti-abb-regulator.c
... | ... | @@ -54,8 +54,8 @@ |
54 | 54 | |
55 | 55 | /** |
56 | 56 | * struct ti_abb_reg - Register description for ABB block |
57 | - * @setup_reg: setup register offset from base | |
58 | - * @control_reg: control register offset from base | |
57 | + * @setup_off: setup register offset from base | |
58 | + * @control_off: control register offset from base | |
59 | 59 | * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask |
60 | 60 | * @fbb_sel_mask: setup register- FBB sel mask |
61 | 61 | * @rbb_sel_mask: setup register- RBB sel mask |
... | ... | @@ -64,8 +64,8 @@ |
64 | 64 | * @opp_sel_mask: control register - mask for mode to operate |
65 | 65 | */ |
66 | 66 | struct ti_abb_reg { |
67 | - u32 setup_reg; | |
68 | - u32 control_reg; | |
67 | + u32 setup_off; | |
68 | + u32 control_off; | |
69 | 69 | |
70 | 70 | /* Setup register fields */ |
71 | 71 | u32 sr2_wtcnt_value_mask; |
... | ... | @@ -83,6 +83,8 @@ |
83 | 83 | * @rdesc: regulator descriptor |
84 | 84 | * @clk: clock(usually sysclk) supplying ABB block |
85 | 85 | * @base: base address of ABB block |
86 | + * @setup_reg: setup register of ABB block | |
87 | + * @control_reg: control register of ABB block | |
86 | 88 | * @int_base: interrupt register base address |
87 | 89 | * @efuse_base: (optional) efuse base address for ABB modes |
88 | 90 | * @ldo_base: (optional) LDOVBB vset override base address |
... | ... | @@ -99,6 +101,8 @@ |
99 | 101 | struct regulator_desc rdesc; |
100 | 102 | struct clk *clk; |
101 | 103 | void __iomem *base; |
104 | + void __iomem *setup_reg; | |
105 | + void __iomem *control_reg; | |
102 | 106 | void __iomem *int_base; |
103 | 107 | void __iomem *efuse_base; |
104 | 108 | void __iomem *ldo_base; |
105 | 109 | |
106 | 110 | |
107 | 111 | |
... | ... | @@ -118,20 +122,18 @@ |
118 | 122 | * ti_abb_rmw() - handy wrapper to set specific register bits |
119 | 123 | * @mask: mask for register field |
120 | 124 | * @value: value shifted to mask location and written |
121 | - * @offset: offset of register | |
122 | - * @base: base address | |
125 | + * @reg: register address | |
123 | 126 | * |
124 | 127 | * Return: final register value (may be unused) |
125 | 128 | */ |
126 | -static inline u32 ti_abb_rmw(u32 mask, u32 value, u32 offset, | |
127 | - void __iomem *base) | |
129 | +static inline u32 ti_abb_rmw(u32 mask, u32 value, void __iomem *reg) | |
128 | 130 | { |
129 | 131 | u32 val; |
130 | 132 | |
131 | - val = readl(base + offset); | |
133 | + val = readl(reg); | |
132 | 134 | val &= ~mask; |
133 | 135 | val |= (value << __ffs(mask)) & mask; |
134 | - writel(val, base + offset); | |
136 | + writel(val, reg); | |
135 | 137 | |
136 | 138 | return val; |
137 | 139 | } |
138 | 140 | |
139 | 141 | |
140 | 142 | |
... | ... | @@ -263,21 +265,19 @@ |
263 | 265 | if (ret) |
264 | 266 | goto out; |
265 | 267 | |
266 | - ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, regs->setup_reg, | |
267 | - abb->base); | |
268 | + ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, abb->setup_reg); | |
268 | 269 | |
269 | 270 | switch (info->opp_sel) { |
270 | 271 | case TI_ABB_SLOW_OPP: |
271 | - ti_abb_rmw(regs->rbb_sel_mask, 1, regs->setup_reg, abb->base); | |
272 | + ti_abb_rmw(regs->rbb_sel_mask, 1, abb->setup_reg); | |
272 | 273 | break; |
273 | 274 | case TI_ABB_FAST_OPP: |
274 | - ti_abb_rmw(regs->fbb_sel_mask, 1, regs->setup_reg, abb->base); | |
275 | + ti_abb_rmw(regs->fbb_sel_mask, 1, abb->setup_reg); | |
275 | 276 | break; |
276 | 277 | } |
277 | 278 | |
278 | 279 | /* program next state of ABB ldo */ |
279 | - ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, regs->control_reg, | |
280 | - abb->base); | |
280 | + ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, abb->control_reg); | |
281 | 281 | |
282 | 282 | /* |
283 | 283 | * program LDO VBB vset override if needed for !bypass mode |
... | ... | @@ -288,7 +288,7 @@ |
288 | 288 | ti_abb_program_ldovbb(dev, abb, info); |
289 | 289 | |
290 | 290 | /* Initiate ABB ldo change */ |
291 | - ti_abb_rmw(regs->opp_change_mask, 1, regs->control_reg, abb->base); | |
291 | + ti_abb_rmw(regs->opp_change_mask, 1, abb->control_reg); | |
292 | 292 | |
293 | 293 | /* Wait for ABB LDO to complete transition to new Bias setting */ |
294 | 294 | ret = ti_abb_wait_txdone(dev, abb); |
... | ... | @@ -490,8 +490,7 @@ |
490 | 490 | dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__, |
491 | 491 | clk_get_rate(abb->clk), sr2_wt_cnt_val); |
492 | 492 | |
493 | - ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, regs->setup_reg, | |
494 | - abb->base); | |
493 | + ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, abb->setup_reg); | |
495 | 494 | |
496 | 495 | return 0; |
497 | 496 | } |
498 | 497 | |
499 | 498 | |
500 | 499 | |
501 | 500 | |
... | ... | @@ -508,32 +507,24 @@ |
508 | 507 | struct regulator_init_data *rinit_data) |
509 | 508 | { |
510 | 509 | struct ti_abb_info *info; |
511 | - const struct property *prop; | |
512 | - const __be32 *abb_info; | |
513 | 510 | const u32 num_values = 6; |
514 | 511 | char *pname = "ti,abb_info"; |
515 | - u32 num_entries, i; | |
512 | + u32 i; | |
516 | 513 | unsigned int *volt_table; |
517 | - int min_uV = INT_MAX, max_uV = 0; | |
514 | + int num_entries, min_uV = INT_MAX, max_uV = 0; | |
518 | 515 | struct regulation_constraints *c = &rinit_data->constraints; |
519 | 516 | |
520 | - prop = of_find_property(dev->of_node, pname, NULL); | |
521 | - if (!prop) { | |
522 | - dev_err(dev, "No '%s' property?\n", pname); | |
523 | - return -ENODEV; | |
524 | - } | |
525 | - | |
526 | - if (!prop->value) { | |
527 | - dev_err(dev, "Empty '%s' property?\n", pname); | |
528 | - return -ENODATA; | |
529 | - } | |
530 | - | |
531 | 517 | /* |
532 | 518 | * Each abb_info is a set of n-tuple, where n is num_values, consisting |
533 | 519 | * of voltage and a set of detection logic for ABB information for that |
534 | 520 | * voltage to apply. |
535 | 521 | */ |
536 | - num_entries = prop->length / sizeof(u32); | |
522 | + num_entries = of_property_count_u32_elems(dev->of_node, pname); | |
523 | + if (num_entries < 0) { | |
524 | + dev_err(dev, "No '%s' property?\n", pname); | |
525 | + return num_entries; | |
526 | + } | |
527 | + | |
537 | 528 | if (!num_entries || (num_entries % num_values)) { |
538 | 529 | dev_err(dev, "All '%s' list entries need %d vals\n", pname, |
539 | 530 | num_values); |
540 | 531 | |
541 | 532 | |
542 | 533 | |
543 | 534 | |
544 | 535 | |
... | ... | @@ -542,38 +533,38 @@ |
542 | 533 | num_entries /= num_values; |
543 | 534 | |
544 | 535 | info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL); |
545 | - if (!info) { | |
546 | - dev_err(dev, "Can't allocate info table for '%s' property\n", | |
547 | - pname); | |
536 | + if (!info) | |
548 | 537 | return -ENOMEM; |
549 | - } | |
538 | + | |
550 | 539 | abb->info = info; |
551 | 540 | |
552 | 541 | volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries, |
553 | 542 | GFP_KERNEL); |
554 | - if (!volt_table) { | |
555 | - dev_err(dev, "Can't allocate voltage table for '%s' property\n", | |
556 | - pname); | |
543 | + if (!volt_table) | |
557 | 544 | return -ENOMEM; |
558 | - } | |
559 | 545 | |
560 | 546 | abb->rdesc.n_voltages = num_entries; |
561 | 547 | abb->rdesc.volt_table = volt_table; |
562 | 548 | /* We do not know where the OPP voltage is at the moment */ |
563 | 549 | abb->current_info_idx = -EINVAL; |
564 | 550 | |
565 | - abb_info = prop->value; | |
566 | 551 | for (i = 0; i < num_entries; i++, info++, volt_table++) { |
567 | 552 | u32 efuse_offset, rbb_mask, fbb_mask, vset_mask; |
568 | 553 | u32 efuse_val; |
569 | 554 | |
570 | 555 | /* NOTE: num_values should equal to entries picked up here */ |
571 | - *volt_table = be32_to_cpup(abb_info++); | |
572 | - info->opp_sel = be32_to_cpup(abb_info++); | |
573 | - efuse_offset = be32_to_cpup(abb_info++); | |
574 | - rbb_mask = be32_to_cpup(abb_info++); | |
575 | - fbb_mask = be32_to_cpup(abb_info++); | |
576 | - vset_mask = be32_to_cpup(abb_info++); | |
556 | + of_property_read_u32_index(dev->of_node, pname, i * num_values, | |
557 | + volt_table); | |
558 | + of_property_read_u32_index(dev->of_node, pname, | |
559 | + i * num_values + 1, &info->opp_sel); | |
560 | + of_property_read_u32_index(dev->of_node, pname, | |
561 | + i * num_values + 2, &efuse_offset); | |
562 | + of_property_read_u32_index(dev->of_node, pname, | |
563 | + i * num_values + 3, &rbb_mask); | |
564 | + of_property_read_u32_index(dev->of_node, pname, | |
565 | + i * num_values + 4, &fbb_mask); | |
566 | + of_property_read_u32_index(dev->of_node, pname, | |
567 | + i * num_values + 5, &vset_mask); | |
577 | 568 | |
578 | 569 | dev_dbg(dev, |
579 | 570 | "[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n", |
... | ... | @@ -648,8 +639,8 @@ |
648 | 639 | /* Default ABB block offsets, IF this changes in future, create new one */ |
649 | 640 | static const struct ti_abb_reg abb_regs_v1 = { |
650 | 641 | /* WARNING: registers are wrongly documented in TRM */ |
651 | - .setup_reg = 0x04, | |
652 | - .control_reg = 0x00, | |
642 | + .setup_off = 0x04, | |
643 | + .control_off = 0x00, | |
653 | 644 | |
654 | 645 | .sr2_wtcnt_value_mask = (0xff << 8), |
655 | 646 | .fbb_sel_mask = (0x01 << 2), |
... | ... | @@ -661,8 +652,8 @@ |
661 | 652 | }; |
662 | 653 | |
663 | 654 | static const struct ti_abb_reg abb_regs_v2 = { |
664 | - .setup_reg = 0x00, | |
665 | - .control_reg = 0x04, | |
655 | + .setup_off = 0x00, | |
656 | + .control_off = 0x04, | |
666 | 657 | |
667 | 658 | .sr2_wtcnt_value_mask = (0xff << 8), |
668 | 659 | .fbb_sel_mask = (0x01 << 2), |
669 | 660 | |
... | ... | @@ -673,9 +664,20 @@ |
673 | 664 | .opp_sel_mask = (0x03 << 0), |
674 | 665 | }; |
675 | 666 | |
667 | +static const struct ti_abb_reg abb_regs_generic = { | |
668 | + .sr2_wtcnt_value_mask = (0xff << 8), | |
669 | + .fbb_sel_mask = (0x01 << 2), | |
670 | + .rbb_sel_mask = (0x01 << 1), | |
671 | + .sr2_en_mask = (0x01 << 0), | |
672 | + | |
673 | + .opp_change_mask = (0x01 << 2), | |
674 | + .opp_sel_mask = (0x03 << 0), | |
675 | +}; | |
676 | + | |
676 | 677 | static const struct of_device_id ti_abb_of_match[] = { |
677 | 678 | {.compatible = "ti,abb-v1", .data = &abb_regs_v1}, |
678 | 679 | {.compatible = "ti,abb-v2", .data = &abb_regs_v2}, |
680 | + {.compatible = "ti,abb-v3", .data = &abb_regs_generic}, | |
679 | 681 | { }, |
680 | 682 | }; |
681 | 683 | |
682 | 684 | |
... | ... | @@ -722,12 +724,30 @@ |
722 | 724 | abb->regs = match->data; |
723 | 725 | |
724 | 726 | /* Map ABB resources */ |
725 | - pname = "base-address"; | |
726 | - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | |
727 | - abb->base = devm_ioremap_resource(dev, res); | |
728 | - if (IS_ERR(abb->base)) | |
729 | - return PTR_ERR(abb->base); | |
727 | + if (abb->regs->setup_off || abb->regs->control_off) { | |
728 | + pname = "base-address"; | |
729 | + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | |
730 | + abb->base = devm_ioremap_resource(dev, res); | |
731 | + if (IS_ERR(abb->base)) | |
732 | + return PTR_ERR(abb->base); | |
730 | 733 | |
734 | + abb->setup_reg = abb->base + abb->regs->setup_off; | |
735 | + abb->control_reg = abb->base + abb->regs->control_off; | |
736 | + | |
737 | + } else { | |
738 | + pname = "control-address"; | |
739 | + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | |
740 | + abb->control_reg = devm_ioremap_resource(dev, res); | |
741 | + if (IS_ERR(abb->control_reg)) | |
742 | + return PTR_ERR(abb->control_reg); | |
743 | + | |
744 | + pname = "setup-address"; | |
745 | + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | |
746 | + abb->setup_reg = devm_ioremap_resource(dev, res); | |
747 | + if (IS_ERR(abb->setup_reg)) | |
748 | + return PTR_ERR(abb->setup_reg); | |
749 | + } | |
750 | + | |
731 | 751 | pname = "int-address"; |
732 | 752 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); |
733 | 753 | if (!res) { |
... | ... | @@ -860,7 +880,7 @@ |
860 | 880 | platform_set_drvdata(pdev, rdev); |
861 | 881 | |
862 | 882 | /* Enable the ldo if not already done by bootloader */ |
863 | - ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->regs->setup_reg, abb->base); | |
883 | + ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->setup_reg); | |
864 | 884 | |
865 | 885 | return 0; |
866 | 886 | } |
drivers/regulator/tps51632-regulator.c
... | ... | @@ -227,10 +227,8 @@ |
227 | 227 | struct device_node *np = dev->of_node; |
228 | 228 | |
229 | 229 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
230 | - if (!pdata) { | |
231 | - dev_err(dev, "Memory alloc failed for platform data\n"); | |
230 | + if (!pdata) | |
232 | 231 | return NULL; |
233 | - } | |
234 | 232 | |
235 | 233 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); |
236 | 234 | if (!pdata->reg_init_data) { |
237 | 235 | |
... | ... | @@ -299,10 +297,8 @@ |
299 | 297 | } |
300 | 298 | |
301 | 299 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
302 | - if (!tps) { | |
303 | - dev_err(&client->dev, "Memory allocation failed\n"); | |
300 | + if (!tps) | |
304 | 301 | return -ENOMEM; |
305 | - } | |
306 | 302 | |
307 | 303 | tps->dev = &client->dev; |
308 | 304 | tps->desc.name = client->name; |
drivers/regulator/tps62360-regulator.c
... | ... | @@ -299,10 +299,8 @@ |
299 | 299 | struct device_node *np = dev->of_node; |
300 | 300 | |
301 | 301 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
302 | - if (!pdata) { | |
303 | - dev_err(dev, "Memory alloc failed for platform data\n"); | |
302 | + if (!pdata) | |
304 | 303 | return NULL; |
305 | - } | |
306 | 304 | |
307 | 305 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); |
308 | 306 | if (!pdata->reg_init_data) { |
309 | 307 | |
... | ... | @@ -377,11 +375,8 @@ |
377 | 375 | } |
378 | 376 | |
379 | 377 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
380 | - if (!tps) { | |
381 | - dev_err(&client->dev, "%s(): Memory allocation failed\n", | |
382 | - __func__); | |
378 | + if (!tps) | |
383 | 379 | return -ENOMEM; |
384 | - } | |
385 | 380 | |
386 | 381 | tps->en_discharge = pdata->en_discharge; |
387 | 382 | tps->en_internal_pulldn = pdata->en_internal_pulldn; |
drivers/regulator/tps6507x-regulator.c
... | ... | @@ -359,7 +359,6 @@ |
359 | 359 | .map_voltage = regulator_map_voltage_ascend, |
360 | 360 | }; |
361 | 361 | |
362 | -#ifdef CONFIG_OF | |
363 | 362 | static struct of_regulator_match tps6507x_matches[] = { |
364 | 363 | { .name = "VDCDC1"}, |
365 | 364 | { .name = "VDCDC2"}, |
366 | 365 | |
367 | 366 | |
... | ... | @@ -381,12 +380,10 @@ |
381 | 380 | |
382 | 381 | tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), |
383 | 382 | GFP_KERNEL); |
384 | - if (!tps_board) { | |
385 | - dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n"); | |
383 | + if (!tps_board) | |
386 | 384 | return NULL; |
387 | - } | |
388 | 385 | |
389 | - regulators = of_find_node_by_name(np, "regulators"); | |
386 | + regulators = of_get_child_by_name(np, "regulators"); | |
390 | 387 | if (!regulators) { |
391 | 388 | dev_err(&pdev->dev, "regulator node not found\n"); |
392 | 389 | return NULL; |
... | ... | @@ -396,6 +393,7 @@ |
396 | 393 | matches = tps6507x_matches; |
397 | 394 | |
398 | 395 | ret = of_regulator_match(&pdev->dev, regulators, matches, count); |
396 | + of_node_put(regulators); | |
399 | 397 | if (ret < 0) { |
400 | 398 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", |
401 | 399 | ret); |
402 | 400 | |
... | ... | @@ -406,10 +404,8 @@ |
406 | 404 | |
407 | 405 | reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) |
408 | 406 | * TPS6507X_NUM_REGULATOR), GFP_KERNEL); |
409 | - if (!reg_data) { | |
410 | - dev_err(&pdev->dev, "Failure to alloc init data for regulators.\n"); | |
407 | + if (!reg_data) | |
411 | 408 | return NULL; |
412 | - } | |
413 | 409 | |
414 | 410 | tps_board->tps6507x_pmic_init_data = reg_data; |
415 | 411 | |
... | ... | @@ -424,15 +420,7 @@ |
424 | 420 | |
425 | 421 | return tps_board; |
426 | 422 | } |
427 | -#else | |
428 | -static inline struct tps6507x_board *tps6507x_parse_dt_reg_data( | |
429 | - struct platform_device *pdev, | |
430 | - struct of_regulator_match **tps6507x_reg_matches) | |
431 | -{ | |
432 | - *tps6507x_reg_matches = NULL; | |
433 | - return NULL; | |
434 | -} | |
435 | -#endif | |
423 | + | |
436 | 424 | static int tps6507x_pmic_probe(struct platform_device *pdev) |
437 | 425 | { |
438 | 426 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); |
439 | 427 | |
... | ... | @@ -453,9 +441,10 @@ |
453 | 441 | */ |
454 | 442 | |
455 | 443 | tps_board = dev_get_platdata(tps6507x_dev->dev); |
456 | - if (!tps_board && tps6507x_dev->dev->of_node) | |
444 | + if (IS_ENABLED(CONFIG_OF) && !tps_board && | |
445 | + tps6507x_dev->dev->of_node) | |
457 | 446 | tps_board = tps6507x_parse_dt_reg_data(pdev, |
458 | - &tps6507x_reg_matches); | |
447 | + &tps6507x_reg_matches); | |
459 | 448 | if (!tps_board) |
460 | 449 | return -EINVAL; |
461 | 450 | |
... | ... | @@ -481,7 +470,7 @@ |
481 | 470 | tps->info[i] = info; |
482 | 471 | if (init_data->driver_data) { |
483 | 472 | struct tps6507x_reg_platform_data *data = |
484 | - init_data->driver_data; | |
473 | + init_data->driver_data; | |
485 | 474 | tps->info[i]->defdcdc_default = data->defdcdc_default; |
486 | 475 | } |
487 | 476 |
drivers/regulator/tps65090-regulator.c
... | ... | @@ -168,17 +168,13 @@ |
168 | 168 | |
169 | 169 | tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata), |
170 | 170 | GFP_KERNEL); |
171 | - if (!tps65090_pdata) { | |
172 | - dev_err(&pdev->dev, "Memory alloc for tps65090_pdata failed\n"); | |
171 | + if (!tps65090_pdata) | |
173 | 172 | return ERR_PTR(-ENOMEM); |
174 | - } | |
175 | 173 | |
176 | 174 | reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * |
177 | 175 | sizeof(*reg_pdata), GFP_KERNEL); |
178 | - if (!reg_pdata) { | |
179 | - dev_err(&pdev->dev, "Memory alloc for reg_pdata failed\n"); | |
176 | + if (!reg_pdata) | |
180 | 177 | return ERR_PTR(-ENOMEM); |
181 | - } | |
182 | 178 | |
183 | 179 | regulators = of_get_child_by_name(np, "regulators"); |
184 | 180 | if (!regulators) { |
... | ... | @@ -188,6 +184,7 @@ |
188 | 184 | |
189 | 185 | ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches, |
190 | 186 | ARRAY_SIZE(tps65090_matches)); |
187 | + of_node_put(regulators); | |
191 | 188 | if (ret < 0) { |
192 | 189 | dev_err(&pdev->dev, |
193 | 190 | "Error parsing regulator init data: %d\n", ret); |
194 | 191 | |
... | ... | @@ -252,10 +249,8 @@ |
252 | 249 | |
253 | 250 | pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic), |
254 | 251 | GFP_KERNEL); |
255 | - if (!pmic) { | |
256 | - dev_err(&pdev->dev, "mem alloc for pmic failed\n"); | |
252 | + if (!pmic) | |
257 | 253 | return -ENOMEM; |
258 | - } | |
259 | 254 | |
260 | 255 | for (num = 0; num < TPS65090_REGULATOR_MAX; num++) { |
261 | 256 | tps_pdata = tps65090_pdata->reg_pdata[num]; |
drivers/regulator/tps65217-regulator.c
... | ... | @@ -187,7 +187,7 @@ |
187 | 187 | struct device_node *regs; |
188 | 188 | int i, count; |
189 | 189 | |
190 | - regs = of_find_node_by_name(node, "regulators"); | |
190 | + regs = of_get_child_by_name(node, "regulators"); | |
191 | 191 | if (!regs) |
192 | 192 | return NULL; |
193 | 193 | |
... | ... | @@ -202,7 +202,7 @@ |
202 | 202 | return NULL; |
203 | 203 | |
204 | 204 | for (i = 0; i < count; i++) { |
205 | - if (!reg_matches[i].init_data || !reg_matches[i].of_node) | |
205 | + if (!reg_matches[i].of_node) | |
206 | 206 | continue; |
207 | 207 | |
208 | 208 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; |
... | ... | @@ -222,7 +222,6 @@ |
222 | 222 | { |
223 | 223 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); |
224 | 224 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); |
225 | - struct regulator_init_data *reg_data; | |
226 | 225 | struct regulator_dev *rdev; |
227 | 226 | struct regulator_config config = { }; |
228 | 227 | int i; |
229 | 228 | |
... | ... | @@ -243,19 +242,9 @@ |
243 | 242 | platform_set_drvdata(pdev, tps); |
244 | 243 | |
245 | 244 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { |
246 | - | |
247 | - reg_data = pdata->tps65217_init_data[i]; | |
248 | - | |
249 | - /* | |
250 | - * Regulator API handles empty constraints but not NULL | |
251 | - * constraints | |
252 | - */ | |
253 | - if (!reg_data) | |
254 | - continue; | |
255 | - | |
256 | 245 | /* Register the regulators */ |
257 | 246 | config.dev = tps->dev; |
258 | - config.init_data = reg_data; | |
247 | + config.init_data = pdata->tps65217_init_data[i]; | |
259 | 248 | config.driver_data = tps; |
260 | 249 | config.regmap = tps->regmap; |
261 | 250 | if (tps->dev->of_node) |
include/linux/mfd/samsung/core.h
include/linux/mfd/samsung/s5m8767.h
... | ... | @@ -183,8 +183,15 @@ |
183 | 183 | S5M8767_REG_MAX, |
184 | 184 | }; |
185 | 185 | |
186 | +/* LDO_EN/BUCK_EN field in registers */ | |
186 | 187 | #define S5M8767_ENCTRL_SHIFT 6 |
187 | 188 | #define S5M8767_ENCTRL_MASK (0x3 << S5M8767_ENCTRL_SHIFT) |
189 | + | |
190 | +/* | |
191 | + * LDO_EN/BUCK_EN register value for controlling this Buck or LDO | |
192 | + * by GPIO (PWREN, BUCKEN). | |
193 | + */ | |
194 | +#define S5M8767_ENCTRL_USE_GPIO 0x1 | |
188 | 195 | |
189 | 196 | /* |
190 | 197 | * Values for BUCK_RAMP field in DVS_RAMP register, matching raw values |