Merge tag 'regulator-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Aug 2023 16:40:16 +0000 (09:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Aug 2023 16:40:16 +0000 (09:40 -0700)
Pull regulator updates from Mark Brown:
 "Other than new device support and some minor fixes this has been a
  really quiet release, the only notable things are the new drivers.

  There's a couple of MFDs among the new devices so the generic parts
  are pulled in:

   - Support for Analog Devices MAX77831/57/59, Awinc AW37503, Qualcom
     PMX75 and RFGEN, RealTek RT5733, RichTek RTQ2208 and Texas
     Instruments TPS65086"

* tag 'regulator-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (68 commits)
  regulator: userspace-consumer: Drop event support for this cycle
  regulator: aw37503: Switch back to use struct i2c_driver's .probe()
  dt-bindings: regulator: qcom,rpmh-regulator: allow i, j, l, m & n as RPMh resource name suffix
  regulator: dt-bindings: Add Awinic AW37503
  regulator: aw37503: add regulator driver for Awinic AW37503
  regulator: tps65086: Select dedicated regulator config for chip variant
  mfd: tps65086: Read DEVICE ID register 1 from device
  regulator: raa215300: Update help description
  regulator: raa215300: Add missing blank space
  regulator: raa215300: Change rate from 32000->32768
  regulator: db8500-prcmu: Remove unused declaration power_state_active_is_enabled()
  regulator: raa215300: Add const definition
  regulator: raa215300: Fix resource leak in case of error
  regulator: rtq2208: Switch back to use struct i2c_driver's .probe()
  regulator: lp872x: Fix Wvoid-pointer-to-enum-cast warning
  regulator: max77857: Fix Wvoid-pointer-to-enum-cast warning
  regulator: ltc3589: Fix Wvoid-pointer-to-enum-cast warning
  regulator: qcom_rpm-regulator: Use devm_kmemdup to replace devm_kmalloc + memcpy
  regulator: tps6286x-regulator: Remove redundant of_match_ptr() macros
  regulator: pfuze100-regulator: Remove redundant of_match_ptr() macro
  ...

94 files changed:
Documentation/devicetree/bindings/regulator/active-semi,act8846.yaml
Documentation/devicetree/bindings/regulator/adi,max77857.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/awinic,aw37503.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/dlg,da9121.yaml
Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/mps,mp5416.yaml
Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml
Documentation/devicetree/bindings/regulator/pfuze100.yaml
Documentation/devicetree/bindings/regulator/qcom,rpm-regulator.yaml
Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml
Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml
Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml
Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml
Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/richtek,rtq6752-regulator.yaml
Documentation/devicetree/bindings/regulator/slg51000.txt [deleted file]
Documentation/devicetree/bindings/regulator/st,stm32mp1-pwr-reg.yaml
Documentation/devicetree/bindings/regulator/wlf,arizona.yaml
MAINTAINERS
drivers/mfd/tps65086.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/act8945a-regulator.c
drivers/regulator/atc260x-regulator.c
drivers/regulator/aw37503-regulator.c [new file with mode: 0644]
drivers/regulator/axp20x-regulator.c
drivers/regulator/bd71815-regulator.c
drivers/regulator/bd71828-regulator.c
drivers/regulator/bd718x7-regulator.c
drivers/regulator/cpcap-regulator.c
drivers/regulator/da9062-regulator.c
drivers/regulator/da9121-regulator.c
drivers/regulator/fan53555.c
drivers/regulator/fixed.c
drivers/regulator/helpers.c
drivers/regulator/hi6421-regulator.c
drivers/regulator/lp872x.c
drivers/regulator/lp8755.c
drivers/regulator/lp87565-regulator.c
drivers/regulator/ltc3589.c
drivers/regulator/max20086-regulator.c
drivers/regulator/max5970-regulator.c [moved from drivers/regulator/max597x-regulator.c with 94% similarity]
drivers/regulator/max77541-regulator.c
drivers/regulator/max77650-regulator.c
drivers/regulator/max77826-regulator.c
drivers/regulator/max77857-regulator.c [new file with mode: 0644]
drivers/regulator/max8893.c
drivers/regulator/mcp16502.c
drivers/regulator/mp5416.c
drivers/regulator/mp886x.c
drivers/regulator/mpq7920.c
drivers/regulator/mt6311-regulator.c
drivers/regulator/mt6315-regulator.c
drivers/regulator/mt6359-regulator.c
drivers/regulator/mtk-dvfsrc-regulator.c
drivers/regulator/pbias-regulator.c
drivers/regulator/pca9450-regulator.c
drivers/regulator/pfuze100-regulator.c
drivers/regulator/pwm-regulator.c
drivers/regulator/qcom-refgen-regulator.c [new file with mode: 0644]
drivers/regulator/qcom-rpmh-regulator.c
drivers/regulator/qcom_rpm-regulator.c
drivers/regulator/qcom_smd-regulator.c
drivers/regulator/qcom_usb_vbus-regulator.c
drivers/regulator/raa215300.c
drivers/regulator/rc5t583-regulator.c
drivers/regulator/rk808-regulator.c
drivers/regulator/rohm-regulator.c
drivers/regulator/rpi-panel-attiny-regulator.c
drivers/regulator/rt5739.c
drivers/regulator/rt5759-regulator.c
drivers/regulator/rtq2208-regulator.c [new file with mode: 0644]
drivers/regulator/s2mpa01.c
drivers/regulator/stm32-pwr.c
drivers/regulator/stm32-vrefbuf.c
drivers/regulator/sy8824x.c
drivers/regulator/sy8827n.c
drivers/regulator/tps6286x-regulator.c
drivers/regulator/tps6287x-regulator.c
drivers/regulator/tps65086-regulator.c
drivers/regulator/tps65218-regulator.c
drivers/regulator/tps65219-regulator.c
drivers/regulator/tps65910-regulator.c
drivers/regulator/tps6594-regulator.c
drivers/regulator/twl-regulator.c
drivers/regulator/twl6030-regulator.c
drivers/regulator/uniphier-regulator.c
drivers/regulator/vctrl-regulator.c
drivers/regulator/vexpress-regulator.c
include/linux/mfd/tps65086.h
include/linux/regulator/db8500-prcmu.h
include/linux/regulator/driver.h

index 3725348..02f45b5 100644 (file)
@@ -28,75 +28,37 @@ properties:
       the VSEL pin is assumed to be low.
     type: boolean
 
-  regulators:
-    type: object
-    additionalProperties: false
+  inl1-supply:
+    description: Handle to the INL1 input supply (REG5-7)
 
-    properties:
-      REG1:
-        type: object
-        $ref: /schemas/regulator/regulator.yaml#
-        unevaluatedProperties: false
+  inl2-supply:
+    description: Handle to the INL2 input supply (REG8-9)
 
-        properties:
-          vp1-supply:
-            description: Handle to the VP1 input supply
+  inl3-supply:
+    description: Handle to the INL3 input supply (REG10-12)
 
-      REG2:
-        type: object
-        $ref: /schemas/regulator/regulator.yaml#
-        unevaluatedProperties: false
+  vp1-supply:
+    description: Handle to the VP1 input supply (REG1)
 
-        properties:
-          vp2-supply:
-            description: Handle to the VP2 input supply
+  vp2-supply:
+    description: Handle to the VP2 input supply (REG2)
 
-      REG3:
-        type: object
-        $ref: /schemas/regulator/regulator.yaml#
-        unevaluatedProperties: false
+  vp3-supply:
+    description: Handle to the VP3 input supply (REG3)
 
-        properties:
-          vp3-supply:
-            description: Handle to the VP3 input supply
-
-      REG4:
-        type: object
-        $ref: /schemas/regulator/regulator.yaml#
-        unevaluatedProperties: false
+  vp4-supply:
+    description: Handle to the VP4 input supply (REG4)
 
-        properties:
-          vp4-supply:
-            description: Handle to the VP4 input supply
+  regulators:
+    type: object
+    additionalProperties: false
 
     patternProperties:
-      "^REG[5-7]$":
+      "^REG([1-9]|1[0-2])$":
         type: object
         $ref: /schemas/regulator/regulator.yaml#
         unevaluatedProperties: false
 
-        properties:
-          inl1-supply:
-            description: Handle to the INL1 input supply
-
-      "^REG[8-9]$":
-        type: object
-        $ref: /schemas/regulator/regulator.yaml#
-        unevaluatedProperties: false
-
-        properties:
-          inl2-supply:
-            description: Handle to the INL2 input supply
-
-      "^REG1[0-2]$":
-        type: object
-        $ref: /schemas/regulator/regulator.yaml#
-        unevaluatedProperties: false
-
-        properties:
-          inl3-supply:
-            description: Handle to the INL3 input supply
-
 additionalProperties: false
 
 required:
diff --git a/Documentation/devicetree/bindings/regulator/adi,max77857.yaml b/Documentation/devicetree/bindings/regulator/adi,max77857.yaml
new file mode 100644 (file)
index 0000000..d1fa74a
--- /dev/null
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2022 Analog Devices Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/adi,max77857.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices MAX77857 Buck-Boost Converter
+
+maintainers:
+  - Ibrahim Tilki <Ibrahim.Tilki@analog.com>
+  - Okan Sahin <Okan.Sahin@analog.com>
+
+description: Analog Devices MAX77857 Buck-Boost Converter
+
+properties:
+  compatible:
+    enum:
+      - adi,max77831
+      - adi,max77857
+      - adi,max77859
+      - adi,max77859a
+
+  reg:
+    description: I2C address of the device
+    items:
+      - enum: [0x66, 0x67, 0x6E, 0x6F]
+
+  interrupts:
+    maxItems: 1
+
+  adi,switch-frequency-hz:
+    description: Switching frequency of the Buck-Boost converter in Hz.
+    items:
+      - enum: [1200000, 1500000, 1800000, 2100000]
+
+  adi,rtop-ohms:
+    description: Top feedback resistor value in ohms for external feedback.
+    minimum: 150000
+    maximum: 330000
+
+  adi,rbot-ohms:
+    description: Bottom feedback resistor value in ohms for external feedback.
+
+dependencies:
+  adi,rtop-ohms: [ 'adi,rbot-ohms' ]
+  adi,rbot-ohms: [ 'adi,rtop-ohms' ]
+
+required:
+  - compatible
+  - reg
+
+allOf:
+  - $ref: regulator.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - adi,max77831
+
+    then:
+      properties:
+        adi,switch-frequency-hz:
+          items:
+            enum: [1200000, 1500000, 1800000]
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        regulator@66 {
+            reg = <0x66>;
+            compatible = "adi,max77857";
+            interrupt-parent = <&gpio>;
+            interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+
+            adi,rtop-ohms = <312000>;
+            adi,rbot-ohms = <12000>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/regulator/awinic,aw37503.yaml b/Documentation/devicetree/bindings/regulator/awinic,aw37503.yaml
new file mode 100644 (file)
index 0000000..c92a881
--- /dev/null
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/awinic,aw37503.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Awinic AW37503 Voltage Regulator
+
+maintainers:
+  - Alec Li <like@awinic.com>
+
+description:
+  The AW37503 are dual voltage regulator, designed to support positive/negative
+  supply for driving TFT-LCD panels. It support software-configurable output
+  switching and monitoring. The output voltages can be programmed via an I2C
+  compatible interface.
+
+properties:
+  compatible:
+    const: awinic,aw37503
+
+  reg:
+    maxItems: 1
+
+patternProperties:
+  "^out[pn]$":
+    type: object
+    $ref: regulator.yaml#
+    unevaluatedProperties: false
+    description:
+      Properties for single regulator.
+
+    properties:
+      enable-gpios:
+        maxItems: 1
+        description:
+          GPIO specifier to enable the GPIO control (on/off) for regulator.
+
+    required:
+      - regulator-name
+
+required:
+  - compatible
+  - reg
+  - outp
+  - outn
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        regulator@3e {
+            compatible = "awinic,aw37503";
+            reg = <0x3e>;
+
+            outp {
+                regulator-name = "outp";
+                regulator-boot-on;
+                regulator-always-on;
+                enable-gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+            };
+
+            outn {
+                regulator-name = "outn";
+                regulator-boot-on;
+                regulator-always-on;
+                enable-gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
+            };
+        };
+    };
+...
+
index dc62651..13b3f75 100644 (file)
@@ -95,11 +95,6 @@ properties:
           Properties for a single BUCK regulator
 
         properties:
-          regulator-name:
-            pattern: "^BUCK([1-2])$"
-            description: |
-              BUCK2 present in DA9122, DA9220, DA9131, DA9132 only
-
           regulator-initial-mode:
             enum: [ 0, 1, 2, 3 ]
             description: Defined in include/dt-bindings/regulator/dlg,da9121-regulator.h
@@ -122,6 +117,23 @@ required:
   - reg
   - regulators
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              enum:
+                - dlg,da9122
+                - dlg,da9131
+                - dlg,da9132
+                - dlg,da9220
+    then:
+      properties:
+        regulators:
+          properties:
+            buck2: false
+
 additionalProperties: false
 
 examples:
diff --git a/Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml b/Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml
new file mode 100644 (file)
index 0000000..bad1404
--- /dev/null
@@ -0,0 +1,132 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/dlg,slg51000.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Dialog Semiconductor SLG51000 Voltage Regulator
+
+maintainers:
+  - Eric Jeong <eric.jeong.opensource@diasemi.com>
+  - Support Opensource <support.opensource@diasemi.com>
+
+properties:
+  compatible:
+    const: dlg,slg51000
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  dlg,cs-gpios:
+    maxItems: 1
+    description:
+      GPIO for chip select
+
+  vin3-supply:
+    description:
+      Input supply for ldo3, required if regulator is enabled
+
+  vin4-supply:
+    description:
+      Input supply for ldo4, required if regulator is enabled
+
+  vin5-supply:
+    description:
+      Input supply for ldo5, required if regulator is enabled
+
+  vin6-supply:
+    description:
+      Input supply for ldo6, required if regulator is enabled
+
+  vin7-supply:
+    description:
+      Input supply for ldo7, required if regulator is enabled
+
+  regulators:
+    type: object
+    additionalProperties: false
+
+    patternProperties:
+      "^ldo[1-7]$":
+        type: object
+        $ref: /schemas/regulator/regulator.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          enable-gpios:
+            maxItems: 1
+
+        required:
+          - regulator-name
+
+required:
+  - compatible
+  - reg
+  - regulators
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/regulator/dlg,da9121-regulator.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic@75 {
+            compatible = "dlg,slg51000";
+            reg = <0x75>;
+            dlg,cs-gpios = <&tlmm 69 GPIO_ACTIVE_HIGH>;
+            vin5-supply = <&vreg_s1f_1p2>;
+            vin6-supply = <&vreg_s1f_1p2>;
+
+            regulators {
+                ldo1 {
+                    regulator-name = "slg51000_b_ldo1";
+                    regulator-min-microvolt = <2400000>;
+                    regulator-max-microvolt = <3300000>;
+                };
+
+                ldo2 {
+                    regulator-name = "slg51000_b_ldo2";
+                    regulator-min-microvolt = <2400000>;
+                    regulator-max-microvolt = <3300000>;
+                };
+
+                ldo3 {
+                    regulator-name = "slg51000_b_ldo3";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <3750000>;
+                };
+
+                ldo4 {
+                    regulator-name = "slg51000_b_ldo4";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <3750000>;
+                };
+
+                ldo5 {
+                    regulator-name = "slg51000_b_ldo5";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <1200000>;
+                };
+
+                ldo6 {
+                    regulator-name = "slg51000_b_ldo6";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <1200000>;
+                };
+
+                ldo7 {
+                    regulator-name = "slg51000_b_ldo7";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <3750000>;
+                };
+            };
+        };
+    };
index 2e720d1..0221397 100644 (file)
@@ -29,10 +29,12 @@ properties:
     patternProperties:
       "^buck[1-4]$":
         $ref: regulator.yaml#
+        unevaluatedProperties: false
         type: object
 
       "^ldo[1-4]$":
         $ref: regulator.yaml#
+        unevaluatedProperties: false
         type: object
 
     additionalProperties: false
index f3fcfc8..6de5b02 100644 (file)
@@ -21,7 +21,6 @@ properties:
 
   regulators:
     type: object
-    $ref: regulator.yaml#
 
     description: |
       list of regulators provided by this controller, must be named
@@ -39,11 +38,13 @@ properties:
       ldortc:
         type: object
         $ref: regulator.yaml#
+        unevaluatedProperties: false
 
     patternProperties:
       "^ldo[1-4]$":
         type: object
         $ref: regulator.yaml#
+        unevaluatedProperties: false
 
       "^buck[1-4]$":
         type: object
index e384e49..0eda447 100644 (file)
@@ -68,18 +68,22 @@ properties:
       "^sw([1-4]|[1-4][a-c]|[1-4][a-c][a-c])$":
         $ref: regulator.yaml#
         type: object
+        unevaluatedProperties: false
 
       "^vgen[1-6]$":
         $ref: regulator.yaml#
         type: object
+        unevaluatedProperties: false
 
       "^vldo[1-4]$":
         $ref: regulator.yaml#
         type: object
+        unevaluatedProperties: false
 
       "^(vsnvs|vref|vrefddr|swbst|coin|v33|vccsd)$":
         $ref: regulator.yaml#
         type: object
+        unevaluatedProperties: false
 
     additionalProperties: false
 
index 8a08698..b4eb400 100644 (file)
@@ -49,7 +49,7 @@ patternProperties:
   ".*-supply$":
     description: Input supply phandle(s) for this node
 
-  "^((s|l|lvs)[0-9]*)|(s[1-2][a-b])|(ncp)|(mvs)|(usb-switch)|(hdmi-switch)$":
+  "^((s|l|lvs)[0-9]*|s[1-2][a-b]|ncp|mvs|usb-switch|hdmi-switch)$":
     description: List of regulators and its properties
     $ref: regulator.yaml#
     unevaluatedProperties: false
index b949850..127a6f3 100644 (file)
@@ -53,6 +53,7 @@ description: |
       For PMR735A, smps1 - smps3, ldo1 - ldo7
       For PMX55, smps1 - smps7, ldo1 - ldo16
       For PMX65, smps1 - smps8, ldo1 - ldo21
+      For PMX75, smps1 - smps10, ldo1 - ldo21
 
 properties:
   compatible:
@@ -84,13 +85,14 @@ properties:
       - qcom,pmr735a-rpmh-regulators
       - qcom,pmx55-rpmh-regulators
       - qcom,pmx65-rpmh-regulators
+      - qcom,pmx75-rpmh-regulators
 
   qcom,pmic-id:
     description: |
         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, g, h, k]
+    enum: [a, b, c, d, e, f, g, h, i, j, k, l, m, n]
 
   qcom,always-wait-for-ack:
     description: |
@@ -109,6 +111,7 @@ properties:
   bob:
     type: object
     $ref: regulator.yaml#
+    unevaluatedProperties: false
     description: BOB regulator node.
     dependencies:
       regulator-allow-set-load: [ regulator-allowed-modes ]
@@ -117,6 +120,7 @@ patternProperties:
   "^(smps|ldo|lvs|bob)[0-9]+$":
     type: object
     $ref: regulator.yaml#
+    unevaluatedProperties: false
     description: smps/ldo regulator nodes(s).
     dependencies:
       regulator-allow-set-load: [ regulator-allowed-modes ]
@@ -424,10 +428,28 @@ allOf:
         vdd-l11-l13-supply: true
       patternProperties:
         "^vdd-l[1347]-supply$": true
-        "^vdd-l1[0245789]-supply$": true
+        "^vdd-l1[024579]-supply$": true
         "^vdd-l2[01]-supply$": true
         "^vdd-s[1-8]-supply$": true
 
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,pmx75-rpmh-regulators
+    then:
+      properties:
+        vdd-l2-l18-supply: true
+        vdd-l4-l16-supply: true
+        vdd-l5-l6-supply: true
+        vdd-l8-l9-supply: true
+        vdd-l11-l13-supply: true
+        vdd-l20-l21-supply: true
+      patternProperties:
+        "^vdd-l[137]-supply$": true
+        "^vdd-l1[024579]-supply$": true
+        "^vdd-s([1-9]|10)-supply$": true
+
 unevaluatedProperties: false
 
 examples:
diff --git a/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml
new file mode 100644 (file)
index 0000000..f02f97d
--- /dev/null
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/qcom,sdm845-refgen-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. REFGEN Regulator
+
+maintainers:
+  - Konrad Dybcio <konradybcio@kernel.org>
+
+description:
+  The REFGEN (reference voltage generator) regulator provides reference
+  voltage for on-chip IPs (like PHYs) on some Qualcomm SoCs.
+
+allOf:
+  - $ref: regulator.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - qcom,sc7180-refgen-regulator
+              - qcom,sc8180x-refgen-regulator
+              - qcom,sm8150-refgen-regulator
+          - const: qcom,sdm845-refgen-regulator
+
+      - items:
+          - enum:
+              - qcom,sc7280-refgen-regulator
+              - qcom,sc8280xp-refgen-regulator
+              - qcom,sm6350-refgen-regulator
+              - qcom,sm6375-refgen-regulator
+              - qcom,sm8350-refgen-regulator
+          - const: qcom,sm8250-refgen-regulator
+
+      - enum:
+          - qcom,sdm845-refgen-regulator
+          - qcom,sm8250-refgen-regulator
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    regulator@162f000 {
+      compatible = "qcom,sm8250-refgen-regulator";
+      reg = <0x0162f000 0x84>;
+    };
+...
index a8ca8e0..9ea8ac0 100644 (file)
@@ -110,6 +110,7 @@ patternProperties:
   "^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$":
     description: List of regulators and its properties
     $ref: regulator.yaml#
+    unevaluatedProperties: false
 
 additionalProperties: false
 
index d9c2333..cd06e95 100644 (file)
@@ -29,6 +29,7 @@ patternProperties:
   "^DSV(LCM|P|N)$":
     type: object
     $ref: regulator.yaml#
+    unevaluatedProperties: false
     description:
       Properties for single Display Bias Voltage regulator.
 
index 358297d..e95e046 100644 (file)
@@ -21,6 +21,7 @@ allOf:
 properties:
   compatible:
     enum:
+      - richtek,rt5733
       - richtek,rt5739
 
   reg:
index 446ec51..fec3d39 100644 (file)
@@ -121,6 +121,7 @@ properties:
     description: load switch current regulator description.
     type: object
     $ref: regulator.yaml#
+    unevaluatedProperties: false
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
new file mode 100644 (file)
index 0000000..609c066
--- /dev/null
@@ -0,0 +1,197 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rtq2208.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RTQ2208 SubPMIC Regulator
+
+maintainers:
+  - Alina Yu <alina_yu@richtek.com>
+
+description: |
+  RTQ2208 is a highly integrated power converter that offers functional safety dual
+  multi-configurable synchronous buck converters and two LDOs.
+
+  Bucks support "regulator-allowed-modes" and "regulator-mode". The former defines the permitted
+  switching operation in normal mode; the latter defines the operation in suspend to RAM mode.
+
+  No matter the RTQ2208 is configured to normal or suspend to RAM mode, there are two switching
+  operation modes for all buck rails, automatic power saving mode (Auto mode) and forced continuous
+  conduction mode (FCCM).
+
+  The definition of modes is in the datasheet which is available in below link
+  and their meaning is::
+    0 - Auto mode for power saving, which reducing the switching frequency at light load condition
+    to maintain high frequency.
+    1 - FCCM to meet the strict voltage regulation accuracy, which keeping constant switching frequency.
+
+  Datasheet will be available soon at
+  https://www.richtek.com/assets/Products
+
+properties:
+  compatible:
+    enum:
+      - richtek,rtq2208
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+    
+  richtek,mtp-sel-high:
+    type: boolean
+    description:
+      vout register selection based on this boolean value.
+      false - Using DVS0 register setting to adjust vout
+      true - Using DVS1 register setting to adjust vout
+
+  regulators:
+    type: object
+    additionalProperties: false
+
+    patternProperties:
+      "^buck-[a-h]$":
+        type: object
+        $ref: regulator.yaml#
+        unevaluatedProperties: false
+        description:
+          description for buck-[a-h] regulator.
+
+        properties:
+          regulator-allowed-modes:
+            description:
+              two buck modes in different switching accuracy.
+              0 - Auto mode
+              1 - FCCM
+            items:
+              enum: [0, 1]
+
+      "^ldo[1-2]$":
+        type: object
+        $ref: regulator.yaml#
+        unevaluatedProperties: false
+        description:
+          regulator description for ldo[1-2].
+
+required:
+  - compatible
+  - reg
+  - regulators
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      pmic@10 {
+        compatible = "richtek,rtq2208";
+        reg = <0x10>;
+        interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;
+        richtek,mtp-sel-high;
+
+        regulators {
+          buck-a {
+            regulator-min-microvolt = <400000>;
+            regulator-max-microvolt = <2050000>;
+            regulator-allowed-modes = <0 1>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+              regulator-mode = <1>;
+            };
+          };
+          buck-b {
+            regulator-min-microvolt = <400000>;
+            regulator-max-microvolt = <2050000>;
+            regulator-allowed-modes = <0 1>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+              regulator-mode = <1>;
+            };
+          };
+          buck-c {
+            regulator-min-microvolt = <400000>;
+            regulator-max-microvolt = <2050000>;
+            regulator-allowed-modes = <0 1>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+              regulator-mode = <1>;
+            };
+          };
+          buck-d {
+            regulator-min-microvolt = <400000>;
+            regulator-max-microvolt = <2050000>;
+            regulator-allowed-modes = <0 1>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+              regulator-mode = <1>;
+            };
+          };
+          buck-e {
+            regulator-min-microvolt = <400000>;
+            regulator-max-microvolt = <2050000>;
+            regulator-allowed-modes = <0 1>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+              regulator-mode = <1>;
+            };
+          };
+          buck-f {
+            regulator-min-microvolt = <400000>;
+            regulator-max-microvolt = <2050000>;
+            regulator-allowed-modes = <0 1>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+              regulator-mode = <1>;
+            };
+          };
+          buck-g {
+            regulator-min-microvolt = <400000>;
+            regulator-max-microvolt = <2050000>;
+            regulator-allowed-modes = <0 1>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+              regulator-mode = <1>;
+            };
+          };
+          buck-h {
+            regulator-min-microvolt = <400000>;
+            regulator-max-microvolt = <2050000>;
+            regulator-allowed-modes = <0 1>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+              regulator-mode = <1>;
+            };
+          };
+          ldo1 {
+            regulator-min-microvolt = <1200000>;
+            regulator-max-microvolt = <1200000>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+            };
+          };
+          ldo2 {
+            regulator-min-microvolt = <3300000>;
+            regulator-max-microvolt = <3300000>;
+            regulator-always-on;
+            regulator-state-mem {
+              regulator-on-in-suspend;
+            };
+          };
+        };
+      };
+    };
index e6e5a9a..ef62c61 100644 (file)
@@ -35,6 +35,7 @@ properties:
       "^(p|n)avdd$":
         type: object
         $ref: regulator.yaml#
+        unevaluatedProperties: false
         description: |
           regulator description for pavdd and navdd.
 
diff --git a/Documentation/devicetree/bindings/regulator/slg51000.txt b/Documentation/devicetree/bindings/regulator/slg51000.txt
deleted file mode 100644 (file)
index aa0733e..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-* Dialog Semiconductor SLG51000 Voltage Regulator
-
-Required properties:
-- compatible : Should be "dlg,slg51000" for SLG51000
-- reg : Specifies the I2C slave address.
-- xxx-supply: Input voltage supply regulator for ldo3 to ldo7.
-  These entries are required if regulators are enabled for a device.
-  An absence of these properties can cause the regulator registration to fail.
-  If some of input supply is powered through battery or always-on supply then
-  also it is required to have these parameters with proper node handle of always
-  on power supply.
-    vin3-supply: Input supply for ldo3
-    vin4-supply: Input supply for ldo4
-    vin5-supply: Input supply for ldo5
-    vin6-supply: Input supply for ldo6
-    vin7-supply: Input supply for ldo7
-
-Optional properties:
-- interrupt-parent : Specifies the reference to the interrupt controller.
-- interrupts : IRQ line information.
-- dlg,cs-gpios : Specify a valid GPIO for chip select
-
-Sub-nodes:
-- regulators : This node defines the settings for the regulators.
-  The content of the sub-node is defined by the standard binding
-  for regulators; see regulator.txt.
-
-  The SLG51000 regulators are bound using their names listed below:
-    ldo1
-    ldo2
-    ldo3
-    ldo4
-    ldo5
-    ldo6
-    ldo7
-
-Optional properties for regulators:
-- enable-gpios : Specify a valid GPIO for platform control of the regulator.
-
-Example:
-       pmic: slg51000@75 {
-               compatible = "dlg,slg51000";
-               reg = <0x75>;
-
-               regulators {
-                       ldo1 {
-                               regulator-name = "ldo1";
-                               regulator-min-microvolt = <2400000>;
-                               regulator-max-microvolt = <3300000>;
-                       };
-
-                       ldo2 {
-                               regulator-name = "ldo2";
-                               regulator-min-microvolt = <2400000>;
-                               regulator-max-microvolt = <3300000>;
-                       };
-
-                       ldo3 {
-                               regulator-name = "ldo3";
-                               regulator-min-microvolt = <1200000>;
-                               regulator-max-microvolt = <3750000>;
-                       };
-
-                       ldo4 {
-                               regulator-name = "ldo4";
-                               regulator-min-microvolt = <1200000>;
-                               regulator-max-microvolt = <3750000>;
-                       };
-
-                       ldo5 {
-                               regulator-name = "ldo5";
-                               regulator-min-microvolt = <500000>;
-                               regulator-max-microvolt = <1200000>;
-                       };
-
-                       ldo6 {
-                               regulator-name = "ldo6";
-                               regulator-min-microvolt = <500000>;
-                               regulator-max-microvolt = <1200000>;
-                       };
-
-                       ldo7 {
-                               regulator-name = "ldo7";
-                               regulator-min-microvolt = <1200000>;
-                               regulator-max-microvolt = <3750000>;
-                       };
-               };
-       };
index 7d53cfa..c9586d2 100644 (file)
@@ -25,8 +25,8 @@ properties:
 patternProperties:
   "^(reg11|reg18|usb33)$":
     type: object
-
     $ref: regulator.yaml#
+    unevaluatedProperties: false
 
 required:
   - compatible
index 011819c..11e3786 100644 (file)
@@ -29,11 +29,13 @@ properties:
       Initial data for the LDO1 regulator.
     $ref: regulator.yaml#
     type: object
+    unevaluatedProperties: false
 
   micvdd:
     description:
       Initial data for the MICVDD regulator.
     $ref: regulator.yaml#
     type: object
+    unevaluatedProperties: false
 
 additionalProperties: true
index 9b2f913..9040fd2 100644 (file)
@@ -6010,7 +6010,7 @@ F:        Documentation/devicetree/bindings/mfd/da90*.txt
 F:     Documentation/devicetree/bindings/mfd/dlg,da90*.yaml
 F:     Documentation/devicetree/bindings/regulator/da92*.txt
 F:     Documentation/devicetree/bindings/regulator/dlg,da9*.yaml
-F:     Documentation/devicetree/bindings/regulator/slg51000.txt
+F:     Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml
 F:     Documentation/devicetree/bindings/sound/da[79]*.txt
 F:     Documentation/devicetree/bindings/thermal/da90??-thermal.txt
 F:     Documentation/devicetree/bindings/watchdog/da90??-wdt.txt
index 6a21000..9bb7d7d 100644 (file)
@@ -81,16 +81,23 @@ static int tps65086_probe(struct i2c_client *client)
                return PTR_ERR(tps->regmap);
        }
 
-       ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
+       /* Store device ID to load regulator configuration that fit to IC variant */
+       ret = regmap_read(tps->regmap, TPS65086_DEVICEID1, &tps->chip_id);
        if (ret) {
-               dev_err(tps->dev, "Failed to read revision register\n");
+               dev_err(tps->dev, "Failed to read revision register 1\n");
+               return ret;
+       }
+
+       ret = regmap_read(tps->regmap, TPS65086_DEVICEID2, &version);
+       if (ret) {
+               dev_err(tps->dev, "Failed to read revision register 2\n");
                return ret;
        }
 
        dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
-                (version & TPS65086_DEVICEID_PART_MASK),
-                (char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
-                (version & TPS65086_DEVICEID_REV_MASK) >> 6);
+                (version & TPS65086_DEVICEID2_PART_MASK),
+                (char)((version & TPS65086_DEVICEID2_OTP_MASK) >> 4) + 'A',
+                (version & TPS65086_DEVICEID2_REV_MASK) >> 6);
 
        if (tps->irq > 0) {
                ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
index 823f8e6..965d4f0 100644 (file)
@@ -178,6 +178,14 @@ config REGULATOR_ATC260X
          ATC260x PMICs. This will enable support for all the software
          controllable DCDC/LDO regulators.
 
+config REGULATOR_AW37503
+       tristate "Awinic AW37503 Dual Output Power regulators"
+       depends on I2C && GPIOLIB
+       select REGMAP_I2C
+       help
+         This driver supports AW37503 single inductor - dual output
+         power supply specifically designed for display panels.
+
 config REGULATOR_AXP20X
        tristate "X-POWERS AXP20X PMIC Regulators"
        depends on MFD_AXP20X
@@ -546,11 +554,11 @@ config REGULATOR_MAX1586
          regulator via I2C bus. The provided regulator is suitable
          for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
 
-config REGULATOR_MAX597X
-       tristate "Maxim 597x power switch and monitor"
+config REGULATOR_MAX5970
+       tristate "Maxim 5970/5978 power switch and monitor"
        depends on I2C
        depends on OF
-       depends on MFD_MAX597X
+       depends on MFD_MAX5970
        help
          This driver controls a Maxim 5970/5978 switch via I2C bus.
          The MAX5970/5978 is a smart switch with no output regulation, but
@@ -584,6 +592,16 @@ config REGULATOR_MAX77650
          Semiconductor. This device has a SIMO with three independent
          power rails and an LDO.
 
+config REGULATOR_MAX77857
+       tristate "ADI MAX77857/MAX77831 regulator support"
+       depends on I2C
+       select REGMAP_I2C
+       help
+         This driver controls a ADI MAX77857 and MAX77831 regulators.
+         via I2C bus. MAX77857 and MAX77831 are high efficiency buck-boost
+         converters with input voltage range (2.5V to 16V). Say Y here to
+         enable the regulator driver
+
 config REGULATOR_MAX8649
        tristate "Maxim 8649 voltage regulator"
        depends on I2C
@@ -989,6 +1007,18 @@ config REGULATOR_PWM
          This driver supports PWM controlled voltage regulators. PWM
          duty cycle can increase or decrease the voltage.
 
+config REGULATOR_QCOM_REFGEN
+       tristate "Qualcomm REFGEN regulator driver"
+       depends on ARCH_QCOM || COMPILE_TEST
+       depends on HAS_IOMEM
+       depends on REGMAP
+       help
+         This driver supports the MMIO-mapped reference voltage regulator,
+         used internally by some PHYs on many Qualcomm SoCs.
+
+         Say M here if you want to include support for this regulator as
+         a module. The module will be named "qcom-refgen-regulator".
+
 config REGULATOR_QCOM_RPM
        tristate "Qualcomm RPM regulator driver"
        depends on MFD_QCOM_RPM
@@ -1050,7 +1080,11 @@ config REGULATOR_RAA215300
        depends on COMMON_CLK
        depends on I2C
        help
-         Support for the Renesas RAA215300 PMIC.
+         If you say yes to this option, support will be included for the
+         Renesas RAA215300 PMIC.
+
+         Say M here if you want to include support for Renesas RAA215300 PMIC
+         as a module. The module will be named "raa215300".
 
 config REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY
        tristate "Raspberry Pi 7-inch touchscreen panel ATTINY regulator"
@@ -1232,6 +1266,17 @@ config REGULATOR_RTQ6752
          synchronous boost converters for PAVDD, and one synchronous NAVDD
          buck-boost. This device is suitable for automotive TFT-LCD panel.
 
+config REGULATOR_RTQ2208
+       tristate "Richtek RTQ2208 SubPMIC Regulator"
+       depends on I2C
+       select REGMAP_I2C
+       help
+         This driver adds support for RTQ2208 SubPMIC regulators.
+         The RTQ2208 is a multi-phase, programmable power management IC that
+         integrate with dual multi-configurable, synchronous buck converters
+         and two ldos. It features wide output voltage range from 0.4V to 2.05V
+         and the capability to configure the corresponding power stages.
+
 config REGULATOR_S2MPA01
        tristate "Samsung S2MPA01 voltage regulator"
        depends on MFD_SEC_CORE || COMPILE_TEST
index 15e0d61..2307471 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_ARM_SCMI) += scmi-regulator.o
 obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
 obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
 obj-$(CONFIG_REGULATOR_ATC260X) += atc260x-regulator.o
+obj-$(CONFIG_REGULATOR_AW37503) += aw37503-regulator.o
 obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
 obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
 obj-$(CONFIG_REGULATOR_BD71815)        += bd71815-regulator.o
@@ -67,7 +68,7 @@ obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
 obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
 obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
-obj-$(CONFIG_REGULATOR_MAX597X) += max597x-regulator.o
+obj-$(CONFIG_REGULATOR_MAX5970) += max5970-regulator.o
 obj-$(CONFIG_REGULATOR_MAX77541) += max77541-regulator.o
 obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
 obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o
@@ -86,6 +87,7 @@ obj-$(CONFIG_REGULATOR_MAX77686) += max77686-regulator.o
 obj-$(CONFIG_REGULATOR_MAX77693) += max77693-regulator.o
 obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o
 obj-$(CONFIG_REGULATOR_MAX77826) += max77826-regulator.o
+obj-$(CONFIG_REGULATOR_MAX77857) += max77857-regulator.o
 obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
@@ -108,6 +110,7 @@ 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_QCOM_LABIBB) += qcom-labibb-regulator.o
+obj-$(CONFIG_REGULATOR_QCOM_REFGEN) += qcom-refgen-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
@@ -145,6 +148,7 @@ obj-$(CONFIG_REGULATOR_RT6245)      += rt6245-regulator.o
 obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
 obj-$(CONFIG_REGULATOR_RTQ2134) += rtq2134-regulator.o
 obj-$(CONFIG_REGULATOR_RTQ6752)        += rtq6752-regulator.o
+obj-$(CONFIG_REGULATOR_RTQ2208) += rtq2208-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
index e262645..24cbdd8 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
index 87e237d..3e9f8fd 100644 (file)
@@ -7,7 +7,8 @@
 
 #include <linux/mfd/atc260x/core.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 
@@ -37,7 +38,7 @@ static const struct linear_range atc2609a_ldo_voltage_ranges1[] = {
 };
 
 static const unsigned int atc260x_ldo_voltage_range_sel[] = {
-       0x0, 0x20,
+       0x0, 0x1,
 };
 
 static int atc260x_dcdc_set_voltage_time_sel(struct regulator_dev *rdev,
@@ -427,7 +428,7 @@ enum atc2609a_reg_ids {
        .vsel_mask = GENMASK(4, 1), \
        .vsel_range_reg = ATC2609A_PMU_LDO##num##_CTL0, \
        .vsel_range_mask = BIT(5), \
-       .linear_range_selectors = atc260x_ldo_voltage_range_sel, \
+       .linear_range_selectors_bitfield = atc260x_ldo_voltage_range_sel, \
        .enable_reg = ATC2609A_PMU_LDO##num##_CTL0, \
        .enable_mask = BIT(0), \
        .enable_time = 2000, \
diff --git a/drivers/regulator/aw37503-regulator.c b/drivers/regulator/aw37503-regulator.c
new file mode 100644 (file)
index 0000000..a5ff6df
--- /dev/null
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// AWINIC AW37503 Regulator Driver
+//
+// Copyright (C) 2023 awinic. All Rights Reserved
+//
+// Author: <like@awinic.com>
+
+#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 AW37503_REG_VPOS               0x00
+#define AW37503_REG_VNEG               0x01
+#define AW37503_REG_APPS               0x03
+#define AW37503_REG_CONTROL            0x04
+#define AW37503_REG_WPRTEN             0x21
+
+#define AW37503_VOUT_MASK              0x1F
+#define AW37503_VOUT_N_VOLTAGE         0x15
+#define AW37503_VOUT_VMIN              4000000
+#define AW37503_VOUT_VMAX              6000000
+#define AW37503_VOUT_STEP              100000
+
+#define AW37503_REG_APPS_DIS_VPOS      BIT(1)
+#define AW37503_REG_APPS_DIS_VNEG      BIT(0)
+
+#define AW37503_REGULATOR_ID_VPOS      0
+#define AW37503_REGULATOR_ID_VNEG      1
+#define AW37503_MAX_REGULATORS         2
+
+struct aw37503_reg_pdata {
+       struct gpio_desc *en_gpiod;
+       int ena_gpio_state;
+};
+
+struct aw37503_regulator {
+       struct device *dev;
+       struct aw37503_reg_pdata reg_pdata[AW37503_MAX_REGULATORS];
+};
+
+static int aw37503_regulator_enable(struct regulator_dev *rdev)
+{
+       struct aw37503_regulator *chip = rdev_get_drvdata(rdev);
+       int id = rdev_get_id(rdev);
+       struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[id];
+       int ret;
+
+       if (!IS_ERR(rpdata->en_gpiod)) {
+               gpiod_set_value_cansleep(rpdata->en_gpiod, 1);
+               rpdata->ena_gpio_state = 1;
+       }
+
+       /* Hardware automatically enable discharge bit in enable */
+       if (rdev->constraints->active_discharge ==
+                       REGULATOR_ACTIVE_DISCHARGE_DISABLE) {
+               ret = regulator_set_active_discharge_regmap(rdev, false);
+               if (ret < 0) {
+                       dev_err(chip->dev, "Failed to disable active discharge: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int aw37503_regulator_disable(struct regulator_dev *rdev)
+{
+       struct aw37503_regulator *chip = rdev_get_drvdata(rdev);
+       int id = rdev_get_id(rdev);
+       struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[id];
+
+       if (!IS_ERR(rpdata->en_gpiod)) {
+               gpiod_set_value_cansleep(rpdata->en_gpiod, 0);
+               rpdata->ena_gpio_state = 0;
+       }
+
+       return 0;
+}
+
+static int aw37503_regulator_is_enabled(struct regulator_dev *rdev)
+{
+       struct aw37503_regulator *chip = rdev_get_drvdata(rdev);
+       int id = rdev_get_id(rdev);
+       struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[id];
+
+       if (!IS_ERR(rpdata->en_gpiod))
+               return rpdata->ena_gpio_state;
+
+       return 1;
+}
+
+static const struct regulator_ops aw37503_regulator_ops = {
+       .enable = aw37503_regulator_enable,
+       .disable = aw37503_regulator_disable,
+       .is_enabled = aw37503_regulator_is_enabled,
+       .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,
+       .set_active_discharge = regulator_set_active_discharge_regmap,
+};
+
+static int aw37503_of_parse_cb(struct device_node *np,
+                               const struct regulator_desc *desc,
+                               struct regulator_config *config)
+{
+       struct aw37503_regulator *chip = config->driver_data;
+       struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[desc->id];
+       int ret;
+
+       rpdata->en_gpiod = devm_fwnode_gpiod_get(chip->dev, of_fwnode_handle(np),
+                                                "enable", GPIOD_OUT_LOW,
+                                                "enable");
+
+       if (IS_ERR(rpdata->en_gpiod)) {
+               ret = PTR_ERR(rpdata->en_gpiod);
+
+               /* Ignore the error other than probe defer */
+               if (ret == -EPROBE_DEFER)
+                       return ret;
+               return 0;
+       }
+
+       return 0;
+}
+
+#define AW37503_REGULATOR_DESC(_id, _name)             \
+       [AW37503_REGULATOR_ID_##_id] = {                \
+               .name = "aw37503-"#_name,               \
+               .supply_name = "vin",                   \
+               .id = AW37503_REGULATOR_ID_##_id,       \
+               .of_match = of_match_ptr(#_name),       \
+               .of_parse_cb = aw37503_of_parse_cb,     \
+               .ops = &aw37503_regulator_ops,          \
+               .n_voltages = AW37503_VOUT_N_VOLTAGE,   \
+               .min_uV = AW37503_VOUT_VMIN,            \
+               .uV_step = AW37503_VOUT_STEP,           \
+               .enable_time = 500,                     \
+               .vsel_mask = AW37503_VOUT_MASK, \
+               .vsel_reg = AW37503_REG_##_id,          \
+               .active_discharge_off = 0,                      \
+               .active_discharge_on = AW37503_REG_APPS_DIS_##_id, \
+               .active_discharge_mask = AW37503_REG_APPS_DIS_##_id, \
+               .active_discharge_reg = AW37503_REG_APPS, \
+               .type = REGULATOR_VOLTAGE,              \
+               .owner = THIS_MODULE,                   \
+       }
+
+static const struct regulator_desc aw_regs_desc[AW37503_MAX_REGULATORS] = {
+       AW37503_REGULATOR_DESC(VPOS, outp),
+       AW37503_REGULATOR_DESC(VNEG, outn),
+};
+
+static const struct regmap_range aw37503_no_reg_ranges[] = {
+       regmap_reg_range(AW37503_REG_CONTROL + 1,
+                        AW37503_REG_WPRTEN - 1),
+};
+
+static const struct regmap_access_table aw37503_no_reg_table = {
+       .no_ranges = aw37503_no_reg_ranges,
+       .n_no_ranges = ARRAY_SIZE(aw37503_no_reg_ranges),
+};
+
+static const struct regmap_config aw37503_regmap_config = {
+       .reg_bits       = 8,
+       .val_bits       = 8,
+       .max_register   = AW37503_REG_WPRTEN,
+       .rd_table       = &aw37503_no_reg_table,
+       .wr_table       = &aw37503_no_reg_table,
+};
+
+static int aw37503_probe(struct i2c_client *client)
+{
+       struct device *dev = &client->dev;
+       struct aw37503_regulator *chip;
+       struct regulator_dev *rdev;
+       struct regmap *regmap;
+       struct regulator_config config = { };
+       int id;
+
+       chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+       regmap = devm_regmap_init_i2c(client, &aw37503_regmap_config);
+       if (IS_ERR(regmap))
+               return dev_err_probe(dev, PTR_ERR(regmap),
+                                    "Failed to init regmap\n");
+
+       i2c_set_clientdata(client, chip);
+       chip->dev = dev;
+
+       config.regmap = regmap;
+       config.dev = dev;
+       config.driver_data = chip;
+
+       for (id = 0; id < AW37503_MAX_REGULATORS; ++id) {
+               rdev = devm_regulator_register(dev, &aw_regs_desc[id],
+                                              &config);
+               if (IS_ERR(rdev))
+                       return dev_err_probe(dev, PTR_ERR(rdev),
+                                            "Failed to register regulator %s\n",
+                                            aw_regs_desc[id].name);
+       }
+       return 0;
+}
+
+static const struct i2c_device_id aw37503_id[] = {
+       {.name = "aw37503",},
+       {},
+};
+MODULE_DEVICE_TABLE(i2c, aw37503_id);
+
+static const struct of_device_id aw37503_of_match[] = {
+       {.compatible = "awinic,aw37503",},
+       { /* Sentinel */ },
+};
+
+MODULE_DEVICE_TABLE(of, aw37503_of_match);
+
+static struct i2c_driver aw37503_i2c_driver = {
+       .driver = {
+               .name = "aw37503",
+               .of_match_table = aw37503_of_match,
+       },
+       .probe = aw37503_probe,
+       .id_table = aw37503_id,
+};
+
+module_i2c_driver(aw37503_i2c_driver);
+
+MODULE_DESCRIPTION("aw37503 regulator driver");
+MODULE_AUTHOR("Alec Li <like@awinic.com>");
+MODULE_LICENSE("GPL");
index 810f90f..c657820 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/mfd/axp20x.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
index 475b1e0..26192d5 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/regulator/driver.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/gpio.h>
 #include <linux/mfd/rohm-generic.h>
 #include <linux/mfd/rohm-bd71815.h>
 #include <linux/regulator/of_regulator.h>
index f3205dc..08d4ee3 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <linux/delay.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mfd/rohm-bd71828.h>
index b0b9938..c3fb05d 100644 (file)
@@ -289,7 +289,7 @@ static const struct linear_range bd71837_buck5_volts[] = {
  * and 0x1 for last 3 ranges.
  */
 static const unsigned int bd71837_buck5_volt_range_sel[] = {
-       0x0, 0x0, 0x0, 0x80, 0x80, 0x80
+       0x0, 0x0, 0x0, 0x1, 0x1, 0x1
 };
 
 /*
@@ -309,7 +309,7 @@ static const struct linear_range bd71847_buck3_volts[] = {
 };
 
 static const unsigned int bd71847_buck3_volt_range_sel[] = {
-       0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80
+       0x0, 0x0, 0x0, 0x1, 0x2, 0x2, 0x2
 };
 
 static const struct linear_range bd71847_buck4_volts[] = {
@@ -317,7 +317,7 @@ static const struct linear_range bd71847_buck4_volts[] = {
        REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000),
 };
 
-static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 };
+static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x1 };
 
 /*
  * BUCK6
@@ -360,7 +360,7 @@ static const struct linear_range bd718xx_ldo1_volts[] = {
        REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
 };
 
-static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x20 };
+static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x1 };
 
 /*
  * LDO2
@@ -403,7 +403,7 @@ static const struct linear_range bd71847_ldo5_volts[] = {
        REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000),
 };
 
-static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 };
+static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x1 };
 
 /*
  * LDO6
@@ -817,7 +817,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
                        .vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
                        .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
                        .vsel_range_mask = BD71847_BUCK3_RANGE_MASK,
-                       .linear_range_selectors = bd71847_buck3_volt_range_sel,
+                       .linear_range_selectors_bitfield = bd71847_buck3_volt_range_sel,
                        .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
                        .enable_mask = BD718XX_BUCK_EN,
                        .enable_time = BD71847_BUCK3_STARTUP_TIME,
@@ -845,7 +845,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
                        .vsel_mask = BD71847_BUCK4_MASK,
                        .vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
                        .vsel_range_mask = BD71847_BUCK4_RANGE_MASK,
-                       .linear_range_selectors = bd71847_buck4_volt_range_sel,
+                       .linear_range_selectors_bitfield = bd71847_buck4_volt_range_sel,
                        .enable_mask = BD718XX_BUCK_EN,
                        .enable_time = BD71847_BUCK4_STARTUP_TIME,
                        .owner = THIS_MODULE,
@@ -916,7 +916,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
                        .vsel_mask = BD718XX_LDO1_MASK,
                        .vsel_range_reg = BD718XX_REG_LDO1_VOLT,
                        .vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
-                       .linear_range_selectors = bd718xx_ldo1_volt_range_sel,
+                       .linear_range_selectors_bitfield = bd718xx_ldo1_volt_range_sel,
                        .enable_reg = BD718XX_REG_LDO1_VOLT,
                        .enable_mask = BD718XX_LDO_EN,
                        .enable_time = BD71847_LDO1_STARTUP_TIME,
@@ -1010,7 +1010,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
                        .vsel_mask = BD71847_LDO5_MASK,
                        .vsel_range_reg = BD718XX_REG_LDO5_VOLT,
                        .vsel_range_mask = BD71847_LDO5_RANGE_MASK,
-                       .linear_range_selectors = bd71847_ldo5_volt_range_sel,
+                       .linear_range_selectors_bitfield = bd71847_ldo5_volt_range_sel,
                        .enable_reg = BD718XX_REG_LDO5_VOLT,
                        .enable_mask = BD718XX_LDO_EN,
                        .enable_time = BD71847_LDO5_STARTUP_TIME,
@@ -1232,7 +1232,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
                        .vsel_mask = BD71837_BUCK5_MASK,
                        .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
                        .vsel_range_mask = BD71837_BUCK5_RANGE_MASK,
-                       .linear_range_selectors = bd71837_buck5_volt_range_sel,
+                       .linear_range_selectors_bitfield = bd71837_buck5_volt_range_sel,
                        .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
                        .enable_mask = BD718XX_BUCK_EN,
                        .enable_time = BD71837_BUCK5_STARTUP_TIME,
@@ -1328,7 +1328,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
                        .vsel_mask = BD718XX_LDO1_MASK,
                        .vsel_range_reg = BD718XX_REG_LDO1_VOLT,
                        .vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
-                       .linear_range_selectors = bd718xx_ldo1_volt_range_sel,
+                       .linear_range_selectors_bitfield = bd718xx_ldo1_volt_range_sel,
                        .enable_reg = BD718XX_REG_LDO1_VOLT,
                        .enable_mask = BD718XX_LDO_EN,
                        .enable_time = BD71837_LDO1_STARTUP_TIME,
index 1fd79fb..6958d15 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/of_platform.h>
+#include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
index c28b061..1d354db 100644 (file)
@@ -924,7 +924,7 @@ static int da9062_regulator_probe(struct platform_device *pdev)
        struct da9062_regulator *regl;
        struct regulator_config config = { };
        const struct da9062_regulator_info *rinfo;
-       int irq, n, ret;
+       int n, ret;
        int max_regulators;
 
        switch (chip->chip_type) {
@@ -1012,12 +1012,11 @@ static int da9062_regulator_probe(struct platform_device *pdev)
        }
 
        /* LDOs overcurrent event support */
-       irq = platform_get_irq_byname(pdev, "LDO_LIM");
-       if (irq < 0)
-               return irq;
-       regulators->irq_ldo_lim = irq;
+       regulators->irq_ldo_lim = platform_get_irq_byname_optional(pdev, "LDO_LIM");
+       if (regulators->irq_ldo_lim < 0)
+               return 0;
 
-       ret = devm_request_threaded_irq(&pdev->dev, irq,
+       ret = devm_request_threaded_irq(&pdev->dev, regulators->irq_ldo_lim,
                                        NULL, da9062_ldo_lim_event,
                                        IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                        "LDO_LIM", regulators);
index 1221249..8009803 100644 (file)
@@ -440,7 +440,7 @@ static const struct regulator_desc da9121_reg = {
        .of_match = "buck1",
        .of_parse_cb = da9121_of_parse_cb,
        .owner = THIS_MODULE,
-       .regulators_node = of_match_ptr("regulators"),
+       .regulators_node = "regulators",
        .of_map_mode = da9121_map_mode,
        .ops = &da9121_buck_ops,
        .type = REGULATOR_VOLTAGE,
@@ -465,7 +465,7 @@ static const struct regulator_desc da9220_reg[2] = {
                .of_match = "buck1",
                .of_parse_cb = da9121_of_parse_cb,
                .owner = THIS_MODULE,
-               .regulators_node = of_match_ptr("regulators"),
+               .regulators_node = "regulators",
                .of_map_mode = da9121_map_mode,
                .ops = &da9121_buck_ops,
                .type = REGULATOR_VOLTAGE,
@@ -484,7 +484,7 @@ static const struct regulator_desc da9220_reg[2] = {
                .of_match = "buck2",
                .of_parse_cb = da9121_of_parse_cb,
                .owner = THIS_MODULE,
-               .regulators_node = of_match_ptr("regulators"),
+               .regulators_node = "regulators",
                .of_map_mode = da9121_map_mode,
                .ops = &da9121_buck_ops,
                .type = REGULATOR_VOLTAGE,
@@ -506,7 +506,7 @@ static const struct regulator_desc da9122_reg[2] = {
                .of_match = "buck1",
                .of_parse_cb = da9121_of_parse_cb,
                .owner = THIS_MODULE,
-               .regulators_node = of_match_ptr("regulators"),
+               .regulators_node = "regulators",
                .of_map_mode = da9121_map_mode,
                .ops = &da9121_buck_ops,
                .type = REGULATOR_VOLTAGE,
@@ -525,7 +525,7 @@ static const struct regulator_desc da9122_reg[2] = {
                .of_match = "buck2",
                .of_parse_cb = da9121_of_parse_cb,
                .owner = THIS_MODULE,
-               .regulators_node = of_match_ptr("regulators"),
+               .regulators_node = "regulators",
                .of_map_mode = da9121_map_mode,
                .ops = &da9121_buck_ops,
                .type = REGULATOR_VOLTAGE,
@@ -546,7 +546,7 @@ static const struct regulator_desc da9217_reg = {
        .of_match = "buck1",
        .of_parse_cb = da9121_of_parse_cb,
        .owner = THIS_MODULE,
-       .regulators_node = of_match_ptr("regulators"),
+       .regulators_node = "regulators",
        .of_map_mode = da9121_map_mode,
        .ops = &da9121_buck_ops,
        .type = REGULATOR_VOLTAGE,
@@ -573,7 +573,7 @@ static const struct regulator_desc da9141_reg = {
        .of_match = "buck1",
        .of_parse_cb = da9121_of_parse_cb,
        .owner = THIS_MODULE,
-       .regulators_node = of_match_ptr("regulators"),
+       .regulators_node = "regulators",
        .of_map_mode = da9121_map_mode,
        .ops = &da9121_buck_ops,
        .type = REGULATOR_VOLTAGE,
@@ -593,7 +593,7 @@ static const struct regulator_desc da9142_reg = {
        .of_match = "buck1",
        .of_parse_cb = da9121_of_parse_cb,
        .owner = THIS_MODULE,
-       .regulators_node = of_match_ptr("regulators"),
+       .regulators_node = "regulators",
        .of_map_mode = da9121_map_mode,
        .ops = &da9121_buck_ops,
        .type = REGULATOR_VOLTAGE,
@@ -1195,7 +1195,7 @@ static struct i2c_driver da9121_regulator_driver = {
        .driver = {
                .name = "da9121",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
-               .of_match_table = of_match_ptr(da9121_dt_ids),
+               .of_match_table = da9121_dt_ids,
        },
        .probe = da9121_i2c_probe,
        .remove = da9121_i2c_remove,
index 289c06e..48f3121 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/param.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
index 364d1a2..55130ef 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/gpio/consumer.h>
 #include <linux/slab.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/machine.h>
 #include <linux/clk.h>
index e6c999b..5ad5f3b 100644 (file)
@@ -5,13 +5,14 @@
 // Copyright 2007, 2008 Wolfson Microelectronics PLC.
 // Copyright 2008 SlimLogic Ltd.
 
-#include <linux/kernel.h>
-#include <linux/err.h>
+#include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/driver.h>
-#include <linux/module.h>
 
 #include "internal.h"
 
@@ -104,13 +105,14 @@ static int regulator_range_selector_to_index(struct regulator_dev *rdev,
 {
        int i;
 
-       if (!rdev->desc->linear_range_selectors)
+       if (!rdev->desc->linear_range_selectors_bitfield)
                return -EINVAL;
 
        rval &= rdev->desc->vsel_range_mask;
+       rval >>= ffs(rdev->desc->vsel_range_mask) - 1;
 
        for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
-               if (rdev->desc->linear_range_selectors[i] == rval)
+               if (rdev->desc->linear_range_selectors_bitfield[i] == rval)
                        return i;
        }
        return -EINVAL;
@@ -194,7 +196,8 @@ int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
        sel <<= ffs(rdev->desc->vsel_mask) - 1;
        sel += rdev->desc->linear_ranges[i].min_sel;
 
-       range = rdev->desc->linear_range_selectors[i];
+       range = rdev->desc->linear_range_selectors_bitfield[i];
+       range <<= ffs(rdev->desc->vsel_mask) - 1;
 
        if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) {
                ret = regmap_update_bits(rdev->regmap,
index 1b52423..82e9e36 100644 (file)
@@ -131,8 +131,8 @@ static const struct regulator_ops hi6421_buck345_ops;
        [HI6421_##_id] = {                                              \
                .desc = {                                               \
                        .name           = #_id,                         \
-                       .of_match        = of_match_ptr(#_match),       \
-                       .regulators_node = of_match_ptr("regulators"),  \
+                       .of_match        = #_match,                     \
+                       .regulators_node = "regulators",                \
                        .ops            = &hi6421_ldo_ops,              \
                        .type           = REGULATOR_VOLTAGE,            \
                        .id             = HI6421_##_id,                 \
@@ -170,8 +170,8 @@ static const struct regulator_ops hi6421_buck345_ops;
        [HI6421_##_id] = {                                              \
                .desc = {                                               \
                        .name           = #_id,                         \
-                       .of_match        = of_match_ptr(#_match),       \
-                       .regulators_node = of_match_ptr("regulators"),  \
+                       .of_match        = #_match,                     \
+                       .regulators_node = "regulators",                \
                        .ops            = &hi6421_ldo_linear_ops,       \
                        .type           = REGULATOR_VOLTAGE,            \
                        .id             = HI6421_##_id,                 \
@@ -210,8 +210,8 @@ static const struct regulator_ops hi6421_buck345_ops;
        [HI6421_##_id] = {                                              \
                .desc = {                                               \
                        .name           = #_id,                         \
-                       .of_match        = of_match_ptr(#_match),       \
-                       .regulators_node = of_match_ptr("regulators"),  \
+                       .of_match        = #_match,                     \
+                       .regulators_node = "regulators",                \
                        .ops            = &hi6421_ldo_linear_range_ops, \
                        .type           = REGULATOR_VOLTAGE,            \
                        .id             = HI6421_##_id,                 \
@@ -247,8 +247,8 @@ static const struct regulator_ops hi6421_buck345_ops;
        [HI6421_##_id] = {                                              \
                .desc = {                                               \
                        .name           = #_id,                         \
-                       .of_match        = of_match_ptr(#_match),       \
-                       .regulators_node = of_match_ptr("regulators"),  \
+                       .of_match        = #_match,                     \
+                       .regulators_node = "regulators",                \
                        .ops            = &hi6421_buck012_ops,          \
                        .type           = REGULATOR_VOLTAGE,            \
                        .id             = HI6421_##_id,                 \
@@ -284,8 +284,8 @@ static const struct regulator_ops hi6421_buck345_ops;
        [HI6421_##_id] = {                                              \
                .desc = {                                               \
                        .name           = #_id,                         \
-                       .of_match        = of_match_ptr(#_match),       \
-                       .regulators_node = of_match_ptr("regulators"),  \
+                       .of_match        = #_match,                     \
+                       .regulators_node = "regulators",                \
                        .ops            = &hi6421_buck345_ops,          \
                        .type           = REGULATOR_VOLTAGE,            \
                        .id             = HI6421_##_id,                 \
index 63aa227..942f370 100644 (file)
@@ -864,7 +864,7 @@ static struct lp872x_platform_data
 
        for (i = 0; i < num_matches; i++) {
                pdata->regulator_data[i].id =
-                               (enum lp872x_regulator_id)match[i].driver_data;
+                               (uintptr_t)match[i].driver_data;
                pdata->regulator_data[i].init_data = match[i].init_data;
        }
 out:
index 4bc310f..8d01e18 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/err.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
 #include <linux/regmap.h>
 #include <linux/uaccess.h>
 #include <linux/regulator/driver.h>
index bdb60d8..61ee5cf 100644 (file)
@@ -29,8 +29,8 @@ enum LP87565_regulator_id {
                        .name                   = _name,                \
                        .supply_name            = _of "-in",            \
                        .id                     = _id,                  \
-                       .of_match               = of_match_ptr(_of),    \
-                       .regulators_node        = of_match_ptr("regulators"),\
+                       .of_match               = _of,                  \
+                       .regulators_node        = "regulators",         \
                        .ops                    = &_ops,                \
                        .n_voltages             = _n,                   \
                        .type                   = REGULATOR_VOLTAGE,    \
index e9751c2..d892c2a 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
@@ -392,8 +391,7 @@ static int ltc3589_probe(struct i2c_client *client)
 
        i2c_set_clientdata(client, ltc3589);
        if (client->dev.of_node)
-               ltc3589->variant = (enum ltc3589_variant)
-                       of_device_get_match_data(&client->dev);
+               ltc3589->variant = (uintptr_t)of_device_get_match_data(&client->dev);
        else
                ltc3589->variant = id->driver_data;
        ltc3589->dev = dev;
index fad31f5..32f47b8 100644 (file)
@@ -6,7 +6,6 @@
 // Copyright (C) 2018 Avnet, Inc.
 
 #include <linux/err.h>
-#include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
similarity index 94%
rename from drivers/regulator/max597x-regulator.c
rename to drivers/regulator/max5970-regulator.c
index 7873a52..b56a174 100644 (file)
@@ -20,9 +20,9 @@
 #include <linux/regulator/of_regulator.h>
 #include <linux/platform_device.h>
 
-#include <linux/mfd/max597x.h>
+#include <linux/mfd/max5970.h>
 
-struct max597x_regulator {
+struct max5970_regulator {
        int num_switches, mon_rng, irng, shunt_micro_ohms, lim_uA;
        struct regmap *regmap;
 };
@@ -58,7 +58,7 @@ static int max597x_set_vp(struct regulator_dev *rdev, int lim_uV, int severity,
                          bool enable, bool overvoltage)
 {
        int off_h, off_l, reg, ret;
-       struct max597x_regulator *data = rdev_get_drvdata(rdev);
+       struct max5970_regulator *data = rdev_get_drvdata(rdev);
        int channel = rdev_get_id(rdev);
 
        if (overvoltage) {
@@ -140,7 +140,7 @@ static int max597x_set_ocp(struct regulator_dev *rdev, int lim_uA,
        int val, reg;
        unsigned int vthst, vthfst;
 
-       struct max597x_regulator *data = rdev_get_drvdata(rdev);
+       struct max5970_regulator *data = rdev_get_drvdata(rdev);
        int rdev_id = rdev_get_id(rdev);
        /*
         * MAX5970 doesn't has enable control for ocp.
@@ -222,7 +222,7 @@ static int max597x_dt_parse(struct device_node *np,
                            const struct regulator_desc *desc,
                            struct regulator_config *cfg)
 {
-       struct max597x_regulator *data = cfg->driver_data;
+       struct max5970_regulator *data = cfg->driver_data;
        int ret = 0;
 
        ret =
@@ -274,7 +274,7 @@ static int max597x_irq_handler(int irq, struct regulator_irq_data *rid,
                               unsigned long *dev_mask)
 {
        struct regulator_err_state *stat;
-       struct max597x_regulator *d = (struct max597x_regulator *)rid->data;
+       struct max5970_regulator *d = (struct max5970_regulator *)rid->data;
        int val, ret, i;
 
        ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT0, &val);
@@ -394,7 +394,7 @@ static int max597x_adc_range(struct regmap *regmap, const int ch,
 static int max597x_setup_irq(struct device *dev,
                             int irq,
                             struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES],
-                            int num_switches, struct max597x_regulator *data)
+                            int num_switches, struct max5970_regulator *data)
 {
        struct regulator_irq_desc max597x_notif = {
                .name = "max597x-irq",
@@ -425,9 +425,9 @@ static int max597x_setup_irq(struct device *dev,
 
 static int max597x_regulator_probe(struct platform_device *pdev)
 {
-       struct max597x_data *max597x;
+       struct max5970_data *max597x;
        struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
-       struct max597x_regulator *data;
+       struct max5970_regulator *data;
        struct i2c_client *i2c = to_i2c_client(pdev->dev.parent);
        struct regulator_config config = { };
        struct regulator_dev *rdev;
@@ -438,16 +438,16 @@ static int max597x_regulator_probe(struct platform_device *pdev)
        if (!regmap)
                return -EPROBE_DEFER;
 
-       max597x = devm_kzalloc(&i2c->dev, sizeof(struct max597x_data), GFP_KERNEL);
+       max597x = devm_kzalloc(&i2c->dev, sizeof(struct max5970_data), GFP_KERNEL);
        if (!max597x)
                return -ENOMEM;
 
        i2c_set_clientdata(i2c, max597x);
 
        if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5978"))
-               max597x->num_switches = MAX597x_TYPE_MAX5978;
+               max597x->num_switches = MAX5978_NUM_SWITCHES;
        else if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5970"))
-               max597x->num_switches = MAX597x_TYPE_MAX5970;
+               max597x->num_switches = MAX5970_NUM_SWITCHES;
        else
                return -ENODEV;
 
@@ -456,7 +456,7 @@ static int max597x_regulator_probe(struct platform_device *pdev)
 
        for (i = 0; i < num_switches; i++) {
                data =
-                   devm_kzalloc(&i2c->dev, sizeof(struct max597x_regulator),
+                   devm_kzalloc(&i2c->dev, sizeof(struct max5970_regulator),
                                 GFP_KERNEL);
                if (!data)
                        return -ENOMEM;
@@ -500,7 +500,7 @@ static int max597x_regulator_probe(struct platform_device *pdev)
 
 static struct platform_driver max597x_regulator_driver = {
        .driver = {
-               .name = "max597x-regulator",
+               .name = "max5970-regulator",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
        .probe = max597x_regulator_probe,
index 2976f9c..e6b3d91 100644 (file)
@@ -44,7 +44,7 @@ static const struct linear_range max77541_buck_ranges[] = {
 };
 
 static const unsigned int max77541_buck_volt_range_sel[] = {
-       0x00, 0x00, 0x40, 0x40, 0x80, 0x80,
+       0x0, 0x0, 0x1, 0x1, 0x2, 0x2,
 };
 
 enum max77541_regulators {
@@ -67,7 +67,7 @@ enum max77541_regulators {
                .vsel_mask = MAX77541_BITS_MX_VOUT,                     \
                .vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1,       \
                .vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG,           \
-               .linear_range_selectors = max77541_buck_volt_range_sel, \
+               .linear_range_selectors_bitfield = max77541_buck_volt_range_sel, \
                .owner = THIS_MODULE,                                   \
        }
 
@@ -86,7 +86,7 @@ enum max77541_regulators {
                .vsel_mask = MAX77541_BITS_MX_VOUT,                     \
                .vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1,       \
                .vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG,           \
-               .linear_range_selectors = max77541_buck_volt_range_sel, \
+               .linear_range_selectors_bitfield = max77541_buck_volt_range_sel, \
                .owner = THIS_MODULE,                                   \
        }
 
index f6539b9..94abfbb 100644 (file)
@@ -239,7 +239,7 @@ static struct max77650_regulator_desc max77651_SBB1_desc = {
                .supply_name            = "in-sbb1",
                .id                     = MAX77650_REGULATOR_ID_SBB1,
                .ops                    = &max77651_SBB1_regulator_ops,
-               .linear_range_selectors = max77651_sbb1_volt_range_sel,
+               .linear_range_selectors_bitfield        = max77651_sbb1_volt_range_sel,
                .linear_ranges          = max77651_sbb1_volt_ranges,
                .n_linear_ranges        = ARRAY_SIZE(max77651_sbb1_volt_ranges),
                .n_voltages             = 58,
index 3855f5e..5590cdf 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c
new file mode 100644 (file)
index 0000000..145ad02
--- /dev/null
@@ -0,0 +1,461 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023 Analog Devices, Inc.
+ * ADI Regulator driver for the MAX77857
+ * MAX77859 and MAX77831.
+ */
+#include <linux/bitfield.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/util_macros.h>
+
+#define MAX77857_REG_INT_SRC           0x10
+#define MAX77857_REG_INT_MASK          0x11
+#define MAX77857_REG_CONT1             0x12
+#define MAX77857_REG_CONT2             0x13
+#define MAX77857_REG_CONT3             0x14
+
+#define MAX77857_INT_SRC_OCP           BIT(0)
+#define MAX77857_INT_SRC_THS           BIT(1)
+#define MAX77857_INT_SRC_HARDSHORT     BIT(2)
+#define MAX77857_INT_SRC_OVP           BIT(3)
+#define MAX77857_INT_SRC_POK           BIT(4)
+
+#define MAX77857_ILIM_MASK             GENMASK(2, 0)
+#define MAX77857_CONT1_FREQ            GENMASK(4, 3)
+#define MAX77857_CONT3_FPWM            BIT(5)
+
+#define MAX77859_REG_INT_SRC           0x11
+#define MAX77859_REG_CONT1             0x13
+#define MAX77859_REG_CONT2             0x14
+#define MAX77859_REG_CONT3             0x15
+#define MAX77859_REG_CONT5             0x17
+#define MAX77859_CONT2_FPWM            BIT(2)
+#define MAX77859_CONT2_INTB            BIT(3)
+#define MAX77859_CONT3_DVS_START       BIT(2)
+#define MAX77859_VOLTAGE_SEL_MASK      GENMASK(9, 0)
+
+#define MAX77859_CURRENT_MIN           1000000
+#define MAX77859_CURRENT_MAX           5000000
+#define MAX77859_CURRENT_STEP          50000
+
+enum max77857_id {
+       ID_MAX77831 = 1,
+       ID_MAX77857,
+       ID_MAX77859,
+       ID_MAX77859A,
+};
+
+static bool max77857_volatile_reg(struct device *dev, unsigned int reg)
+{
+       enum max77857_id id = (uintptr_t)dev_get_drvdata(dev);
+
+       switch (id) {
+       case ID_MAX77831:
+       case ID_MAX77857:
+               return reg == MAX77857_REG_INT_SRC;
+       case ID_MAX77859:
+       case ID_MAX77859A:
+               return reg == MAX77859_REG_INT_SRC;
+       default:
+               return true;
+       }
+}
+
+static struct regmap_config max77857_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .cache_type = REGCACHE_MAPLE,
+       .volatile_reg = max77857_volatile_reg,
+};
+
+static int max77857_get_status(struct regulator_dev *rdev)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val);
+       if (ret)
+               return ret;
+
+       if (FIELD_GET(MAX77857_INT_SRC_POK, val))
+               return REGULATOR_STATUS_ON;
+
+       return REGULATOR_STATUS_ERROR;
+}
+
+static unsigned int max77857_get_mode(struct regulator_dev *rdev)
+{
+       enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev);
+       unsigned int regval;
+       int ret;
+
+       switch (id) {
+       case ID_MAX77831:
+       case ID_MAX77857:
+               ret = regmap_read(rdev->regmap, MAX77857_REG_CONT3, &regval);
+               if (ret)
+                       return ret;
+
+               if (FIELD_GET(MAX77857_CONT3_FPWM, regval))
+                       return REGULATOR_MODE_FAST;
+
+               break;
+       case ID_MAX77859:
+       case ID_MAX77859A:
+               ret = regmap_read(rdev->regmap, MAX77859_REG_CONT2, &regval);
+               if (ret)
+                       return ret;
+
+               if (FIELD_GET(MAX77859_CONT2_FPWM, regval))
+                       return REGULATOR_MODE_FAST;
+
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return REGULATOR_MODE_NORMAL;
+}
+
+static int max77857_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev);
+       unsigned int reg, val;
+
+       switch (id) {
+       case ID_MAX77831:
+       case ID_MAX77857:
+               reg = MAX77857_REG_CONT3;
+               val = MAX77857_CONT3_FPWM;
+               break;
+       case ID_MAX77859:
+       case ID_MAX77859A:
+               reg = MAX77859_REG_CONT2;
+               val = MAX77859_CONT2_FPWM;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+               return regmap_set_bits(rdev->regmap, reg, val);
+       case REGULATOR_MODE_NORMAL:
+               return regmap_clear_bits(rdev->regmap, reg, val);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int max77857_get_error_flags(struct regulator_dev *rdev,
+                                   unsigned int *flags)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val);
+       if (ret)
+               return ret;
+
+       *flags = 0;
+
+       if (FIELD_GET(MAX77857_INT_SRC_OVP, val))
+               *flags |= REGULATOR_ERROR_OVER_VOLTAGE_WARN;
+
+       if (FIELD_GET(MAX77857_INT_SRC_OCP, val) ||
+           FIELD_GET(MAX77857_INT_SRC_HARDSHORT, val))
+               *flags |= REGULATOR_ERROR_OVER_CURRENT;
+
+       if (FIELD_GET(MAX77857_INT_SRC_THS, val))
+               *flags |= REGULATOR_ERROR_OVER_TEMP;
+
+       if (!FIELD_GET(MAX77857_INT_SRC_POK, val))
+               *flags |= REGULATOR_ERROR_FAIL;
+
+       return 0;
+}
+
+static struct linear_range max77859_lin_ranges[] = {
+       REGULATOR_LINEAR_RANGE(3200000, 0x0A0, 0x320, 20000)
+};
+
+static const unsigned int max77859_ramp_table[4] = {
+       1000, 500, 250, 125
+};
+
+static int max77859_set_voltage_sel(struct regulator_dev *rdev,
+                                   unsigned int sel)
+{
+       __be16 reg;
+       int ret;
+
+       reg = cpu_to_be16(sel);
+
+       ret = regmap_bulk_write(rdev->regmap, MAX77859_REG_CONT3, &reg, 2);
+       if (ret)
+               return ret;
+
+       /* actually apply new voltage */
+       return regmap_set_bits(rdev->regmap, MAX77859_REG_CONT3,
+                              MAX77859_CONT3_DVS_START);
+}
+
+static int max77859_get_voltage_sel(struct regulator_dev *rdev)
+{
+       __be16 reg;
+       int ret;
+
+       ret = regmap_bulk_read(rdev->regmap, MAX77859_REG_CONT3, &reg, 2);
+       if (ret)
+               return ret;
+
+       return FIELD_GET(MAX77859_VOLTAGE_SEL_MASK, __be16_to_cpu(reg));
+}
+
+static int max77859_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)
+{
+       u32 selector;
+
+       if (max_uA < MAX77859_CURRENT_MIN)
+               return -EINVAL;
+
+       selector = 0x12 + (max_uA - MAX77859_CURRENT_MIN) / MAX77859_CURRENT_STEP;
+
+       selector = clamp_val(selector, 0x00, 0x7F);
+
+       return regmap_write(rdev->regmap, MAX77859_REG_CONT5, selector);
+}
+
+static int max77859_get_current_limit(struct regulator_dev *rdev)
+{
+       u32 selector;
+       int ret;
+
+       ret = regmap_read(rdev->regmap, MAX77859_REG_CONT5, &selector);
+       if (ret)
+               return ret;
+
+       if (selector <= 0x12)
+               return MAX77859_CURRENT_MIN;
+
+       if (selector >= 0x64)
+               return MAX77859_CURRENT_MAX;
+
+       return MAX77859_CURRENT_MIN + (selector - 0x12) * MAX77859_CURRENT_STEP;
+}
+
+static const struct regulator_ops max77859_regulator_ops = {
+       .list_voltage = regulator_list_voltage_linear_range,
+       .set_voltage_sel = max77859_set_voltage_sel,
+       .get_voltage_sel = max77859_get_voltage_sel,
+       .set_ramp_delay = regulator_set_ramp_delay_regmap,
+       .get_status = max77857_get_status,
+       .set_mode = max77857_set_mode,
+       .get_mode = max77857_get_mode,
+       .get_error_flags = max77857_get_error_flags,
+};
+
+static const struct regulator_ops max77859a_regulator_ops = {
+       .list_voltage = regulator_list_voltage_linear_range,
+       .set_voltage_sel = max77859_set_voltage_sel,
+       .get_voltage_sel = max77859_get_voltage_sel,
+       .set_current_limit = max77859_set_current_limit,
+       .get_current_limit = max77859_get_current_limit,
+       .set_ramp_delay = regulator_set_ramp_delay_regmap,
+       .get_status = max77857_get_status,
+       .set_mode = max77857_set_mode,
+       .get_mode = max77857_get_mode,
+       .get_error_flags = max77857_get_error_flags,
+};
+
+static const struct regulator_ops max77857_regulator_ops = {
+       .list_voltage = regulator_list_voltage_linear_range,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .set_ramp_delay = regulator_set_ramp_delay_regmap,
+       .get_status = max77857_get_status,
+       .set_mode = max77857_set_mode,
+       .get_mode = max77857_get_mode,
+       .get_error_flags = max77857_get_error_flags,
+};
+
+static struct linear_range max77857_lin_ranges[] = {
+       REGULATOR_LINEAR_RANGE(4485000, 0x3D, 0xCC, 73500)
+};
+
+static const unsigned int max77857_switch_freq[] = {
+       1200000, 1500000, 1800000, 2100000
+};
+
+#define RAMAP_DELAY_INIT_VAL 1333
+
+static const unsigned int max77857_ramp_table[2][4] = {
+       { RAMAP_DELAY_INIT_VAL, 667, 333, 227 }, /* when switch freq is 1.8MHz or 2.1MHz */
+       { 1166, 667, 333, 167 }, /* when switch freq is 1.2MHz or 1.5MHz */
+};
+
+static struct regulator_desc max77857_regulator_desc = {
+       .ops = &max77857_regulator_ops,
+       .name = "max77857",
+       .linear_ranges = max77857_lin_ranges,
+       .n_linear_ranges = ARRAY_SIZE(max77857_lin_ranges),
+       .vsel_mask = 0xFF,
+       .vsel_reg = MAX77857_REG_CONT2,
+       .ramp_delay_table = max77857_ramp_table[0],
+       .n_ramp_values = ARRAY_SIZE(max77857_ramp_table[0]),
+       .ramp_reg = MAX77857_REG_CONT3,
+       .ramp_mask = GENMASK(1, 0),
+       .ramp_delay = RAMAP_DELAY_INIT_VAL,
+       .owner = THIS_MODULE,
+};
+
+static void max77857_calc_range(struct device *dev, enum max77857_id id)
+{
+       struct linear_range *range;
+       unsigned long vref_step;
+       u32 rtop = 0;
+       u32 rbot = 0;
+
+       device_property_read_u32(dev, "adi,rtop-ohms", &rtop);
+       device_property_read_u32(dev, "adi,rbot-ohms", &rbot);
+
+       if (!rbot || !rtop)
+               return;
+
+       switch (id) {
+       case ID_MAX77831:
+       case ID_MAX77857:
+               range = max77857_lin_ranges;
+               vref_step = 4900UL;
+               break;
+       case ID_MAX77859:
+       case ID_MAX77859A:
+               range = max77859_lin_ranges;
+               vref_step = 1250UL;
+               break;
+       }
+
+       range->step = DIV_ROUND_CLOSEST(vref_step * (rbot + rtop), rbot);
+       range->min = range->step * range->min_sel;
+}
+
+static int max77857_probe(struct i2c_client *client)
+{
+       const struct i2c_device_id *i2c_id;
+       struct device *dev = &client->dev;
+       struct regulator_config cfg = { };
+       struct regulator_dev *rdev;
+       struct regmap *regmap;
+       enum max77857_id id;
+       u32 switch_freq = 0;
+       int ret;
+
+       i2c_id = i2c_client_get_device_id(client);
+       if (!i2c_id)
+               return -EINVAL;
+
+       id = i2c_id->driver_data;
+
+       dev_set_drvdata(dev, (void *)id);
+
+       if (id == ID_MAX77859 || id == ID_MAX77859A) {
+               max77857_regulator_desc.ops = &max77859_regulator_ops;
+               max77857_regulator_desc.linear_ranges = max77859_lin_ranges;
+               max77857_regulator_desc.ramp_delay_table = max77859_ramp_table;
+               max77857_regulator_desc.ramp_delay = max77859_ramp_table[0];
+       }
+
+       if (id == ID_MAX77859A)
+               max77857_regulator_desc.ops = &max77859a_regulator_ops;
+
+       max77857_calc_range(dev, id);
+
+       regmap = devm_regmap_init_i2c(client, &max77857_regmap_config);
+       if (IS_ERR(regmap))
+               return dev_err_probe(dev, PTR_ERR(regmap),
+                                    "cannot initialize regmap\n");
+
+       device_property_read_u32(dev, "adi,switch-frequency-hz", &switch_freq);
+       if (switch_freq) {
+               switch_freq = find_closest(switch_freq, max77857_switch_freq,
+                                          ARRAY_SIZE(max77857_switch_freq));
+
+               if (id == ID_MAX77831 && switch_freq == 3)
+                       switch_freq = 2;
+
+               switch (id) {
+               case ID_MAX77831:
+               case ID_MAX77857:
+                       ret = regmap_update_bits(regmap, MAX77857_REG_CONT1,
+                                                MAX77857_CONT1_FREQ, switch_freq);
+
+                       if (switch_freq >= 2)
+                               break;
+
+                       max77857_regulator_desc.ramp_delay_table = max77857_ramp_table[1];
+                       max77857_regulator_desc.ramp_delay = max77857_ramp_table[1][0];
+                       break;
+               case ID_MAX77859:
+               case ID_MAX77859A:
+                       ret = regmap_update_bits(regmap, MAX77859_REG_CONT1,
+                                                MAX77857_CONT1_FREQ, switch_freq);
+                       break;
+               }
+               if (ret)
+                       return ret;
+       }
+
+       cfg.dev = dev;
+       cfg.driver_data = (void *)id;
+       cfg.regmap = regmap;
+       cfg.init_data = of_get_regulator_init_data(dev, dev->of_node,
+                                                  &max77857_regulator_desc);
+       if (!cfg.init_data)
+               return -ENOMEM;
+
+       rdev = devm_regulator_register(dev, &max77857_regulator_desc, &cfg);
+       if (IS_ERR(rdev))
+               return dev_err_probe(dev, PTR_ERR(rdev),
+                                    "cannot register regulator\n");
+
+       return 0;
+}
+
+const struct i2c_device_id max77857_id[] = {
+       { "max77831", ID_MAX77831 },
+       { "max77857", ID_MAX77857 },
+       { "max77859", ID_MAX77859 },
+       { "max77859a", ID_MAX77859A },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, max77857_id);
+
+static const struct of_device_id max77857_of_id[] = {
+       { .compatible = "adi,max77831", .data = (void *)ID_MAX77831 },
+       { .compatible = "adi,max77857", .data = (void *)ID_MAX77857 },
+       { .compatible = "adi,max77859", .data = (void *)ID_MAX77859 },
+       { .compatible = "adi,max77859a", .data = (void *)ID_MAX77859A },
+       { }
+};
+MODULE_DEVICE_TABLE(of, max77857_of_id);
+
+static struct i2c_driver max77857_driver = {
+       .driver = {
+               .name = "max77857",
+               .of_match_table = max77857_of_id,
+       },
+       .id_table = max77857_id,
+       .probe = max77857_probe,
+};
+module_i2c_driver(max77857_driver);
+
+MODULE_DESCRIPTION("Analog Devices MAX77857 Buck-Boost Converter Driver");
+MODULE_AUTHOR("Ibrahim Tilki <Ibrahim.Tilki@analog.com>");
+MODULE_AUTHOR("Okan Sahin <Okan.Sahin@analog.com>");
+MODULE_LICENSE("GPL");
index cb0e729..3059242 100644 (file)
@@ -125,7 +125,7 @@ static const struct regmap_config max8893_regmap = {
        .val_bits = 8,
 };
 
-static int max8893_probe_new(struct i2c_client *i2c)
+static int max8893_probe(struct i2c_client *i2c)
 {
        int id, ret;
        struct regulator_config config = {.dev = &i2c->dev};
@@ -168,7 +168,7 @@ static const struct i2c_device_id max8893_ids[] = {
 MODULE_DEVICE_TABLE(i2c, max8893_ids);
 
 static struct i2c_driver max8893_driver = {
-       .probe          = max8893_probe_new,
+       .probe          = max8893_probe,
        .driver         = {
                .name   = "max8893",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
index 6c6f5a2..0c15a19 100644 (file)
@@ -8,7 +8,6 @@
 //
 // Inspired from tps65086-regulator.c
 
-#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -111,7 +110,7 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode)
 #define MCP16502_REGULATOR(_name, _id, _ranges, _ops, _ramp_table)     \
        [_id] = {                                                       \
                .name                   = _name,                        \
-               .regulators_node        = of_match_ptr("regulators"),   \
+               .regulators_node        = "regulators",                 \
                .id                     = _id,                          \
                .ops                    = &(_ops),                      \
                .type                   = REGULATOR_VOLTAGE,            \
@@ -120,7 +119,7 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode)
                .linear_ranges          = _ranges,                      \
                .linear_min_sel         = VDD_LOW_SEL,                  \
                .n_linear_ranges        = ARRAY_SIZE(_ranges),          \
-               .of_match               = of_match_ptr(_name),          \
+               .of_match               = _name,                        \
                .of_map_mode            = mcp16502_of_map_mode,         \
                .vsel_reg               = (((_id) + 1) << 4),           \
                .vsel_mask              = MCP16502_VSEL,                \
@@ -588,7 +587,7 @@ static struct i2c_driver mcp16502_drv = {
        .driver         = {
                .name   = "mcp16502-regulator",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
-               .of_match_table = of_match_ptr(mcp16502_ids),
+               .of_match_table = mcp16502_ids,
 #ifdef CONFIG_PM
                .pm = &mcp16502_pm_ops,
 #endif
index 3886b25..d068ac9 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
index ede1b1e..9911be2 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
index bf677c5..a670e09 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
@@ -319,7 +318,7 @@ static struct i2c_driver mpq7920_regulator_driver = {
        .driver = {
                .name = "mpq7920",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
-               .of_match_table = of_match_ptr(mpq7920_of_match),
+               .of_match_table = mpq7920_of_match,
        },
        .probe = mpq7920_i2c_probe,
        .id_table = mpq7920_id,
index b077177..63a5148 100644 (file)
@@ -4,7 +4,6 @@
 // Author: Henry Chen <henryc.chen@mediatek.com>
 
 #include <linux/err.h>
-#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index 8047081..2608a66 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2021 MediaTek Inc.
 
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
index 3eb86ec..c8a7888 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/mfd/mt6359p/registers.h>
 #include <linux/mfd/mt6397/core.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
index efca672..f1280d4 100644 (file)
@@ -6,8 +6,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
+#include <linux/of_.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/soc/mediatek/mtk_dvfsrc.h>
index 0c9873e..cd5a0d7 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 
 struct pbias_reg_info {
        u32 enable;
index 91bfb7e..2ab365d 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
index 8d7e6c3..4685460 100644 (file)
@@ -699,8 +699,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client)
                return -ENOMEM;
 
        if (client->dev.of_node) {
-               match = of_match_device(of_match_ptr(pfuze_dt_ids),
-                               &client->dev);
+               match = of_match_device(pfuze_dt_ids, &client->dev);
                if (!match) {
                        dev_err(&client->dev, "Error: No device match found\n");
                        return -ENODEV;
index b64d996..2aff6db 100644 (file)
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/pwm.h>
 #include <linux/gpio/consumer.h>
 
diff --git a/drivers/regulator/qcom-refgen-regulator.c b/drivers/regulator/qcom-refgen-regulator.c
new file mode 100644 (file)
index 0000000..656fe33
--- /dev/null
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2017, 2019-2020, The Linux Foundation. All rights reserved.
+// Copyright (c) 2023, Linaro Limited
+
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+#define REFGEN_REG_BIAS_EN             0x08
+#define REFGEN_BIAS_EN_MASK            GENMASK(2, 0)
+ #define REFGEN_BIAS_EN_ENABLE         0x7
+ #define REFGEN_BIAS_EN_DISABLE                0x6
+
+#define REFGEN_REG_BG_CTRL             0x14
+#define REFGEN_BG_CTRL_MASK            GENMASK(2, 1)
+ #define REFGEN_BG_CTRL_ENABLE         0x3
+ #define REFGEN_BG_CTRL_DISABLE                0x2
+
+#define REFGEN_REG_PWRDWN_CTRL5                0x80
+#define REFGEN_PWRDWN_CTRL5_MASK       BIT(0)
+ #define REFGEN_PWRDWN_CTRL5_ENABLE    0x1
+
+static int qcom_sdm845_refgen_enable(struct regulator_dev *rdev)
+{
+       regmap_update_bits(rdev->regmap, REFGEN_REG_BG_CTRL, REFGEN_BG_CTRL_MASK,
+                          FIELD_PREP(REFGEN_BG_CTRL_MASK, REFGEN_BG_CTRL_ENABLE));
+
+       regmap_write(rdev->regmap, REFGEN_REG_BIAS_EN,
+                    FIELD_PREP(REFGEN_BIAS_EN_MASK, REFGEN_BIAS_EN_ENABLE));
+
+       return 0;
+}
+
+static int qcom_sdm845_refgen_disable(struct regulator_dev *rdev)
+{
+       regmap_write(rdev->regmap, REFGEN_REG_BIAS_EN,
+                    FIELD_PREP(REFGEN_BIAS_EN_MASK, REFGEN_BIAS_EN_DISABLE));
+
+       regmap_update_bits(rdev->regmap, REFGEN_REG_BG_CTRL, REFGEN_BG_CTRL_MASK,
+                          FIELD_PREP(REFGEN_BG_CTRL_MASK, REFGEN_BG_CTRL_DISABLE));
+
+       return 0;
+}
+
+static int qcom_sdm845_refgen_is_enabled(struct regulator_dev *rdev)
+{
+       u32 val;
+
+       regmap_read(rdev->regmap, REFGEN_REG_BG_CTRL, &val);
+       if (FIELD_GET(REFGEN_BG_CTRL_MASK, val) != REFGEN_BG_CTRL_ENABLE)
+               return 0;
+
+       regmap_read(rdev->regmap, REFGEN_REG_BIAS_EN, &val);
+       if (FIELD_GET(REFGEN_BIAS_EN_MASK, val) != REFGEN_BIAS_EN_ENABLE)
+               return 0;
+
+       return 1;
+}
+
+static struct regulator_desc sdm845_refgen_desc = {
+       .enable_time = 5,
+       .name = "refgen",
+       .owner = THIS_MODULE,
+       .type = REGULATOR_VOLTAGE,
+       .ops = &(const struct regulator_ops) {
+               .enable         = qcom_sdm845_refgen_enable,
+               .disable        = qcom_sdm845_refgen_disable,
+               .is_enabled     = qcom_sdm845_refgen_is_enabled,
+       },
+};
+
+static struct regulator_desc sm8250_refgen_desc = {
+       .enable_reg = REFGEN_REG_PWRDWN_CTRL5,
+       .enable_mask = REFGEN_PWRDWN_CTRL5_MASK,
+       .enable_val = REFGEN_PWRDWN_CTRL5_ENABLE,
+       .disable_val = 0,
+       .enable_time = 5,
+       .name = "refgen",
+       .owner = THIS_MODULE,
+       .type = REGULATOR_VOLTAGE,
+       .ops = &(const struct regulator_ops) {
+               .enable         = regulator_enable_regmap,
+               .disable        = regulator_disable_regmap,
+               .is_enabled     = regulator_is_enabled_regmap,
+       },
+};
+
+static const struct regmap_config qcom_refgen_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .fast_io = true,
+};
+
+static int qcom_refgen_probe(struct platform_device *pdev)
+{
+       struct regulator_init_data *init_data;
+       struct regulator_config config = {};
+       const struct regulator_desc *rdesc;
+       struct device *dev = &pdev->dev;
+       struct regulator_dev *rdev;
+       struct regmap *regmap;
+       void __iomem *base;
+
+       rdesc = of_device_get_match_data(dev);
+       if (!rdesc)
+               return -ENODATA;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       regmap = devm_regmap_init_mmio(dev, base, &qcom_refgen_regmap_config);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       init_data = of_get_regulator_init_data(dev, dev->of_node, rdesc);
+       if (!init_data)
+               return -ENOMEM;
+
+       config.dev = dev;
+       config.init_data = init_data;
+       config.of_node = dev->of_node;
+       config.regmap = regmap;
+
+       rdev = devm_regulator_register(dev, rdesc, &config);
+       if (IS_ERR(rdev))
+               return PTR_ERR(rdev);
+
+       return 0;
+}
+
+static const struct of_device_id qcom_refgen_match_table[] = {
+       { .compatible = "qcom,sdm845-refgen-regulator", .data = &sdm845_refgen_desc },
+       { .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_refgen_desc },
+       { }
+};
+
+static struct platform_driver qcom_refgen_driver = {
+       .probe = qcom_refgen_probe,
+       .driver = {
+               .name = "qcom-refgen-regulator",
+               .of_match_table = qcom_refgen_match_table,
+       },
+};
+module_platform_driver(qcom_refgen_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Qualcomm REFGEN regulator driver");
index cd077b7..d990ba1 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -1273,6 +1272,40 @@ static const struct rpmh_vreg_init_data pmx65_vreg_data[] = {
        {}
 };
 
+static const struct rpmh_vreg_init_data pmx75_vreg_data[] = {
+       RPMH_VREG("smps1",   "smp%s1",    &pmic5_ftsmps525_lv, "vdd-s1"),
+       RPMH_VREG("smps2",   "smp%s2",    &pmic5_ftsmps525_lv, "vdd-s2"),
+       RPMH_VREG("smps3",   "smp%s3",    &pmic5_ftsmps525_lv, "vdd-s3"),
+       RPMH_VREG("smps4",   "smp%s4",    &pmic5_ftsmps525_mv, "vdd-s4"),
+       RPMH_VREG("smps5",   "smp%s5",    &pmic5_ftsmps525_lv, "vdd-s5"),
+       RPMH_VREG("smps6",   "smp%s6",    &pmic5_ftsmps525_lv, "vdd-s6"),
+       RPMH_VREG("smps7",   "smp%s7",    &pmic5_ftsmps525_lv, "vdd-s7"),
+       RPMH_VREG("smps8",   "smp%s8",    &pmic5_ftsmps525_lv, "vdd-s8"),
+       RPMH_VREG("smps9",   "smp%s9",    &pmic5_ftsmps525_lv, "vdd-s9"),
+       RPMH_VREG("smps10",  "smp%s10",   &pmic5_ftsmps525_lv, "vdd-s10"),
+       RPMH_VREG("ldo1",    "ldo%s1",    &pmic5_nldo515,   "vdd-l1"),
+       RPMH_VREG("ldo2",    "ldo%s2",    &pmic5_nldo515,   "vdd-l2-18"),
+       RPMH_VREG("ldo3",    "ldo%s3",    &pmic5_nldo515,   "vdd-l3"),
+       RPMH_VREG("ldo4",    "ldo%s4",    &pmic5_nldo515,   "vdd-l4-l16"),
+       RPMH_VREG("ldo5",    "ldo%s5",    &pmic5_pldo_lv,   "vdd-l5-l6"),
+       RPMH_VREG("ldo6",    "ldo%s6",    &pmic5_pldo_lv,   "vdd-l5-l6"),
+       RPMH_VREG("ldo7",    "ldo%s7",    &pmic5_nldo515,   "vdd-l7"),
+       RPMH_VREG("ldo8",    "ldo%s8",    &pmic5_nldo515,   "vdd-l8-l9"),
+       RPMH_VREG("ldo9",    "ldo%s9",    &pmic5_nldo515,   "vdd-l8-l9"),
+       RPMH_VREG("ldo10",   "ldo%s10",   &pmic5_pldo,      "vdd-l10"),
+       RPMH_VREG("ldo11",   "ldo%s11",   &pmic5_pldo,      "vdd-l11-l13"),
+       RPMH_VREG("ldo12",   "ldo%s12",   &pmic5_nldo515,   "vdd-l12"),
+       RPMH_VREG("ldo13",   "ldo%s13",   &pmic5_pldo,      "vdd-l11-l13"),
+       RPMH_VREG("ldo14",   "ldo%s14",   &pmic5_nldo515,   "vdd-l14"),
+       RPMH_VREG("ldo15",   "ldo%s15",   &pmic5_nldo515,   "vdd-l15"),
+       RPMH_VREG("ldo16",   "ldo%s16",   &pmic5_nldo515,   "vdd-l4-l16"),
+       RPMH_VREG("ldo17",   "ldo%s17",   &pmic5_nldo515,   "vdd-l17"),
+       /* ldo18 not configured */
+       RPMH_VREG("ldo19",   "ldo%s19",   &pmic5_nldo515,   "vdd-l19"),
+       RPMH_VREG("ldo20",   "ldo%s20",   &pmic5_nldo515,   "vdd-l20-l21"),
+       RPMH_VREG("ldo21",   "ldo%s21",   &pmic5_nldo515,   "vdd-l20-l21"),
+};
+
 static const struct rpmh_vreg_init_data pm7325_vreg_data[] = {
        RPMH_VREG("smps1",  "smp%s1",  &pmic5_hfsmps510, "vdd-s1"),
        RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps520, "vdd-s2"),
@@ -1495,6 +1528,10 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
                .data = pmx65_vreg_data,
        },
        {
+               .compatible = "qcom,pmx75-rpmh-regulators",
+               .data = pmx75_vreg_data,
+       },
+       {
                .compatible = "qcom,pm7325-rpmh-regulators",
                .data = pm7325_vreg_data,
        },
index f95bc92..9366488 100644 (file)
@@ -956,11 +956,10 @@ static int rpm_reg_probe(struct platform_device *pdev)
        }
 
        for (reg = match->data; reg->name; reg++) {
-               vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
+               vreg = devm_kmemdup(&pdev->dev, reg->template, sizeof(*vreg), GFP_KERNEL);
                if (!vreg)
                        return -ENOMEM;
 
-               memcpy(vreg, reg->template, sizeof(*vreg));
                mutex_init(&vreg->lock);
 
                vreg->dev = &pdev->dev;
index 18189f3..f53ada0 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
index 57ec613..cd94ed6 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
index 24a1c89..6982565 100644 (file)
 #define RAA215300_REG_BLOCK_EN_RTC_EN  BIT(6)
 #define RAA215300_RTC_DEFAULT_ADDR     0x6f
 
-const char *clkin_name = "clkin";
-const char *xin_name = "xin";
-static struct clk *clk;
-
 static const struct regmap_config raa215300_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
@@ -51,10 +47,6 @@ static const struct regmap_config raa215300_regmap_config = {
 static void raa215300_rtc_unregister_device(void *data)
 {
        i2c_unregister_device(data);
-       if (!clk) {
-               clk_unregister_fixed_rate(clk);
-               clk = NULL;
-       }
 }
 
 static int raa215300_clk_present(struct i2c_client *client, const char *name)
@@ -71,8 +63,10 @@ static int raa215300_clk_present(struct i2c_client *client, const char *name)
 static int raa215300_i2c_probe(struct i2c_client *client)
 {
        struct device *dev = &client->dev;
-       const char *clk_name = xin_name;
+       const char *clkin_name = "clkin";
        unsigned int pmic_version, val;
+       const char *xin_name = "xin";
+       const char *clk_name = NULL;
        struct regmap *regmap;
        int ret;
 
@@ -92,7 +86,7 @@ static int raa215300_i2c_probe(struct i2c_client *client)
        val &= RAA215300_REG_BLOCK_EN_RTC_EN;
        regmap_write(regmap, RAA215300_REG_BLOCK_EN, val);
 
-       /*Clear the latched registers */
+       /* Clear the latched registers */
        regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_1, &val);
        regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_1, val);
        regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_2, &val);
@@ -114,24 +108,32 @@ static int raa215300_i2c_probe(struct i2c_client *client)
        ret = raa215300_clk_present(client, xin_name);
        if (ret < 0) {
                return ret;
-       } else if (!ret) {
+       } else if (ret) {
+               clk_name = xin_name;
+       } else {
                ret = raa215300_clk_present(client, clkin_name);
                if (ret < 0)
                        return ret;
-
-               clk_name = clkin_name;
+               if (ret)
+                       clk_name = clkin_name;
        }
 
-       if (ret) {
-               char *name = pmic_version >= 0x12 ? "isl1208" : "raa215300_a0";
+       if (clk_name) {
+               const char *name = pmic_version >= 0x12 ? "isl1208" : "raa215300_a0";
                struct device_node *np = client->dev.of_node;
                u32 addr = RAA215300_RTC_DEFAULT_ADDR;
                struct i2c_board_info info = {};
                struct i2c_client *rtc_client;
+               struct clk_hw *hw;
                ssize_t size;
 
-               clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, 32000);
-               clk_register_clkdev(clk, clk_name, NULL);
+               hw = devm_clk_hw_register_fixed_rate(dev, clk_name, NULL, 0, 32768);
+               if (IS_ERR(hw))
+                       return PTR_ERR(hw);
+
+               ret = devm_clk_hw_register_clkdev(dev, hw, clk_name, NULL);
+               if (ret)
+                       return dev_err_probe(dev, ret, "Failed to initialize clkdev\n");
 
                if (np) {
                        int i;
@@ -180,7 +182,7 @@ static struct i2c_driver raa215300_i2c_driver = {
                .name = "raa215300",
                .of_match_table = raa215300_dt_match,
        },
-       .probe_new = raa215300_i2c_probe,
+       .probe = raa215300_i2c_probe,
 };
 module_i2c_driver(raa215300_i2c_driver);
 
index a5afca7..a25a141 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
-#include <linux/gpio.h>
 #include <linux/mfd/rc5t583.h>
 
 struct rc5t583_regulator_info {
index 460525e..867a2cf 100644 (file)
 #include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/mfd/rk808.h>
+#include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/gpio/consumer.h>
index f97a9a5..0e2418e 100644 (file)
@@ -36,7 +36,7 @@ static int set_dvs_level(const struct regulator_desc *desc,
        }
        for (i = 0; i < desc->n_voltages; i++) {
                /* NOTE to next hacker - Does not support pickable ranges */
-               if (desc->linear_range_selectors)
+               if (desc->linear_range_selectors_bitfield)
                        return -EINVAL;
                if (desc->n_linear_ranges)
                        ret = regulator_desc_list_voltage_linear_range(desc, i);
index e9719a3..f52c3d4 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <linux/backlight.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
 #include <linux/gpio/driver.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
@@ -397,7 +396,7 @@ static struct i2c_driver attiny_regulator_driver = {
        .driver = {
                .name = "rpi_touchscreen_attiny",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
-               .of_match_table = of_match_ptr(attiny_dt_ids),
+               .of_match_table = attiny_dt_ids,
        },
        .probe = attiny_i2c_probe,
        .remove = attiny_i2c_remove,
index 0ce6a16..91412c9 100644 (file)
 #define RT5739_MODEVSEL1_MASK  BIT(1)
 #define RT5739_MODEVSEL0_MASK  BIT(0)
 #define RT5739_VID_MASK                GENMASK(7, 5)
+#define RT5739_DID_MASK                GENMASK(3, 0)
 #define RT5739_ACTD_MASK       BIT(7)
 #define RT5739_ENVSEL1_MASK    BIT(1)
 #define RT5739_ENVSEL0_MASK    BIT(0)
 
+#define RT5733_CHIPDIE_ID      0x1
+#define RT5733_VOLT_MINUV      270000
+#define RT5733_VOLT_MAXUV      1401250
+#define RT5733_VOLT_STPUV      6250
+#define RT5733_N_VOLTS         182
+
 #define RT5739_VOLT_MINUV      300000
 #define RT5739_VOLT_MAXUV      1300000
 #define RT5739_VOLT_STPUV      5000
@@ -93,8 +100,11 @@ static int rt5739_set_suspend_voltage(struct regulator_dev *rdev, int uV)
        const struct regulator_desc *desc = rdev->desc;
        struct regmap *regmap = rdev_get_regmap(rdev);
        unsigned int reg, vsel;
+       int max_uV;
+
+       max_uV = desc->min_uV + desc->uV_step * (desc->n_voltages - 1);
 
-       if (uV < RT5739_VOLT_MINUV || uV > RT5739_VOLT_MAXUV)
+       if (uV < desc->min_uV || uV > max_uV)
                return -EINVAL;
 
        if (desc->vsel_reg == RT5739_REG_NSEL0)
@@ -102,7 +112,7 @@ static int rt5739_set_suspend_voltage(struct regulator_dev *rdev, int uV)
        else
                reg = RT5739_REG_NSEL0;
 
-       vsel = (uV - RT5739_VOLT_MINUV) / RT5739_VOLT_STPUV;
+       vsel = (uV - desc->min_uV) / desc->uV_step;
        return regmap_write(regmap, reg, vsel);
 }
 
@@ -189,15 +199,12 @@ static unsigned int rt5739_of_map_mode(unsigned int mode)
 }
 
 static void rt5739_init_regulator_desc(struct regulator_desc *desc,
-                                      bool vsel_active_high)
+                                      bool vsel_active_high, u8 did)
 {
        /* Fixed */
        desc->name = "rt5739-regulator";
        desc->owner = THIS_MODULE;
        desc->ops = &rt5739_regulator_ops;
-       desc->n_voltages = RT5739_N_VOLTS;
-       desc->min_uV = RT5739_VOLT_MINUV;
-       desc->uV_step = RT5739_VOLT_STPUV;
        desc->vsel_mask = RT5739_VSEL_MASK;
        desc->enable_reg = RT5739_REG_CNTL2;
        desc->active_discharge_reg = RT5739_REG_CNTL1;
@@ -213,6 +220,20 @@ static void rt5739_init_regulator_desc(struct regulator_desc *desc,
                desc->vsel_reg = RT5739_REG_NSEL0;
                desc->enable_mask = RT5739_ENVSEL0_MASK;
        }
+
+       /* Assigned by CHIPDIE ID */
+       switch (did) {
+       case RT5733_CHIPDIE_ID:
+               desc->n_voltages = RT5733_N_VOLTS;
+               desc->min_uV = RT5733_VOLT_MINUV;
+               desc->uV_step = RT5733_VOLT_STPUV;
+               break;
+       default:
+               desc->n_voltages = RT5739_N_VOLTS;
+               desc->min_uV = RT5739_VOLT_MINUV;
+               desc->uV_step = RT5739_VOLT_STPUV;
+               break;
+       }
 }
 
 static const struct regmap_config rt5739_regmap_config = {
@@ -258,7 +279,7 @@ static int rt5739_probe(struct i2c_client *i2c)
 
        vsel_acth = device_property_read_bool(dev, "richtek,vsel-active-high");
 
-       rt5739_init_regulator_desc(desc, vsel_acth);
+       rt5739_init_regulator_desc(desc, vsel_acth, vid & RT5739_DID_MASK);
 
        cfg.dev = dev;
        cfg.of_node = dev_of_node(dev);
@@ -271,6 +292,7 @@ static int rt5739_probe(struct i2c_client *i2c)
 }
 
 static const struct of_device_id rt5739_device_table[] = {
+       { .compatible = "richtek,rt5733" },
        { .compatible = "richtek,rt5739" },
        { /* sentinel */ }
 };
index 90555a9..c2553dc 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/i2c.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
diff --git a/drivers/regulator/rtq2208-regulator.c b/drivers/regulator/rtq2208-regulator.c
new file mode 100644 (file)
index 0000000..2d54844
--- /dev/null
@@ -0,0 +1,583 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <linux/util_macros.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/mod_devicetable.h>
+
+/* Register */
+#define RTQ2208_REG_GLOBAL_INT1                        0x12
+#define RTQ2208_REG_FLT_RECORDBUCK_CB          0x18
+#define RTQ2208_REG_GLOBAL_INT1_MASK           0x1D
+#define RTQ2208_REG_FLT_MASKBUCK_CB            0x1F
+#define RTQ2208_REG_BUCK_C_CFG0                        0x32
+#define RTQ2208_REG_BUCK_B_CFG0                        0x42
+#define RTQ2208_REG_BUCK_A_CFG0                        0x52
+#define RTQ2208_REG_BUCK_D_CFG0                        0x62
+#define RTQ2208_REG_BUCK_G_CFG0                        0x72
+#define RTQ2208_REG_BUCK_F_CFG0                        0x82
+#define RTQ2208_REG_BUCK_E_CFG0                        0x92
+#define RTQ2208_REG_BUCK_H_CFG0                        0xA2
+#define RTQ2208_REG_LDO1_CFG                   0xB1
+#define RTQ2208_REG_LDO2_CFG                   0xC1
+
+/* Mask */
+#define RTQ2208_BUCK_NR_MTP_SEL_MASK           GENMASK(7, 0)
+#define RTQ2208_BUCK_EN_NR_MTP_SEL0_MASK       BIT(0)
+#define RTQ2208_BUCK_EN_NR_MTP_SEL1_MASK       BIT(1)
+#define RTQ2208_BUCK_RSPUP_MASK                        GENMASK(6, 4)
+#define RTQ2208_BUCK_RSPDN_MASK                        GENMASK(2, 0)
+#define RTQ2208_BUCK_NRMODE_MASK               BIT(5)
+#define RTQ2208_BUCK_STRMODE_MASK              BIT(5)
+#define RTQ2208_BUCK_EN_STR_MASK               BIT(0)
+#define RTQ2208_LDO_EN_STR_MASK                        BIT(7)
+#define RTQ2208_EN_DIS_MASK                    BIT(0)
+#define RTQ2208_BUCK_RAMP_SEL_MASK             GENMASK(2, 0)
+#define RTQ2208_HD_INT_MASK                    BIT(0)
+
+/* Size */
+#define RTQ2208_VOUT_MAXNUM                    256
+#define RTQ2208_BUCK_NUM_IRQ_REGS              5
+#define RTQ2208_STS_NUM_IRQ_REGS               2
+
+/* Value */
+#define RTQ2208_RAMP_VALUE_MIN_uV              500
+#define RTQ2208_RAMP_VALUE_MAX_uV              64000
+
+#define RTQ2208_BUCK_MASK(uv_irq, ov_irq)      (1 << ((uv_irq) % 8) | 1 << ((ov_irq) % 8))
+
+enum {
+       RTQ2208_BUCK_B = 0,
+       RTQ2208_BUCK_C,
+       RTQ2208_BUCK_D,
+       RTQ2208_BUCK_A,
+       RTQ2208_BUCK_F,
+       RTQ2208_BUCK_G,
+       RTQ2208_BUCK_H,
+       RTQ2208_BUCK_E,
+       RTQ2208_LDO2,
+       RTQ2208_LDO1,
+       RTQ2208_LDO_MAX,
+};
+
+enum {
+       RTQ2208_AUTO_MODE = 0,
+       RTQ2208_FCCM,
+};
+
+struct rtq2208_regulator_desc {
+       struct regulator_desc desc;
+       unsigned int mtp_sel_reg;
+       unsigned int mtp_sel_mask;
+       unsigned int mode_reg;
+       unsigned int mode_mask;
+       unsigned int suspend_config_reg;
+       unsigned int suspend_enable_mask;
+       unsigned int suspend_mode_mask;
+};
+
+struct rtq2208_rdev_map {
+       struct regulator_dev *rdev[RTQ2208_LDO_MAX];
+       struct regmap *regmap;
+       struct device *dev;
+};
+
+/* set Normal Auto/FCCM mode */
+static int rtq2208_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       const struct rtq2208_regulator_desc *rdesc =
+               (const struct rtq2208_regulator_desc *)rdev->desc;
+       unsigned int val, shift;
+
+       switch (mode) {
+       case REGULATOR_MODE_NORMAL:
+               val = RTQ2208_AUTO_MODE;
+               break;
+       case REGULATOR_MODE_FAST:
+               val = RTQ2208_FCCM;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       shift = ffs(rdesc->mode_mask) - 1;
+       return regmap_update_bits(rdev->regmap, rdesc->mode_reg,
+                                 rdesc->mode_mask, val << shift);
+}
+
+static unsigned int rtq2208_get_mode(struct regulator_dev *rdev)
+{
+       const struct rtq2208_regulator_desc *rdesc =
+               (const struct rtq2208_regulator_desc *)rdev->desc;
+       unsigned int mode_val;
+       int ret;
+
+       ret = regmap_read(rdev->regmap, rdesc->mode_reg, &mode_val);
+       if (ret)
+               return REGULATOR_MODE_INVALID;
+
+       return (mode_val & rdesc->mode_mask) ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
+}
+
+static int rtq2208_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+       const struct regulator_desc *desc = rdev->desc;
+       unsigned int sel = 0, val;
+
+       ramp_delay = max(ramp_delay, RTQ2208_RAMP_VALUE_MIN_uV);
+       ramp_delay = min(ramp_delay, RTQ2208_RAMP_VALUE_MAX_uV);
+
+       ramp_delay /= RTQ2208_RAMP_VALUE_MIN_uV;
+
+       /*
+        * fls(ramp_delay) - 1: doing LSB shift, let it starts from 0
+        *
+        * RTQ2208_BUCK_RAMP_SEL_MASK - sel: doing descending order shifting.
+        * Because the relation of seleltion and value is like that
+        *
+        * seletion: value
+        * 000: 64mv
+        * 001: 32mv
+        * ...
+        * 111: 0.5mv
+        *
+        * For example, if I would like to select 64mv, the fls(ramp_delay) - 1 will be 0b111,
+        * and I need to use 0b111 - sel to do the shifting
+        */
+
+       sel = fls(ramp_delay) - 1;
+       sel = RTQ2208_BUCK_RAMP_SEL_MASK - sel;
+
+       val = FIELD_PREP(RTQ2208_BUCK_RSPUP_MASK, sel) | FIELD_PREP(RTQ2208_BUCK_RSPDN_MASK, sel);
+
+       return regmap_update_bits(rdev->regmap, desc->ramp_reg,
+                                 RTQ2208_BUCK_RSPUP_MASK | RTQ2208_BUCK_RSPDN_MASK, val);
+}
+
+static int rtq2208_set_suspend_enable(struct regulator_dev *rdev)
+{
+       const struct rtq2208_regulator_desc *rdesc =
+               (const struct rtq2208_regulator_desc *)rdev->desc;
+
+       return regmap_set_bits(rdev->regmap, rdesc->suspend_config_reg, rdesc->suspend_enable_mask);
+}
+
+static int rtq2208_set_suspend_disable(struct regulator_dev *rdev)
+{
+       const struct rtq2208_regulator_desc *rdesc =
+               (const struct rtq2208_regulator_desc *)rdev->desc;
+
+       return regmap_update_bits(rdev->regmap, rdesc->suspend_config_reg, rdesc->suspend_enable_mask, 0);
+}
+
+static int rtq2208_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       const struct rtq2208_regulator_desc *rdesc =
+               (const struct rtq2208_regulator_desc *)rdev->desc;
+       unsigned int val, shift;
+
+       switch (mode) {
+       case REGULATOR_MODE_NORMAL:
+               val = RTQ2208_AUTO_MODE;
+               break;
+       case REGULATOR_MODE_FAST:
+               val = RTQ2208_FCCM;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       shift = ffs(rdesc->suspend_mode_mask) - 1;
+
+       return regmap_update_bits(rdev->regmap, rdesc->suspend_config_reg,
+                       rdesc->suspend_mode_mask, val << shift);
+}
+
+static const struct regulator_ops rtq2208_regulator_buck_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_mode = rtq2208_set_mode,
+       .get_mode = rtq2208_get_mode,
+       .set_ramp_delay = rtq2208_set_ramp_delay,
+       .set_active_discharge = regulator_set_active_discharge_regmap,
+       .set_suspend_enable = rtq2208_set_suspend_enable,
+       .set_suspend_disable = rtq2208_set_suspend_disable,
+       .set_suspend_mode = rtq2208_set_suspend_mode,
+};
+
+static const struct regulator_ops rtq2208_regulator_ldo_ops = {
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .set_active_discharge = regulator_set_active_discharge_regmap,
+       .set_suspend_enable = rtq2208_set_suspend_enable,
+       .set_suspend_disable = rtq2208_set_suspend_disable,
+};
+
+static unsigned int rtq2208_of_map_mode(unsigned int mode)
+{
+       switch (mode) {
+       case RTQ2208_AUTO_MODE:
+               return REGULATOR_MODE_NORMAL;
+       case RTQ2208_FCCM:
+               return REGULATOR_MODE_FAST;
+       default:
+               return REGULATOR_MODE_INVALID;
+       }
+}
+
+static int rtq2208_init_irq_mask(struct rtq2208_rdev_map *rdev_map, unsigned int *buck_masks)
+{
+       unsigned char buck_clr_masks[5] = {0x33, 0x33, 0x33, 0x33, 0x33},
+                     sts_clr_masks[2] = {0xE7, 0xF7}, sts_masks[2] = {0xE6, 0xF6};
+       int ret;
+
+       /* write clear all buck irq once */
+       ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_FLT_RECORDBUCK_CB, buck_clr_masks, 5);
+       if (ret)
+               return dev_err_probe(rdev_map->dev, ret, "Failed to clr buck irqs\n");
+
+       /* write clear general irq once */
+       ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1, sts_clr_masks, 2);
+       if (ret)
+               return dev_err_probe(rdev_map->dev, ret, "Failed to clr general irqs\n");
+
+       /* unmask buck ov/uv irq */
+       ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_FLT_MASKBUCK_CB, buck_masks, 5);
+       if (ret)
+               return dev_err_probe(rdev_map->dev, ret, "Failed to unmask buck irqs\n");
+
+       /* unmask needed general irq */
+       return regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1_MASK, sts_masks, 2);
+}
+
+static irqreturn_t rtq2208_irq_handler(int irqno, void *devid)
+{
+       unsigned char buck_flags[RTQ2208_BUCK_NUM_IRQ_REGS], sts_flags[RTQ2208_STS_NUM_IRQ_REGS];
+       int ret = 0, i, uv_bit, ov_bit;
+       struct rtq2208_rdev_map *rdev_map = devid;
+       struct regulator_dev *rdev;
+
+       if (!rdev_map)
+               return IRQ_NONE;
+
+       /* read irq event */
+       ret = regmap_bulk_read(rdev_map->regmap, RTQ2208_REG_FLT_RECORDBUCK_CB,
+                               buck_flags, ARRAY_SIZE(buck_flags));
+       if (ret)
+               return IRQ_NONE;
+
+       ret = regmap_bulk_read(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1,
+                               sts_flags, ARRAY_SIZE(sts_flags));
+       if (ret)
+               return IRQ_NONE;
+
+       /* clear irq event */
+       ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_FLT_RECORDBUCK_CB,
+                               buck_flags, ARRAY_SIZE(buck_flags));
+       if (ret)
+               return IRQ_NONE;
+
+       ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1,
+                               sts_flags, ARRAY_SIZE(sts_flags));
+       if (ret)
+               return IRQ_NONE;
+
+       for (i = 0; i < RTQ2208_LDO_MAX; i++) {
+               if (!rdev_map->rdev[i])
+                       continue;
+
+               rdev = rdev_map->rdev[i];
+               /* uv irq */
+               uv_bit = (i & 1) ? 4 : 0;
+               if (buck_flags[i >> 1] & (1 << uv_bit))
+                       regulator_notifier_call_chain(rdev,
+                                       REGULATOR_EVENT_UNDER_VOLTAGE, NULL);
+               /* ov irq */
+               ov_bit = uv_bit + 1;
+               if (buck_flags[i >> 1] & (1 << ov_bit))
+                       regulator_notifier_call_chain(rdev,
+                                       REGULATOR_EVENT_REGULATION_OUT, NULL);
+
+               /* hd irq */
+               if (sts_flags[1] & RTQ2208_HD_INT_MASK)
+                       regulator_notifier_call_chain(rdev,
+                                       REGULATOR_EVENT_OVER_TEMP, NULL);
+       }
+
+       return IRQ_HANDLED;
+}
+
+#define RTQ2208_REGULATOR_INFO(_name, _base) \
+{ \
+       .name = #_name, \
+       .base = _base, \
+}
+#define BUCK_RG_BASE(_id)      RTQ2208_REG_BUCK_##_id##_CFG0
+#define BUCK_RG_SHIFT(_base, _shift)   (_base + _shift)
+#define LDO_RG_BASE(_id)       RTQ2208_REG_LDO##_id##_CFG
+#define LDO_RG_SHIFT(_base, _shift)    (_base + _shift)
+#define        VSEL_SHIFT(_sel)        (_sel ? 3 : 1)
+#define MTP_SEL_MASK(_sel)     RTQ2208_BUCK_EN_NR_MTP_SEL##_sel##_MASK
+
+static const struct linear_range rtq2208_vout_range[] = {
+       REGULATOR_LINEAR_RANGE(400000, 0, 180, 5000),
+       REGULATOR_LINEAR_RANGE(1310000, 181, 255, 10000),
+};
+
+static int rtq2208_of_get_fixed_voltage(struct device *dev,
+                                       struct of_regulator_match *rtq2208_ldo_match, int n_fixed)
+{
+       struct device_node *np;
+       struct of_regulator_match *match;
+       struct rtq2208_regulator_desc *rdesc;
+       struct regulator_init_data *init_data;
+       int ret, i;
+
+       if (!dev->of_node)
+               return -ENODEV;
+
+       np = of_get_child_by_name(dev->of_node, "regulators");
+       if (!np)
+               np = dev->of_node;
+
+       ret = of_regulator_match(dev, np, rtq2208_ldo_match, n_fixed);
+
+       of_node_put(np);
+
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < n_fixed; i++) {
+               match = rtq2208_ldo_match + i;
+               init_data = match->init_data;
+               rdesc = (struct rtq2208_regulator_desc *)match->driver_data;
+
+               if (!init_data || !rdesc)
+                       continue;
+
+               if (init_data->constraints.min_uV == init_data->constraints.max_uV)
+                       rdesc->desc.fixed_uV = init_data->constraints.min_uV;
+       }
+
+       return 0;
+}
+
+static void rtq2208_init_regulator_desc(struct rtq2208_regulator_desc *rdesc, int mtp_sel,
+                                       int idx, struct of_regulator_match *rtq2208_ldo_match, int *ldo_idx)
+{
+       struct regulator_desc *desc;
+       static const struct {
+               char *name;
+               int base;
+       } regulator_info[] = {
+               RTQ2208_REGULATOR_INFO(buck-b, BUCK_RG_BASE(B)),
+               RTQ2208_REGULATOR_INFO(buck-c, BUCK_RG_BASE(C)),
+               RTQ2208_REGULATOR_INFO(buck-d, BUCK_RG_BASE(D)),
+               RTQ2208_REGULATOR_INFO(buck-a, BUCK_RG_BASE(A)),
+               RTQ2208_REGULATOR_INFO(buck-f, BUCK_RG_BASE(F)),
+               RTQ2208_REGULATOR_INFO(buck-g, BUCK_RG_BASE(G)),
+               RTQ2208_REGULATOR_INFO(buck-h, BUCK_RG_BASE(H)),
+               RTQ2208_REGULATOR_INFO(buck-e, BUCK_RG_BASE(E)),
+               RTQ2208_REGULATOR_INFO(ldo2, LDO_RG_BASE(2)),
+               RTQ2208_REGULATOR_INFO(ldo1, LDO_RG_BASE(1)),
+       }, *curr_info;
+
+       curr_info = regulator_info + idx;
+       desc = &rdesc->desc;
+       desc->name = curr_info->name;
+       desc->of_match = of_match_ptr(curr_info->name);
+       desc->regulators_node = of_match_ptr("regulators");
+       desc->id = idx;
+       desc->owner = THIS_MODULE;
+       desc->type = REGULATOR_VOLTAGE;
+       desc->enable_mask = mtp_sel ? MTP_SEL_MASK(1) : MTP_SEL_MASK(0);
+       desc->active_discharge_on = RTQ2208_EN_DIS_MASK;
+       desc->active_discharge_off = 0;
+       desc->active_discharge_mask = RTQ2208_EN_DIS_MASK;
+
+       rdesc->mode_mask = RTQ2208_BUCK_NRMODE_MASK;
+
+       if (idx >= RTQ2208_BUCK_B && idx <= RTQ2208_BUCK_E) {
+               /* init buck desc */
+               desc->enable_reg = BUCK_RG_SHIFT(curr_info->base, 2);
+               desc->ops = &rtq2208_regulator_buck_ops;
+               desc->vsel_reg = curr_info->base + VSEL_SHIFT(mtp_sel);
+               desc->vsel_mask = RTQ2208_BUCK_NR_MTP_SEL_MASK;
+               desc->n_voltages = RTQ2208_VOUT_MAXNUM;
+               desc->linear_ranges = rtq2208_vout_range;
+               desc->n_linear_ranges = ARRAY_SIZE(rtq2208_vout_range);
+               desc->ramp_reg = BUCK_RG_SHIFT(curr_info->base, 5);
+               desc->active_discharge_reg = curr_info->base;
+               desc->of_map_mode = rtq2208_of_map_mode;
+
+               rdesc->mode_reg = BUCK_RG_SHIFT(curr_info->base, 2);
+               rdesc->suspend_config_reg = BUCK_RG_SHIFT(curr_info->base, 4);
+               rdesc->suspend_enable_mask = RTQ2208_BUCK_EN_STR_MASK;
+               rdesc->suspend_mode_mask = RTQ2208_BUCK_STRMODE_MASK;
+       } else {
+               /* init ldo desc */
+               desc->enable_reg = curr_info->base;
+               desc->ops = &rtq2208_regulator_ldo_ops;
+               desc->n_voltages = 1;
+               desc->active_discharge_reg = LDO_RG_SHIFT(curr_info->base, 2);
+
+               rtq2208_ldo_match[*ldo_idx].name = desc->name;
+               rtq2208_ldo_match[*ldo_idx].driver_data = rdesc;
+               rtq2208_ldo_match[(*ldo_idx)++].desc = desc;
+
+               rdesc->suspend_config_reg = curr_info->base;
+               rdesc->suspend_enable_mask = RTQ2208_LDO_EN_STR_MASK;
+       }
+}
+
+static int rtq2208_parse_regulator_dt_data(int n_regulator, const unsigned int *regulator_idx_table,
+               struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX], struct device *dev)
+{
+       struct of_regulator_match rtq2208_ldo_match[2];
+       int mtp_sel, ret, i, idx, ldo_idx = 0;
+
+       /* get mtp_sel0 or mtp_sel1 */
+       mtp_sel = device_property_read_bool(dev, "richtek,mtp-sel-high");
+
+       for (i = 0; i < n_regulator; i++) {
+               idx = regulator_idx_table[i];
+
+               rdesc[i] = devm_kcalloc(dev, 1, sizeof(*rdesc[0]), GFP_KERNEL);
+               if (!rdesc[i])
+                       return -ENOMEM;
+
+               rtq2208_init_regulator_desc(rdesc[i], mtp_sel, idx, rtq2208_ldo_match, &ldo_idx);
+       }
+
+       /* init ldo fixed_uV */
+       ret = rtq2208_of_get_fixed_voltage(dev, rtq2208_ldo_match, ldo_idx);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to get ldo fixed_uV\n");
+
+       return 0;
+
+}
+
+/** different slave address corresponds different used bucks
+ * slave address 0x10: BUCK[BCA FGE]
+ * slave address 0x20: BUCK[BC FGHE]
+ * slave address 0x40: BUCK[C G]
+ */
+static int rtq2208_regulator_check(int slave_addr, int *num,
+                               int *regulator_idx_table, unsigned int *buck_masks)
+{
+       static bool rtq2208_used_table[3][RTQ2208_LDO_MAX] = {
+               /* BUCK[BCA FGE], LDO[12] */
+               {1, 1, 0, 1, 1, 1, 0, 1, 1, 1},
+               /* BUCK[BC FGHE], LDO[12]*/
+               {1, 1, 0, 0, 1, 1, 1, 1, 1, 1},
+               /* BUCK[C G], LDO[12] */
+               {0, 1, 0, 0, 0, 1, 0, 0, 1, 1},
+       };
+       int i, idx = ffs(slave_addr >> 4) - 1;
+       u8 mask;
+
+       for (i = 0; i < RTQ2208_LDO_MAX; i++) {
+               if (!rtq2208_used_table[idx][i])
+                       continue;
+
+               regulator_idx_table[(*num)++] = i;
+
+               mask = RTQ2208_BUCK_MASK(4 * i, 4 * i + 1);
+               buck_masks[i >> 1] &= ~mask;
+       }
+
+       return 0;
+}
+
+static const struct regmap_config rtq2208_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = 0xEF,
+};
+
+static int rtq2208_probe(struct i2c_client *i2c)
+{
+       struct device *dev = &i2c->dev;
+       struct regmap *regmap;
+       struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX];
+       struct regulator_dev *rdev;
+       struct regulator_config cfg;
+       struct rtq2208_rdev_map *rdev_map;
+       int i, ret = 0, idx, n_regulator = 0;
+       unsigned int regulator_idx_table[RTQ2208_LDO_MAX],
+                    buck_masks[RTQ2208_BUCK_NUM_IRQ_REGS] = {0x33, 0x33, 0x33, 0x33, 0x33};
+
+       rdev_map = devm_kzalloc(dev, sizeof(struct rtq2208_rdev_map), GFP_KERNEL);
+       if (!rdev_map)
+               return -ENOMEM;
+
+       regmap = devm_regmap_init_i2c(i2c, &rtq2208_regmap_config);
+       if (IS_ERR(regmap))
+               return dev_err_probe(dev, PTR_ERR(regmap), "Failed to allocate regmap\n");
+
+       /* get needed regulator */
+       ret = rtq2208_regulator_check(i2c->addr, &n_regulator, regulator_idx_table, buck_masks);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to check used regulators\n");
+
+       rdev_map->regmap = regmap;
+       rdev_map->dev = dev;
+
+       cfg.dev = dev;
+
+       /* init regulator desc */
+       ret = rtq2208_parse_regulator_dt_data(n_regulator, regulator_idx_table, rdesc, dev);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < n_regulator; i++) {
+               idx = regulator_idx_table[i];
+
+               /* register regulator */
+               rdev = devm_regulator_register(dev, &rdesc[i]->desc, &cfg);
+               if (IS_ERR(rdev))
+                       return PTR_ERR(rdev);
+
+               rdev_map->rdev[idx] = rdev;
+       }
+
+       /* init interrupt mask */
+       ret = rtq2208_init_irq_mask(rdev_map, buck_masks);
+       if (ret)
+               return ret;
+
+       /* register interrupt */
+       return devm_request_threaded_irq(dev, i2c->irq, NULL, rtq2208_irq_handler,
+                                       IRQF_ONESHOT, dev_name(dev), rdev_map);
+}
+
+static const struct of_device_id rtq2208_device_tables[] = {
+       { .compatible = "richtek,rtq2208" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, rtq2208_device_tables);
+
+static struct i2c_driver rtq2208_driver = {
+       .driver = {
+               .name = "rtq2208",
+               .of_match_table = rtq2208_device_tables,
+       },
+       .probe = rtq2208_probe,
+};
+module_i2c_driver(rtq2208_driver);
+
+MODULE_AUTHOR("Alina Yu <alina_yu@richtek.com>");
+MODULE_DESCRIPTION("Richtek RTQ2208 Regulator Driver");
+MODULE_LICENSE("GPL");
index b147ff6..c22fdde 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <linux/bug.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/of.h>
index 4c60edd..85b0102 100644 (file)
@@ -6,8 +6,7 @@
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
index f5ccc7d..717144c 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
index d070310..d49c0cb 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
index 433959b..f11ff38 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
index b1c4b51..758c702 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/machine.h>
@@ -84,11 +84,11 @@ static unsigned int tps6286x_of_map_mode(unsigned int mode)
 
 static const struct regulator_desc tps6286x_reg = {
        .name = "tps6286x",
-       .of_match = of_match_ptr("SW"),
+       .of_match = "SW",
        .owner = THIS_MODULE,
        .ops = &tps6286x_regulator_ops,
        .of_map_mode = tps6286x_of_map_mode,
-       .regulators_node = of_match_ptr("regulators"),
+       .regulators_node = "regulators",
        .type = REGULATOR_VOLTAGE,
        .n_voltages = ((TPS6286X_MAX_MV - TPS6286X_MIN_MV) / TPS6286X_STEP_MV) + 1,
        .min_uV = TPS6286X_MIN_MV * 1000,
@@ -148,7 +148,7 @@ static struct i2c_driver tps6286x_regulator_driver = {
        .driver = {
                .name = "tps6286x",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
-               .of_match_table = of_match_ptr(tps6286x_dt_ids),
+               .of_match_table = tps6286x_dt_ids,
        },
        .probe = tps6286x_i2c_probe,
        .id_table = tps6286x_i2c_id,
index b1c0963..d022184 100644 (file)
@@ -8,8 +8,8 @@
 
 #include <linux/err.h>
 #include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/machine.h>
@@ -41,7 +41,7 @@ static const struct linear_range tps6287x_voltage_ranges[] = {
 };
 
 static const unsigned int tps6287x_voltage_range_sel[] = {
-       0x0, 0x4, 0x8, 0xC
+       0x0, 0x1, 0x2, 0x3
 };
 
 static const unsigned int tps6287x_ramp_table[] = {
@@ -122,7 +122,7 @@ static struct regulator_desc tps6287x_reg = {
        .n_voltages = 256,
        .linear_ranges = tps6287x_voltage_ranges,
        .n_linear_ranges = ARRAY_SIZE(tps6287x_voltage_ranges),
-       .linear_range_selectors = tps6287x_voltage_range_sel,
+       .linear_range_selectors_bitfield = tps6287x_voltage_range_sel,
 };
 
 static int tps6287x_i2c_probe(struct i2c_client *i2c)
index 6637891..2d284c6 100644 (file)
 #include <linux/mfd/tps65086.h>
 
 enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
-       LDOA2, LDOA3, SWA1, SWB1, SWB2, VTT };
+       LDOA2, LDOA3, VTT, SWA1, SWB1, SWB2 };
+
+/* Selector for regulator configuration regarding PMIC chip ID. */
+enum tps65086_ids {
+       TPS6508640 = 0,
+       TPS65086401,
+       TPS6508641,
+       TPS65086470,
+};
 
 #define TPS65086_REGULATOR(_name, _of, _id, _nv, _vr, _vm, _er, _em, _lr, _dr, _dm)    \
        [_id] = {                                                       \
@@ -57,12 +65,24 @@ enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
                },                                                      \
        }
 
+
+#define TPS65086_REGULATOR_CONFIG(_chip_id, _config)                   \
+       [_chip_id] = {                                                  \
+               .config = _config,                                      \
+               .num_elems = ARRAY_SIZE(_config),                       \
+       }
+
 struct tps65086_regulator {
        struct regulator_desc desc;
        unsigned int decay_reg;
        unsigned int decay_mask;
 };
 
+struct tps65086_regulator_config {
+       struct tps65086_regulator * const config;
+       const unsigned int num_elems;
+};
+
 static const struct linear_range tps65086_10mv_ranges[] = {
        REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
        REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000),
@@ -114,7 +134,125 @@ static int tps65086_of_parse_cb(struct device_node *dev,
                                const struct regulator_desc *desc,
                                struct regulator_config *config);
 
-static struct tps65086_regulator regulators[] = {
+static struct tps65086_regulator tps6508640_regulator_config[] = {
+       TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
+                          BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
+                          BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
+                          tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
+                          BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
+                          tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
+                          BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK4VID,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
+                          BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
+                          BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
+                          VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
+                          tps65086_ldoa1_ranges, 0, 0),
+       TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
+                          VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
+                          tps65086_ldoa23_ranges, 0, 0),
+       TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
+                          VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
+                          tps65086_ldoa23_ranges, 0, 0),
+       TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+       TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
+       TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
+       TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_LDOA1CTRL, BIT(0)),
+};
+
+static struct tps65086_regulator tps65086401_regulator_config[] = {
+       TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
+                          BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
+                          BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
+                          tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
+                          BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
+                          tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
+                          BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK4VID,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
+                          BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
+                          BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
+                          VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
+                          tps65086_ldoa1_ranges, 0, 0),
+       TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
+                          VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
+                          tps65086_ldoa23_ranges, 0, 0),
+       TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
+                          VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
+                          tps65086_ldoa23_ranges, 0, 0),
+       TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+       TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
+       TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
+};
+
+static struct tps65086_regulator tps6508641_regulator_config[] = {
+       TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
+                          BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
+                          BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
+                          tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
+                          BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
+                          tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
+                          BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK4VID,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
+                          BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
+                          BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
+                          tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
+                          BIT(0)),
+       TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
+                          VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
+                          tps65086_ldoa1_ranges, 0, 0),
+       TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
+                          VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
+                          tps65086_ldoa23_ranges, 0, 0),
+       TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
+                          VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
+                          tps65086_ldoa23_ranges, 0, 0),
+       TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+       TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
+       TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
+};
+
+static struct tps65086_regulator tps65086470_regulator_config[] = {
        TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
                           BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
                           tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
@@ -148,16 +286,25 @@ static struct tps65086_regulator regulators[] = {
        TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
                           VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
                           tps65086_ldoa23_ranges, 0, 0),
+       TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
        TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
        TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
        TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_SWVTT_EN, BIT(7)),
-       TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+};
+
+static const struct tps65086_regulator_config regulator_configs[] = {
+       TPS65086_REGULATOR_CONFIG(TPS6508640, tps6508640_regulator_config),
+       TPS65086_REGULATOR_CONFIG(TPS65086401, tps65086401_regulator_config),
+       TPS65086_REGULATOR_CONFIG(TPS6508641, tps6508641_regulator_config),
+       TPS65086_REGULATOR_CONFIG(TPS65086470, tps65086470_regulator_config)
 };
 
 static int tps65086_of_parse_cb(struct device_node *node,
                                const struct regulator_desc *desc,
                                struct regulator_config *config)
 {
+       struct tps65086 * const tps = dev_get_drvdata(config->dev);
+       struct tps65086_regulator *regulators = tps->reg_config->config;
        int ret;
 
        /* Check for 25mV step mode */
@@ -203,9 +350,30 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
 {
        struct tps65086 *tps = dev_get_drvdata(pdev->dev.parent);
        struct regulator_config config = { };
+       unsigned int selector_reg_config;
        struct regulator_dev *rdev;
        int i;
 
+       /* Select regulator configuration for used PMIC device */
+       switch (tps->chip_id) {
+       case TPS6508640_ID:
+               selector_reg_config = TPS6508640;
+               break;
+       case TPS65086401_ID:
+               selector_reg_config = TPS65086401;
+               break;
+       case TPS6508641_ID:
+               selector_reg_config = TPS6508641;
+               break;
+       case TPS65086470_ID:
+               selector_reg_config = TPS65086470;
+               break;
+       default:
+               dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n");
+               return -ENODEV;
+       }
+       tps->reg_config = &regulator_configs[selector_reg_config];
+
        platform_set_drvdata(pdev, tps);
 
        config.dev = &pdev->dev;
@@ -213,12 +381,16 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
        config.driver_data = tps;
        config.regmap = tps->regmap;
 
-       for (i = 0; i < ARRAY_SIZE(regulators); i++) {
-               rdev = devm_regulator_register(&pdev->dev, &regulators[i].desc,
-                                              &config);
+       for (i = 0; i < tps->reg_config->num_elems; ++i) {
+               struct regulator_desc * const desc_ptr = &tps->reg_config->config[i].desc;
+
+               dev_dbg(tps->dev, "Index: %u; Regulator name: \"%s\"; Regulator ID: %d\n",
+                       i, desc_ptr->name, desc_ptr->id);
+
+               rdev = devm_regulator_register(&pdev->dev, desc_ptr, &config);
                if (IS_ERR(rdev)) {
-                       dev_err(tps->dev, "failed to register %s regulator\n",
-                               pdev->name);
+                       dev_err(tps->dev, "failed to register %d \"%s\" regulator\n",
+                               i, desc_ptr->name);
                        return PTR_ERR(rdev);
                }
        }
index 1398588..f44b576 100644 (file)
@@ -8,12 +8,12 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
-#include <linux/of_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/driver.h>
index 8971b50..b406535 100644 (file)
@@ -15,8 +15,8 @@
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
-#include <linux/of_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/driver.h>
index 2a0965b..3a3027e 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/slab.h>
-#include <linux/gpio.h>
 #include <linux/mfd/tps65910.h>
 #include <linux/regulator/of_regulator.h>
 
index d5a574e..25ef102 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
index 3e724f5..5bacfce 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
index f9c695f..6eed0f6 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
index 7e2785e..1d8304b 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
index 85dca90..2796580 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/platform_device.h>
 #include <linux/regulator/coupler.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
index b545dbc..6687077 100644 (file)
@@ -8,7 +8,8 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
index 16f87cc..9185b5c 100644 (file)
@@ -13,8 +13,9 @@
 #include <linux/regmap.h>
 
 /* List of registers for TPS65086 */
-#define TPS65086_DEVICEID              0x01
-#define TPS65086_IRQ                   0x02
+#define TPS65086_DEVICEID1             0x00
+#define TPS65086_DEVICEID2             0x01
+#define TPS65086_IRQ           0x02
 #define TPS65086_IRQ_MASK              0x03
 #define TPS65086_PMICSTAT              0x04
 #define TPS65086_SHUTDNSRC             0x05
 #define TPS65086_IRQ_SHUTDN_MASK       BIT(3)
 #define TPS65086_IRQ_FAULT_MASK                BIT(7)
 
-/* DEVICEID Register field definitions */
-#define TPS65086_DEVICEID_PART_MASK    GENMASK(3, 0)
-#define TPS65086_DEVICEID_OTP_MASK     GENMASK(5, 4)
-#define TPS65086_DEVICEID_REV_MASK     GENMASK(7, 6)
+/* DEVICEID1 Register field definitions */
+#define TPS6508640_ID                  0x00
+#define TPS65086401_ID                 0x01
+#define TPS6508641_ID                  0x10
+#define TPS65086470_ID                 0x70
+
+/* DEVICEID2 Register field definitions */
+#define TPS65086_DEVICEID2_PART_MASK   GENMASK(3, 0)
+#define TPS65086_DEVICEID2_OTP_MASK    GENMASK(5, 4)
+#define TPS65086_DEVICEID2_REV_MASK    GENMASK(7, 6)
 
 /* VID Masks */
 #define BUCK_VID_MASK                  GENMASK(7, 1)
@@ -92,6 +99,8 @@ enum tps65086_irqs {
        TPS65086_IRQ_FAULT,
 };
 
+struct tps65086_regulator_config;
+
 /**
  * struct tps65086 - state holder for the tps65086 driver
  *
@@ -100,6 +109,8 @@ enum tps65086_irqs {
 struct tps65086 {
        struct device *dev;
        struct regmap *regmap;
+       unsigned int chip_id;
+       const struct tps65086_regulator_config *reg_config;
 
        /* IRQ Data */
        int irq;
index f90df9e..d58ff27 100644 (file)
@@ -35,10 +35,4 @@ enum db8500_regulator_id {
        DB8500_NUM_REGULATORS
 };
 
-/*
- * Exported interface for CPUIdle only. This function is called with all
- * interrupts turned off.
- */
-int power_state_active_is_enabled(void);
-
 #endif
index c6ef7d6..4b7eceb 100644 (file)
@@ -292,11 +292,12 @@ enum regulator_type {
  * @ramp_delay: Time to settle down after voltage change (unit: uV/us)
  * @min_dropout_uV: The minimum dropout voltage this regulator can handle
  * @linear_ranges: A constant table of possible voltage ranges.
- * @linear_range_selectors: A constant table of voltage range selectors.
- *                         If pickable ranges are used each range must
- *                         have corresponding selector here.
+ * @linear_range_selectors_bitfield: A constant table of voltage range
+ *                                   selectors as bitfield values. If
+ *                                   pickable ranges are used each range
+ *                                   must have corresponding selector here.
  * @n_linear_ranges: Number of entries in the @linear_ranges (and in
- *                  linear_range_selectors if used) table(s).
+ *                  linear_range_selectors_bitfield if used) table(s).
  * @volt_table: Voltage mapping table (if table based mapping)
  * @curr_table: Current limit mapping table (if table based mapping)
  *
@@ -384,7 +385,7 @@ struct regulator_desc {
        int min_dropout_uV;
 
        const struct linear_range *linear_ranges;
-       const unsigned int *linear_range_selectors;
+       const unsigned int *linear_range_selectors_bitfield;
 
        int n_linear_ranges;