diff options
46 files changed, 4320 insertions, 770 deletions
diff --git a/Documentation/devicetree/bindings/regulator/da9211.txt b/Documentation/devicetree/bindings/regulator/da9211.txt new file mode 100644 index 000000000000..240019a82f9a --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/da9211.txt | |||
@@ -0,0 +1,63 @@ | |||
1 | * Dialog Semiconductor DA9211/DA9213 Voltage Regulator | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "dlg,da9211" or "dlg,da9213". | ||
5 | - reg: I2C slave address, usually 0x68. | ||
6 | - interrupts: the interrupt outputs of the controller | ||
7 | - regulators: A node that houses a sub-node for each regulator within the | ||
8 | device. Each sub-node is identified using the node's name, with valid | ||
9 | values listed below. The content of each sub-node is defined by the | ||
10 | standard binding for regulators; see regulator.txt. | ||
11 | BUCKA and BUCKB. | ||
12 | |||
13 | Optional properties: | ||
14 | - Any optional property defined in regulator.txt | ||
15 | |||
16 | Example 1) DA9211 | ||
17 | |||
18 | pmic: da9211@68 { | ||
19 | compatible = "dlg,da9211"; | ||
20 | reg = <0x68>; | ||
21 | interrupts = <3 27>; | ||
22 | |||
23 | regulators { | ||
24 | BUCKA { | ||
25 | regulator-name = "VBUCKA"; | ||
26 | regulator-min-microvolt = < 300000>; | ||
27 | regulator-max-microvolt = <1570000>; | ||
28 | regulator-min-microamp = <2000000>; | ||
29 | regulator-max-microamp = <5000000>; | ||
30 | }; | ||
31 | BUCKB { | ||
32 | regulator-name = "VBUCKB"; | ||
33 | regulator-min-microvolt = < 300000>; | ||
34 | regulator-max-microvolt = <1570000>; | ||
35 | regulator-min-microamp = <2000000>; | ||
36 | regulator-max-microamp = <5000000>; | ||
37 | }; | ||
38 | }; | ||
39 | }; | ||
40 | |||
41 | Example 2) DA92113 | ||
42 | pmic: da9213@68 { | ||
43 | compatible = "dlg,da9213"; | ||
44 | reg = <0x68>; | ||
45 | interrupts = <3 27>; | ||
46 | |||
47 | regulators { | ||
48 | BUCKA { | ||
49 | regulator-name = "VBUCKA"; | ||
50 | regulator-min-microvolt = < 300000>; | ||
51 | regulator-max-microvolt = <1570000>; | ||
52 | regulator-min-microamp = <3000000>; | ||
53 | regulator-max-microamp = <6000000>; | ||
54 | }; | ||
55 | BUCKB { | ||
56 | regulator-name = "VBUCKB"; | ||
57 | regulator-min-microvolt = < 300000>; | ||
58 | regulator-max-microvolt = <1570000>; | ||
59 | regulator-min-microamp = <3000000>; | ||
60 | regulator-max-microamp = <6000000>; | ||
61 | }; | ||
62 | }; | ||
63 | }; | ||
diff --git a/Documentation/devicetree/bindings/regulator/fan53555.txt b/Documentation/devicetree/bindings/regulator/fan53555.txt new file mode 100644 index 000000000000..54a3f2c80e3a --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/fan53555.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | Binding for Fairchild FAN53555 regulators | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: one of "fcs,fan53555", "silergy,syr827", "silergy,syr828" | ||
5 | - reg: I2C address | ||
6 | |||
7 | Optional properties: | ||
8 | - fcs,suspend-voltage-selector: declare which of the two available | ||
9 | voltage selector registers should be used for the suspend | ||
10 | voltage. The other one is used for the runtime voltage setting | ||
11 | Possible values are either <0> or <1> | ||
12 | - vin-supply: regulator supplying the vin pin | ||
13 | |||
14 | Example: | ||
15 | |||
16 | regulator@40 { | ||
17 | compatible = "fcs,fan53555"; | ||
18 | regulator-name = "fan53555"; | ||
19 | regulator-min-microvolt = <1000000>; | ||
20 | regulator-max-microvolt = <1800000>; | ||
21 | vin-supply = <&parent_reg>; | ||
22 | fcs,suspend-voltage-selector = <1>; | ||
23 | }; | ||
diff --git a/Documentation/devicetree/bindings/regulator/isl9305.txt b/Documentation/devicetree/bindings/regulator/isl9305.txt new file mode 100644 index 000000000000..a626fc1bbf0d --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/isl9305.txt | |||
@@ -0,0 +1,36 @@ | |||
1 | Intersil ISL9305/ISL9305H voltage regulator | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible: "isl,isl9305" or "isl,isl9305h" | ||
6 | - reg: I2C slave address, usually 0x68. | ||
7 | - regulators: A node that houses a sub-node for each regulator within the | ||
8 | device. Each sub-node is identified using the node's name, with valid | ||
9 | values being "dcd1", "dcd2", "ldo1" and "ldo2". The content of each sub-node | ||
10 | is defined by the standard binding for regulators; see regulator.txt. | ||
11 | - VINDCD1-supply: A phandle to a regulator node supplying VINDCD1. | ||
12 | VINDCD2-supply: A phandle to a regulator node supplying VINDCD2. | ||
13 | VINLDO1-supply: A phandle to a regulator node supplying VINLDO1. | ||
14 | VINLDO2-supply: A phandle to a regulator node supplying VINLDO2. | ||
15 | |||
16 | Optional properties: | ||
17 | - Per-regulator optional properties are defined in regulator.txt | ||
18 | |||
19 | Example | ||
20 | |||
21 | pmic: isl9305@68 { | ||
22 | compatible = "isl,isl9305"; | ||
23 | reg = <0x68>; | ||
24 | |||
25 | VINDCD1-supply = <&system_power>; | ||
26 | VINDCD2-supply = <&system_power>; | ||
27 | VINLDO1-supply = <&system_power>; | ||
28 | VINLDO2-supply = <&system_power>; | ||
29 | |||
30 | regulators { | ||
31 | dcd1 { | ||
32 | regulator-name = "VDD_DSP"; | ||
33 | regulator-always-on; | ||
34 | }; | ||
35 | }; | ||
36 | }; | ||
diff --git a/Documentation/devicetree/bindings/regulator/max1586-regulator.txt b/Documentation/devicetree/bindings/regulator/max1586-regulator.txt new file mode 100644 index 000000000000..c050c1744cb8 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/max1586-regulator.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | Maxim MAX1586 voltage regulator | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: must be "maxim,max1586" | ||
5 | - reg: I2C slave address, usually 0x14 | ||
6 | - v3-gain: integer specifying the V3 gain as per datasheet | ||
7 | (1 + R24/R25 + R24/185.5kOhm) | ||
8 | - any required generic properties defined in regulator.txt | ||
9 | |||
10 | Example: | ||
11 | |||
12 | i2c_master { | ||
13 | max1586@14 { | ||
14 | compatible = "maxim,max1586"; | ||
15 | reg = <0x14>; | ||
16 | v3-gain = <1000000>; | ||
17 | |||
18 | regulators { | ||
19 | vcc_core: v3 { | ||
20 | regulator-name = "vcc_core"; | ||
21 | regulator-compatible = "Output_V3"; | ||
22 | regulator-min-microvolt = <1000000>; | ||
23 | regulator-max-microvolt = <1705000>; | ||
24 | regulator-always-on; | ||
25 | }; | ||
26 | }; | ||
27 | }; | ||
28 | }; | ||
diff --git a/Documentation/devicetree/bindings/regulator/max77802.txt b/Documentation/devicetree/bindings/regulator/max77802.txt new file mode 100644 index 000000000000..5aeaffc0f1f0 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/max77802.txt | |||
@@ -0,0 +1,53 @@ | |||
1 | Binding for Maxim MAX77802 regulators | ||
2 | |||
3 | This is a part of device tree bindings of MAX77802 multi-function device. | ||
4 | More information can be found in bindings/mfd/max77802.txt file. | ||
5 | |||
6 | The MAX77802 PMIC has 10 high-efficiency Buck and 32 Low-dropout (LDO) | ||
7 | regulators that can be controlled over I2C. | ||
8 | |||
9 | Following properties should be present in main device node of the MFD chip. | ||
10 | |||
11 | Optional node: | ||
12 | - regulators : The regulators of max77802 have to be instantiated | ||
13 | under subnode named "regulators" using the following format. | ||
14 | |||
15 | regulator-name { | ||
16 | standard regulator constraints.... | ||
17 | }; | ||
18 | refer Documentation/devicetree/bindings/regulator/regulator.txt | ||
19 | |||
20 | The regulator node name should be initialized with a string to get matched | ||
21 | with their hardware counterparts as follow. The valid names are: | ||
22 | |||
23 | -LDOn : for LDOs, where n can lie in ranges 1-15, 17-21, 23-30 | ||
24 | and 32-35. | ||
25 | example: LDO1, LDO2, LDO35. | ||
26 | -BUCKn : for BUCKs, where n can lie in range 1 to 10. | ||
27 | example: BUCK1, BUCK5, BUCK10. | ||
28 | Example: | ||
29 | |||
30 | max77802@09 { | ||
31 | compatible = "maxim,max77802"; | ||
32 | interrupt-parent = <&wakeup_eint>; | ||
33 | interrupts = <26 0>; | ||
34 | reg = <0x09>; | ||
35 | #address-cells = <1>; | ||
36 | #size-cells = <0>; | ||
37 | |||
38 | regulators { | ||
39 | ldo11_reg: LDO11 { | ||
40 | regulator-name = "vdd_ldo11"; | ||
41 | regulator-min-microvolt = <1900000>; | ||
42 | regulator-max-microvolt = <1900000>; | ||
43 | regulator-always-on; | ||
44 | }; | ||
45 | |||
46 | buck1_reg: BUCK1 { | ||
47 | regulator-name = "vdd_mif"; | ||
48 | regulator-min-microvolt = <950000>; | ||
49 | regulator-max-microvolt = <1300000>; | ||
50 | regulator-always-on; | ||
51 | regulator-boot-on; | ||
52 | }; | ||
53 | }; | ||
diff --git a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt new file mode 100644 index 000000000000..ce91f61feb12 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt | |||
@@ -0,0 +1,27 @@ | |||
1 | pwm regulator bindings | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "pwm-regulator" | ||
5 | - pwms: OF device-tree PWM specification (see PWM binding pwm.txt) | ||
6 | - voltage-table: voltage and duty table, include 2 members in each set of | ||
7 | brackets, first one is voltage(unit: uv), the next is duty(unit: percent) | ||
8 | |||
9 | Any property defined as part of the core regulator binding defined in | ||
10 | regulator.txt can also be used. | ||
11 | |||
12 | Example: | ||
13 | pwm_regulator { | ||
14 | compatible = "pwm-regulator; | ||
15 | pwms = <&pwm1 0 8448 0>; | ||
16 | |||
17 | voltage-table = <1114000 0>, | ||
18 | <1095000 10>, | ||
19 | <1076000 20>, | ||
20 | <1056000 30>, | ||
21 | <1036000 40>, | ||
22 | <1016000 50>; | ||
23 | |||
24 | regulator-min-microvolt = <1016000>; | ||
25 | regulator-max-microvolt = <1114000>; | ||
26 | regulator-name = "vdd_logic"; | ||
27 | }; | ||
diff --git a/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt b/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt new file mode 100644 index 000000000000..882455e9b36d --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | SKY81452 voltage regulator | ||
2 | |||
3 | Required properties: | ||
4 | - any required generic properties defined in regulator.txt | ||
5 | |||
6 | Optional properties: | ||
7 | - any available generic properties defined in regulator.txt | ||
8 | |||
9 | Example: | ||
10 | |||
11 | regulator { | ||
12 | /* generic regulator properties */ | ||
13 | regulator-name = "touch_en"; | ||
14 | regulator-min-microvolt = <4500000>; | ||
15 | regulator-max-microvolt = <8000000>; | ||
16 | }; | ||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index ac7269f90764..6073e76575ea 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -49,6 +49,7 @@ epson Seiko Epson Corp. | |||
49 | est ESTeem Wireless Modems | 49 | est ESTeem Wireless Modems |
50 | eukrea Eukréa Electromatique | 50 | eukrea Eukréa Electromatique |
51 | excito Excito | 51 | excito Excito |
52 | fcs Fairchild Semiconductor | ||
52 | fsl Freescale Semiconductor | 53 | fsl Freescale Semiconductor |
53 | GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. | 54 | GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. |
54 | gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. | 55 | gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. |
@@ -124,6 +125,7 @@ sil Silicon Image | |||
124 | silabs Silicon Laboratories | 125 | silabs Silicon Laboratories |
125 | simtek | 126 | simtek |
126 | sii Seiko Instruments, Inc. | 127 | sii Seiko Instruments, Inc. |
128 | silergy Silergy Corp. | ||
127 | sirf SiRF Technology, Inc. | 129 | sirf SiRF Technology, Inc. |
128 | smsc Standard Microsystems Corporation | 130 | smsc Standard Microsystems Corporation |
129 | snps Synopsys, Inc. | 131 | snps Synopsys, Inc. |
diff --git a/MAINTAINERS b/MAINTAINERS index 8d9567186aa9..78cb4aad5bfe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9895,6 +9895,7 @@ F: drivers/scsi/vmw_pvscsi.h | |||
9895 | VOLTAGE AND CURRENT REGULATOR FRAMEWORK | 9895 | VOLTAGE AND CURRENT REGULATOR FRAMEWORK |
9896 | M: Liam Girdwood <lgirdwood@gmail.com> | 9896 | M: Liam Girdwood <lgirdwood@gmail.com> |
9897 | M: Mark Brown <broonie@kernel.org> | 9897 | M: Mark Brown <broonie@kernel.org> |
9898 | L: linux-kernel@vger.kernel.org | ||
9898 | W: http://opensource.wolfsonmicro.com/node/15 | 9899 | W: http://opensource.wolfsonmicro.com/node/15 |
9899 | W: http://www.slimlogic.co.uk/?p=48 | 9900 | W: http://www.slimlogic.co.uk/?p=48 |
9900 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git | 9901 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2dc8289e5dba..55d7b7b0f2e0 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -199,13 +199,14 @@ config REGULATOR_DA9210 | |||
199 | interface. | 199 | interface. |
200 | 200 | ||
201 | config REGULATOR_DA9211 | 201 | config REGULATOR_DA9211 |
202 | tristate "Dialog Semiconductor DA9211/DA9212 regulator" | 202 | tristate "Dialog Semiconductor DA9211/DA9212/DA9213/DA9214 regulator" |
203 | depends on I2C | 203 | depends on I2C |
204 | select REGMAP_I2C | 204 | select REGMAP_I2C |
205 | help | 205 | help |
206 | Say y here to support for the Dialog Semiconductor DA9211/DA9212. | 206 | Say y here to support for the Dialog Semiconductor DA9211/DA9212 |
207 | The DA9211/DA9212 is a multi-phase synchronous step down | 207 | /DA9213/DA9214. |
208 | converter 12A DC-DC Buck controlled through an I2C | 208 | The DA9211/DA9212/DA9213/DA9214 is a multi-phase synchronous |
209 | step down converter 12A or 16A DC-DC Buck controlled through an I2C | ||
209 | interface. | 210 | interface. |
210 | 211 | ||
211 | config REGULATOR_DBX500_PRCMU | 212 | config REGULATOR_DBX500_PRCMU |
@@ -240,6 +241,23 @@ config REGULATOR_GPIO | |||
240 | and the platform has to provide a mapping of GPIO-states | 241 | and the platform has to provide a mapping of GPIO-states |
241 | to target volts/amps. | 242 | to target volts/amps. |
242 | 243 | ||
244 | config REGULATOR_HI6421 | ||
245 | tristate "HiSilicon Hi6421 PMIC voltage regulator support" | ||
246 | depends on MFD_HI6421_PMIC && OF | ||
247 | help | ||
248 | This driver provides support for the voltage regulators on the | ||
249 | HiSilicon Hi6421 PMU / Codec IC. | ||
250 | Hi6421 is a multi-function device which, on regulator part, provides | ||
251 | 21 general purpose LDOs, 3 dedicated LDOs, and 5 BUCKs. All | ||
252 | of them come with support to either ECO (idle) or sleep mode. | ||
253 | |||
254 | config REGULATOR_ISL9305 | ||
255 | tristate "Intersil ISL9305 regulator" | ||
256 | depends on I2C | ||
257 | select REGMAP_I2C | ||
258 | help | ||
259 | This driver supports ISL9305 voltage regulator chip. | ||
260 | |||
243 | config REGULATOR_ISL6271A | 261 | config REGULATOR_ISL6271A |
244 | tristate "Intersil ISL6271A Power regulator" | 262 | tristate "Intersil ISL6271A Power regulator" |
245 | depends on I2C | 263 | depends on I2C |
@@ -387,6 +405,15 @@ config REGULATOR_MAX77693 | |||
387 | and one current regulator 'CHARGER'. This is suitable for | 405 | and one current regulator 'CHARGER'. This is suitable for |
388 | Exynos-4x12 chips. | 406 | Exynos-4x12 chips. |
389 | 407 | ||
408 | config REGULATOR_MAX77802 | ||
409 | tristate "Maxim 77802 regulator" | ||
410 | depends on MFD_MAX77686 | ||
411 | help | ||
412 | This driver controls a Maxim 77802 regulator | ||
413 | via I2C bus. The provided regulator is suitable for | ||
414 | Exynos5420/Exynos5800 SoCs to control various voltages. | ||
415 | It includes support for control of voltage and ramp speed. | ||
416 | |||
390 | config REGULATOR_MC13XXX_CORE | 417 | config REGULATOR_MC13XXX_CORE |
391 | tristate | 418 | tristate |
392 | 419 | ||
@@ -449,6 +476,25 @@ config REGULATOR_PFUZE100 | |||
449 | Say y here to support the regulators found on the Freescale | 476 | Say y here to support the regulators found on the Freescale |
450 | PFUZE100/PFUZE200 PMIC. | 477 | PFUZE100/PFUZE200 PMIC. |
451 | 478 | ||
479 | config REGULATOR_PWM | ||
480 | tristate "PWM voltage regulator" | ||
481 | depends on PWM | ||
482 | help | ||
483 | This driver supports PWM controlled voltage regulators. PWM | ||
484 | duty cycle can increase or decrease the voltage. | ||
485 | |||
486 | config REGULATOR_QCOM_RPM | ||
487 | tristate "Qualcomm RPM regulator driver" | ||
488 | depends on MFD_QCOM_RPM | ||
489 | help | ||
490 | If you say yes to this option, support will be included for the | ||
491 | regulators exposed by the Resource Power Manager found in Qualcomm | ||
492 | 8660, 8960 and 8064 based devices. | ||
493 | |||
494 | Say M here if you want to include support for the regulators on the | ||
495 | Qualcomm RPM as a module. The module will be named | ||
496 | "qcom_rpm-regulator". | ||
497 | |||
452 | config REGULATOR_RC5T583 | 498 | config REGULATOR_RC5T583 |
453 | tristate "RICOH RC5T583 Power regulators" | 499 | tristate "RICOH RC5T583 Power regulators" |
454 | depends on MFD_RC5T583 | 500 | depends on MFD_RC5T583 |
@@ -459,6 +505,22 @@ config REGULATOR_RC5T583 | |||
459 | through regulator interface. The device supports multiple DCDC/LDO | 505 | through regulator interface. The device supports multiple DCDC/LDO |
460 | outputs which can be controlled by i2c communication. | 506 | outputs which can be controlled by i2c communication. |
461 | 507 | ||
508 | config REGULATOR_RK808 | ||
509 | tristate "Rockchip RK808 Power regulators" | ||
510 | depends on MFD_RK808 | ||
511 | help | ||
512 | Select this option to enable the power regulator of ROCKCHIP | ||
513 | PMIC RK808. | ||
514 | This driver supports the control of different power rails of device | ||
515 | through regulator interface. The device supports multiple DCDC/LDO | ||
516 | outputs which can be controlled by i2c communication. | ||
517 | |||
518 | config REGULATOR_RN5T618 | ||
519 | tristate "Ricoh RN5T618 voltage regulators" | ||
520 | depends on MFD_RN5T618 | ||
521 | help | ||
522 | Say y here to support the regulators found on Ricoh RN5T618 PMIC. | ||
523 | |||
462 | config REGULATOR_S2MPA01 | 524 | config REGULATOR_S2MPA01 |
463 | tristate "Samsung S2MPA01 voltage regulator" | 525 | tristate "Samsung S2MPA01 voltage regulator" |
464 | depends on MFD_SEC_CORE | 526 | depends on MFD_SEC_CORE |
@@ -483,11 +545,16 @@ config REGULATOR_S5M8767 | |||
483 | via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and | 545 | via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and |
484 | supports DVS mode with 8bits of output voltage control. | 546 | supports DVS mode with 8bits of output voltage control. |
485 | 547 | ||
486 | config REGULATOR_ST_PWM | 548 | config REGULATOR_SKY81452 |
487 | tristate "STMicroelectronics PWM voltage regulator" | 549 | tristate "Skyworks Solutions SKY81452 voltage regulator" |
488 | depends on ARCH_STI | 550 | depends on SKY81452 |
489 | help | 551 | help |
490 | This driver supports ST's PWM controlled voltage regulators. | 552 | This driver supports Skyworks SKY81452 voltage output regulator |
553 | via I2C bus. SKY81452 has one voltage linear regulator can be | ||
554 | programmed from 4.5V to 20V. | ||
555 | |||
556 | This driver can also be built as a module. If so, the module | ||
557 | will be called sky81452-regulator. | ||
491 | 558 | ||
492 | config REGULATOR_TI_ABB | 559 | config REGULATOR_TI_ABB |
493 | tristate "TI Adaptive Body Bias on-chip LDO" | 560 | tristate "TI Adaptive Body Bias on-chip LDO" |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index aa4a6aa7b558..1029ed39c512 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -32,7 +32,9 @@ obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o | |||
32 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o | 32 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o |
33 | obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o | 33 | obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o |
34 | obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o | 34 | obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o |
35 | obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o | ||
35 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o | 36 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o |
37 | obj-$(CONFIG_REGULATOR_ISL9305) += isl9305.o | ||
36 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o | 38 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o |
37 | obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o | 39 | obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o |
38 | obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o | 40 | obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o |
@@ -52,20 +54,25 @@ obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o | |||
52 | obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o | 54 | obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o |
53 | obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o | 55 | obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o |
54 | obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o | 56 | obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o |
57 | obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o | ||
55 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o | 58 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o |
56 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o | 59 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o |
57 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o | 60 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o |
61 | obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o | ||
58 | obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o | 62 | obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o |
59 | obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o | 63 | obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o |
64 | obj-$(CONFIG_REGULATOR_PWM) += pwm-regulator.o | ||
60 | obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o | 65 | obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o |
61 | obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o | 66 | obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o |
62 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | 67 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o |
63 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | 68 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o |
64 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o | 69 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o |
70 | obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o | ||
71 | obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o | ||
65 | obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o | 72 | obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o |
66 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o | 73 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o |
67 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o | 74 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o |
68 | obj-$(CONFIG_REGULATOR_ST_PWM) += st-pwm.o | 75 | obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o |
69 | obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o | 76 | obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o |
70 | obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o | 77 | obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o |
71 | obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o | 78 | obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o |
diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index b47283f91e2d..8459b0b648cd 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c | |||
@@ -22,12 +22,10 @@ | |||
22 | 22 | ||
23 | struct as3711_regulator_info { | 23 | struct as3711_regulator_info { |
24 | struct regulator_desc desc; | 24 | struct regulator_desc desc; |
25 | unsigned int max_uV; | ||
26 | }; | 25 | }; |
27 | 26 | ||
28 | struct as3711_regulator { | 27 | struct as3711_regulator { |
29 | struct as3711_regulator_info *reg_info; | 28 | struct as3711_regulator_info *reg_info; |
30 | struct regulator_dev *rdev; | ||
31 | }; | 29 | }; |
32 | 30 | ||
33 | /* | 31 | /* |
@@ -132,39 +130,37 @@ static const struct regulator_linear_range as3711_dldo_ranges[] = { | |||
132 | REGULATOR_LINEAR_RANGE(1750000, 0x20, 0x3f, 50000), | 130 | REGULATOR_LINEAR_RANGE(1750000, 0x20, 0x3f, 50000), |
133 | }; | 131 | }; |
134 | 132 | ||
135 | #define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _vshift, _min_uV, _max_uV, _sfx) \ | 133 | #define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _sfx) \ |
136 | [AS3711_REGULATOR_ ## _id] = { \ | 134 | [AS3711_REGULATOR_ ## _id] = { \ |
137 | .desc = { \ | 135 | .desc = { \ |
138 | .name = "as3711-regulator-" # _id, \ | 136 | .name = "as3711-regulator-" # _id, \ |
139 | .id = AS3711_REGULATOR_ ## _id, \ | 137 | .id = AS3711_REGULATOR_ ## _id, \ |
140 | .n_voltages = (_vmask + 1), \ | 138 | .n_voltages = (_vmask + 1), \ |
141 | .ops = &as3711_ ## _sfx ## _ops, \ | 139 | .ops = &as3711_ ## _sfx ## _ops, \ |
142 | .type = REGULATOR_VOLTAGE, \ | 140 | .type = REGULATOR_VOLTAGE, \ |
143 | .owner = THIS_MODULE, \ | 141 | .owner = THIS_MODULE, \ |
144 | .vsel_reg = AS3711_ ## _id ## _VOLTAGE, \ | 142 | .vsel_reg = AS3711_ ## _id ## _VOLTAGE, \ |
145 | .vsel_mask = _vmask << _vshift, \ | 143 | .vsel_mask = _vmask, \ |
146 | .enable_reg = AS3711_ ## _en_reg, \ | 144 | .enable_reg = AS3711_ ## _en_reg, \ |
147 | .enable_mask = BIT(_en_bit), \ | 145 | .enable_mask = BIT(_en_bit), \ |
148 | .min_uV = _min_uV, \ | 146 | .linear_ranges = as3711_ ## _sfx ## _ranges, \ |
149 | .linear_ranges = as3711_ ## _sfx ## _ranges, \ | 147 | .n_linear_ranges = ARRAY_SIZE(as3711_ ## _sfx ## _ranges), \ |
150 | .n_linear_ranges = ARRAY_SIZE(as3711_ ## _sfx ## _ranges), \ | 148 | }, \ |
151 | }, \ | ||
152 | .max_uV = _max_uV, \ | ||
153 | } | 149 | } |
154 | 150 | ||
155 | static struct as3711_regulator_info as3711_reg_info[] = { | 151 | static struct as3711_regulator_info as3711_reg_info[] = { |
156 | AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, 0, 612500, 3350000, sd), | 152 | AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, sd), |
157 | AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, 0, 612500, 3350000, sd), | 153 | AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, sd), |
158 | AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, 0, 612500, 3350000, sd), | 154 | AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, sd), |
159 | AS3711_REG(SD_4, SD_CONTROL, 3, 0x7f, 0, 612500, 3350000, sd), | 155 | AS3711_REG(SD_4, SD_CONTROL, 3, 0x7f, sd), |
160 | AS3711_REG(LDO_1, LDO_1_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo), | 156 | AS3711_REG(LDO_1, LDO_1_VOLTAGE, 7, 0x1f, aldo), |
161 | AS3711_REG(LDO_2, LDO_2_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo), | 157 | AS3711_REG(LDO_2, LDO_2_VOLTAGE, 7, 0x1f, aldo), |
162 | AS3711_REG(LDO_3, LDO_3_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 158 | AS3711_REG(LDO_3, LDO_3_VOLTAGE, 7, 0x3f, dldo), |
163 | AS3711_REG(LDO_4, LDO_4_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 159 | AS3711_REG(LDO_4, LDO_4_VOLTAGE, 7, 0x3f, dldo), |
164 | AS3711_REG(LDO_5, LDO_5_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 160 | AS3711_REG(LDO_5, LDO_5_VOLTAGE, 7, 0x3f, dldo), |
165 | AS3711_REG(LDO_6, LDO_6_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 161 | AS3711_REG(LDO_6, LDO_6_VOLTAGE, 7, 0x3f, dldo), |
166 | AS3711_REG(LDO_7, LDO_7_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 162 | AS3711_REG(LDO_7, LDO_7_VOLTAGE, 7, 0x3f, dldo), |
167 | AS3711_REG(LDO_8, LDO_8_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 163 | AS3711_REG(LDO_8, LDO_8_VOLTAGE, 7, 0x3f, dldo), |
168 | /* StepUp output voltage depends on supplying regulator */ | 164 | /* StepUp output voltage depends on supplying regulator */ |
169 | }; | 165 | }; |
170 | 166 | ||
@@ -263,7 +259,6 @@ static int as3711_regulator_probe(struct platform_device *pdev) | |||
263 | ri->desc.name); | 259 | ri->desc.name); |
264 | return PTR_ERR(rdev); | 260 | return PTR_ERR(rdev); |
265 | } | 261 | } |
266 | reg->rdev = rdev; | ||
267 | } | 262 | } |
268 | platform_set_drvdata(pdev, regs); | 263 | platform_set_drvdata(pdev, regs); |
269 | return 0; | 264 | return 0; |
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 004aadb7bcc1..2e1010a34ddc 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c | |||
@@ -245,7 +245,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev) | |||
245 | for (i = 0; i < AXP20X_REG_ID_MAX; i++) { | 245 | for (i = 0; i < AXP20X_REG_ID_MAX; i++) { |
246 | init_data = axp20x_matches[i].init_data; | 246 | init_data = axp20x_matches[i].init_data; |
247 | 247 | ||
248 | config.dev = &pdev->dev; | 248 | config.dev = pdev->dev.parent; |
249 | config.init_data = init_data; | 249 | config.init_data = init_data; |
250 | config.regmap = axp20x->regmap; | 250 | config.regmap = axp20x->regmap; |
251 | config.of_node = axp20x_matches[i].of_node; | 251 | config.of_node = axp20x_matches[i].of_node; |
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index 5d1fd6f3d10a..fe6ac69549a6 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c | |||
@@ -202,7 +202,6 @@ static struct bcm590xx_info bcm590xx_regs[] = { | |||
202 | struct bcm590xx_reg { | 202 | struct bcm590xx_reg { |
203 | struct regulator_desc *desc; | 203 | struct regulator_desc *desc; |
204 | struct bcm590xx *mfd; | 204 | struct bcm590xx *mfd; |
205 | struct bcm590xx_info **info; | ||
206 | }; | 205 | }; |
207 | 206 | ||
208 | static int bcm590xx_get_vsel_register(int id) | 207 | static int bcm590xx_get_vsel_register(int id) |
@@ -389,11 +388,6 @@ static int bcm590xx_probe(struct platform_device *pdev) | |||
389 | if (!pmu->desc) | 388 | if (!pmu->desc) |
390 | return -ENOMEM; | 389 | return -ENOMEM; |
391 | 390 | ||
392 | pmu->info = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS * | ||
393 | sizeof(struct bcm590xx_info *), GFP_KERNEL); | ||
394 | if (!pmu->info) | ||
395 | return -ENOMEM; | ||
396 | |||
397 | info = bcm590xx_regs; | 391 | info = bcm590xx_regs; |
398 | 392 | ||
399 | for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) { | 393 | for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) { |
@@ -403,8 +397,6 @@ static int bcm590xx_probe(struct platform_device *pdev) | |||
403 | reg_data = NULL; | 397 | reg_data = NULL; |
404 | 398 | ||
405 | /* Register the regulators */ | 399 | /* Register the regulators */ |
406 | pmu->info[i] = info; | ||
407 | |||
408 | pmu->desc[i].name = info->name; | 400 | pmu->desc[i].name = info->name; |
409 | pmu->desc[i].supply_name = info->vin_name; | 401 | pmu->desc[i].supply_name = info->vin_name; |
410 | pmu->desc[i].id = i; | 402 | pmu->desc[i].id = i; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a3c3785901f5..cd87c0c37034 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -102,7 +102,7 @@ static int _regulator_disable(struct regulator_dev *rdev); | |||
102 | static int _regulator_get_voltage(struct regulator_dev *rdev); | 102 | static int _regulator_get_voltage(struct regulator_dev *rdev); |
103 | static int _regulator_get_current_limit(struct regulator_dev *rdev); | 103 | static int _regulator_get_current_limit(struct regulator_dev *rdev); |
104 | static unsigned int _regulator_get_mode(struct regulator_dev *rdev); | 104 | static unsigned int _regulator_get_mode(struct regulator_dev *rdev); |
105 | static void _notifier_call_chain(struct regulator_dev *rdev, | 105 | static int _notifier_call_chain(struct regulator_dev *rdev, |
106 | unsigned long event, void *data); | 106 | unsigned long event, void *data); |
107 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, | 107 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, |
108 | int min_uV, int max_uV); | 108 | int min_uV, int max_uV); |
@@ -839,7 +839,7 @@ static void print_constraints(struct regulator_dev *rdev) | |||
839 | static int machine_constraints_voltage(struct regulator_dev *rdev, | 839 | static int machine_constraints_voltage(struct regulator_dev *rdev, |
840 | struct regulation_constraints *constraints) | 840 | struct regulation_constraints *constraints) |
841 | { | 841 | { |
842 | struct regulator_ops *ops = rdev->desc->ops; | 842 | const struct regulator_ops *ops = rdev->desc->ops; |
843 | int ret; | 843 | int ret; |
844 | 844 | ||
845 | /* do we need to apply the constraint voltage */ | 845 | /* do we need to apply the constraint voltage */ |
@@ -938,7 +938,7 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, | |||
938 | static int machine_constraints_current(struct regulator_dev *rdev, | 938 | static int machine_constraints_current(struct regulator_dev *rdev, |
939 | struct regulation_constraints *constraints) | 939 | struct regulation_constraints *constraints) |
940 | { | 940 | { |
941 | struct regulator_ops *ops = rdev->desc->ops; | 941 | const struct regulator_ops *ops = rdev->desc->ops; |
942 | int ret; | 942 | int ret; |
943 | 943 | ||
944 | if (!constraints->min_uA && !constraints->max_uA) | 944 | if (!constraints->min_uA && !constraints->max_uA) |
@@ -982,7 +982,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, | |||
982 | const struct regulation_constraints *constraints) | 982 | const struct regulation_constraints *constraints) |
983 | { | 983 | { |
984 | int ret = 0; | 984 | int ret = 0; |
985 | struct regulator_ops *ops = rdev->desc->ops; | 985 | const struct regulator_ops *ops = rdev->desc->ops; |
986 | 986 | ||
987 | if (constraints) | 987 | if (constraints) |
988 | rdev->constraints = kmemdup(constraints, sizeof(*constraints), | 988 | rdev->constraints = kmemdup(constraints, sizeof(*constraints), |
@@ -1759,6 +1759,45 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) | |||
1759 | return 0; | 1759 | return 0; |
1760 | } | 1760 | } |
1761 | 1761 | ||
1762 | /** | ||
1763 | * _regulator_enable_delay - a delay helper function | ||
1764 | * @delay: time to delay in microseconds | ||
1765 | * | ||
1766 | * Delay for the requested amount of time as per the guidelines in: | ||
1767 | * | ||
1768 | * Documentation/timers/timers-howto.txt | ||
1769 | * | ||
1770 | * The assumption here is that regulators will never be enabled in | ||
1771 | * atomic context and therefore sleeping functions can be used. | ||
1772 | */ | ||
1773 | static void _regulator_enable_delay(unsigned int delay) | ||
1774 | { | ||
1775 | unsigned int ms = delay / 1000; | ||
1776 | unsigned int us = delay % 1000; | ||
1777 | |||
1778 | if (ms > 0) { | ||
1779 | /* | ||
1780 | * For small enough values, handle super-millisecond | ||
1781 | * delays in the usleep_range() call below. | ||
1782 | */ | ||
1783 | if (ms < 20) | ||
1784 | us += ms * 1000; | ||
1785 | else | ||
1786 | msleep(ms); | ||
1787 | } | ||
1788 | |||
1789 | /* | ||
1790 | * Give the scheduler some room to coalesce with any other | ||
1791 | * wakeup sources. For delays shorter than 10 us, don't even | ||
1792 | * bother setting up high-resolution timers and just busy- | ||
1793 | * loop. | ||
1794 | */ | ||
1795 | if (us >= 10) | ||
1796 | usleep_range(us, us + 100); | ||
1797 | else | ||
1798 | udelay(us); | ||
1799 | } | ||
1800 | |||
1762 | static int _regulator_do_enable(struct regulator_dev *rdev) | 1801 | static int _regulator_do_enable(struct regulator_dev *rdev) |
1763 | { | 1802 | { |
1764 | int ret, delay; | 1803 | int ret, delay; |
@@ -1774,6 +1813,31 @@ static int _regulator_do_enable(struct regulator_dev *rdev) | |||
1774 | 1813 | ||
1775 | trace_regulator_enable(rdev_get_name(rdev)); | 1814 | trace_regulator_enable(rdev_get_name(rdev)); |
1776 | 1815 | ||
1816 | if (rdev->desc->off_on_delay) { | ||
1817 | /* if needed, keep a distance of off_on_delay from last time | ||
1818 | * this regulator was disabled. | ||
1819 | */ | ||
1820 | unsigned long start_jiffy = jiffies; | ||
1821 | unsigned long intended, max_delay, remaining; | ||
1822 | |||
1823 | max_delay = usecs_to_jiffies(rdev->desc->off_on_delay); | ||
1824 | intended = rdev->last_off_jiffy + max_delay; | ||
1825 | |||
1826 | if (time_before(start_jiffy, intended)) { | ||
1827 | /* calc remaining jiffies to deal with one-time | ||
1828 | * timer wrapping. | ||
1829 | * in case of multiple timer wrapping, either it can be | ||
1830 | * detected by out-of-range remaining, or it cannot be | ||
1831 | * detected and we gets a panelty of | ||
1832 | * _regulator_enable_delay(). | ||
1833 | */ | ||
1834 | remaining = intended - start_jiffy; | ||
1835 | if (remaining <= max_delay) | ||
1836 | _regulator_enable_delay( | ||
1837 | jiffies_to_usecs(remaining)); | ||
1838 | } | ||
1839 | } | ||
1840 | |||
1777 | if (rdev->ena_pin) { | 1841 | if (rdev->ena_pin) { |
1778 | ret = regulator_ena_gpio_ctrl(rdev, true); | 1842 | ret = regulator_ena_gpio_ctrl(rdev, true); |
1779 | if (ret < 0) | 1843 | if (ret < 0) |
@@ -1792,40 +1856,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) | |||
1792 | * together. */ | 1856 | * together. */ |
1793 | trace_regulator_enable_delay(rdev_get_name(rdev)); | 1857 | trace_regulator_enable_delay(rdev_get_name(rdev)); |
1794 | 1858 | ||
1795 | /* | 1859 | _regulator_enable_delay(delay); |
1796 | * Delay for the requested amount of time as per the guidelines in: | ||
1797 | * | ||
1798 | * Documentation/timers/timers-howto.txt | ||
1799 | * | ||
1800 | * The assumption here is that regulators will never be enabled in | ||
1801 | * atomic context and therefore sleeping functions can be used. | ||
1802 | */ | ||
1803 | if (delay) { | ||
1804 | unsigned int ms = delay / 1000; | ||
1805 | unsigned int us = delay % 1000; | ||
1806 | |||
1807 | if (ms > 0) { | ||
1808 | /* | ||
1809 | * For small enough values, handle super-millisecond | ||
1810 | * delays in the usleep_range() call below. | ||
1811 | */ | ||
1812 | if (ms < 20) | ||
1813 | us += ms * 1000; | ||
1814 | else | ||
1815 | msleep(ms); | ||
1816 | } | ||
1817 | |||
1818 | /* | ||
1819 | * Give the scheduler some room to coalesce with any other | ||
1820 | * wakeup sources. For delays shorter than 10 us, don't even | ||
1821 | * bother setting up high-resolution timers and just busy- | ||
1822 | * loop. | ||
1823 | */ | ||
1824 | if (us >= 10) | ||
1825 | usleep_range(us, us + 100); | ||
1826 | else | ||
1827 | udelay(us); | ||
1828 | } | ||
1829 | 1860 | ||
1830 | trace_regulator_enable_complete(rdev_get_name(rdev)); | 1861 | trace_regulator_enable_complete(rdev_get_name(rdev)); |
1831 | 1862 | ||
@@ -1919,6 +1950,12 @@ static int _regulator_do_disable(struct regulator_dev *rdev) | |||
1919 | return ret; | 1950 | return ret; |
1920 | } | 1951 | } |
1921 | 1952 | ||
1953 | /* cares about last_off_jiffy only if off_on_delay is required by | ||
1954 | * device. | ||
1955 | */ | ||
1956 | if (rdev->desc->off_on_delay) | ||
1957 | rdev->last_off_jiffy = jiffies; | ||
1958 | |||
1922 | trace_regulator_disable_complete(rdev_get_name(rdev)); | 1959 | trace_regulator_disable_complete(rdev_get_name(rdev)); |
1923 | 1960 | ||
1924 | return 0; | 1961 | return 0; |
@@ -2208,9 +2245,9 @@ EXPORT_SYMBOL_GPL(regulator_count_voltages); | |||
2208 | */ | 2245 | */ |
2209 | int regulator_list_voltage(struct regulator *regulator, unsigned selector) | 2246 | int regulator_list_voltage(struct regulator *regulator, unsigned selector) |
2210 | { | 2247 | { |
2211 | struct regulator_dev *rdev = regulator->rdev; | 2248 | struct regulator_dev *rdev = regulator->rdev; |
2212 | struct regulator_ops *ops = rdev->desc->ops; | 2249 | const struct regulator_ops *ops = rdev->desc->ops; |
2213 | int ret; | 2250 | int ret; |
2214 | 2251 | ||
2215 | if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector) | 2252 | if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector) |
2216 | return rdev->desc->fixed_uV; | 2253 | return rdev->desc->fixed_uV; |
@@ -2270,8 +2307,8 @@ int regulator_get_hardware_vsel_register(struct regulator *regulator, | |||
2270 | unsigned *vsel_reg, | 2307 | unsigned *vsel_reg, |
2271 | unsigned *vsel_mask) | 2308 | unsigned *vsel_mask) |
2272 | { | 2309 | { |
2273 | struct regulator_dev *rdev = regulator->rdev; | 2310 | struct regulator_dev *rdev = regulator->rdev; |
2274 | struct regulator_ops *ops = rdev->desc->ops; | 2311 | const struct regulator_ops *ops = rdev->desc->ops; |
2275 | 2312 | ||
2276 | if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap) | 2313 | if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap) |
2277 | return -EOPNOTSUPP; | 2314 | return -EOPNOTSUPP; |
@@ -2297,8 +2334,8 @@ EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register); | |||
2297 | int regulator_list_hardware_vsel(struct regulator *regulator, | 2334 | int regulator_list_hardware_vsel(struct regulator *regulator, |
2298 | unsigned selector) | 2335 | unsigned selector) |
2299 | { | 2336 | { |
2300 | struct regulator_dev *rdev = regulator->rdev; | 2337 | struct regulator_dev *rdev = regulator->rdev; |
2301 | struct regulator_ops *ops = rdev->desc->ops; | 2338 | const struct regulator_ops *ops = rdev->desc->ops; |
2302 | 2339 | ||
2303 | if (selector >= rdev->desc->n_voltages) | 2340 | if (selector >= rdev->desc->n_voltages) |
2304 | return -EINVAL; | 2341 | return -EINVAL; |
@@ -2369,6 +2406,55 @@ int regulator_is_supported_voltage(struct regulator *regulator, | |||
2369 | } | 2406 | } |
2370 | EXPORT_SYMBOL_GPL(regulator_is_supported_voltage); | 2407 | EXPORT_SYMBOL_GPL(regulator_is_supported_voltage); |
2371 | 2408 | ||
2409 | static int _regulator_call_set_voltage(struct regulator_dev *rdev, | ||
2410 | int min_uV, int max_uV, | ||
2411 | unsigned *selector) | ||
2412 | { | ||
2413 | struct pre_voltage_change_data data; | ||
2414 | int ret; | ||
2415 | |||
2416 | data.old_uV = _regulator_get_voltage(rdev); | ||
2417 | data.min_uV = min_uV; | ||
2418 | data.max_uV = max_uV; | ||
2419 | ret = _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_VOLTAGE_CHANGE, | ||
2420 | &data); | ||
2421 | if (ret & NOTIFY_STOP_MASK) | ||
2422 | return -EINVAL; | ||
2423 | |||
2424 | ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, selector); | ||
2425 | if (ret >= 0) | ||
2426 | return ret; | ||
2427 | |||
2428 | _notifier_call_chain(rdev, REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE, | ||
2429 | (void *)data.old_uV); | ||
2430 | |||
2431 | return ret; | ||
2432 | } | ||
2433 | |||
2434 | static int _regulator_call_set_voltage_sel(struct regulator_dev *rdev, | ||
2435 | int uV, unsigned selector) | ||
2436 | { | ||
2437 | struct pre_voltage_change_data data; | ||
2438 | int ret; | ||
2439 | |||
2440 | data.old_uV = _regulator_get_voltage(rdev); | ||
2441 | data.min_uV = uV; | ||
2442 | data.max_uV = uV; | ||
2443 | ret = _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_VOLTAGE_CHANGE, | ||
2444 | &data); | ||
2445 | if (ret & NOTIFY_STOP_MASK) | ||
2446 | return -EINVAL; | ||
2447 | |||
2448 | ret = rdev->desc->ops->set_voltage_sel(rdev, selector); | ||
2449 | if (ret >= 0) | ||
2450 | return ret; | ||
2451 | |||
2452 | _notifier_call_chain(rdev, REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE, | ||
2453 | (void *)data.old_uV); | ||
2454 | |||
2455 | return ret; | ||
2456 | } | ||
2457 | |||
2372 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, | 2458 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, |
2373 | int min_uV, int max_uV) | 2459 | int min_uV, int max_uV) |
2374 | { | 2460 | { |
@@ -2396,8 +2482,8 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
2396 | } | 2482 | } |
2397 | 2483 | ||
2398 | if (rdev->desc->ops->set_voltage) { | 2484 | if (rdev->desc->ops->set_voltage) { |
2399 | ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, | 2485 | ret = _regulator_call_set_voltage(rdev, min_uV, max_uV, |
2400 | &selector); | 2486 | &selector); |
2401 | 2487 | ||
2402 | if (ret >= 0) { | 2488 | if (ret >= 0) { |
2403 | if (rdev->desc->ops->list_voltage) | 2489 | if (rdev->desc->ops->list_voltage) |
@@ -2432,8 +2518,8 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
2432 | if (old_selector == selector) | 2518 | if (old_selector == selector) |
2433 | ret = 0; | 2519 | ret = 0; |
2434 | else | 2520 | else |
2435 | ret = rdev->desc->ops->set_voltage_sel( | 2521 | ret = _regulator_call_set_voltage_sel( |
2436 | rdev, ret); | 2522 | rdev, best_val, selector); |
2437 | } else { | 2523 | } else { |
2438 | ret = -EINVAL; | 2524 | ret = -EINVAL; |
2439 | } | 2525 | } |
@@ -2572,8 +2658,8 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage); | |||
2572 | int regulator_set_voltage_time(struct regulator *regulator, | 2658 | int regulator_set_voltage_time(struct regulator *regulator, |
2573 | int old_uV, int new_uV) | 2659 | int old_uV, int new_uV) |
2574 | { | 2660 | { |
2575 | struct regulator_dev *rdev = regulator->rdev; | 2661 | struct regulator_dev *rdev = regulator->rdev; |
2576 | struct regulator_ops *ops = rdev->desc->ops; | 2662 | const struct regulator_ops *ops = rdev->desc->ops; |
2577 | int old_sel = -1; | 2663 | int old_sel = -1; |
2578 | int new_sel = -1; | 2664 | int new_sel = -1; |
2579 | int voltage; | 2665 | int voltage; |
@@ -3079,11 +3165,11 @@ EXPORT_SYMBOL_GPL(regulator_unregister_notifier); | |||
3079 | /* notify regulator consumers and downstream regulator consumers. | 3165 | /* notify regulator consumers and downstream regulator consumers. |
3080 | * Note mutex must be held by caller. | 3166 | * Note mutex must be held by caller. |
3081 | */ | 3167 | */ |
3082 | static void _notifier_call_chain(struct regulator_dev *rdev, | 3168 | static int _notifier_call_chain(struct regulator_dev *rdev, |
3083 | unsigned long event, void *data) | 3169 | unsigned long event, void *data) |
3084 | { | 3170 | { |
3085 | /* call rdev chain first */ | 3171 | /* call rdev chain first */ |
3086 | blocking_notifier_call_chain(&rdev->notifier, event, data); | 3172 | return blocking_notifier_call_chain(&rdev->notifier, event, data); |
3087 | } | 3173 | } |
3088 | 3174 | ||
3089 | /** | 3175 | /** |
@@ -3336,9 +3422,9 @@ EXPORT_SYMBOL_GPL(regulator_mode_to_status); | |||
3336 | */ | 3422 | */ |
3337 | static int add_regulator_attributes(struct regulator_dev *rdev) | 3423 | static int add_regulator_attributes(struct regulator_dev *rdev) |
3338 | { | 3424 | { |
3339 | struct device *dev = &rdev->dev; | 3425 | struct device *dev = &rdev->dev; |
3340 | struct regulator_ops *ops = rdev->desc->ops; | 3426 | const struct regulator_ops *ops = rdev->desc->ops; |
3341 | int status = 0; | 3427 | int status = 0; |
3342 | 3428 | ||
3343 | /* some attributes need specific methods to be displayed */ | 3429 | /* some attributes need specific methods to be displayed */ |
3344 | if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || | 3430 | if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || |
@@ -3516,12 +3602,17 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3516 | return ERR_PTR(-EINVAL); | 3602 | return ERR_PTR(-EINVAL); |
3517 | } | 3603 | } |
3518 | 3604 | ||
3519 | init_data = config->init_data; | ||
3520 | |||
3521 | rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); | 3605 | rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); |
3522 | if (rdev == NULL) | 3606 | if (rdev == NULL) |
3523 | return ERR_PTR(-ENOMEM); | 3607 | return ERR_PTR(-ENOMEM); |
3524 | 3608 | ||
3609 | init_data = regulator_of_get_init_data(dev, regulator_desc, | ||
3610 | &rdev->dev.of_node); | ||
3611 | if (!init_data) { | ||
3612 | init_data = config->init_data; | ||
3613 | rdev->dev.of_node = of_node_get(config->of_node); | ||
3614 | } | ||
3615 | |||
3525 | mutex_lock(®ulator_list_mutex); | 3616 | mutex_lock(®ulator_list_mutex); |
3526 | 3617 | ||
3527 | mutex_init(&rdev->mutex); | 3618 | mutex_init(&rdev->mutex); |
@@ -3548,7 +3639,6 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3548 | 3639 | ||
3549 | /* register with sysfs */ | 3640 | /* register with sysfs */ |
3550 | rdev->dev.class = ®ulator_class; | 3641 | rdev->dev.class = ®ulator_class; |
3551 | rdev->dev.of_node = of_node_get(config->of_node); | ||
3552 | rdev->dev.parent = dev; | 3642 | rdev->dev.parent = dev; |
3553 | dev_set_name(&rdev->dev, "regulator.%d", | 3643 | dev_set_name(&rdev->dev, "regulator.%d", |
3554 | atomic_inc_return(®ulator_no) - 1); | 3644 | atomic_inc_return(®ulator_no) - 1); |
@@ -3905,7 +3995,7 @@ core_initcall(regulator_init); | |||
3905 | static int __init regulator_init_complete(void) | 3995 | static int __init regulator_init_complete(void) |
3906 | { | 3996 | { |
3907 | struct regulator_dev *rdev; | 3997 | struct regulator_dev *rdev; |
3908 | struct regulator_ops *ops; | 3998 | const struct regulator_ops *ops; |
3909 | struct regulation_constraints *c; | 3999 | struct regulation_constraints *c; |
3910 | int enabled, ret; | 4000 | int enabled, ret; |
3911 | 4001 | ||
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 1482adafa1ad..c78d2106d6cb 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * da9211-regulator.c - Regulator device driver for DA9211 | 2 | * da9211-regulator.c - Regulator device driver for DA9211/DA9213 |
3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. | 3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
@@ -24,9 +24,14 @@ | |||
24 | #include <linux/regmap.h> | 24 | #include <linux/regmap.h> |
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/regulator/of_regulator.h> | ||
27 | #include <linux/regulator/da9211.h> | 28 | #include <linux/regulator/da9211.h> |
28 | #include "da9211-regulator.h" | 29 | #include "da9211-regulator.h" |
29 | 30 | ||
31 | /* DEVICE IDs */ | ||
32 | #define DA9211_DEVICE_ID 0x22 | ||
33 | #define DA9213_DEVICE_ID 0x23 | ||
34 | |||
30 | #define DA9211_BUCK_MODE_SLEEP 1 | 35 | #define DA9211_BUCK_MODE_SLEEP 1 |
31 | #define DA9211_BUCK_MODE_SYNC 2 | 36 | #define DA9211_BUCK_MODE_SYNC 2 |
32 | #define DA9211_BUCK_MODE_AUTO 3 | 37 | #define DA9211_BUCK_MODE_AUTO 3 |
@@ -42,6 +47,7 @@ struct da9211 { | |||
42 | struct regulator_dev *rdev[DA9211_MAX_REGULATORS]; | 47 | struct regulator_dev *rdev[DA9211_MAX_REGULATORS]; |
43 | int num_regulator; | 48 | int num_regulator; |
44 | int chip_irq; | 49 | int chip_irq; |
50 | int chip_id; | ||
45 | }; | 51 | }; |
46 | 52 | ||
47 | static const struct regmap_range_cfg da9211_regmap_range[] = { | 53 | static const struct regmap_range_cfg da9211_regmap_range[] = { |
@@ -52,14 +58,14 @@ static const struct regmap_range_cfg da9211_regmap_range[] = { | |||
52 | .window_start = 0, | 58 | .window_start = 0, |
53 | .window_len = 256, | 59 | .window_len = 256, |
54 | .range_min = 0, | 60 | .range_min = 0, |
55 | .range_max = 2*256, | 61 | .range_max = 5*128, |
56 | }, | 62 | }, |
57 | }; | 63 | }; |
58 | 64 | ||
59 | static const struct regmap_config da9211_regmap_config = { | 65 | static const struct regmap_config da9211_regmap_config = { |
60 | .reg_bits = 8, | 66 | .reg_bits = 8, |
61 | .val_bits = 8, | 67 | .val_bits = 8, |
62 | .max_register = 2 * 256, | 68 | .max_register = 5 * 128, |
63 | .ranges = da9211_regmap_range, | 69 | .ranges = da9211_regmap_range, |
64 | .num_ranges = ARRAY_SIZE(da9211_regmap_range), | 70 | .num_ranges = ARRAY_SIZE(da9211_regmap_range), |
65 | }; | 71 | }; |
@@ -69,11 +75,20 @@ static const struct regmap_config da9211_regmap_config = { | |||
69 | #define DA9211_MAX_MV 1570 | 75 | #define DA9211_MAX_MV 1570 |
70 | #define DA9211_STEP_MV 10 | 76 | #define DA9211_STEP_MV 10 |
71 | 77 | ||
72 | /* Current limits for buck (uA) indices corresponds with register values */ | 78 | /* Current limits for DA9211 buck (uA) indices |
79 | * corresponds with register values | ||
80 | */ | ||
73 | static const int da9211_current_limits[] = { | 81 | static const int da9211_current_limits[] = { |
74 | 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, | 82 | 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, |
75 | 3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000 | 83 | 3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000 |
76 | }; | 84 | }; |
85 | /* Current limits for DA9213 buck (uA) indices | ||
86 | * corresponds with register values | ||
87 | */ | ||
88 | static const int da9213_current_limits[] = { | ||
89 | 3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, | ||
90 | 4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000 | ||
91 | }; | ||
77 | 92 | ||
78 | static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev) | 93 | static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev) |
79 | { | 94 | { |
@@ -129,12 +144,26 @@ static int da9211_set_current_limit(struct regulator_dev *rdev, int min, | |||
129 | { | 144 | { |
130 | int id = rdev_get_id(rdev); | 145 | int id = rdev_get_id(rdev); |
131 | struct da9211 *chip = rdev_get_drvdata(rdev); | 146 | struct da9211 *chip = rdev_get_drvdata(rdev); |
132 | int i; | 147 | int i, max_size; |
148 | const int *current_limits; | ||
149 | |||
150 | switch (chip->chip_id) { | ||
151 | case DA9211: | ||
152 | current_limits = da9211_current_limits; | ||
153 | max_size = ARRAY_SIZE(da9211_current_limits)-1; | ||
154 | break; | ||
155 | case DA9213: | ||
156 | current_limits = da9213_current_limits; | ||
157 | max_size = ARRAY_SIZE(da9213_current_limits)-1; | ||
158 | break; | ||
159 | default: | ||
160 | return -EINVAL; | ||
161 | } | ||
133 | 162 | ||
134 | /* search for closest to maximum */ | 163 | /* search for closest to maximum */ |
135 | for (i = ARRAY_SIZE(da9211_current_limits)-1; i >= 0; i--) { | 164 | for (i = max_size; i >= 0; i--) { |
136 | if (min <= da9211_current_limits[i] && | 165 | if (min <= current_limits[i] && |
137 | max >= da9211_current_limits[i]) { | 166 | max >= current_limits[i]) { |
138 | return regmap_update_bits(chip->regmap, | 167 | return regmap_update_bits(chip->regmap, |
139 | DA9211_REG_BUCK_ILIM, | 168 | DA9211_REG_BUCK_ILIM, |
140 | (0x0F << id*4), (i << id*4)); | 169 | (0x0F << id*4), (i << id*4)); |
@@ -150,14 +179,28 @@ static int da9211_get_current_limit(struct regulator_dev *rdev) | |||
150 | struct da9211 *chip = rdev_get_drvdata(rdev); | 179 | struct da9211 *chip = rdev_get_drvdata(rdev); |
151 | unsigned int data; | 180 | unsigned int data; |
152 | int ret; | 181 | int ret; |
182 | const int *current_limits; | ||
183 | |||
184 | switch (chip->chip_id) { | ||
185 | case DA9211: | ||
186 | current_limits = da9211_current_limits; | ||
187 | break; | ||
188 | case DA9213: | ||
189 | current_limits = da9213_current_limits; | ||
190 | break; | ||
191 | default: | ||
192 | return -EINVAL; | ||
193 | } | ||
153 | 194 | ||
154 | ret = regmap_read(chip->regmap, DA9211_REG_BUCK_ILIM, &data); | 195 | ret = regmap_read(chip->regmap, DA9211_REG_BUCK_ILIM, &data); |
155 | if (ret < 0) | 196 | if (ret < 0) |
156 | return ret; | 197 | return ret; |
157 | 198 | ||
158 | /* select one of 16 values: 0000 (2000mA) to 1111 (5000mA) */ | 199 | /* select one of 16 values: 0000 (2000mA or 3000mA) |
200 | * to 1111 (5000mA or 6000mA). | ||
201 | */ | ||
159 | data = (data >> id*4) & 0x0F; | 202 | data = (data >> id*4) & 0x0F; |
160 | return da9211_current_limits[data]; | 203 | return current_limits[data]; |
161 | } | 204 | } |
162 | 205 | ||
163 | static struct regulator_ops da9211_buck_ops = { | 206 | static struct regulator_ops da9211_buck_ops = { |
@@ -194,6 +237,59 @@ static struct regulator_desc da9211_regulators[] = { | |||
194 | DA9211_BUCK(BUCKB), | 237 | DA9211_BUCK(BUCKB), |
195 | }; | 238 | }; |
196 | 239 | ||
240 | #ifdef CONFIG_OF | ||
241 | static struct of_regulator_match da9211_matches[] = { | ||
242 | [DA9211_ID_BUCKA] = { .name = "BUCKA" }, | ||
243 | [DA9211_ID_BUCKB] = { .name = "BUCKB" }, | ||
244 | }; | ||
245 | |||
246 | static struct da9211_pdata *da9211_parse_regulators_dt( | ||
247 | struct device *dev) | ||
248 | { | ||
249 | struct da9211_pdata *pdata; | ||
250 | struct device_node *node; | ||
251 | int i, num, n; | ||
252 | |||
253 | node = of_get_child_by_name(dev->of_node, "regulators"); | ||
254 | if (!node) { | ||
255 | dev_err(dev, "regulators node not found\n"); | ||
256 | return ERR_PTR(-ENODEV); | ||
257 | } | ||
258 | |||
259 | num = of_regulator_match(dev, node, da9211_matches, | ||
260 | ARRAY_SIZE(da9211_matches)); | ||
261 | of_node_put(node); | ||
262 | if (num < 0) { | ||
263 | dev_err(dev, "Failed to match regulators\n"); | ||
264 | return ERR_PTR(-EINVAL); | ||
265 | } | ||
266 | |||
267 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
268 | if (!pdata) | ||
269 | return ERR_PTR(-ENOMEM); | ||
270 | |||
271 | pdata->num_buck = num; | ||
272 | |||
273 | n = 0; | ||
274 | for (i = 0; i < ARRAY_SIZE(da9211_matches); i++) { | ||
275 | if (!da9211_matches[i].init_data) | ||
276 | continue; | ||
277 | |||
278 | pdata->init_data[n] = da9211_matches[i].init_data; | ||
279 | |||
280 | n++; | ||
281 | } | ||
282 | |||
283 | return pdata; | ||
284 | } | ||
285 | #else | ||
286 | static struct da9211_pdata *da9211_parse_regulators_dt( | ||
287 | struct device *dev) | ||
288 | { | ||
289 | return ERR_PTR(-ENODEV); | ||
290 | } | ||
291 | #endif | ||
292 | |||
197 | static irqreturn_t da9211_irq_handler(int irq, void *data) | 293 | static irqreturn_t da9211_irq_handler(int irq, void *data) |
198 | { | 294 | { |
199 | struct da9211 *chip = data; | 295 | struct da9211 *chip = data; |
@@ -264,13 +360,11 @@ static int da9211_regulator_init(struct da9211 *chip) | |||
264 | } | 360 | } |
265 | 361 | ||
266 | for (i = 0; i < chip->num_regulator; i++) { | 362 | for (i = 0; i < chip->num_regulator; i++) { |
267 | if (chip->pdata) | 363 | config.init_data = chip->pdata->init_data[i]; |
268 | config.init_data = | ||
269 | &(chip->pdata->init_data[i]); | ||
270 | |||
271 | config.dev = chip->dev; | 364 | config.dev = chip->dev; |
272 | config.driver_data = chip; | 365 | config.driver_data = chip; |
273 | config.regmap = chip->regmap; | 366 | config.regmap = chip->regmap; |
367 | config.of_node = chip->dev->of_node; | ||
274 | 368 | ||
275 | chip->rdev[i] = devm_regulator_register(chip->dev, | 369 | chip->rdev[i] = devm_regulator_register(chip->dev, |
276 | &da9211_regulators[i], &config); | 370 | &da9211_regulators[i], &config); |
@@ -282,7 +376,7 @@ static int da9211_regulator_init(struct da9211 *chip) | |||
282 | 376 | ||
283 | if (chip->chip_irq != 0) { | 377 | if (chip->chip_irq != 0) { |
284 | ret = regmap_update_bits(chip->regmap, | 378 | ret = regmap_update_bits(chip->regmap, |
285 | DA9211_REG_MASK_B, DA9211_M_OV_CURR_A << i, 1); | 379 | DA9211_REG_MASK_B, DA9211_M_OV_CURR_A << i, 0); |
286 | if (ret < 0) { | 380 | if (ret < 0) { |
287 | dev_err(chip->dev, | 381 | dev_err(chip->dev, |
288 | "Failed to update mask reg: %d\n", ret); | 382 | "Failed to update mask reg: %d\n", ret); |
@@ -293,6 +387,7 @@ static int da9211_regulator_init(struct da9211 *chip) | |||
293 | 387 | ||
294 | return 0; | 388 | return 0; |
295 | } | 389 | } |
390 | |||
296 | /* | 391 | /* |
297 | * I2C driver interface functions | 392 | * I2C driver interface functions |
298 | */ | 393 | */ |
@@ -301,14 +396,17 @@ static int da9211_i2c_probe(struct i2c_client *i2c, | |||
301 | { | 396 | { |
302 | struct da9211 *chip; | 397 | struct da9211 *chip; |
303 | int error, ret; | 398 | int error, ret; |
399 | unsigned int data; | ||
304 | 400 | ||
305 | chip = devm_kzalloc(&i2c->dev, sizeof(struct da9211), GFP_KERNEL); | 401 | chip = devm_kzalloc(&i2c->dev, sizeof(struct da9211), GFP_KERNEL); |
402 | if (!chip) | ||
403 | return -ENOMEM; | ||
306 | 404 | ||
307 | chip->dev = &i2c->dev; | 405 | chip->dev = &i2c->dev; |
308 | chip->regmap = devm_regmap_init_i2c(i2c, &da9211_regmap_config); | 406 | chip->regmap = devm_regmap_init_i2c(i2c, &da9211_regmap_config); |
309 | if (IS_ERR(chip->regmap)) { | 407 | if (IS_ERR(chip->regmap)) { |
310 | error = PTR_ERR(chip->regmap); | 408 | error = PTR_ERR(chip->regmap); |
311 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 409 | dev_err(chip->dev, "Failed to allocate register map: %d\n", |
312 | error); | 410 | error); |
313 | return error; | 411 | return error; |
314 | } | 412 | } |
@@ -316,11 +414,33 @@ static int da9211_i2c_probe(struct i2c_client *i2c, | |||
316 | i2c_set_clientdata(i2c, chip); | 414 | i2c_set_clientdata(i2c, chip); |
317 | 415 | ||
318 | chip->pdata = i2c->dev.platform_data; | 416 | chip->pdata = i2c->dev.platform_data; |
319 | if (!chip->pdata) { | 417 | |
320 | dev_err(&i2c->dev, "No platform init data supplied\n"); | 418 | ret = regmap_read(chip->regmap, DA9211_REG_DEVICE_ID, &data); |
419 | if (ret < 0) { | ||
420 | dev_err(chip->dev, "Failed to read DEVICE_ID reg: %d\n", ret); | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | switch (data) { | ||
425 | case DA9211_DEVICE_ID: | ||
426 | chip->chip_id = DA9211; | ||
427 | break; | ||
428 | case DA9213_DEVICE_ID: | ||
429 | chip->chip_id = DA9213; | ||
430 | break; | ||
431 | default: | ||
432 | dev_err(chip->dev, "Unsupported device id = 0x%x.\n", data); | ||
321 | return -ENODEV; | 433 | return -ENODEV; |
322 | } | 434 | } |
323 | 435 | ||
436 | if (!chip->pdata) | ||
437 | chip->pdata = da9211_parse_regulators_dt(chip->dev); | ||
438 | |||
439 | if (IS_ERR(chip->pdata)) { | ||
440 | dev_err(chip->dev, "No regulators defined for the platform\n"); | ||
441 | return PTR_ERR(chip->pdata); | ||
442 | } | ||
443 | |||
324 | chip->chip_irq = i2c->irq; | 444 | chip->chip_irq = i2c->irq; |
325 | 445 | ||
326 | if (chip->chip_irq != 0) { | 446 | if (chip->chip_irq != 0) { |
@@ -340,22 +460,32 @@ static int da9211_i2c_probe(struct i2c_client *i2c, | |||
340 | ret = da9211_regulator_init(chip); | 460 | ret = da9211_regulator_init(chip); |
341 | 461 | ||
342 | if (ret < 0) | 462 | if (ret < 0) |
343 | dev_err(&i2c->dev, "Failed to initialize regulator: %d\n", ret); | 463 | dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); |
344 | 464 | ||
345 | return ret; | 465 | return ret; |
346 | } | 466 | } |
347 | 467 | ||
348 | static const struct i2c_device_id da9211_i2c_id[] = { | 468 | static const struct i2c_device_id da9211_i2c_id[] = { |
349 | {"da9211", 0}, | 469 | {"da9211", DA9211}, |
470 | {"da9213", DA9213}, | ||
350 | {}, | 471 | {}, |
351 | }; | 472 | }; |
352 | |||
353 | MODULE_DEVICE_TABLE(i2c, da9211_i2c_id); | 473 | MODULE_DEVICE_TABLE(i2c, da9211_i2c_id); |
354 | 474 | ||
475 | #ifdef CONFIG_OF | ||
476 | static const struct of_device_id da9211_dt_ids[] = { | ||
477 | { .compatible = "dlg,da9211", .data = &da9211_i2c_id[0] }, | ||
478 | { .compatible = "dlg,da9213", .data = &da9211_i2c_id[1] }, | ||
479 | {}, | ||
480 | }; | ||
481 | MODULE_DEVICE_TABLE(of, da9211_dt_ids); | ||
482 | #endif | ||
483 | |||
355 | static struct i2c_driver da9211_regulator_driver = { | 484 | static struct i2c_driver da9211_regulator_driver = { |
356 | .driver = { | 485 | .driver = { |
357 | .name = "da9211", | 486 | .name = "da9211", |
358 | .owner = THIS_MODULE, | 487 | .owner = THIS_MODULE, |
488 | .of_match_table = of_match_ptr(da9211_dt_ids), | ||
359 | }, | 489 | }, |
360 | .probe = da9211_i2c_probe, | 490 | .probe = da9211_i2c_probe, |
361 | .id_table = da9211_i2c_id, | 491 | .id_table = da9211_i2c_id, |
@@ -364,5 +494,5 @@ static struct i2c_driver da9211_regulator_driver = { | |||
364 | module_i2c_driver(da9211_regulator_driver); | 494 | module_i2c_driver(da9211_regulator_driver); |
365 | 495 | ||
366 | MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>"); | 496 | MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>"); |
367 | MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211"); | 497 | MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211/DA9213"); |
368 | MODULE_LICENSE("GPL v2"); | 498 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h index 88b1769e8058..93fa9df2721c 100644 --- a/drivers/regulator/da9211-regulator.h +++ b/drivers/regulator/da9211-regulator.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * da9211-regulator.h - Regulator definitions for DA9211 | 2 | * da9211-regulator.h - Regulator definitions for DA9211/DA9213 |
3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. | 3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
@@ -53,12 +53,15 @@ | |||
53 | /* BUCK Phase Selection*/ | 53 | /* BUCK Phase Selection*/ |
54 | #define DA9211_REG_CONFIG_E 0x147 | 54 | #define DA9211_REG_CONFIG_E 0x147 |
55 | 55 | ||
56 | /* Device ID */ | ||
57 | #define DA9211_REG_DEVICE_ID 0x201 | ||
58 | |||
56 | /* | 59 | /* |
57 | * Registers bits | 60 | * Registers bits |
58 | */ | 61 | */ |
59 | /* DA9211_REG_PAGE_CON (addr=0x00) */ | 62 | /* DA9211_REG_PAGE_CON (addr=0x00) */ |
60 | #define DA9211_REG_PAGE_SHIFT 1 | 63 | #define DA9211_REG_PAGE_SHIFT 1 |
61 | #define DA9211_REG_PAGE_MASK 0x02 | 64 | #define DA9211_REG_PAGE_MASK 0x06 |
62 | /* On I2C registers 0x00 - 0xFF */ | 65 | /* On I2C registers 0x00 - 0xFF */ |
63 | #define DA9211_REG_PAGE0 0 | 66 | #define DA9211_REG_PAGE0 0 |
64 | /* On I2C registers 0x100 - 0x1FF */ | 67 | /* On I2C registers 0x100 - 0x1FF */ |
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 714fd9a89aa1..f8e4257aef92 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/regulator/driver.h> | 19 | #include <linux/regulator/driver.h> |
20 | #include <linux/regulator/machine.h> | 20 | #include <linux/regulator/machine.h> |
21 | #include <linux/regulator/of_regulator.h> | ||
22 | #include <linux/of_device.h> | ||
21 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
22 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
23 | #include <linux/regmap.h> | 25 | #include <linux/regmap.h> |
@@ -50,6 +52,11 @@ | |||
50 | 52 | ||
51 | #define FAN53555_NVOLTAGES 64 /* Numbers of voltages */ | 53 | #define FAN53555_NVOLTAGES 64 /* Numbers of voltages */ |
52 | 54 | ||
55 | enum fan53555_vendor { | ||
56 | FAN53555_VENDOR_FAIRCHILD = 0, | ||
57 | FAN53555_VENDOR_SILERGY, | ||
58 | }; | ||
59 | |||
53 | /* IC Type */ | 60 | /* IC Type */ |
54 | enum { | 61 | enum { |
55 | FAN53555_CHIP_ID_00 = 0, | 62 | FAN53555_CHIP_ID_00 = 0, |
@@ -60,7 +67,12 @@ enum { | |||
60 | FAN53555_CHIP_ID_05, | 67 | FAN53555_CHIP_ID_05, |
61 | }; | 68 | }; |
62 | 69 | ||
70 | enum { | ||
71 | SILERGY_SYR82X = 8, | ||
72 | }; | ||
73 | |||
63 | struct fan53555_device_info { | 74 | struct fan53555_device_info { |
75 | enum fan53555_vendor vendor; | ||
64 | struct regmap *regmap; | 76 | struct regmap *regmap; |
65 | struct device *dev; | 77 | struct device *dev; |
66 | struct regulator_desc desc; | 78 | struct regulator_desc desc; |
@@ -135,6 +147,38 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev) | |||
135 | return REGULATOR_MODE_NORMAL; | 147 | return REGULATOR_MODE_NORMAL; |
136 | } | 148 | } |
137 | 149 | ||
150 | static int slew_rates[] = { | ||
151 | 64000, | ||
152 | 32000, | ||
153 | 16000, | ||
154 | 8000, | ||
155 | 4000, | ||
156 | 2000, | ||
157 | 1000, | ||
158 | 500, | ||
159 | }; | ||
160 | |||
161 | static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp) | ||
162 | { | ||
163 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | ||
164 | int regval = -1, i; | ||
165 | |||
166 | for (i = 0; i < ARRAY_SIZE(slew_rates); i++) { | ||
167 | if (ramp <= slew_rates[i]) | ||
168 | regval = i; | ||
169 | else | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | if (regval < 0) { | ||
174 | dev_err(di->dev, "unsupported ramp value %d\n", ramp); | ||
175 | return -EINVAL; | ||
176 | } | ||
177 | |||
178 | return regmap_update_bits(di->regmap, FAN53555_CONTROL, | ||
179 | CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT); | ||
180 | } | ||
181 | |||
138 | static struct regulator_ops fan53555_regulator_ops = { | 182 | static struct regulator_ops fan53555_regulator_ops = { |
139 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 183 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
140 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 184 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
@@ -146,8 +190,50 @@ static struct regulator_ops fan53555_regulator_ops = { | |||
146 | .is_enabled = regulator_is_enabled_regmap, | 190 | .is_enabled = regulator_is_enabled_regmap, |
147 | .set_mode = fan53555_set_mode, | 191 | .set_mode = fan53555_set_mode, |
148 | .get_mode = fan53555_get_mode, | 192 | .get_mode = fan53555_get_mode, |
193 | .set_ramp_delay = fan53555_set_ramp, | ||
149 | }; | 194 | }; |
150 | 195 | ||
196 | static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di) | ||
197 | { | ||
198 | /* Init voltage range and step */ | ||
199 | switch (di->chip_id) { | ||
200 | case FAN53555_CHIP_ID_00: | ||
201 | case FAN53555_CHIP_ID_01: | ||
202 | case FAN53555_CHIP_ID_03: | ||
203 | case FAN53555_CHIP_ID_05: | ||
204 | di->vsel_min = 600000; | ||
205 | di->vsel_step = 10000; | ||
206 | break; | ||
207 | case FAN53555_CHIP_ID_04: | ||
208 | di->vsel_min = 603000; | ||
209 | di->vsel_step = 12826; | ||
210 | break; | ||
211 | default: | ||
212 | dev_err(di->dev, | ||
213 | "Chip ID %d not supported!\n", di->chip_id); | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di) | ||
221 | { | ||
222 | /* Init voltage range and step */ | ||
223 | switch (di->chip_id) { | ||
224 | case SILERGY_SYR82X: | ||
225 | di->vsel_min = 712500; | ||
226 | di->vsel_step = 12500; | ||
227 | break; | ||
228 | default: | ||
229 | dev_err(di->dev, | ||
230 | "Chip ID %d not supported!\n", di->chip_id); | ||
231 | return -EINVAL; | ||
232 | } | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
151 | /* For 00,01,03,05 options: | 237 | /* For 00,01,03,05 options: |
152 | * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V. | 238 | * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V. |
153 | * For 04 option: | 239 | * For 04 option: |
@@ -156,7 +242,7 @@ static struct regulator_ops fan53555_regulator_ops = { | |||
156 | static int fan53555_device_setup(struct fan53555_device_info *di, | 242 | static int fan53555_device_setup(struct fan53555_device_info *di, |
157 | struct fan53555_platform_data *pdata) | 243 | struct fan53555_platform_data *pdata) |
158 | { | 244 | { |
159 | unsigned int reg, data, mask; | 245 | int ret = 0; |
160 | 246 | ||
161 | /* Setup voltage control register */ | 247 | /* Setup voltage control register */ |
162 | switch (pdata->sleep_vsel_id) { | 248 | switch (pdata->sleep_vsel_id) { |
@@ -172,33 +258,20 @@ static int fan53555_device_setup(struct fan53555_device_info *di, | |||
172 | dev_err(di->dev, "Invalid VSEL ID!\n"); | 258 | dev_err(di->dev, "Invalid VSEL ID!\n"); |
173 | return -EINVAL; | 259 | return -EINVAL; |
174 | } | 260 | } |
175 | /* Init voltage range and step */ | 261 | |
176 | switch (di->chip_id) { | 262 | switch (di->vendor) { |
177 | case FAN53555_CHIP_ID_00: | 263 | case FAN53555_VENDOR_FAIRCHILD: |
178 | case FAN53555_CHIP_ID_01: | 264 | ret = fan53555_voltages_setup_fairchild(di); |
179 | case FAN53555_CHIP_ID_03: | ||
180 | case FAN53555_CHIP_ID_05: | ||
181 | di->vsel_min = 600000; | ||
182 | di->vsel_step = 10000; | ||
183 | break; | 265 | break; |
184 | case FAN53555_CHIP_ID_04: | 266 | case FAN53555_VENDOR_SILERGY: |
185 | di->vsel_min = 603000; | 267 | ret = fan53555_voltages_setup_silergy(di); |
186 | di->vsel_step = 12826; | ||
187 | break; | 268 | break; |
188 | default: | 269 | default: |
189 | dev_err(di->dev, | 270 | dev_err(di->dev, "vendor %d not supported!\n", di->vendor); |
190 | "Chip ID[%d]\n not supported!\n", di->chip_id); | ||
191 | return -EINVAL; | 271 | return -EINVAL; |
192 | } | 272 | } |
193 | /* Init slew rate */ | 273 | |
194 | if (pdata->slew_rate & 0x7) | 274 | return ret; |
195 | di->slew_rate = pdata->slew_rate; | ||
196 | else | ||
197 | di->slew_rate = FAN53555_SLEW_RATE_64MV; | ||
198 | reg = FAN53555_CONTROL; | ||
199 | data = di->slew_rate << CTL_SLEW_SHIFT; | ||
200 | mask = CTL_SLEW_MASK; | ||
201 | return regmap_update_bits(di->regmap, reg, mask, data); | ||
202 | } | 275 | } |
203 | 276 | ||
204 | static int fan53555_regulator_register(struct fan53555_device_info *di, | 277 | static int fan53555_regulator_register(struct fan53555_device_info *di, |
@@ -207,6 +280,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, | |||
207 | struct regulator_desc *rdesc = &di->desc; | 280 | struct regulator_desc *rdesc = &di->desc; |
208 | 281 | ||
209 | rdesc->name = "fan53555-reg"; | 282 | rdesc->name = "fan53555-reg"; |
283 | rdesc->supply_name = "vin"; | ||
210 | rdesc->ops = &fan53555_regulator_ops; | 284 | rdesc->ops = &fan53555_regulator_ops; |
211 | rdesc->type = REGULATOR_VOLTAGE; | 285 | rdesc->type = REGULATOR_VOLTAGE; |
212 | rdesc->n_voltages = FAN53555_NVOLTAGES; | 286 | rdesc->n_voltages = FAN53555_NVOLTAGES; |
@@ -227,9 +301,46 @@ static struct regmap_config fan53555_regmap_config = { | |||
227 | .val_bits = 8, | 301 | .val_bits = 8, |
228 | }; | 302 | }; |
229 | 303 | ||
304 | static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev, | ||
305 | struct device_node *np) | ||
306 | { | ||
307 | struct fan53555_platform_data *pdata; | ||
308 | int ret; | ||
309 | u32 tmp; | ||
310 | |||
311 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
312 | if (!pdata) | ||
313 | return NULL; | ||
314 | |||
315 | pdata->regulator = of_get_regulator_init_data(dev, np); | ||
316 | |||
317 | ret = of_property_read_u32(np, "fcs,suspend-voltage-selector", | ||
318 | &tmp); | ||
319 | if (!ret) | ||
320 | pdata->sleep_vsel_id = tmp; | ||
321 | |||
322 | return pdata; | ||
323 | } | ||
324 | |||
325 | static const struct of_device_id fan53555_dt_ids[] = { | ||
326 | { | ||
327 | .compatible = "fcs,fan53555", | ||
328 | .data = (void *)FAN53555_VENDOR_FAIRCHILD | ||
329 | }, { | ||
330 | .compatible = "silergy,syr827", | ||
331 | .data = (void *)FAN53555_VENDOR_SILERGY, | ||
332 | }, { | ||
333 | .compatible = "silergy,syr828", | ||
334 | .data = (void *)FAN53555_VENDOR_SILERGY, | ||
335 | }, | ||
336 | { } | ||
337 | }; | ||
338 | MODULE_DEVICE_TABLE(of, fan53555_dt_ids); | ||
339 | |||
230 | static int fan53555_regulator_probe(struct i2c_client *client, | 340 | static int fan53555_regulator_probe(struct i2c_client *client, |
231 | const struct i2c_device_id *id) | 341 | const struct i2c_device_id *id) |
232 | { | 342 | { |
343 | struct device_node *np = client->dev.of_node; | ||
233 | struct fan53555_device_info *di; | 344 | struct fan53555_device_info *di; |
234 | struct fan53555_platform_data *pdata; | 345 | struct fan53555_platform_data *pdata; |
235 | struct regulator_config config = { }; | 346 | struct regulator_config config = { }; |
@@ -237,6 +348,9 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
237 | int ret; | 348 | int ret; |
238 | 349 | ||
239 | pdata = dev_get_platdata(&client->dev); | 350 | pdata = dev_get_platdata(&client->dev); |
351 | if (!pdata) | ||
352 | pdata = fan53555_parse_dt(&client->dev, np); | ||
353 | |||
240 | if (!pdata || !pdata->regulator) { | 354 | if (!pdata || !pdata->regulator) { |
241 | dev_err(&client->dev, "Platform data not found!\n"); | 355 | dev_err(&client->dev, "Platform data not found!\n"); |
242 | return -ENODEV; | 356 | return -ENODEV; |
@@ -247,13 +361,35 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
247 | if (!di) | 361 | if (!di) |
248 | return -ENOMEM; | 362 | return -ENOMEM; |
249 | 363 | ||
364 | di->regulator = pdata->regulator; | ||
365 | if (client->dev.of_node) { | ||
366 | const struct of_device_id *match; | ||
367 | |||
368 | match = of_match_device(of_match_ptr(fan53555_dt_ids), | ||
369 | &client->dev); | ||
370 | if (!match) | ||
371 | return -ENODEV; | ||
372 | |||
373 | di->vendor = (unsigned long) match->data; | ||
374 | } else { | ||
375 | /* if no ramp constraint set, get the pdata ramp_delay */ | ||
376 | if (!di->regulator->constraints.ramp_delay) { | ||
377 | int slew_idx = (pdata->slew_rate & 0x7) | ||
378 | ? pdata->slew_rate : 0; | ||
379 | |||
380 | di->regulator->constraints.ramp_delay | ||
381 | = slew_rates[slew_idx]; | ||
382 | } | ||
383 | |||
384 | di->vendor = id->driver_data; | ||
385 | } | ||
386 | |||
250 | di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); | 387 | di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); |
251 | if (IS_ERR(di->regmap)) { | 388 | if (IS_ERR(di->regmap)) { |
252 | dev_err(&client->dev, "Failed to allocate regmap!\n"); | 389 | dev_err(&client->dev, "Failed to allocate regmap!\n"); |
253 | return PTR_ERR(di->regmap); | 390 | return PTR_ERR(di->regmap); |
254 | } | 391 | } |
255 | di->dev = &client->dev; | 392 | di->dev = &client->dev; |
256 | di->regulator = pdata->regulator; | ||
257 | i2c_set_clientdata(client, di); | 393 | i2c_set_clientdata(client, di); |
258 | /* Get chip ID */ | 394 | /* Get chip ID */ |
259 | ret = regmap_read(di->regmap, FAN53555_ID1, &val); | 395 | ret = regmap_read(di->regmap, FAN53555_ID1, &val); |
@@ -282,6 +418,8 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
282 | config.init_data = di->regulator; | 418 | config.init_data = di->regulator; |
283 | config.regmap = di->regmap; | 419 | config.regmap = di->regmap; |
284 | config.driver_data = di; | 420 | config.driver_data = di; |
421 | config.of_node = np; | ||
422 | |||
285 | ret = fan53555_regulator_register(di, &config); | 423 | ret = fan53555_regulator_register(di, &config); |
286 | if (ret < 0) | 424 | if (ret < 0) |
287 | dev_err(&client->dev, "Failed to register regulator!\n"); | 425 | dev_err(&client->dev, "Failed to register regulator!\n"); |
@@ -290,13 +428,20 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
290 | } | 428 | } |
291 | 429 | ||
292 | static const struct i2c_device_id fan53555_id[] = { | 430 | static const struct i2c_device_id fan53555_id[] = { |
293 | {"fan53555", -1}, | 431 | { |
432 | .name = "fan53555", | ||
433 | .driver_data = FAN53555_VENDOR_FAIRCHILD | ||
434 | }, { | ||
435 | .name = "syr82x", | ||
436 | .driver_data = FAN53555_VENDOR_SILERGY | ||
437 | }, | ||
294 | { }, | 438 | { }, |
295 | }; | 439 | }; |
296 | 440 | ||
297 | static struct i2c_driver fan53555_regulator_driver = { | 441 | static struct i2c_driver fan53555_regulator_driver = { |
298 | .driver = { | 442 | .driver = { |
299 | .name = "fan53555-regulator", | 443 | .name = "fan53555-regulator", |
444 | .of_match_table = of_match_ptr(fan53555_dt_ids), | ||
300 | }, | 445 | }, |
301 | .probe = fan53555_regulator_probe, | 446 | .probe = fan53555_regulator_probe, |
302 | .id_table = fan53555_id, | 447 | .id_table = fan53555_id, |
diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c new file mode 100644 index 000000000000..156d0d1a55f1 --- /dev/null +++ b/drivers/regulator/hi6421-regulator.c | |||
@@ -0,0 +1,634 @@ | |||
1 | /* | ||
2 | * Device driver for regulators in Hi6421 IC | ||
3 | * | ||
4 | * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. | ||
5 | * http://www.hisilicon.com | ||
6 | * Copyright (c) <2013-2014> Linaro Ltd. | ||
7 | * http://www.linaro.org | ||
8 | * | ||
9 | * Author: Guodong Xu <guodong.xu@linaro.org> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/slab.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/regulator/driver.h> | ||
24 | #include <linux/regulator/machine.h> | ||
25 | #include <linux/regulator/of_regulator.h> | ||
26 | #include <linux/mfd/hi6421-pmic.h> | ||
27 | |||
28 | /* | ||
29 | * struct hi6421_regulator_pdata - Hi6421 regulator data of platform device | ||
30 | * @lock: mutex to serialize regulator enable | ||
31 | */ | ||
32 | struct hi6421_regulator_pdata { | ||
33 | struct mutex lock; | ||
34 | }; | ||
35 | |||
36 | /* | ||
37 | * struct hi6421_regulator_info - hi6421 regulator information | ||
38 | * @desc: regulator description | ||
39 | * @mode_mask: ECO mode bitmask of LDOs; for BUCKs, this masks sleep | ||
40 | * @eco_microamp: eco mode load upper limit (in uA), valid for LDOs only | ||
41 | */ | ||
42 | struct hi6421_regulator_info { | ||
43 | struct regulator_desc desc; | ||
44 | u8 mode_mask; | ||
45 | u32 eco_microamp; | ||
46 | }; | ||
47 | |||
48 | /* HI6421 regulators */ | ||
49 | enum hi6421_regulator_id { | ||
50 | HI6421_LDO0, | ||
51 | HI6421_LDO1, | ||
52 | HI6421_LDO2, | ||
53 | HI6421_LDO3, | ||
54 | HI6421_LDO4, | ||
55 | HI6421_LDO5, | ||
56 | HI6421_LDO6, | ||
57 | HI6421_LDO7, | ||
58 | HI6421_LDO8, | ||
59 | HI6421_LDO9, | ||
60 | HI6421_LDO10, | ||
61 | HI6421_LDO11, | ||
62 | HI6421_LDO12, | ||
63 | HI6421_LDO13, | ||
64 | HI6421_LDO14, | ||
65 | HI6421_LDO15, | ||
66 | HI6421_LDO16, | ||
67 | HI6421_LDO17, | ||
68 | HI6421_LDO18, | ||
69 | HI6421_LDO19, | ||
70 | HI6421_LDO20, | ||
71 | HI6421_LDOAUDIO, | ||
72 | HI6421_BUCK0, | ||
73 | HI6421_BUCK1, | ||
74 | HI6421_BUCK2, | ||
75 | HI6421_BUCK3, | ||
76 | HI6421_BUCK4, | ||
77 | HI6421_BUCK5, | ||
78 | HI6421_NUM_REGULATORS, | ||
79 | }; | ||
80 | |||
81 | #define HI6421_REGULATOR_OF_MATCH(_name, id) \ | ||
82 | { \ | ||
83 | .name = #_name, \ | ||
84 | .driver_data = (void *) HI6421_##id, \ | ||
85 | } | ||
86 | |||
87 | static struct of_regulator_match hi6421_regulator_match[] = { | ||
88 | HI6421_REGULATOR_OF_MATCH(hi6421_vout0, LDO0), | ||
89 | HI6421_REGULATOR_OF_MATCH(hi6421_vout1, LDO1), | ||
90 | HI6421_REGULATOR_OF_MATCH(hi6421_vout2, LDO2), | ||
91 | HI6421_REGULATOR_OF_MATCH(hi6421_vout3, LDO3), | ||
92 | HI6421_REGULATOR_OF_MATCH(hi6421_vout4, LDO4), | ||
93 | HI6421_REGULATOR_OF_MATCH(hi6421_vout5, LDO5), | ||
94 | HI6421_REGULATOR_OF_MATCH(hi6421_vout6, LDO6), | ||
95 | HI6421_REGULATOR_OF_MATCH(hi6421_vout7, LDO7), | ||
96 | HI6421_REGULATOR_OF_MATCH(hi6421_vout8, LDO8), | ||
97 | HI6421_REGULATOR_OF_MATCH(hi6421_vout9, LDO9), | ||
98 | HI6421_REGULATOR_OF_MATCH(hi6421_vout10, LDO10), | ||
99 | HI6421_REGULATOR_OF_MATCH(hi6421_vout11, LDO11), | ||
100 | HI6421_REGULATOR_OF_MATCH(hi6421_vout12, LDO12), | ||
101 | HI6421_REGULATOR_OF_MATCH(hi6421_vout13, LDO13), | ||
102 | HI6421_REGULATOR_OF_MATCH(hi6421_vout14, LDO14), | ||
103 | HI6421_REGULATOR_OF_MATCH(hi6421_vout15, LDO15), | ||
104 | HI6421_REGULATOR_OF_MATCH(hi6421_vout16, LDO16), | ||
105 | HI6421_REGULATOR_OF_MATCH(hi6421_vout17, LDO17), | ||
106 | HI6421_REGULATOR_OF_MATCH(hi6421_vout18, LDO18), | ||
107 | HI6421_REGULATOR_OF_MATCH(hi6421_vout19, LDO19), | ||
108 | HI6421_REGULATOR_OF_MATCH(hi6421_vout20, LDO20), | ||
109 | HI6421_REGULATOR_OF_MATCH(hi6421_vout_audio, LDOAUDIO), | ||
110 | HI6421_REGULATOR_OF_MATCH(hi6421_buck0, BUCK0), | ||
111 | HI6421_REGULATOR_OF_MATCH(hi6421_buck1, BUCK1), | ||
112 | HI6421_REGULATOR_OF_MATCH(hi6421_buck2, BUCK2), | ||
113 | HI6421_REGULATOR_OF_MATCH(hi6421_buck3, BUCK3), | ||
114 | HI6421_REGULATOR_OF_MATCH(hi6421_buck4, BUCK4), | ||
115 | HI6421_REGULATOR_OF_MATCH(hi6421_buck5, BUCK5), | ||
116 | }; | ||
117 | |||
118 | /* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */ | ||
119 | static const unsigned int ldo_0_voltages[] = { | ||
120 | 1500000, 1800000, 2400000, 2500000, | ||
121 | 2600000, 2700000, 2850000, 3000000, | ||
122 | }; | ||
123 | |||
124 | /* LDO 8, 15 have same voltage table. */ | ||
125 | static const unsigned int ldo_8_voltages[] = { | ||
126 | 1500000, 1800000, 2400000, 2600000, | ||
127 | 2700000, 2850000, 3000000, 3300000, | ||
128 | }; | ||
129 | |||
130 | /* Ranges are sorted in ascending order. */ | ||
131 | static const struct regulator_linear_range ldo_audio_volt_range[] = { | ||
132 | REGULATOR_LINEAR_RANGE(2800000, 0, 3, 50000), | ||
133 | REGULATOR_LINEAR_RANGE(3000000, 4, 7, 100000), | ||
134 | }; | ||
135 | |||
136 | static const unsigned int buck_3_voltages[] = { | ||
137 | 950000, 1050000, 1100000, 1117000, | ||
138 | 1134000, 1150000, 1167000, 1200000, | ||
139 | }; | ||
140 | |||
141 | static const unsigned int buck_4_voltages[] = { | ||
142 | 1150000, 1200000, 1250000, 1350000, | ||
143 | 1700000, 1800000, 1900000, 2000000, | ||
144 | }; | ||
145 | |||
146 | static const unsigned int buck_5_voltages[] = { | ||
147 | 1150000, 1200000, 1250000, 1350000, | ||
148 | 1600000, 1700000, 1800000, 1900000, | ||
149 | }; | ||
150 | |||
151 | static const struct regulator_ops hi6421_ldo_ops; | ||
152 | static const struct regulator_ops hi6421_ldo_linear_ops; | ||
153 | static const struct regulator_ops hi6421_ldo_linear_range_ops; | ||
154 | static const struct regulator_ops hi6421_buck012_ops; | ||
155 | static const struct regulator_ops hi6421_buck345_ops; | ||
156 | |||
157 | #define HI6421_LDO_ENABLE_TIME (350) | ||
158 | /* | ||
159 | * _id - LDO id name string | ||
160 | * v_table - voltage table | ||
161 | * vreg - voltage select register | ||
162 | * vmask - voltage select mask | ||
163 | * ereg - enable register | ||
164 | * emask - enable mask | ||
165 | * odelay - off/on delay time in uS | ||
166 | * ecomask - eco mode mask | ||
167 | * ecoamp - eco mode load uppler limit in uA | ||
168 | */ | ||
169 | #define HI6421_LDO(_id, v_table, vreg, vmask, ereg, emask, \ | ||
170 | odelay, ecomask, ecoamp) \ | ||
171 | [HI6421_##_id] = { \ | ||
172 | .desc = { \ | ||
173 | .name = #_id, \ | ||
174 | .ops = &hi6421_ldo_ops, \ | ||
175 | .type = REGULATOR_VOLTAGE, \ | ||
176 | .id = HI6421_##_id, \ | ||
177 | .owner = THIS_MODULE, \ | ||
178 | .n_voltages = ARRAY_SIZE(v_table), \ | ||
179 | .volt_table = v_table, \ | ||
180 | .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ | ||
181 | .vsel_mask = vmask, \ | ||
182 | .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ | ||
183 | .enable_mask = emask, \ | ||
184 | .enable_time = HI6421_LDO_ENABLE_TIME, \ | ||
185 | .off_on_delay = odelay, \ | ||
186 | }, \ | ||
187 | .mode_mask = ecomask, \ | ||
188 | .eco_microamp = ecoamp, \ | ||
189 | } | ||
190 | |||
191 | /* HI6421 LDO1~3 are linear voltage regulators at fixed uV_step | ||
192 | * | ||
193 | * _id - LDO id name string | ||
194 | * _min_uV - minimum voltage supported in uV | ||
195 | * n_volt - number of votages available | ||
196 | * vstep - voltage increase in each linear step in uV | ||
197 | * vreg - voltage select register | ||
198 | * vmask - voltage select mask | ||
199 | * ereg - enable register | ||
200 | * emask - enable mask | ||
201 | * odelay - off/on delay time in uS | ||
202 | * ecomask - eco mode mask | ||
203 | * ecoamp - eco mode load uppler limit in uA | ||
204 | */ | ||
205 | #define HI6421_LDO_LINEAR(_id, _min_uV, n_volt, vstep, vreg, vmask, \ | ||
206 | ereg, emask, odelay, ecomask, ecoamp) \ | ||
207 | [HI6421_##_id] = { \ | ||
208 | .desc = { \ | ||
209 | .name = #_id, \ | ||
210 | .ops = &hi6421_ldo_linear_ops, \ | ||
211 | .type = REGULATOR_VOLTAGE, \ | ||
212 | .id = HI6421_##_id, \ | ||
213 | .owner = THIS_MODULE, \ | ||
214 | .min_uV = _min_uV, \ | ||
215 | .n_voltages = n_volt, \ | ||
216 | .uV_step = vstep, \ | ||
217 | .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ | ||
218 | .vsel_mask = vmask, \ | ||
219 | .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ | ||
220 | .enable_mask = emask, \ | ||
221 | .enable_time = HI6421_LDO_ENABLE_TIME, \ | ||
222 | .off_on_delay = odelay, \ | ||
223 | }, \ | ||
224 | .mode_mask = ecomask, \ | ||
225 | .eco_microamp = ecoamp, \ | ||
226 | } | ||
227 | |||
228 | /* HI6421 LDOAUDIO is a linear voltage regulator with two 4-step ranges | ||
229 | * | ||
230 | * _id - LDO id name string | ||
231 | * n_volt - number of votages available | ||
232 | * volt_ranges - array of regulator_linear_range | ||
233 | * vstep - voltage increase in each linear step in uV | ||
234 | * vreg - voltage select register | ||
235 | * vmask - voltage select mask | ||
236 | * ereg - enable register | ||
237 | * emask - enable mask | ||
238 | * odelay - off/on delay time in uS | ||
239 | * ecomask - eco mode mask | ||
240 | * ecoamp - eco mode load uppler limit in uA | ||
241 | */ | ||
242 | #define HI6421_LDO_LINEAR_RANGE(_id, n_volt, volt_ranges, vreg, vmask, \ | ||
243 | ereg, emask, odelay, ecomask, ecoamp) \ | ||
244 | [HI6421_##_id] = { \ | ||
245 | .desc = { \ | ||
246 | .name = #_id, \ | ||
247 | .ops = &hi6421_ldo_linear_range_ops, \ | ||
248 | .type = REGULATOR_VOLTAGE, \ | ||
249 | .id = HI6421_##_id, \ | ||
250 | .owner = THIS_MODULE, \ | ||
251 | .n_voltages = n_volt, \ | ||
252 | .linear_ranges = volt_ranges, \ | ||
253 | .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ | ||
254 | .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ | ||
255 | .vsel_mask = vmask, \ | ||
256 | .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ | ||
257 | .enable_mask = emask, \ | ||
258 | .enable_time = HI6421_LDO_ENABLE_TIME, \ | ||
259 | .off_on_delay = odelay, \ | ||
260 | }, \ | ||
261 | .mode_mask = ecomask, \ | ||
262 | .eco_microamp = ecoamp, \ | ||
263 | } | ||
264 | |||
265 | /* HI6421 BUCK0/1/2 are linear voltage regulators at fixed uV_step | ||
266 | * | ||
267 | * _id - BUCK0/1/2 id name string | ||
268 | * vreg - voltage select register | ||
269 | * vmask - voltage select mask | ||
270 | * ereg - enable register | ||
271 | * emask - enable mask | ||
272 | * sleepmask - mask of sleep mode | ||
273 | * etime - enable time | ||
274 | * odelay - off/on delay time in uS | ||
275 | */ | ||
276 | #define HI6421_BUCK012(_id, vreg, vmask, ereg, emask, sleepmask, \ | ||
277 | etime, odelay) \ | ||
278 | [HI6421_##_id] = { \ | ||
279 | .desc = { \ | ||
280 | .name = #_id, \ | ||
281 | .ops = &hi6421_buck012_ops, \ | ||
282 | .type = REGULATOR_VOLTAGE, \ | ||
283 | .id = HI6421_##_id, \ | ||
284 | .owner = THIS_MODULE, \ | ||
285 | .min_uV = 700000, \ | ||
286 | .n_voltages = 128, \ | ||
287 | .uV_step = 7086, \ | ||
288 | .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ | ||
289 | .vsel_mask = vmask, \ | ||
290 | .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ | ||
291 | .enable_mask = emask, \ | ||
292 | .enable_time = etime, \ | ||
293 | .off_on_delay = odelay, \ | ||
294 | }, \ | ||
295 | .mode_mask = sleepmask, \ | ||
296 | } | ||
297 | |||
298 | /* HI6421 BUCK3/4/5 share similar configurations as LDOs, with exception | ||
299 | * that it supports SLEEP mode, so has different .ops. | ||
300 | * | ||
301 | * _id - LDO id name string | ||
302 | * v_table - voltage table | ||
303 | * vreg - voltage select register | ||
304 | * vmask - voltage select mask | ||
305 | * ereg - enable register | ||
306 | * emask - enable mask | ||
307 | * odelay - off/on delay time in uS | ||
308 | * sleepmask - mask of sleep mode | ||
309 | */ | ||
310 | #define HI6421_BUCK345(_id, v_table, vreg, vmask, ereg, emask, \ | ||
311 | odelay, sleepmask) \ | ||
312 | [HI6421_##_id] = { \ | ||
313 | .desc = { \ | ||
314 | .name = #_id, \ | ||
315 | .ops = &hi6421_buck345_ops, \ | ||
316 | .type = REGULATOR_VOLTAGE, \ | ||
317 | .id = HI6421_##_id, \ | ||
318 | .owner = THIS_MODULE, \ | ||
319 | .n_voltages = ARRAY_SIZE(v_table), \ | ||
320 | .volt_table = v_table, \ | ||
321 | .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ | ||
322 | .vsel_mask = vmask, \ | ||
323 | .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ | ||
324 | .enable_mask = emask, \ | ||
325 | .enable_time = HI6421_LDO_ENABLE_TIME, \ | ||
326 | .off_on_delay = odelay, \ | ||
327 | }, \ | ||
328 | .mode_mask = sleepmask, \ | ||
329 | } | ||
330 | |||
331 | /* HI6421 regulator information */ | ||
332 | static struct hi6421_regulator_info | ||
333 | hi6421_regulator_info[HI6421_NUM_REGULATORS] = { | ||
334 | HI6421_LDO(LDO0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10, | ||
335 | 10000, 0x20, 8000), | ||
336 | HI6421_LDO_LINEAR(LDO1, 1700000, 4, 100000, 0x21, 0x03, 0x21, 0x10, | ||
337 | 10000, 0x20, 5000), | ||
338 | HI6421_LDO_LINEAR(LDO2, 1050000, 8, 50000, 0x22, 0x07, 0x22, 0x10, | ||
339 | 20000, 0x20, 8000), | ||
340 | HI6421_LDO_LINEAR(LDO3, 1050000, 8, 50000, 0x23, 0x07, 0x23, 0x10, | ||
341 | 20000, 0x20, 8000), | ||
342 | HI6421_LDO(LDO4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10, | ||
343 | 20000, 0x20, 8000), | ||
344 | HI6421_LDO(LDO5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10, | ||
345 | 20000, 0x20, 8000), | ||
346 | HI6421_LDO(LDO6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10, | ||
347 | 20000, 0x20, 8000), | ||
348 | HI6421_LDO(LDO7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10, | ||
349 | 20000, 0x20, 5000), | ||
350 | HI6421_LDO(LDO8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10, | ||
351 | 20000, 0x20, 8000), | ||
352 | HI6421_LDO(LDO9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10, | ||
353 | 40000, 0x20, 8000), | ||
354 | HI6421_LDO(LDO10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10, | ||
355 | 40000, 0x20, 8000), | ||
356 | HI6421_LDO(LDO11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10, | ||
357 | 40000, 0x20, 8000), | ||
358 | HI6421_LDO(LDO12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10, | ||
359 | 40000, 0x20, 8000), | ||
360 | HI6421_LDO(LDO13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10, | ||
361 | 40000, 0x20, 8000), | ||
362 | HI6421_LDO(LDO14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10, | ||
363 | 40000, 0x20, 8000), | ||
364 | HI6421_LDO(LDO15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10, | ||
365 | 40000, 0x20, 8000), | ||
366 | HI6421_LDO(LDO16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10, | ||
367 | 40000, 0x20, 8000), | ||
368 | HI6421_LDO(LDO17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10, | ||
369 | 40000, 0x20, 8000), | ||
370 | HI6421_LDO(LDO18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10, | ||
371 | 40000, 0x20, 8000), | ||
372 | HI6421_LDO(LDO19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10, | ||
373 | 40000, 0x20, 8000), | ||
374 | HI6421_LDO(LDO20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10, | ||
375 | 40000, 0x20, 8000), | ||
376 | HI6421_LDO_LINEAR_RANGE(LDOAUDIO, 8, ldo_audio_volt_range, 0x36, | ||
377 | 0x70, 0x36, 0x01, 40000, 0x02, 5000), | ||
378 | HI6421_BUCK012(BUCK0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400, 20000), | ||
379 | HI6421_BUCK012(BUCK1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400, 20000), | ||
380 | HI6421_BUCK012(BUCK2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350, 100), | ||
381 | HI6421_BUCK345(BUCK3, buck_3_voltages, 0x13, 0x07, 0x12, 0x01, | ||
382 | 20000, 0x10), | ||
383 | HI6421_BUCK345(BUCK4, buck_4_voltages, 0x15, 0x07, 0x14, 0x01, | ||
384 | 20000, 0x10), | ||
385 | HI6421_BUCK345(BUCK5, buck_5_voltages, 0x17, 0x07, 0x16, 0x01, | ||
386 | 20000, 0x10), | ||
387 | }; | ||
388 | |||
389 | static int hi6421_regulator_enable(struct regulator_dev *rdev) | ||
390 | { | ||
391 | struct hi6421_regulator_pdata *pdata; | ||
392 | |||
393 | pdata = dev_get_drvdata(rdev->dev.parent); | ||
394 | /* hi6421 spec requires regulator enablement must be serialized: | ||
395 | * - Because when BUCK, LDO switching from off to on, it will have | ||
396 | * a huge instantaneous current; so you can not turn on two or | ||
397 | * more LDO or BUCKs simultaneously, or it may burn the chip. | ||
398 | */ | ||
399 | mutex_lock(&pdata->lock); | ||
400 | |||
401 | /* call regulator regmap helper */ | ||
402 | regulator_enable_regmap(rdev); | ||
403 | |||
404 | mutex_unlock(&pdata->lock); | ||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev) | ||
409 | { | ||
410 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | ||
411 | u32 reg_val; | ||
412 | |||
413 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); | ||
414 | if (reg_val & info->mode_mask) | ||
415 | return REGULATOR_MODE_IDLE; | ||
416 | |||
417 | return REGULATOR_MODE_NORMAL; | ||
418 | } | ||
419 | |||
420 | static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) | ||
421 | { | ||
422 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | ||
423 | u32 reg_val; | ||
424 | |||
425 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); | ||
426 | if (reg_val & info->mode_mask) | ||
427 | return REGULATOR_MODE_STANDBY; | ||
428 | |||
429 | return REGULATOR_MODE_NORMAL; | ||
430 | } | ||
431 | |||
432 | static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, | ||
433 | unsigned int mode) | ||
434 | { | ||
435 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | ||
436 | u32 new_mode; | ||
437 | |||
438 | switch (mode) { | ||
439 | case REGULATOR_MODE_NORMAL: | ||
440 | new_mode = 0; | ||
441 | break; | ||
442 | case REGULATOR_MODE_IDLE: | ||
443 | new_mode = info->mode_mask; | ||
444 | break; | ||
445 | default: | ||
446 | return -EINVAL; | ||
447 | } | ||
448 | |||
449 | /* set mode */ | ||
450 | regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
451 | info->mode_mask, new_mode); | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev, | ||
457 | unsigned int mode) | ||
458 | { | ||
459 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | ||
460 | u32 new_mode; | ||
461 | |||
462 | switch (mode) { | ||
463 | case REGULATOR_MODE_NORMAL: | ||
464 | new_mode = 0; | ||
465 | break; | ||
466 | case REGULATOR_MODE_STANDBY: | ||
467 | new_mode = info->mode_mask; | ||
468 | break; | ||
469 | default: | ||
470 | return -EINVAL; | ||
471 | } | ||
472 | |||
473 | /* set mode */ | ||
474 | regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
475 | info->mode_mask, new_mode); | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | unsigned int hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev, | ||
481 | int input_uV, int output_uV, int load_uA) | ||
482 | { | ||
483 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | ||
484 | |||
485 | if (load_uA > info->eco_microamp) | ||
486 | return REGULATOR_MODE_NORMAL; | ||
487 | |||
488 | return REGULATOR_MODE_IDLE; | ||
489 | } | ||
490 | |||
491 | static const struct regulator_ops hi6421_ldo_ops = { | ||
492 | .is_enabled = regulator_is_enabled_regmap, | ||
493 | .enable = hi6421_regulator_enable, | ||
494 | .disable = regulator_disable_regmap, | ||
495 | .list_voltage = regulator_list_voltage_table, | ||
496 | .map_voltage = regulator_map_voltage_ascend, | ||
497 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
498 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
499 | .get_mode = hi6421_regulator_ldo_get_mode, | ||
500 | .set_mode = hi6421_regulator_ldo_set_mode, | ||
501 | .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode, | ||
502 | }; | ||
503 | |||
504 | static const struct regulator_ops hi6421_ldo_linear_ops = { | ||
505 | .is_enabled = regulator_is_enabled_regmap, | ||
506 | .enable = hi6421_regulator_enable, | ||
507 | .disable = regulator_disable_regmap, | ||
508 | .list_voltage = regulator_list_voltage_linear, | ||
509 | .map_voltage = regulator_map_voltage_linear, | ||
510 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
511 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
512 | .get_mode = hi6421_regulator_ldo_get_mode, | ||
513 | .set_mode = hi6421_regulator_ldo_set_mode, | ||
514 | .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode, | ||
515 | }; | ||
516 | |||
517 | static const struct regulator_ops hi6421_ldo_linear_range_ops = { | ||
518 | .is_enabled = regulator_is_enabled_regmap, | ||
519 | .enable = hi6421_regulator_enable, | ||
520 | .disable = regulator_disable_regmap, | ||
521 | .list_voltage = regulator_list_voltage_linear_range, | ||
522 | .map_voltage = regulator_map_voltage_linear_range, | ||
523 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
524 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
525 | .get_mode = hi6421_regulator_ldo_get_mode, | ||
526 | .set_mode = hi6421_regulator_ldo_set_mode, | ||
527 | .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode, | ||
528 | }; | ||
529 | |||
530 | static const struct regulator_ops hi6421_buck012_ops = { | ||
531 | .is_enabled = regulator_is_enabled_regmap, | ||
532 | .enable = hi6421_regulator_enable, | ||
533 | .disable = regulator_disable_regmap, | ||
534 | .list_voltage = regulator_list_voltage_linear, | ||
535 | .map_voltage = regulator_map_voltage_linear, | ||
536 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
537 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
538 | .get_mode = hi6421_regulator_buck_get_mode, | ||
539 | .set_mode = hi6421_regulator_buck_set_mode, | ||
540 | }; | ||
541 | |||
542 | static const struct regulator_ops hi6421_buck345_ops = { | ||
543 | .is_enabled = regulator_is_enabled_regmap, | ||
544 | .enable = hi6421_regulator_enable, | ||
545 | .disable = regulator_disable_regmap, | ||
546 | .list_voltage = regulator_list_voltage_table, | ||
547 | .map_voltage = regulator_map_voltage_ascend, | ||
548 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
549 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
550 | .get_mode = hi6421_regulator_buck_get_mode, | ||
551 | .set_mode = hi6421_regulator_buck_set_mode, | ||
552 | }; | ||
553 | |||
554 | static int hi6421_regulator_register(struct platform_device *pdev, | ||
555 | struct regmap *rmap, | ||
556 | struct regulator_init_data *init_data, | ||
557 | int id, struct device_node *np) | ||
558 | { | ||
559 | struct hi6421_regulator_info *info = NULL; | ||
560 | struct regulator_config config = { }; | ||
561 | struct regulator_dev *rdev; | ||
562 | |||
563 | /* assign per-regulator data */ | ||
564 | info = &hi6421_regulator_info[id]; | ||
565 | |||
566 | config.dev = &pdev->dev; | ||
567 | config.init_data = init_data; | ||
568 | config.driver_data = info; | ||
569 | config.regmap = rmap; | ||
570 | config.of_node = np; | ||
571 | |||
572 | /* register regulator with framework */ | ||
573 | rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); | ||
574 | if (IS_ERR(rdev)) { | ||
575 | dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
576 | info->desc.name); | ||
577 | return PTR_ERR(rdev); | ||
578 | } | ||
579 | |||
580 | return 0; | ||
581 | } | ||
582 | |||
583 | static int hi6421_regulator_probe(struct platform_device *pdev) | ||
584 | { | ||
585 | struct device *dev = &pdev->dev; | ||
586 | struct device_node *np; | ||
587 | struct hi6421_pmic *pmic; | ||
588 | struct hi6421_regulator_pdata *pdata; | ||
589 | int i, ret = 0; | ||
590 | |||
591 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
592 | if (!pdata) | ||
593 | return -ENOMEM; | ||
594 | mutex_init(&pdata->lock); | ||
595 | platform_set_drvdata(pdev, pdata); | ||
596 | |||
597 | np = of_get_child_by_name(dev->parent->of_node, "regulators"); | ||
598 | if (!np) | ||
599 | return -ENODEV; | ||
600 | |||
601 | ret = of_regulator_match(dev, np, | ||
602 | hi6421_regulator_match, | ||
603 | ARRAY_SIZE(hi6421_regulator_match)); | ||
604 | of_node_put(np); | ||
605 | if (ret < 0) { | ||
606 | dev_err(dev, "Error parsing regulator init data: %d\n", ret); | ||
607 | return ret; | ||
608 | } | ||
609 | |||
610 | pmic = dev_get_drvdata(dev->parent); | ||
611 | |||
612 | for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) { | ||
613 | ret = hi6421_regulator_register(pdev, pmic->regmap, | ||
614 | hi6421_regulator_match[i].init_data, i, | ||
615 | hi6421_regulator_match[i].of_node); | ||
616 | if (ret) | ||
617 | return ret; | ||
618 | } | ||
619 | |||
620 | return 0; | ||
621 | } | ||
622 | |||
623 | static struct platform_driver hi6421_regulator_driver = { | ||
624 | .driver = { | ||
625 | .name = "hi6421-regulator", | ||
626 | .owner = THIS_MODULE, | ||
627 | }, | ||
628 | .probe = hi6421_regulator_probe, | ||
629 | }; | ||
630 | module_platform_driver(hi6421_regulator_driver); | ||
631 | |||
632 | MODULE_AUTHOR("Guodong Xu <guodong.xu@linaro.org>"); | ||
633 | MODULE_DESCRIPTION("Hi6421 regulator driver"); | ||
634 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 84bbda10c396..80ba2a35a04b 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h | |||
@@ -35,4 +35,18 @@ struct regulator { | |||
35 | struct dentry *debugfs; | 35 | struct dentry *debugfs; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #ifdef CONFIG_OF | ||
39 | struct regulator_init_data *regulator_of_get_init_data(struct device *dev, | ||
40 | const struct regulator_desc *desc, | ||
41 | struct device_node **node); | ||
42 | #else | ||
43 | static inline struct regulator_init_data * | ||
44 | regulator_of_get_init_data(struct device *dev, | ||
45 | const struct regulator_desc *desc, | ||
46 | struct device_node **node) | ||
47 | { | ||
48 | return NULL; | ||
49 | } | ||
50 | #endif | ||
51 | |||
38 | #endif | 52 | #endif |
diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c new file mode 100644 index 000000000000..92fefd98da58 --- /dev/null +++ b/drivers/regulator/isl9305.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * isl9305 - Intersil ISL9305 DCDC regulator | ||
3 | * | ||
4 | * Copyright 2014 Linaro Ltd | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@kernel.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/platform_data/isl9305.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/regulator/driver.h> | ||
21 | #include <linux/regulator/of_regulator.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | /* | ||
25 | * Registers | ||
26 | */ | ||
27 | #define ISL9305_DCD1OUT 0x0 | ||
28 | #define ISL9305_DCD2OUT 0x1 | ||
29 | #define ISL9305_LDO1OUT 0x2 | ||
30 | #define ISL9305_LDO2OUT 0x3 | ||
31 | #define ISL9305_DCD_PARAMETER 0x4 | ||
32 | #define ISL9305_SYSTEM_PARAMETER 0x5 | ||
33 | #define ISL9305_DCD_SRCTL 0x6 | ||
34 | |||
35 | #define ISL9305_MAX_REG ISL9305_DCD_SRCTL | ||
36 | |||
37 | /* | ||
38 | * DCD_PARAMETER | ||
39 | */ | ||
40 | #define ISL9305_DCD_PHASE 0x40 | ||
41 | #define ISL9305_DCD2_ULTRA 0x20 | ||
42 | #define ISL9305_DCD1_ULTRA 0x10 | ||
43 | #define ISL9305_DCD2_BLD 0x08 | ||
44 | #define ISL9305_DCD1_BLD 0x04 | ||
45 | #define ISL9305_DCD2_MODE 0x02 | ||
46 | #define ISL9305_DCD1_MODE 0x01 | ||
47 | |||
48 | /* | ||
49 | * SYSTEM_PARAMETER | ||
50 | */ | ||
51 | #define ISL9305_I2C_EN 0x40 | ||
52 | #define ISL9305_DCDPOR_MASK 0x30 | ||
53 | #define ISL9305_LDO2_EN 0x08 | ||
54 | #define ISL9305_LDO1_EN 0x04 | ||
55 | #define ISL9305_DCD2_EN 0x02 | ||
56 | #define ISL9305_DCD1_EN 0x01 | ||
57 | |||
58 | /* | ||
59 | * DCD_SRCTL | ||
60 | */ | ||
61 | #define ISL9305_DCD2SR_MASK 0xc0 | ||
62 | #define ISL9305_DCD1SR_MASK 0x07 | ||
63 | |||
64 | static const struct regulator_ops isl9305_ops = { | ||
65 | .enable = regulator_enable_regmap, | ||
66 | .disable = regulator_disable_regmap, | ||
67 | .is_enabled = regulator_is_enabled_regmap, | ||
68 | .list_voltage = regulator_list_voltage_linear, | ||
69 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
70 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
71 | }; | ||
72 | |||
73 | static const struct regulator_desc isl9305_regulators[] = { | ||
74 | [ISL9305_DCD1] = { | ||
75 | .name = "DCD1", | ||
76 | .of_match = of_match_ptr("dcd1"), | ||
77 | .regulators_node = of_match_ptr("regulators"), | ||
78 | .n_voltages = 0x70, | ||
79 | .min_uV = 825000, | ||
80 | .uV_step = 25000, | ||
81 | .vsel_reg = ISL9305_DCD1OUT, | ||
82 | .vsel_mask = 0x7f, | ||
83 | .enable_reg = ISL9305_SYSTEM_PARAMETER, | ||
84 | .enable_mask = ISL9305_DCD1_EN, | ||
85 | .supply_name = "VINDCD1", | ||
86 | .ops = &isl9305_ops, | ||
87 | }, | ||
88 | [ISL9305_DCD2] = { | ||
89 | .name = "DCD2", | ||
90 | .of_match = of_match_ptr("dcd2"), | ||
91 | .regulators_node = of_match_ptr("regulators"), | ||
92 | .n_voltages = 0x70, | ||
93 | .min_uV = 825000, | ||
94 | .uV_step = 25000, | ||
95 | .vsel_reg = ISL9305_DCD2OUT, | ||
96 | .vsel_mask = 0x7f, | ||
97 | .enable_reg = ISL9305_SYSTEM_PARAMETER, | ||
98 | .enable_mask = ISL9305_DCD2_EN, | ||
99 | .supply_name = "VINDCD2", | ||
100 | .ops = &isl9305_ops, | ||
101 | }, | ||
102 | [ISL9305_LDO1] = { | ||
103 | .name = "LDO1", | ||
104 | .of_match = of_match_ptr("ldo1"), | ||
105 | .regulators_node = of_match_ptr("regulators"), | ||
106 | .n_voltages = 0x37, | ||
107 | .min_uV = 900000, | ||
108 | .uV_step = 50000, | ||
109 | .vsel_reg = ISL9305_LDO1OUT, | ||
110 | .vsel_mask = 0x3f, | ||
111 | .enable_reg = ISL9305_SYSTEM_PARAMETER, | ||
112 | .enable_mask = ISL9305_LDO1_EN, | ||
113 | .supply_name = "VINLDO1", | ||
114 | .ops = &isl9305_ops, | ||
115 | }, | ||
116 | [ISL9305_LDO2] = { | ||
117 | .name = "LDO2", | ||
118 | .of_match = of_match_ptr("ldo2"), | ||
119 | .regulators_node = of_match_ptr("regulators"), | ||
120 | .n_voltages = 0x37, | ||
121 | .min_uV = 900000, | ||
122 | .uV_step = 50000, | ||
123 | .vsel_reg = ISL9305_LDO2OUT, | ||
124 | .vsel_mask = 0x3f, | ||
125 | .enable_reg = ISL9305_SYSTEM_PARAMETER, | ||
126 | .enable_mask = ISL9305_LDO2_EN, | ||
127 | .supply_name = "VINLDO2", | ||
128 | .ops = &isl9305_ops, | ||
129 | }, | ||
130 | }; | ||
131 | |||
132 | static const struct regmap_config isl9305_regmap = { | ||
133 | .reg_bits = 8, | ||
134 | .val_bits = 8, | ||
135 | |||
136 | .max_register = ISL9305_MAX_REG, | ||
137 | .cache_type = REGCACHE_RBTREE, | ||
138 | }; | ||
139 | |||
140 | static int isl9305_i2c_probe(struct i2c_client *i2c, | ||
141 | const struct i2c_device_id *id) | ||
142 | { | ||
143 | struct regulator_config config = { }; | ||
144 | struct isl9305_pdata *pdata = i2c->dev.platform_data; | ||
145 | struct regulator_dev *rdev; | ||
146 | struct regmap *regmap; | ||
147 | int i, ret; | ||
148 | |||
149 | regmap = devm_regmap_init_i2c(i2c, &isl9305_regmap); | ||
150 | if (IS_ERR(regmap)) { | ||
151 | ret = PTR_ERR(regmap); | ||
152 | dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | config.dev = &i2c->dev; | ||
157 | |||
158 | for (i = 0; i < ARRAY_SIZE(isl9305_regulators); i++) { | ||
159 | if (pdata) | ||
160 | config.init_data = pdata->init_data[i]; | ||
161 | else | ||
162 | config.init_data = NULL; | ||
163 | |||
164 | rdev = devm_regulator_register(&i2c->dev, | ||
165 | &isl9305_regulators[i], | ||
166 | &config); | ||
167 | if (IS_ERR(rdev)) { | ||
168 | ret = PTR_ERR(rdev); | ||
169 | dev_err(&i2c->dev, "Failed to register %s: %d\n", | ||
170 | isl9305_regulators[i].name, ret); | ||
171 | return ret; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | #ifdef CONFIG_OF | ||
179 | static const struct of_device_id isl9305_dt_ids[] = { | ||
180 | { .compatible = "isl,isl9305" }, | ||
181 | { .compatible = "isl,isl9305h" }, | ||
182 | {}, | ||
183 | }; | ||
184 | #endif | ||
185 | |||
186 | static const struct i2c_device_id isl9305_i2c_id[] = { | ||
187 | { "isl9305", }, | ||
188 | { "isl9305h", }, | ||
189 | { } | ||
190 | }; | ||
191 | MODULE_DEVICE_TABLE(i2c, isl9305_i2c_id); | ||
192 | |||
193 | static struct i2c_driver isl9305_regulator_driver = { | ||
194 | .driver = { | ||
195 | .name = "isl9305", | ||
196 | .owner = THIS_MODULE, | ||
197 | .of_match_table = of_match_ptr(isl9305_dt_ids), | ||
198 | }, | ||
199 | .probe = isl9305_i2c_probe, | ||
200 | .id_table = isl9305_i2c_id, | ||
201 | }; | ||
202 | |||
203 | module_i2c_driver(isl9305_regulator_driver); | ||
204 | |||
205 | MODULE_AUTHOR("Mark Brown"); | ||
206 | MODULE_DESCRIPTION("Intersil ISL9305 DCDC regulator"); | ||
207 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index c756955bfcc5..0ce8e4e0fa73 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c | |||
@@ -372,6 +372,7 @@ static bool ltc3589_volatile_reg(struct device *dev, unsigned int reg) | |||
372 | switch (reg) { | 372 | switch (reg) { |
373 | case LTC3589_IRQSTAT: | 373 | case LTC3589_IRQSTAT: |
374 | case LTC3589_PGSTAT: | 374 | case LTC3589_PGSTAT: |
375 | case LTC3589_VCCR: | ||
375 | return true; | 376 | return true; |
376 | } | 377 | } |
377 | return false; | 378 | return false; |
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index d23d0577754b..86db310d5304 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/regulator/driver.h> | 24 | #include <linux/regulator/driver.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/regulator/max1586.h> | 26 | #include <linux/regulator/max1586.h> |
27 | #include <linux/of_device.h> | ||
28 | #include <linux/regulator/of_regulator.h> | ||
27 | 29 | ||
28 | #define MAX1586_V3_MAX_VSEL 31 | 30 | #define MAX1586_V3_MAX_VSEL 31 |
29 | #define MAX1586_V6_MAX_VSEL 3 | 31 | #define MAX1586_V6_MAX_VSEL 3 |
@@ -157,13 +159,87 @@ static struct regulator_desc max1586_reg[] = { | |||
157 | }, | 159 | }, |
158 | }; | 160 | }; |
159 | 161 | ||
162 | static int of_get_max1586_platform_data(struct device *dev, | ||
163 | struct max1586_platform_data *pdata) | ||
164 | { | ||
165 | struct max1586_subdev_data *sub; | ||
166 | struct of_regulator_match rmatch[ARRAY_SIZE(max1586_reg)]; | ||
167 | struct device_node *np = dev->of_node; | ||
168 | int i, matched; | ||
169 | |||
170 | if (of_property_read_u32(np, "v3-gain", | ||
171 | &pdata->v3_gain) < 0) { | ||
172 | dev_err(dev, "%s has no 'v3-gain' property\n", np->full_name); | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | |||
176 | np = of_get_child_by_name(np, "regulators"); | ||
177 | if (!np) { | ||
178 | dev_err(dev, "missing 'regulators' subnode in DT\n"); | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | for (i = 0; i < ARRAY_SIZE(rmatch); i++) | ||
183 | rmatch[i].name = max1586_reg[i].name; | ||
184 | |||
185 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch)); | ||
186 | of_node_put(np); | ||
187 | /* | ||
188 | * If matched is 0, ie. neither Output_V3 nor Output_V6 have been found, | ||
189 | * return 0, which signals the normal situation where no subregulator is | ||
190 | * available. This is normal because the max1586 doesn't provide any | ||
191 | * readback support, so the subregulators can't report any status | ||
192 | * anyway. If matched < 0, return the error. | ||
193 | */ | ||
194 | if (matched <= 0) | ||
195 | return matched; | ||
196 | |||
197 | pdata->subdevs = devm_kzalloc(dev, sizeof(struct max1586_subdev_data) * | ||
198 | matched, GFP_KERNEL); | ||
199 | if (!pdata->subdevs) | ||
200 | return -ENOMEM; | ||
201 | |||
202 | pdata->num_subdevs = matched; | ||
203 | sub = pdata->subdevs; | ||
204 | |||
205 | for (i = 0; i < matched; i++) { | ||
206 | sub->id = i; | ||
207 | sub->name = rmatch[i].of_node->name; | ||
208 | sub->platform_data = rmatch[i].init_data; | ||
209 | sub++; | ||
210 | } | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static const struct of_device_id max1586_of_match[] = { | ||
216 | { .compatible = "maxim,max1586", }, | ||
217 | {}, | ||
218 | }; | ||
219 | MODULE_DEVICE_TABLE(of, max1586_of_match); | ||
220 | |||
160 | static int max1586_pmic_probe(struct i2c_client *client, | 221 | static int max1586_pmic_probe(struct i2c_client *client, |
161 | const struct i2c_device_id *i2c_id) | 222 | const struct i2c_device_id *i2c_id) |
162 | { | 223 | { |
163 | struct max1586_platform_data *pdata = dev_get_platdata(&client->dev); | 224 | struct max1586_platform_data *pdata, pdata_of; |
164 | struct regulator_config config = { }; | 225 | struct regulator_config config = { }; |
165 | struct max1586_data *max1586; | 226 | struct max1586_data *max1586; |
166 | int i, id; | 227 | int i, id, ret; |
228 | const struct of_device_id *match; | ||
229 | |||
230 | pdata = dev_get_platdata(&client->dev); | ||
231 | if (client->dev.of_node && !pdata) { | ||
232 | match = of_match_device(of_match_ptr(max1586_of_match), | ||
233 | &client->dev); | ||
234 | if (!match) { | ||
235 | dev_err(&client->dev, "Error: No device match found\n"); | ||
236 | return -ENODEV; | ||
237 | } | ||
238 | ret = of_get_max1586_platform_data(&client->dev, &pdata_of); | ||
239 | if (ret < 0) | ||
240 | return ret; | ||
241 | pdata = &pdata_of; | ||
242 | } | ||
167 | 243 | ||
168 | max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data), | 244 | max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data), |
169 | GFP_KERNEL); | 245 | GFP_KERNEL); |
@@ -229,6 +305,7 @@ static struct i2c_driver max1586_pmic_driver = { | |||
229 | .driver = { | 305 | .driver = { |
230 | .name = "max1586", | 306 | .name = "max1586", |
231 | .owner = THIS_MODULE, | 307 | .owner = THIS_MODULE, |
308 | .of_match_table = of_match_ptr(max1586_of_match), | ||
232 | }, | 309 | }, |
233 | .id_table = max1586_id, | 310 | .id_table = max1586_id, |
234 | }; | 311 | }; |
diff --git a/drivers/regulator/max77802.c b/drivers/regulator/max77802.c new file mode 100644 index 000000000000..d89792b084e9 --- /dev/null +++ b/drivers/regulator/max77802.c | |||
@@ -0,0 +1,586 @@ | |||
1 | /* | ||
2 | * max77802.c - Regulator driver for the Maxim 77802 | ||
3 | * | ||
4 | * Copyright (C) 2013-2014 Google, Inc | ||
5 | * Simon Glass <sjg@chromium.org> | ||
6 | * | ||
7 | * Copyright (C) 2012 Samsung Electronics | ||
8 | * Chiwoong Byun <woong.byun@smasung.com> | ||
9 | * Jonghwa Lee <jonghwa3.lee@samsung.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * This driver is based on max8997.c | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/bug.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/gpio/consumer.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/regulator/driver.h> | ||
32 | #include <linux/regulator/machine.h> | ||
33 | #include <linux/regulator/of_regulator.h> | ||
34 | #include <linux/mfd/max77686.h> | ||
35 | #include <linux/mfd/max77686-private.h> | ||
36 | |||
37 | /* Default ramp delay in case it is not manually set */ | ||
38 | #define MAX77802_RAMP_DELAY 100000 /* uV/us */ | ||
39 | |||
40 | #define MAX77802_OPMODE_SHIFT_LDO 6 | ||
41 | #define MAX77802_OPMODE_BUCK234_SHIFT 4 | ||
42 | #define MAX77802_OPMODE_MASK 0x3 | ||
43 | |||
44 | #define MAX77802_VSEL_MASK 0x3F | ||
45 | #define MAX77802_DVS_VSEL_MASK 0xFF | ||
46 | |||
47 | #define MAX77802_RAMP_RATE_MASK_2BIT 0xC0 | ||
48 | #define MAX77802_RAMP_RATE_SHIFT_2BIT 6 | ||
49 | #define MAX77802_RAMP_RATE_MASK_4BIT 0xF0 | ||
50 | #define MAX77802_RAMP_RATE_SHIFT_4BIT 4 | ||
51 | |||
52 | /* MAX77802 has two register formats: 2-bit and 4-bit */ | ||
53 | static const unsigned int ramp_table_77802_2bit[] = { | ||
54 | 12500, | ||
55 | 25000, | ||
56 | 50000, | ||
57 | 100000, | ||
58 | }; | ||
59 | |||
60 | static unsigned int ramp_table_77802_4bit[] = { | ||
61 | 1000, 2000, 3030, 4000, | ||
62 | 5000, 5880, 7140, 8330, | ||
63 | 9090, 10000, 11110, 12500, | ||
64 | 16670, 25000, 50000, 100000, | ||
65 | }; | ||
66 | |||
67 | struct max77802_regulator_prv { | ||
68 | unsigned int opmode[MAX77802_REG_MAX]; | ||
69 | }; | ||
70 | |||
71 | static int max77802_get_opmode_shift(int id) | ||
72 | { | ||
73 | if (id == MAX77802_BUCK1 || (id >= MAX77802_BUCK5 && | ||
74 | id <= MAX77802_BUCK10)) | ||
75 | return 0; | ||
76 | |||
77 | if (id >= MAX77802_BUCK2 && id <= MAX77802_BUCK4) | ||
78 | return MAX77802_OPMODE_BUCK234_SHIFT; | ||
79 | |||
80 | if (id >= MAX77802_LDO1 && id <= MAX77802_LDO35) | ||
81 | return MAX77802_OPMODE_SHIFT_LDO; | ||
82 | |||
83 | return -EINVAL; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Some BUCKS supports Normal[ON/OFF] mode during suspend | ||
88 | * | ||
89 | * BUCK 1, 6, 2-4, 5, 7-10 (all) | ||
90 | * | ||
91 | * The other mode (0x02) will make PWRREQ switch between normal | ||
92 | * and low power. | ||
93 | */ | ||
94 | static int max77802_buck_set_suspend_disable(struct regulator_dev *rdev) | ||
95 | { | ||
96 | unsigned int val = MAX77802_OPMODE_STANDBY; | ||
97 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); | ||
98 | int id = rdev_get_id(rdev); | ||
99 | int shift = max77802_get_opmode_shift(id); | ||
100 | |||
101 | max77802->opmode[id] = val; | ||
102 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
103 | rdev->desc->enable_mask, val << shift); | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state | ||
108 | * (Enable Control Logic1 by PWRREQ) | ||
109 | * | ||
110 | * LDOs 2, 4-19, 22-35. | ||
111 | * | ||
112 | */ | ||
113 | static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev, | ||
114 | unsigned int mode) | ||
115 | { | ||
116 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); | ||
117 | int id = rdev_get_id(rdev); | ||
118 | unsigned int val; | ||
119 | int shift = max77802_get_opmode_shift(id); | ||
120 | |||
121 | switch (mode) { | ||
122 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ | ||
123 | val = MAX77802_OPMODE_LP; | ||
124 | break; | ||
125 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | ||
126 | val = MAX77802_OPMODE_NORMAL; | ||
127 | break; | ||
128 | case REGULATOR_MODE_STANDBY: /* ON/OFF by PWRREQ */ | ||
129 | val = MAX77802_OPMODE_STANDBY; | ||
130 | break; | ||
131 | default: | ||
132 | dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", | ||
133 | rdev->desc->name, mode); | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | max77802->opmode[id] = val; | ||
138 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
139 | rdev->desc->enable_mask, val << shift); | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Mode 1 (Output[ON/OFF] by PWRREQ) is not supported on some LDOs | ||
144 | * (Enable Control Logic2 by PWRREQ) | ||
145 | * | ||
146 | * LDOs 1, 20, 21, and 3, | ||
147 | * | ||
148 | */ | ||
149 | static int max77802_ldo_set_suspend_mode_logic2(struct regulator_dev *rdev, | ||
150 | unsigned int mode) | ||
151 | { | ||
152 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); | ||
153 | int id = rdev_get_id(rdev); | ||
154 | unsigned int val; | ||
155 | int shift = max77802_get_opmode_shift(id); | ||
156 | |||
157 | switch (mode) { | ||
158 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ | ||
159 | val = MAX77802_OPMODE_LP; | ||
160 | break; | ||
161 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | ||
162 | val = MAX77802_OPMODE_NORMAL; | ||
163 | break; | ||
164 | default: | ||
165 | dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", | ||
166 | rdev->desc->name, mode); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | |||
170 | max77802->opmode[id] = val; | ||
171 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
172 | rdev->desc->enable_mask, val << shift); | ||
173 | } | ||
174 | |||
175 | static int max77802_enable(struct regulator_dev *rdev) | ||
176 | { | ||
177 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); | ||
178 | int id = rdev_get_id(rdev); | ||
179 | int shift = max77802_get_opmode_shift(id); | ||
180 | |||
181 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
182 | rdev->desc->enable_mask, | ||
183 | max77802->opmode[id] << shift); | ||
184 | } | ||
185 | |||
186 | static int max77802_find_ramp_value(struct regulator_dev *rdev, | ||
187 | const unsigned int limits[], int size, | ||
188 | unsigned int ramp_delay) | ||
189 | { | ||
190 | int i; | ||
191 | |||
192 | for (i = 0; i < size; i++) { | ||
193 | if (ramp_delay <= limits[i]) | ||
194 | return i; | ||
195 | } | ||
196 | |||
197 | /* Use maximum value for no ramp control */ | ||
198 | dev_warn(&rdev->dev, "%s: ramp_delay: %d not supported, setting 100000\n", | ||
199 | rdev->desc->name, ramp_delay); | ||
200 | return size - 1; | ||
201 | } | ||
202 | |||
203 | /* Used for BUCKs 2-4 */ | ||
204 | static int max77802_set_ramp_delay_2bit(struct regulator_dev *rdev, | ||
205 | int ramp_delay) | ||
206 | { | ||
207 | int id = rdev_get_id(rdev); | ||
208 | unsigned int ramp_value; | ||
209 | |||
210 | if (id > MAX77802_BUCK4) { | ||
211 | dev_warn(&rdev->dev, | ||
212 | "%s: regulator: ramp delay not supported\n", | ||
213 | rdev->desc->name); | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_2bit, | ||
217 | ARRAY_SIZE(ramp_table_77802_2bit), ramp_delay); | ||
218 | |||
219 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
220 | MAX77802_RAMP_RATE_MASK_2BIT, | ||
221 | ramp_value << MAX77802_RAMP_RATE_SHIFT_2BIT); | ||
222 | } | ||
223 | |||
224 | /* For BUCK1, 6 */ | ||
225 | static int max77802_set_ramp_delay_4bit(struct regulator_dev *rdev, | ||
226 | int ramp_delay) | ||
227 | { | ||
228 | unsigned int ramp_value; | ||
229 | |||
230 | ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_4bit, | ||
231 | ARRAY_SIZE(ramp_table_77802_4bit), ramp_delay); | ||
232 | |||
233 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
234 | MAX77802_RAMP_RATE_MASK_4BIT, | ||
235 | ramp_value << MAX77802_RAMP_RATE_SHIFT_4BIT); | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * LDOs 2, 4-19, 22-35 | ||
240 | */ | ||
241 | static struct regulator_ops max77802_ldo_ops_logic1 = { | ||
242 | .list_voltage = regulator_list_voltage_linear, | ||
243 | .map_voltage = regulator_map_voltage_linear, | ||
244 | .is_enabled = regulator_is_enabled_regmap, | ||
245 | .enable = max77802_enable, | ||
246 | .disable = regulator_disable_regmap, | ||
247 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
248 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
249 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
250 | .set_suspend_mode = max77802_ldo_set_suspend_mode_logic1, | ||
251 | }; | ||
252 | |||
253 | /* | ||
254 | * LDOs 1, 20, 21, 3 | ||
255 | */ | ||
256 | static struct regulator_ops max77802_ldo_ops_logic2 = { | ||
257 | .list_voltage = regulator_list_voltage_linear, | ||
258 | .map_voltage = regulator_map_voltage_linear, | ||
259 | .is_enabled = regulator_is_enabled_regmap, | ||
260 | .enable = max77802_enable, | ||
261 | .disable = regulator_disable_regmap, | ||
262 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
263 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
264 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
265 | .set_suspend_mode = max77802_ldo_set_suspend_mode_logic2, | ||
266 | }; | ||
267 | |||
268 | /* BUCKS 1, 6 */ | ||
269 | static struct regulator_ops max77802_buck_16_dvs_ops = { | ||
270 | .list_voltage = regulator_list_voltage_linear, | ||
271 | .map_voltage = regulator_map_voltage_linear, | ||
272 | .is_enabled = regulator_is_enabled_regmap, | ||
273 | .enable = max77802_enable, | ||
274 | .disable = regulator_disable_regmap, | ||
275 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
276 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
277 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
278 | .set_ramp_delay = max77802_set_ramp_delay_4bit, | ||
279 | .set_suspend_disable = max77802_buck_set_suspend_disable, | ||
280 | }; | ||
281 | |||
282 | /* BUCKs 2-4, 5, 7-10 */ | ||
283 | static struct regulator_ops max77802_buck_dvs_ops = { | ||
284 | .list_voltage = regulator_list_voltage_linear, | ||
285 | .map_voltage = regulator_map_voltage_linear, | ||
286 | .is_enabled = regulator_is_enabled_regmap, | ||
287 | .enable = max77802_enable, | ||
288 | .disable = regulator_disable_regmap, | ||
289 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
290 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
291 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
292 | .set_ramp_delay = max77802_set_ramp_delay_2bit, | ||
293 | .set_suspend_disable = max77802_buck_set_suspend_disable, | ||
294 | }; | ||
295 | |||
296 | /* LDOs 3-7, 9-14, 18-26, 28, 29, 32-34 */ | ||
297 | #define regulator_77802_desc_p_ldo(num, supply, log) { \ | ||
298 | .name = "LDO"#num, \ | ||
299 | .id = MAX77802_LDO##num, \ | ||
300 | .supply_name = "inl"#supply, \ | ||
301 | .ops = &max77802_ldo_ops_logic##log, \ | ||
302 | .type = REGULATOR_VOLTAGE, \ | ||
303 | .owner = THIS_MODULE, \ | ||
304 | .min_uV = 800000, \ | ||
305 | .uV_step = 50000, \ | ||
306 | .ramp_delay = MAX77802_RAMP_DELAY, \ | ||
307 | .n_voltages = 1 << 6, \ | ||
308 | .vsel_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ | ||
309 | .vsel_mask = MAX77802_VSEL_MASK, \ | ||
310 | .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ | ||
311 | .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ | ||
312 | } | ||
313 | |||
314 | /* LDOs 1, 2, 8, 15, 17, 27, 30, 35 */ | ||
315 | #define regulator_77802_desc_n_ldo(num, supply, log) { \ | ||
316 | .name = "LDO"#num, \ | ||
317 | .id = MAX77802_LDO##num, \ | ||
318 | .supply_name = "inl"#supply, \ | ||
319 | .ops = &max77802_ldo_ops_logic##log, \ | ||
320 | .type = REGULATOR_VOLTAGE, \ | ||
321 | .owner = THIS_MODULE, \ | ||
322 | .min_uV = 800000, \ | ||
323 | .uV_step = 25000, \ | ||
324 | .ramp_delay = MAX77802_RAMP_DELAY, \ | ||
325 | .n_voltages = 1 << 6, \ | ||
326 | .vsel_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ | ||
327 | .vsel_mask = MAX77802_VSEL_MASK, \ | ||
328 | .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ | ||
329 | .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ | ||
330 | } | ||
331 | |||
332 | /* BUCKs 1, 6 */ | ||
333 | #define regulator_77802_desc_16_buck(num) { \ | ||
334 | .name = "BUCK"#num, \ | ||
335 | .id = MAX77802_BUCK##num, \ | ||
336 | .supply_name = "inb"#num, \ | ||
337 | .ops = &max77802_buck_16_dvs_ops, \ | ||
338 | .type = REGULATOR_VOLTAGE, \ | ||
339 | .owner = THIS_MODULE, \ | ||
340 | .min_uV = 612500, \ | ||
341 | .uV_step = 6250, \ | ||
342 | .ramp_delay = MAX77802_RAMP_DELAY, \ | ||
343 | .n_voltages = 1 << 8, \ | ||
344 | .vsel_reg = MAX77802_REG_BUCK ## num ## DVS1, \ | ||
345 | .vsel_mask = MAX77802_DVS_VSEL_MASK, \ | ||
346 | .enable_reg = MAX77802_REG_BUCK ## num ## CTRL, \ | ||
347 | .enable_mask = MAX77802_OPMODE_MASK, \ | ||
348 | } | ||
349 | |||
350 | /* BUCKS 2-4 */ | ||
351 | #define regulator_77802_desc_234_buck(num) { \ | ||
352 | .name = "BUCK"#num, \ | ||
353 | .id = MAX77802_BUCK##num, \ | ||
354 | .supply_name = "inb"#num, \ | ||
355 | .ops = &max77802_buck_dvs_ops, \ | ||
356 | .type = REGULATOR_VOLTAGE, \ | ||
357 | .owner = THIS_MODULE, \ | ||
358 | .min_uV = 600000, \ | ||
359 | .uV_step = 6250, \ | ||
360 | .ramp_delay = MAX77802_RAMP_DELAY, \ | ||
361 | .n_voltages = 0x91, \ | ||
362 | .vsel_reg = MAX77802_REG_BUCK ## num ## DVS1, \ | ||
363 | .vsel_mask = MAX77802_DVS_VSEL_MASK, \ | ||
364 | .enable_reg = MAX77802_REG_BUCK ## num ## CTRL1, \ | ||
365 | .enable_mask = MAX77802_OPMODE_MASK << \ | ||
366 | MAX77802_OPMODE_BUCK234_SHIFT, \ | ||
367 | } | ||
368 | |||
369 | /* BUCK 5 */ | ||
370 | #define regulator_77802_desc_buck5(num) { \ | ||
371 | .name = "BUCK"#num, \ | ||
372 | .id = MAX77802_BUCK##num, \ | ||
373 | .supply_name = "inb"#num, \ | ||
374 | .ops = &max77802_buck_dvs_ops, \ | ||
375 | .type = REGULATOR_VOLTAGE, \ | ||
376 | .owner = THIS_MODULE, \ | ||
377 | .min_uV = 750000, \ | ||
378 | .uV_step = 50000, \ | ||
379 | .ramp_delay = MAX77802_RAMP_DELAY, \ | ||
380 | .n_voltages = 1 << 6, \ | ||
381 | .vsel_reg = MAX77802_REG_BUCK5OUT, \ | ||
382 | .vsel_mask = MAX77802_VSEL_MASK, \ | ||
383 | .enable_reg = MAX77802_REG_BUCK5CTRL, \ | ||
384 | .enable_mask = MAX77802_OPMODE_MASK, \ | ||
385 | } | ||
386 | |||
387 | /* BUCKs 7-10 */ | ||
388 | #define regulator_77802_desc_buck7_10(num) { \ | ||
389 | .name = "BUCK"#num, \ | ||
390 | .id = MAX77802_BUCK##num, \ | ||
391 | .supply_name = "inb"#num, \ | ||
392 | .ops = &max77802_buck_dvs_ops, \ | ||
393 | .type = REGULATOR_VOLTAGE, \ | ||
394 | .owner = THIS_MODULE, \ | ||
395 | .min_uV = 750000, \ | ||
396 | .uV_step = 50000, \ | ||
397 | .ramp_delay = MAX77802_RAMP_DELAY, \ | ||
398 | .n_voltages = 1 << 6, \ | ||
399 | .vsel_reg = MAX77802_REG_BUCK7OUT + (num - 7) * 3, \ | ||
400 | .vsel_mask = MAX77802_VSEL_MASK, \ | ||
401 | .enable_reg = MAX77802_REG_BUCK7CTRL + (num - 7) * 3, \ | ||
402 | .enable_mask = MAX77802_OPMODE_MASK, \ | ||
403 | } | ||
404 | |||
405 | static struct regulator_desc regulators[] = { | ||
406 | regulator_77802_desc_16_buck(1), | ||
407 | regulator_77802_desc_234_buck(2), | ||
408 | regulator_77802_desc_234_buck(3), | ||
409 | regulator_77802_desc_234_buck(4), | ||
410 | regulator_77802_desc_buck5(5), | ||
411 | regulator_77802_desc_16_buck(6), | ||
412 | regulator_77802_desc_buck7_10(7), | ||
413 | regulator_77802_desc_buck7_10(8), | ||
414 | regulator_77802_desc_buck7_10(9), | ||
415 | regulator_77802_desc_buck7_10(10), | ||
416 | regulator_77802_desc_n_ldo(1, 10, 2), | ||
417 | regulator_77802_desc_n_ldo(2, 10, 1), | ||
418 | regulator_77802_desc_p_ldo(3, 3, 2), | ||
419 | regulator_77802_desc_p_ldo(4, 6, 1), | ||
420 | regulator_77802_desc_p_ldo(5, 3, 1), | ||
421 | regulator_77802_desc_p_ldo(6, 3, 1), | ||
422 | regulator_77802_desc_p_ldo(7, 3, 1), | ||
423 | regulator_77802_desc_n_ldo(8, 1, 1), | ||
424 | regulator_77802_desc_p_ldo(9, 5, 1), | ||
425 | regulator_77802_desc_p_ldo(10, 4, 1), | ||
426 | regulator_77802_desc_p_ldo(11, 4, 1), | ||
427 | regulator_77802_desc_p_ldo(12, 9, 1), | ||
428 | regulator_77802_desc_p_ldo(13, 4, 1), | ||
429 | regulator_77802_desc_p_ldo(14, 4, 1), | ||
430 | regulator_77802_desc_n_ldo(15, 1, 1), | ||
431 | regulator_77802_desc_n_ldo(17, 2, 1), | ||
432 | regulator_77802_desc_p_ldo(18, 7, 1), | ||
433 | regulator_77802_desc_p_ldo(19, 5, 1), | ||
434 | regulator_77802_desc_p_ldo(20, 7, 2), | ||
435 | regulator_77802_desc_p_ldo(21, 6, 2), | ||
436 | regulator_77802_desc_p_ldo(23, 9, 1), | ||
437 | regulator_77802_desc_p_ldo(24, 6, 1), | ||
438 | regulator_77802_desc_p_ldo(25, 9, 1), | ||
439 | regulator_77802_desc_p_ldo(26, 9, 1), | ||
440 | regulator_77802_desc_n_ldo(27, 2, 1), | ||
441 | regulator_77802_desc_p_ldo(28, 7, 1), | ||
442 | regulator_77802_desc_p_ldo(29, 7, 1), | ||
443 | regulator_77802_desc_n_ldo(30, 2, 1), | ||
444 | regulator_77802_desc_p_ldo(32, 9, 1), | ||
445 | regulator_77802_desc_p_ldo(33, 6, 1), | ||
446 | regulator_77802_desc_p_ldo(34, 9, 1), | ||
447 | regulator_77802_desc_n_ldo(35, 2, 1), | ||
448 | }; | ||
449 | |||
450 | #ifdef CONFIG_OF | ||
451 | static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev, | ||
452 | struct max77686_platform_data *pdata) | ||
453 | { | ||
454 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
455 | struct device_node *pmic_np, *regulators_np; | ||
456 | struct max77686_regulator_data *rdata; | ||
457 | struct of_regulator_match rmatch; | ||
458 | unsigned int i; | ||
459 | |||
460 | pmic_np = iodev->dev->of_node; | ||
461 | regulators_np = of_get_child_by_name(pmic_np, "regulators"); | ||
462 | if (!regulators_np) { | ||
463 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | ||
464 | return -EINVAL; | ||
465 | } | ||
466 | |||
467 | pdata->num_regulators = ARRAY_SIZE(regulators); | ||
468 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * | ||
469 | pdata->num_regulators, GFP_KERNEL); | ||
470 | if (!rdata) { | ||
471 | of_node_put(regulators_np); | ||
472 | return -ENOMEM; | ||
473 | } | ||
474 | |||
475 | for (i = 0; i < pdata->num_regulators; i++) { | ||
476 | rmatch.name = regulators[i].name; | ||
477 | rmatch.init_data = NULL; | ||
478 | rmatch.of_node = NULL; | ||
479 | if (of_regulator_match(&pdev->dev, regulators_np, &rmatch, | ||
480 | 1) != 1) { | ||
481 | dev_warn(&pdev->dev, "No matching regulator for '%s'\n", | ||
482 | rmatch.name); | ||
483 | continue; | ||
484 | } | ||
485 | rdata[i].initdata = rmatch.init_data; | ||
486 | rdata[i].of_node = rmatch.of_node; | ||
487 | rdata[i].id = regulators[i].id; | ||
488 | } | ||
489 | |||
490 | pdata->regulators = rdata; | ||
491 | of_node_put(regulators_np); | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | #else | ||
496 | static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev, | ||
497 | struct max77686_platform_data *pdata) | ||
498 | { | ||
499 | return 0; | ||
500 | } | ||
501 | #endif /* CONFIG_OF */ | ||
502 | |||
503 | static int max77802_pmic_probe(struct platform_device *pdev) | ||
504 | { | ||
505 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
506 | struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
507 | struct max77802_regulator_prv *max77802; | ||
508 | int i, ret = 0, val; | ||
509 | struct regulator_config config = { }; | ||
510 | |||
511 | /* This is allocated by the MFD driver */ | ||
512 | if (!pdata) { | ||
513 | dev_err(&pdev->dev, "no platform data found for regulator\n"); | ||
514 | return -ENODEV; | ||
515 | } | ||
516 | |||
517 | max77802 = devm_kzalloc(&pdev->dev, | ||
518 | sizeof(struct max77802_regulator_prv), | ||
519 | GFP_KERNEL); | ||
520 | if (!max77802) | ||
521 | return -ENOMEM; | ||
522 | |||
523 | if (iodev->dev->of_node) { | ||
524 | ret = max77802_pmic_dt_parse_pdata(pdev, pdata); | ||
525 | if (ret) | ||
526 | return ret; | ||
527 | } | ||
528 | |||
529 | config.dev = iodev->dev; | ||
530 | config.regmap = iodev->regmap; | ||
531 | config.driver_data = max77802; | ||
532 | platform_set_drvdata(pdev, max77802); | ||
533 | |||
534 | for (i = 0; i < MAX77802_REG_MAX; i++) { | ||
535 | struct regulator_dev *rdev; | ||
536 | int id = pdata->regulators[i].id; | ||
537 | int shift = max77802_get_opmode_shift(id); | ||
538 | |||
539 | config.init_data = pdata->regulators[i].initdata; | ||
540 | config.of_node = pdata->regulators[i].of_node; | ||
541 | |||
542 | ret = regmap_read(iodev->regmap, regulators[i].enable_reg, &val); | ||
543 | val = val >> shift & MAX77802_OPMODE_MASK; | ||
544 | |||
545 | /* | ||
546 | * If the regulator is disabled and the system warm rebooted, | ||
547 | * the hardware reports OFF as the regulator operating mode. | ||
548 | * Default to operating mode NORMAL in that case. | ||
549 | */ | ||
550 | if (val == MAX77802_OPMODE_OFF) | ||
551 | max77802->opmode[id] = MAX77802_OPMODE_NORMAL; | ||
552 | else | ||
553 | max77802->opmode[id] = val; | ||
554 | |||
555 | rdev = devm_regulator_register(&pdev->dev, | ||
556 | ®ulators[i], &config); | ||
557 | if (IS_ERR(rdev)) { | ||
558 | dev_err(&pdev->dev, | ||
559 | "regulator init failed for %d\n", i); | ||
560 | return PTR_ERR(rdev); | ||
561 | } | ||
562 | } | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | static const struct platform_device_id max77802_pmic_id[] = { | ||
568 | {"max77802-pmic", 0}, | ||
569 | { }, | ||
570 | }; | ||
571 | MODULE_DEVICE_TABLE(platform, max77802_pmic_id); | ||
572 | |||
573 | static struct platform_driver max77802_pmic_driver = { | ||
574 | .driver = { | ||
575 | .name = "max77802-pmic", | ||
576 | .owner = THIS_MODULE, | ||
577 | }, | ||
578 | .probe = max77802_pmic_probe, | ||
579 | .id_table = max77802_pmic_id, | ||
580 | }; | ||
581 | |||
582 | module_platform_driver(max77802_pmic_driver); | ||
583 | |||
584 | MODULE_DESCRIPTION("MAXIM 77802 Regulator Driver"); | ||
585 | MODULE_AUTHOR("Simon Glass <sjg@chromium.org>"); | ||
586 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index f374fa57220f..793b662a1967 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c | |||
@@ -526,6 +526,7 @@ static unsigned int mc13892_vcam_get_mode(struct regulator_dev *rdev) | |||
526 | return REGULATOR_MODE_NORMAL; | 526 | return REGULATOR_MODE_NORMAL; |
527 | } | 527 | } |
528 | 528 | ||
529 | static struct regulator_ops mc13892_vcam_ops; | ||
529 | 530 | ||
530 | static int mc13892_regulator_probe(struct platform_device *pdev) | 531 | static int mc13892_regulator_probe(struct platform_device *pdev) |
531 | { | 532 | { |
@@ -582,10 +583,12 @@ static int mc13892_regulator_probe(struct platform_device *pdev) | |||
582 | } | 583 | } |
583 | mc13xxx_unlock(mc13892); | 584 | mc13xxx_unlock(mc13892); |
584 | 585 | ||
585 | mc13892_regulators[MC13892_VCAM].desc.ops->set_mode | 586 | /* update mc13892_vcam ops */ |
586 | = mc13892_vcam_set_mode; | 587 | memcpy(&mc13892_vcam_ops, mc13892_regulators[MC13892_VCAM].desc.ops, |
587 | mc13892_regulators[MC13892_VCAM].desc.ops->get_mode | 588 | sizeof(struct regulator_ops)); |
588 | = mc13892_vcam_get_mode; | 589 | mc13892_vcam_ops.set_mode = mc13892_vcam_set_mode, |
590 | mc13892_vcam_ops.get_mode = mc13892_vcam_get_mode, | ||
591 | mc13892_regulators[MC13892_VCAM].desc.ops = &mc13892_vcam_ops; | ||
589 | 592 | ||
590 | mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators, | 593 | mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators, |
591 | ARRAY_SIZE(mc13892_regulators)); | 594 | ARRAY_SIZE(mc13892_regulators)); |
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index ee5e67bc8d5b..7a51814abdc5 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c | |||
@@ -14,8 +14,11 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/regulator/machine.h> | 16 | #include <linux/regulator/machine.h> |
17 | #include <linux/regulator/driver.h> | ||
17 | #include <linux/regulator/of_regulator.h> | 18 | #include <linux/regulator/of_regulator.h> |
18 | 19 | ||
20 | #include "internal.h" | ||
21 | |||
19 | static void of_get_regulation_constraints(struct device_node *np, | 22 | static void of_get_regulation_constraints(struct device_node *np, |
20 | struct regulator_init_data **init_data) | 23 | struct regulator_init_data **init_data) |
21 | { | 24 | { |
@@ -189,3 +192,51 @@ int of_regulator_match(struct device *dev, struct device_node *node, | |||
189 | return count; | 192 | return count; |
190 | } | 193 | } |
191 | EXPORT_SYMBOL_GPL(of_regulator_match); | 194 | EXPORT_SYMBOL_GPL(of_regulator_match); |
195 | |||
196 | struct regulator_init_data *regulator_of_get_init_data(struct device *dev, | ||
197 | const struct regulator_desc *desc, | ||
198 | struct device_node **node) | ||
199 | { | ||
200 | struct device_node *search, *child; | ||
201 | struct regulator_init_data *init_data = NULL; | ||
202 | const char *name; | ||
203 | |||
204 | if (!dev->of_node || !desc->of_match) | ||
205 | return NULL; | ||
206 | |||
207 | if (desc->regulators_node) | ||
208 | search = of_get_child_by_name(dev->of_node, | ||
209 | desc->regulators_node); | ||
210 | else | ||
211 | search = dev->of_node; | ||
212 | |||
213 | if (!search) { | ||
214 | dev_err(dev, "Failed to find regulator container node\n"); | ||
215 | return NULL; | ||
216 | } | ||
217 | |||
218 | for_each_child_of_node(search, child) { | ||
219 | name = of_get_property(child, "regulator-compatible", NULL); | ||
220 | if (!name) | ||
221 | name = child->name; | ||
222 | |||
223 | if (strcmp(desc->of_match, name)) | ||
224 | continue; | ||
225 | |||
226 | init_data = of_get_regulator_init_data(dev, child); | ||
227 | if (!init_data) { | ||
228 | dev_err(dev, | ||
229 | "failed to parse DT for regulator %s\n", | ||
230 | child->name); | ||
231 | break; | ||
232 | } | ||
233 | |||
234 | of_node_get(child); | ||
235 | *node = child; | ||
236 | break; | ||
237 | } | ||
238 | |||
239 | of_node_put(search); | ||
240 | |||
241 | return init_data; | ||
242 | } | ||
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c new file mode 100644 index 000000000000..d3f55eaea058 --- /dev/null +++ b/drivers/regulator/pwm-regulator.c | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * Regulator driver for 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 | struct pwm_regulator_data { | ||
24 | struct regulator_desc desc; | ||
25 | struct pwm_voltages *duty_cycle_table; | ||
26 | struct pwm_device *pwm; | ||
27 | bool enabled; | ||
28 | int state; | ||
29 | }; | ||
30 | |||
31 | struct pwm_voltages { | ||
32 | unsigned int uV; | ||
33 | unsigned int dutycycle; | ||
34 | }; | ||
35 | |||
36 | static int pwm_regulator_get_voltage_sel(struct regulator_dev *dev) | ||
37 | { | ||
38 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
39 | |||
40 | return drvdata->state; | ||
41 | } | ||
42 | |||
43 | static int pwm_regulator_set_voltage_sel(struct regulator_dev *dev, | ||
44 | unsigned selector) | ||
45 | { | ||
46 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
47 | unsigned int pwm_reg_period; | ||
48 | int dutycycle; | ||
49 | int ret; | ||
50 | |||
51 | pwm_reg_period = pwm_get_period(drvdata->pwm); | ||
52 | |||
53 | dutycycle = (pwm_reg_period * | ||
54 | drvdata->duty_cycle_table[selector].dutycycle) / 100; | ||
55 | |||
56 | ret = pwm_config(drvdata->pwm, dutycycle, pwm_reg_period); | ||
57 | if (ret) { | ||
58 | dev_err(&dev->dev, "Failed to configure PWM\n"); | ||
59 | return ret; | ||
60 | } | ||
61 | |||
62 | drvdata->state = selector; | ||
63 | |||
64 | if (!drvdata->enabled) { | ||
65 | ret = pwm_enable(drvdata->pwm); | ||
66 | if (ret) { | ||
67 | dev_err(&dev->dev, "Failed to enable PWM\n"); | ||
68 | return ret; | ||
69 | } | ||
70 | drvdata->enabled = true; | ||
71 | } | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int pwm_regulator_list_voltage(struct regulator_dev *dev, | ||
77 | unsigned selector) | ||
78 | { | ||
79 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
80 | |||
81 | if (selector >= drvdata->desc.n_voltages) | ||
82 | return -EINVAL; | ||
83 | |||
84 | return drvdata->duty_cycle_table[selector].uV; | ||
85 | } | ||
86 | |||
87 | static struct regulator_ops pwm_regulator_voltage_ops = { | ||
88 | .set_voltage_sel = pwm_regulator_set_voltage_sel, | ||
89 | .get_voltage_sel = pwm_regulator_get_voltage_sel, | ||
90 | .list_voltage = pwm_regulator_list_voltage, | ||
91 | .map_voltage = regulator_map_voltage_iterate, | ||
92 | }; | ||
93 | |||
94 | static const struct regulator_desc pwm_regulator_desc = { | ||
95 | .name = "pwm-regulator", | ||
96 | .ops = &pwm_regulator_voltage_ops, | ||
97 | .type = REGULATOR_VOLTAGE, | ||
98 | .owner = THIS_MODULE, | ||
99 | .supply_name = "pwm", | ||
100 | }; | ||
101 | |||
102 | static int pwm_regulator_probe(struct platform_device *pdev) | ||
103 | { | ||
104 | struct pwm_regulator_data *drvdata; | ||
105 | struct property *prop; | ||
106 | struct regulator_dev *regulator; | ||
107 | struct regulator_config config = { }; | ||
108 | struct device_node *np = pdev->dev.of_node; | ||
109 | int length, ret; | ||
110 | |||
111 | if (!np) { | ||
112 | dev_err(&pdev->dev, "Device Tree node missing\n"); | ||
113 | return -EINVAL; | ||
114 | } | ||
115 | |||
116 | drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); | ||
117 | if (!drvdata) | ||
118 | return -ENOMEM; | ||
119 | |||
120 | memcpy(&drvdata->desc, &pwm_regulator_desc, sizeof(pwm_regulator_desc)); | ||
121 | |||
122 | /* determine the number of voltage-table */ | ||
123 | prop = of_find_property(np, "voltage-table", &length); | ||
124 | if (!prop) { | ||
125 | dev_err(&pdev->dev, "No voltage-table\n"); | ||
126 | return -EINVAL; | ||
127 | } | ||
128 | |||
129 | if ((length < sizeof(*drvdata->duty_cycle_table)) || | ||
130 | (length % sizeof(*drvdata->duty_cycle_table))) { | ||
131 | dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n", | ||
132 | length); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | |||
136 | drvdata->desc.n_voltages = length / sizeof(*drvdata->duty_cycle_table); | ||
137 | |||
138 | drvdata->duty_cycle_table = devm_kzalloc(&pdev->dev, | ||
139 | length, GFP_KERNEL); | ||
140 | if (!drvdata->duty_cycle_table) | ||
141 | return -ENOMEM; | ||
142 | |||
143 | /* read voltage table from DT property */ | ||
144 | ret = of_property_read_u32_array(np, "voltage-table", | ||
145 | (u32 *)drvdata->duty_cycle_table, | ||
146 | length / sizeof(u32)); | ||
147 | if (ret < 0) { | ||
148 | dev_err(&pdev->dev, "read voltage-table failed\n"); | ||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | config.init_data = of_get_regulator_init_data(&pdev->dev, np); | ||
153 | if (!config.init_data) | ||
154 | return -ENOMEM; | ||
155 | |||
156 | config.of_node = np; | ||
157 | config.dev = &pdev->dev; | ||
158 | config.driver_data = drvdata; | ||
159 | |||
160 | drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); | ||
161 | if (IS_ERR(drvdata->pwm)) { | ||
162 | dev_err(&pdev->dev, "Failed to get PWM\n"); | ||
163 | return PTR_ERR(drvdata->pwm); | ||
164 | } | ||
165 | |||
166 | regulator = devm_regulator_register(&pdev->dev, | ||
167 | &drvdata->desc, &config); | ||
168 | if (IS_ERR(regulator)) { | ||
169 | dev_err(&pdev->dev, "Failed to register regulator %s\n", | ||
170 | drvdata->desc.name); | ||
171 | return PTR_ERR(regulator); | ||
172 | } | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static const struct of_device_id pwm_of_match[] = { | ||
178 | { .compatible = "pwm-regulator" }, | ||
179 | { }, | ||
180 | }; | ||
181 | MODULE_DEVICE_TABLE(of, pwm_of_match); | ||
182 | |||
183 | static struct platform_driver pwm_regulator_driver = { | ||
184 | .driver = { | ||
185 | .name = "pwm-regulator", | ||
186 | .owner = THIS_MODULE, | ||
187 | .of_match_table = of_match_ptr(pwm_of_match), | ||
188 | }, | ||
189 | .probe = pwm_regulator_probe, | ||
190 | }; | ||
191 | |||
192 | module_platform_driver(pwm_regulator_driver); | ||
193 | |||
194 | MODULE_LICENSE("GPL"); | ||
195 | MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>"); | ||
196 | MODULE_DESCRIPTION("PWM Regulator Driver"); | ||
197 | MODULE_ALIAS("platform:pwm-regulator"); | ||
diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c new file mode 100644 index 000000000000..b55cd5b50ebe --- /dev/null +++ b/drivers/regulator/qcom_rpm-regulator.c | |||
@@ -0,0 +1,798 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014, Sony Mobile Communications AB. | ||
3 | * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 and | ||
7 | * only version 2 as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_device.h> | ||
19 | #include <linux/regulator/driver.h> | ||
20 | #include <linux/regulator/machine.h> | ||
21 | #include <linux/regulator/of_regulator.h> | ||
22 | #include <linux/mfd/qcom_rpm.h> | ||
23 | |||
24 | #include <dt-bindings/mfd/qcom-rpm.h> | ||
25 | |||
26 | #define MAX_REQUEST_LEN 2 | ||
27 | |||
28 | struct request_member { | ||
29 | int word; | ||
30 | unsigned int mask; | ||
31 | int shift; | ||
32 | }; | ||
33 | |||
34 | struct rpm_reg_parts { | ||
35 | struct request_member mV; /* used if voltage is in mV */ | ||
36 | struct request_member uV; /* used if voltage is in uV */ | ||
37 | struct request_member ip; /* peak current in mA */ | ||
38 | struct request_member pd; /* pull down enable */ | ||
39 | struct request_member ia; /* average current in mA */ | ||
40 | struct request_member fm; /* force mode */ | ||
41 | struct request_member pm; /* power mode */ | ||
42 | struct request_member pc; /* pin control */ | ||
43 | struct request_member pf; /* pin function */ | ||
44 | struct request_member enable_state; /* NCP and switch */ | ||
45 | struct request_member comp_mode; /* NCP */ | ||
46 | struct request_member freq; /* frequency: NCP and SMPS */ | ||
47 | struct request_member freq_clk_src; /* clock source: SMPS */ | ||
48 | struct request_member hpm; /* switch: control OCP and SS */ | ||
49 | int request_len; | ||
50 | }; | ||
51 | |||
52 | #define FORCE_MODE_IS_2_BITS(reg) \ | ||
53 | (((reg)->parts->fm.mask >> (reg)->parts->fm.shift) == 3) | ||
54 | |||
55 | struct qcom_rpm_reg { | ||
56 | struct qcom_rpm *rpm; | ||
57 | |||
58 | struct mutex lock; | ||
59 | struct device *dev; | ||
60 | struct regulator_desc desc; | ||
61 | const struct rpm_reg_parts *parts; | ||
62 | |||
63 | int resource; | ||
64 | u32 val[MAX_REQUEST_LEN]; | ||
65 | |||
66 | int uV; | ||
67 | int is_enabled; | ||
68 | |||
69 | bool supports_force_mode_auto; | ||
70 | bool supports_force_mode_bypass; | ||
71 | }; | ||
72 | |||
73 | static const struct rpm_reg_parts rpm8660_ldo_parts = { | ||
74 | .request_len = 2, | ||
75 | .mV = { 0, 0x00000FFF, 0 }, | ||
76 | .ip = { 0, 0x00FFF000, 12 }, | ||
77 | .fm = { 0, 0x03000000, 24 }, | ||
78 | .pc = { 0, 0x3C000000, 26 }, | ||
79 | .pf = { 0, 0xC0000000, 30 }, | ||
80 | .pd = { 1, 0x00000001, 0 }, | ||
81 | .ia = { 1, 0x00001FFE, 1 }, | ||
82 | }; | ||
83 | |||
84 | static const struct rpm_reg_parts rpm8660_smps_parts = { | ||
85 | .request_len = 2, | ||
86 | .mV = { 0, 0x00000FFF, 0 }, | ||
87 | .ip = { 0, 0x00FFF000, 12 }, | ||
88 | .fm = { 0, 0x03000000, 24 }, | ||
89 | .pc = { 0, 0x3C000000, 26 }, | ||
90 | .pf = { 0, 0xC0000000, 30 }, | ||
91 | .pd = { 1, 0x00000001, 0 }, | ||
92 | .ia = { 1, 0x00001FFE, 1 }, | ||
93 | .freq = { 1, 0x001FE000, 13 }, | ||
94 | .freq_clk_src = { 1, 0x00600000, 21 }, | ||
95 | }; | ||
96 | |||
97 | static const struct rpm_reg_parts rpm8660_switch_parts = { | ||
98 | .request_len = 1, | ||
99 | .enable_state = { 0, 0x00000001, 0 }, | ||
100 | .pd = { 0, 0x00000002, 1 }, | ||
101 | .pc = { 0, 0x0000003C, 2 }, | ||
102 | .pf = { 0, 0x000000C0, 6 }, | ||
103 | .hpm = { 0, 0x00000300, 8 }, | ||
104 | }; | ||
105 | |||
106 | static const struct rpm_reg_parts rpm8660_ncp_parts = { | ||
107 | .request_len = 1, | ||
108 | .mV = { 0, 0x00000FFF, 0 }, | ||
109 | .enable_state = { 0, 0x00001000, 12 }, | ||
110 | .comp_mode = { 0, 0x00002000, 13 }, | ||
111 | .freq = { 0, 0x003FC000, 14 }, | ||
112 | }; | ||
113 | |||
114 | static const struct rpm_reg_parts rpm8960_ldo_parts = { | ||
115 | .request_len = 2, | ||
116 | .uV = { 0, 0x007FFFFF, 0 }, | ||
117 | .pd = { 0, 0x00800000, 23 }, | ||
118 | .pc = { 0, 0x0F000000, 24 }, | ||
119 | .pf = { 0, 0xF0000000, 28 }, | ||
120 | .ip = { 1, 0x000003FF, 0 }, | ||
121 | .ia = { 1, 0x000FFC00, 10 }, | ||
122 | .fm = { 1, 0x00700000, 20 }, | ||
123 | }; | ||
124 | |||
125 | static const struct rpm_reg_parts rpm8960_smps_parts = { | ||
126 | .request_len = 2, | ||
127 | .uV = { 0, 0x007FFFFF, 0 }, | ||
128 | .pd = { 0, 0x00800000, 23 }, | ||
129 | .pc = { 0, 0x0F000000, 24 }, | ||
130 | .pf = { 0, 0xF0000000, 28 }, | ||
131 | .ip = { 1, 0x000003FF, 0 }, | ||
132 | .ia = { 1, 0x000FFC00, 10 }, | ||
133 | .fm = { 1, 0x00700000, 20 }, | ||
134 | .pm = { 1, 0x00800000, 23 }, | ||
135 | .freq = { 1, 0x1F000000, 24 }, | ||
136 | .freq_clk_src = { 1, 0x60000000, 29 }, | ||
137 | }; | ||
138 | |||
139 | static const struct rpm_reg_parts rpm8960_switch_parts = { | ||
140 | .request_len = 1, | ||
141 | .enable_state = { 0, 0x00000001, 0 }, | ||
142 | .pd = { 0, 0x00000002, 1 }, | ||
143 | .pc = { 0, 0x0000003C, 2 }, | ||
144 | .pf = { 0, 0x000003C0, 6 }, | ||
145 | .hpm = { 0, 0x00000C00, 10 }, | ||
146 | }; | ||
147 | |||
148 | static const struct rpm_reg_parts rpm8960_ncp_parts = { | ||
149 | .request_len = 1, | ||
150 | .uV = { 0, 0x007FFFFF, 0 }, | ||
151 | .enable_state = { 0, 0x00800000, 23 }, | ||
152 | .comp_mode = { 0, 0x01000000, 24 }, | ||
153 | .freq = { 0, 0x3E000000, 25 }, | ||
154 | }; | ||
155 | |||
156 | /* | ||
157 | * Physically available PMIC regulator voltage ranges | ||
158 | */ | ||
159 | static const struct regulator_linear_range pldo_ranges[] = { | ||
160 | REGULATOR_LINEAR_RANGE( 750000, 0, 59, 12500), | ||
161 | REGULATOR_LINEAR_RANGE(1500000, 60, 123, 25000), | ||
162 | REGULATOR_LINEAR_RANGE(3100000, 124, 160, 50000), | ||
163 | }; | ||
164 | |||
165 | static const struct regulator_linear_range nldo_ranges[] = { | ||
166 | REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500), | ||
167 | }; | ||
168 | |||
169 | static const struct regulator_linear_range nldo1200_ranges[] = { | ||
170 | REGULATOR_LINEAR_RANGE( 375000, 0, 59, 6250), | ||
171 | REGULATOR_LINEAR_RANGE( 750000, 60, 123, 12500), | ||
172 | }; | ||
173 | |||
174 | static const struct regulator_linear_range smps_ranges[] = { | ||
175 | REGULATOR_LINEAR_RANGE( 375000, 0, 29, 12500), | ||
176 | REGULATOR_LINEAR_RANGE( 750000, 30, 89, 12500), | ||
177 | REGULATOR_LINEAR_RANGE(1500000, 90, 153, 25000), | ||
178 | }; | ||
179 | |||
180 | static const struct regulator_linear_range ftsmps_ranges[] = { | ||
181 | REGULATOR_LINEAR_RANGE( 350000, 0, 6, 50000), | ||
182 | REGULATOR_LINEAR_RANGE( 700000, 7, 63, 12500), | ||
183 | REGULATOR_LINEAR_RANGE(1500000, 64, 100, 50000), | ||
184 | }; | ||
185 | |||
186 | static const struct regulator_linear_range ncp_ranges[] = { | ||
187 | REGULATOR_LINEAR_RANGE(1500000, 0, 31, 50000), | ||
188 | }; | ||
189 | |||
190 | static int rpm_reg_write(struct qcom_rpm_reg *vreg, | ||
191 | const struct request_member *req, | ||
192 | const int value) | ||
193 | { | ||
194 | if (WARN_ON((value << req->shift) & ~req->mask)) | ||
195 | return -EINVAL; | ||
196 | |||
197 | vreg->val[req->word] &= ~req->mask; | ||
198 | vreg->val[req->word] |= value << req->shift; | ||
199 | |||
200 | return qcom_rpm_write(vreg->rpm, | ||
201 | vreg->resource, | ||
202 | vreg->val, | ||
203 | vreg->parts->request_len); | ||
204 | } | ||
205 | |||
206 | static int rpm_reg_set_mV_sel(struct regulator_dev *rdev, | ||
207 | unsigned selector) | ||
208 | { | ||
209 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
210 | const struct rpm_reg_parts *parts = vreg->parts; | ||
211 | const struct request_member *req = &parts->mV; | ||
212 | int ret = 0; | ||
213 | int uV; | ||
214 | |||
215 | if (req->mask == 0) | ||
216 | return -EINVAL; | ||
217 | |||
218 | uV = regulator_list_voltage_linear_range(rdev, selector); | ||
219 | if (uV < 0) | ||
220 | return uV; | ||
221 | |||
222 | mutex_lock(&vreg->lock); | ||
223 | vreg->uV = uV; | ||
224 | if (vreg->is_enabled) | ||
225 | ret = rpm_reg_write(vreg, req, vreg->uV / 1000); | ||
226 | mutex_unlock(&vreg->lock); | ||
227 | |||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | static int rpm_reg_set_uV_sel(struct regulator_dev *rdev, | ||
232 | unsigned selector) | ||
233 | { | ||
234 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
235 | const struct rpm_reg_parts *parts = vreg->parts; | ||
236 | const struct request_member *req = &parts->uV; | ||
237 | int ret = 0; | ||
238 | int uV; | ||
239 | |||
240 | if (req->mask == 0) | ||
241 | return -EINVAL; | ||
242 | |||
243 | uV = regulator_list_voltage_linear_range(rdev, selector); | ||
244 | if (uV < 0) | ||
245 | return uV; | ||
246 | |||
247 | mutex_lock(&vreg->lock); | ||
248 | vreg->uV = uV; | ||
249 | if (vreg->is_enabled) | ||
250 | ret = rpm_reg_write(vreg, req, vreg->uV); | ||
251 | mutex_unlock(&vreg->lock); | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | static int rpm_reg_get_voltage(struct regulator_dev *rdev) | ||
257 | { | ||
258 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
259 | |||
260 | return vreg->uV; | ||
261 | } | ||
262 | |||
263 | static int rpm_reg_mV_enable(struct regulator_dev *rdev) | ||
264 | { | ||
265 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
266 | const struct rpm_reg_parts *parts = vreg->parts; | ||
267 | const struct request_member *req = &parts->mV; | ||
268 | int ret; | ||
269 | |||
270 | if (req->mask == 0) | ||
271 | return -EINVAL; | ||
272 | |||
273 | mutex_lock(&vreg->lock); | ||
274 | ret = rpm_reg_write(vreg, req, vreg->uV / 1000); | ||
275 | if (!ret) | ||
276 | vreg->is_enabled = 1; | ||
277 | mutex_unlock(&vreg->lock); | ||
278 | |||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | static int rpm_reg_uV_enable(struct regulator_dev *rdev) | ||
283 | { | ||
284 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
285 | const struct rpm_reg_parts *parts = vreg->parts; | ||
286 | const struct request_member *req = &parts->uV; | ||
287 | int ret; | ||
288 | |||
289 | if (req->mask == 0) | ||
290 | return -EINVAL; | ||
291 | |||
292 | mutex_lock(&vreg->lock); | ||
293 | ret = rpm_reg_write(vreg, req, vreg->uV); | ||
294 | if (!ret) | ||
295 | vreg->is_enabled = 1; | ||
296 | mutex_unlock(&vreg->lock); | ||
297 | |||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | static int rpm_reg_switch_enable(struct regulator_dev *rdev) | ||
302 | { | ||
303 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
304 | const struct rpm_reg_parts *parts = vreg->parts; | ||
305 | const struct request_member *req = &parts->enable_state; | ||
306 | int ret; | ||
307 | |||
308 | if (req->mask == 0) | ||
309 | return -EINVAL; | ||
310 | |||
311 | mutex_lock(&vreg->lock); | ||
312 | ret = rpm_reg_write(vreg, req, 1); | ||
313 | if (!ret) | ||
314 | vreg->is_enabled = 1; | ||
315 | mutex_unlock(&vreg->lock); | ||
316 | |||
317 | return ret; | ||
318 | } | ||
319 | |||
320 | static int rpm_reg_mV_disable(struct regulator_dev *rdev) | ||
321 | { | ||
322 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
323 | const struct rpm_reg_parts *parts = vreg->parts; | ||
324 | const struct request_member *req = &parts->mV; | ||
325 | int ret; | ||
326 | |||
327 | if (req->mask == 0) | ||
328 | return -EINVAL; | ||
329 | |||
330 | mutex_lock(&vreg->lock); | ||
331 | ret = rpm_reg_write(vreg, req, 0); | ||
332 | if (!ret) | ||
333 | vreg->is_enabled = 0; | ||
334 | mutex_unlock(&vreg->lock); | ||
335 | |||
336 | return ret; | ||
337 | } | ||
338 | |||
339 | static int rpm_reg_uV_disable(struct regulator_dev *rdev) | ||
340 | { | ||
341 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
342 | const struct rpm_reg_parts *parts = vreg->parts; | ||
343 | const struct request_member *req = &parts->uV; | ||
344 | int ret; | ||
345 | |||
346 | if (req->mask == 0) | ||
347 | return -EINVAL; | ||
348 | |||
349 | mutex_lock(&vreg->lock); | ||
350 | ret = rpm_reg_write(vreg, req, 0); | ||
351 | if (!ret) | ||
352 | vreg->is_enabled = 0; | ||
353 | mutex_unlock(&vreg->lock); | ||
354 | |||
355 | return ret; | ||
356 | } | ||
357 | |||
358 | static int rpm_reg_switch_disable(struct regulator_dev *rdev) | ||
359 | { | ||
360 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
361 | const struct rpm_reg_parts *parts = vreg->parts; | ||
362 | const struct request_member *req = &parts->enable_state; | ||
363 | int ret; | ||
364 | |||
365 | if (req->mask == 0) | ||
366 | return -EINVAL; | ||
367 | |||
368 | mutex_lock(&vreg->lock); | ||
369 | ret = rpm_reg_write(vreg, req, 0); | ||
370 | if (!ret) | ||
371 | vreg->is_enabled = 0; | ||
372 | mutex_unlock(&vreg->lock); | ||
373 | |||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | static int rpm_reg_is_enabled(struct regulator_dev *rdev) | ||
378 | { | ||
379 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | ||
380 | |||
381 | return vreg->is_enabled; | ||
382 | } | ||
383 | |||
384 | static struct regulator_ops uV_ops = { | ||
385 | .list_voltage = regulator_list_voltage_linear_range, | ||
386 | |||
387 | .set_voltage_sel = rpm_reg_set_uV_sel, | ||
388 | .get_voltage = rpm_reg_get_voltage, | ||
389 | |||
390 | .enable = rpm_reg_uV_enable, | ||
391 | .disable = rpm_reg_uV_disable, | ||
392 | .is_enabled = rpm_reg_is_enabled, | ||
393 | }; | ||
394 | |||
395 | static struct regulator_ops mV_ops = { | ||
396 | .list_voltage = regulator_list_voltage_linear_range, | ||
397 | |||
398 | .set_voltage_sel = rpm_reg_set_mV_sel, | ||
399 | .get_voltage = rpm_reg_get_voltage, | ||
400 | |||
401 | .enable = rpm_reg_mV_enable, | ||
402 | .disable = rpm_reg_mV_disable, | ||
403 | .is_enabled = rpm_reg_is_enabled, | ||
404 | }; | ||
405 | |||
406 | static struct regulator_ops switch_ops = { | ||
407 | .enable = rpm_reg_switch_enable, | ||
408 | .disable = rpm_reg_switch_disable, | ||
409 | .is_enabled = rpm_reg_is_enabled, | ||
410 | }; | ||
411 | |||
412 | /* | ||
413 | * PM8058 regulators | ||
414 | */ | ||
415 | static const struct qcom_rpm_reg pm8058_pldo = { | ||
416 | .desc.linear_ranges = pldo_ranges, | ||
417 | .desc.n_linear_ranges = ARRAY_SIZE(pldo_ranges), | ||
418 | .desc.n_voltages = 161, | ||
419 | .desc.ops = &mV_ops, | ||
420 | .parts = &rpm8660_ldo_parts, | ||
421 | .supports_force_mode_auto = false, | ||
422 | .supports_force_mode_bypass = false, | ||
423 | }; | ||
424 | |||
425 | static const struct qcom_rpm_reg pm8058_nldo = { | ||
426 | .desc.linear_ranges = nldo_ranges, | ||
427 | .desc.n_linear_ranges = ARRAY_SIZE(nldo_ranges), | ||
428 | .desc.n_voltages = 64, | ||
429 | .desc.ops = &mV_ops, | ||
430 | .parts = &rpm8660_ldo_parts, | ||
431 | .supports_force_mode_auto = false, | ||
432 | .supports_force_mode_bypass = false, | ||
433 | }; | ||
434 | |||
435 | static const struct qcom_rpm_reg pm8058_smps = { | ||
436 | .desc.linear_ranges = smps_ranges, | ||
437 | .desc.n_linear_ranges = ARRAY_SIZE(smps_ranges), | ||
438 | .desc.n_voltages = 154, | ||
439 | .desc.ops = &mV_ops, | ||
440 | .parts = &rpm8660_smps_parts, | ||
441 | .supports_force_mode_auto = false, | ||
442 | .supports_force_mode_bypass = false, | ||
443 | }; | ||
444 | |||
445 | static const struct qcom_rpm_reg pm8058_ncp = { | ||
446 | .desc.linear_ranges = ncp_ranges, | ||
447 | .desc.n_linear_ranges = ARRAY_SIZE(ncp_ranges), | ||
448 | .desc.n_voltages = 32, | ||
449 | .desc.ops = &mV_ops, | ||
450 | .parts = &rpm8660_ncp_parts, | ||
451 | }; | ||
452 | |||
453 | static const struct qcom_rpm_reg pm8058_switch = { | ||
454 | .desc.ops = &switch_ops, | ||
455 | .parts = &rpm8660_switch_parts, | ||
456 | }; | ||
457 | |||
458 | /* | ||
459 | * PM8901 regulators | ||
460 | */ | ||
461 | static const struct qcom_rpm_reg pm8901_pldo = { | ||
462 | .desc.linear_ranges = pldo_ranges, | ||
463 | .desc.n_linear_ranges = ARRAY_SIZE(pldo_ranges), | ||
464 | .desc.n_voltages = 161, | ||
465 | .desc.ops = &mV_ops, | ||
466 | .parts = &rpm8660_ldo_parts, | ||
467 | .supports_force_mode_auto = false, | ||
468 | .supports_force_mode_bypass = true, | ||
469 | }; | ||
470 | |||
471 | static const struct qcom_rpm_reg pm8901_nldo = { | ||
472 | .desc.linear_ranges = nldo_ranges, | ||
473 | .desc.n_linear_ranges = ARRAY_SIZE(nldo_ranges), | ||
474 | .desc.n_voltages = 64, | ||
475 | .desc.ops = &mV_ops, | ||
476 | .parts = &rpm8660_ldo_parts, | ||
477 | .supports_force_mode_auto = false, | ||
478 | .supports_force_mode_bypass = true, | ||
479 | }; | ||
480 | |||
481 | static const struct qcom_rpm_reg pm8901_ftsmps = { | ||
482 | .desc.linear_ranges = ftsmps_ranges, | ||
483 | .desc.n_linear_ranges = ARRAY_SIZE(ftsmps_ranges), | ||
484 | .desc.n_voltages = 101, | ||
485 | .desc.ops = &mV_ops, | ||
486 | .parts = &rpm8660_smps_parts, | ||
487 | .supports_force_mode_auto = true, | ||
488 | .supports_force_mode_bypass = false, | ||
489 | }; | ||
490 | |||
491 | static const struct qcom_rpm_reg pm8901_switch = { | ||
492 | .desc.ops = &switch_ops, | ||
493 | .parts = &rpm8660_switch_parts, | ||
494 | }; | ||
495 | |||
496 | /* | ||
497 | * PM8921 regulators | ||
498 | */ | ||
499 | static const struct qcom_rpm_reg pm8921_pldo = { | ||
500 | .desc.linear_ranges = pldo_ranges, | ||
501 | .desc.n_linear_ranges = ARRAY_SIZE(pldo_ranges), | ||
502 | .desc.n_voltages = 161, | ||
503 | .desc.ops = &uV_ops, | ||
504 | .parts = &rpm8960_ldo_parts, | ||
505 | .supports_force_mode_auto = false, | ||
506 | .supports_force_mode_bypass = true, | ||
507 | }; | ||
508 | |||
509 | static const struct qcom_rpm_reg pm8921_nldo = { | ||
510 | .desc.linear_ranges = nldo_ranges, | ||
511 | .desc.n_linear_ranges = ARRAY_SIZE(nldo_ranges), | ||
512 | .desc.n_voltages = 64, | ||
513 | .desc.ops = &uV_ops, | ||
514 | .parts = &rpm8960_ldo_parts, | ||
515 | .supports_force_mode_auto = false, | ||
516 | .supports_force_mode_bypass = true, | ||
517 | }; | ||
518 | |||
519 | static const struct qcom_rpm_reg pm8921_nldo1200 = { | ||
520 | .desc.linear_ranges = nldo1200_ranges, | ||
521 | .desc.n_linear_ranges = ARRAY_SIZE(nldo1200_ranges), | ||
522 | .desc.n_voltages = 124, | ||
523 | .desc.ops = &uV_ops, | ||
524 | .parts = &rpm8960_ldo_parts, | ||
525 | .supports_force_mode_auto = false, | ||
526 | .supports_force_mode_bypass = true, | ||
527 | }; | ||
528 | |||
529 | static const struct qcom_rpm_reg pm8921_smps = { | ||
530 | .desc.linear_ranges = smps_ranges, | ||
531 | .desc.n_linear_ranges = ARRAY_SIZE(smps_ranges), | ||
532 | .desc.n_voltages = 154, | ||
533 | .desc.ops = &uV_ops, | ||
534 | .parts = &rpm8960_smps_parts, | ||
535 | .supports_force_mode_auto = true, | ||
536 | .supports_force_mode_bypass = false, | ||
537 | }; | ||
538 | |||
539 | static const struct qcom_rpm_reg pm8921_ftsmps = { | ||
540 | .desc.linear_ranges = ftsmps_ranges, | ||
541 | .desc.n_linear_ranges = ARRAY_SIZE(ftsmps_ranges), | ||
542 | .desc.n_voltages = 101, | ||
543 | .desc.ops = &uV_ops, | ||
544 | .parts = &rpm8960_smps_parts, | ||
545 | .supports_force_mode_auto = true, | ||
546 | .supports_force_mode_bypass = false, | ||
547 | }; | ||
548 | |||
549 | static const struct qcom_rpm_reg pm8921_ncp = { | ||
550 | .desc.linear_ranges = ncp_ranges, | ||
551 | .desc.n_linear_ranges = ARRAY_SIZE(ncp_ranges), | ||
552 | .desc.n_voltages = 32, | ||
553 | .desc.ops = &uV_ops, | ||
554 | .parts = &rpm8960_ncp_parts, | ||
555 | }; | ||
556 | |||
557 | static const struct qcom_rpm_reg pm8921_switch = { | ||
558 | .desc.ops = &switch_ops, | ||
559 | .parts = &rpm8960_switch_parts, | ||
560 | }; | ||
561 | |||
562 | static const struct of_device_id rpm_of_match[] = { | ||
563 | { .compatible = "qcom,rpm-pm8058-pldo", .data = &pm8058_pldo }, | ||
564 | { .compatible = "qcom,rpm-pm8058-nldo", .data = &pm8058_nldo }, | ||
565 | { .compatible = "qcom,rpm-pm8058-smps", .data = &pm8058_smps }, | ||
566 | { .compatible = "qcom,rpm-pm8058-ncp", .data = &pm8058_ncp }, | ||
567 | { .compatible = "qcom,rpm-pm8058-switch", .data = &pm8058_switch }, | ||
568 | |||
569 | { .compatible = "qcom,rpm-pm8901-pldo", .data = &pm8901_pldo }, | ||
570 | { .compatible = "qcom,rpm-pm8901-nldo", .data = &pm8901_nldo }, | ||
571 | { .compatible = "qcom,rpm-pm8901-ftsmps", .data = &pm8901_ftsmps }, | ||
572 | { .compatible = "qcom,rpm-pm8901-switch", .data = &pm8901_switch }, | ||
573 | |||
574 | { .compatible = "qcom,rpm-pm8921-pldo", .data = &pm8921_pldo }, | ||
575 | { .compatible = "qcom,rpm-pm8921-nldo", .data = &pm8921_nldo }, | ||
576 | { .compatible = "qcom,rpm-pm8921-nldo1200", .data = &pm8921_nldo1200 }, | ||
577 | { .compatible = "qcom,rpm-pm8921-smps", .data = &pm8921_smps }, | ||
578 | { .compatible = "qcom,rpm-pm8921-ftsmps", .data = &pm8921_ftsmps }, | ||
579 | { .compatible = "qcom,rpm-pm8921-ncp", .data = &pm8921_ncp }, | ||
580 | { .compatible = "qcom,rpm-pm8921-switch", .data = &pm8921_switch }, | ||
581 | { } | ||
582 | }; | ||
583 | MODULE_DEVICE_TABLE(of, rpm_of_match); | ||
584 | |||
585 | static int rpm_reg_set(struct qcom_rpm_reg *vreg, | ||
586 | const struct request_member *req, | ||
587 | const int value) | ||
588 | { | ||
589 | if (req->mask == 0 || (value << req->shift) & ~req->mask) | ||
590 | return -EINVAL; | ||
591 | |||
592 | vreg->val[req->word] &= ~req->mask; | ||
593 | vreg->val[req->word] |= value << req->shift; | ||
594 | |||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static int rpm_reg_of_parse_freq(struct device *dev, struct qcom_rpm_reg *vreg) | ||
599 | { | ||
600 | static const int freq_table[] = { | ||
601 | 19200000, 9600000, 6400000, 4800000, 3840000, 3200000, 2740000, | ||
602 | 2400000, 2130000, 1920000, 1750000, 1600000, 1480000, 1370000, | ||
603 | 1280000, 1200000, | ||
604 | |||
605 | }; | ||
606 | const char *key; | ||
607 | u32 freq; | ||
608 | int ret; | ||
609 | int i; | ||
610 | |||
611 | key = "qcom,switch-mode-frequency"; | ||
612 | ret = of_property_read_u32(dev->of_node, key, &freq); | ||
613 | if (ret) { | ||
614 | dev_err(dev, "regulator requires %s property\n", key); | ||
615 | return -EINVAL; | ||
616 | } | ||
617 | |||
618 | for (i = 0; i < ARRAY_SIZE(freq_table); i++) { | ||
619 | if (freq == freq_table[i]) { | ||
620 | rpm_reg_set(vreg, &vreg->parts->freq, i + 1); | ||
621 | return 0; | ||
622 | } | ||
623 | } | ||
624 | |||
625 | dev_err(dev, "invalid frequency %d\n", freq); | ||
626 | return -EINVAL; | ||
627 | } | ||
628 | |||
629 | static int rpm_reg_probe(struct platform_device *pdev) | ||
630 | { | ||
631 | struct regulator_init_data *initdata; | ||
632 | const struct qcom_rpm_reg *template; | ||
633 | const struct of_device_id *match; | ||
634 | struct regulator_config config = { }; | ||
635 | struct regulator_dev *rdev; | ||
636 | struct qcom_rpm_reg *vreg; | ||
637 | const char *key; | ||
638 | u32 force_mode; | ||
639 | bool pwm; | ||
640 | u32 val; | ||
641 | int ret; | ||
642 | |||
643 | match = of_match_device(rpm_of_match, &pdev->dev); | ||
644 | template = match->data; | ||
645 | |||
646 | initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); | ||
647 | if (!initdata) | ||
648 | return -EINVAL; | ||
649 | |||
650 | vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL); | ||
651 | if (!vreg) { | ||
652 | dev_err(&pdev->dev, "failed to allocate vreg\n"); | ||
653 | return -ENOMEM; | ||
654 | } | ||
655 | memcpy(vreg, template, sizeof(*vreg)); | ||
656 | mutex_init(&vreg->lock); | ||
657 | vreg->dev = &pdev->dev; | ||
658 | vreg->desc.id = -1; | ||
659 | vreg->desc.owner = THIS_MODULE; | ||
660 | vreg->desc.type = REGULATOR_VOLTAGE; | ||
661 | vreg->desc.name = pdev->dev.of_node->name; | ||
662 | |||
663 | vreg->rpm = dev_get_drvdata(pdev->dev.parent); | ||
664 | if (!vreg->rpm) { | ||
665 | dev_err(&pdev->dev, "unable to retrieve handle to rpm\n"); | ||
666 | return -ENODEV; | ||
667 | } | ||
668 | |||
669 | key = "reg"; | ||
670 | ret = of_property_read_u32(pdev->dev.of_node, key, &val); | ||
671 | if (ret) { | ||
672 | dev_err(&pdev->dev, "failed to read %s\n", key); | ||
673 | return ret; | ||
674 | } | ||
675 | vreg->resource = val; | ||
676 | |||
677 | if ((vreg->parts->uV.mask || vreg->parts->mV.mask) && | ||
678 | (!initdata->constraints.min_uV || !initdata->constraints.max_uV)) { | ||
679 | dev_err(&pdev->dev, "no voltage specified for regulator\n"); | ||
680 | return -EINVAL; | ||
681 | } | ||
682 | |||
683 | key = "bias-pull-down"; | ||
684 | if (of_property_read_bool(pdev->dev.of_node, key)) { | ||
685 | ret = rpm_reg_set(vreg, &vreg->parts->pd, 1); | ||
686 | if (ret) { | ||
687 | dev_err(&pdev->dev, "%s is invalid", key); | ||
688 | return ret; | ||
689 | } | ||
690 | } | ||
691 | |||
692 | if (vreg->parts->freq.mask) { | ||
693 | ret = rpm_reg_of_parse_freq(&pdev->dev, vreg); | ||
694 | if (ret < 0) | ||
695 | return ret; | ||
696 | } | ||
697 | |||
698 | if (vreg->parts->pm.mask) { | ||
699 | key = "qcom,power-mode-hysteretic"; | ||
700 | pwm = !of_property_read_bool(pdev->dev.of_node, key); | ||
701 | |||
702 | ret = rpm_reg_set(vreg, &vreg->parts->pm, pwm); | ||
703 | if (ret) { | ||
704 | dev_err(&pdev->dev, "failed to set power mode\n"); | ||
705 | return ret; | ||
706 | } | ||
707 | } | ||
708 | |||
709 | if (vreg->parts->fm.mask) { | ||
710 | force_mode = -1; | ||
711 | |||
712 | key = "qcom,force-mode"; | ||
713 | ret = of_property_read_u32(pdev->dev.of_node, key, &val); | ||
714 | if (ret == -EINVAL) { | ||
715 | val = QCOM_RPM_FORCE_MODE_NONE; | ||
716 | } else if (ret < 0) { | ||
717 | dev_err(&pdev->dev, "failed to read %s\n", key); | ||
718 | return ret; | ||
719 | } | ||
720 | |||
721 | /* | ||
722 | * If force-mode is encoded as 2 bits then the | ||
723 | * possible register values are: | ||
724 | * NONE, LPM, HPM | ||
725 | * otherwise: | ||
726 | * NONE, LPM, AUTO, HPM, BYPASS | ||
727 | */ | ||
728 | switch (val) { | ||
729 | case QCOM_RPM_FORCE_MODE_NONE: | ||
730 | force_mode = 0; | ||
731 | break; | ||
732 | case QCOM_RPM_FORCE_MODE_LPM: | ||
733 | force_mode = 1; | ||
734 | break; | ||
735 | case QCOM_RPM_FORCE_MODE_HPM: | ||
736 | if (FORCE_MODE_IS_2_BITS(vreg)) | ||
737 | force_mode = 2; | ||
738 | else | ||
739 | force_mode = 3; | ||
740 | break; | ||
741 | case QCOM_RPM_FORCE_MODE_AUTO: | ||
742 | if (vreg->supports_force_mode_auto) | ||
743 | force_mode = 2; | ||
744 | break; | ||
745 | case QCOM_RPM_FORCE_MODE_BYPASS: | ||
746 | if (vreg->supports_force_mode_bypass) | ||
747 | force_mode = 4; | ||
748 | break; | ||
749 | } | ||
750 | |||
751 | if (force_mode < 0) { | ||
752 | dev_err(&pdev->dev, "invalid force mode\n"); | ||
753 | return -EINVAL; | ||
754 | } | ||
755 | |||
756 | ret = rpm_reg_set(vreg, &vreg->parts->fm, force_mode); | ||
757 | if (ret) { | ||
758 | dev_err(&pdev->dev, "failed to set force mode\n"); | ||
759 | return ret; | ||
760 | } | ||
761 | } | ||
762 | |||
763 | config.dev = &pdev->dev; | ||
764 | config.init_data = initdata; | ||
765 | config.driver_data = vreg; | ||
766 | config.of_node = pdev->dev.of_node; | ||
767 | rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config); | ||
768 | if (IS_ERR(rdev)) { | ||
769 | dev_err(&pdev->dev, "can't register regulator\n"); | ||
770 | return PTR_ERR(rdev); | ||
771 | } | ||
772 | |||
773 | return 0; | ||
774 | } | ||
775 | |||
776 | static struct platform_driver rpm_reg_driver = { | ||
777 | .probe = rpm_reg_probe, | ||
778 | .driver = { | ||
779 | .name = "qcom_rpm_reg", | ||
780 | .owner = THIS_MODULE, | ||
781 | .of_match_table = of_match_ptr(rpm_of_match), | ||
782 | }, | ||
783 | }; | ||
784 | |||
785 | static int __init rpm_reg_init(void) | ||
786 | { | ||
787 | return platform_driver_register(&rpm_reg_driver); | ||
788 | } | ||
789 | subsys_initcall(rpm_reg_init); | ||
790 | |||
791 | static void __exit rpm_reg_exit(void) | ||
792 | { | ||
793 | platform_driver_unregister(&rpm_reg_driver); | ||
794 | } | ||
795 | module_exit(rpm_reg_exit) | ||
796 | |||
797 | MODULE_DESCRIPTION("Qualcomm RPM regulator driver"); | ||
798 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c new file mode 100644 index 000000000000..e305416d7697 --- /dev/null +++ b/drivers/regulator/rk808-regulator.c | |||
@@ -0,0 +1,381 @@ | |||
1 | /* | ||
2 | * Regulator driver for Rockchip RK808 | ||
3 | * | ||
4 | * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd | ||
5 | * | ||
6 | * Author: Chris Zhong <zyw@rock-chips.com> | ||
7 | * Author: Zhang Qing <zhangqing@rock-chips.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms and conditions of the GNU General Public License, | ||
11 | * version 2, as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/mfd/rk808.h> | ||
22 | #include <linux/of_device.h> | ||
23 | #include <linux/regulator/driver.h> | ||
24 | #include <linux/regulator/of_regulator.h> | ||
25 | |||
26 | /* Field Definitions */ | ||
27 | #define RK808_BUCK_VSEL_MASK 0x3f | ||
28 | #define RK808_BUCK4_VSEL_MASK 0xf | ||
29 | #define RK808_LDO_VSEL_MASK 0x1f | ||
30 | |||
31 | /* Ramp rate definitions for buck1 / buck2 only */ | ||
32 | #define RK808_RAMP_RATE_OFFSET 3 | ||
33 | #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) | ||
34 | #define RK808_RAMP_RATE_2MV_PER_US (0 << RK808_RAMP_RATE_OFFSET) | ||
35 | #define RK808_RAMP_RATE_4MV_PER_US (1 << RK808_RAMP_RATE_OFFSET) | ||
36 | #define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET) | ||
37 | #define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET) | ||
38 | |||
39 | static const int rk808_buck_config_regs[] = { | ||
40 | RK808_BUCK1_CONFIG_REG, | ||
41 | RK808_BUCK2_CONFIG_REG, | ||
42 | RK808_BUCK3_CONFIG_REG, | ||
43 | RK808_BUCK4_CONFIG_REG, | ||
44 | }; | ||
45 | |||
46 | static const struct regulator_linear_range rk808_buck_voltage_ranges[] = { | ||
47 | REGULATOR_LINEAR_RANGE(700000, 0, 63, 12500), | ||
48 | }; | ||
49 | |||
50 | static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = { | ||
51 | REGULATOR_LINEAR_RANGE(1800000, 0, 15, 100000), | ||
52 | }; | ||
53 | |||
54 | static const struct regulator_linear_range rk808_ldo_voltage_ranges[] = { | ||
55 | REGULATOR_LINEAR_RANGE(1800000, 0, 16, 100000), | ||
56 | }; | ||
57 | |||
58 | static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = { | ||
59 | REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000), | ||
60 | REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0), | ||
61 | }; | ||
62 | |||
63 | static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = { | ||
64 | REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000), | ||
65 | }; | ||
66 | |||
67 | static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | ||
68 | { | ||
69 | unsigned int ramp_value = RK808_RAMP_RATE_10MV_PER_US; | ||
70 | unsigned int reg = rk808_buck_config_regs[rdev->desc->id - | ||
71 | RK808_ID_DCDC1]; | ||
72 | |||
73 | switch (ramp_delay) { | ||
74 | case 1 ... 2000: | ||
75 | ramp_value = RK808_RAMP_RATE_2MV_PER_US; | ||
76 | break; | ||
77 | case 2001 ... 4000: | ||
78 | ramp_value = RK808_RAMP_RATE_4MV_PER_US; | ||
79 | break; | ||
80 | case 4001 ... 6000: | ||
81 | ramp_value = RK808_RAMP_RATE_6MV_PER_US; | ||
82 | break; | ||
83 | case 6001 ... 10000: | ||
84 | break; | ||
85 | default: | ||
86 | pr_warn("%s ramp_delay: %d not supported, setting 10000\n", | ||
87 | rdev->desc->name, ramp_delay); | ||
88 | } | ||
89 | |||
90 | return regmap_update_bits(rdev->regmap, reg, | ||
91 | RK808_RAMP_RATE_MASK, ramp_value); | ||
92 | } | ||
93 | |||
94 | static struct regulator_ops rk808_buck1_2_ops = { | ||
95 | .list_voltage = regulator_list_voltage_linear_range, | ||
96 | .map_voltage = regulator_map_voltage_linear_range, | ||
97 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
98 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
99 | .enable = regulator_enable_regmap, | ||
100 | .disable = regulator_disable_regmap, | ||
101 | .is_enabled = regulator_is_enabled_regmap, | ||
102 | .set_ramp_delay = rk808_set_ramp_delay, | ||
103 | }; | ||
104 | |||
105 | static struct regulator_ops rk808_reg_ops = { | ||
106 | .list_voltage = regulator_list_voltage_linear_range, | ||
107 | .map_voltage = regulator_map_voltage_linear_range, | ||
108 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
109 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
110 | .enable = regulator_enable_regmap, | ||
111 | .disable = regulator_disable_regmap, | ||
112 | .is_enabled = regulator_is_enabled_regmap, | ||
113 | }; | ||
114 | |||
115 | static struct regulator_ops rk808_switch_ops = { | ||
116 | .enable = regulator_enable_regmap, | ||
117 | .disable = regulator_disable_regmap, | ||
118 | .is_enabled = regulator_is_enabled_regmap, | ||
119 | }; | ||
120 | |||
121 | static const struct regulator_desc rk808_reg[] = { | ||
122 | { | ||
123 | .name = "DCDC_REG1", | ||
124 | .supply_name = "vcc1", | ||
125 | .id = RK808_ID_DCDC1, | ||
126 | .ops = &rk808_buck1_2_ops, | ||
127 | .type = REGULATOR_VOLTAGE, | ||
128 | .n_voltages = 64, | ||
129 | .linear_ranges = rk808_buck_voltage_ranges, | ||
130 | .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges), | ||
131 | .vsel_reg = RK808_BUCK1_ON_VSEL_REG, | ||
132 | .vsel_mask = RK808_BUCK_VSEL_MASK, | ||
133 | .enable_reg = RK808_DCDC_EN_REG, | ||
134 | .enable_mask = BIT(0), | ||
135 | .owner = THIS_MODULE, | ||
136 | }, { | ||
137 | .name = "DCDC_REG2", | ||
138 | .supply_name = "vcc2", | ||
139 | .id = RK808_ID_DCDC2, | ||
140 | .ops = &rk808_buck1_2_ops, | ||
141 | .type = REGULATOR_VOLTAGE, | ||
142 | .n_voltages = 64, | ||
143 | .linear_ranges = rk808_buck_voltage_ranges, | ||
144 | .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges), | ||
145 | .vsel_reg = RK808_BUCK2_ON_VSEL_REG, | ||
146 | .vsel_mask = RK808_BUCK_VSEL_MASK, | ||
147 | .enable_reg = RK808_DCDC_EN_REG, | ||
148 | .enable_mask = BIT(1), | ||
149 | .owner = THIS_MODULE, | ||
150 | }, { | ||
151 | .name = "DCDC_REG3", | ||
152 | .supply_name = "vcc3", | ||
153 | .id = RK808_ID_DCDC3, | ||
154 | .ops = &rk808_switch_ops, | ||
155 | .type = REGULATOR_VOLTAGE, | ||
156 | .n_voltages = 1, | ||
157 | .enable_reg = RK808_DCDC_EN_REG, | ||
158 | .enable_mask = BIT(2), | ||
159 | .owner = THIS_MODULE, | ||
160 | }, { | ||
161 | .name = "DCDC_REG4", | ||
162 | .supply_name = "vcc4", | ||
163 | .id = RK808_ID_DCDC4, | ||
164 | .ops = &rk808_reg_ops, | ||
165 | .type = REGULATOR_VOLTAGE, | ||
166 | .n_voltages = 16, | ||
167 | .linear_ranges = rk808_buck4_voltage_ranges, | ||
168 | .n_linear_ranges = ARRAY_SIZE(rk808_buck4_voltage_ranges), | ||
169 | .vsel_reg = RK808_BUCK4_ON_VSEL_REG, | ||
170 | .vsel_mask = RK808_BUCK4_VSEL_MASK, | ||
171 | .enable_reg = RK808_DCDC_EN_REG, | ||
172 | .enable_mask = BIT(3), | ||
173 | .owner = THIS_MODULE, | ||
174 | }, { | ||
175 | .name = "LDO_REG1", | ||
176 | .supply_name = "vcc6", | ||
177 | .id = RK808_ID_LDO1, | ||
178 | .ops = &rk808_reg_ops, | ||
179 | .type = REGULATOR_VOLTAGE, | ||
180 | .n_voltages = 17, | ||
181 | .linear_ranges = rk808_ldo_voltage_ranges, | ||
182 | .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), | ||
183 | .vsel_reg = RK808_LDO1_ON_VSEL_REG, | ||
184 | .vsel_mask = RK808_LDO_VSEL_MASK, | ||
185 | .enable_reg = RK808_LDO_EN_REG, | ||
186 | .enable_mask = BIT(0), | ||
187 | .owner = THIS_MODULE, | ||
188 | }, { | ||
189 | .name = "LDO_REG2", | ||
190 | .supply_name = "vcc6", | ||
191 | .id = RK808_ID_LDO2, | ||
192 | .ops = &rk808_reg_ops, | ||
193 | .type = REGULATOR_VOLTAGE, | ||
194 | .n_voltages = 17, | ||
195 | .linear_ranges = rk808_ldo_voltage_ranges, | ||
196 | .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), | ||
197 | .vsel_reg = RK808_LDO2_ON_VSEL_REG, | ||
198 | .vsel_mask = RK808_LDO_VSEL_MASK, | ||
199 | .enable_reg = RK808_LDO_EN_REG, | ||
200 | .enable_mask = BIT(1), | ||
201 | .owner = THIS_MODULE, | ||
202 | }, { | ||
203 | .name = "LDO_REG3", | ||
204 | .supply_name = "vcc7", | ||
205 | .id = RK808_ID_LDO3, | ||
206 | .ops = &rk808_reg_ops, | ||
207 | .type = REGULATOR_VOLTAGE, | ||
208 | .n_voltages = 16, | ||
209 | .linear_ranges = rk808_ldo3_voltage_ranges, | ||
210 | .n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges), | ||
211 | .vsel_reg = RK808_LDO3_ON_VSEL_REG, | ||
212 | .vsel_mask = RK808_BUCK4_VSEL_MASK, | ||
213 | .enable_reg = RK808_LDO_EN_REG, | ||
214 | .enable_mask = BIT(2), | ||
215 | .owner = THIS_MODULE, | ||
216 | }, { | ||
217 | .name = "LDO_REG4", | ||
218 | .supply_name = "vcc9", | ||
219 | .id = RK808_ID_LDO4, | ||
220 | .ops = &rk808_reg_ops, | ||
221 | .type = REGULATOR_VOLTAGE, | ||
222 | .n_voltages = 17, | ||
223 | .linear_ranges = rk808_ldo_voltage_ranges, | ||
224 | .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), | ||
225 | .vsel_reg = RK808_LDO4_ON_VSEL_REG, | ||
226 | .vsel_mask = RK808_LDO_VSEL_MASK, | ||
227 | .enable_reg = RK808_LDO_EN_REG, | ||
228 | .enable_mask = BIT(3), | ||
229 | .owner = THIS_MODULE, | ||
230 | }, { | ||
231 | .name = "LDO_REG5", | ||
232 | .supply_name = "vcc9", | ||
233 | .id = RK808_ID_LDO5, | ||
234 | .ops = &rk808_reg_ops, | ||
235 | .type = REGULATOR_VOLTAGE, | ||
236 | .n_voltages = 17, | ||
237 | .linear_ranges = rk808_ldo_voltage_ranges, | ||
238 | .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), | ||
239 | .vsel_reg = RK808_LDO5_ON_VSEL_REG, | ||
240 | .vsel_mask = RK808_LDO_VSEL_MASK, | ||
241 | .enable_reg = RK808_LDO_EN_REG, | ||
242 | .enable_mask = BIT(4), | ||
243 | .owner = THIS_MODULE, | ||
244 | }, { | ||
245 | .name = "LDO_REG6", | ||
246 | .supply_name = "vcc10", | ||
247 | .id = RK808_ID_LDO6, | ||
248 | .ops = &rk808_reg_ops, | ||
249 | .type = REGULATOR_VOLTAGE, | ||
250 | .n_voltages = 18, | ||
251 | .linear_ranges = rk808_ldo6_voltage_ranges, | ||
252 | .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges), | ||
253 | .vsel_reg = RK808_LDO6_ON_VSEL_REG, | ||
254 | .vsel_mask = RK808_LDO_VSEL_MASK, | ||
255 | .enable_reg = RK808_LDO_EN_REG, | ||
256 | .enable_mask = BIT(5), | ||
257 | .owner = THIS_MODULE, | ||
258 | }, { | ||
259 | .name = "LDO_REG7", | ||
260 | .supply_name = "vcc7", | ||
261 | .id = RK808_ID_LDO7, | ||
262 | .ops = &rk808_reg_ops, | ||
263 | .type = REGULATOR_VOLTAGE, | ||
264 | .n_voltages = 18, | ||
265 | .linear_ranges = rk808_ldo6_voltage_ranges, | ||
266 | .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges), | ||
267 | .vsel_reg = RK808_LDO7_ON_VSEL_REG, | ||
268 | .vsel_mask = RK808_LDO_VSEL_MASK, | ||
269 | .enable_reg = RK808_LDO_EN_REG, | ||
270 | .enable_mask = BIT(6), | ||
271 | .owner = THIS_MODULE, | ||
272 | }, { | ||
273 | .name = "LDO_REG8", | ||
274 | .supply_name = "vcc11", | ||
275 | .id = RK808_ID_LDO8, | ||
276 | .ops = &rk808_reg_ops, | ||
277 | .type = REGULATOR_VOLTAGE, | ||
278 | .n_voltages = 17, | ||
279 | .linear_ranges = rk808_ldo_voltage_ranges, | ||
280 | .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), | ||
281 | .vsel_reg = RK808_LDO8_ON_VSEL_REG, | ||
282 | .vsel_mask = RK808_LDO_VSEL_MASK, | ||
283 | .enable_reg = RK808_LDO_EN_REG, | ||
284 | .enable_mask = BIT(7), | ||
285 | .owner = THIS_MODULE, | ||
286 | }, { | ||
287 | .name = "SWITCH_REG1", | ||
288 | .supply_name = "vcc8", | ||
289 | .id = RK808_ID_SWITCH1, | ||
290 | .ops = &rk808_switch_ops, | ||
291 | .type = REGULATOR_VOLTAGE, | ||
292 | .enable_reg = RK808_DCDC_EN_REG, | ||
293 | .enable_mask = BIT(5), | ||
294 | .owner = THIS_MODULE, | ||
295 | }, { | ||
296 | .name = "SWITCH_REG2", | ||
297 | .supply_name = "vcc12", | ||
298 | .id = RK808_ID_SWITCH2, | ||
299 | .ops = &rk808_switch_ops, | ||
300 | .type = REGULATOR_VOLTAGE, | ||
301 | .enable_reg = RK808_DCDC_EN_REG, | ||
302 | .enable_mask = BIT(6), | ||
303 | .owner = THIS_MODULE, | ||
304 | }, | ||
305 | }; | ||
306 | |||
307 | static struct of_regulator_match rk808_reg_matches[] = { | ||
308 | [RK808_ID_DCDC1] = { .name = "DCDC_REG1" }, | ||
309 | [RK808_ID_DCDC2] = { .name = "DCDC_REG2" }, | ||
310 | [RK808_ID_DCDC3] = { .name = "DCDC_REG3" }, | ||
311 | [RK808_ID_DCDC4] = { .name = "DCDC_REG4" }, | ||
312 | [RK808_ID_LDO1] = { .name = "LDO_REG1" }, | ||
313 | [RK808_ID_LDO2] = { .name = "LDO_REG2" }, | ||
314 | [RK808_ID_LDO3] = { .name = "LDO_REG3" }, | ||
315 | [RK808_ID_LDO4] = { .name = "LDO_REG4" }, | ||
316 | [RK808_ID_LDO5] = { .name = "LDO_REG5" }, | ||
317 | [RK808_ID_LDO6] = { .name = "LDO_REG6" }, | ||
318 | [RK808_ID_LDO7] = { .name = "LDO_REG7" }, | ||
319 | [RK808_ID_LDO8] = { .name = "LDO_REG8" }, | ||
320 | [RK808_ID_SWITCH1] = { .name = "SWITCH_REG1" }, | ||
321 | [RK808_ID_SWITCH2] = { .name = "SWITCH_REG2" }, | ||
322 | }; | ||
323 | |||
324 | static int rk808_regulator_probe(struct platform_device *pdev) | ||
325 | { | ||
326 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | ||
327 | struct i2c_client *client = rk808->i2c; | ||
328 | struct device_node *reg_np; | ||
329 | struct regulator_config config = {}; | ||
330 | struct regulator_dev *rk808_rdev; | ||
331 | int ret, i; | ||
332 | |||
333 | reg_np = of_get_child_by_name(client->dev.of_node, "regulators"); | ||
334 | if (!reg_np) | ||
335 | return -ENXIO; | ||
336 | |||
337 | ret = of_regulator_match(&pdev->dev, reg_np, rk808_reg_matches, | ||
338 | RK808_NUM_REGULATORS); | ||
339 | of_node_put(reg_np); | ||
340 | if (ret < 0) | ||
341 | return ret; | ||
342 | |||
343 | /* Instantiate the regulators */ | ||
344 | for (i = 0; i < RK808_NUM_REGULATORS; i++) { | ||
345 | if (!rk808_reg_matches[i].init_data || | ||
346 | !rk808_reg_matches[i].of_node) | ||
347 | continue; | ||
348 | |||
349 | config.dev = &client->dev; | ||
350 | config.driver_data = rk808; | ||
351 | config.regmap = rk808->regmap; | ||
352 | config.of_node = rk808_reg_matches[i].of_node; | ||
353 | config.init_data = rk808_reg_matches[i].init_data; | ||
354 | |||
355 | rk808_rdev = devm_regulator_register(&pdev->dev, | ||
356 | &rk808_reg[i], &config); | ||
357 | if (IS_ERR(rk808_rdev)) { | ||
358 | dev_err(&client->dev, | ||
359 | "failed to register %d regulator\n", i); | ||
360 | return PTR_ERR(rk808_rdev); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static struct platform_driver rk808_regulator_driver = { | ||
368 | .probe = rk808_regulator_probe, | ||
369 | .driver = { | ||
370 | .name = "rk808-regulator", | ||
371 | .owner = THIS_MODULE, | ||
372 | }, | ||
373 | }; | ||
374 | |||
375 | module_platform_driver(rk808_regulator_driver); | ||
376 | |||
377 | MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs"); | ||
378 | MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>"); | ||
379 | MODULE_AUTHOR("Zhang Qing<zhangqing@rock-chips.com>"); | ||
380 | MODULE_LICENSE("GPL"); | ||
381 | MODULE_ALIAS("platform:rk808-regulator"); | ||
diff --git a/drivers/regulator/rn5t618-regulator.c b/drivers/regulator/rn5t618-regulator.c new file mode 100644 index 000000000000..e58d79aeb393 --- /dev/null +++ b/drivers/regulator/rn5t618-regulator.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * Regulator driver for Ricoh RN5T618 PMIC | ||
3 | * | ||
4 | * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * You should have received a copy of the GNU General Public License | ||
11 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
12 | */ | ||
13 | |||
14 | #include <linux/mfd/rn5t618.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/regulator/driver.h> | ||
20 | #include <linux/regulator/of_regulator.h> | ||
21 | |||
22 | static struct regulator_ops rn5t618_reg_ops = { | ||
23 | .enable = regulator_enable_regmap, | ||
24 | .disable = regulator_disable_regmap, | ||
25 | .is_enabled = regulator_is_enabled_regmap, | ||
26 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
27 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
28 | .list_voltage = regulator_list_voltage_linear, | ||
29 | }; | ||
30 | |||
31 | #define REG(rid, ereg, emask, vreg, vmask, min, max, step) \ | ||
32 | [RN5T618_##rid] = { \ | ||
33 | .name = #rid, \ | ||
34 | .id = RN5T618_##rid, \ | ||
35 | .type = REGULATOR_VOLTAGE, \ | ||
36 | .owner = THIS_MODULE, \ | ||
37 | .ops = &rn5t618_reg_ops, \ | ||
38 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
39 | .min_uV = (min), \ | ||
40 | .uV_step = (step), \ | ||
41 | .enable_reg = RN5T618_##ereg, \ | ||
42 | .enable_mask = (emask), \ | ||
43 | .vsel_reg = RN5T618_##vreg, \ | ||
44 | .vsel_mask = (vmask), \ | ||
45 | } | ||
46 | |||
47 | static struct regulator_desc rn5t618_regulators[] = { | ||
48 | /* DCDC */ | ||
49 | REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), | ||
50 | REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), | ||
51 | REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500), | ||
52 | /* LDO */ | ||
53 | REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000), | ||
54 | REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000), | ||
55 | REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 600000, 3500000, 25000), | ||
56 | REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000), | ||
57 | REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 900000, 3500000, 25000), | ||
58 | /* LDO RTC */ | ||
59 | REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1700000, 3500000, 25000), | ||
60 | REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), | ||
61 | }; | ||
62 | |||
63 | static struct of_regulator_match rn5t618_matches[] = { | ||
64 | [RN5T618_DCDC1] = { .name = "DCDC1" }, | ||
65 | [RN5T618_DCDC2] = { .name = "DCDC2" }, | ||
66 | [RN5T618_DCDC3] = { .name = "DCDC3" }, | ||
67 | [RN5T618_LDO1] = { .name = "LDO1" }, | ||
68 | [RN5T618_LDO2] = { .name = "LDO2" }, | ||
69 | [RN5T618_LDO3] = { .name = "LDO3" }, | ||
70 | [RN5T618_LDO4] = { .name = "LDO4" }, | ||
71 | [RN5T618_LDO5] = { .name = "LDO5" }, | ||
72 | [RN5T618_LDORTC1] = { .name = "LDORTC1" }, | ||
73 | [RN5T618_LDORTC2] = { .name = "LDORTC2" }, | ||
74 | }; | ||
75 | |||
76 | static int rn5t618_regulator_parse_dt(struct platform_device *pdev) | ||
77 | { | ||
78 | struct device_node *np, *regulators; | ||
79 | int ret; | ||
80 | |||
81 | np = of_node_get(pdev->dev.parent->of_node); | ||
82 | if (!np) | ||
83 | return 0; | ||
84 | |||
85 | regulators = of_get_child_by_name(np, "regulators"); | ||
86 | if (!regulators) { | ||
87 | dev_err(&pdev->dev, "regulators node not found\n"); | ||
88 | return -EINVAL; | ||
89 | } | ||
90 | |||
91 | ret = of_regulator_match(&pdev->dev, regulators, rn5t618_matches, | ||
92 | ARRAY_SIZE(rn5t618_matches)); | ||
93 | of_node_put(regulators); | ||
94 | if (ret < 0) { | ||
95 | dev_err(&pdev->dev, "error parsing regulator init data: %d\n", | ||
96 | ret); | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int rn5t618_regulator_probe(struct platform_device *pdev) | ||
103 | { | ||
104 | struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); | ||
105 | struct regulator_config config = { }; | ||
106 | struct regulator_dev *rdev; | ||
107 | int ret, i; | ||
108 | |||
109 | ret = rn5t618_regulator_parse_dt(pdev); | ||
110 | if (ret) | ||
111 | return ret; | ||
112 | |||
113 | for (i = 0; i < RN5T618_REG_NUM; i++) { | ||
114 | config.dev = &pdev->dev; | ||
115 | config.init_data = rn5t618_matches[i].init_data; | ||
116 | config.of_node = rn5t618_matches[i].of_node; | ||
117 | config.regmap = rn5t618->regmap; | ||
118 | |||
119 | rdev = devm_regulator_register(&pdev->dev, | ||
120 | &rn5t618_regulators[i], | ||
121 | &config); | ||
122 | if (IS_ERR(rdev)) { | ||
123 | dev_err(&pdev->dev, "failed to register %s regulator\n", | ||
124 | rn5t618_regulators[i].name); | ||
125 | return PTR_ERR(rdev); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static struct platform_driver rn5t618_regulator_driver = { | ||
133 | .probe = rn5t618_regulator_probe, | ||
134 | .driver = { | ||
135 | .name = "rn5t618-regulator", | ||
136 | }, | ||
137 | }; | ||
138 | |||
139 | module_platform_driver(rn5t618_regulator_driver); | ||
140 | |||
141 | MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); | ||
142 | MODULE_DESCRIPTION("RN5T618 regulator driver"); | ||
143 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index ee83b4876420..4acefa6b462e 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c | |||
@@ -235,28 +235,14 @@ static struct regulator_ops s2mpa01_buck_ops = { | |||
235 | .set_ramp_delay = s2mpa01_set_ramp_delay, | 235 | .set_ramp_delay = s2mpa01_set_ramp_delay, |
236 | }; | 236 | }; |
237 | 237 | ||
238 | #define regulator_desc_ldo1(num) { \ | 238 | #define regulator_desc_ldo(num, step) { \ |
239 | .name = "LDO"#num, \ | 239 | .name = "LDO"#num, \ |
240 | .id = S2MPA01_LDO##num, \ | 240 | .id = S2MPA01_LDO##num, \ |
241 | .ops = &s2mpa01_ldo_ops, \ | 241 | .ops = &s2mpa01_ldo_ops, \ |
242 | .type = REGULATOR_VOLTAGE, \ | 242 | .type = REGULATOR_VOLTAGE, \ |
243 | .owner = THIS_MODULE, \ | 243 | .owner = THIS_MODULE, \ |
244 | .min_uV = S2MPA01_LDO_MIN, \ | 244 | .min_uV = MIN_800_MV, \ |
245 | .uV_step = S2MPA01_LDO_STEP1, \ | 245 | .uV_step = step, \ |
246 | .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ | ||
247 | .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
248 | .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ | ||
249 | .enable_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
250 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
251 | } | ||
252 | #define regulator_desc_ldo2(num) { \ | ||
253 | .name = "LDO"#num, \ | ||
254 | .id = S2MPA01_LDO##num, \ | ||
255 | .ops = &s2mpa01_ldo_ops, \ | ||
256 | .type = REGULATOR_VOLTAGE, \ | ||
257 | .owner = THIS_MODULE, \ | ||
258 | .min_uV = S2MPA01_LDO_MIN, \ | ||
259 | .uV_step = S2MPA01_LDO_STEP2, \ | ||
260 | .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ | 246 | .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ |
261 | .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ | 247 | .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ |
262 | .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ | 248 | .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ |
@@ -270,8 +256,8 @@ static struct regulator_ops s2mpa01_buck_ops = { | |||
270 | .ops = &s2mpa01_buck_ops, \ | 256 | .ops = &s2mpa01_buck_ops, \ |
271 | .type = REGULATOR_VOLTAGE, \ | 257 | .type = REGULATOR_VOLTAGE, \ |
272 | .owner = THIS_MODULE, \ | 258 | .owner = THIS_MODULE, \ |
273 | .min_uV = S2MPA01_BUCK_MIN1, \ | 259 | .min_uV = MIN_600_MV, \ |
274 | .uV_step = S2MPA01_BUCK_STEP1, \ | 260 | .uV_step = STEP_6_25_MV, \ |
275 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | 261 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ |
276 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | 262 | .ramp_delay = S2MPA01_RAMP_DELAY, \ |
277 | .vsel_reg = S2MPA01_REG_B1CTRL2 + (num - 1) * 2, \ | 263 | .vsel_reg = S2MPA01_REG_B1CTRL2 + (num - 1) * 2, \ |
@@ -286,8 +272,8 @@ static struct regulator_ops s2mpa01_buck_ops = { | |||
286 | .ops = &s2mpa01_buck_ops, \ | 272 | .ops = &s2mpa01_buck_ops, \ |
287 | .type = REGULATOR_VOLTAGE, \ | 273 | .type = REGULATOR_VOLTAGE, \ |
288 | .owner = THIS_MODULE, \ | 274 | .owner = THIS_MODULE, \ |
289 | .min_uV = S2MPA01_BUCK_MIN2, \ | 275 | .min_uV = MIN_800_MV, \ |
290 | .uV_step = S2MPA01_BUCK_STEP1, \ | 276 | .uV_step = STEP_6_25_MV, \ |
291 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | 277 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ |
292 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | 278 | .ramp_delay = S2MPA01_RAMP_DELAY, \ |
293 | .vsel_reg = S2MPA01_REG_B5CTRL2, \ | 279 | .vsel_reg = S2MPA01_REG_B5CTRL2, \ |
@@ -296,14 +282,14 @@ static struct regulator_ops s2mpa01_buck_ops = { | |||
296 | .enable_mask = S2MPA01_ENABLE_MASK \ | 282 | .enable_mask = S2MPA01_ENABLE_MASK \ |
297 | } | 283 | } |
298 | 284 | ||
299 | #define regulator_desc_buck6_7(num) { \ | 285 | #define regulator_desc_buck6_10(num, min, step) { \ |
300 | .name = "BUCK"#num, \ | 286 | .name = "BUCK"#num, \ |
301 | .id = S2MPA01_BUCK##num, \ | 287 | .id = S2MPA01_BUCK##num, \ |
302 | .ops = &s2mpa01_buck_ops, \ | 288 | .ops = &s2mpa01_buck_ops, \ |
303 | .type = REGULATOR_VOLTAGE, \ | 289 | .type = REGULATOR_VOLTAGE, \ |
304 | .owner = THIS_MODULE, \ | 290 | .owner = THIS_MODULE, \ |
305 | .min_uV = S2MPA01_BUCK_MIN1, \ | 291 | .min_uV = min, \ |
306 | .uV_step = S2MPA01_BUCK_STEP1, \ | 292 | .uV_step = step, \ |
307 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | 293 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ |
308 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | 294 | .ramp_delay = S2MPA01_RAMP_DELAY, \ |
309 | .vsel_reg = S2MPA01_REG_B6CTRL2 + (num - 6) * 2, \ | 295 | .vsel_reg = S2MPA01_REG_B6CTRL2 + (num - 6) * 2, \ |
@@ -312,91 +298,43 @@ static struct regulator_ops s2mpa01_buck_ops = { | |||
312 | .enable_mask = S2MPA01_ENABLE_MASK \ | 298 | .enable_mask = S2MPA01_ENABLE_MASK \ |
313 | } | 299 | } |
314 | 300 | ||
315 | #define regulator_desc_buck8 { \ | ||
316 | .name = "BUCK8", \ | ||
317 | .id = S2MPA01_BUCK8, \ | ||
318 | .ops = &s2mpa01_buck_ops, \ | ||
319 | .type = REGULATOR_VOLTAGE, \ | ||
320 | .owner = THIS_MODULE, \ | ||
321 | .min_uV = S2MPA01_BUCK_MIN2, \ | ||
322 | .uV_step = S2MPA01_BUCK_STEP2, \ | ||
323 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
324 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
325 | .vsel_reg = S2MPA01_REG_B8CTRL2, \ | ||
326 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
327 | .enable_reg = S2MPA01_REG_B8CTRL1, \ | ||
328 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
329 | } | ||
330 | |||
331 | #define regulator_desc_buck9 { \ | ||
332 | .name = "BUCK9", \ | ||
333 | .id = S2MPA01_BUCK9, \ | ||
334 | .ops = &s2mpa01_buck_ops, \ | ||
335 | .type = REGULATOR_VOLTAGE, \ | ||
336 | .owner = THIS_MODULE, \ | ||
337 | .min_uV = S2MPA01_BUCK_MIN4, \ | ||
338 | .uV_step = S2MPA01_BUCK_STEP2, \ | ||
339 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
340 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
341 | .vsel_reg = S2MPA01_REG_B9CTRL2, \ | ||
342 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
343 | .enable_reg = S2MPA01_REG_B9CTRL1, \ | ||
344 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
345 | } | ||
346 | |||
347 | #define regulator_desc_buck10 { \ | ||
348 | .name = "BUCK10", \ | ||
349 | .id = S2MPA01_BUCK10, \ | ||
350 | .ops = &s2mpa01_buck_ops, \ | ||
351 | .type = REGULATOR_VOLTAGE, \ | ||
352 | .owner = THIS_MODULE, \ | ||
353 | .min_uV = S2MPA01_BUCK_MIN3, \ | ||
354 | .uV_step = S2MPA01_BUCK_STEP2, \ | ||
355 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
356 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
357 | .vsel_reg = S2MPA01_REG_B10CTRL2, \ | ||
358 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
359 | .enable_reg = S2MPA01_REG_B10CTRL1, \ | ||
360 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
361 | } | ||
362 | |||
363 | static struct regulator_desc regulators[] = { | 301 | static struct regulator_desc regulators[] = { |
364 | regulator_desc_ldo2(1), | 302 | regulator_desc_ldo(1, STEP_25_MV), |
365 | regulator_desc_ldo1(2), | 303 | regulator_desc_ldo(2, STEP_50_MV), |
366 | regulator_desc_ldo1(3), | 304 | regulator_desc_ldo(3, STEP_50_MV), |
367 | regulator_desc_ldo1(4), | 305 | regulator_desc_ldo(4, STEP_50_MV), |
368 | regulator_desc_ldo1(5), | 306 | regulator_desc_ldo(5, STEP_50_MV), |
369 | regulator_desc_ldo2(6), | 307 | regulator_desc_ldo(6, STEP_25_MV), |
370 | regulator_desc_ldo1(7), | 308 | regulator_desc_ldo(7, STEP_50_MV), |
371 | regulator_desc_ldo1(8), | 309 | regulator_desc_ldo(8, STEP_50_MV), |
372 | regulator_desc_ldo1(9), | 310 | regulator_desc_ldo(9, STEP_50_MV), |
373 | regulator_desc_ldo1(10), | 311 | regulator_desc_ldo(10, STEP_50_MV), |
374 | regulator_desc_ldo2(11), | 312 | regulator_desc_ldo(11, STEP_25_MV), |
375 | regulator_desc_ldo1(12), | 313 | regulator_desc_ldo(12, STEP_50_MV), |
376 | regulator_desc_ldo1(13), | 314 | regulator_desc_ldo(13, STEP_50_MV), |
377 | regulator_desc_ldo1(14), | 315 | regulator_desc_ldo(14, STEP_50_MV), |
378 | regulator_desc_ldo1(15), | 316 | regulator_desc_ldo(15, STEP_50_MV), |
379 | regulator_desc_ldo1(16), | 317 | regulator_desc_ldo(16, STEP_50_MV), |
380 | regulator_desc_ldo1(17), | 318 | regulator_desc_ldo(17, STEP_50_MV), |
381 | regulator_desc_ldo1(18), | 319 | regulator_desc_ldo(18, STEP_50_MV), |
382 | regulator_desc_ldo1(19), | 320 | regulator_desc_ldo(19, STEP_50_MV), |
383 | regulator_desc_ldo1(20), | 321 | regulator_desc_ldo(20, STEP_50_MV), |
384 | regulator_desc_ldo1(21), | 322 | regulator_desc_ldo(21, STEP_50_MV), |
385 | regulator_desc_ldo2(22), | 323 | regulator_desc_ldo(22, STEP_25_MV), |
386 | regulator_desc_ldo2(23), | 324 | regulator_desc_ldo(23, STEP_25_MV), |
387 | regulator_desc_ldo1(24), | 325 | regulator_desc_ldo(24, STEP_50_MV), |
388 | regulator_desc_ldo1(25), | 326 | regulator_desc_ldo(25, STEP_50_MV), |
389 | regulator_desc_ldo1(26), | 327 | regulator_desc_ldo(26, STEP_50_MV), |
390 | regulator_desc_buck1_4(1), | 328 | regulator_desc_buck1_4(1), |
391 | regulator_desc_buck1_4(2), | 329 | regulator_desc_buck1_4(2), |
392 | regulator_desc_buck1_4(3), | 330 | regulator_desc_buck1_4(3), |
393 | regulator_desc_buck1_4(4), | 331 | regulator_desc_buck1_4(4), |
394 | regulator_desc_buck5, | 332 | regulator_desc_buck5, |
395 | regulator_desc_buck6_7(6), | 333 | regulator_desc_buck6_10(6, MIN_600_MV, STEP_6_25_MV), |
396 | regulator_desc_buck6_7(7), | 334 | regulator_desc_buck6_10(7, MIN_600_MV, STEP_6_25_MV), |
397 | regulator_desc_buck8, | 335 | regulator_desc_buck6_10(8, MIN_800_MV, STEP_12_5_MV), |
398 | regulator_desc_buck9, | 336 | regulator_desc_buck6_10(9, MIN_1500_MV, STEP_12_5_MV), |
399 | regulator_desc_buck10, | 337 | regulator_desc_buck6_10(10, MIN_1000_MV, STEP_12_5_MV), |
400 | }; | 338 | }; |
401 | 339 | ||
402 | static int s2mpa01_pmic_probe(struct platform_device *pdev) | 340 | static int s2mpa01_pmic_probe(struct platform_device *pdev) |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index b16c53a8272f..adab82d5279f 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -255,28 +255,14 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
255 | .set_ramp_delay = s2mps11_set_ramp_delay, | 255 | .set_ramp_delay = s2mps11_set_ramp_delay, |
256 | }; | 256 | }; |
257 | 257 | ||
258 | #define regulator_desc_s2mps11_ldo1(num) { \ | 258 | #define regulator_desc_s2mps11_ldo(num, step) { \ |
259 | .name = "LDO"#num, \ | 259 | .name = "LDO"#num, \ |
260 | .id = S2MPS11_LDO##num, \ | 260 | .id = S2MPS11_LDO##num, \ |
261 | .ops = &s2mps11_ldo_ops, \ | 261 | .ops = &s2mps11_ldo_ops, \ |
262 | .type = REGULATOR_VOLTAGE, \ | 262 | .type = REGULATOR_VOLTAGE, \ |
263 | .owner = THIS_MODULE, \ | 263 | .owner = THIS_MODULE, \ |
264 | .min_uV = S2MPS11_LDO_MIN, \ | 264 | .min_uV = MIN_800_MV, \ |
265 | .uV_step = S2MPS11_LDO_STEP1, \ | 265 | .uV_step = step, \ |
266 | .n_voltages = S2MPS11_LDO_N_VOLTAGES, \ | ||
267 | .vsel_reg = S2MPS11_REG_L1CTRL + num - 1, \ | ||
268 | .vsel_mask = S2MPS11_LDO_VSEL_MASK, \ | ||
269 | .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ | ||
270 | .enable_mask = S2MPS11_ENABLE_MASK \ | ||
271 | } | ||
272 | #define regulator_desc_s2mps11_ldo2(num) { \ | ||
273 | .name = "LDO"#num, \ | ||
274 | .id = S2MPS11_LDO##num, \ | ||
275 | .ops = &s2mps11_ldo_ops, \ | ||
276 | .type = REGULATOR_VOLTAGE, \ | ||
277 | .owner = THIS_MODULE, \ | ||
278 | .min_uV = S2MPS11_LDO_MIN, \ | ||
279 | .uV_step = S2MPS11_LDO_STEP2, \ | ||
280 | .n_voltages = S2MPS11_LDO_N_VOLTAGES, \ | 266 | .n_voltages = S2MPS11_LDO_N_VOLTAGES, \ |
281 | .vsel_reg = S2MPS11_REG_L1CTRL + num - 1, \ | 267 | .vsel_reg = S2MPS11_REG_L1CTRL + num - 1, \ |
282 | .vsel_mask = S2MPS11_LDO_VSEL_MASK, \ | 268 | .vsel_mask = S2MPS11_LDO_VSEL_MASK, \ |
@@ -290,8 +276,8 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
290 | .ops = &s2mps11_buck_ops, \ | 276 | .ops = &s2mps11_buck_ops, \ |
291 | .type = REGULATOR_VOLTAGE, \ | 277 | .type = REGULATOR_VOLTAGE, \ |
292 | .owner = THIS_MODULE, \ | 278 | .owner = THIS_MODULE, \ |
293 | .min_uV = S2MPS11_BUCK_MIN1, \ | 279 | .min_uV = MIN_600_MV, \ |
294 | .uV_step = S2MPS11_BUCK_STEP1, \ | 280 | .uV_step = STEP_6_25_MV, \ |
295 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ | 281 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ |
296 | .ramp_delay = S2MPS11_RAMP_DELAY, \ | 282 | .ramp_delay = S2MPS11_RAMP_DELAY, \ |
297 | .vsel_reg = S2MPS11_REG_B1CTRL2 + (num - 1) * 2, \ | 283 | .vsel_reg = S2MPS11_REG_B1CTRL2 + (num - 1) * 2, \ |
@@ -306,8 +292,8 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
306 | .ops = &s2mps11_buck_ops, \ | 292 | .ops = &s2mps11_buck_ops, \ |
307 | .type = REGULATOR_VOLTAGE, \ | 293 | .type = REGULATOR_VOLTAGE, \ |
308 | .owner = THIS_MODULE, \ | 294 | .owner = THIS_MODULE, \ |
309 | .min_uV = S2MPS11_BUCK_MIN1, \ | 295 | .min_uV = MIN_600_MV, \ |
310 | .uV_step = S2MPS11_BUCK_STEP1, \ | 296 | .uV_step = STEP_6_25_MV, \ |
311 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ | 297 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ |
312 | .ramp_delay = S2MPS11_RAMP_DELAY, \ | 298 | .ramp_delay = S2MPS11_RAMP_DELAY, \ |
313 | .vsel_reg = S2MPS11_REG_B5CTRL2, \ | 299 | .vsel_reg = S2MPS11_REG_B5CTRL2, \ |
@@ -316,14 +302,14 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
316 | .enable_mask = S2MPS11_ENABLE_MASK \ | 302 | .enable_mask = S2MPS11_ENABLE_MASK \ |
317 | } | 303 | } |
318 | 304 | ||
319 | #define regulator_desc_s2mps11_buck6_8(num) { \ | 305 | #define regulator_desc_s2mps11_buck6_10(num, min, step) { \ |
320 | .name = "BUCK"#num, \ | 306 | .name = "BUCK"#num, \ |
321 | .id = S2MPS11_BUCK##num, \ | 307 | .id = S2MPS11_BUCK##num, \ |
322 | .ops = &s2mps11_buck_ops, \ | 308 | .ops = &s2mps11_buck_ops, \ |
323 | .type = REGULATOR_VOLTAGE, \ | 309 | .type = REGULATOR_VOLTAGE, \ |
324 | .owner = THIS_MODULE, \ | 310 | .owner = THIS_MODULE, \ |
325 | .min_uV = S2MPS11_BUCK_MIN1, \ | 311 | .min_uV = min, \ |
326 | .uV_step = S2MPS11_BUCK_STEP1, \ | 312 | .uV_step = step, \ |
327 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ | 313 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ |
328 | .ramp_delay = S2MPS11_RAMP_DELAY, \ | 314 | .ramp_delay = S2MPS11_RAMP_DELAY, \ |
329 | .vsel_reg = S2MPS11_REG_B6CTRL2 + (num - 6) * 2, \ | 315 | .vsel_reg = S2MPS11_REG_B6CTRL2 + (num - 6) * 2, \ |
@@ -332,87 +318,55 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
332 | .enable_mask = S2MPS11_ENABLE_MASK \ | 318 | .enable_mask = S2MPS11_ENABLE_MASK \ |
333 | } | 319 | } |
334 | 320 | ||
335 | #define regulator_desc_s2mps11_buck9 { \ | ||
336 | .name = "BUCK9", \ | ||
337 | .id = S2MPS11_BUCK9, \ | ||
338 | .ops = &s2mps11_buck_ops, \ | ||
339 | .type = REGULATOR_VOLTAGE, \ | ||
340 | .owner = THIS_MODULE, \ | ||
341 | .min_uV = S2MPS11_BUCK_MIN3, \ | ||
342 | .uV_step = S2MPS11_BUCK_STEP3, \ | ||
343 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ | ||
344 | .ramp_delay = S2MPS11_RAMP_DELAY, \ | ||
345 | .vsel_reg = S2MPS11_REG_B9CTRL2, \ | ||
346 | .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ | ||
347 | .enable_reg = S2MPS11_REG_B9CTRL1, \ | ||
348 | .enable_mask = S2MPS11_ENABLE_MASK \ | ||
349 | } | ||
350 | |||
351 | #define regulator_desc_s2mps11_buck10 { \ | ||
352 | .name = "BUCK10", \ | ||
353 | .id = S2MPS11_BUCK10, \ | ||
354 | .ops = &s2mps11_buck_ops, \ | ||
355 | .type = REGULATOR_VOLTAGE, \ | ||
356 | .owner = THIS_MODULE, \ | ||
357 | .min_uV = S2MPS11_BUCK_MIN2, \ | ||
358 | .uV_step = S2MPS11_BUCK_STEP2, \ | ||
359 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ | ||
360 | .ramp_delay = S2MPS11_RAMP_DELAY, \ | ||
361 | .vsel_reg = S2MPS11_REG_B10CTRL2, \ | ||
362 | .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ | ||
363 | .enable_reg = S2MPS11_REG_B10CTRL1, \ | ||
364 | .enable_mask = S2MPS11_ENABLE_MASK \ | ||
365 | } | ||
366 | |||
367 | static const struct regulator_desc s2mps11_regulators[] = { | 321 | static const struct regulator_desc s2mps11_regulators[] = { |
368 | regulator_desc_s2mps11_ldo2(1), | 322 | regulator_desc_s2mps11_ldo(1, STEP_25_MV), |
369 | regulator_desc_s2mps11_ldo1(2), | 323 | regulator_desc_s2mps11_ldo(2, STEP_50_MV), |
370 | regulator_desc_s2mps11_ldo1(3), | 324 | regulator_desc_s2mps11_ldo(3, STEP_50_MV), |
371 | regulator_desc_s2mps11_ldo1(4), | 325 | regulator_desc_s2mps11_ldo(4, STEP_50_MV), |
372 | regulator_desc_s2mps11_ldo1(5), | 326 | regulator_desc_s2mps11_ldo(5, STEP_50_MV), |
373 | regulator_desc_s2mps11_ldo2(6), | 327 | regulator_desc_s2mps11_ldo(6, STEP_25_MV), |
374 | regulator_desc_s2mps11_ldo1(7), | 328 | regulator_desc_s2mps11_ldo(7, STEP_50_MV), |
375 | regulator_desc_s2mps11_ldo1(8), | 329 | regulator_desc_s2mps11_ldo(8, STEP_50_MV), |
376 | regulator_desc_s2mps11_ldo1(9), | 330 | regulator_desc_s2mps11_ldo(9, STEP_50_MV), |
377 | regulator_desc_s2mps11_ldo1(10), | 331 | regulator_desc_s2mps11_ldo(10, STEP_50_MV), |
378 | regulator_desc_s2mps11_ldo2(11), | 332 | regulator_desc_s2mps11_ldo(11, STEP_25_MV), |
379 | regulator_desc_s2mps11_ldo1(12), | 333 | regulator_desc_s2mps11_ldo(12, STEP_50_MV), |
380 | regulator_desc_s2mps11_ldo1(13), | 334 | regulator_desc_s2mps11_ldo(13, STEP_50_MV), |
381 | regulator_desc_s2mps11_ldo1(14), | 335 | regulator_desc_s2mps11_ldo(14, STEP_50_MV), |
382 | regulator_desc_s2mps11_ldo1(15), | 336 | regulator_desc_s2mps11_ldo(15, STEP_50_MV), |
383 | regulator_desc_s2mps11_ldo1(16), | 337 | regulator_desc_s2mps11_ldo(16, STEP_50_MV), |
384 | regulator_desc_s2mps11_ldo1(17), | 338 | regulator_desc_s2mps11_ldo(17, STEP_50_MV), |
385 | regulator_desc_s2mps11_ldo1(18), | 339 | regulator_desc_s2mps11_ldo(18, STEP_50_MV), |
386 | regulator_desc_s2mps11_ldo1(19), | 340 | regulator_desc_s2mps11_ldo(19, STEP_50_MV), |
387 | regulator_desc_s2mps11_ldo1(20), | 341 | regulator_desc_s2mps11_ldo(20, STEP_50_MV), |
388 | regulator_desc_s2mps11_ldo1(21), | 342 | regulator_desc_s2mps11_ldo(21, STEP_50_MV), |
389 | regulator_desc_s2mps11_ldo2(22), | 343 | regulator_desc_s2mps11_ldo(22, STEP_25_MV), |
390 | regulator_desc_s2mps11_ldo2(23), | 344 | regulator_desc_s2mps11_ldo(23, STEP_25_MV), |
391 | regulator_desc_s2mps11_ldo1(24), | 345 | regulator_desc_s2mps11_ldo(24, STEP_50_MV), |
392 | regulator_desc_s2mps11_ldo1(25), | 346 | regulator_desc_s2mps11_ldo(25, STEP_50_MV), |
393 | regulator_desc_s2mps11_ldo1(26), | 347 | regulator_desc_s2mps11_ldo(26, STEP_50_MV), |
394 | regulator_desc_s2mps11_ldo2(27), | 348 | regulator_desc_s2mps11_ldo(27, STEP_25_MV), |
395 | regulator_desc_s2mps11_ldo1(28), | 349 | regulator_desc_s2mps11_ldo(28, STEP_50_MV), |
396 | regulator_desc_s2mps11_ldo1(29), | 350 | regulator_desc_s2mps11_ldo(29, STEP_50_MV), |
397 | regulator_desc_s2mps11_ldo1(30), | 351 | regulator_desc_s2mps11_ldo(30, STEP_50_MV), |
398 | regulator_desc_s2mps11_ldo1(31), | 352 | regulator_desc_s2mps11_ldo(31, STEP_50_MV), |
399 | regulator_desc_s2mps11_ldo1(32), | 353 | regulator_desc_s2mps11_ldo(32, STEP_50_MV), |
400 | regulator_desc_s2mps11_ldo1(33), | 354 | regulator_desc_s2mps11_ldo(33, STEP_50_MV), |
401 | regulator_desc_s2mps11_ldo1(34), | 355 | regulator_desc_s2mps11_ldo(34, STEP_50_MV), |
402 | regulator_desc_s2mps11_ldo1(35), | 356 | regulator_desc_s2mps11_ldo(35, STEP_50_MV), |
403 | regulator_desc_s2mps11_ldo1(36), | 357 | regulator_desc_s2mps11_ldo(36, STEP_50_MV), |
404 | regulator_desc_s2mps11_ldo1(37), | 358 | regulator_desc_s2mps11_ldo(37, STEP_50_MV), |
405 | regulator_desc_s2mps11_ldo1(38), | 359 | regulator_desc_s2mps11_ldo(38, STEP_50_MV), |
406 | regulator_desc_s2mps11_buck1_4(1), | 360 | regulator_desc_s2mps11_buck1_4(1), |
407 | regulator_desc_s2mps11_buck1_4(2), | 361 | regulator_desc_s2mps11_buck1_4(2), |
408 | regulator_desc_s2mps11_buck1_4(3), | 362 | regulator_desc_s2mps11_buck1_4(3), |
409 | regulator_desc_s2mps11_buck1_4(4), | 363 | regulator_desc_s2mps11_buck1_4(4), |
410 | regulator_desc_s2mps11_buck5, | 364 | regulator_desc_s2mps11_buck5, |
411 | regulator_desc_s2mps11_buck6_8(6), | 365 | regulator_desc_s2mps11_buck6_10(6, MIN_600_MV, STEP_6_25_MV), |
412 | regulator_desc_s2mps11_buck6_8(7), | 366 | regulator_desc_s2mps11_buck6_10(7, MIN_600_MV, STEP_6_25_MV), |
413 | regulator_desc_s2mps11_buck6_8(8), | 367 | regulator_desc_s2mps11_buck6_10(8, MIN_600_MV, STEP_6_25_MV), |
414 | regulator_desc_s2mps11_buck9, | 368 | regulator_desc_s2mps11_buck6_10(9, MIN_3000_MV, STEP_25_MV), |
415 | regulator_desc_s2mps11_buck10, | 369 | regulator_desc_s2mps11_buck6_10(10, MIN_750_MV, STEP_12_5_MV), |
416 | }; | 370 | }; |
417 | 371 | ||
418 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) | 372 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) |
@@ -510,56 +464,29 @@ static struct regulator_ops s2mps14_reg_ops = { | |||
510 | .set_suspend_disable = s2mps14_regulator_set_suspend_disable, | 464 | .set_suspend_disable = s2mps14_regulator_set_suspend_disable, |
511 | }; | 465 | }; |
512 | 466 | ||
513 | #define regulator_desc_s2mps14_ldo1(num) { \ | 467 | #define regulator_desc_s2mps14_ldo(num, min, step) { \ |
514 | .name = "LDO"#num, \ | ||
515 | .id = S2MPS14_LDO##num, \ | ||
516 | .ops = &s2mps14_reg_ops, \ | ||
517 | .type = REGULATOR_VOLTAGE, \ | ||
518 | .owner = THIS_MODULE, \ | ||
519 | .min_uV = S2MPS14_LDO_MIN_800MV, \ | ||
520 | .uV_step = S2MPS14_LDO_STEP_25MV, \ | ||
521 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
522 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
523 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
524 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
525 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
526 | } | ||
527 | #define regulator_desc_s2mps14_ldo2(num) { \ | ||
528 | .name = "LDO"#num, \ | ||
529 | .id = S2MPS14_LDO##num, \ | ||
530 | .ops = &s2mps14_reg_ops, \ | ||
531 | .type = REGULATOR_VOLTAGE, \ | ||
532 | .owner = THIS_MODULE, \ | ||
533 | .min_uV = S2MPS14_LDO_MIN_1800MV, \ | ||
534 | .uV_step = S2MPS14_LDO_STEP_25MV, \ | ||
535 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
536 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
537 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
538 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
539 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
540 | } | ||
541 | #define regulator_desc_s2mps14_ldo3(num) { \ | ||
542 | .name = "LDO"#num, \ | 468 | .name = "LDO"#num, \ |
543 | .id = S2MPS14_LDO##num, \ | 469 | .id = S2MPS14_LDO##num, \ |
544 | .ops = &s2mps14_reg_ops, \ | 470 | .ops = &s2mps14_reg_ops, \ |
545 | .type = REGULATOR_VOLTAGE, \ | 471 | .type = REGULATOR_VOLTAGE, \ |
546 | .owner = THIS_MODULE, \ | 472 | .owner = THIS_MODULE, \ |
547 | .min_uV = S2MPS14_LDO_MIN_800MV, \ | 473 | .min_uV = min, \ |
548 | .uV_step = S2MPS14_LDO_STEP_12_5MV, \ | 474 | .uV_step = step, \ |
549 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | 475 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ |
550 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | 476 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ |
551 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | 477 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ |
552 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | 478 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ |
553 | .enable_mask = S2MPS14_ENABLE_MASK \ | 479 | .enable_mask = S2MPS14_ENABLE_MASK \ |
554 | } | 480 | } |
555 | #define regulator_desc_s2mps14_buck1235(num) { \ | 481 | |
482 | #define regulator_desc_s2mps14_buck(num, min, step) { \ | ||
556 | .name = "BUCK"#num, \ | 483 | .name = "BUCK"#num, \ |
557 | .id = S2MPS14_BUCK##num, \ | 484 | .id = S2MPS14_BUCK##num, \ |
558 | .ops = &s2mps14_reg_ops, \ | 485 | .ops = &s2mps14_reg_ops, \ |
559 | .type = REGULATOR_VOLTAGE, \ | 486 | .type = REGULATOR_VOLTAGE, \ |
560 | .owner = THIS_MODULE, \ | 487 | .owner = THIS_MODULE, \ |
561 | .min_uV = S2MPS14_BUCK1235_MIN_600MV, \ | 488 | .min_uV = min, \ |
562 | .uV_step = S2MPS14_BUCK1235_STEP_6_25MV, \ | 489 | .uV_step = step, \ |
563 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | 490 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ |
564 | .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ | 491 | .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ |
565 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ | 492 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ |
@@ -568,54 +495,38 @@ static struct regulator_ops s2mps14_reg_ops = { | |||
568 | .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ | 495 | .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ |
569 | .enable_mask = S2MPS14_ENABLE_MASK \ | 496 | .enable_mask = S2MPS14_ENABLE_MASK \ |
570 | } | 497 | } |
571 | #define regulator_desc_s2mps14_buck4(num) { \ | ||
572 | .name = "BUCK"#num, \ | ||
573 | .id = S2MPS14_BUCK##num, \ | ||
574 | .ops = &s2mps14_reg_ops, \ | ||
575 | .type = REGULATOR_VOLTAGE, \ | ||
576 | .owner = THIS_MODULE, \ | ||
577 | .min_uV = S2MPS14_BUCK4_MIN_1400MV, \ | ||
578 | .uV_step = S2MPS14_BUCK4_STEP_12_5MV, \ | ||
579 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
580 | .linear_min_sel = S2MPS14_BUCK4_START_SEL, \ | ||
581 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ | ||
582 | .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ | ||
583 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
584 | .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ | ||
585 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
586 | } | ||
587 | 498 | ||
588 | static const struct regulator_desc s2mps14_regulators[] = { | 499 | static const struct regulator_desc s2mps14_regulators[] = { |
589 | regulator_desc_s2mps14_ldo3(1), | 500 | regulator_desc_s2mps14_ldo(1, MIN_800_MV, STEP_12_5_MV), |
590 | regulator_desc_s2mps14_ldo3(2), | 501 | regulator_desc_s2mps14_ldo(2, MIN_800_MV, STEP_12_5_MV), |
591 | regulator_desc_s2mps14_ldo1(3), | 502 | regulator_desc_s2mps14_ldo(3, MIN_800_MV, STEP_25_MV), |
592 | regulator_desc_s2mps14_ldo1(4), | 503 | regulator_desc_s2mps14_ldo(4, MIN_800_MV, STEP_25_MV), |
593 | regulator_desc_s2mps14_ldo3(5), | 504 | regulator_desc_s2mps14_ldo(5, MIN_800_MV, STEP_12_5_MV), |
594 | regulator_desc_s2mps14_ldo3(6), | 505 | regulator_desc_s2mps14_ldo(6, MIN_800_MV, STEP_12_5_MV), |
595 | regulator_desc_s2mps14_ldo1(7), | 506 | regulator_desc_s2mps14_ldo(7, MIN_800_MV, STEP_25_MV), |
596 | regulator_desc_s2mps14_ldo2(8), | 507 | regulator_desc_s2mps14_ldo(8, MIN_1800_MV, STEP_25_MV), |
597 | regulator_desc_s2mps14_ldo3(9), | 508 | regulator_desc_s2mps14_ldo(9, MIN_800_MV, STEP_12_5_MV), |
598 | regulator_desc_s2mps14_ldo3(10), | 509 | regulator_desc_s2mps14_ldo(10, MIN_800_MV, STEP_12_5_MV), |
599 | regulator_desc_s2mps14_ldo1(11), | 510 | regulator_desc_s2mps14_ldo(11, MIN_800_MV, STEP_25_MV), |
600 | regulator_desc_s2mps14_ldo2(12), | 511 | regulator_desc_s2mps14_ldo(12, MIN_1800_MV, STEP_25_MV), |
601 | regulator_desc_s2mps14_ldo2(13), | 512 | regulator_desc_s2mps14_ldo(13, MIN_1800_MV, STEP_25_MV), |
602 | regulator_desc_s2mps14_ldo2(14), | 513 | regulator_desc_s2mps14_ldo(14, MIN_1800_MV, STEP_25_MV), |
603 | regulator_desc_s2mps14_ldo2(15), | 514 | regulator_desc_s2mps14_ldo(15, MIN_1800_MV, STEP_25_MV), |
604 | regulator_desc_s2mps14_ldo2(16), | 515 | regulator_desc_s2mps14_ldo(16, MIN_1800_MV, STEP_25_MV), |
605 | regulator_desc_s2mps14_ldo2(17), | 516 | regulator_desc_s2mps14_ldo(17, MIN_1800_MV, STEP_25_MV), |
606 | regulator_desc_s2mps14_ldo2(18), | 517 | regulator_desc_s2mps14_ldo(18, MIN_1800_MV, STEP_25_MV), |
607 | regulator_desc_s2mps14_ldo1(19), | 518 | regulator_desc_s2mps14_ldo(19, MIN_800_MV, STEP_25_MV), |
608 | regulator_desc_s2mps14_ldo1(20), | 519 | regulator_desc_s2mps14_ldo(20, MIN_800_MV, STEP_25_MV), |
609 | regulator_desc_s2mps14_ldo1(21), | 520 | regulator_desc_s2mps14_ldo(21, MIN_800_MV, STEP_25_MV), |
610 | regulator_desc_s2mps14_ldo3(22), | 521 | regulator_desc_s2mps14_ldo(22, MIN_800_MV, STEP_12_5_MV), |
611 | regulator_desc_s2mps14_ldo1(23), | 522 | regulator_desc_s2mps14_ldo(23, MIN_800_MV, STEP_25_MV), |
612 | regulator_desc_s2mps14_ldo2(24), | 523 | regulator_desc_s2mps14_ldo(24, MIN_1800_MV, STEP_25_MV), |
613 | regulator_desc_s2mps14_ldo2(25), | 524 | regulator_desc_s2mps14_ldo(25, MIN_1800_MV, STEP_25_MV), |
614 | regulator_desc_s2mps14_buck1235(1), | 525 | regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV), |
615 | regulator_desc_s2mps14_buck1235(2), | 526 | regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV), |
616 | regulator_desc_s2mps14_buck1235(3), | 527 | regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV), |
617 | regulator_desc_s2mps14_buck4(4), | 528 | regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV), |
618 | regulator_desc_s2mps14_buck1235(5), | 529 | regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV), |
619 | }; | 530 | }; |
620 | 531 | ||
621 | static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11, | 532 | static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11, |
diff --git a/drivers/regulator/sky81452-regulator.c b/drivers/regulator/sky81452-regulator.c new file mode 100644 index 000000000000..97aff0ccd65f --- /dev/null +++ b/drivers/regulator/sky81452-regulator.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * sky81452-regulator.c SKY81452 regulator driver | ||
3 | * | ||
4 | * Copyright 2014 Skyworks Solutions Inc. | ||
5 | * Author : Gyungoh Yoo <jack.yoo@skyworksinc.com> | ||
6 | * | ||
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, or (at your option) any | ||
10 | * later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/of.h> | ||
27 | #include <linux/regulator/driver.h> | ||
28 | #include <linux/regulator/of_regulator.h> | ||
29 | |||
30 | /* registers */ | ||
31 | #define SKY81452_REG1 0x01 | ||
32 | #define SKY81452_REG3 0x03 | ||
33 | |||
34 | /* bit mask */ | ||
35 | #define SKY81452_LEN 0x40 | ||
36 | #define SKY81452_LOUT 0x1F | ||
37 | |||
38 | static struct regulator_ops sky81452_reg_ops = { | ||
39 | .list_voltage = regulator_list_voltage_linear_range, | ||
40 | .map_voltage = regulator_map_voltage_linear_range, | ||
41 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
42 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
43 | .enable = regulator_enable_regmap, | ||
44 | .disable = regulator_disable_regmap, | ||
45 | .is_enabled = regulator_is_enabled_regmap, | ||
46 | }; | ||
47 | |||
48 | static const struct regulator_linear_range sky81452_reg_ranges[] = { | ||
49 | REGULATOR_LINEAR_RANGE(4500000, 0, 14, 250000), | ||
50 | REGULATOR_LINEAR_RANGE(9000000, 15, 31, 1000000), | ||
51 | }; | ||
52 | |||
53 | static const struct regulator_desc sky81452_reg = { | ||
54 | .name = "LOUT", | ||
55 | .ops = &sky81452_reg_ops, | ||
56 | .type = REGULATOR_VOLTAGE, | ||
57 | .owner = THIS_MODULE, | ||
58 | .n_voltages = SKY81452_LOUT + 1, | ||
59 | .linear_ranges = sky81452_reg_ranges, | ||
60 | .n_linear_ranges = ARRAY_SIZE(sky81452_reg_ranges), | ||
61 | .vsel_reg = SKY81452_REG3, | ||
62 | .vsel_mask = SKY81452_LOUT, | ||
63 | .enable_reg = SKY81452_REG1, | ||
64 | .enable_mask = SKY81452_LEN, | ||
65 | }; | ||
66 | |||
67 | #ifdef CONFIG_OF | ||
68 | static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev) | ||
69 | { | ||
70 | struct regulator_init_data *init_data; | ||
71 | struct device_node *np; | ||
72 | |||
73 | np = of_get_child_by_name(dev->parent->of_node, "regulator"); | ||
74 | if (unlikely(!np)) { | ||
75 | dev_err(dev, "regulator node not found"); | ||
76 | return NULL; | ||
77 | } | ||
78 | |||
79 | init_data = of_get_regulator_init_data(dev, np); | ||
80 | |||
81 | of_node_put(np); | ||
82 | return init_data; | ||
83 | } | ||
84 | #else | ||
85 | static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev) | ||
86 | { | ||
87 | return ERR_PTR(-EINVAL); | ||
88 | } | ||
89 | #endif | ||
90 | |||
91 | static int sky81452_reg_probe(struct platform_device *pdev) | ||
92 | { | ||
93 | struct device *dev = &pdev->dev; | ||
94 | const struct regulator_init_data *init_data = dev_get_platdata(dev); | ||
95 | struct regulator_config config = { }; | ||
96 | struct regulator_dev *rdev; | ||
97 | |||
98 | if (!init_data) { | ||
99 | init_data = sky81452_reg_parse_dt(dev); | ||
100 | if (IS_ERR(init_data)) | ||
101 | return PTR_ERR(init_data); | ||
102 | } | ||
103 | |||
104 | config.dev = dev; | ||
105 | config.init_data = init_data; | ||
106 | config.of_node = dev->of_node; | ||
107 | config.regmap = dev_get_drvdata(dev->parent); | ||
108 | |||
109 | rdev = devm_regulator_register(dev, &sky81452_reg, &config); | ||
110 | if (IS_ERR(rdev)) | ||
111 | return PTR_ERR(rdev); | ||
112 | |||
113 | platform_set_drvdata(pdev, rdev); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static struct platform_driver sky81452_reg_driver = { | ||
119 | .driver = { | ||
120 | .name = "sky81452-regulator", | ||
121 | }, | ||
122 | .probe = sky81452_reg_probe, | ||
123 | }; | ||
124 | |||
125 | module_platform_driver(sky81452_reg_driver); | ||
126 | |||
127 | MODULE_DESCRIPTION("Skyworks SKY81452 Regulator driver"); | ||
128 | MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@skyworksinc.com>"); | ||
129 | MODULE_LICENSE("GPL"); | ||
130 | MODULE_VERSION("1.0"); | ||
diff --git a/drivers/regulator/st-pwm.c b/drivers/regulator/st-pwm.c deleted file mode 100644 index 5ea78df449f8..000000000000 --- a/drivers/regulator/st-pwm.c +++ /dev/null | |||
@@ -1,190 +0,0 @@ | |||
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 const 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"); | ||
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 3ef67a86115c..7380af8bd50d 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c | |||
@@ -211,9 +211,6 @@ static int tps_65023_probe(struct i2c_client *client, | |||
211 | int i; | 211 | int i; |
212 | int error; | 212 | int error; |
213 | 213 | ||
214 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
215 | return -EIO; | ||
216 | |||
217 | /** | 214 | /** |
218 | * init_data points to array of regulator_init structures | 215 | * init_data points to array of regulator_init structures |
219 | * coming from the board-evm file. | 216 | * coming from the board-evm file. |
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index d58db72a63b0..adbe4fc5cf07 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -27,10 +27,13 @@ | |||
27 | #include <linux/regulator/machine.h> | 27 | #include <linux/regulator/machine.h> |
28 | #include <linux/mfd/tps65217.h> | 28 | #include <linux/mfd/tps65217.h> |
29 | 29 | ||
30 | #define TPS65217_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _em, _t, _lr, _nlr) \ | 30 | #define TPS65217_REGULATOR(_name, _id, _of_match, _ops, _n, _vr, _vm, _em, \ |
31 | _t, _lr, _nlr) \ | ||
31 | { \ | 32 | { \ |
32 | .name = _name, \ | 33 | .name = _name, \ |
33 | .id = _id, \ | 34 | .id = _id, \ |
35 | .of_match = of_match_ptr(_of_match), \ | ||
36 | .regulators_node= of_match_ptr("regulators"), \ | ||
34 | .ops = &_ops, \ | 37 | .ops = &_ops, \ |
35 | .n_voltages = _n, \ | 38 | .n_voltages = _n, \ |
36 | .type = REGULATOR_VOLTAGE, \ | 39 | .type = REGULATOR_VOLTAGE, \ |
@@ -138,87 +141,40 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = { | |||
138 | }; | 141 | }; |
139 | 142 | ||
140 | static const struct regulator_desc regulators[] = { | 143 | static const struct regulator_desc regulators[] = { |
141 | TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64, | 144 | TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, "dcdc1", |
142 | TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK, | 145 | tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC1, |
143 | TPS65217_ENABLE_DC1_EN, NULL, tps65217_uv1_ranges, | 146 | TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC1_EN, |
144 | 2), /* DCDC1 voltage range: 900000 ~ 1800000 */ | 147 | NULL, tps65217_uv1_ranges, 2), |
145 | TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64, | 148 | TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, "dcdc2", |
146 | TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK, | 149 | tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC2, |
147 | TPS65217_ENABLE_DC2_EN, NULL, tps65217_uv1_ranges, | 150 | TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC2_EN, |
151 | NULL, tps65217_uv1_ranges, | ||
148 | ARRAY_SIZE(tps65217_uv1_ranges)), | 152 | ARRAY_SIZE(tps65217_uv1_ranges)), |
149 | TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64, | 153 | TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, "dcdc3", |
150 | TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK, | 154 | tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC3, |
151 | TPS65217_ENABLE_DC3_EN, NULL, tps65217_uv1_ranges, | 155 | TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC3_EN, |
152 | 1), /* DCDC3 voltage range: 900000 ~ 1500000 */ | 156 | NULL, tps65217_uv1_ranges, 1), |
153 | TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, tps65217_pmic_ldo1_ops, 16, | 157 | TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, "ldo1", |
154 | TPS65217_REG_DEFLDO1, TPS65217_DEFLDO1_LDO1_MASK, | 158 | tps65217_pmic_ldo1_ops, 16, TPS65217_REG_DEFLDO1, |
155 | TPS65217_ENABLE_LDO1_EN, LDO1_VSEL_table, NULL, 0), | 159 | TPS65217_DEFLDO1_LDO1_MASK, TPS65217_ENABLE_LDO1_EN, |
156 | TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, tps65217_pmic_ops, 64, | 160 | LDO1_VSEL_table, NULL, 0), |
157 | TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK, | 161 | TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, "ldo2", tps65217_pmic_ops, |
158 | TPS65217_ENABLE_LDO2_EN, NULL, tps65217_uv1_ranges, | 162 | 64, TPS65217_REG_DEFLDO2, |
163 | TPS65217_DEFLDO2_LDO2_MASK, TPS65217_ENABLE_LDO2_EN, | ||
164 | NULL, tps65217_uv1_ranges, | ||
159 | ARRAY_SIZE(tps65217_uv1_ranges)), | 165 | ARRAY_SIZE(tps65217_uv1_ranges)), |
160 | TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, tps65217_pmic_ops, 32, | 166 | TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, "ldo3", tps65217_pmic_ops, |
161 | TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK, | 167 | 32, TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK, |
162 | TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, | 168 | TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, |
163 | NULL, tps65217_uv2_ranges, | 169 | NULL, tps65217_uv2_ranges, |
164 | ARRAY_SIZE(tps65217_uv2_ranges)), | 170 | ARRAY_SIZE(tps65217_uv2_ranges)), |
165 | TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, tps65217_pmic_ops, 32, | 171 | TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, "ldo4", tps65217_pmic_ops, |
166 | TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK, | 172 | 32, TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK, |
167 | TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, | 173 | TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, |
168 | NULL, tps65217_uv2_ranges, | 174 | NULL, tps65217_uv2_ranges, |
169 | ARRAY_SIZE(tps65217_uv2_ranges)), | 175 | ARRAY_SIZE(tps65217_uv2_ranges)), |
170 | }; | 176 | }; |
171 | 177 | ||
172 | #ifdef CONFIG_OF | ||
173 | static struct of_regulator_match reg_matches[] = { | ||
174 | { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, | ||
175 | { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, | ||
176 | { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, | ||
177 | { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, | ||
178 | { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, | ||
179 | { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, | ||
180 | { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, | ||
181 | }; | ||
182 | |||
183 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
184 | { | ||
185 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | ||
186 | struct device_node *node = tps->dev->of_node; | ||
187 | struct tps65217_board *pdata; | ||
188 | struct device_node *regs; | ||
189 | int i, count; | ||
190 | |||
191 | regs = of_get_child_by_name(node, "regulators"); | ||
192 | if (!regs) | ||
193 | return NULL; | ||
194 | |||
195 | count = of_regulator_match(&pdev->dev, regs, reg_matches, | ||
196 | TPS65217_NUM_REGULATOR); | ||
197 | of_node_put(regs); | ||
198 | if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) | ||
199 | return NULL; | ||
200 | |||
201 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
202 | if (!pdata) | ||
203 | return NULL; | ||
204 | |||
205 | for (i = 0; i < count; i++) { | ||
206 | if (!reg_matches[i].of_node) | ||
207 | continue; | ||
208 | |||
209 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | ||
210 | pdata->of_node[i] = reg_matches[i].of_node; | ||
211 | } | ||
212 | |||
213 | return pdata; | ||
214 | } | ||
215 | #else | ||
216 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
217 | { | ||
218 | return NULL; | ||
219 | } | ||
220 | #endif | ||
221 | |||
222 | static int tps65217_regulator_probe(struct platform_device *pdev) | 178 | static int tps65217_regulator_probe(struct platform_device *pdev) |
223 | { | 179 | { |
224 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | 180 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); |
@@ -227,14 +183,6 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
227 | struct regulator_config config = { }; | 183 | struct regulator_config config = { }; |
228 | int i; | 184 | int i; |
229 | 185 | ||
230 | if (tps->dev->of_node) | ||
231 | pdata = tps65217_parse_dt(pdev); | ||
232 | |||
233 | if (!pdata) { | ||
234 | dev_err(&pdev->dev, "Platform data not found\n"); | ||
235 | return -EINVAL; | ||
236 | } | ||
237 | |||
238 | if (tps65217_chip_id(tps) != TPS65217) { | 186 | if (tps65217_chip_id(tps) != TPS65217) { |
239 | dev_err(&pdev->dev, "Invalid tps chip version\n"); | 187 | dev_err(&pdev->dev, "Invalid tps chip version\n"); |
240 | return -ENODEV; | 188 | return -ENODEV; |
@@ -245,11 +193,10 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
245 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | 193 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { |
246 | /* Register the regulators */ | 194 | /* Register the regulators */ |
247 | config.dev = tps->dev; | 195 | config.dev = tps->dev; |
248 | config.init_data = pdata->tps65217_init_data[i]; | 196 | if (pdata) |
197 | config.init_data = pdata->tps65217_init_data[i]; | ||
249 | config.driver_data = tps; | 198 | config.driver_data = tps; |
250 | config.regmap = tps->regmap; | 199 | config.regmap = tps->regmap; |
251 | if (tps->dev->of_node) | ||
252 | config.of_node = pdata->of_node[i]; | ||
253 | 200 | ||
254 | rdev = devm_regulator_register(&pdev->dev, ®ulators[i], | 201 | rdev = devm_regulator_register(&pdev->dev, ®ulators[i], |
255 | &config); | 202 | &config); |
@@ -259,6 +206,7 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
259 | return PTR_ERR(rdev); | 206 | return PTR_ERR(rdev); |
260 | } | 207 | } |
261 | } | 208 | } |
209 | |||
262 | return 0; | 210 | return 0; |
263 | } | 211 | } |
264 | 212 | ||
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index e584c998b55f..18fc991175bc 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c | |||
@@ -1047,7 +1047,7 @@ static struct tps65910_board *tps65910_parse_dt_reg_data( | |||
1047 | *tps65910_reg_matches = matches; | 1047 | *tps65910_reg_matches = matches; |
1048 | 1048 | ||
1049 | for (idx = 0; idx < count; idx++) { | 1049 | for (idx = 0; idx < count; idx++) { |
1050 | if (!matches[idx].init_data || !matches[idx].of_node) | 1050 | if (!matches[idx].of_node) |
1051 | continue; | 1051 | continue; |
1052 | 1052 | ||
1053 | pmic_plat_data->tps65910_pmic_init_data[idx] = | 1053 | pmic_plat_data->tps65910_pmic_init_data[idx] = |
@@ -1077,7 +1077,6 @@ static int tps65910_probe(struct platform_device *pdev) | |||
1077 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); | 1077 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); |
1078 | struct regulator_config config = { }; | 1078 | struct regulator_config config = { }; |
1079 | struct tps_info *info; | 1079 | struct tps_info *info; |
1080 | struct regulator_init_data *reg_data; | ||
1081 | struct regulator_dev *rdev; | 1080 | struct regulator_dev *rdev; |
1082 | struct tps65910_reg *pmic; | 1081 | struct tps65910_reg *pmic; |
1083 | struct tps65910_board *pmic_plat_data; | 1082 | struct tps65910_board *pmic_plat_data; |
@@ -1140,14 +1139,6 @@ static int tps65910_probe(struct platform_device *pdev) | |||
1140 | 1139 | ||
1141 | for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS; | 1140 | for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS; |
1142 | i++, info++) { | 1141 | i++, info++) { |
1143 | |||
1144 | reg_data = pmic_plat_data->tps65910_pmic_init_data[i]; | ||
1145 | |||
1146 | /* Regulator API handles empty constraints but not NULL | ||
1147 | * constraints */ | ||
1148 | if (!reg_data) | ||
1149 | continue; | ||
1150 | |||
1151 | /* Register the regulators */ | 1142 | /* Register the regulators */ |
1152 | pmic->info[i] = info; | 1143 | pmic->info[i] = info; |
1153 | 1144 | ||
@@ -1199,7 +1190,7 @@ static int tps65910_probe(struct platform_device *pdev) | |||
1199 | pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED; | 1190 | pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED; |
1200 | 1191 | ||
1201 | config.dev = tps65910->dev; | 1192 | config.dev = tps65910->dev; |
1202 | config.init_data = reg_data; | 1193 | config.init_data = pmic_plat_data->tps65910_pmic_init_data[i]; |
1203 | config.driver_data = pmic; | 1194 | config.driver_data = pmic; |
1204 | config.regmap = tps65910->regmap; | 1195 | config.regmap = tps65910->regmap; |
1205 | 1196 | ||
diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index b5f73de81aad..1825edacbda7 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h | |||
@@ -14,6 +14,27 @@ | |||
14 | #ifndef __LINUX_MFD_SEC_CORE_H | 14 | #ifndef __LINUX_MFD_SEC_CORE_H |
15 | #define __LINUX_MFD_SEC_CORE_H | 15 | #define __LINUX_MFD_SEC_CORE_H |
16 | 16 | ||
17 | /* Macros to represent minimum voltages for LDO/BUCK */ | ||
18 | #define MIN_3000_MV 3000000 | ||
19 | #define MIN_2500_MV 2500000 | ||
20 | #define MIN_2000_MV 2000000 | ||
21 | #define MIN_1800_MV 1800000 | ||
22 | #define MIN_1500_MV 1500000 | ||
23 | #define MIN_1400_MV 1400000 | ||
24 | #define MIN_1000_MV 1000000 | ||
25 | |||
26 | #define MIN_900_MV 900000 | ||
27 | #define MIN_850_MV 850000 | ||
28 | #define MIN_800_MV 800000 | ||
29 | #define MIN_750_MV 750000 | ||
30 | #define MIN_600_MV 600000 | ||
31 | |||
32 | /* Macros to represent steps for LDO/BUCK */ | ||
33 | #define STEP_50_MV 50000 | ||
34 | #define STEP_25_MV 25000 | ||
35 | #define STEP_12_5_MV 12500 | ||
36 | #define STEP_6_25_MV 6250 | ||
37 | |||
17 | enum sec_device_type { | 38 | enum sec_device_type { |
18 | S5M8751X, | 39 | S5M8751X, |
19 | S5M8763X, | 40 | S5M8763X, |
diff --git a/include/linux/mfd/samsung/s2mpa01.h b/include/linux/mfd/samsung/s2mpa01.h index fbc63bc0d6a2..2766108bca2f 100644 --- a/include/linux/mfd/samsung/s2mpa01.h +++ b/include/linux/mfd/samsung/s2mpa01.h | |||
@@ -155,18 +155,6 @@ enum s2mpa01_regulators { | |||
155 | S2MPA01_REGULATOR_MAX, | 155 | S2MPA01_REGULATOR_MAX, |
156 | }; | 156 | }; |
157 | 157 | ||
158 | #define S2MPA01_BUCK_MIN1 600000 | ||
159 | #define S2MPA01_BUCK_MIN2 800000 | ||
160 | #define S2MPA01_BUCK_MIN3 1000000 | ||
161 | #define S2MPA01_BUCK_MIN4 1500000 | ||
162 | #define S2MPA01_LDO_MIN 800000 | ||
163 | |||
164 | #define S2MPA01_BUCK_STEP1 6250 | ||
165 | #define S2MPA01_BUCK_STEP2 12500 | ||
166 | |||
167 | #define S2MPA01_LDO_STEP1 50000 | ||
168 | #define S2MPA01_LDO_STEP2 25000 | ||
169 | |||
170 | #define S2MPA01_LDO_VSEL_MASK 0x3F | 158 | #define S2MPA01_LDO_VSEL_MASK 0x3F |
171 | #define S2MPA01_BUCK_VSEL_MASK 0xFF | 159 | #define S2MPA01_BUCK_VSEL_MASK 0xFF |
172 | #define S2MPA01_ENABLE_MASK (0x03 << S2MPA01_ENABLE_SHIFT) | 160 | #define S2MPA01_ENABLE_MASK (0x03 << S2MPA01_ENABLE_SHIFT) |
diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h index b3ddf98dec37..7981a9d77d3f 100644 --- a/include/linux/mfd/samsung/s2mps11.h +++ b/include/linux/mfd/samsung/s2mps11.h | |||
@@ -171,15 +171,6 @@ enum s2mps11_regulators { | |||
171 | S2MPS11_REGULATOR_MAX, | 171 | S2MPS11_REGULATOR_MAX, |
172 | }; | 172 | }; |
173 | 173 | ||
174 | #define S2MPS11_BUCK_MIN1 600000 | ||
175 | #define S2MPS11_BUCK_MIN2 750000 | ||
176 | #define S2MPS11_BUCK_MIN3 3000000 | ||
177 | #define S2MPS11_LDO_MIN 800000 | ||
178 | #define S2MPS11_BUCK_STEP1 6250 | ||
179 | #define S2MPS11_BUCK_STEP2 12500 | ||
180 | #define S2MPS11_BUCK_STEP3 25000 | ||
181 | #define S2MPS11_LDO_STEP1 50000 | ||
182 | #define S2MPS11_LDO_STEP2 25000 | ||
183 | #define S2MPS11_LDO_VSEL_MASK 0x3F | 174 | #define S2MPS11_LDO_VSEL_MASK 0x3F |
184 | #define S2MPS11_BUCK_VSEL_MASK 0xFF | 175 | #define S2MPS11_BUCK_VSEL_MASK 0xFF |
185 | #define S2MPS11_ENABLE_MASK (0x03 << S2MPS11_ENABLE_SHIFT) | 176 | #define S2MPS11_ENABLE_MASK (0x03 << S2MPS11_ENABLE_SHIFT) |
diff --git a/include/linux/mfd/samsung/s2mps14.h b/include/linux/mfd/samsung/s2mps14.h index 900cd7a04314..c92f4782afb5 100644 --- a/include/linux/mfd/samsung/s2mps14.h +++ b/include/linux/mfd/samsung/s2mps14.h | |||
@@ -123,10 +123,6 @@ enum s2mps14_regulators { | |||
123 | }; | 123 | }; |
124 | 124 | ||
125 | /* Regulator constraints for BUCKx */ | 125 | /* Regulator constraints for BUCKx */ |
126 | #define S2MPS14_BUCK1235_MIN_600MV 600000 | ||
127 | #define S2MPS14_BUCK4_MIN_1400MV 1400000 | ||
128 | #define S2MPS14_BUCK1235_STEP_6_25MV 6250 | ||
129 | #define S2MPS14_BUCK4_STEP_12_5MV 12500 | ||
130 | #define S2MPS14_BUCK1235_START_SEL 0x20 | 126 | #define S2MPS14_BUCK1235_START_SEL 0x20 |
131 | #define S2MPS14_BUCK4_START_SEL 0x40 | 127 | #define S2MPS14_BUCK4_START_SEL 0x40 |
132 | /* | 128 | /* |
@@ -136,12 +132,6 @@ enum s2mps14_regulators { | |||
136 | */ | 132 | */ |
137 | #define S2MPS14_BUCK_RAMP_DELAY 12500 | 133 | #define S2MPS14_BUCK_RAMP_DELAY 12500 |
138 | 134 | ||
139 | /* Regulator constraints for different types of LDOx */ | ||
140 | #define S2MPS14_LDO_MIN_800MV 800000 | ||
141 | #define S2MPS14_LDO_MIN_1800MV 1800000 | ||
142 | #define S2MPS14_LDO_STEP_12_5MV 12500 | ||
143 | #define S2MPS14_LDO_STEP_25MV 25000 | ||
144 | |||
145 | #define S2MPS14_LDO_VSEL_MASK 0x3F | 135 | #define S2MPS14_LDO_VSEL_MASK 0x3F |
146 | #define S2MPS14_BUCK_VSEL_MASK 0xFF | 136 | #define S2MPS14_BUCK_VSEL_MASK 0xFF |
147 | #define S2MPS14_ENABLE_MASK (0x03 << S2MPS14_ENABLE_SHIFT) | 137 | #define S2MPS14_ENABLE_MASK (0x03 << S2MPS14_ENABLE_SHIFT) |
diff --git a/include/linux/platform_data/isl9305.h b/include/linux/platform_data/isl9305.h new file mode 100644 index 000000000000..1419133fa69e --- /dev/null +++ b/include/linux/platform_data/isl9305.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * isl9305 - Intersil ISL9305 DCDC regulator | ||
3 | * | ||
4 | * Copyright 2014 Linaro Ltd | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@kernel.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #ifndef __ISL9305_H | ||
15 | #define __ISL9305_H | ||
16 | |||
17 | #define ISL9305_DCD1 0 | ||
18 | #define ISL9305_DCD2 1 | ||
19 | #define ISL9305_LDO1 2 | ||
20 | #define ISL9305_LDO2 3 | ||
21 | |||
22 | #define ISL9305_MAX_REGULATOR ISL9305_LDO2 | ||
23 | |||
24 | struct regulator_init_data; | ||
25 | |||
26 | struct isl9305_pdata { | ||
27 | struct regulator_init_data *init_data[ISL9305_MAX_REGULATOR]; | ||
28 | }; | ||
29 | |||
30 | #endif | ||
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index f8a8733068a7..d347c805f923 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h | |||
@@ -93,7 +93,12 @@ struct regmap; | |||
93 | * OVER_TEMP Regulator over temp. | 93 | * OVER_TEMP Regulator over temp. |
94 | * FORCE_DISABLE Regulator forcibly shut down by software. | 94 | * FORCE_DISABLE Regulator forcibly shut down by software. |
95 | * VOLTAGE_CHANGE Regulator voltage changed. | 95 | * VOLTAGE_CHANGE Regulator voltage changed. |
96 | * Data passed is old voltage cast to (void *). | ||
96 | * DISABLE Regulator was disabled. | 97 | * DISABLE Regulator was disabled. |
98 | * PRE_VOLTAGE_CHANGE Regulator is about to have voltage changed. | ||
99 | * Data passed is "struct pre_voltage_change_data" | ||
100 | * ABORT_VOLTAGE_CHANGE Regulator voltage change failed for some reason. | ||
101 | * Data passed is old voltage cast to (void *). | ||
97 | * | 102 | * |
98 | * NOTE: These events can be OR'ed together when passed into handler. | 103 | * NOTE: These events can be OR'ed together when passed into handler. |
99 | */ | 104 | */ |
@@ -106,6 +111,21 @@ struct regmap; | |||
106 | #define REGULATOR_EVENT_FORCE_DISABLE 0x20 | 111 | #define REGULATOR_EVENT_FORCE_DISABLE 0x20 |
107 | #define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40 | 112 | #define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40 |
108 | #define REGULATOR_EVENT_DISABLE 0x80 | 113 | #define REGULATOR_EVENT_DISABLE 0x80 |
114 | #define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100 | ||
115 | #define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200 | ||
116 | |||
117 | /** | ||
118 | * struct pre_voltage_change_data - Data sent with PRE_VOLTAGE_CHANGE event | ||
119 | * | ||
120 | * @old_uV: Current voltage before change. | ||
121 | * @min_uV: Min voltage we'll change to. | ||
122 | * @max_uV: Max voltage we'll change to. | ||
123 | */ | ||
124 | struct pre_voltage_change_data { | ||
125 | unsigned long old_uV; | ||
126 | unsigned long min_uV; | ||
127 | unsigned long max_uV; | ||
128 | }; | ||
109 | 129 | ||
110 | struct regulator; | 130 | struct regulator; |
111 | 131 | ||
diff --git a/include/linux/regulator/da9211.h b/include/linux/regulator/da9211.h index 0981ce0e72cc..5479394fefce 100644 --- a/include/linux/regulator/da9211.h +++ b/include/linux/regulator/da9211.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * da9211.h - Regulator device driver for DA9211 | 2 | * da9211.h - Regulator device driver for DA9211/DA9213 |
3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. | 3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
@@ -20,6 +20,11 @@ | |||
20 | 20 | ||
21 | #define DA9211_MAX_REGULATORS 2 | 21 | #define DA9211_MAX_REGULATORS 2 |
22 | 22 | ||
23 | enum da9211_chip_id { | ||
24 | DA9211, | ||
25 | DA9213, | ||
26 | }; | ||
27 | |||
23 | struct da9211_pdata { | 28 | struct da9211_pdata { |
24 | /* | 29 | /* |
25 | * Number of buck | 30 | * Number of buck |
@@ -27,6 +32,6 @@ struct da9211_pdata { | |||
27 | * 2 : 2 phase 2 buck | 32 | * 2 : 2 phase 2 buck |
28 | */ | 33 | */ |
29 | int num_buck; | 34 | int num_buck; |
30 | struct regulator_init_data *init_data; | 35 | struct regulator_init_data *init_data[DA9211_MAX_REGULATORS]; |
31 | }; | 36 | }; |
32 | #endif | 37 | #endif |
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 4efa1ed8a2b0..fc0ee0ce8325 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
@@ -203,6 +203,8 @@ enum regulator_type { | |||
203 | * | 203 | * |
204 | * @name: Identifying name for the regulator. | 204 | * @name: Identifying name for the regulator. |
205 | * @supply_name: Identifying the regulator supply | 205 | * @supply_name: Identifying the regulator supply |
206 | * @of_match: Name used to identify regulator in DT. | ||
207 | * @regulators_node: Name of node containing regulator definitions in DT. | ||
206 | * @id: Numerical identifier for the regulator. | 208 | * @id: Numerical identifier for the regulator. |
207 | * @ops: Regulator operations table. | 209 | * @ops: Regulator operations table. |
208 | * @irq: Interrupt number for the regulator. | 210 | * @irq: Interrupt number for the regulator. |
@@ -240,14 +242,17 @@ enum regulator_type { | |||
240 | * @bypass_val_off: Disabling value for control when using regmap set_bypass | 242 | * @bypass_val_off: Disabling value for control when using regmap set_bypass |
241 | * | 243 | * |
242 | * @enable_time: Time taken for initial enable of regulator (in uS). | 244 | * @enable_time: Time taken for initial enable of regulator (in uS). |
245 | * @off_on_delay: guard time (in uS), before re-enabling a regulator | ||
243 | */ | 246 | */ |
244 | struct regulator_desc { | 247 | struct regulator_desc { |
245 | const char *name; | 248 | const char *name; |
246 | const char *supply_name; | 249 | const char *supply_name; |
250 | const char *of_match; | ||
251 | const char *regulators_node; | ||
247 | int id; | 252 | int id; |
248 | bool continuous_voltage_range; | 253 | bool continuous_voltage_range; |
249 | unsigned n_voltages; | 254 | unsigned n_voltages; |
250 | struct regulator_ops *ops; | 255 | const struct regulator_ops *ops; |
251 | int irq; | 256 | int irq; |
252 | enum regulator_type type; | 257 | enum regulator_type type; |
253 | struct module *owner; | 258 | struct module *owner; |
@@ -278,6 +283,8 @@ struct regulator_desc { | |||
278 | unsigned int bypass_val_off; | 283 | unsigned int bypass_val_off; |
279 | 284 | ||
280 | unsigned int enable_time; | 285 | unsigned int enable_time; |
286 | |||
287 | unsigned int off_on_delay; | ||
281 | }; | 288 | }; |
282 | 289 | ||
283 | /** | 290 | /** |
@@ -350,6 +357,9 @@ struct regulator_dev { | |||
350 | 357 | ||
351 | struct regulator_enable_gpio *ena_pin; | 358 | struct regulator_enable_gpio *ena_pin; |
352 | unsigned int ena_gpio_state:1; | 359 | unsigned int ena_gpio_state:1; |
360 | |||
361 | /* time when this regulator was disabled last time */ | ||
362 | unsigned long last_off_jiffy; | ||
353 | }; | 363 | }; |
354 | 364 | ||
355 | struct regulator_dev * | 365 | struct regulator_dev * |
diff --git a/include/linux/regulator/max1586.h b/include/linux/regulator/max1586.h index de9a7fae20be..cedd0febe882 100644 --- a/include/linux/regulator/max1586.h +++ b/include/linux/regulator/max1586.h | |||
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | struct max1586_subdev_data { | 41 | struct max1586_subdev_data { |
42 | int id; | 42 | int id; |
43 | char *name; | 43 | const char *name; |
44 | struct regulator_init_data *platform_data; | 44 | struct regulator_init_data *platform_data; |
45 | }; | 45 | }; |
46 | 46 | ||