Merge remote-tracking branch 'regulator/for-5.19' into regulator-next
authorMark Brown <broonie@kernel.org>
Tue, 17 May 2022 15:59:05 +0000 (16:59 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 17 May 2022 15:59:05 +0000 (16:59 +0100)
24 files changed:
Documentation/ABI/testing/sysfs-class-regulator
Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml
Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
Documentation/devicetree/bindings/regulator/richtek,rt5759-regulator.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/siliconmitus,sm5703-regulator.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/socionext,uniphier-regulator.yaml
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/core.c
drivers/regulator/da9121-regulator.c
drivers/regulator/fixed.c
drivers/regulator/mt6358-regulator.c
drivers/regulator/pca9450-regulator.c
drivers/regulator/pfuze100-regulator.c
drivers/regulator/rpi-panel-attiny-regulator.c
drivers/regulator/rt4801-regulator.c
drivers/regulator/rt5759-regulator.c [new file with mode: 0644]
drivers/regulator/scmi-regulator.c
drivers/regulator/sm5703-regulator.c [new file with mode: 0644]
drivers/regulator/stm32-vrefbuf.c
include/linux/regulator/mt6358-regulator.h
include/linux/regulator/pca9450.h

index 8516f08..475b9a3 100644 (file)
@@ -370,3 +370,84 @@ Description:
 
                'unknown' means software cannot determine the state, or
                the reported state is invalid.
+
+What:          /sys/class/regulator/.../under_voltage
+Date:          April 2022
+KernelVersion: 5.18
+Contact:       Zev Weiss <zev@bewilderbeest.net>
+Description:
+               Some regulator directories will contain a field called
+               under_voltage.  This indicates if the device reports an
+               under-voltage fault (1) or not (0).
+
+What:          /sys/class/regulator/.../over_current
+Date:          April 2022
+KernelVersion: 5.18
+Contact:       Zev Weiss <zev@bewilderbeest.net>
+Description:
+               Some regulator directories will contain a field called
+               over_current.  This indicates if the device reports an
+               over-current fault (1) or not (0).
+
+What:          /sys/class/regulator/.../regulation_out
+Date:          April 2022
+KernelVersion: 5.18
+Contact:       Zev Weiss <zev@bewilderbeest.net>
+Description:
+               Some regulator directories will contain a field called
+               regulation_out.  This indicates if the device reports an
+               out-of-regulation fault (1) or not (0).
+
+What:          /sys/class/regulator/.../fail
+Date:          April 2022
+KernelVersion: 5.18
+Contact:       Zev Weiss <zev@bewilderbeest.net>
+Description:
+               Some regulator directories will contain a field called
+               fail.  This indicates if the device reports an output failure
+               (1) or not (0).
+
+What:          /sys/class/regulator/.../over_temp
+Date:          April 2022
+KernelVersion: 5.18
+Contact:       Zev Weiss <zev@bewilderbeest.net>
+Description:
+               Some regulator directories will contain a field called
+               over_temp.  This indicates if the device reports an
+               over-temperature fault (1) or not (0).
+
+What:          /sys/class/regulator/.../under_voltage_warn
+Date:          April 2022
+KernelVersion: 5.18
+Contact:       Zev Weiss <zev@bewilderbeest.net>
+Description:
+               Some regulator directories will contain a field called
+               under_voltage_warn.  This indicates if the device reports an
+               under-voltage warning (1) or not (0).
+
+What:          /sys/class/regulator/.../over_current_warn
+Date:          April 2022
+KernelVersion: 5.18
+Contact:       Zev Weiss <zev@bewilderbeest.net>
+Description:
+               Some regulator directories will contain a field called
+               over_current_warn.  This indicates if the device reports an
+               over-current warning (1) or not (0).
+
+What:          /sys/class/regulator/.../over_voltage_warn
+Date:          April 2022
+KernelVersion: 5.18
+Contact:       Zev Weiss <zev@bewilderbeest.net>
+Description:
+               Some regulator directories will contain a field called
+               over_voltage_warn.  This indicates if the device reports an
+               over-voltage warning (1) or not (0).
+
+What:          /sys/class/regulator/.../over_temp_warn
+Date:          April 2022
+KernelVersion: 5.18
+Contact:       Zev Weiss <zev@bewilderbeest.net>
+Description:
+               Some regulator directories will contain a field called
+               over_temp_warn.  This indicates if the device reports an
+               over-temperature warning (1) or not (0).
index 9a90a92..7034cdc 100644 (file)
@@ -8,14 +8,14 @@ Documentation/devicetree/bindings/regulator/regulator.txt.
 
 The valid names for regulators are::
 BUCK:
-  buck_vdram1, buck_vcore, buck_vpa, buck_vproc11, buck_vproc12, buck_vgpu,
-  buck_vs2, buck_vmodem, buck_vs1
+  buck_vdram1, buck_vcore, buck_vcore_sshub, buck_vpa, buck_vproc11,
+  buck_vproc12, buck_vgpu, buck_vs2, buck_vmodem, buck_vs1
 LDO:
   ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio,
   ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others,
-  ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28,
-  ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18,
-  ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
+  ldo_vsram_others_sshub, ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18,
+  ldo_vmch, ldo_vbif28, ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12,
+  ldo_vrf18, ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
   ldo_vsim2
 
 Example:
@@ -354,5 +354,17 @@ Example:
                                regulator-max-microvolt = <3100000>;
                                regulator-enable-ramp-delay = <540>;
                        };
+
+                       mt6358_vcore_sshub_reg: buck_vcore_sshub {
+                               regulator-name = "vcore_sshub";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                       };
+
+                       mt6358_vsram_others_sshub_reg: ldo_vsram_others_sshub {
+                               regulator-name = "vsram_others_sshub";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                       };
                };
        };
index f70f2e7..b539781 100644 (file)
@@ -92,6 +92,17 @@ properties:
       LDO5CTRL_L or LDO5CTRL_H register. Use this if the SD_VSEL signal is
       connected to a host GPIO.
 
+  nxp,i2c-lt-enable:
+    type: boolean
+    description:
+      Indicates that the I2C Level Translator is used.
+
+  nxp,wdog_b-warm-reset:
+    type: boolean
+    description:
+      When WDOG_B signal is asserted a warm reset will be done instead of cold
+      reset.
+
 required:
   - compatible
   - reg
index e28ee9e..9a36bee 100644 (file)
@@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm Technologies, Inc. RPMh Regulators
 
 maintainers:
-  - David Collins <collinsd@codeaurora.org>
+  - Bjorn Andersson <bjorn.andersson@linaro.org>
+  - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 
 description: |
     rpmh-regulator devices support PMIC regulator management via the Voltage
@@ -78,7 +79,7 @@ properties:
         RPMh resource name suffix used for the regulators found
         on this PMIC.
     $ref: /schemas/types.yaml#/definitions/string
-    enum: [a, b, c, d, e, f]
+    enum: [a, b, c, d, e, f, h, k]
 
   qcom,always-wait-for-ack:
     description: |
@@ -94,35 +95,264 @@ properties:
   vdd-rgb-supply:
     description: Input supply phandle of rgb.
 
-  vin-lvs-1-2-supply:
-    description: Input supply phandle of one or more regulators.
-
-  vdd-bob-supply:
-    description: BOB regulator parent supply phandle.
-
   bob:
     type: object
     $ref: "regulator.yaml#"
     description: BOB regulator node.
 
 patternProperties:
-  "^vdd-s([0-9]+)-supply$":
-    description: Input supply phandle(s) of one or more regulators.
-
-  "^vdd-(l[0-9]+[-]){1,5}supply$":
-    description: Input supply phandle(s) of one or more regulators.
-
   "^(smps|ldo|lvs)[0-9]+$":
     type: object
     $ref: "regulator.yaml#"
     description: smps/ldo regulator nodes(s).
 
-additionalProperties: false
-
 required:
   - compatible
   - qcom,pmic-id
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm6150-rpmh-regulators
+    then:
+      properties:
+        vdd-l2-l3-supply: true
+        vdd-l4-l7-l8-supply: true
+        vdd-l5-l16-l17-l18-l19-supply: true
+        vdd-l10-l14-l15-supply: true
+        vdd-l11-l12-l13-supply: true
+      patternProperties:
+        "^vdd-l[169]-supply$": true
+        "^vdd-s[1-5]-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm6150l-rpmh-regulators
+    then:
+      properties:
+        vdd-bob-supply:
+          description: BOB regulator parent supply phandle.
+        vdd-l1-l8-supply: true
+        vdd-l2-l3-supply: true
+        vdd-l4-l5-l6-supply: true
+        vdd-l7-l11-supply: true
+        vdd-l9-l10-supply: true
+      patternProperties:
+        "^vdd-s[1-8]-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm7325-rpmh-regulators
+    then:
+      properties:
+        vdd-l1-l4-l12-l15-supply: true
+        vdd-l2-l7-supply: true
+        vdd-l6-l9-l10-supply: true
+        vdd-l11-l17-l18-l19-supply: true
+        vdd-l13-supply: true
+        vdd-l14-l16-supply: true
+      patternProperties:
+        "^vdd-l[358]-supply$": true
+        "^vdd-s[1-8]-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm8005-rpmh-regulators
+    then:
+      patternProperties:
+        "^vdd-s[1-4]-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm8009-rpmh-regulators
+            - qcom,pm8009-1-rpmh-regulators
+    then:
+      properties:
+        vdd-l5-l6-supply: true
+      patternProperties:
+        "^vdd-l[1-47]-supply$": true
+        "^vdd-s[1-2]-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm8150-rpmh-regulators
+            - qcom,pmm8155au-rpmh-regulators
+    then:
+      properties:
+        vdd-l1-l8-l11-supply: true
+        vdd-l2-l10-supply: true
+        vdd-l3-l4-l5-l18-supply: true
+        vdd-l6-l9-supply: true
+        vdd-l7-l12-l14-l15-supply: true
+        vdd-l13-l16-l17-supply: true
+      patternProperties:
+        "^vdd-s([1-9]|10)-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm8150l-rpmh-regulators
+    then:
+      properties:
+        vdd-bob-supply:
+          description: BOB regulator parent supply phandle.
+        vdd-l1-l8-supply: true
+        vdd-l2-l3-supply: true
+        vdd-l4-l5-l6-supply: true
+        vdd-l7-l11-supply: true
+        vdd-l9-l10-supply: true
+      patternProperties:
+        "^vdd-s[1-8]-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm8350-rpmh-regulators
+    then:
+      properties:
+        vdd-l1-l4-supply: true
+        vdd-l2-l7-supply: true
+        vdd-l3-l5-supply: true
+        vdd-l6-l9-l10-supply: true
+        vdd-l8-supply: true
+      patternProperties:
+        "^vdd-s([1-9]|1[0-2])-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm8350c-rpmh-regulators
+    then:
+      properties:
+        vdd-bob-supply:
+          description: BOB regulator parent supply phandle.
+        vdd-l1-l12-supply: true
+        vdd-l2-l8-supply: true
+        vdd-l3-l4-l5-l7-l13-supply: true
+        vdd-l6-l9-l11-supply: true
+        vdd-l10-supply: true
+      patternProperties:
+        "^vdd-s([1-9]|10)-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm8450-rpmh-regulators
+    then:
+      patternProperties:
+        "^vdd-l[1-4]-supply$": true
+        "^vdd-s[1-6]-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pm8998-rpmh-regulators
+    then:
+      properties:
+        vdd-l1-l27-supply: true
+        vdd-l2-l8-l17-supply: true
+        vdd-l3-l11-supply: true
+        vdd-l4-l5-supply: true
+        vdd-l6-supply: true
+        vdd-l7-l12-l14-l15-supply: true
+        vdd-l9-supply: true
+        vdd-l10-l23-l25-supply: true
+        vdd-l13-l19-l21-supply: true
+        vdd-l16-l28-supply: true
+        vdd-l18-l22-supply: true
+        vdd-l20-l24-supply: true
+        vdd-l26-supply: true
+        vin-lvs-1-2-supply: true
+      patternProperties:
+        "^vdd-s([1-9]|1[0-3])-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pmg1110-rpmh-regulators
+    then:
+      properties:
+        vdd-s1-supply: true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pmi8998-rpmh-regulators
+    then:
+      properties:
+        vdd-bob-supply:
+          description: BOB regulator parent supply phandle.
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pmr735a-rpmh-regulators
+    then:
+      properties:
+        vdd-l1-l2-supply: true
+        vdd-l3-supply: true
+        vdd-l4-supply: true
+        vdd-l5-l6-supply: true
+        vdd-l7-bob-supply: true
+      patternProperties:
+        "^vdd-s[1-3]-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pmx55-rpmh-regulators
+    then:
+      properties:
+        vdd-l1-l2-supply: true
+        vdd-l3-l9-supply: true
+        vdd-l4-l12-supply: true
+        vdd-l5-l6-supply: true
+        vdd-l7-l8-supply: true
+        vdd-l10-l11-l13-supply: true
+      patternProperties:
+        "^vdd-l1[4-6]-supply$": true
+        "^vdd-s[1-7]-supply$": true
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pmx65-rpmh-regulators
+    then:
+      properties:
+        vdd-l2-l18-supply: true
+        vdd-l5-l6-l16-supply: true
+        vdd-l8-l9-supply: true
+        vdd-l11-l13-supply: true
+      patternProperties:
+        "^vdd-l[1347]-supply$": true
+        "^vdd-l1[0245789]-supply$": true
+        "^vdd-l2[01]-supply$": true
+        "^vdd-s[1-8]-supply$": true
+
+unevaluatedProperties: false
+
 examples:
   - |
     #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
index 235e593..091150c 100644 (file)
@@ -17,9 +17,6 @@ description: |
   Datasheet is available at
   https://www.richtek.com/assets/product_file/RT4801H/DS4801H-00.pdf
 
-#The valid names for RT4801 regulator nodes are:
-#DSVP, DSVN
-
 properties:
   compatible:
     enum:
@@ -33,10 +30,13 @@ properties:
       The first one is ENP to enable DSVP, and second one is ENM to enable DSVN.
       Number of GPIO in the array list could be 1 or 2.
       If only one gpio is specified, only one gpio used to control ENP/ENM.
-      Else both are spefied, DSVP/DSVN could be controlled individually.
-      Othersie, this property not specified. treat both as always-on regulator.
+      Else if both are specified, DSVP/DSVN could be controlled individually.
+      If this property not specified, treat both as always-on regulators.
+
+      Property is deprecated. Use enable-gpios in each regulator.
     minItems: 1
     maxItems: 2
+    deprecated: true
 
 patternProperties:
   "^DSV(P|N)$":
@@ -45,6 +45,14 @@ patternProperties:
     description:
       Properties for single display bias regulator.
 
+    properties:
+      enable-gpios:
+        description:
+          GPIO to use to enable DSVP/DSVN regulator. One GPIO can be configured
+          for controlling both regulators.  If this property not specified for
+          any regulator, treat both as always-on regulators.
+        maxItems: 1
+
 required:
   - compatible
   - reg
@@ -60,19 +68,20 @@ examples:
         rt4801@73 {
             compatible = "richtek,rt4801";
             reg = <0x73>;
-            enable-gpios = <&gpio26 2 0>, <&gpio26 3 0>;
 
             dsvp: DSVP {
                 regulator-name = "rt4801,dsvp";
                 regulator-min-microvolt = <4000000>;
                 regulator-max-microvolt = <6000000>;
                 regulator-boot-on;
+                enable-gpios = <&gpio26 2 0>;
             };
             dsvn: DSVN {
                 regulator-name = "rt4801,dsvn";
                 regulator-min-microvolt = <4000000>;
                 regulator-max-microvolt = <6000000>;
                 regulator-boot-on;
+                enable-gpios = <&gpio26 3 0>;
             };
 
         };
diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt5759-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rt5759-regulator.yaml
new file mode 100644 (file)
index 0000000..0a4c957
--- /dev/null
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt5759-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT5759 High Performance DCDC Converter
+
+maintainers:
+  - ChiYuan Huang <cy_huang@richtek.com>
+
+description: |
+  The RT5759 is a high-performance, synchronous step-down DC-DC converter that
+  can deliver up to 9A output current from 3V to 6.5V input supply, The output
+  voltage can be programmable with I2C controlled 7-Bit VID.
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT5759/DS5759-00.pdf
+
+properties:
+  compatible:
+    enum:
+      - richtek,rt5759
+      - richtek,rt5759a
+
+  reg:
+    maxItems: 1
+
+  regulator-allowed-modes:
+    description: |
+      buck allowed operating mode
+        0: auto mode (PSKIP: pulse skipping)
+        1: force pwm mode
+    items:
+      enum: [0, 1]
+
+  richtek,watchdog-enable:
+    description: enable the external watchdog reset pin listening
+    type: boolean
+
+allOf:
+  - $ref: regulator.yaml#
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: richtek,rt5759
+    then:
+      properties:
+        richtek,watchdog-enable: false
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  # example 1 for RT5759
+  - |
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      regulator@62 {
+        compatible = "richtek,rt5759";
+        reg = <0x62>;
+        regulator-name = "rt5759-buck";
+        regulator-min-microvolt = <600000>;
+        regulator-max-microvolt = <1500000>;
+        regulator-boot-on;
+      };
+    };
+  # example 2 for RT5759A
+  - |
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      regulator@62 {
+        compatible = "richtek,rt5759a";
+        reg = <0x62>;
+        regulator-name = "rt5759a-buck";
+        regulator-min-microvolt = <600000>;
+        regulator-max-microvolt = <1725000>;
+        regulator-boot-on;
+        richtek,watchdog-enable;
+      };
+    };
diff --git a/Documentation/devicetree/bindings/regulator/siliconmitus,sm5703-regulator.yaml b/Documentation/devicetree/bindings/regulator/siliconmitus,sm5703-regulator.yaml
new file mode 100644 (file)
index 0000000..9d84117
--- /dev/null
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/siliconmitus,sm5703-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Silicon Mitus SM5703 multi function device regulators
+
+maintainers:
+  - Markuss Broks <markuss.broks@gmail.com>
+
+description: |
+  SM5703 regulators node should be a sub node of the SM5703 MFD node. See SM5703 MFD
+  bindings at Documentation/devicetree/bindings/mfd/siliconmitus,sm5703.yaml
+  Regulator nodes should be named as USBLDO_<number>, BUCK, VBUS, LDO_<number>.
+  The definition for each of these nodes is defined using the standard
+  binding for regulators at Documentation/devicetree/bindings/regulator/regulator.txt.
+
+properties:
+  buck:
+    type: object
+    $ref: regulator.yaml#
+    unevaluatedProperties: false
+    description:
+      Properties for the BUCK regulator.
+
+  vbus:
+    type: object
+    $ref: regulator.yaml#
+    unevaluatedProperties: false
+    description:
+      Properties for the VBUS regulator.
+
+patternProperties:
+  "^ldo[1-3]$":
+    type: object
+    $ref: regulator.yaml#
+    unevaluatedProperties: false
+    description:
+      Properties for single LDO regulator.
+
+  "^usbldo[1-2]$":
+    type: object
+    $ref: regulator.yaml#
+    unevaluatedProperties: false
+    description:
+      Properties for a single USBLDO regulator.
+
+additionalProperties: false
index 1218f21..75087c6 100644 (file)
@@ -14,9 +14,6 @@ description: |
 maintainers:
   - Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
 
-allOf:
-  - $ref: "regulator.yaml#"
-
 # USB3 Controller
 
 properties:
@@ -36,27 +33,51 @@ properties:
     minItems: 1
     maxItems: 2
 
-  clock-names:
-    oneOf:
-      - items:          # for Pro4, Pro5
-          - const: gio
-          - const: link
-      - items:          # for others
-          - const: link
+  clock-names: true
 
   resets:
     minItems: 1
     maxItems: 2
 
-  reset-names:
-    oneOf:
-      - items:          # for Pro4, Pro5
-          - const: gio
-          - const: link
-      - items:
-          - const: link
+  reset-names: true
 
-additionalProperties: false
+allOf:
+  - $ref: "regulator.yaml#"
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - socionext,uniphier-pro4-usb3-regulator
+              - socionext,uniphier-pro5-usb3-regulator
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: gio
+            - const: link
+        resets:
+          minItems: 2
+          maxItems: 2
+        reset-names:
+          items:
+            - const: gio
+            - const: link
+    else:
+      properties:
+        clocks:
+          maxItems: 1
+        clock-names:
+          const: link
+        resets:
+          maxItems: 1
+        reset-names:
+          const: link
+
+unevaluatedProperties: false
 
 required:
   - compatible
index 5ef2306..cbe0f96 100644 (file)
@@ -1057,6 +1057,16 @@ config REGULATOR_RT5190A
          buck converters, 1 LDO, mute AC OFF depop function, with the general
          I2C control interface.
 
+config REGULATOR_RT5759
+       tristate "Richtek RT5759 Regulator"
+       depends on I2C
+       select REGMAP_I2C
+       help
+         This adds support for voltage regulator in Richtek RT5759.
+         The RT5759 is a high-performance, synchronous step-down DC-DC
+         converter that can deliver up to 9A output current from 3V to 6.5V
+         input supply.
+
 config REGULATOR_RT6160
        tristate "Richtek RT6160 BuckBoost voltage regulator"
        depends on I2C
@@ -1157,6 +1167,13 @@ config REGULATOR_SLG51000
          The SLG51000 is seven compact and customizable low dropout
          regulators.
 
+config REGULATOR_SM5703
+       tristate "Silicon Mitus SM5703 regulators"
+       depends on MFD_SM5703
+       help
+         This driver provides support for voltage regulators of SM5703
+         multi-function device.
+
 config REGULATOR_STM32_BOOSTER
        tristate "STMicroelectronics STM32 BOOSTER"
        depends on ARCH_STM32 || COMPILE_TEST
index 1b64ad5..8d3ee8b 100644 (file)
@@ -127,6 +127,7 @@ obj-$(CONFIG_REGULATOR_RT4801)      += rt4801-regulator.o
 obj-$(CONFIG_REGULATOR_RT4831) += rt4831-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_RT5190A) += rt5190a-regulator.o
+obj-$(CONFIG_REGULATOR_RT5759) += rt5759-regulator.o
 obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o
 obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o
 obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
@@ -138,6 +139,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
 obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o
+obj-$(CONFIG_REGULATOR_SM5703) += sm5703-regulator.o
 obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o
 obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
 obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
index c4d844f..1e54a83 100644 (file)
@@ -83,6 +83,7 @@ struct regulator_supply_alias {
 
 static int _regulator_is_enabled(struct regulator_dev *rdev);
 static int _regulator_disable(struct regulator *regulator);
+static int _regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags);
 static int _regulator_get_current_limit(struct regulator_dev *rdev);
 static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
 static int _notifier_call_chain(struct regulator_dev *rdev,
@@ -911,6 +912,30 @@ static ssize_t bypass_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(bypass);
 
+#define REGULATOR_ERROR_ATTR(name, bit)                                                        \
+       static ssize_t name##_show(struct device *dev, struct device_attribute *attr,   \
+                                  char *buf)                                           \
+       {                                                                               \
+               int ret;                                                                \
+               unsigned int flags;                                                     \
+               struct regulator_dev *rdev = dev_get_drvdata(dev);                      \
+               ret = _regulator_get_error_flags(rdev, &flags);                         \
+               if (ret)                                                                \
+                       return ret;                                                     \
+               return sysfs_emit(buf, "%d\n", !!(flags & (bit)));                      \
+       }                                                                               \
+       static DEVICE_ATTR_RO(name)
+
+REGULATOR_ERROR_ATTR(under_voltage, REGULATOR_ERROR_UNDER_VOLTAGE);
+REGULATOR_ERROR_ATTR(over_current, REGULATOR_ERROR_OVER_CURRENT);
+REGULATOR_ERROR_ATTR(regulation_out, REGULATOR_ERROR_REGULATION_OUT);
+REGULATOR_ERROR_ATTR(fail, REGULATOR_ERROR_FAIL);
+REGULATOR_ERROR_ATTR(over_temp, REGULATOR_ERROR_OVER_TEMP);
+REGULATOR_ERROR_ATTR(under_voltage_warn, REGULATOR_ERROR_UNDER_VOLTAGE_WARN);
+REGULATOR_ERROR_ATTR(over_current_warn, REGULATOR_ERROR_OVER_CURRENT_WARN);
+REGULATOR_ERROR_ATTR(over_voltage_warn, REGULATOR_ERROR_OVER_VOLTAGE_WARN);
+REGULATOR_ERROR_ATTR(over_temp_warn, REGULATOR_ERROR_OVER_TEMP_WARN);
+
 /* Calculate the new optimum regulator operating mode based on the new total
  * consumer load. All locks held by caller
  */
@@ -1522,6 +1547,24 @@ static int set_machine_constraints(struct regulator_dev *rdev)
                }
        }
 
+       /*
+        * If there is no mechanism for controlling the regulator then
+        * flag it as always_on so we don't end up duplicating checks
+        * for this so much.  Note that we could control the state of
+        * a supply to control the output on a regulator that has no
+        * direct control.
+        */
+       if (!rdev->ena_pin && !ops->enable) {
+               if (rdev->supply_name && !rdev->supply)
+                       return -EPROBE_DEFER;
+
+               if (rdev->supply)
+                       rdev->constraints->always_on =
+                               rdev->supply->rdev->constraints->always_on;
+               else
+                       rdev->constraints->always_on = true;
+       }
+
        /* If the constraints say the regulator should be on at this point
         * and we have control then make sure it is enabled.
         */
@@ -2514,17 +2557,17 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
 }
 
 /**
- * _regulator_enable_delay - a delay helper function
+ * _regulator_delay_helper - a delay helper function
  * @delay: time to delay in microseconds
  *
  * Delay for the requested amount of time as per the guidelines in:
  *
  *     Documentation/timers/timers-howto.rst
  *
- * The assumption here is that regulators will never be enabled in
+ * The assumption here is that these regulator operations will never used in
  * atomic context and therefore sleeping functions can be used.
  */
-static void _regulator_enable_delay(unsigned int delay)
+static void _regulator_delay_helper(unsigned int delay)
 {
        unsigned int ms = delay / 1000;
        unsigned int us = delay % 1000;
@@ -2606,7 +2649,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
                s64 remaining = ktime_us_delta(end, ktime_get());
 
                if (remaining > 0)
-                       _regulator_enable_delay(remaining);
+                       _regulator_delay_helper(remaining);
        }
 
        if (rdev->ena_pin) {
@@ -2633,14 +2676,14 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
        /* If poll_enabled_time is set, poll upto the delay calculated
         * above, delaying poll_enabled_time uS to check if the regulator
         * actually got enabled.
-        * If the regulator isn't enabled after enable_delay has
-        * expired, return -ETIMEDOUT.
+        * If the regulator isn't enabled after our delay helper has expired,
+        * return -ETIMEDOUT.
         */
        if (rdev->desc->poll_enabled_time) {
                unsigned int time_remaining = delay;
 
                while (time_remaining > 0) {
-                       _regulator_enable_delay(rdev->desc->poll_enabled_time);
+                       _regulator_delay_helper(rdev->desc->poll_enabled_time);
 
                        if (rdev->desc->ops->get_status) {
                                ret = _regulator_check_status_enabled(rdev);
@@ -2659,7 +2702,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
                        return -ETIMEDOUT;
                }
        } else {
-               _regulator_enable_delay(delay);
+               _regulator_delay_helper(delay);
        }
 
        trace_regulator_enable_complete(rdev_get_name(rdev));
@@ -3551,12 +3594,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
        }
 
        /* Insert any necessary delays */
-       if (delay >= 1000) {
-               mdelay(delay / 1000);
-               udelay(delay % 1000);
-       } else if (delay) {
-               udelay(delay);
-       }
+       _regulator_delay_helper(delay);
 
        if (best_val >= 0) {
                unsigned long data = best_val;
@@ -4974,6 +5012,15 @@ static struct attribute *regulator_dev_attrs[] = {
        &dev_attr_max_microvolts.attr,
        &dev_attr_min_microamps.attr,
        &dev_attr_max_microamps.attr,
+       &dev_attr_under_voltage.attr,
+       &dev_attr_over_current.attr,
+       &dev_attr_regulation_out.attr,
+       &dev_attr_fail.attr,
+       &dev_attr_over_temp.attr,
+       &dev_attr_under_voltage_warn.attr,
+       &dev_attr_over_current_warn.attr,
+       &dev_attr_over_voltage_warn.attr,
+       &dev_attr_over_temp_warn.attr,
        &dev_attr_suspend_standby_state.attr,
        &dev_attr_suspend_mem_state.attr,
        &dev_attr_suspend_disk_state.attr,
@@ -5029,6 +5076,17 @@ static umode_t regulator_attr_is_visible(struct kobject *kobj,
        if (attr == &dev_attr_bypass.attr)
                return ops->get_bypass ? mode : 0;
 
+       if (attr == &dev_attr_under_voltage.attr ||
+           attr == &dev_attr_over_current.attr ||
+           attr == &dev_attr_regulation_out.attr ||
+           attr == &dev_attr_fail.attr ||
+           attr == &dev_attr_over_temp.attr ||
+           attr == &dev_attr_under_voltage_warn.attr ||
+           attr == &dev_attr_over_current_warn.attr ||
+           attr == &dev_attr_over_voltage_warn.attr ||
+           attr == &dev_attr_over_temp_warn.attr)
+               return ops->get_error_flags ? mode : 0;
+
        /* constraints need specific supporting methods */
        if (attr == &dev_attr_min_microvolts.attr ||
            attr == &dev_attr_max_microvolts.attr)
index eb9df48..76e0e23 100644 (file)
@@ -1030,6 +1030,8 @@ static int da9121_assign_chip_model(struct i2c_client *i2c,
                chip->variant_id = DA9121_TYPE_DA9142;
                regmap = &da9121_2ch_regmap_config;
                break;
+       default:
+               return -EINVAL;
        }
 
        /* Set these up for of_regulator_match call which may want .of_map_modes */
index 599ad20..2a9867a 100644 (file)
@@ -236,11 +236,8 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
                drvdata->desc.supply_name = devm_kstrdup(&pdev->dev,
                                            config->input_supply,
                                            GFP_KERNEL);
-               if (!drvdata->desc.supply_name) {
-                       dev_err(&pdev->dev,
-                               "Failed to allocate input supply\n");
+               if (!drvdata->desc.supply_name)
                        return -ENOMEM;
-               }
        }
 
        if (config->microvolts)
index eb80278..8a5ce99 100644 (file)
@@ -130,6 +130,102 @@ struct mt6358_regulator_info {
        .qi = BIT(15),                                                  \
 }
 
+#define MT6366_BUCK(match, vreg, min, max, step,               \
+       volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask,   \
+       _modeset_reg, _modeset_shift)           \
+[MT6366_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_range_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6366_ID_##vreg,         \
+               .owner = THIS_MODULE,           \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+               .linear_ranges = volt_ranges,           \
+               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .vsel_reg = MT6358_BUCK_##vreg##_ELR0,  \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_BUCK_##vreg##_CON0,        \
+               .enable_mask = BIT(0),  \
+               .of_map_mode = mt6358_map_mode, \
+       },      \
+       .status_reg = MT6358_BUCK_##vreg##_DBG1,        \
+       .qi = BIT(0),   \
+       .da_vsel_reg = _da_vsel_reg,    \
+       .da_vsel_mask = _da_vsel_mask,  \
+       .modeset_reg = _modeset_reg,    \
+       .modeset_mask = BIT(_modeset_shift),    \
+}
+
+#define MT6366_LDO(match, vreg, ldo_volt_table,        \
+       ldo_index_table, enreg, enbit, vosel,   \
+       vosel_mask)     \
+[MT6366_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_table_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6366_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = ARRAY_SIZE(ldo_volt_table),       \
+               .volt_table = ldo_volt_table,   \
+               .vsel_reg = vosel,      \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = enreg,    \
+               .enable_mask = BIT(enbit),      \
+       },      \
+       .status_reg = MT6358_LDO_##vreg##_CON1, \
+       .qi = BIT(15),  \
+       .index_table = ldo_index_table, \
+       .n_table = ARRAY_SIZE(ldo_index_table), \
+}
+
+#define MT6366_LDO1(match, vreg, min, max, step,       \
+       volt_ranges, _da_vsel_reg, _da_vsel_mask,       \
+       vosel, vosel_mask)      \
+[MT6366_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_range_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6366_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+               .linear_ranges = volt_ranges,   \
+               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .vsel_reg = vosel,      \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_LDO_##vreg##_CON0, \
+               .enable_mask = BIT(0),  \
+       },      \
+       .da_vsel_reg = _da_vsel_reg,    \
+       .da_vsel_mask = _da_vsel_mask,  \
+       .status_reg = MT6358_LDO_##vreg##_DBG1, \
+       .qi = BIT(0),   \
+}
+
+#define MT6366_REG_FIXED(match, vreg,  \
+       enreg, enbit, volt)     \
+[MT6366_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_fixed_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6366_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = 1,        \
+               .enable_reg = enreg,    \
+               .enable_mask = BIT(enbit),      \
+               .min_uV = volt, \
+       },      \
+       .status_reg = MT6358_LDO_##vreg##_CON1, \
+       .qi = BIT(15),                                                  \
+}
+
 static const struct linear_range buck_volt_range1[] = {
        REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
 };
@@ -409,6 +505,9 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
        MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
                    buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
                    MT6358_VCORE_VGPU_ANA_CON0, 1),
+       MT6358_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
+                   MT6358_VCORE_VGPU_ANA_CON0, 1),
        MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
                    buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
                    MT6358_VPA_ANA_CON0, 3),
@@ -488,6 +587,10 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
        MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
                    buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
                    MT6358_LDO_VSRAM_CON2, 0x7f),
+       MT6358_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
+                   1293750, 6250, buck_volt_range1,
+                   MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
+                   MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
        MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
                    buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
                    MT6358_LDO_VSRAM_CON3, 0x7f),
@@ -496,24 +599,124 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
                    MT6358_LDO_VSRAM_CON1, 0x7f),
 };
 
+/* The array is indexed by id(MT6366_ID_XXX) */
+static struct mt6358_regulator_info mt6366_regulators[] = {
+       MT6366_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
+                   buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
+                   MT6358_VDRAM1_ANA_CON0, 8),
+       MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
+                   MT6358_VCORE_VGPU_ANA_CON0, 1),
+       MT6366_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
+                   MT6358_VCORE_VGPU_ANA_CON0, 1),
+       MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
+                   buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
+                   MT6358_VPA_ANA_CON0, 3),
+       MT6366_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
+                   MT6358_VPROC_ANA_CON0, 1),
+       MT6366_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
+                   MT6358_VPROC_ANA_CON0, 2),
+       MT6366_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f,
+                   MT6358_VCORE_VGPU_ANA_CON0, 2),
+       MT6366_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
+                   buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f,
+                   MT6358_VS2_ANA_CON0, 8),
+       MT6366_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
+                   MT6358_VMODEM_ANA_CON0, 8),
+       MT6366_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
+                   buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f,
+                   MT6358_VS1_ANA_CON0, 8),
+       MT6366_REG_FIXED("ldo_vrf12", VRF12,
+                        MT6358_LDO_VRF12_CON0, 0, 1200000),
+       MT6366_REG_FIXED("ldo_vio18", VIO18,
+                        MT6358_LDO_VIO18_CON0, 0, 1800000),
+       MT6366_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
+       MT6366_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
+       MT6366_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
+       MT6366_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
+       MT6366_REG_FIXED("ldo_vaux18", VAUX18,
+                        MT6358_LDO_VAUX18_CON0, 0, 1800000),
+       MT6366_REG_FIXED("ldo_vbif28", VBIF28,
+                        MT6358_LDO_VBIF28_CON0, 0, 2800000),
+       MT6366_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
+       MT6366_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
+       MT6366_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
+       MT6366_REG_FIXED("ldo_vaud28", VAUD28,
+                        MT6358_LDO_VAUD28_CON0, 0, 2800000),
+       MT6366_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
+                  MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10),
+       MT6366_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
+                  MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00),
+       MT6366_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
+                  MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00),
+       MT6366_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
+                  MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700),
+       MT6366_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
+                  MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00),
+       MT6366_LDO("ldo_vmch", VMCH, vmch_vemc_voltages, vmch_vemc_idx,
+                  MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),
+       MT6366_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
+                  MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
+       MT6366_LDO("ldo_vcn33_bt", VCN33_BT, vcn33_bt_wifi_voltages,
+                  vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_0,
+                  0, MT6358_VCN33_ANA_CON0, 0x300),
+       MT6366_LDO("ldo_vcn33_wifi", VCN33_WIFI, vcn33_bt_wifi_voltages,
+                  vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_1,
+                  0, MT6358_VCN33_ANA_CON0, 0x300),
+       MT6366_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
+                  MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),
+       MT6366_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
+                  MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
+       MT6366_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00,
+                   MT6358_LDO_VSRAM_CON0, 0x7f),
+       MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
+                   MT6358_LDO_VSRAM_CON2, 0x7f),
+       MT6366_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
+                   1293750, 6250, buck_volt_range1,
+                   MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
+                   MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
+       MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
+                   MT6358_LDO_VSRAM_CON3, 0x7f),
+       MT6366_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00,
+                   MT6358_LDO_VSRAM_CON1, 0x7f),
+};
+
 static int mt6358_regulator_probe(struct platform_device *pdev)
 {
        struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
        struct regulator_config config = {};
        struct regulator_dev *rdev;
-       int i;
+       struct mt6358_regulator_info *mt6358_info;
+       int i, max_regulator;
+
+       if (mt6397->chip_id == MT6366_CHIP_ID) {
+               max_regulator = MT6366_MAX_REGULATOR;
+               mt6358_info = mt6366_regulators;
+       } else {
+               max_regulator = MT6358_MAX_REGULATOR;
+               mt6358_info = mt6358_regulators;
+       }
 
-       for (i = 0; i < MT6358_MAX_REGULATOR; i++) {
+       for (i = 0; i < max_regulator; i++) {
                config.dev = &pdev->dev;
-               config.driver_data = &mt6358_regulators[i];
+               config.driver_data = &mt6358_info[i];
                config.regmap = mt6397->regmap;
 
                rdev = devm_regulator_register(&pdev->dev,
-                                              &mt6358_regulators[i].desc,
+                                              &mt6358_info[i].desc,
                                               &config);
                if (IS_ERR(rdev)) {
                        dev_err(&pdev->dev, "failed to register %s\n",
-                               mt6358_regulators[i].desc.name);
+                               mt6358_info[i].desc.name);
                        return PTR_ERR(rdev);
                }
        }
index 64e5f5f..14b7d33 100644 (file)
@@ -174,6 +174,14 @@ static int buck_set_dvs(const struct regulator_desc *desc,
                }
        }
 
+       if (ret == 0) {
+               struct pca9450_regulator_desc *regulator = container_of(desc,
+                                       struct pca9450_regulator_desc, desc);
+
+               /* Enable DVS control through PMIC_STBY_REQ for this BUCK */
+               ret = regmap_update_bits(regmap, regulator->desc.enable_reg,
+                                        BUCK1_DVS_CTRL, BUCK1_DVS_CTRL);
+       }
        return ret;
 }
 
@@ -702,6 +710,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,
        struct regulator_config config = { };
        struct pca9450 *pca9450;
        unsigned int device_id, i;
+       unsigned int reset_ctrl;
        int ret;
 
        if (!i2c->irq) {
@@ -802,14 +811,30 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
+       if (of_property_read_bool(i2c->dev.of_node, "nxp,wdog_b-warm-reset"))
+               reset_ctrl = WDOG_B_CFG_WARM;
+       else
+               reset_ctrl = WDOG_B_CFG_COLD_LDO12;
+
        /* Set reset behavior on assertion of WDOG_B signal */
        ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
-                               WDOG_B_CFG_MASK, WDOG_B_CFG_COLD_LDO12);
+                                WDOG_B_CFG_MASK, reset_ctrl);
        if (ret) {
                dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");
                return ret;
        }
 
+       if (of_property_read_bool(i2c->dev.of_node, "nxp,i2c-lt-enable")) {
+               /* Enable I2C Level Translator */
+               ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_CONFIG2,
+                                        I2C_LT_MASK, I2C_LT_ON_STANDBY_RUN);
+               if (ret) {
+                       dev_err(&i2c->dev,
+                               "Failed to enable I2C level translator\n");
+                       return ret;
+               }
+       }
+
        /*
         * The driver uses the LDO5CTRL_H register to control the LDO5 regulator.
         * This is only valid if the SD_VSEL input of the PMIC is high. Let's
index d60d7d1..aa55cfc 100644 (file)
@@ -521,6 +521,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
        parent = of_get_child_by_name(np, "regulators");
        if (!parent) {
                dev_err(dev, "regulators node not found\n");
+               of_node_put(np);
                return -EINVAL;
        }
 
@@ -550,6 +551,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
        }
 
        of_node_put(parent);
+       of_node_put(np);
        if (ret < 0) {
                dev_err(dev, "Error parsing regulator init data: %d\n",
                        ret);
index f7df0f4..fa8706a 100644 (file)
@@ -364,7 +364,6 @@ static int attiny_i2c_probe(struct i2c_client *i2c,
        state->gc.parent = &i2c->dev;
        state->gc.label = i2c->name;
        state->gc.owner = THIS_MODULE;
-       state->gc.of_node = i2c->dev.of_node;
        state->gc.base = -1;
        state->gc.ngpio = NUM_GPIO;
 
index 7a87788..563d791 100644 (file)
 
 struct rt4801_priv {
        struct device *dev;
-       struct gpio_descs *enable_gpios;
+       struct gpio_desc *enable_gpios[DSV_OUT_MAX];
        unsigned int enable_flag;
        unsigned int volt_sel[DSV_OUT_MAX];
 };
 
+static int rt4801_of_parse_cb(struct device_node *np,
+                             const struct regulator_desc *desc,
+                             struct regulator_config *config)
+{
+       struct rt4801_priv *priv = config->driver_data;
+       int id = desc->id;
+
+       if (priv->enable_gpios[id]) {
+               dev_warn(priv->dev, "duplicated enable-gpios property\n");
+               return 0;
+       }
+       priv->enable_gpios[id] = devm_fwnode_gpiod_get_index(priv->dev,
+                                                            of_fwnode_handle(np),
+                                                            "enable", 0,
+                                                            GPIOD_OUT_HIGH,
+                                                            "rt4801");
+       if (IS_ERR(priv->enable_gpios[id]))
+               priv->enable_gpios[id] = NULL;
+
+       return 0;
+}
+
 static int rt4801_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector)
 {
        struct rt4801_priv *priv = rdev_get_drvdata(rdev);
@@ -63,15 +85,14 @@ static int rt4801_get_voltage_sel(struct regulator_dev *rdev)
 static int rt4801_enable(struct regulator_dev *rdev)
 {
        struct rt4801_priv *priv = rdev_get_drvdata(rdev);
-       struct gpio_descs *gpios = priv->enable_gpios;
        int id = rdev_get_id(rdev), ret;
 
-       if (!gpios || gpios->ndescs <= id) {
+       if (!priv->enable_gpios[id]) {
                dev_warn(&rdev->dev, "no dedicated gpio can control\n");
                goto bypass_gpio;
        }
 
-       gpiod_set_value(gpios->desc[id], 1);
+       gpiod_set_value(priv->enable_gpios[id], 1);
 
 bypass_gpio:
        ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, priv->volt_sel[id]);
@@ -85,15 +106,14 @@ bypass_gpio:
 static int rt4801_disable(struct regulator_dev *rdev)
 {
        struct rt4801_priv *priv = rdev_get_drvdata(rdev);
-       struct gpio_descs *gpios = priv->enable_gpios;
        int id = rdev_get_id(rdev);
 
-       if (!gpios || gpios->ndescs <= id) {
+       if (!priv->enable_gpios[id]) {
                dev_warn(&rdev->dev, "no dedicated gpio can control\n");
                goto bypass_gpio;
        }
 
-       gpiod_set_value(gpios->desc[id], 0);
+       gpiod_set_value(priv->enable_gpios[id], 0);
 
 bypass_gpio:
        priv->enable_flag &= ~BIT(id);
@@ -122,6 +142,7 @@ static const struct regulator_desc rt4801_regulator_descs[] = {
                .name = "DSVP",
                .ops = &rt4801_regulator_ops,
                .of_match = of_match_ptr("DSVP"),
+               .of_parse_cb = rt4801_of_parse_cb,
                .type = REGULATOR_VOLTAGE,
                .id = DSV_OUT_POS,
                .min_uV = MIN_UV,
@@ -135,6 +156,7 @@ static const struct regulator_desc rt4801_regulator_descs[] = {
                .name = "DSVN",
                .ops = &rt4801_regulator_ops,
                .of_match = of_match_ptr("DSVN"),
+               .of_parse_cb = rt4801_of_parse_cb,
                .type = REGULATOR_VOLTAGE,
                .id = DSV_OUT_NEG,
                .min_uV = MIN_UV,
@@ -172,10 +194,15 @@ static int rt4801_probe(struct i2c_client *i2c)
                return PTR_ERR(regmap);
        }
 
-       priv->enable_gpios = devm_gpiod_get_array_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
-       if (IS_ERR(priv->enable_gpios)) {
-               dev_err(&i2c->dev, "Failed to get gpios\n");
-               return PTR_ERR(priv->enable_gpios);
+       for (i = 0; i < DSV_OUT_MAX; i++) {
+               priv->enable_gpios[i] = devm_gpiod_get_index_optional(&i2c->dev,
+                                                                     "enable",
+                                                                     i,
+                                                                     GPIOD_OUT_HIGH);
+               if (IS_ERR(priv->enable_gpios[i])) {
+                       dev_err(&i2c->dev, "Failed to get gpios\n");
+                       return PTR_ERR(priv->enable_gpios[i]);
+               }
        }
 
        for (i = 0; i < DSV_OUT_MAX; i++) {
diff --git a/drivers/regulator/rt5759-regulator.c b/drivers/regulator/rt5759-regulator.c
new file mode 100644 (file)
index 0000000..6b96899
--- /dev/null
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/bits.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#define RT5759_REG_VENDORINFO  0x00
+#define RT5759_REG_FREQ                0x01
+#define RT5759_REG_VSEL                0x02
+#define RT5759_REG_DCDCCTRL    0x03
+#define RT5759_REG_STATUS      0x04
+#define RT5759_REG_DCDCSET     0x05
+#define RT5759A_REG_WDTEN      0x42
+
+#define RT5759_TSTEP_MASK      GENMASK(3, 2)
+#define RT5759_VSEL_MASK       GENMASK(6, 0)
+#define RT5759_DISCHARGE_MASK  BIT(3)
+#define RT5759_FPWM_MASK       BIT(2)
+#define RT5759_ENABLE_MASK     BIT(1)
+#define RT5759_OT_MASK         BIT(1)
+#define RT5759_UV_MASK         BIT(0)
+#define RT5957_OCLVL_MASK      GENMASK(7, 6)
+#define RT5759_OCLVL_SHIFT     6
+#define RT5957_OTLVL_MASK      GENMASK(5, 4)
+#define RT5759_OTLVL_SHIFT     4
+#define RT5759A_WDTEN_MASK     BIT(1)
+
+#define RT5759_MANUFACTURER_ID 0x82
+/* vsel range 0x00 ~ 0x5A */
+#define RT5759_NUM_VOLTS       91
+#define RT5759_MIN_UV          600000
+#define RT5759_STEP_UV         10000
+#define RT5759A_STEP_UV                12500
+#define RT5759_MINSS_TIMEUS    1500
+
+#define RT5759_PSKIP_MODE      0
+#define RT5759_FPWM_MODE       1
+
+enum {
+       CHIP_TYPE_RT5759 = 0,
+       CHIP_TYPE_RT5759A,
+       CHIP_TYPE_MAX
+};
+
+struct rt5759_priv {
+       struct device *dev;
+       struct regmap *regmap;
+       struct regulator_desc desc;
+       unsigned long chip_type;
+};
+
+static int rt5759_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       struct regmap *regmap = rdev_get_regmap(rdev);
+       unsigned int mode_val;
+
+       switch (mode) {
+       case REGULATOR_MODE_NORMAL:
+               mode_val = 0;
+               break;
+       case REGULATOR_MODE_FAST:
+               mode_val = RT5759_FPWM_MASK;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return regmap_update_bits(regmap, RT5759_REG_STATUS, RT5759_FPWM_MASK,
+                                 mode_val);
+}
+
+static unsigned int rt5759_get_mode(struct regulator_dev *rdev)
+{
+       struct regmap *regmap = rdev_get_regmap(rdev);
+       unsigned int regval;
+       int ret;
+
+       ret = regmap_read(regmap, RT5759_REG_DCDCCTRL, &regval);
+       if (ret)
+               return REGULATOR_MODE_INVALID;
+
+       if (regval & RT5759_FPWM_MASK)
+               return REGULATOR_MODE_FAST;
+
+       return REGULATOR_MODE_NORMAL;
+}
+
+static int rt5759_get_error_flags(struct regulator_dev *rdev,
+                                 unsigned int *flags)
+{
+       struct regmap *regmap = rdev_get_regmap(rdev);
+       unsigned int status, events = 0;
+       int ret;
+
+       ret = regmap_read(regmap, RT5759_REG_STATUS, &status);
+       if (ret)
+               return ret;
+
+       if (status & RT5759_OT_MASK)
+               events |= REGULATOR_ERROR_OVER_TEMP;
+
+       if (status & RT5759_UV_MASK)
+               events |= REGULATOR_ERROR_UNDER_VOLTAGE;
+
+       *flags = events;
+       return 0;
+}
+
+static int rt5759_set_ocp(struct regulator_dev *rdev, int lim_uA, int severity,
+                         bool enable)
+{
+       struct regmap *regmap = rdev_get_regmap(rdev);
+       int ocp_lvl[] = { 9800000, 10800000, 11800000 };
+       unsigned int ocp_regval;
+       int i;
+
+       /* Only support over current protection parameter */
+       if (severity != REGULATOR_SEVERITY_PROT)
+               return 0;
+
+       if (enable) {
+               /* Default ocp level is 10.8A */
+               if (lim_uA == 0)
+                       lim_uA = 10800000;
+
+               for (i = 0; i < ARRAY_SIZE(ocp_lvl); i++) {
+                       if (lim_uA <= ocp_lvl[i])
+                               break;
+               }
+
+               if (i == ARRAY_SIZE(ocp_lvl))
+                       i = ARRAY_SIZE(ocp_lvl) - 1;
+
+               ocp_regval = i + 1;
+       } else
+               ocp_regval = 0;
+
+       return regmap_update_bits(regmap, RT5759_REG_DCDCSET, RT5957_OCLVL_MASK,
+                                 ocp_regval << RT5759_OCLVL_SHIFT);
+}
+
+static int rt5759_set_otp(struct regulator_dev *rdev, int lim, int severity,
+                         bool enable)
+{
+       struct regmap *regmap = rdev_get_regmap(rdev);
+       int otp_lvl[] = { 140, 150, 170 };
+       unsigned int otp_regval;
+       int i;
+
+       /* Only support over temperature protection parameter */
+       if (severity != REGULATOR_SEVERITY_PROT)
+               return 0;
+
+       if (enable) {
+               /* Default otp level is 150'c */
+               if (lim == 0)
+                       lim = 150;
+
+               for (i = 0; i < ARRAY_SIZE(otp_lvl); i++) {
+                       if (lim <= otp_lvl[i])
+                               break;
+               }
+
+               if (i == ARRAY_SIZE(otp_lvl))
+                       i = ARRAY_SIZE(otp_lvl) - 1;
+
+               otp_regval = i + 1;
+       } else
+               otp_regval = 0;
+
+       return regmap_update_bits(regmap, RT5759_REG_DCDCSET, RT5957_OTLVL_MASK,
+                                 otp_regval << RT5759_OTLVL_SHIFT);
+}
+
+static const struct regulator_ops rt5759_regulator_ops = {
+       .list_voltage = regulator_list_voltage_linear,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .set_active_discharge = regulator_set_active_discharge_regmap,
+       .set_mode = rt5759_set_mode,
+       .get_mode = rt5759_get_mode,
+       .set_ramp_delay = regulator_set_ramp_delay_regmap,
+       .get_error_flags = rt5759_get_error_flags,
+       .set_over_current_protection = rt5759_set_ocp,
+       .set_thermal_protection = rt5759_set_otp,
+};
+
+static unsigned int rt5759_of_map_mode(unsigned int mode)
+{
+       switch (mode) {
+       case RT5759_FPWM_MODE:
+               return REGULATOR_MODE_FAST;
+       case RT5759_PSKIP_MODE:
+               return REGULATOR_MODE_NORMAL;
+       default:
+               return REGULATOR_MODE_INVALID;
+       }
+}
+
+static const unsigned int rt5759_ramp_table[] = { 20000, 15000, 10000, 5000 };
+
+static int rt5759_regulator_register(struct rt5759_priv *priv)
+{
+       struct device_node *np = priv->dev->of_node;
+       struct regulator_desc *reg_desc = &priv->desc;
+       struct regulator_config reg_cfg;
+       struct regulator_dev *rdev;
+       int ret;
+
+       reg_desc->name = "rt5759-buck";
+       reg_desc->type = REGULATOR_VOLTAGE;
+       reg_desc->owner = THIS_MODULE;
+       reg_desc->ops = &rt5759_regulator_ops;
+       reg_desc->n_voltages = RT5759_NUM_VOLTS;
+       reg_desc->min_uV = RT5759_MIN_UV;
+       reg_desc->uV_step = RT5759_STEP_UV;
+       reg_desc->vsel_reg = RT5759_REG_VSEL;
+       reg_desc->vsel_mask = RT5759_VSEL_MASK;
+       reg_desc->enable_reg = RT5759_REG_DCDCCTRL;
+       reg_desc->enable_mask = RT5759_ENABLE_MASK;
+       reg_desc->active_discharge_reg = RT5759_REG_DCDCCTRL;
+       reg_desc->active_discharge_mask = RT5759_DISCHARGE_MASK;
+       reg_desc->active_discharge_on = RT5759_DISCHARGE_MASK;
+       reg_desc->ramp_reg = RT5759_REG_FREQ;
+       reg_desc->ramp_mask = RT5759_TSTEP_MASK;
+       reg_desc->ramp_delay_table = rt5759_ramp_table;
+       reg_desc->n_ramp_values = ARRAY_SIZE(rt5759_ramp_table);
+       reg_desc->enable_time = RT5759_MINSS_TIMEUS;
+       reg_desc->of_map_mode = rt5759_of_map_mode;
+
+       /*
+        * RT5759 step uV = 10000
+        * RT5759A step uV = 12500
+        */
+       if (priv->chip_type == CHIP_TYPE_RT5759A)
+               reg_desc->uV_step = RT5759A_STEP_UV;
+
+       reg_cfg.dev = priv->dev;
+       reg_cfg.of_node = np;
+       reg_cfg.init_data = of_get_regulator_init_data(priv->dev, np, reg_desc);
+       reg_cfg.regmap = priv->regmap;
+
+       rdev = devm_regulator_register(priv->dev, reg_desc, &reg_cfg);
+       if (IS_ERR(rdev)) {
+               ret = PTR_ERR(rdev);
+               dev_err(priv->dev, "Failed to register regulator (%d)\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int rt5759_init_device_property(struct rt5759_priv *priv)
+{
+       unsigned int val = 0;
+
+       /*
+        * Only RT5759A support external watchdog input
+        */
+       if (priv->chip_type != CHIP_TYPE_RT5759A)
+               return 0;
+
+       if (device_property_read_bool(priv->dev, "richtek,watchdog-enable"))
+               val = RT5759A_WDTEN_MASK;
+
+       return regmap_update_bits(priv->regmap, RT5759A_REG_WDTEN,
+                                 RT5759A_WDTEN_MASK, val);
+}
+
+static int rt5759_manufacturer_check(struct rt5759_priv *priv)
+{
+       unsigned int vendor;
+       int ret;
+
+       ret = regmap_read(priv->regmap, RT5759_REG_VENDORINFO, &vendor);
+       if (ret)
+               return ret;
+
+       if (vendor != RT5759_MANUFACTURER_ID) {
+               dev_err(priv->dev, "vendor info not correct (%d)\n", vendor);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static bool rt5759_is_accessible_reg(struct device *dev, unsigned int reg)
+{
+       struct rt5759_priv *priv = dev_get_drvdata(dev);
+
+       if (reg <= RT5759_REG_DCDCSET)
+               return true;
+
+       if (priv->chip_type == CHIP_TYPE_RT5759A && reg == RT5759A_REG_WDTEN)
+               return true;
+
+       return false;
+}
+
+static const struct regmap_config rt5759_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = RT5759A_REG_WDTEN,
+       .readable_reg = rt5759_is_accessible_reg,
+       .writeable_reg = rt5759_is_accessible_reg,
+};
+
+static int rt5759_probe(struct i2c_client *i2c)
+{
+       struct rt5759_priv *priv;
+       int ret;
+
+       priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->dev = &i2c->dev;
+       priv->chip_type = (unsigned long)of_device_get_match_data(&i2c->dev);
+       i2c_set_clientdata(i2c, priv);
+
+       priv->regmap = devm_regmap_init_i2c(i2c, &rt5759_regmap_config);
+       if (IS_ERR(priv->regmap)) {
+               ret = PTR_ERR(priv->regmap);
+               dev_err(&i2c->dev, "Failed to allocate regmap (%d)\n", ret);
+               return ret;
+       }
+
+       ret = rt5759_manufacturer_check(priv);
+       if (ret) {
+               dev_err(&i2c->dev, "Failed to check device (%d)\n", ret);
+               return ret;
+       }
+
+       ret = rt5759_init_device_property(priv);
+       if (ret) {
+               dev_err(&i2c->dev, "Failed to init device (%d)\n", ret);
+               return ret;
+       }
+
+       return rt5759_regulator_register(priv);
+}
+
+static const struct of_device_id __maybe_unused rt5759_device_table[] = {
+       { .compatible = "richtek,rt5759", .data = (void *)CHIP_TYPE_RT5759 },
+       { .compatible = "richtek,rt5759a", .data = (void *)CHIP_TYPE_RT5759A },
+       {}
+};
+MODULE_DEVICE_TABLE(of, rt5759_device_table);
+
+static struct i2c_driver rt5759_driver = {
+       .driver = {
+               .name = "rt5759",
+               .of_match_table = of_match_ptr(rt5759_device_table),
+       },
+       .probe_new = rt5759_probe,
+};
+module_i2c_driver(rt5759_driver);
+
+MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
+MODULE_DESCRIPTION("Richtek RT5759 Regulator Driver");
+MODULE_LICENSE("GPL v2");
index 1f02f60..41ae7ac 100644 (file)
@@ -352,7 +352,7 @@ static int scmi_regulator_probe(struct scmi_device *sdev)
                        return ret;
                }
        }
-
+       of_node_put(np);
        /*
         * Register a regulator for each valid regulator-DT-entry that we
         * can successfully reach via SCMI and has a valid associated voltage
diff --git a/drivers/regulator/sm5703-regulator.c b/drivers/regulator/sm5703-regulator.c
new file mode 100644 (file)
index 0000000..05ad28f
--- /dev/null
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/mfd/sm5703.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+enum sm5703_regulators {
+       SM5703_BUCK,
+       SM5703_LDO1,
+       SM5703_LDO2,
+       SM5703_LDO3,
+       SM5703_USBLDO1,
+       SM5703_USBLDO2,
+       SM5703_VBUS,
+       SM5703_MAX_REGULATORS,
+};
+
+static const int sm5703_ldo_voltagemap[] = {
+       1500000, 1800000, 2600000, 2800000, 3000000, 3300000,
+};
+
+static const int sm5703_buck_voltagemap[] = {
+       1000000, 1000000, 1000000, 1000000,
+       1000000, 1000000, 1000000, 1000000,
+       1000000, 1000000, 1000000, 1100000,
+       1200000, 1300000, 1400000, 1500000,
+       1600000, 1700000, 1800000, 1900000,
+       2000000, 2100000, 2200000, 2300000,
+       2400000, 2500000, 2600000, 2700000,
+       2800000, 2900000, 3000000, 3000000,
+};
+
+#define SM5703USBLDO(_name, _id)                                       \
+       [SM5703_USBLDO ## _id] = {                                      \
+               .name = _name,                                          \
+               .of_match = _name,                                      \
+               .regulators_node = "regulators",                        \
+               .type = REGULATOR_VOLTAGE,                              \
+               .id = SM5703_USBLDO ## _id,                             \
+               .ops = &sm5703_regulator_ops_fixed,                     \
+               .fixed_uV = SM5703_USBLDO_MICROVOLT,                    \
+               .enable_reg = SM5703_REG_USBLDO12,                      \
+               .enable_mask = SM5703_REG_EN_USBLDO ##_id,              \
+               .owner                  = THIS_MODULE,                  \
+       }
+
+#define SM5703VBUS(_name)                                              \
+       [SM5703_VBUS] = {                                               \
+               .name = _name,                                          \
+               .of_match = _name,                                      \
+               .regulators_node = "regulators",                        \
+               .type = REGULATOR_VOLTAGE,                              \
+               .id = SM5703_VBUS,                                      \
+               .ops = &sm5703_regulator_ops_fixed,                     \
+               .fixed_uV = SM5703_VBUS_MICROVOLT,                      \
+               .enable_reg = SM5703_REG_CNTL,                          \
+               .enable_mask = SM5703_OPERATION_MODE_MASK,              \
+               .enable_val = SM5703_OPERATION_MODE_USB_OTG_MODE,       \
+               .disable_val = SM5703_OPERATION_MODE_CHARGING_ON,       \
+               .owner                  = THIS_MODULE,                  \
+       }
+
+#define SM5703BUCK(_name)                                              \
+       [SM5703_BUCK] = {                                               \
+               .name = _name,                                          \
+               .of_match = _name,                                      \
+               .regulators_node = "regulators",                        \
+               .type = REGULATOR_VOLTAGE,                              \
+               .id = SM5703_BUCK,                                      \
+               .ops = &sm5703_regulator_ops,                           \
+               .n_voltages = ARRAY_SIZE(sm5703_buck_voltagemap),       \
+               .volt_table = sm5703_buck_voltagemap,                   \
+               .vsel_reg = SM5703_REG_BUCK,                            \
+               .vsel_mask = SM5703_BUCK_VOLT_MASK,                     \
+               .enable_reg = SM5703_REG_BUCK,                          \
+               .enable_mask = SM5703_REG_EN_BUCK,                      \
+               .owner                  = THIS_MODULE,                  \
+       }
+
+#define SM5703LDO(_name, _id)                                          \
+       [SM5703_LDO ## _id] = {                                         \
+               .name = _name,                                          \
+               .of_match = _name,                                      \
+               .regulators_node = "regulators",                        \
+               .type = REGULATOR_VOLTAGE,                              \
+               .id = SM5703_LDO ## _id,                                \
+               .ops = &sm5703_regulator_ops,                           \
+               .n_voltages = ARRAY_SIZE(sm5703_ldo_voltagemap),        \
+               .volt_table = sm5703_ldo_voltagemap,                    \
+               .vsel_reg = SM5703_REG_LDO ##_id,                       \
+               .vsel_mask = SM5703_LDO_VOLT_MASK,                      \
+               .enable_reg = SM5703_REG_LDO ##_id,                     \
+               .enable_mask = SM5703_LDO_EN,                           \
+               .owner                  = THIS_MODULE,                  \
+       }
+
+static const struct regulator_ops sm5703_regulator_ops = {
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .list_voltage           = regulator_list_voltage_table,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+};
+
+static const struct regulator_ops sm5703_regulator_ops_fixed = {
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .is_enabled             = regulator_is_enabled_regmap,
+};
+
+static struct regulator_desc sm5703_regulators_desc[SM5703_MAX_REGULATORS] = {
+       SM5703BUCK("buck"),
+       SM5703LDO("ldo1", 1),
+       SM5703LDO("ldo2", 2),
+       SM5703LDO("ldo3", 3),
+       SM5703USBLDO("usbldo1", 1),
+       SM5703USBLDO("usbldo2", 2),
+       SM5703VBUS("vbus"),
+};
+
+static int sm5703_regulator_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct regulator_config config = { NULL, };
+       struct regulator_dev *rdev;
+       struct sm5703_dev *sm5703 = dev_get_drvdata(pdev->dev.parent);
+       int i;
+
+       config.dev = dev->parent;
+       config.regmap = sm5703->regmap;
+
+       for (i = 0; i < SM5703_MAX_REGULATORS; i++) {
+               rdev = devm_regulator_register(dev,
+                                              &sm5703_regulators_desc[i],
+                                              &config);
+               if (IS_ERR(rdev))
+                       return dev_err_probe(dev, PTR_ERR(rdev),
+                                            "Failed to register a regulator\n");
+       }
+
+       return 0;
+}
+
+static const struct platform_device_id sm5703_regulator_id[] = {
+       { "sm5703-regulator", 0 },
+       {}
+};
+MODULE_DEVICE_TABLE(platform, sm5703_regulator_id);
+
+static struct platform_driver sm5703_regulator_driver = {
+       .driver = {
+               .name = "sm5703-regulator",
+       },
+       .probe  = sm5703_regulator_probe,
+       .id_table       = sm5703_regulator_id,
+};
+
+module_platform_driver(sm5703_regulator_driver);
+
+MODULE_DESCRIPTION("Silicon Mitus SM5703 LDO/Buck/USB regulator driver");
+MODULE_AUTHOR("Markuss Broks <markuss.broks@gmail.com>");
+MODULE_LICENSE("GPL");
index 161622e..30ea3bc 100644 (file)
@@ -44,11 +44,9 @@ static int stm32_vrefbuf_enable(struct regulator_dev *rdev)
        u32 val;
        int ret;
 
-       ret = pm_runtime_get_sync(priv->dev);
-       if (ret < 0) {
-               pm_runtime_put_noidle(priv->dev);
+       ret = pm_runtime_resume_and_get(priv->dev);
+       if (ret < 0)
                return ret;
-       }
 
        val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
        val = (val & ~STM32_HIZ) | STM32_ENVR;
@@ -81,11 +79,9 @@ static int stm32_vrefbuf_disable(struct regulator_dev *rdev)
        u32 val;
        int ret;
 
-       ret = pm_runtime_get_sync(priv->dev);
-       if (ret < 0) {
-               pm_runtime_put_noidle(priv->dev);
+       ret = pm_runtime_resume_and_get(priv->dev);
+       if (ret < 0)
                return ret;
-       }
 
        val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
        val &= ~STM32_ENVR;
@@ -102,11 +98,9 @@ static int stm32_vrefbuf_is_enabled(struct regulator_dev *rdev)
        struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
        int ret;
 
-       ret = pm_runtime_get_sync(priv->dev);
-       if (ret < 0) {
-               pm_runtime_put_noidle(priv->dev);
+       ret = pm_runtime_resume_and_get(priv->dev);
+       if (ret < 0)
                return ret;
-       }
 
        ret = readl_relaxed(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR;
 
@@ -123,11 +117,9 @@ static int stm32_vrefbuf_set_voltage_sel(struct regulator_dev *rdev,
        u32 val;
        int ret;
 
-       ret = pm_runtime_get_sync(priv->dev);
-       if (ret < 0) {
-               pm_runtime_put_noidle(priv->dev);
+       ret = pm_runtime_resume_and_get(priv->dev);
+       if (ret < 0)
                return ret;
-       }
 
        val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
        val = (val & ~STM32_VRS) | FIELD_PREP(STM32_VRS, sel);
@@ -145,11 +137,9 @@ static int stm32_vrefbuf_get_voltage_sel(struct regulator_dev *rdev)
        u32 val;
        int ret;
 
-       ret = pm_runtime_get_sync(priv->dev);
-       if (ret < 0) {
-               pm_runtime_put_noidle(priv->dev);
+       ret = pm_runtime_resume_and_get(priv->dev);
+       if (ret < 0)
                return ret;
-       }
 
        val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
        ret = FIELD_GET(STM32_VRS, val);
index 1cc3049..bdcf83c 100644 (file)
@@ -48,9 +48,54 @@ enum {
        MT6358_ID_VLDO28,
        MT6358_ID_VAUD28,
        MT6358_ID_VSIM2,
+       MT6358_ID_VCORE_SSHUB,
+       MT6358_ID_VSRAM_OTHERS_SSHUB,
        MT6358_ID_RG_MAX,
 };
 
+enum {
+       MT6366_ID_VDRAM1 = 0,
+       MT6366_ID_VCORE,
+       MT6366_ID_VPA,
+       MT6366_ID_VPROC11,
+       MT6366_ID_VPROC12,
+       MT6366_ID_VGPU,
+       MT6366_ID_VS2,
+       MT6366_ID_VMODEM,
+       MT6366_ID_VS1,
+       MT6366_ID_VDRAM2,
+       MT6366_ID_VSIM1,
+       MT6366_ID_VIBR,
+       MT6366_ID_VRF12,
+       MT6366_ID_VIO18,
+       MT6366_ID_VUSB,
+       MT6366_ID_VCN18,
+       MT6366_ID_VFE28,
+       MT6366_ID_VSRAM_PROC11,
+       MT6366_ID_VCN28,
+       MT6366_ID_VSRAM_OTHERS,
+       MT6366_ID_VSRAM_GPU,
+       MT6366_ID_VXO22,
+       MT6366_ID_VEFUSE,
+       MT6366_ID_VAUX18,
+       MT6366_ID_VMCH,
+       MT6366_ID_VBIF28,
+       MT6366_ID_VSRAM_PROC12,
+       MT6366_ID_VEMC,
+       MT6366_ID_VIO28,
+       MT6366_ID_VA12,
+       MT6366_ID_VRF18,
+       MT6366_ID_VCN33_BT,
+       MT6366_ID_VCN33_WIFI,
+       MT6366_ID_VMC,
+       MT6366_ID_VAUD28,
+       MT6366_ID_VSIM2,
+       MT6366_ID_VCORE_SSHUB,
+       MT6366_ID_VSRAM_OTHERS_SSHUB,
+       MT6366_ID_RG_MAX,
+};
+
 #define MT6358_MAX_REGULATOR   MT6358_ID_RG_MAX
+#define MT6366_MAX_REGULATOR   MT6366_ID_RG_MAX
 
 #endif /* __LINUX_REGULATOR_MT6358_H */
index 71902f4..3c01c2b 100644 (file)
@@ -226,4 +226,11 @@ enum {
 #define WDOG_B_CFG_COLD_LDO12          0x80
 #define WDOG_B_CFG_COLD                        0xC0
 
+/* PCA9450_REG_CONFIG2 bits */
+#define I2C_LT_MASK                    0x03
+#define I2C_LT_FORCE_DISABLE           0x00
+#define I2C_LT_ON_STANDBY_RUN          0x01
+#define I2C_LT_ON_RUN                  0x02
+#define I2C_LT_FORCE_ENABLE            0x03
+
 #endif /* __LINUX_REG_PCA9450_H__ */