summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-10-01 15:01:17 +0100
committerMark Brown <broonie@kernel.org>2026-10-01 15:01:17 +0100
commite40a96a4f9b58bd5f2d45ef44f5c13b48e54081a (patch)
tree65a27b510ae4eab2754d5291f4c05f28d385fc1c
parent3bd7fb35077f6f4e2000d0981ca0ca0055565509 (diff)
parent6722016006986d96906dae1a2880875a9c414759 (diff)
downloadlinux-next-e40a96a4f9b58bd5f2d45ef44f5c13b48e54081a.tar.gz
linux-next-e40a96a4f9b58bd5f2d45ef44f5c13b48e54081a.zip
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
-rw-r--r--Documentation/devicetree/bindings/regulator/maxim,max77620-regulator.yaml12
-rw-r--r--Documentation/devicetree/bindings/regulator/maxim,max77826.yaml4
-rw-r--r--Documentation/devicetree/bindings/regulator/maxim,max77838.yaml4
-rw-r--r--Documentation/devicetree/bindings/regulator/mediatek,mt6380-regulator.yaml117
-rw-r--r--Documentation/devicetree/bindings/regulator/mps,mp5416.yaml36
-rw-r--r--Documentation/devicetree/bindings/regulator/mps,mp886x.yaml30
-rw-r--r--Documentation/devicetree/bindings/regulator/mps,mpq4210.yaml68
-rw-r--r--Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml50
-rw-r--r--Documentation/devicetree/bindings/regulator/mt6380-regulator.txt89
-rw-r--r--Documentation/devicetree/bindings/regulator/nexperia,nex10000ub.yaml69
-rw-r--r--Documentation/devicetree/bindings/regulator/nxp,pf0900.yaml2
-rw-r--r--Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml4
-rw-r--r--Documentation/devicetree/bindings/regulator/pwm-regulator.yaml2
-rw-r--r--Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml16
-rw-r--r--Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml6
-rw-r--r--Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml8
-rw-r--r--Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml4
-rw-r--r--Documentation/devicetree/bindings/regulator/ti,tps65023.yaml90
-rw-r--r--Documentation/devicetree/bindings/regulator/ti,tps6586x.yaml196
-rw-r--r--Documentation/devicetree/bindings/regulator/tps65023.txt60
-rw-r--r--Documentation/devicetree/bindings/regulator/tps6586x.txt135
-rw-r--r--Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml3
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.yaml2
-rw-r--r--MAINTAINERS6
-rw-r--r--drivers/regulator/88pm886-regulator.c26
-rw-r--r--drivers/regulator/Kconfig21
-rw-r--r--drivers/regulator/Makefile2
-rw-r--r--drivers/regulator/ab8500-ext.c2
-rw-r--r--drivers/regulator/ab8500.c748
-rw-r--r--drivers/regulator/axp20x-regulator.c6
-rw-r--r--drivers/regulator/core.c10
-rw-r--r--drivers/regulator/fixed.c4
-rw-r--r--drivers/regulator/mp886x.c34
-rw-r--r--drivers/regulator/mpq4210.c243
-rw-r--r--drivers/regulator/nex10000ub-regulator.c147
-rw-r--r--drivers/regulator/pca9450-regulator.c81
-rw-r--r--drivers/regulator/pf1550-regulator.c19
-rw-r--r--drivers/regulator/pv88080-regulator.c4
-rw-r--r--drivers/regulator/qcom-rpmh-regulator.c55
-rw-r--r--drivers/regulator/rt6190-regulator.c18
-rw-r--r--drivers/regulator/tps6105x-regulator.c2
-rw-r--r--drivers/regulator/tps65185.c6
-rw-r--r--include/linux/mfd/88pm886.h7
-rw-r--r--include/linux/regulator/driver.h2
-rw-r--r--include/linux/regulator/pca9450.h4
-rw-r--r--kernel/irq/irqdesc.c10
-rw-r--r--kernel/softirq.c4
47 files changed, 1980 insertions, 488 deletions
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77620-regulator.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77620-regulator.yaml
index 7118c34961ba..0f2901cab8af 100644
--- a/Documentation/devicetree/bindings/regulator/maxim,max77620-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/maxim,max77620-regulator.yaml
@@ -10,17 +10,17 @@ maintainers:
- Svyatoslav Ryhel <clamor95@gmail.com>
description:
- Device has multiple DCDC(sd[0-3]) and LDOs(ldo[0-8]). The input supply
- of these regulators are defined under parent device node. Details of
- regulator properties are defined as child node under sub-node "regulators"
- which is child node of device node.
+ Device has multiple DCDC (sd[0-3], plus sd4 on MAX20024) and LDOs
+ (ldo[0-8]). The input supply of these regulators are defined under parent
+ device node. Details of regulator properties are defined as child node under
+ sub-node "regulators" which is child node of device node.
patternProperties:
- "^in-(sd[0-3]|ldo(0-1|2|3-5|4-6|7-8))-supply$":
+ "^in-(sd[0-4]|ldo(0-1|2|3-5|4-6|7-8))-supply$":
$ref: /schemas/types.yaml#/definitions/phandle
description: Input supply for DCDC or LDO
- "^(sd[0-3]|ldo[0-8])$":
+ "^(sd[0-4]|ldo[0-8])$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77826.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77826.yaml
index 6d6bbfbd26d4..3c02f98a38e9 100644
--- a/Documentation/devicetree/bindings/regulator/maxim,max77826.yaml
+++ b/Documentation/devicetree/bindings/regulator/maxim,max77826.yaml
@@ -62,6 +62,6 @@ examples:
regulator-max-microvolt = <3587500>;
};
};
- };
- };
+ };
+ };
...
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77838.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77838.yaml
index bed36af5493d..bbfc06fbf547 100644
--- a/Documentation/devicetree/bindings/regulator/maxim,max77838.yaml
+++ b/Documentation/devicetree/bindings/regulator/maxim,max77838.yaml
@@ -63,6 +63,6 @@ examples:
regulator-max-microvolt = <1800000>;
};
};
- };
- };
+ };
+ };
...
diff --git a/Documentation/devicetree/bindings/regulator/mediatek,mt6380-regulator.yaml b/Documentation/devicetree/bindings/regulator/mediatek,mt6380-regulator.yaml
new file mode 100644
index 000000000000..0b3c604da727
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mediatek,mt6380-regulator.yaml
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/mediatek,mt6380-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT6380 Regulator
+
+maintainers:
+ - Sean Wang <sean.wang@mediatek.com>
+
+properties:
+ compatible:
+ const: mediatek,mt6380-regulator
+
+patternProperties:
+ '^buck-(vcore1?|vrf)$':
+ description: BUCK regulators
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+ required:
+ - regulator-min-microvolt
+ - regulator-max-microvolt
+ - regulator-ramp-delay
+
+ '^ldo-v([mat]|phy|ddr)$':
+ type: object
+ description: LDO regulators
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+ required:
+ - regulator-min-microvolt
+ - regulator-max-microvolt
+ - regulator-ramp-delay
+
+required:
+ - compatible
+
+additionalProperties: false
+
+examples:
+ - |
+ regulators {
+ compatible = "mediatek,mt6380-regulator";
+
+ buck-vcore1 {
+ regulator-name = "vcore1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1393750>;
+ regulator-ramp-delay = <6250>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck-vcore {
+ regulator-name = "vcore";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1393750>;
+ regulator-ramp-delay = <6250>;
+ };
+
+ buck-vrf {
+ regulator-name = "vrf";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1575000>;
+ regulator-ramp-delay = <0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo-vm {
+ regulator-name = "vm";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-ramp-delay = <0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo-va {
+ regulator-name = "va";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo-vphy {
+ regulator-name = "vphy";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo-vddr {
+ regulator-name = "vddr";
+ regulator-min-microvolt = <1240000>;
+ regulator-max-microvolt = <1840000>;
+ regulator-ramp-delay = <0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo-vt {
+ regulator-name = "vt";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml b/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml
index f825ee9efd81..4b05e07f5537 100644
--- a/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml
+++ b/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml
@@ -53,26 +53,26 @@ examples:
#size-cells = <0>;
pmic@69 {
- compatible = "mps,mp5416";
- reg = <0x69>;
+ compatible = "mps,mp5416";
+ reg = <0x69>;
- regulators {
+ regulators {
- buck1 {
- regulator-name = "buck1";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <2187500>;
- regulator-min-microamp = <3800000>;
- regulator-max-microamp = <6800000>;
- regulator-boot-on;
- };
+ buck1 {
+ regulator-name = "buck1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-min-microamp = <3800000>;
+ regulator-max-microamp = <6800000>;
+ regulator-boot-on;
+ };
- ldo2 {
- regulator-name = "ldo2";
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <3975000>;
+ ldo2 {
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3975000>;
+ };
};
- };
- };
- };
+ };
+ };
...
diff --git a/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml b/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml
index 374a4f6b1e23..68f64e86e476 100644
--- a/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml
+++ b/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml
@@ -4,17 +4,30 @@
$id: http://devicetree.org/schemas/regulator/mps,mp886x.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Monolithic Power Systems MP8867/MP8869 voltage regulator
+title: Monolithic Power Systems MP8864/MP8867/MP8869 voltage regulator
maintainers:
- Jisheng Zhang <jszhang@kernel.org>
allOf:
- $ref: regulator.yaml#
+ - if:
+ properties:
+ compatible:
+ const: mps,mp8864
+ then:
+ properties:
+ mps,switch-frequency-hz:
+ enum: [600000, 850000, 1100000, 1600000]
+ else:
+ properties:
+ mps,switch-frequency-hz:
+ enum: [500000, 750000, 1000000, 1250000, 1500000]
properties:
compatible:
enum:
+ - mps,mp8864
- mps,mp8867
- mps,mp8869
@@ -33,7 +46,6 @@ properties:
mps,switch-frequency-hz:
description: The valid switch frequency in Hertz.
- enum: [500000, 750000, 1000000, 1250000, 1500000]
required:
- compatible
@@ -50,13 +62,13 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
regulator@62 {
- compatible = "mps,mp8869";
- regulator-name = "vcpu";
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <1150000>;
- enable-gpios = <&porta 1 GPIO_ACTIVE_LOW>;
- mps,fb-voltage-divider = <80 240>;
- reg = <0x62>;
+ compatible = "mps,mp8869";
+ regulator-name = "vcpu";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ enable-gpios = <&porta 1 GPIO_ACTIVE_LOW>;
+ mps,fb-voltage-divider = <80 240>;
+ reg = <0x62>;
};
};
diff --git a/Documentation/devicetree/bindings/regulator/mps,mpq4210.yaml b/Documentation/devicetree/bindings/regulator/mps,mpq4210.yaml
new file mode 100644
index 000000000000..c1914aa1a9d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mps,mpq4210.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/mps,mpq4210.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Monolithic Power Systems MPQ4210 buck-boost regulator
+
+maintainers:
+ - Tapio Reijonen <tapio.reijonen@vaisala.com>
+
+description:
+ The MPQ4210 is a synchronous four-switch buck-boost controller with an I2C
+ interface. The output voltage is programmed through an 11-bit feedback
+ reference DAC and scaled by an external feedback resistor divider.
+
+ The controller ramps the feedback reference at 38, 50, 75 or 150 mV/ms.
+ The divider scales the ramp rate along with the voltage, so the output
+ ramp rates that regulator-ramp-delay can select are those values
+ multiplied by (R1 + R2) / R2.
+
+allOf:
+ - $ref: regulator.yaml#
+
+properties:
+ compatible:
+ const: mps,mpq4210
+
+ reg:
+ maxItems: 1
+
+ enable-gpios:
+ description: GPIO connected to the EN pin. If absent, EN is assumed to
+ be permanently asserted.
+ maxItems: 1
+
+ mps,fb-voltage-divider-ohms:
+ description: An array of two integers containing the resistor values R1
+ and R2 of the output feedback voltage divider.
+ maxItems: 2
+
+required:
+ - compatible
+ - reg
+ - mps,fb-voltage-divider-ohms
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ regulator@64 {
+ compatible = "mps,mpq4210";
+ reg = <0x64>;
+ regulator-name = "vout";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <20000000>;
+ enable-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+ /* R1 = 82 kOhm, R2 = 9.1 kOhm */
+ mps,fb-voltage-divider-ohms = <82000 9100>;
+ /* 50 mV/ms reference ramp x (82000 + 9100) / 9100 */
+ regulator-ramp-delay = <500>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml b/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml
index 0d34af98403f..726aaeac054e 100644
--- a/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml
+++ b/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml
@@ -88,30 +88,30 @@ examples:
#size-cells = <0>;
pmic@69 {
- compatible = "mps,mpq7920";
- reg = <0x69>;
-
- regulators {
- mps,switch-freq = /bits/ 8 <1>;
-
- buck1 {
- regulator-name = "buck1";
- regulator-min-microvolt = <400000>;
- regulator-max-microvolt = <3587500>;
- regulator-min-microamp = <460000>;
- regulator-max-microamp = <7600000>;
- regulator-boot-on;
- mps,buck-ovp-disable;
- mps,buck-phase-delay = /bits/ 8 <2>;
- mps,buck-softstart = /bits/ 8 <1>;
+ compatible = "mps,mpq7920";
+ reg = <0x69>;
+
+ regulators {
+ mps,switch-freq = /bits/ 8 <1>;
+
+ buck1 {
+ regulator-name = "buck1";
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <3587500>;
+ regulator-min-microamp = <460000>;
+ regulator-max-microamp = <7600000>;
+ regulator-boot-on;
+ mps,buck-ovp-disable;
+ mps,buck-phase-delay = /bits/ 8 <2>;
+ mps,buck-softstart = /bits/ 8 <1>;
+ };
+
+ ldo2 {
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <3587500>;
+ };
};
-
- ldo2 {
- regulator-name = "ldo2";
- regulator-min-microvolt = <650000>;
- regulator-max-microvolt = <3587500>;
- };
- };
- };
- };
+ };
+ };
...
diff --git a/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt
deleted file mode 100644
index 0058441f16d2..000000000000
--- a/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-MediaTek MT6380 Regulator
-
-All voltage regulators provided by the MT6380 PMIC are described as the
-subnodes of the MT6380 regulators node. Each regulator is named according
-to its regulator type, buck-<name> and ldo-<name>. The definition for each
-of these nodes is defined using the standard binding for regulators at
-Documentation/devicetree/bindings/regulator/regulator.txt.
-
-The valid names for regulators are:
-BUCK:
- buck-core1, buck-vcore, buck-vrf
-LDO:
- ldo-vm ,ldo-va , ldo-vphy, ldo-vddr, ldo-vt
-
-Example:
-
- regulators {
- compatible = "mediatek,mt6380-regulator";
-
- mt6380_vcpu_reg: buck-vcore1 {
- regulator-name = "vcore1";
- regulator-min-microvolt = < 600000>;
- regulator-max-microvolt = <1393750>;
- regulator-ramp-delay = <6250>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- mt6380_vcore_reg: buck-vcore {
- regulator-name = "vcore";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1393750>;
- regulator-ramp-delay = <6250>;
- };
-
- mt6380_vrf_reg: buck-vrf {
- regulator-name = "vrf";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1575000>;
- regulator-ramp-delay = <0>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- mt6380_vm_reg: ldo-vm {
- regulator-name = "vm";
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1400000>;
- regulator-ramp-delay = <0>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- mt6380_va_reg: ldo-va {
- regulator-name = "va";
- regulator-min-microvolt = <2200000>;
- regulator-max-microvolt = <3300000>;
- regulator-ramp-delay = <0>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- mt6380_vphy_reg: ldo-vphy {
- regulator-name = "vphy";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-ramp-delay = <0>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- mt6380_vddr_reg: ldo-vddr {
- regulator-name = "vddr";
- regulator-min-microvolt = <1240000>;
- regulator-max-microvolt = <1840000>;
- regulator-ramp-delay = <0>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- mt6380_vt_reg: ldo-vt {
- regulator-name = "vt";
- regulator-min-microvolt = <2200000>;
- regulator-max-microvolt = <3300000>;
- regulator-ramp-delay = <0>;
- regulator-always-on;
- regulator-boot-on;
- };
- };
diff --git a/Documentation/devicetree/bindings/regulator/nexperia,nex10000ub.yaml b/Documentation/devicetree/bindings/regulator/nexperia,nex10000ub.yaml
new file mode 100644
index 000000000000..3c0db59b8c1f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/nexperia,nex10000ub.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/nexperia,nex10000ub.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nexperia NEX10000UB dual output LCD bias power supply
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+
+description:
+ The NEX10000UB is designed to supply positive/negative supplies for display Panels.
+
+properties:
+ compatible:
+ enum:
+ - nexperia,nex10000ub
+
+ reg:
+ maxItems: 1
+
+ vin-supply: true
+
+patternProperties:
+ "^(vpos|vneg)$":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ enable-gpios:
+ maxItems: 1
+
+ required:
+ - enable-gpios
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ regulator@3e {
+ compatible = "nexperia,nex10000ub";
+ reg = <0x3e>;
+ vin-supply = <&supply>;
+
+ vpos {
+ regulator-name = "outp";
+ regulator-boot-on;
+ enable-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ vneg {
+ regulator-name = "outn";
+ regulator-boot-on;
+ enable-gpios = <&gpio 40 GPIO_ACTIVE_HIGH>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/nxp,pf0900.yaml b/Documentation/devicetree/bindings/regulator/nxp,pf0900.yaml
index 8c8fc2cd4ced..38fe80749c3c 100644
--- a/Documentation/devicetree/bindings/regulator/nxp,pf0900.yaml
+++ b/Documentation/devicetree/bindings/regulator/nxp,pf0900.yaml
@@ -160,4 +160,4 @@ examples:
};
};
};
- };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml b/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml
index b5181719daa1..1618e8f1c4c4 100644
--- a/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml
+++ b/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml
@@ -82,6 +82,6 @@ examples:
regulator-max-microvolt = <1200000>;
};
};
- };
- };
+ };
+ };
...
diff --git a/Documentation/devicetree/bindings/regulator/pwm-regulator.yaml b/Documentation/devicetree/bindings/regulator/pwm-regulator.yaml
index 80ecf938b749..a7f48d33bad5 100644
--- a/Documentation/devicetree/bindings/regulator/pwm-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.yaml
@@ -116,7 +116,7 @@ examples:
regulator-max-microvolt = <1114000>;
regulator-name = "vdd_logic";
- /* Voltage Duty-Cycle */
+ /* Voltage Duty-Cycle */
voltage-table = <1114000 0>,
<1095000 10>,
<1076000 20>,
diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml
index eed2ce7fa861..9115885e7985 100644
--- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml
@@ -191,6 +191,22 @@ allOf:
properties:
compatible:
enum:
+ - qcom,pm6350-rpmh-regulators
+ then:
+ properties:
+ vdd-l2-l5-l7-supply: true
+ vdd-l3-l6-l8-l9-l10-supply: true
+ vdd-l12-l14-supply: true
+ vdd-l15-l19-l22-supply: true
+ vdd-l18-l20-l21-supply: true
+ patternProperties:
+ "^vdd-l([14]|1[1367])-supply$": true
+ "^vdd-s[1-6]-supply$": true
+
+ - if:
+ properties:
+ compatible:
+ enum:
- qcom,pm660-rpmh-regulators
then:
properties:
diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
index fec3d396ca50..1526cd071b61 100644
--- a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
@@ -151,9 +151,9 @@ examples:
richtek,vsync-polarity-high;
lsw {
- regulator-name = "rtmv20,lsw";
- regulator-min-microamp = <0>;
- regulator-max-microamp = <6000000>;
+ regulator-name = "rtmv20,lsw";
+ regulator-min-microamp = <0>;
+ regulator-max-microamp = <6000000>;
};
};
};
diff --git a/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml b/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml
index 82af4d656177..0da920f84f89 100644
--- a/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml
+++ b/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml
@@ -35,10 +35,10 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
regulator@60 {
- compatible = "silergy,sy8824c";
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <1150000>;
- reg = <0x60>;
+ compatible = "silergy,sy8824c";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ reg = <0x60>;
};
};
diff --git a/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml b/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml
index b222adabc7b4..77da91c28c19 100644
--- a/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml
+++ b/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml
@@ -39,8 +39,8 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
regulator@60 {
- compatible = "silergy,sy8827n";
- reg = <0x60>;
+ compatible = "silergy,sy8827n";
+ reg = <0x60>;
};
};
diff --git a/Documentation/devicetree/bindings/regulator/ti,tps65023.yaml b/Documentation/devicetree/bindings/regulator/ti,tps65023.yaml
new file mode 100644
index 000000000000..928698595f52
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/ti,tps65023.yaml
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/ti,tps65023.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments TPS65023 Regulator
+
+maintainers:
+ - Eduard Bostina <egbostina@gmail.com>
+
+properties:
+ compatible:
+ enum:
+ - ti,tps65020
+ - ti,tps65021
+ - ti,tps65023
+
+ reg:
+ maxItems: 1
+
+ regulators:
+ type: object
+ description: >
+ List of child nodes that specify the regulator initialization data.
+ Must be named after their hardware counterparts: VDCDC[1-3] and LDO[1-2].
+
+ patternProperties:
+ "^(VDCDC[1-3]|LDO[1-2])$":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - regulators
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ tps65023@48 {
+ compatible = "ti,tps65023";
+ reg = <0x48>;
+
+ regulators {
+ VDCDC1 {
+ regulator-name = "vdd_mpu";
+ regulator-always-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ VDCDC2 {
+ regulator-name = "vdd_core";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ VDCDC3 {
+ regulator-name = "vdd_io";
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ LDO1 {
+ regulator-name = "vdd_usb18";
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ LDO2 {
+ regulator-name = "vdd_usb33";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/ti,tps6586x.yaml b/Documentation/devicetree/bindings/regulator/ti,tps6586x.yaml
new file mode 100644
index 000000000000..1f7c7b35066f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/ti,tps6586x.yaml
@@ -0,0 +1,196 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/ti,tps6586x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI TPS6586x family of regulators
+
+maintainers:
+ - Thierry Reding <thierry.reding@avionic-design.de>
+
+properties:
+ compatible:
+ const: ti,tps6586x
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ "#gpio-cells":
+ const: 2
+
+ gpio-controller: true
+
+ sys-supply:
+ description: The input supply for SYS.
+
+ ti,system-power-controller:
+ type: boolean
+ description:
+ Whether or not this PMIC is controlling the system power.
+
+ regulators:
+ type: object
+ additionalProperties: false
+ description:
+ list of regulators provided by this controller, LDO5 and LDO_RTC is
+ supplied by SYS regulator internally and driver take care of making
+ proper parent child relationship.
+
+ properties:
+ sys:
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+ patternProperties:
+ "^ldo([0-9]|_rtc)$":
+ type: object
+ allOf:
+ - $ref: /schemas/regulator/regulator.yaml#
+ - $ref: /schemas/regulator/nvidia,tegra-regulators-coupling.yaml#
+ unevaluatedProperties: false
+
+ "^sm[0-2]$":
+ type: object
+ allOf:
+ - $ref: /schemas/regulator/regulator.yaml#
+ - $ref: /schemas/regulator/nvidia,tegra-regulators-coupling.yaml#
+ unevaluatedProperties: false
+
+patternProperties:
+ "^vin-sm[0-2]-supply$":
+ description: The input supply for the corresponding SM (SM0, SM1, or SM2).
+
+ "^vinldo(01|23|4|678|9)-supply$":
+ description: The input supply for the corresponding LDO or group of LDOs.
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - regulators
+ - "#gpio-cells"
+ - gpio-controller
+ - sys-supply
+ - vin-sm0-supply
+ - vin-sm1-supply
+ - vin-sm2-supply
+ - vinldo01-supply
+ - vinldo23-supply
+ - vinldo4-supply
+ - vinldo678-supply
+ - vinldo9-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@34 {
+ compatible = "ti,tps6586x";
+ reg = <0x34>;
+ interrupts = <0 88 0x4>;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ ti,system-power-controller;
+
+ sys-supply = <&vdd_5v0_sys>;
+ vin-sm0-supply = <&sys_reg>;
+ vin-sm1-supply = <&sys_reg>;
+ vin-sm2-supply = <&sys_reg>;
+ vinldo01-supply = <&sm2_reg>;
+ vinldo23-supply = <&sm2_reg>;
+ vinldo4-supply = <&sm2_reg>;
+ vinldo678-supply = <&sm2_reg>;
+ vinldo9-supply = <&sm2_reg>;
+
+ regulators {
+ sys {
+ regulator-name = "vdd_sys";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sm0 {
+ regulator-min-microvolt = < 725000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sm1 {
+ regulator-min-microvolt = < 725000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sm2 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <4550000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo0 {
+ regulator-name = "PCIE CLK";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo1 {
+ regulator-min-microvolt = < 725000>;
+ regulator-max-microvolt = <1500000>;
+ };
+
+ ldo2 {
+ regulator-min-microvolt = < 725000>;
+ regulator-max-microvolt = <1500000>;
+ };
+
+ ldo3 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo4 {
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <2475000>;
+ };
+
+ ldo5 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo6 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo7 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo8 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo9 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/tps65023.txt b/Documentation/devicetree/bindings/regulator/tps65023.txt
deleted file mode 100644
index a4714e4da370..000000000000
--- a/Documentation/devicetree/bindings/regulator/tps65023.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-TPS65023 family of regulators
-
-Required properties:
-- compatible: Must be one of the following.
- "ti,tps65020",
- "ti,tps65021",
- "ti,tps65023",
-- reg: I2C slave address
-- regulators: list of regulators provided by this controller, must be named
- after their hardware counterparts: VDCDC[1-3] and LDO[1-2]
-- regulators: This is the list of child nodes that specify the regulator
- initialization data for defined regulators. The definition for each of
- these nodes is defined using the standard binding for regulators found at
- Documentation/devicetree/bindings/regulator/regulator.txt.
-
-Each regulator is defined using the standard binding for regulators.
-
-Example:
-
- tps65023@48 {
- compatible = "ti,tps65023";
- reg = <0x48>;
-
- regulators {
- VDCDC1 {
- regulator-name = "vdd_mpu";
- regulator-always-on;
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- VDCDC2 {
- regulator-name = "vdd_core";
- regulator-always-on;
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- VDCDC3 {
- regulator-name = "vdd_io";
- regulator-always-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- LDO1 {
- regulator-name = "vdd_usb18";
- regulator-always-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- LDO2 {
- regulator-name = "vdd_usb33";
- regulator-always-on;
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/regulator/tps6586x.txt b/Documentation/devicetree/bindings/regulator/tps6586x.txt
deleted file mode 100644
index 8b40cac24d93..000000000000
--- a/Documentation/devicetree/bindings/regulator/tps6586x.txt
+++ /dev/null
@@ -1,135 +0,0 @@
-TPS6586x family of regulators
-
-Required properties:
-- compatible: "ti,tps6586x"
-- reg: I2C slave address
-- interrupts: the interrupt outputs of the controller
-- #gpio-cells: number of cells to describe a GPIO
-- gpio-controller: mark the device as a GPIO controller
-- regulators: A node that houses a sub-node for each regulator within the
- device. Each sub-node is identified using the node's name (or the deprecated
- regulator-compatible property if present), with valid values listed below.
- The content of each sub-node is defined by the standard binding for
- regulators; see regulator.txt.
- sys, sm[0-2], ldo[0-9] and ldo_rtc
-- sys-supply: The input supply for SYS.
-- vin-sm0-supply: The input supply for the SM0.
-- vin-sm1-supply: The input supply for the SM1.
-- vin-sm2-supply: The input supply for the SM2.
-- vinldo01-supply: The input supply for the LDO1 and LDO2
-- vinldo23-supply: The input supply for the LDO2 and LDO3
-- vinldo4-supply: The input supply for the LDO4
-- vinldo678-supply: The input supply for the LDO6, LDO7 and LDO8
-- vinldo9-supply: The input supply for the LDO9
-
-Optional properties:
-- ti,system-power-controller: Telling whether or not this pmic is controlling
- the system power.
-
-Each regulator is defined using the standard binding for regulators.
-
-Note: LDO5 and LDO_RTC is supplied by SYS regulator internally and driver
- take care of making proper parent child relationship.
-
-Example:
-
- pmu: tps6586x@34 {
- compatible = "ti,tps6586x";
- reg = <0x34>;
- interrupts = <0 88 0x4>;
-
- #gpio-cells = <2>;
- gpio-controller;
-
- ti,system-power-controller;
-
- sys-supply = <&some_reg>;
- vin-sm0-supply = <&some_reg>;
- vin-sm1-supply = <&some_reg>;
- vin-sm2-supply = <&some_reg>;
- vinldo01-supply = <...>;
- vinldo23-supply = <...>;
- vinldo4-supply = <...>;
- vinldo678-supply = <...>;
- vinldo9-supply = <...>;
-
- regulators {
- sys_reg: sys {
- regulator-name = "vdd_sys";
- regulator-boot-on;
- regulator-always-on;
- };
-
- sm0_reg: sm0 {
- regulator-min-microvolt = < 725000>;
- regulator-max-microvolt = <1500000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- sm1_reg: sm1 {
- regulator-min-microvolt = < 725000>;
- regulator-max-microvolt = <1500000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- sm2_reg: sm2 {
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <4550000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- ldo0_reg: ldo0 {
- regulator-name = "PCIE CLK";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- ldo1_reg: ldo1 {
- regulator-min-microvolt = < 725000>;
- regulator-max-microvolt = <1500000>;
- };
-
- ldo2_reg: ldo2 {
- regulator-min-microvolt = < 725000>;
- regulator-max-microvolt = <1500000>;
- };
-
- ldo3_reg: ldo3 {
- regulator-min-microvolt = <1250000>;
- regulator-max-microvolt = <3300000>;
- };
-
- ldo4_reg: ldo4 {
- regulator-min-microvolt = <1700000>;
- regulator-max-microvolt = <2475000>;
- };
-
- ldo5_reg: ldo5 {
- regulator-min-microvolt = <1250000>;
- regulator-max-microvolt = <3300000>;
- };
-
- ldo6_reg: ldo6 {
- regulator-min-microvolt = <1250000>;
- regulator-max-microvolt = <3300000>;
- };
-
- ldo7_reg: ldo7 {
- regulator-min-microvolt = <1250000>;
- regulator-max-microvolt = <3300000>;
- };
-
- ldo8_reg: ldo8 {
- regulator-min-microvolt = <1250000>;
- regulator-max-microvolt = <3300000>;
- };
-
- ldo9_reg: ldo9 {
- regulator-min-microvolt = <1250000>;
- regulator-max-microvolt = <3300000>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml
index e7c4a3984c60..79b755858bad 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml
@@ -105,6 +105,9 @@ properties:
pmic:
type: object
+ regulators:
+ $ref: /schemas/regulator/mediatek,mt6380-regulator.yaml#
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 838def27c9cf..473019dd0126 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1202,6 +1202,8 @@ patternProperties:
description: New Vision Display (Shenzhen) Co., Ltd.
"^nexbox,.*":
description: Nexbox
+ "^nexperia,.*":
+ description: Nexperia B.V.
"^nextthing,.*":
description: Next Thing Co.
"^ni,.*":
diff --git a/MAINTAINERS b/MAINTAINERS
index 83f444c96007..16b032b344d5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18569,6 +18569,12 @@ F: scripts/module*
F: tools/testing/selftests/kmod/
F: tools/testing/selftests/module/
+MONOLITHIC POWER SYSTEM MPQ4210 REGULATOR DRIVER
+M: Tapio Reijonen <tapio.reijonen@vaisala.com>
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/mps,mpq4210.yaml
+F: drivers/regulator/mpq4210.c
+
MONOLITHIC POWER SYSTEM PMIC DRIVER
M: Saravanan Sekar <sravanhome@gmail.com>
S: Maintained
diff --git a/drivers/regulator/88pm886-regulator.c b/drivers/regulator/88pm886-regulator.c
index 7328cd1cf265..1961a7968982 100644
--- a/drivers/regulator/88pm886-regulator.c
+++ b/drivers/regulator/88pm886-regulator.c
@@ -337,6 +337,25 @@ static struct regulator_desc pm886_regulators[] = {
},
};
+static const struct linear_range pm886_vbus_volt_ranges[] = {
+ REGULATOR_LINEAR_RANGE(3750000, 0, 7, 250000)
+};
+
+static struct regulator_desc pm886_vbus_regulator = {
+ .name = "vbus",
+ .regulators_node = "regulators",
+ .of_match = "vbus",
+ .ops = &pm886_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 8,
+ .linear_ranges = pm886_vbus_volt_ranges,
+ .n_linear_ranges = ARRAY_SIZE(pm886_vbus_volt_ranges),
+ .vsel_reg = PM886_REG_BOOST_CONFIG1,
+ .vsel_mask = PM886_REG_BOOST_MASK,
+ .enable_reg = PM886_REG_BATTERY_CONFIG1,
+ .enable_mask = PM886_REG_VBUS_EN,
+};
+
static int pm886_regulator_probe(struct platform_device *pdev)
{
struct pm886_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -369,6 +388,13 @@ static int pm886_regulator_probe(struct platform_device *pdev)
"Failed to register %s\n", rdesc->name);
}
+ rcfg.regmap = chip->regmap_battery;
+ rdesc = &pm886_vbus_regulator;
+ rdev = devm_regulator_register(dev, rdesc, &rcfg);
+ if (IS_ERR(rdev))
+ return dev_err_probe(dev, PTR_ERR(rdev),
+ "Failed to register %s\n", rdesc->name);
+
return 0;
}
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 13928af8cad4..be6b72daa76f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -864,12 +864,23 @@ config REGULATOR_MP8859
module. The module will be named "mp8859".
config REGULATOR_MP886X
- tristate "MPS MP8869 regulator driver"
+ tristate "MPS MP8864/MP8867/MP8869 regulator driver"
depends on I2C && OF
select REGMAP_I2C
help
This driver supports the MP8869 voltage regulator.
+config REGULATOR_MPQ4210
+ tristate "MPS MPQ4210 regulator driver"
+ depends on I2C && OF
+ select REGMAP_I2C
+ help
+ This driver supports the MPQ4210 synchronous buck-boost controller.
+ It supports get/set voltage, enable/disable and ramp rate selection
+ through the regulator interface.
+ Say M here if you want to include support for the regulator as a
+ module. The module will be named "mpq4210".
+
config REGULATOR_MPQ7920
tristate "Monolithic MPQ7920 PMIC"
depends on I2C && OF
@@ -1020,6 +1031,14 @@ config REGULATOR_MTK_DVFSRC
of Mediatek. It allows for voting on regulator state
between multiple users.
+config REGULATOR_NEX10000UB
+ tristate "Nexperia NEX10000UB Dual Output Power regulators"
+ depends on I2C && GPIOLIB
+ select REGMAP_I2C
+ help
+ This driver supports the NEX10000UB single inductor - dual output
+ power supply specifically designed for display panels.
+
config REGULATOR_PALMAS
tristate "TI Palmas PMIC Regulators"
depends on MFD_PALMAS
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 5a764cec8df8..6aabcc54382a 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
obj-$(CONFIG_REGULATOR_MP5416) += mp5416.o
obj-$(CONFIG_REGULATOR_MP8859) += mp8859.o
obj-$(CONFIG_REGULATOR_MP886X) += mp886x.o
+obj-$(CONFIG_REGULATOR_MPQ4210) += mpq4210.o
obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
obj-$(CONFIG_REGULATOR_MT6315) += mt6315-regulator.o
@@ -120,6 +121,7 @@ obj-$(CONFIG_REGULATOR_MT6370) += mt6370-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o
+obj-$(CONFIG_REGULATOR_NEX10000UB) += nex10000ub-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_PM8008) += qcom-pm8008-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_REFGEN) += qcom-refgen-regulator.o
diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c
index b9955aa4e0d1..c0657362a102 100644
--- a/drivers/regulator/ab8500-ext.c
+++ b/drivers/regulator/ab8500-ext.c
@@ -88,7 +88,7 @@ static struct regulator_init_data ab8500_ext_regulators[] = {
* @update_reg: register to control on/off
* @update_mask: mask to enable/disable and set mode of regulator
* @update_val: bits holding the regulator current mode
- * @update_val_hp: bits to set EN pin active (LPn pin deactive)
+ * @update_val_hp: bits to set EN pin active (LPn pin deactivate)
* normally this means high power mode
* @update_val_lp: bits to set EN pin active and LPn pin active
* normally this means low power mode
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index 3705c98b0713..3c1962ad85d4 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -9,15 +9,18 @@
* AB8500 peripheral regulators
*
* AB8500 supports the following regulators:
- * VAUX1/2/3, VINTCORE, VTVOUT, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA
+ * VSMPS1/2/3, VARM, VAPE, VMOD, VAUX1/2/3, VINTCORE, VTVOUT,
+ * VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA
*
* AB8505 supports the following regulators:
- * VAUX1/2/3/4/5/6, VINTCORE, VADC, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA
+ * VSMPSA/B/C/M, VSAFE, VARM, VAUX1/2/3/4/5/6, VINTCORE,
+ * VADC, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500.h>
@@ -39,6 +42,12 @@ enum ab8500_regulator_id {
AB8500_LDO_ANAMIC2,
AB8500_LDO_DMIC,
AB8500_LDO_ANA,
+ AB8500_BUCK_SMPS1,
+ AB8500_BUCK_SMPS2,
+ AB8500_BUCK_SMPS3,
+ AB8500_BUCK_ARM,
+ AB8500_BUCK_APE,
+ AB8500_BUCK_MOD,
AB8500_NUM_REGULATORS,
};
@@ -57,6 +66,12 @@ enum ab8505_regulator_id {
AB8505_LDO_ANAMIC2,
AB8505_LDO_AUX8,
AB8505_LDO_ANA,
+ AB8505_BUCK_SMPSA,
+ AB8505_BUCK_SMPSB,
+ AB8505_BUCK_SAFE,
+ AB8505_BUCK_ARM,
+ AB8505_BUCK_SMPSC,
+ AB8505_BUCK_SMPSM,
AB8505_NUM_REGULATORS,
};
@@ -162,6 +177,7 @@ struct ab8500_shared_mode {
* @update_bank: bank to control on/off
* @update_reg: register to control on/off
* @update_mask: mask to enable/disable and set mode of regulator
+ * @enable_mask: optional mask for an enable bit separate from the mode bit
* @update_val: bits holding the regulator current mode
* @update_val_idle: bits to enable the regulator in idle (low power) mode
* @update_val_normal: bits to enable the regulator in normal (high power) mode
@@ -171,8 +187,17 @@ struct ab8500_shared_mode {
* @mode_val_idle: mode setting for low power
* @mode_val_normal: mode setting for normal power
* @voltage_bank: bank to control regulator voltage
- * @voltage_reg: register to control regulator voltage
+ * @voltage_reg: first register containing a selectable regulator voltage
* @voltage_mask: mask to control regulator voltage
+ * @expand_register: additional register used to select an extra voltage
+ * @voltage_ctrl_bank: bank containing the voltage selector control
+ * @voltage_ctrl_reg: register containing the voltage selector control
+ * @voltage_ctrl_mask: mask selecting one of the first voltage registers
+ * @voltage_ext_ctrl_bank: bank containing the extended selector control
+ * @voltage_ext_ctrl_reg: register containing the extended selector control
+ * @voltage_ext_ctrl_mask: mask selecting one of the extended voltage registers
+ * @voltage_ext_reg: first extended voltage register
+ * @voltage_ext_regs: number of extended voltage registers
*/
struct ab8500_regulator_info {
struct device *dev;
@@ -182,6 +207,7 @@ struct ab8500_regulator_info {
u8 update_bank;
u8 update_reg;
u8 update_mask;
+ u8 enable_mask;
u8 update_val;
u8 update_val_idle;
u8 update_val_normal;
@@ -193,6 +219,20 @@ struct ab8500_regulator_info {
u8 voltage_bank;
u8 voltage_reg;
u8 voltage_mask;
+ struct {
+ u8 voltage_limit;
+ u8 voltage_bank;
+ u8 voltage_reg;
+ u8 voltage_mask;
+ } expand_register;
+ u8 voltage_ctrl_bank;
+ u8 voltage_ctrl_reg;
+ u8 voltage_ctrl_mask;
+ u8 voltage_ext_ctrl_bank;
+ u8 voltage_ext_ctrl_reg;
+ u8 voltage_ext_ctrl_mask;
+ u8 voltage_ext_reg;
+ u8 voltage_ext_regs;
};
/* voltage tables for the vauxn/vintcore supplies */
@@ -226,6 +266,18 @@ static const unsigned int ldo_vaux3_voltages[] = {
2910000,
};
+static const unsigned int ldo_vaux3_ab8505_voltages[] = {
+ 1200000,
+ 1500000,
+ 1800000,
+ 2100000,
+ 2500000,
+ 2750000,
+ 2790000,
+ 2910000,
+ 3050000,
+};
+
static const unsigned int ldo_vaux56_voltages[] = {
1800000,
1050000,
@@ -237,14 +289,13 @@ static const unsigned int ldo_vaux56_voltages[] = {
2790000,
};
-static const unsigned int ldo_vintcore_voltages[] = {
- 1200000,
- 1225000,
- 1250000,
- 1275000,
- 1300000,
- 1325000,
- 1350000,
+static const struct linear_range ldo_vintcore_ranges[] = {
+ REGULATOR_LINEAR_RANGE(1200000, 0, 6, 25000),
+};
+
+static const struct linear_range ldo_vintcore_ab8505_ranges[] = {
+ REGULATOR_LINEAR_RANGE(1200000, 0, 6, 25000),
+ REGULATOR_LINEAR_RANGE(1350000, 7, 7, 0),
};
static const unsigned int fixed_1200000_voltage[] = {
@@ -264,25 +315,54 @@ static const unsigned int fixed_2050000_voltage[] = {
};
static const unsigned int ldo_vana_voltages[] = {
+ 1200000,
1050000,
1075000,
1100000,
1125000,
1150000,
1175000,
- 1200000,
1225000,
};
-static const unsigned int ldo_vaudio_voltages[] = {
- 2000000,
- 2100000,
- 2200000,
- 2300000,
- 2400000,
- 2500000,
- 2600000,
- 2600000, /* Duplicated in Vaudio and IsoUicc Control register. */
+static const struct linear_range ldo_vaudio_ranges[] = {
+ REGULATOR_LINEAR_RANGE(2000000, 0, 6, 100000),
+ /* Duplicated in Vaudio and IsoUicc Control register. */
+ REGULATOR_LINEAR_RANGE(2600000, 7, 7, 0),
+};
+
+/*
+ * AB8505 buck ranges except VARM are selected by OTP. The supported
+ * platforms use the AB8500-compatible profiles for VSMPSA/B and the low
+ * profiles for VSAFE, VSMPSC and VSMPSM.
+ */
+static const struct linear_range buck_low_voltages[] = {
+ REGULATOR_LINEAR_RANGE(700000, 0, 53, 12500),
+ REGULATOR_LINEAR_RANGE(1362500, 54, 63, 0),
+};
+
+/* VSMPS3 and VSAFE have a 7-bit selector, but the same low range. */
+static const struct linear_range buck_low_7bit_voltages[] = {
+ REGULATOR_LINEAR_RANGE(700000, 0, 53, 12500),
+ REGULATOR_LINEAR_RANGE(1362500, 54, 127, 0),
+};
+
+/* AB8505 VARM uses a separate 0.6 V to 1.39375 V selector range. */
+static const struct linear_range ab8505_buck_arm_voltages[] = {
+ REGULATOR_LINEAR_RANGE(600000, 0, 127, 6250),
+};
+
+/* VSMPS1 and the VSMPSA AB8500-compatible profile clamp to this range. */
+static const struct linear_range buck_smps1_voltages[] = {
+ REGULATOR_LINEAR_RANGE(1100000, 0, 32, 0),
+ REGULATOR_LINEAR_RANGE(1112500, 33, 48, 12500),
+ REGULATOR_LINEAR_RANGE(1300000, 49, 63, 0),
+};
+
+/* VSMPS2 and the VSMPSB AB8500-compatible profile clamp to this range. */
+static const struct linear_range buck_smps2_voltages[] = {
+ REGULATOR_LINEAR_RANGE(1800000, 0, 57, 0),
+ REGULATOR_LINEAR_RANGE(1812500, 58, 63, 12500),
};
static DEFINE_MUTEX(shared_mode_mutex);
@@ -343,7 +423,7 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev)
return ret;
}
-static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
+static int ab8500_regulator_get_enable_value(struct regulator_dev *rdev)
{
int ret;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
@@ -368,10 +448,65 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
info->desc.name, info->update_bank, info->update_reg,
info->update_mask, regval);
- if (regval & info->update_mask)
- return 1;
+ return regval & info->update_mask;
+}
+
+static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
+{
+ struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+ u8 enable_mask;
+ int ret;
+
+ ret = ab8500_regulator_get_enable_value(rdev);
+ if (ret < 0)
+ return ret;
+
+ enable_mask = info->enable_mask ? info->enable_mask : info->update_mask;
+
+ return !!(ret & enable_mask);
+}
+
+static int ab8500_buck_enable(struct regulator_dev *rdev)
+{
+ int ret;
+
+ /* Keep an OTP-selected hardware or low-power mode intact. */
+ ret = ab8500_regulator_is_enabled(rdev);
+ if (ret)
+ return ret < 0 ? ret : 0;
+
+ return ab8500_regulator_enable(rdev);
+}
+
+static int ab8500_buck_init(struct regulator_dev *rdev,
+ struct regulator_config *config)
+{
+ struct ab8500_regulator_info *info = config->driver_data;
+ int ret;
+
+ ret = ab8500_regulator_get_enable_value(rdev);
+ if (ret <= 0)
+ return ret;
+
+ /* Report forced LP accurately; HP and hardware control are normal mode. */
+ if (ret == info->update_val_idle)
+ info->update_val = info->update_val_idle;
else
- return 0;
+ info->update_val = info->update_val_normal;
+
+ /*
+ * The SMPS enable state is selected by OTP. An enabled rail may
+ * supply discrete board components which are not represented as
+ * regulator consumers, so keep it out of the unused-regulator sweep.
+ */
+ rdev->constraints->boot_on = true;
+ rdev->constraints->always_on = true;
+ rdev->constraints->valid_ops_mask &= ~REGULATOR_CHANGE_STATUS;
+
+ dev_dbg(config->dev, "%s: preserving OTP-enabled state\n",
+ info->desc.name);
+
+ return 0;
}
static unsigned int ab8500_regulator_get_optimum_mode(
@@ -398,7 +533,7 @@ static unsigned int ab8500_regulator_get_optimum_mode(
static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
- int ret = 0;
+ int enabled, ret = 0;
u8 bank, reg, mask, val;
bool lp_mode_req = false;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
@@ -408,6 +543,8 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
return -EINVAL;
}
+ guard(mutex)(&shared_mode_mutex);
+
if (info->mode_mask) {
bank = info->mode_bank;
reg = info->mode_reg;
@@ -418,9 +555,6 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
mask = info->update_mask;
}
- if (info->shared_mode)
- mutex_lock(&shared_mode_mutex);
-
switch (mode) {
case REGULATOR_MODE_NORMAL:
if (info->shared_mode)
@@ -439,7 +573,7 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
if (!shared_regulator->shared_mode->lp_mode_req) {
/* Other regulator prevent LP mode */
info->shared_mode->lp_mode_req = true;
- goto out_unlock;
+ return 0;
}
lp_mode_req = true;
@@ -451,17 +585,24 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
val = info->update_val_idle;
break;
default:
- ret = -EINVAL;
- goto out_unlock;
+ return -EINVAL;
+ }
+
+ if (info->mode_mask) {
+ enabled = 1;
+ } else {
+ enabled = ab8500_regulator_is_enabled(rdev);
+ if (enabled < 0)
+ return enabled;
}
- if (info->mode_mask || ab8500_regulator_is_enabled(rdev)) {
+ if (enabled) {
ret = abx500_mask_and_set_register_interruptible(info->dev,
bank, reg, mask, val);
if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"couldn't set regulator mode\n");
- goto out_unlock;
+ return ret;
}
dev_vdbg(rdev_get_dev(rdev),
@@ -477,10 +618,6 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
if (info->shared_mode)
info->shared_mode->lp_mode_req = lp_mode_req;
-out_unlock:
- if (info->shared_mode)
- mutex_unlock(&shared_mode_mutex);
-
return ret;
}
@@ -530,11 +667,67 @@ static unsigned int ab8500_regulator_get_mode(struct regulator_dev *rdev)
return ret;
}
+static int ab8500_regulator_get_voltage_reg(struct regulator_dev *rdev,
+ u8 *voltage_reg)
+{
+ struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+ u8 regval;
+ unsigned int selector;
+ int ret;
+
+ if (info->voltage_ext_ctrl_mask) {
+ ret = abx500_get_register_interruptible(info->dev,
+ info->voltage_ext_ctrl_bank,
+ info->voltage_ext_ctrl_reg, &regval);
+ if (ret < 0)
+ return ret;
+
+ selector = (regval & info->voltage_ext_ctrl_mask) >>
+ (ffs(info->voltage_ext_ctrl_mask) - 1);
+ if (selector) {
+ selector = min_t(unsigned int, selector,
+ info->voltage_ext_regs);
+ *voltage_reg = info->voltage_ext_reg + selector - 1;
+ return 0;
+ }
+ }
+
+ if (!info->voltage_ctrl_mask) {
+ *voltage_reg = info->voltage_reg;
+ return 0;
+ }
+
+ ret = abx500_get_register_interruptible(info->dev,
+ info->voltage_ctrl_bank,
+ info->voltage_ctrl_reg, &regval);
+ if (ret < 0)
+ return ret;
+
+ /* The three hardware selector layouts all use consecutive registers. */
+ switch (info->voltage_ctrl_mask) {
+ case 0x0c:
+ selector = min((unsigned int)((regval & 0x0c) >> 2), 2U);
+ break;
+ case 0x24:
+ selector = regval & BIT(5) ? 2 : !!(regval & BIT(2));
+ break;
+ case 0x04:
+ selector = !!(regval & BIT(2));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *voltage_reg = info->voltage_reg + selector;
+
+ return 0;
+}
+
static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
{
int ret, voltage_shift;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
- u8 regval;
+ u8 regval, voltage_reg;
if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
@@ -543,8 +736,15 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
voltage_shift = ffs(info->voltage_mask) - 1;
+ ret = ab8500_regulator_get_voltage_reg(rdev, &voltage_reg);
+ if (ret < 0) {
+ dev_err(rdev_get_dev(rdev),
+ "couldn't read voltage selector control\n");
+ return ret;
+ }
+
ret = abx500_get_register_interruptible(info->dev,
- info->voltage_bank, info->voltage_reg, &regval);
+ info->voltage_bank, voltage_reg, &regval);
if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"couldn't read voltage reg for regulator\n");
@@ -555,7 +755,7 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
"%s-get_voltage (bank, reg, mask, shift, value): "
"0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
info->desc.name, info->voltage_bank,
- info->voltage_reg, info->voltage_mask,
+ voltage_reg, info->voltage_mask,
voltage_shift, regval);
return (regval & info->voltage_mask) >> voltage_shift;
@@ -566,7 +766,7 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
{
int ret, voltage_shift;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
- u8 regval;
+ u8 regval, voltage_reg;
if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
@@ -575,10 +775,17 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
voltage_shift = ffs(info->voltage_mask) - 1;
+ ret = ab8500_regulator_get_voltage_reg(rdev, &voltage_reg);
+ if (ret < 0) {
+ dev_err(rdev_get_dev(rdev),
+ "couldn't read voltage selector control\n");
+ return ret;
+ }
+
/* set the registers for the request */
regval = (u8)selector << voltage_shift;
ret = abx500_mask_and_set_register_interruptible(info->dev,
- info->voltage_bank, info->voltage_reg,
+ info->voltage_bank, voltage_reg,
info->voltage_mask, regval);
if (ret < 0)
dev_err(rdev_get_dev(rdev),
@@ -587,12 +794,70 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
dev_vdbg(rdev_get_dev(rdev),
"%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
" 0x%x\n",
- info->desc.name, info->voltage_bank, info->voltage_reg,
+ info->desc.name, info->voltage_bank, voltage_reg,
info->voltage_mask, regval);
return ret;
}
+static int ab8500_regulator_get_voltage_sel_expand(struct regulator_dev *rdev)
+{
+ struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+ u8 regval;
+ int ret;
+
+ if (!info)
+ return -EINVAL;
+
+ ret = abx500_get_register_interruptible(info->dev,
+ info->expand_register.voltage_bank,
+ info->expand_register.voltage_reg, &regval);
+ if (ret < 0) {
+ dev_err(rdev_get_dev(rdev),
+ "couldn't read voltage expand reg for regulator\n");
+ return ret;
+ }
+
+ if (regval & info->expand_register.voltage_mask)
+ return info->expand_register.voltage_limit;
+
+ return ab8500_regulator_get_voltage_sel(rdev);
+}
+
+static int ab8500_regulator_set_voltage_sel_expand(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+ u8 regval;
+ int ret;
+
+ if (!info)
+ return -EINVAL;
+
+ if (selector > info->expand_register.voltage_limit)
+ return -EINVAL;
+
+ if (selector < info->expand_register.voltage_limit) {
+ ret = ab8500_regulator_set_voltage_sel(rdev, selector);
+ if (ret < 0)
+ return ret;
+
+ regval = 0;
+ } else {
+ regval = info->expand_register.voltage_mask;
+ }
+
+ ret = abx500_mask_and_set_register_interruptible(info->dev,
+ info->expand_register.voltage_bank,
+ info->expand_register.voltage_reg,
+ info->expand_register.voltage_mask, regval);
+ if (ret < 0)
+ dev_err(rdev_get_dev(rdev),
+ "couldn't set voltage expand reg for regulator\n");
+
+ return ret;
+}
+
static const struct regulator_ops ab8500_regulator_volt_mode_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
@@ -605,13 +870,59 @@ static const struct regulator_ops ab8500_regulator_volt_mode_ops = {
.list_voltage = regulator_list_voltage_table,
};
-static const struct regulator_ops ab8500_regulator_volt_ops = {
+static const struct regulator_ops ab8500_regulator_volt_mode_expand_ops = {
+ .enable = ab8500_regulator_enable,
+ .disable = ab8500_regulator_disable,
+ .is_enabled = ab8500_regulator_is_enabled,
+ .get_optimum_mode = ab8500_regulator_get_optimum_mode,
+ .set_mode = ab8500_regulator_set_mode,
+ .get_mode = ab8500_regulator_get_mode,
+ .get_voltage_sel = ab8500_regulator_get_voltage_sel_expand,
+ .set_voltage_sel = ab8500_regulator_set_voltage_sel_expand,
+ .list_voltage = regulator_list_voltage_table,
+};
+
+static const struct regulator_ops ab8500_regulator_linear_range_volt_mode_ops = {
+ .enable = ab8500_regulator_enable,
+ .disable = ab8500_regulator_disable,
+ .is_enabled = ab8500_regulator_is_enabled,
+ .get_optimum_mode = ab8500_regulator_get_optimum_mode,
+ .set_mode = ab8500_regulator_set_mode,
+ .get_mode = ab8500_regulator_get_mode,
+ .get_voltage_sel = ab8500_regulator_get_voltage_sel,
+ .set_voltage_sel = ab8500_regulator_set_voltage_sel,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_ops ab8500_regulator_linear_range_volt_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
.is_enabled = ab8500_regulator_is_enabled,
.get_voltage_sel = ab8500_regulator_get_voltage_sel,
.set_voltage_sel = ab8500_regulator_set_voltage_sel,
- .list_voltage = regulator_list_voltage_table,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_ops ab8500_buck_ops = {
+ .enable = ab8500_buck_enable,
+ .disable = ab8500_regulator_disable,
+ .is_enabled = ab8500_regulator_is_enabled,
+ .get_optimum_mode = ab8500_regulator_get_optimum_mode,
+ .set_mode = ab8500_regulator_set_mode,
+ .get_mode = ab8500_regulator_get_mode,
+ .get_voltage_sel = ab8500_regulator_get_voltage_sel,
+ .set_voltage_sel = ab8500_regulator_set_voltage_sel,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_ops ab8500_buck_voltage_ops = {
+ .get_voltage_sel = ab8500_regulator_get_voltage_sel,
+ .set_voltage_sel = ab8500_regulator_set_voltage_sel,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
};
static const struct regulator_ops ab8500_regulator_mode_ops = {
@@ -721,18 +1032,20 @@ static struct ab8500_regulator_info
[AB8500_LDO_INTCORE] = {
.desc = {
.name = "LDO-INTCORE",
- .ops = &ab8500_regulator_volt_mode_ops,
+ .ops = &ab8500_regulator_linear_range_volt_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_INTCORE,
.owner = THIS_MODULE,
- .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
- .volt_table = ldo_vintcore_voltages,
+ .n_voltages = 7,
+ .linear_ranges = ldo_vintcore_ranges,
+ .n_linear_ranges = ARRAY_SIZE(ldo_vintcore_ranges),
.enable_time = 750,
},
.load_lp_uA = 5000,
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x44,
+ .enable_mask = 0x04,
.update_val = 0x44,
.update_val_idle = 0x44,
.update_val_normal = 0x04,
@@ -761,6 +1074,7 @@ static struct ab8500_regulator_info
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x82,
+ .enable_mask = 0x02,
.update_val = 0x02,
.update_val_idle = 0x82,
.update_val_normal = 0x02,
@@ -852,6 +1166,140 @@ static struct ab8500_regulator_info
.update_val_idle = 0x0c,
.update_val_normal = 0x04,
},
+
+ /* Buck converters */
+ [AB8500_BUCK_SMPS1] = {
+ .desc = {
+ .name = "BUCK-SMPS1",
+ .ops = &ab8500_buck_ops,
+ .init_cb = ab8500_buck_init,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8500_BUCK_SMPS1,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .linear_ranges = buck_smps1_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_smps1_voltages),
+ },
+ .load_lp_uA = 20000,
+ .update_bank = 0x04,
+ .update_reg = 0x03,
+ .update_mask = 0x03,
+ .update_val = 0x01,
+ .update_val_idle = 0x03,
+ .update_val_normal = 0x01,
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x13,
+ .voltage_mask = 0x3f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x03,
+ .voltage_ctrl_mask = 0x0c,
+ },
+ [AB8500_BUCK_SMPS2] = {
+ .desc = {
+ .name = "BUCK-SMPS2",
+ .ops = &ab8500_buck_ops,
+ .init_cb = ab8500_buck_init,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8500_BUCK_SMPS2,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .linear_ranges = buck_smps2_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_smps2_voltages),
+ },
+ .load_lp_uA = 20000,
+ .update_bank = 0x04,
+ .update_reg = 0x04,
+ .update_mask = 0x03,
+ .update_val = 0x01,
+ .update_val_idle = 0x03,
+ .update_val_normal = 0x01,
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x17,
+ .voltage_mask = 0x3f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x04,
+ .voltage_ctrl_mask = 0x0c,
+ },
+ [AB8500_BUCK_SMPS3] = {
+ .desc = {
+ .name = "BUCK-SMPS3",
+ .ops = &ab8500_buck_ops,
+ .init_cb = ab8500_buck_init,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8500_BUCK_SMPS3,
+ .owner = THIS_MODULE,
+ .n_voltages = 128,
+ .linear_ranges = buck_low_7bit_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_low_7bit_voltages),
+ },
+ .load_lp_uA = 50000,
+ .update_bank = 0x04,
+ .update_reg = 0x05,
+ .update_mask = 0x03,
+ .update_val = 0x01,
+ .update_val_idle = 0x03,
+ .update_val_normal = 0x01,
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x1b,
+ .voltage_mask = 0x7f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x05,
+ .voltage_ctrl_mask = 0x0c,
+ },
+ [AB8500_BUCK_ARM] = {
+ .desc = {
+ .name = "BUCK-ARM",
+ .ops = &ab8500_buck_voltage_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8500_BUCK_ARM,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .linear_ranges = buck_low_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_low_voltages),
+ },
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x0b,
+ .voltage_mask = 0x3f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x00,
+ .voltage_ctrl_mask = 0x0c,
+ },
+ [AB8500_BUCK_APE] = {
+ .desc = {
+ .name = "BUCK-APE",
+ .ops = &ab8500_buck_voltage_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8500_BUCK_APE,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .linear_ranges = buck_low_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_low_voltages),
+ },
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x0e,
+ .voltage_mask = 0x3f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x02,
+ .voltage_ctrl_mask = 0x24,
+ },
+ [AB8500_BUCK_MOD] = {
+ .desc = {
+ .name = "BUCK-MOD",
+ .ops = &ab8500_buck_voltage_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8500_BUCK_MOD,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .linear_ranges = buck_low_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_low_voltages),
+ },
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x41,
+ .voltage_mask = 0x3f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x40,
+ .voltage_ctrl_mask = 0x04,
+ },
};
/* AB8505 regulator information */
@@ -908,12 +1356,12 @@ static struct ab8500_regulator_info
[AB8505_LDO_AUX3] = {
.desc = {
.name = "LDO-AUX3",
- .ops = &ab8500_regulator_volt_mode_ops,
+ .ops = &ab8500_regulator_volt_mode_expand_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8505_LDO_AUX3,
.owner = THIS_MODULE,
- .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
- .volt_table = ldo_vaux3_voltages,
+ .n_voltages = ARRAY_SIZE(ldo_vaux3_ab8505_voltages),
+ .volt_table = ldo_vaux3_ab8505_voltages,
},
.load_lp_uA = 5000,
.update_bank = 0x04,
@@ -925,6 +1373,12 @@ static struct ab8500_regulator_info
.voltage_bank = 0x04,
.voltage_reg = 0x21,
.voltage_mask = 0x07,
+ .expand_register = {
+ .voltage_limit = 8,
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x01,
+ .voltage_mask = 0x10,
+ },
},
[AB8505_LDO_AUX4] = {
.desc = {
@@ -964,6 +1418,7 @@ static struct ab8500_regulator_info
.update_bank = 0x01,
.update_reg = 0x55,
.update_mask = 0x18,
+ .enable_mask = 0x10,
.update_val = 0x10,
.update_val_idle = 0x18,
.update_val_normal = 0x10,
@@ -986,6 +1441,7 @@ static struct ab8500_regulator_info
.update_bank = 0x01,
.update_reg = 0x56,
.update_mask = 0x18,
+ .enable_mask = 0x10,
.update_val = 0x10,
.update_val_idle = 0x18,
.update_val_normal = 0x10,
@@ -996,17 +1452,19 @@ static struct ab8500_regulator_info
[AB8505_LDO_INTCORE] = {
.desc = {
.name = "LDO-INTCORE",
- .ops = &ab8500_regulator_volt_mode_ops,
+ .ops = &ab8500_regulator_linear_range_volt_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8505_LDO_INTCORE,
.owner = THIS_MODULE,
- .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
- .volt_table = ldo_vintcore_voltages,
+ .n_voltages = 8,
+ .linear_ranges = ldo_vintcore_ab8505_ranges,
+ .n_linear_ranges = ARRAY_SIZE(ldo_vintcore_ab8505_ranges),
},
.load_lp_uA = 5000,
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x44,
+ .enable_mask = 0x04,
.update_val = 0x04,
.update_val_idle = 0x44,
.update_val_normal = 0x04,
@@ -1035,6 +1493,7 @@ static struct ab8500_regulator_info
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x82,
+ .enable_mask = 0x02,
.update_val = 0x02,
.update_val_idle = 0x82,
.update_val_normal = 0x02,
@@ -1042,12 +1501,13 @@ static struct ab8500_regulator_info
[AB8505_LDO_AUDIO] = {
.desc = {
.name = "LDO-AUDIO",
- .ops = &ab8500_regulator_volt_ops,
+ .ops = &ab8500_regulator_linear_range_volt_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8505_LDO_AUDIO,
.owner = THIS_MODULE,
- .n_voltages = ARRAY_SIZE(ldo_vaudio_voltages),
- .volt_table = ldo_vaudio_voltages,
+ .n_voltages = 8,
+ .linear_ranges = ldo_vaudio_ranges,
+ .n_linear_ranges = ARRAY_SIZE(ldo_vaudio_ranges),
},
.update_bank = 0x03,
.update_reg = 0x83,
@@ -1138,6 +1598,155 @@ static struct ab8500_regulator_info
.voltage_reg = 0x29,
.voltage_mask = 0x7,
},
+
+ /* Buck converters */
+ [AB8505_BUCK_SMPSA] = {
+ .desc = {
+ .name = "BUCK-SMPSA",
+ .ops = &ab8500_buck_ops,
+ .init_cb = ab8500_buck_init,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8505_BUCK_SMPSA,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .linear_ranges = buck_smps1_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_smps1_voltages),
+ },
+ .load_lp_uA = 20000,
+ .update_bank = 0x04,
+ .update_reg = 0x03,
+ .update_mask = 0x03,
+ .update_val = 0x01,
+ .update_val_idle = 0x03,
+ .update_val_normal = 0x01,
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x13,
+ .voltage_mask = 0x3f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x03,
+ .voltage_ctrl_mask = 0x0c,
+ },
+ [AB8505_BUCK_SMPSB] = {
+ .desc = {
+ .name = "BUCK-SMPSB",
+ .ops = &ab8500_buck_ops,
+ .init_cb = ab8500_buck_init,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8505_BUCK_SMPSB,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .linear_ranges = buck_smps2_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_smps2_voltages),
+ },
+ .load_lp_uA = 20000,
+ .update_bank = 0x04,
+ .update_reg = 0x04,
+ .update_mask = 0x03,
+ .update_val = 0x01,
+ .update_val_idle = 0x03,
+ .update_val_normal = 0x01,
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x17,
+ .voltage_mask = 0x3f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x04,
+ .voltage_ctrl_mask = 0x0c,
+ },
+ [AB8505_BUCK_SAFE] = {
+ .desc = {
+ .name = "BUCK-SAFE",
+ .ops = &ab8500_buck_ops,
+ .init_cb = ab8500_buck_init,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8505_BUCK_SAFE,
+ .owner = THIS_MODULE,
+ .n_voltages = 128,
+ .linear_ranges = buck_low_7bit_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_low_7bit_voltages),
+ },
+ .load_lp_uA = 50000,
+ .update_bank = 0x04,
+ .update_reg = 0x05,
+ .update_mask = 0x03,
+ .update_val = 0x01,
+ .update_val_idle = 0x03,
+ .update_val_normal = 0x01,
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x1b,
+ .voltage_mask = 0x7f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x05,
+ .voltage_ctrl_mask = 0x0c,
+ },
+ [AB8505_BUCK_ARM] = {
+ .desc = {
+ .name = "BUCK-ARM",
+ .ops = &ab8500_buck_voltage_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8505_BUCK_ARM,
+ .owner = THIS_MODULE,
+ .n_voltages = 128,
+ .linear_ranges = ab8505_buck_arm_voltages,
+ .n_linear_ranges = ARRAY_SIZE(ab8505_buck_arm_voltages),
+ },
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x0b,
+ .voltage_mask = 0x7f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x00,
+ .voltage_ctrl_mask = 0x0c,
+ .voltage_ext_ctrl_bank = 0x04,
+ .voltage_ext_ctrl_reg = 0x28,
+ .voltage_ext_ctrl_mask = 0x07,
+ .voltage_ext_reg = 0x24,
+ .voltage_ext_regs = 4,
+ },
+ [AB8505_BUCK_SMPSC] = {
+ .desc = {
+ .name = "BUCK-SMPSC",
+ .ops = &ab8500_buck_voltage_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8505_BUCK_SMPSC,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .linear_ranges = buck_low_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_low_voltages),
+ },
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x0e,
+ .voltage_mask = 0x3f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x02,
+ .voltage_ctrl_mask = 0x24,
+ .voltage_ext_ctrl_bank = 0x04,
+ .voltage_ext_ctrl_reg = 0x2a,
+ .voltage_ext_ctrl_mask = 0x03,
+ .voltage_ext_reg = 0x2b,
+ .voltage_ext_regs = 2,
+ },
+ [AB8505_BUCK_SMPSM] = {
+ .desc = {
+ .name = "BUCK-SMPSM",
+ .ops = &ab8500_buck_voltage_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8505_BUCK_SMPSM,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .linear_ranges = buck_low_voltages,
+ .n_linear_ranges = ARRAY_SIZE(buck_low_voltages),
+ },
+ .voltage_bank = 0x04,
+ .voltage_reg = 0x41,
+ .voltage_mask = 0x3f,
+ .voltage_ctrl_bank = 0x04,
+ .voltage_ctrl_reg = 0x40,
+ .voltage_ctrl_mask = 0x04,
+ .voltage_ext_ctrl_bank = 0x04,
+ .voltage_ext_ctrl_reg = 0x47,
+ .voltage_ext_ctrl_mask = 0x03,
+ .voltage_ext_reg = 0x45,
+ .voltage_ext_regs = 2,
+ },
};
static struct ab8500_shared_mode ldo_anamic1_shared = {
@@ -1613,6 +2222,12 @@ static struct of_regulator_match ab8500_regulator_match[] = {
{ .name = "ab8500_ldo_anamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
{ .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
{ .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
+ { .name = "ab8500_buck_smps1", .driver_data = (void *)AB8500_BUCK_SMPS1, },
+ { .name = "ab8500_buck_smps2", .driver_data = (void *)AB8500_BUCK_SMPS2, },
+ { .name = "ab8500_buck_smps3", .driver_data = (void *)AB8500_BUCK_SMPS3, },
+ { .name = "ab8500_buck_arm", .driver_data = (void *)AB8500_BUCK_ARM, },
+ { .name = "ab8500_buck_ape", .driver_data = (void *)AB8500_BUCK_APE, },
+ { .name = "ab8500_buck_mod", .driver_data = (void *)AB8500_BUCK_MOD, },
};
static struct of_regulator_match ab8505_regulator_match[] = {
@@ -1629,6 +2244,12 @@ static struct of_regulator_match ab8505_regulator_match[] = {
{ .name = "ab8500_ldo_anamic2", .driver_data = (void *) AB8505_LDO_ANAMIC2, },
{ .name = "ab8500_ldo_aux8", .driver_data = (void *) AB8505_LDO_AUX8, },
{ .name = "ab8500_ldo_ana", .driver_data = (void *) AB8505_LDO_ANA, },
+ { .name = "ab8505_buck_smpsa", .driver_data = (void *)AB8505_BUCK_SMPSA, },
+ { .name = "ab8505_buck_smpsb", .driver_data = (void *)AB8505_BUCK_SMPSB, },
+ { .name = "ab8505_buck_safe", .driver_data = (void *)AB8505_BUCK_SAFE, },
+ { .name = "ab8505_buck_arm", .driver_data = (void *)AB8505_BUCK_ARM, },
+ { .name = "ab8505_buck_smpsc", .driver_data = (void *)AB8505_BUCK_SMPSC, },
+ { .name = "ab8505_buck_smpsm", .driver_data = (void *)AB8505_BUCK_SMPSM, },
};
static struct {
@@ -1677,9 +2298,14 @@ static int ab8500_regulator_register(struct platform_device *pdev,
config.driver_data = info;
config.of_node = np;
- /* fix for hardware before ab8500v2.0 */
- if (is_ab8500_1p1_or_earlier(ab8500)) {
- if (info->desc.id == AB8500_LDO_AUX3) {
+ /* Handle the different VAUX3 implementations in early AB8500 cuts. */
+ if (info->desc.id == AB8500_LDO_AUX3) {
+ if (is_ab8500_1p0_or_earlier(ab8500)) {
+ info->desc.ops = &ab8500_regulator_mode_ops;
+ info->desc.n_voltages = 1;
+ info->desc.volt_table = fixed_1200000_voltage;
+ info->voltage_mask = 0;
+ } else if (is_ab8500_1p1_or_earlier(ab8500)) {
info->desc.n_voltages =
ARRAY_SIZE(ldo_vauxn_voltages);
info->desc.volt_table = ldo_vauxn_voltages;
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index da891415efc0..ec6ec071ffde 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -1652,7 +1652,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
(regulators == axp803_regulators && i == AXP803_DC1SW) ||
(regulators == axp809_regulators && i == AXP809_DC1SW) ||
(regulators == axp15060_regulators && i == AXP15060_SW)) {
- new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
+ new_desc = devm_kzalloc(&pdev->dev, sizeof(*new_desc),
GFP_KERNEL);
if (!new_desc)
return -ENOMEM;
@@ -1665,7 +1665,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) ||
(regulators == axp809_regulators && i == AXP809_DC5LDO) ||
(regulators == axp15060_regulators && i == AXP15060_CPUSLDO)) {
- new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
+ new_desc = devm_kzalloc(&pdev->dev, sizeof(*new_desc),
GFP_KERNEL);
if (!new_desc)
return -ENOMEM;
@@ -1677,7 +1677,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
if (regulators == axp15060_regulators && i == AXP15060_RTC_LDO) {
- new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
+ new_desc = devm_kzalloc(&pdev->dev, sizeof(*new_desc),
GFP_KERNEL);
if (!new_desc)
return -ENOMEM;
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6a4008f387b5..14422cfe80e2 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -462,6 +462,7 @@ int regulator_check_voltage(struct regulator_dev *rdev,
return 0;
}
+EXPORT_SYMBOL_GPL(regulator_check_voltage);
/* return 0 if the state is valid */
static int regulator_check_states(suspend_state_t state)
@@ -502,6 +503,7 @@ int regulator_check_consumers(struct regulator_dev *rdev,
return 0;
}
+EXPORT_SYMBOL_GPL(regulator_check_consumers);
/* current constraint check */
static int regulator_check_current_limit(struct regulator_dev *rdev,
@@ -2239,6 +2241,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
if (r == rdev) {
dev_err(dev, "Supply for %s (%s) resolved to itself\n",
rdev->desc->name, rdev->supply_name);
+ put_device(&rdev->dev);
if (!have_full_constraints()) {
ret = -EINVAL;
goto out;
@@ -3029,7 +3032,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
*/
trace_regulator_enable_delay(rdev_get_name(rdev));
- /* If poll_enabled_time is set, poll upto the delay calculated
+ /* If poll_enabled_time is set, poll up to the delay calculated
* above, delaying poll_enabled_time uS to check if the regulator
* actually got enabled.
* If the regulator isn't enabled after our delay helper has expired,
@@ -4468,6 +4471,7 @@ int regulator_do_balance_voltage(struct regulator_dev *rdev,
out:
return ret;
}
+EXPORT_SYMBOL_GPL(regulator_do_balance_voltage);
static int regulator_balance_voltage(struct regulator_dev *rdev,
suspend_state_t state)
@@ -5797,6 +5801,7 @@ int regulator_coupler_register(struct regulator_coupler *coupler)
return 0;
}
+EXPORT_SYMBOL_GPL(regulator_coupler_register);
static struct regulator_coupler *
regulator_find_coupler(struct regulator_dev *rdev)
@@ -5861,6 +5866,7 @@ static void regulator_resolve_coupling(struct regulator_dev *rdev)
if (c_rdev->coupling_desc.coupler != coupler) {
rdev_err(rdev, "coupler mismatch with %s\n",
rdev_get_name(c_rdev));
+ put_device(&c_rdev->dev);
return;
}
@@ -5907,6 +5913,8 @@ static void regulator_remove_coupling(struct regulator_dev *rdev)
c_desc->coupled_rdevs[i] = NULL;
c_desc->n_resolved--;
+
+ put_device(&c_rdev->dev);
}
if (coupler && coupler->detach_regulator) {
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 417d282dd4ed..faa82f30eb1f 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -28,6 +28,7 @@
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
#include <linux/clk.h>
+#include <linux/string.h>
struct fixed_voltage_data {
struct regulator_desc desc;
@@ -225,6 +226,9 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
enum gpiod_flags gflags;
int ret;
+ if (!pdev->dev.of_node && strcmp(pdev->name, "reg-fixed-voltage"))
+ return -ENODEV;
+
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
GFP_KERNEL);
if (!drvdata)
diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c
index e0b62bc02a1e..e483e9d7dcf2 100644
--- a/drivers/regulator/mp886x.c
+++ b/drivers/regulator/mp886x.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
//
-// MP8867/MP8869 regulator driver
+// MP8864/MP8867/MP8869 regulator driver
//
// Copyright (C) 2020 Synaptics Incorporated
//
@@ -229,6 +229,23 @@ static const struct regulator_ops mp8867_regulator_ops = {
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
+static const struct mp886x_cfg_info mp8864_ci = {
+ .rops = &mp8867_regulator_ops,
+ .slew_rates = {
+ 64000,
+ 32000,
+ 16000,
+ 8000,
+ 4000,
+ 2000,
+ 1000,
+ 500,
+ },
+ .switch_freq = { 600000, 850000, 1100000, 1600000 },
+ .fs_reg = MP886X_SYSCNTLREG1,
+ .fs_shift = 1,
+};
+
static const struct mp886x_cfg_info mp8867_ci = {
.rops = &mp8867_regulator_ops,
.slew_rates = {
@@ -256,6 +273,7 @@ static int mp886x_regulator_register(struct mp886x_device_info *di,
{
struct regulator_desc *rdesc = &di->desc;
struct regulator_dev *rdev;
+ int sel;
rdesc->name = "mp886x-reg";
rdesc->supply_name = "vin";
@@ -267,7 +285,7 @@ static int mp886x_regulator_register(struct mp886x_device_info *di,
rdesc->min_uV = 600000;
rdesc->uV_step = 10000;
rdesc->vsel_reg = MP886X_VSEL;
- rdesc->vsel_mask = 0x3f;
+ rdesc->vsel_mask = 0x7f;
rdesc->ramp_reg = MP886X_SYSCNTLREG1;
rdesc->ramp_mask = MP886X_SLEW_MASK;
rdesc->ramp_delay_table = di->ci->slew_rates;
@@ -277,7 +295,12 @@ static int mp886x_regulator_register(struct mp886x_device_info *di,
rdev = devm_regulator_register(di->dev, &di->desc, config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
- di->sel = rdesc->ops->get_voltage_sel(rdev);
+
+ sel = rdesc->ops->get_voltage_sel(rdev);
+ if (sel < 0)
+ return sel;
+ di->sel = sel;
+
return 0;
}
@@ -311,6 +334,9 @@ static int mp886x_i2c_probe(struct i2c_client *client)
if (ret)
return ret;
+ if (di->r[1] == 0)
+ return -EINVAL;
+
di->en_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
if (IS_ERR(di->en_gpio))
return PTR_ERR(di->en_gpio);
@@ -341,6 +367,7 @@ static int mp886x_i2c_probe(struct i2c_client *client)
}
static const struct of_device_id mp886x_dt_ids[] = {
+ { .compatible = "mps,mp8864", .data = &mp8864_ci },
{ .compatible = "mps,mp8867", .data = &mp8867_ci },
{ .compatible = "mps,mp8869", .data = &mp8869_ci },
{ }
@@ -348,6 +375,7 @@ static const struct of_device_id mp886x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, mp886x_dt_ids);
static const struct i2c_device_id mp886x_id[] = {
+ { .name = "mp8864", .driver_data = (kernel_ulong_t)&mp8864_ci },
{ .name = "mp8867", .driver_data = (kernel_ulong_t)&mp8867_ci },
{ .name = "mp8869", .driver_data = (kernel_ulong_t)&mp8869_ci },
{ }
diff --git a/drivers/regulator/mpq4210.c b/drivers/regulator/mpq4210.c
new file mode 100644
index 000000000000..293e7b209a98
--- /dev/null
+++ b/drivers/regulator/mpq4210.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Monolithic Power Systems MPQ4210 buck-boost regulator
+ *
+ * Copyright (c) 2026 Vaisala Oyj
+ */
+
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#define MPQ4210_REF_LSB 0x00
+#define MPQ4210_REF_LSB_MASK GENMASK(2, 0)
+#define MPQ4210_REF_LSB_BITS 3
+#define MPQ4210_REF_MSB 0x01
+#define MPQ4210_CONTROL1 0x02
+#define MPQ4210_CONTROL1_SR GENMASK(7, 6)
+#define MPQ4210_CONTROL1_RESERVED BIT(2)
+#define MPQ4210_CONTROL1_GO BIT(1)
+#define MPQ4210_CONTROL1_ENPWR BIT(0)
+#define MPQ4210_INT_MASK 0x06
+
+/*
+ * The feedback reference is an 11 bit value with a 1mV step. The datasheet
+ * specifies no reference below 0.3V, so those selectors are not offered.
+ */
+#define MPQ4210_REF_MIN 0x12c
+#define MPQ4210_REF_MAX 0x7ff
+#define MPQ4210_REF_STEP_UV 1000
+
+#define MPQ4210_ENPWR_DELAY_MS 200
+
+/* Feedback reference slew rate per MPQ4210_CONTROL1_SR value, in uV/us. */
+static const unsigned int mpq4210_ref_slew_rate[] = { 38, 50, 75, 150 };
+
+static const struct regmap_config mpq4210_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MPQ4210_INT_MASK,
+};
+
+/* Scale a feedback reference value by the output voltage divider ratio. */
+static unsigned int mpq4210_scale(unsigned int val, u32 r1, u32 r2)
+{
+ u64 tmp = (u64)val * (r1 + r2);
+
+ do_div(tmp, r2);
+
+ return tmp;
+}
+
+static int mpq4210_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
+{
+ int ret;
+
+ ret = regmap_write(rdev->regmap, MPQ4210_REF_LSB,
+ sel & MPQ4210_REF_LSB_MASK);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(rdev->regmap, MPQ4210_REF_MSB,
+ sel >> MPQ4210_REF_LSB_BITS);
+ if (ret)
+ return ret;
+
+ return regmap_set_bits(rdev->regmap, MPQ4210_CONTROL1,
+ MPQ4210_CONTROL1_GO);
+}
+
+static int mpq4210_get_voltage_sel(struct regulator_dev *rdev)
+{
+ unsigned int lsb, msb;
+ int ret;
+
+ ret = regmap_read(rdev->regmap, MPQ4210_REF_MSB, &msb);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(rdev->regmap, MPQ4210_REF_LSB, &lsb);
+ if (ret)
+ return ret;
+
+ return (msb << MPQ4210_REF_LSB_BITS) | (lsb & MPQ4210_REF_LSB_MASK);
+}
+
+static int mpq4210_enable(struct regulator_dev *rdev)
+{
+ int ret;
+
+ ret = regmap_set_bits(rdev->regmap, MPQ4210_CONTROL1,
+ MPQ4210_CONTROL1_GO);
+ if (ret)
+ return ret;
+
+ /* The reference has to settle before power switching may start. */
+ msleep(MPQ4210_ENPWR_DELAY_MS);
+
+ return regmap_set_bits(rdev->regmap, MPQ4210_CONTROL1,
+ MPQ4210_CONTROL1_ENPWR);
+}
+
+static const struct regulator_ops mpq4210_regulator_ops = {
+ .set_voltage_sel = mpq4210_set_voltage_sel,
+ .get_voltage_sel = mpq4210_get_voltage_sel,
+ .list_voltage = regulator_list_voltage_linear,
+ .set_ramp_delay = regulator_set_ramp_delay_regmap,
+ .enable = mpq4210_enable,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+};
+
+static const struct regulator_desc mpq4210_regulator = {
+ .name = "mpq4210",
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .ops = &mpq4210_regulator_ops,
+ .n_voltages = MPQ4210_REF_MAX + 1,
+ .linear_min_sel = MPQ4210_REF_MIN,
+ .enable_reg = MPQ4210_CONTROL1,
+ .enable_mask = MPQ4210_CONTROL1_ENPWR,
+ .ramp_reg = MPQ4210_CONTROL1,
+ .ramp_mask = MPQ4210_CONTROL1_SR,
+ .n_ramp_values = ARRAY_SIZE(mpq4210_ref_slew_rate),
+};
+
+static int mpq4210_i2c_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct regulator_config config = { };
+ struct regulator_desc *desc;
+ struct regulator_dev *rdev;
+ struct gpio_desc *enable;
+ struct regmap *regmap;
+ unsigned int *slew;
+ unsigned int i, val;
+ u32 r[2];
+ int ret;
+
+ ret = of_property_read_u32_array(dev->of_node,
+ "mps,fb-voltage-divider-ohms",
+ r, ARRAY_SIZE(r));
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to read mps,fb-voltage-divider-ohms\n");
+
+ if (!r[1])
+ return dev_err_probe(dev, -EINVAL,
+ "feedback divider R2 must not be zero\n");
+
+ /* The controller does not answer on the bus while EN is deasserted. */
+ enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
+ if (IS_ERR(enable))
+ return dev_err_probe(dev, PTR_ERR(enable),
+ "failed to get enable GPIO\n");
+
+ regmap = devm_regmap_init_i2c(client, &mpq4210_regmap_config);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap),
+ "failed to init regmap\n");
+
+ desc = devm_kmemdup(dev, &mpq4210_regulator, sizeof(*desc), GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ desc->min_uV = mpq4210_scale(MPQ4210_REF_MIN * MPQ4210_REF_STEP_UV,
+ r[0], r[1]);
+ desc->uV_step = mpq4210_scale(MPQ4210_REF_STEP_UV, r[0], r[1]);
+
+ slew = devm_kcalloc(dev, ARRAY_SIZE(mpq4210_ref_slew_rate),
+ sizeof(*slew), GFP_KERNEL);
+ if (!slew)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(mpq4210_ref_slew_rate); i++)
+ slew[i] = mpq4210_scale(mpq4210_ref_slew_rate[i], r[0], r[1]);
+
+ desc->ramp_delay_table = slew;
+
+ ret = regmap_read(regmap, MPQ4210_CONTROL1, &val);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to read control 1\n");
+
+ /* The core overrides this if the board sets regulator-ramp-delay. */
+ desc->ramp_delay = slew[FIELD_GET(MPQ4210_CONTROL1_SR, val)];
+
+ /*
+ * Documented as reserved, but the datasheet requires it to be set
+ * before the controller starts up.
+ */
+ ret = regmap_set_bits(regmap, MPQ4210_CONTROL1,
+ MPQ4210_CONTROL1_RESERVED);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to write control 1\n");
+
+ config.dev = dev;
+ config.regmap = regmap;
+ config.of_node = dev->of_node;
+ config.init_data = of_get_regulator_init_data(dev, dev->of_node, desc);
+ if (!config.init_data)
+ return -ENOMEM;
+
+ rdev = devm_regulator_register(dev, desc, &config);
+ if (IS_ERR(rdev))
+ return dev_err_probe(dev, PTR_ERR(rdev),
+ "failed to register regulator\n");
+
+ return 0;
+}
+
+static const struct of_device_id mpq4210_of_match[] = {
+ { .compatible = "mps,mpq4210" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mpq4210_of_match);
+
+static const struct i2c_device_id mpq4210_i2c_id[] = {
+ { .name = "mpq4210" },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mpq4210_i2c_id);
+
+static struct i2c_driver mpq4210_regulator_driver = {
+ .driver = {
+ .name = "mpq4210",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ .of_match_table = mpq4210_of_match,
+ },
+ .probe = mpq4210_i2c_probe,
+ .id_table = mpq4210_i2c_id,
+};
+
+module_i2c_driver(mpq4210_regulator_driver);
+
+MODULE_DESCRIPTION("Monolithic Power Systems MPQ4210 voltage regulator driver");
+MODULE_AUTHOR("Tapio Reijonen <tapio.reijonen@vaisala.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/nex10000ub-regulator.c b/drivers/regulator/nex10000ub-regulator.c
new file mode 100644
index 000000000000..f44b8b7906b9
--- /dev/null
+++ b/drivers/regulator/nex10000ub-regulator.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Nexperia NEX10000UB Regulator driver
+ *
+ * Copyright (C) 2026 Linaro Limited.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#define NEX10000UB_REG_VPOS 0x00
+#define NEX10000UB_REG_VNEG 0x01
+#define NEX10000UB_REG_ID 0x02
+
+#define NEX10000UB_VOUT_MASK 0x1F
+#define NEX10000UB_VOUT_N_VOLTAGE 0x15
+#define NEX10000UB_VOUT_VMIN 4000000
+#define NEX10000UB_VOUT_VMAX 6000000
+#define NEX10000UB_VOUT_STEP 100000
+
+#define NEX10000UB_REGULATOR_ID_VPOS 0
+#define NEX10000UB_REGULATOR_ID_VNEG 1
+#define NEX10000UB_MAX_REGULATORS 2
+
+static const struct regulator_ops nex10000ub_regulator_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+};
+
+static int nex10000ub_of_parse_cb(struct device_node *np,
+ const struct regulator_desc *desc,
+ struct regulator_config *config)
+{
+ struct gpio_desc *ena_gpiod;
+
+ ena_gpiod = fwnode_gpiod_get_index(of_fwnode_handle(np), "enable", 0,
+ GPIOD_OUT_LOW, desc->name);
+ if (IS_ERR(ena_gpiod))
+ return PTR_ERR(ena_gpiod);
+
+ config->ena_gpiod = ena_gpiod;
+
+ return 0;
+}
+
+#define NEX10000UB_REGULATOR_DESC(_id, _name) \
+ [NEX10000UB_REGULATOR_ID_##_id] = { \
+ .name = "nex10000ub-"#_name, \
+ .supply_name = "vin", \
+ .id = NEX10000UB_REGULATOR_ID_##_id, \
+ .of_match = of_match_ptr(#_name), \
+ .of_parse_cb = nex10000ub_of_parse_cb, \
+ .ops = &nex10000ub_regulator_ops, \
+ .n_voltages = NEX10000UB_VOUT_N_VOLTAGE, \
+ .min_uV = NEX10000UB_VOUT_VMIN, \
+ .uV_step = NEX10000UB_VOUT_STEP, \
+ .enable_time = 2000, \
+ .vsel_mask = NEX10000UB_VOUT_MASK, \
+ .vsel_reg = NEX10000UB_REG_##_id, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ }
+
+static const struct regulator_desc nex10000_regs_desc[NEX10000UB_MAX_REGULATORS] = {
+ NEX10000UB_REGULATOR_DESC(VPOS, vpos),
+ NEX10000UB_REGULATOR_DESC(VNEG, vneg),
+};
+
+static const struct regmap_config nex10000ub_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = NEX10000UB_REG_ID,
+ .cache_type = REGCACHE_NONE,
+};
+
+static int nex10000ub_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct regmap *map;
+ int id;
+ int ret;
+
+ map = devm_regmap_init_i2c(client, &nex10000ub_regmap_config);
+ if (IS_ERR(map)) {
+ ret = PTR_ERR(map);
+ dev_err(dev, "regmap init failed: %d\n", ret);
+ return ret;
+ }
+
+ for (id = 0; id < NEX10000UB_MAX_REGULATORS; ++id) {
+ struct regulator_config config = { };
+ struct regulator_dev *rdev;
+
+ config.regmap = map;
+ config.dev = dev;
+
+ rdev = devm_regulator_register(dev, &nex10000_regs_desc[id],
+ &config);
+ if (IS_ERR(rdev)) {
+ ret = PTR_ERR(rdev);
+ dev_err(dev, "regulator %s register failed: %d\n",
+ nex10000_regs_desc[id].name, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id nex10000ub_id[] = {
+ { .name = "nex10000ub" },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, nex10000ub_id);
+
+static const struct of_device_id __maybe_unused nex10000ub_of_match[] = {
+ { .compatible = "nexperia,nex10000ub" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, nex10000ub_of_match);
+
+static struct i2c_driver nex10000ub_i2c_driver = {
+ .driver = {
+ .name = "nex10000ub",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ .of_match_table = of_match_ptr(nex10000ub_of_match),
+ },
+ .probe = nex10000ub_probe,
+ .id_table = nex10000ub_id,
+};
+
+module_i2c_driver(nex10000ub_i2c_driver);
+
+MODULE_DESCRIPTION("NEX10000UB regulator driver");
+MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index c41db70fa052..613bce411f31 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -77,10 +77,56 @@ static const unsigned int pca9450_dvs_buck_ramp_table[] = {
25000, 12500, 6250, 3125
};
+static int pca9450_regulator_is_enabled(struct regulator_dev *rdev)
+{
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
+ if (ret)
+ return ret;
+
+ /* All valid nonzero ENMODE values enable the regulator in RUN mode. */
+ return !!(val & rdev->desc->enable_mask);
+}
+
+static int pca9450_set_suspend_disable(struct regulator_dev *rdev,
+ unsigned int suspend_val)
+{
+ int ret;
+
+ /* Do not enable a runtime-disabled regulator when returning to RUN. */
+ ret = pca9450_regulator_is_enabled(rdev);
+ if (ret < 0)
+ return ret;
+ if (!ret)
+ return 0;
+
+ return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+ rdev->desc->enable_mask,
+ suspend_val);
+}
+
+/*
+ * ENMODE = 10b keeps the regulator enabled in RUN mode and disables it
+ * while PMIC_STBY_REQ is asserted.
+ */
+static int pca9450_buck_set_suspend_disable(struct regulator_dev *rdev)
+{
+ return pca9450_set_suspend_disable(rdev,
+ BUCK_ENMODE_ONREQ_STBYREQ);
+}
+
+static int pca9450_ldo_set_suspend_disable(struct regulator_dev *rdev)
+{
+ return pca9450_set_suspend_disable(rdev,
+ LDO_ENMODE_ONREQ_STBYREQ);
+}
+
static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
+ .is_enabled = pca9450_regulator_is_enabled,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@@ -88,18 +134,20 @@ static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_mode = pca9450_buck_set_mode,
.get_mode = pca9450_buck_get_mode,
+ .set_suspend_disable = pca9450_buck_set_suspend_disable,
};
static const struct regulator_ops pca9450_buck_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
+ .is_enabled = pca9450_regulator_is_enabled,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_mode = pca9450_buck_set_mode,
.get_mode = pca9450_buck_get_mode,
+ .set_suspend_disable = pca9450_buck_set_suspend_disable,
};
static const struct regulator_ops pca9450_ldo_regulator_ops = {
@@ -111,6 +159,16 @@ static const struct regulator_ops pca9450_ldo_regulator_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
+static const struct regulator_ops pca9450_ldo_suspend_regulator_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_suspend_disable = pca9450_ldo_set_suspend_disable,
+};
+
static unsigned int pca9450_ldo5_get_reg_voltage_sel(struct regulator_dev *rdev)
{
struct pca9450 *pca9450 = rdev_get_drvdata(rdev);
@@ -164,6 +222,7 @@ static const struct regulator_ops pca9450_ldo5_regulator_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = pca9450_ldo5_set_voltage_sel_regmap,
.get_voltage_sel = pca9450_ldo5_get_voltage_sel_regmap,
+ .set_suspend_disable = pca9450_ldo_set_suspend_disable,
};
/*
@@ -575,7 +634,7 @@ static struct pca9450_regulator_desc pca9450a_regulators[] = {
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO3,
- .ops = &pca9450_ldo_regulator_ops,
+ .ops = &pca9450_ldo_suspend_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
@@ -594,7 +653,7 @@ static struct pca9450_regulator_desc pca9450a_regulators[] = {
.of_match = of_match_ptr("LDO4"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO4,
- .ops = &pca9450_ldo_regulator_ops,
+ .ops = &pca9450_ldo_suspend_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
@@ -621,7 +680,7 @@ static struct pca9450_regulator_desc pca9450a_regulators[] = {
.vsel_reg = PCA9450_REG_LDO5CTRL_H,
.vsel_mask = LDO5HOUT_MASK,
.enable_reg = PCA9450_REG_LDO5CTRL_L,
- .enable_mask = LDO5H_EN_MASK,
+ .enable_mask = LDO5L_EN_MASK,
.owner = THIS_MODULE,
},
},
@@ -820,7 +879,7 @@ static struct pca9450_regulator_desc pca9450bc_regulators[] = {
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO3,
- .ops = &pca9450_ldo_regulator_ops,
+ .ops = &pca9450_ldo_suspend_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
@@ -839,7 +898,7 @@ static struct pca9450_regulator_desc pca9450bc_regulators[] = {
.of_match = of_match_ptr("LDO4"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO4,
- .ops = &pca9450_ldo_regulator_ops,
+ .ops = &pca9450_ldo_suspend_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
@@ -866,7 +925,7 @@ static struct pca9450_regulator_desc pca9450bc_regulators[] = {
.vsel_reg = PCA9450_REG_LDO5CTRL_H,
.vsel_mask = LDO5HOUT_MASK,
.enable_reg = PCA9450_REG_LDO5CTRL_L,
- .enable_mask = LDO5H_EN_MASK,
+ .enable_mask = LDO5L_EN_MASK,
.owner = THIS_MODULE,
},
},
@@ -1040,7 +1099,7 @@ static struct pca9450_regulator_desc pca9451a_regulators[] = {
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO3,
- .ops = &pca9450_ldo_regulator_ops,
+ .ops = &pca9450_ldo_suspend_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
@@ -1059,7 +1118,7 @@ static struct pca9450_regulator_desc pca9451a_regulators[] = {
.of_match = of_match_ptr("LDO4"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO4,
- .ops = &pca9450_ldo_regulator_ops,
+ .ops = &pca9450_ldo_suspend_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
@@ -1086,7 +1145,7 @@ static struct pca9450_regulator_desc pca9451a_regulators[] = {
.vsel_reg = PCA9450_REG_LDO5CTRL_H,
.vsel_mask = LDO5HOUT_MASK,
.enable_reg = PCA9450_REG_LDO5CTRL_L,
- .enable_mask = LDO5H_EN_MASK,
+ .enable_mask = LDO5L_EN_MASK,
.owner = THIS_MODULE,
},
},
diff --git a/drivers/regulator/pf1550-regulator.c b/drivers/regulator/pf1550-regulator.c
index ceee553a84b2..84f8b187a91b 100644
--- a/drivers/regulator/pf1550-regulator.c
+++ b/drivers/regulator/pf1550-regulator.c
@@ -49,17 +49,26 @@ static const int pf1550_ldo13_volts[] = {
static int pf1550_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
int id = rdev_get_id(rdev);
- unsigned int ramp_bits = 0;
+ unsigned int ramp_bits;
int ret;
if (id > PF1550_VREFDDR)
return -EACCES;
- if (ramp_delay < 0 || ramp_delay > 6250)
+ switch (ramp_delay) {
+ case 0:
+ /* Ramp control is disabled, so use the fastest rate. */
+ ramp_bits = 0;
+ break;
+ case 1 ... 3125:
+ ramp_bits = 1;
+ break;
+ case 3126 ... 6250:
+ ramp_bits = 0;
+ break;
+ default:
return -EINVAL;
-
- ramp_delay = 6250 / ramp_delay;
- ramp_bits = ramp_delay >> 1;
+ }
ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg + 4, 0x10,
ramp_bits << 4);
diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c
index b96afbf11ff3..1f2c405fd2bd 100644
--- a/drivers/regulator/pv88080-regulator.c
+++ b/drivers/regulator/pv88080-regulator.c
@@ -432,7 +432,7 @@ static int pv88080_i2c_probe(struct i2c_client *i2c)
config.dev = chip->dev;
config.regmap = chip->regmap;
- /* Registeration for BUCK1, 2, 3 */
+ /* Registration for BUCK1, 2, 3 */
for (i = 0; i < PV88080_MAX_REGULATORS-1; i++) {
if (init_data)
config.init_data = &init_data[i];
@@ -498,7 +498,7 @@ static int pv88080_i2c_probe(struct i2c_client *i2c)
pv88080_regulator_info[PV88080_ID_HVBUCK].desc.vsel_mask
= regmap_config->hvbuck_vsel_mask;
- /* Registeration for HVBUCK */
+ /* Registration for HVBUCK */
if (init_data)
config.init_data = &init_data[PV88080_ID_HVBUCK];
diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
index 25c14de3cd8b..4c90d206e63b 100644
--- a/drivers/regulator/qcom-rpmh-regulator.c
+++ b/drivers/regulator/qcom-rpmh-regulator.c
@@ -400,7 +400,7 @@ static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
* This function is used in the regulator_ops for VRM type RPMh regulator
* devices.
*
- * Return: 0 on success, or a negative error number on failure
+ * Return: the regulator mode to use for the load
*/
static unsigned int rpmh_regulator_vrm_get_optimum_mode(
struct regulator_dev *rdev, int input_uV, int output_uV, int load_uA)
@@ -1589,31 +1589,34 @@ static const struct rpmh_vreg_init_data pm6150l_vreg_data[] = {
};
static const struct rpmh_vreg_init_data pm6350_vreg_data[] = {
- RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, NULL),
- RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps510, NULL),
- /* smps3 - smps5 not configured */
- RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, NULL),
- RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, NULL),
- RPMH_VREG("ldo3", LDO, 3, &pmic5_pldo, NULL),
- RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, NULL),
- RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, NULL),
- RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, NULL),
- RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, NULL),
- RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo, NULL),
- RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, NULL),
- RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, NULL),
- RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, NULL),
- RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo, NULL),
- RPMH_VREG("ldo13", LDO, 13, &pmic5_nldo, NULL),
- RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo, NULL),
- RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo, NULL),
- RPMH_VREG("ldo16", LDO, 16, &pmic5_nldo, NULL),
- /* ldo17 not configured */
- RPMH_VREG("ldo18", LDO, 18, &pmic5_nldo, NULL),
- RPMH_VREG("ldo19", LDO, 19, &pmic5_nldo, NULL),
- RPMH_VREG("ldo20", LDO, 20, &pmic5_nldo, NULL),
- RPMH_VREG("ldo21", LDO, 21, &pmic5_nldo, NULL),
- RPMH_VREG("ldo22", LDO, 22, &pmic5_nldo, NULL),
+ RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"),
+ RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps510, "vdd-s2"),
+ RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps510, "vdd-s3"),
+ RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps510, "vdd-s4"),
+ RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps510, "vdd-s5"),
+ RPMH_VREG("smps6", SMPS, 6, &pmic5_hfsmps510, "vdd-s6"),
+ RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1"),
+ RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, "vdd-l2-l5-l7"),
+ RPMH_VREG("ldo3", LDO, 3, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"),
+ RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l4"),
+ RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l2-l5-l7"),
+ RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"),
+ RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l2-l5-l7"),
+ RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"),
+ RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"),
+ RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"),
+ RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, "vdd-l11"),
+ RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo, "vdd-l12-l14"),
+ RPMH_VREG("ldo13", LDO, 13, &pmic5_nldo, "vdd-l13"),
+ RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo, "vdd-l12-l14"),
+ RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo, "vdd-l15-l19-l22"),
+ RPMH_VREG("ldo16", LDO, 16, &pmic5_nldo, "vdd-l16"),
+ RPMH_VREG("ldo17", LDO, 17, &pmic5_nldo, "vdd-l17"),
+ RPMH_VREG("ldo18", LDO, 18, &pmic5_nldo, "vdd-l18-l20-l21"),
+ RPMH_VREG("ldo19", LDO, 19, &pmic5_nldo, "vdd-l15-l19-l22"),
+ RPMH_VREG("ldo20", LDO, 20, &pmic5_nldo, "vdd-l18-l20-l21"),
+ RPMH_VREG("ldo21", LDO, 21, &pmic5_nldo, "vdd-l18-l20-l21"),
+ RPMH_VREG("ldo22", LDO, 22, &pmic5_nldo, "vdd-l15-l19-l22"),
};
static const struct rpmh_vreg_init_data pmcx0102_vreg_data[] = {
diff --git a/drivers/regulator/rt6190-regulator.c b/drivers/regulator/rt6190-regulator.c
index f2cd9540038d..21ced348a2cf 100644
--- a/drivers/regulator/rt6190-regulator.c
+++ b/drivers/regulator/rt6190-regulator.c
@@ -108,19 +108,27 @@ static int rt6190_out_enable(struct regulator_dev *rdev)
ret = regmap_raw_read(regmap, RT6190_REG_OUTV, out_cfg,
sizeof(out_cfg));
if (ret)
- return ret;
+ goto err_pm_put;
ret = regulator_enable_regmap(rdev);
if (ret)
- return ret;
+ goto err_pm_put;
ret = regmap_raw_write(regmap, RT6190_REG_OUTV, out_cfg,
sizeof(out_cfg));
if (ret)
- return ret;
+ goto err_pm_put;
+
+ ret = regmap_update_bits(regmap, RT6190_REG_SET5, RT6190_ENGCP_MASK,
+ RT6190_ENGCP_MASK);
+ if (ret)
+ goto err_pm_put;
+
+ return 0;
- return regmap_update_bits(regmap, RT6190_REG_SET5, RT6190_ENGCP_MASK,
- RT6190_ENGCP_MASK);
+err_pm_put:
+ pm_runtime_put(data->dev);
+ return ret;
}
static int rt6190_out_disable(struct regulator_dev *rdev)
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c
index a09c6ae6a0ce..7f99f3e90bec 100644
--- a/drivers/regulator/tps6105x-regulator.c
+++ b/drivers/regulator/tps6105x-regulator.c
@@ -65,7 +65,7 @@ static int tps6105x_regulator_probe(struct platform_device *pdev)
/* This instance is not set for regulator mode so bail out */
if (pdata->mode != TPS6105X_MODE_VOLTAGE) {
dev_info(&pdev->dev,
- "chip not in voltage mode mode, exit probe\n");
+ "chip not in voltage mode, exit probe\n");
return 0;
}
diff --git a/drivers/regulator/tps65185.c b/drivers/regulator/tps65185.c
index 6a3130177e7a..4865227e444a 100644
--- a/drivers/regulator/tps65185.c
+++ b/drivers/regulator/tps65185.c
@@ -392,8 +392,7 @@ static int tps65185_probe(struct i2c_client *client)
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"PGOOD", data);
if (ret)
- return dev_err_probe(&client->dev, ret,
- "failed to request power good irq\n");
+ return ret;
if (client->irq) {
ret = devm_request_threaded_irq(&client->dev, client->irq,
@@ -401,8 +400,7 @@ static int tps65185_probe(struct i2c_client *client)
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"tps65185", data);
if (ret)
- return dev_err_probe(&client->dev, ret,
- "failed to request irq\n");
+ return ret;
}
ret = regmap_update_bits(data->regmap, TPS65185_REG_INT_EN2, BIT(0), BIT(0));
diff --git a/include/linux/mfd/88pm886.h b/include/linux/mfd/88pm886.h
index 2c24dd3032ab..9e96d2cb92f5 100644
--- a/include/linux/mfd/88pm886.h
+++ b/include/linux/mfd/88pm886.h
@@ -2,6 +2,7 @@
#ifndef __MFD_88PM886_H
#define __MFD_88PM886_H
+#include <linux/bits.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
@@ -130,6 +131,12 @@
#define PM886_GPADC_INDEX_TO_BIAS_uA(i) (1 + (i) * 5)
/* Battery block register definitions */
+#define PM886_REG_BATTERY_CONFIG1 0x28
+#define PM886_REG_VBUS_EN BIT(7)
+
+#define PM886_REG_BOOST_CONFIG1 0x6b
+#define PM886_REG_BOOST_MASK GENMASK(2, 0)
+
#define PM886_REG_CLS_CONFIG1 0x71
struct pm886_chip {
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index cc6ce709ec86..55cc519103ed 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -362,7 +362,7 @@ enum regulator_type {
* @off_on_delay: guard time (in uS), before re-enabling a regulator
*
* @poll_enabled_time: The polling interval (in uS) to use while checking that
- * the regulator was actually enabled. Max upto enable_time.
+ * the regulator was actually enabled. Max up to enable_time.
*
* @of_map_mode: Maps a hardware mode defined in a DeviceTree to a standard mode
*/
diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h
index 0df8b3c48082..bf94df5fafe3 100644
--- a/include/linux/regulator/pca9450.h
+++ b/include/linux/regulator/pca9450.h
@@ -210,9 +210,11 @@ enum {
#define LDO5L_EN_MASK 0xC0
#define LDO5LOUT_MASK 0x0F
-#define LDO5H_EN_MASK 0xC0
#define LDO5HOUT_MASK 0x0F
+/* LDO ENMODE value: ON in RUN, OFF while PMIC_STBY_REQ is asserted */
+#define LDO_ENMODE_ONREQ_STBYREQ 0x80
+
/* PCA9450_REG_IRQ bits */
#define IRQ_PWRON 0x80
#define IRQ_WDOGB 0x40
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 3a818f07a101..7cbcc3fb9e6d 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -28,7 +28,15 @@ static struct lock_class_key irq_desc_lock_class;
static int __init irq_affinity_setup(char *str)
{
alloc_bootmem_cpumask_var(&irq_default_affinity);
- cpulist_parse(str, irq_default_affinity);
+ if (cpulist_parse(str, irq_default_affinity) < 0) {
+ /*
+ * Clear the mask so that init_irq_default_affinity()
+ * defaults it later.
+ */
+ cpumask_clear(irq_default_affinity);
+ pr_warn("irqaffinity: incorrect CPU range, using default\n");
+ return 1;
+ }
/*
* Set at least the boot cpu. We don't want to end up with
* bugreports caused by random commandline masks
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 5d02c36c40e3..c3729c5b284b 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -645,8 +645,8 @@ restart:
h->action();
trace_softirq_exit(vec_nr);
if (unlikely(prev_count != preempt_count())) {
- pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n",
- vec_nr, softirq_to_name[vec_nr], h->action,
+ pr_err("huh, entered softirq %u %s with preempt_count %08x, exited with %08x?\n",
+ vec_nr, softirq_to_name[vec_nr],
prev_count, preempt_count());
preempt_count_set(prev_count);
}