Merge tag 'regulator-v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Jun 2023 20:32:47 +0000 (13:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Jun 2023 20:32:47 +0000 (13:32 -0700)
Pull regulator updates from Mark Brown:
 "This release is almost all drivers, there's some small improvements in
  the core but otherwise everything is updates to drivers, mostly the
  addition of new ones.

  There's also a bunch of changes pulled in from the MFD subsystem as
  dependencies, Rockchip and TI core MFD code that the regulator drivers
  depend on.

  I've also yet again managed to put a SPI commit in the regulator tree,
  I don't know what it is about those two trees (this for
  spi-geni-qcom).

  Summary:

   - Support for Renesas RAA215300, Rockchip RK808, Texas Instruments
     TPS6594 and TPS6287x, and X-Powers AXP15060 and AXP313a"

* tag 'regulator-v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (43 commits)
  regulator: Add Renesas PMIC RAA215300 driver
  regulator: dt-bindings: Add Renesas RAA215300 PMIC bindings
  regulator: ltc3676: Use maple tree register cache
  regulator: ltc3589: Use maple tree register cache
  regulator: helper: Document ramp_delay parameter of regulator_set_ramp_delay_regmap()
  regulator: mt6358: Use linear voltage helpers for single range regulators
  regulator: mt6358: Const-ify mt6358_regulator_info data structures
  regulator: mt6358: Drop *_SSHUB regulators
  regulator: mt6358: Merge VCN33_* regulators
  regulator: dt-bindings: mt6358: Drop *_sshub regulators
  regulator: dt-bindings: mt6358: Merge ldo_vcn33_* regulators
  regulator: dt-bindings: pwm-regulator: Add missing type for "pwm-dutycycle-unit"
  regulator: Switch two more i2c drivers back to use .probe()
  spi: spi-geni-qcom: Do not do DMA map/unmap inside driver, use framework instead
  soc: qcom: geni-se: Add interfaces geni_se_tx_init_dma() and geni_se_rx_init_dma()
  regulator: tps6594-regulator: Add driver for TI TPS6594 regulators
  regulator: axp20x: Add AXP15060 support
  regulator: axp20x: Add support for AXP313a variant
  dt-bindings: pfuze100.yaml: Add an entry for interrupts
  regulator: stm32-pwr: Fix regulator disabling
  ...

101 files changed:
Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
Documentation/devicetree/bindings/regulator/pfuze100.yaml
Documentation/devicetree/bindings/regulator/pwm-regulator.yaml
Documentation/devicetree/bindings/regulator/renesas,raa215300.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/ti,tps62870.yaml [new file with mode: 0644]
drivers/clk/Kconfig
drivers/clk/clk-rk808.c
drivers/input/misc/Kconfig
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/axp20x-i2c.c
drivers/mfd/axp20x.c
drivers/mfd/rk8xx-core.c [moved from drivers/mfd/rk808.c with 71% similarity]
drivers/mfd/rk8xx-i2c.c [new file with mode: 0644]
drivers/mfd/rk8xx-spi.c [new file with mode: 0644]
drivers/mfd/tps6594-core.c [new file with mode: 0644]
drivers/mfd/tps6594-i2c.c [new file with mode: 0644]
drivers/mfd/tps6594-spi.c [new file with mode: 0644]
drivers/pinctrl/Kconfig
drivers/pinctrl/pinctrl-rk805.c
drivers/power/supply/Kconfig
drivers/regulator/88pg86x.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/act8865-regulator.c
drivers/regulator/ad5398.c
drivers/regulator/axp20x-regulator.c
drivers/regulator/core.c
drivers/regulator/da9121-regulator.c
drivers/regulator/da9210-regulator.c
drivers/regulator/da9211-regulator.c
drivers/regulator/fan53555.c
drivers/regulator/fan53880.c
drivers/regulator/helpers.c
drivers/regulator/isl6271a-regulator.c
drivers/regulator/isl9305.c
drivers/regulator/lp3971.c
drivers/regulator/lp3972.c
drivers/regulator/lp872x.c
drivers/regulator/lp8755.c
drivers/regulator/ltc3589.c
drivers/regulator/ltc3676.c
drivers/regulator/max1586.c
drivers/regulator/max20086-regulator.c
drivers/regulator/max20411-regulator.c
drivers/regulator/max77826-regulator.c
drivers/regulator/max8649.c
drivers/regulator/max8660.c
drivers/regulator/max8893.c
drivers/regulator/max8952.c
drivers/regulator/max8973-regulator.c
drivers/regulator/mcp16502.c
drivers/regulator/mp5416.c
drivers/regulator/mp8859.c
drivers/regulator/mp886x.c
drivers/regulator/mpq7920.c
drivers/regulator/mt6311-regulator.c
drivers/regulator/mt6358-regulator.c
drivers/regulator/pca9450-regulator.c
drivers/regulator/pf8x00-regulator.c
drivers/regulator/pfuze100-regulator.c
drivers/regulator/pv88060-regulator.c
drivers/regulator/pv88080-regulator.c
drivers/regulator/pv88090-regulator.c
drivers/regulator/raa215300.c [new file with mode: 0644]
drivers/regulator/rk808-regulator.c
drivers/regulator/rpi-panel-attiny-regulator.c
drivers/regulator/rt4801-regulator.c
drivers/regulator/rt5190a-regulator.c
drivers/regulator/rt5739.c
drivers/regulator/rt5759-regulator.c
drivers/regulator/rt6160-regulator.c
drivers/regulator/rt6190-regulator.c
drivers/regulator/rt6245-regulator.c
drivers/regulator/rtmv20-regulator.c
drivers/regulator/rtq2134-regulator.c
drivers/regulator/rtq6752-regulator.c
drivers/regulator/slg51000-regulator.c
drivers/regulator/stm32-pwr.c
drivers/regulator/sy8106a-regulator.c
drivers/regulator/sy8824x.c
drivers/regulator/sy8827n.c
drivers/regulator/tps51632-regulator.c
drivers/regulator/tps62360-regulator.c
drivers/regulator/tps6286x-regulator.c
drivers/regulator/tps6287x-regulator.c [new file with mode: 0644]
drivers/regulator/tps65023-regulator.c
drivers/regulator/tps65132-regulator.c
drivers/regulator/tps65219-regulator.c
drivers/regulator/tps6594-regulator.c [new file with mode: 0644]
drivers/rtc/Kconfig
drivers/soc/qcom/qcom-geni-se.c
drivers/spi/spi-geni-qcom.c
include/linux/mfd/axp20x.h
include/linux/mfd/rk808.h
include/linux/mfd/tps6594.h [new file with mode: 0644]
include/linux/regulator/driver.h
include/linux/regulator/mt6358-regulator.h
include/linux/soc/qcom/geni-se.h
sound/soc/codecs/Kconfig

diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
new file mode 100644 (file)
index 0000000..cf2500f
--- /dev/null
@@ -0,0 +1,406 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/rockchip,rk806.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RK806 Power Management Integrated Circuit
+
+maintainers:
+  - Sebastian Reichel <sebastian.reichel@collabora.com>
+
+description:
+  Rockchip RK806 series PMIC. This device consists of an spi or
+  i2c controlled MFD that includes multiple switchable regulators.
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk806
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  vcc1-supply:
+    description:
+      The input supply for dcdc-reg1.
+
+  vcc2-supply:
+    description:
+      The input supply for dcdc-reg2.
+
+  vcc3-supply:
+    description:
+      The input supply for dcdc-reg3.
+
+  vcc4-supply:
+    description:
+      The input supply for dcdc-reg4.
+
+  vcc5-supply:
+    description:
+      The input supply for dcdc-reg5.
+
+  vcc6-supply:
+    description:
+      The input supply for dcdc-reg6.
+
+  vcc7-supply:
+    description:
+      The input supply for dcdc-reg7.
+
+  vcc8-supply:
+    description:
+      The input supply for dcdc-reg8.
+
+  vcc9-supply:
+    description:
+      The input supply for dcdc-reg9.
+
+  vcc10-supply:
+    description:
+      The input supply for dcdc-reg10.
+
+  vcc11-supply:
+    description:
+      The input supply for pldo-reg1, pldo-reg2 and pldo-reg3.
+
+  vcc12-supply:
+    description:
+      The input supply for pldo-reg4 and pldo-reg5.
+
+  vcc13-supply:
+    description:
+      The input supply for nldo-reg1, nldo-reg2 and nldo-reg3.
+
+  vcc14-supply:
+    description:
+      The input supply for nldo-reg4 and nldo-reg5.
+
+  vcca-supply:
+    description:
+      The input supply for pldo-reg6.
+
+  regulators:
+    type: object
+    additionalProperties: false
+    patternProperties:
+      "^(dcdc-reg([1-9]|10)|pldo-reg[1-6]|nldo-reg[1-5])$":
+        type: object
+        $ref: /schemas/regulator/regulator.yaml#
+        unevaluatedProperties: false
+
+patternProperties:
+  '-pins$':
+    type: object
+    additionalProperties: false
+    $ref: /schemas/pinctrl/pinmux-node.yaml
+
+    properties:
+      function:
+        enum: [pin_fun0, pin_fun1, pin_fun2, pin_fun3, pin_fun4, pin_fun5]
+
+      pins:
+        $ref: /schemas/types.yaml#/definitions/string
+        enum: [gpio_pwrctrl1, gpio_pwrctrl2, gpio_pwrctrl3]
+
+allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/pinctrl/rockchip.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/gpio/gpio.h>
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic@0 {
+            compatible = "rockchip,rk806";
+            reg = <0x0>;
+
+            interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+            vcc1-supply = <&vcc5v0_sys>;
+            vcc2-supply = <&vcc5v0_sys>;
+            vcc3-supply = <&vcc5v0_sys>;
+            vcc4-supply = <&vcc5v0_sys>;
+            vcc5-supply = <&vcc5v0_sys>;
+            vcc6-supply = <&vcc5v0_sys>;
+            vcc7-supply = <&vcc5v0_sys>;
+            vcc8-supply = <&vcc5v0_sys>;
+            vcc9-supply = <&vcc5v0_sys>;
+            vcc10-supply = <&vcc5v0_sys>;
+            vcc11-supply = <&vcc_2v0_pldo_s3>;
+            vcc12-supply = <&vcc5v0_sys>;
+            vcc13-supply = <&vcc5v0_sys>;
+            vcc14-supply = <&vcc_1v1_nldo_s3>;
+            vcca-supply = <&vcc5v0_sys>;
+
+            regulators {
+                vdd_gpu_s0: dcdc-reg1 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <550000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_gpu_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_npu_s0: dcdc-reg2 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <550000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_npu_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_log_s0: dcdc-reg3 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_log_s0";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <750000>;
+                    };
+                };
+
+                vdd_vdenc_s0: dcdc-reg4 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <550000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_vdenc_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_gpu_mem_s0: dcdc-reg5 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <675000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_gpu_mem_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_npu_mem_s0: dcdc-reg6 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <675000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_npu_mem_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vcc_2v0_pldo_s3: dcdc-reg7 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <2000000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_2v0_pldo_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <2000000>;
+                    };
+                };
+
+                vdd_vdenc_mem_s0: dcdc-reg8 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <675000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_vdenc_mem_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd2_ddr_s3: dcdc-reg9 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-name = "vdd2_ddr_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                    };
+                };
+
+                vcc_1v1_nldo_s3: dcdc-reg10 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1100000>;
+                    regulator-max-microvolt = <1100000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vcc_1v1_nldo_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1100000>;
+                    };
+                };
+
+                avcc_1v8_s0: pldo-reg1 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "avcc_1v8_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd1_1v8_ddr_s3: pldo-reg2 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd1_1v8_ddr_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1800000>;
+                    };
+                };
+
+                vcc_1v8_s3: pldo-reg3 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vcc_1v8_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1800000>;
+                    };
+                };
+
+                vcc_3v3_s0: pldo-reg4 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <3300000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vcc_3v3_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vccio_sd_s0: pldo-reg5 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vccio_sd_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                master_pldo6_s3: pldo-reg6 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-name = "master_pldo6_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1800000>;
+                    };
+                };
+
+                vdd_0v75_s3: nldo-reg1 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_0v75_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <750000>;
+                    };
+                };
+
+                vdd2l_0v9_ddr_s3: nldo-reg2 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <900000>;
+                    regulator-max-microvolt = <900000>;
+                    regulator-name = "vdd2l_0v9_ddr_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <900000>;
+                    };
+                };
+
+                master_nldo3: nldo-reg3 {
+                    regulator-name = "master_nldo3";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                avdd_0v75_s0: nldo-reg4 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-name = "avdd_0v75_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_0v85_s0: nldo-reg5 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <850000>;
+                    regulator-max-microvolt = <850000>;
+                    regulator-name = "vdd_0v85_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+            };
+        };
+    };
index 7034cdca54e04f0e29228ef456f1456799c71f68..b6384306db5c689a471397a9428bc40d69f44cf3 100644 (file)
@@ -8,15 +8,14 @@ Documentation/devicetree/bindings/regulator/regulator.txt.
 
 The valid names for regulators are::
 BUCK:
-  buck_vdram1, buck_vcore, buck_vcore_sshub, buck_vpa, buck_vproc11,
-  buck_vproc12, buck_vgpu, buck_vs2, buck_vmodem, buck_vs1
+  buck_vdram1, buck_vcore, buck_vpa, buck_vproc11, buck_vproc12, buck_vgpu,
+  buck_vs2, buck_vmodem, buck_vs1
 LDO:
   ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio,
   ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others,
-  ldo_vsram_others_sshub, ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18,
-  ldo_vmch, ldo_vbif28, ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12,
-  ldo_vrf18, ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
-  ldo_vsim2
+  ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28,
+  ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18,
+  ldo_vcn33, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28, ldo_vsim2
 
 Example:
 
@@ -305,15 +304,8 @@ Example:
                                regulator-enable-ramp-delay = <120>;
                        };
 
-                       mt6358_vcn33_bt_reg: ldo_vcn33_bt {
-                               regulator-name = "vcn33_bt";
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3500000>;
-                               regulator-enable-ramp-delay = <270>;
-                       };
-
-                       mt6358_vcn33_wifi_reg: ldo_vcn33_wifi {
-                               regulator-name = "vcn33_wifi";
+                       mt6358_vcn33_reg: ldo_vcn33 {
+                               regulator-name = "vcn33";
                                regulator-min-microvolt = <3300000>;
                                regulator-max-microvolt = <3500000>;
                                regulator-enable-ramp-delay = <270>;
@@ -354,17 +346,5 @@ Example:
                                regulator-max-microvolt = <3100000>;
                                regulator-enable-ramp-delay = <540>;
                        };
-
-                       mt6358_vcore_sshub_reg: buck_vcore_sshub {
-                               regulator-name = "vcore_sshub";
-                               regulator-min-microvolt = <500000>;
-                               regulator-max-microvolt = <1293750>;
-                       };
-
-                       mt6358_vsram_others_sshub_reg: ldo_vsram_others_sshub {
-                               regulator-name = "vsram_others_sshub";
-                               regulator-min-microvolt = <500000>;
-                               regulator-max-microvolt = <1293750>;
-                       };
                };
        };
index 67a30b23b92c6a6721d67252a121b5b5709a7aa0..e384e4953f0a71643c585cded806e05a369319ed 100644 (file)
@@ -36,6 +36,9 @@ properties:
   reg:
     maxItems: 1
 
+  interrupts:
+    maxItems: 1
+
   fsl,pfuze-support-disable-sw:
     $ref: /schemas/types.yaml#/definitions/flag
     description: |
index 7e58471097f8c70e2b6e8d806f533e7530cff8e7..80ecf938b74933fd836c9bab0d5e75cf039ebbf3 100644 (file)
@@ -64,6 +64,7 @@ properties:
         defined, <100> is assumed, meaning that
         pwm-dutycycle-range contains values expressed in
         percent.
+    $ref: /schemas/types.yaml#/definitions/uint32
     default: 100
 
   pwm-dutycycle-range:
diff --git a/Documentation/devicetree/bindings/regulator/renesas,raa215300.yaml b/Documentation/devicetree/bindings/regulator/renesas,raa215300.yaml
new file mode 100644 (file)
index 0000000..97cff71
--- /dev/null
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/renesas,raa215300.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RAA215300 Power Management Integrated Circuit (PMIC)
+
+maintainers:
+  - Biju Das <biju.das.jz@bp.renesas.com>
+
+description: |
+  The RAA215300 is a high-performance, low-cost 9-channel PMIC designed for
+  32-bit and 64-bit MCU and MPU applications. It supports DDR3, DDR3L, DDR4,
+  and LPDDR4 memory power requirements. The internally compensated regulators,
+  built-in Real-Time Clock (RTC), 32kHz crystal oscillator, and coin cell
+  battery charger provide a highly integrated, small footprint power solution
+  ideal for System-On-Module (SOM) applications. A spread spectrum feature
+  provides an ease-of-use solution for noise-sensitive audio or RF applications.
+
+  This device exposes two devices via I2C. One for the integrated RTC IP, and
+  one for everything else.
+
+  Link to datasheet:
+  https://www.renesas.com/in/en/products/power-power-management/multi-channel-power-management-ics-pmics/ssdsoc-power-management-ics-pmic-and-pmus/raa215300-high-performance-9-channel-pmic-supporting-ddr-memory-built-charger-and-rtc
+
+properties:
+  compatible:
+    enum:
+      - renesas,raa215300
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: main
+      - const: rtc
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    description: |
+      The clocks are optional. The RTC is disabled, if no clocks are
+      provided(either xin or clkin).
+    maxItems: 1
+
+  clock-names:
+    description: |
+      Use xin, if connected to an external crystal.
+      Use clkin, if connected to an external clock signal.
+    enum:
+      - xin
+      - clkin
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    /* 32.768kHz crystal */
+    x2: x2-clock {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <32768>;
+    };
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        raa215300: pmic@12 {
+            compatible = "renesas,raa215300";
+            reg = <0x12>, <0x6f>;
+            reg-names = "main", "rtc";
+
+            clocks = <&x2>;
+            clock-names = "xin";
+        };
+    };
diff --git a/Documentation/devicetree/bindings/regulator/ti,tps62870.yaml b/Documentation/devicetree/bindings/regulator/ti,tps62870.yaml
new file mode 100644 (file)
index 0000000..3869895
--- /dev/null
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/ti,tps62870.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI TPS62870/TPS62871/TPS62872/TPS62873 voltage regulator
+
+maintainers:
+  - MÃ¥rten Lindahl <marten.lindahl@axis.com>
+
+allOf:
+  - $ref: regulator.yaml#
+
+properties:
+  compatible:
+    enum:
+      - ti,tps62870
+      - ti,tps62871
+      - ti,tps62872
+      - ti,tps62873
+
+  reg:
+    maxItems: 1
+
+  regulator-initial-mode:
+    enum: [ 1, 2 ]
+    description: 1 - Forced PWM mode, 2 - Low power mode
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      regulator@41 {
+        compatible = "ti,tps62873";
+        reg = <0x41>;
+        regulator-name = "+0.75V";
+        regulator-min-microvolt = <400000>;
+        regulator-max-microvolt = <1675000>;
+        regulator-initial-mode = <1>;
+      };
+    };
+
+...
index 016814e15536a97d81be6702af644e31abfd8af7..c0c8e526a1e953898d6144230a091b33f9fb2488 100644 (file)
@@ -82,7 +82,7 @@ config COMMON_CLK_MAX9485
 
 config COMMON_CLK_RK808
        tristate "Clock driver for RK805/RK808/RK809/RK817/RK818"
-       depends on MFD_RK808
+       depends on MFD_RK8XX
        help
          This driver supports RK805, RK809 and RK817, RK808 and RK818 crystal oscillator clock.
          These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each.
index 32f833d732ed5655fdcd7419ea626cc2fa04654d..f7412b137e5ef4766254729621e9ce82eae29cb1 100644 (file)
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/rk808.h>
-#include <linux/i2c.h>
 
 struct rk808_clkout {
-       struct rk808 *rk808;
+       struct regmap           *regmap;
        struct clk_hw           clkout1_hw;
        struct clk_hw           clkout2_hw;
 };
@@ -31,9 +30,8 @@ static int rk808_clkout2_enable(struct clk_hw *hw, bool enable)
        struct rk808_clkout *rk808_clkout = container_of(hw,
                                                         struct rk808_clkout,
                                                         clkout2_hw);
-       struct rk808 *rk808 = rk808_clkout->rk808;
 
-       return regmap_update_bits(rk808->regmap, RK808_CLK32OUT_REG,
+       return regmap_update_bits(rk808_clkout->regmap, RK808_CLK32OUT_REG,
                                  CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0);
 }
 
@@ -52,10 +50,9 @@ static int rk808_clkout2_is_prepared(struct clk_hw *hw)
        struct rk808_clkout *rk808_clkout = container_of(hw,
                                                         struct rk808_clkout,
                                                         clkout2_hw);
-       struct rk808 *rk808 = rk808_clkout->rk808;
        uint32_t val;
 
-       int ret = regmap_read(rk808->regmap, RK808_CLK32OUT_REG, &val);
+       int ret = regmap_read(rk808_clkout->regmap, RK808_CLK32OUT_REG, &val);
 
        if (ret < 0)
                return ret;
@@ -93,9 +90,8 @@ static int rk817_clkout2_enable(struct clk_hw *hw, bool enable)
        struct rk808_clkout *rk808_clkout = container_of(hw,
                                                         struct rk808_clkout,
                                                         clkout2_hw);
-       struct rk808 *rk808 = rk808_clkout->rk808;
 
-       return regmap_update_bits(rk808->regmap, RK817_SYS_CFG(1),
+       return regmap_update_bits(rk808_clkout->regmap, RK817_SYS_CFG(1),
                                  RK817_CLK32KOUT2_EN,
                                  enable ? RK817_CLK32KOUT2_EN : 0);
 }
@@ -115,10 +111,9 @@ static int rk817_clkout2_is_prepared(struct clk_hw *hw)
        struct rk808_clkout *rk808_clkout = container_of(hw,
                                                         struct rk808_clkout,
                                                         clkout2_hw);
-       struct rk808 *rk808 = rk808_clkout->rk808;
        unsigned int val;
 
-       int ret = regmap_read(rk808->regmap, RK817_SYS_CFG(1), &val);
+       int ret = regmap_read(rk808_clkout->regmap, RK817_SYS_CFG(1), &val);
 
        if (ret < 0)
                return 0;
@@ -153,18 +148,21 @@ static const struct clk_ops *rkpmic_get_ops(long variant)
 static int rk808_clkout_probe(struct platform_device *pdev)
 {
        struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
-       struct i2c_client *client = rk808->i2c;
-       struct device_node *node = client->dev.of_node;
+       struct device *dev = &pdev->dev;
        struct clk_init_data init = {};
        struct rk808_clkout *rk808_clkout;
        int ret;
 
-       rk808_clkout = devm_kzalloc(&client->dev,
+       dev->of_node = pdev->dev.parent->of_node;
+
+       rk808_clkout = devm_kzalloc(dev,
                                    sizeof(*rk808_clkout), GFP_KERNEL);
        if (!rk808_clkout)
                return -ENOMEM;
 
-       rk808_clkout->rk808 = rk808;
+       rk808_clkout->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+       if (!rk808_clkout->regmap)
+               return -ENODEV;
 
        init.parent_names = NULL;
        init.num_parents = 0;
@@ -173,10 +171,10 @@ static int rk808_clkout_probe(struct platform_device *pdev)
        rk808_clkout->clkout1_hw.init = &init;
 
        /* optional override of the clockname */
-       of_property_read_string_index(node, "clock-output-names",
+       of_property_read_string_index(dev->of_node, "clock-output-names",
                                      0, &init.name);
 
-       ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout1_hw);
+       ret = devm_clk_hw_register(dev, &rk808_clkout->clkout1_hw);
        if (ret)
                return ret;
 
@@ -185,10 +183,10 @@ static int rk808_clkout_probe(struct platform_device *pdev)
        rk808_clkout->clkout2_hw.init = &init;
 
        /* optional override of the clockname */
-       of_property_read_string_index(node, "clock-output-names",
+       of_property_read_string_index(dev->of_node, "clock-output-names",
                                      1, &init.name);
 
-       ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout2_hw);
+       ret = devm_clk_hw_register(dev, &rk808_clkout->clkout2_hw);
        if (ret)
                return ret;
 
index 81a54a59e13c4411e7f831e49f7c99424aae2750..8a320e6218e372a36b385bc04a8fa0bfb455cbd2 100644 (file)
@@ -609,7 +609,7 @@ config INPUT_PWM_VIBRA
 
 config INPUT_RK805_PWRKEY
        tristate "Rockchip RK805 PMIC power key support"
-       depends on MFD_RK808
+       depends on MFD_RK8XX
        help
          Select this option to enable power key driver for RK805.
 
index e90463c4441ce325e17d8cf11f2b34d88c59149d..f89f455c130a48fc208ad8b35bda91044b599136 100644 (file)
@@ -1183,12 +1183,17 @@ config MFD_RC5T583
          Additional drivers must be enabled in order to use the
          different functionality of the device.
 
-config MFD_RK808
+config MFD_RK8XX
+       bool
+       select MFD_CORE
+
+config MFD_RK8XX_I2C
        tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
        depends on I2C && OF
        select MFD_CORE
        select REGMAP_I2C
        select REGMAP_IRQ
+       select MFD_RK8XX
        help
          If you say yes here you get support for the RK805, RK808, RK809,
          RK817 and RK818 Power Management chips.
@@ -1196,6 +1201,20 @@ config MFD_RK808
          through I2C interface. The device supports multiple sub-devices
          including interrupts, RTC, LDO & DCDC regulators, and onkey.
 
+config MFD_RK8XX_SPI
+       tristate "Rockchip RK806 Power Management Chip"
+       depends on SPI && OF
+       select MFD_CORE
+       select REGMAP_SPI
+       select REGMAP_IRQ
+       select MFD_RK8XX
+       help
+         If you say yes here you get support for the RK806 Power Management
+         chip.
+         This driver provides common support for accessing the device
+         through an SPI interface. The device supports multiple sub-devices
+         including interrupts, LDO & DCDC regulators, and power on-key.
+
 config MFD_RN5T618
        tristate "Ricoh RN5T567/618 PMIC"
        depends on I2C
@@ -1679,6 +1698,38 @@ config MFD_TPS65912_SPI
          If you say yes here you get support for the TPS65912 series of
          PM chips with SPI interface.
 
+config MFD_TPS6594
+       tristate
+       select MFD_CORE
+       select REGMAP
+       select REGMAP_IRQ
+
+config MFD_TPS6594_I2C
+       tristate "TI TPS6594 Power Management chip with I2C"
+       select MFD_TPS6594
+       select REGMAP_I2C
+       select CRC8
+       depends on I2C
+       help
+         If you say yes here you get support for the TPS6594 series of
+         PM chips with I2C interface.
+
+         This driver can also be built as a module.  If so, the module
+         will be called tps6594-i2c.
+
+config MFD_TPS6594_SPI
+       tristate "TI TPS6594 Power Management chip with SPI"
+       select MFD_TPS6594
+       select REGMAP_SPI
+       select CRC8
+       depends on SPI_MASTER
+       help
+         If you say yes here you get support for the TPS6594 series of
+         PM chips with SPI interface.
+
+         This driver can also be built as a module.  If so, the module
+         will be called tps6594-spi.
+
 config TWL4030_CORE
        bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 Support"
        depends on I2C=y
index 1d2392f06f78a84ad5ed919ee9b0c063a58935ca..39c4615361812bfdfcaf6608b44581cfb62457d9 100644 (file)
@@ -96,6 +96,9 @@ obj-$(CONFIG_MFD_TPS65910)    += tps65910.o
 obj-$(CONFIG_MFD_TPS65912)     += tps65912-core.o
 obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o
 obj-$(CONFIG_MFD_TPS65912_SPI)  += tps65912-spi.o
+obj-$(CONFIG_MFD_TPS6594)      += tps6594-core.o
+obj-$(CONFIG_MFD_TPS6594_I2C)  += tps6594-i2c.o
+obj-$(CONFIG_MFD_TPS6594_SPI)  += tps6594-spi.o
 obj-$(CONFIG_MENELAUS)         += menelaus.o
 
 obj-$(CONFIG_TWL4030_CORE)     += twl-core.o twl4030-irq.o twl6030-irq.o
@@ -214,7 +217,9 @@ obj-$(CONFIG_MFD_PALMAS)    += palmas.o
 obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
 obj-$(CONFIG_MFD_NTXEC)                += ntxec.o
 obj-$(CONFIG_MFD_RC5T583)      += rc5t583.o rc5t583-irq.o
-obj-$(CONFIG_MFD_RK808)                += rk808.o
+obj-$(CONFIG_MFD_RK8XX)                += rk8xx-core.o
+obj-$(CONFIG_MFD_RK8XX_I2C)    += rk8xx-i2c.o
+obj-$(CONFIG_MFD_RK8XX_SPI)    += rk8xx-spi.o
 obj-$(CONFIG_MFD_RN5T618)      += rn5t618.o
 obj-$(CONFIG_MFD_SEC_CORE)     += sec-core.o sec-irq.o
 obj-$(CONFIG_MFD_SYSCON)       += syscon.o
index b4f5cb457117eef57ee3ede5a32a5b2f74e2cb60..a49e5e217554ae22f6bac01e2a60a6c792035547 100644 (file)
@@ -63,6 +63,7 @@ static const struct of_device_id axp20x_i2c_of_match[] = {
        { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
        { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
        { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
+       { .compatible = "x-powers,axp313a", .data = (void *)AXP313A_ID },
        { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
        { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
        { .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
@@ -77,6 +78,7 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
        { "axp209", 0 },
        { "axp221", 0 },
        { "axp223", 0 },
+       { "axp313a", 0 },
        { "axp803", 0 },
        { "axp806", 0 },
        { "axp15060", 0 },
index 72b87aae60cc02d06594f6e28faa686dc3ac0fef..07a846ecbf18eb68540fa8d88d2e4102bf7f63c6 100644 (file)
@@ -39,6 +39,7 @@ static const char * const axp20x_model_names[] = {
        "AXP221",
        "AXP223",
        "AXP288",
+       "AXP313a",
        "AXP803",
        "AXP806",
        "AXP809",
@@ -156,6 +157,25 @@ static const struct regmap_range axp806_writeable_ranges[] = {
        regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
 };
 
+static const struct regmap_range axp313a_writeable_ranges[] = {
+       regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
+};
+
+static const struct regmap_range axp313a_volatile_ranges[] = {
+       regmap_reg_range(AXP313A_SHUTDOWN_CTRL, AXP313A_SHUTDOWN_CTRL),
+       regmap_reg_range(AXP313A_IRQ_STATE, AXP313A_IRQ_STATE),
+};
+
+static const struct regmap_access_table axp313a_writeable_table = {
+       .yes_ranges = axp313a_writeable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges),
+};
+
+static const struct regmap_access_table axp313a_volatile_table = {
+       .yes_ranges = axp313a_volatile_ranges,
+       .n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges),
+};
+
 static const struct regmap_range axp806_volatile_ranges[] = {
        regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
 };
@@ -248,6 +268,11 @@ static const struct resource axp288_fuel_gauge_resources[] = {
        DEFINE_RES_IRQ(AXP288_IRQ_WL1),
 };
 
+static const struct resource axp313a_pek_resources[] = {
+       DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
+       DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
+};
+
 static const struct resource axp803_pek_resources[] = {
        DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
        DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
@@ -304,6 +329,15 @@ static const struct regmap_config axp288_regmap_config = {
        .cache_type     = REGCACHE_RBTREE,
 };
 
+static const struct regmap_config axp313a_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .wr_table = &axp313a_writeable_table,
+       .volatile_table = &axp313a_volatile_table,
+       .max_register = AXP313A_IRQ_STATE,
+       .cache_type = REGCACHE_RBTREE,
+};
+
 static const struct regmap_config axp806_regmap_config = {
        .reg_bits       = 8,
        .val_bits       = 8,
@@ -456,6 +490,16 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
        INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG,            5, 1),
 };
 
+static const struct regmap_irq axp313a_regmap_irqs[] = {
+       INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE,          0, 7),
+       INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE,          0, 6),
+       INIT_REGMAP_IRQ(AXP313A, PEK_SHORT,             0, 5),
+       INIT_REGMAP_IRQ(AXP313A, PEK_LONG,              0, 4),
+       INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW,           0, 3),
+       INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW,           0, 2),
+       INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH,         0, 0),
+};
+
 static const struct regmap_irq axp803_regmap_irqs[] = {
        INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V,            0, 7),
        INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN,            0, 6),
@@ -606,6 +650,17 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
 
 };
 
+static const struct regmap_irq_chip axp313a_regmap_irq_chip = {
+       .name                   = "axp313a_irq_chip",
+       .status_base            = AXP313A_IRQ_STATE,
+       .ack_base               = AXP313A_IRQ_STATE,
+       .unmask_base            = AXP313A_IRQ_EN,
+       .init_ack_masked        = true,
+       .irqs                   = axp313a_regmap_irqs,
+       .num_irqs               = ARRAY_SIZE(axp313a_regmap_irqs),
+       .num_regs               = 1,
+};
+
 static const struct regmap_irq_chip axp803_regmap_irq_chip = {
        .name                   = "axp803",
        .status_base            = AXP20X_IRQ1_STATE,
@@ -745,6 +800,11 @@ static const struct mfd_cell axp152_cells[] = {
        },
 };
 
+static struct mfd_cell axp313a_cells[] = {
+       MFD_CELL_NAME("axp20x-regulator"),
+       MFD_CELL_RES("axp313a-pek", axp313a_pek_resources),
+};
+
 static const struct resource axp288_adc_resources[] = {
        DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
 };
@@ -914,8 +974,18 @@ static const struct mfd_cell axp_regulator_only_cells[] = {
 static int axp20x_power_off(struct sys_off_data *data)
 {
        struct axp20x_dev *axp20x = data->cb_data;
+       unsigned int shutdown_reg;
 
-       regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
+       switch (axp20x->variant) {
+       case AXP313A_ID:
+               shutdown_reg = AXP313A_SHUTDOWN_CTRL;
+               break;
+       default:
+               shutdown_reg = AXP20X_OFF_CTRL;
+               break;
+       }
+
+       regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF);
 
        /* Give capacitors etc. time to drain to avoid kernel panic msg. */
        mdelay(500);
@@ -978,6 +1048,12 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
                axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
                axp20x->irq_flags = IRQF_TRIGGER_LOW;
                break;
+       case AXP313A_ID:
+               axp20x->nr_cells = ARRAY_SIZE(axp313a_cells);
+               axp20x->cells = axp313a_cells;
+               axp20x->regmap_cfg = &axp313a_regmap_config;
+               axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip;
+               break;
        case AXP803_ID:
                axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
                axp20x->cells = axp803_cells;
similarity index 71%
rename from drivers/mfd/rk808.c
rename to drivers/mfd/rk8xx-core.c
index 0f22ef61e8170dd594777597bc2d7e34daa99cd1..e8fc9e2ab1d0d2e27a4d05029a14fa02082f3cd1 100644 (file)
@@ -1,18 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * MFD core driver for Rockchip RK808/RK818
+ * MFD core driver for Rockchip RK8XX
  *
  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) 2016 PHYTEC Messtechnik GmbH
  *
  * Author: Chris Zhong <zyw@rock-chips.com>
  * Author: Zhang Qing <zhangqing@rock-chips.com>
- *
- * Copyright (C) 2016 PHYTEC Messtechnik GmbH
- *
  * Author: Wadim Egorov <w.egorov@phytec.de>
  */
 
-#include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/rk808.h>
 #include <linux/mfd/core.h>
@@ -27,92 +24,6 @@ struct rk808_reg_data {
        int value;
 };
 
-static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
-{
-       /*
-        * Notes:
-        * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
-        *   we don't use that feature.  It's better to cache.
-        * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
-        *   bits are cleared in case when we shutoff anyway, but better safe.
-        */
-
-       switch (reg) {
-       case RK808_SECONDS_REG ... RK808_WEEKS_REG:
-       case RK808_RTC_STATUS_REG:
-       case RK808_VB_MON_REG:
-       case RK808_THERMAL_REG:
-       case RK808_DCDC_UV_STS_REG:
-       case RK808_LDO_UV_STS_REG:
-       case RK808_DCDC_PG_REG:
-       case RK808_LDO_PG_REG:
-       case RK808_DEVCTRL_REG:
-       case RK808_INT_STS_REG1:
-       case RK808_INT_STS_REG2:
-               return true;
-       }
-
-       return false;
-}
-
-static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
-{
-       /*
-        * Notes:
-        * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
-        *   we don't use that feature.  It's better to cache.
-        */
-
-       switch (reg) {
-       case RK817_SECONDS_REG ... RK817_WEEKS_REG:
-       case RK817_RTC_STATUS_REG:
-       case RK817_CODEC_DTOP_LPT_SRST:
-       case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
-       case RK817_PMIC_CHRG_STS:
-       case RK817_PMIC_CHRG_OUT:
-       case RK817_PMIC_CHRG_IN:
-       case RK817_INT_STS_REG0:
-       case RK817_INT_STS_REG1:
-       case RK817_INT_STS_REG2:
-       case RK817_SYS_STS:
-               return true;
-       }
-
-       return false;
-}
-
-static const struct regmap_config rk818_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-       .max_register = RK818_USB_CTRL_REG,
-       .cache_type = REGCACHE_RBTREE,
-       .volatile_reg = rk808_is_volatile_reg,
-};
-
-static const struct regmap_config rk805_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-       .max_register = RK805_OFF_SOURCE_REG,
-       .cache_type = REGCACHE_RBTREE,
-       .volatile_reg = rk808_is_volatile_reg,
-};
-
-static const struct regmap_config rk808_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-       .max_register = RK808_IO_POL_REG,
-       .cache_type = REGCACHE_RBTREE,
-       .volatile_reg = rk808_is_volatile_reg,
-};
-
-static const struct regmap_config rk817_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-       .max_register = RK817_GPIO_INT_CFG,
-       .cache_type = REGCACHE_NONE,
-       .volatile_reg = rk817_is_volatile_reg,
-};
-
 static const struct resource rtc_resources[] = {
        DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
 };
@@ -126,6 +37,11 @@ static const struct resource rk805_key_resources[] = {
        DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
 };
 
+static struct resource rk806_pwrkey_resources[] = {
+       DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
+       DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
+};
+
 static const struct resource rk817_pwrkey_resources[] = {
        DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
        DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
@@ -153,6 +69,17 @@ static const struct mfd_cell rk805s[] = {
        },
 };
 
+static const struct mfd_cell rk806s[] = {
+       { .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, },
+       { .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, },
+       {
+               .name = "rk805-pwrkey",
+               .resources = rk806_pwrkey_resources,
+               .num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
+               .id = PLATFORM_DEVID_AUTO,
+       },
+};
+
 static const struct mfd_cell rk808s[] = {
        { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
        { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
@@ -212,6 +139,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = {
        {RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
 };
 
+static const struct rk808_reg_data rk806_pre_init_reg[] = {
+       { RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
+       { RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
+       { RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
+};
+
 static const struct rk808_reg_data rk808_pre_init_reg[] = {
        { RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
        { RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
@@ -362,6 +295,27 @@ static const struct regmap_irq rk805_irqs[] = {
        },
 };
 
+static const struct regmap_irq rk806_irqs[] = {
+       /* INT_STS0 IRQs */
+       REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
+       REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
+       REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
+       REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
+       REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
+       REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
+       REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
+       REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
+       /* INT_STS1 IRQs */
+       REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
+       REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
+       REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
+       REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
+       REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
+       REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
+       REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
+       REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
+};
+
 static const struct regmap_irq rk808_irqs[] = {
        /* INT_STS */
        [RK808_IRQ_VOUT_LO] = {
@@ -512,6 +466,18 @@ static struct regmap_irq_chip rk805_irq_chip = {
        .init_ack_masked = true,
 };
 
+static struct regmap_irq_chip rk806_irq_chip = {
+       .name = "rk806",
+       .irqs = rk806_irqs,
+       .num_irqs = ARRAY_SIZE(rk806_irqs),
+       .num_regs = 2,
+       .irq_reg_stride = 2,
+       .mask_base = RK806_INT_MSK0,
+       .status_base = RK806_INT_STS0,
+       .ack_base = RK806_INT_STS0,
+       .init_ack_masked = true,
+};
+
 static const struct regmap_irq_chip rk808_irq_chip = {
        .name = "rk808",
        .irqs = rk808_irqs,
@@ -548,13 +514,11 @@ static const struct regmap_irq_chip rk818_irq_chip = {
        .init_ack_masked = true,
 };
 
-static struct i2c_client *rk808_i2c_client;
-
-static void rk808_pm_power_off(void)
+static int rk808_power_off(struct sys_off_data *data)
 {
+       struct rk808 *rk808 = data->cb_data;
        int ret;
        unsigned int reg, bit;
-       struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
 
        switch (rk808->variant) {
        case RK805_ID:
@@ -575,16 +539,18 @@ static void rk808_pm_power_off(void)
                bit = DEV_OFF;
                break;
        default:
-               return;
+               return NOTIFY_DONE;
        }
        ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
        if (ret)
-               dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
+               dev_err(rk808->dev, "Failed to shutdown device!\n");
+
+       return NOTIFY_DONE;
 }
 
-static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd)
+static int rk808_restart(struct sys_off_data *data)
 {
-       struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+       struct rk808 *rk808 = data->cb_data;
        unsigned int reg, bit;
        int ret;
 
@@ -600,19 +566,14 @@ static int rk808_restart_notify(struct notifier_block *this, unsigned long mode,
        }
        ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
        if (ret)
-               dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n");
+               dev_err(rk808->dev, "Failed to restart device!\n");
 
        return NOTIFY_DONE;
 }
 
-static struct notifier_block rk808_restart_handler = {
-       .notifier_call = rk808_restart_notify,
-       .priority = 192,
-};
-
-static void rk8xx_shutdown(struct i2c_client *client)
+void rk8xx_shutdown(struct device *dev)
 {
-       struct rk808 *rk808 = i2c_get_clientdata(client);
+       struct rk808 *rk808 = dev_get_drvdata(dev);
        int ret;
 
        switch (rk808->variant) {
@@ -633,75 +594,47 @@ static void rk8xx_shutdown(struct i2c_client *client)
                return;
        }
        if (ret)
-               dev_warn(&client->dev,
+               dev_warn(dev,
                         "Cannot switch to power down function\n");
 }
+EXPORT_SYMBOL_GPL(rk8xx_shutdown);
 
-static const struct of_device_id rk808_of_match[] = {
-       { .compatible = "rockchip,rk805" },
-       { .compatible = "rockchip,rk808" },
-       { .compatible = "rockchip,rk809" },
-       { .compatible = "rockchip,rk817" },
-       { .compatible = "rockchip,rk818" },
-       { },
-};
-MODULE_DEVICE_TABLE(of, rk808_of_match);
-
-static int rk808_probe(struct i2c_client *client)
+int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
 {
-       struct device_node *np = client->dev.of_node;
        struct rk808 *rk808;
        const struct rk808_reg_data *pre_init_reg;
        const struct mfd_cell *cells;
+       int dual_support = 0;
        int nr_pre_init_regs;
        int nr_cells;
-       int msb, lsb;
-       unsigned char pmic_id_msb, pmic_id_lsb;
        int ret;
        int i;
 
-       rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
+       rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
        if (!rk808)
                return -ENOMEM;
-
-       if (of_device_is_compatible(np, "rockchip,rk817") ||
-           of_device_is_compatible(np, "rockchip,rk809")) {
-               pmic_id_msb = RK817_ID_MSB;
-               pmic_id_lsb = RK817_ID_LSB;
-       } else {
-               pmic_id_msb = RK808_ID_MSB;
-               pmic_id_lsb = RK808_ID_LSB;
-       }
-
-       /* Read chip variant */
-       msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
-       if (msb < 0) {
-               dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
-                       RK808_ID_MSB);
-               return msb;
-       }
-
-       lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
-       if (lsb < 0) {
-               dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
-                       RK808_ID_LSB);
-               return lsb;
-       }
-
-       rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
-       dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
+       rk808->dev = dev;
+       rk808->variant = variant;
+       rk808->regmap = regmap;
+       dev_set_drvdata(dev, rk808);
 
        switch (rk808->variant) {
        case RK805_ID:
-               rk808->regmap_cfg = &rk805_regmap_config;
                rk808->regmap_irq_chip = &rk805_irq_chip;
                pre_init_reg = rk805_pre_init_reg;
                nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
                cells = rk805s;
                nr_cells = ARRAY_SIZE(rk805s);
                break;
+       case RK806_ID:
+               rk808->regmap_irq_chip = &rk806_irq_chip;
+               pre_init_reg = rk806_pre_init_reg;
+               nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
+               cells = rk806s;
+               nr_cells = ARRAY_SIZE(rk806s);
+               dual_support = IRQF_SHARED;
+               break;
        case RK808_ID:
-               rk808->regmap_cfg = &rk808_regmap_config;
                rk808->regmap_irq_chip = &rk808_irq_chip;
                pre_init_reg = rk808_pre_init_reg;
                nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
@@ -709,7 +642,6 @@ static int rk808_probe(struct i2c_client *client)
                nr_cells = ARRAY_SIZE(rk808s);
                break;
        case RK818_ID:
-               rk808->regmap_cfg = &rk818_regmap_config;
                rk808->regmap_irq_chip = &rk818_irq_chip;
                pre_init_reg = rk818_pre_init_reg;
                nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
@@ -718,7 +650,6 @@ static int rk808_probe(struct i2c_client *client)
                break;
        case RK809_ID:
        case RK817_ID:
-               rk808->regmap_cfg = &rk817_regmap_config;
                rk808->regmap_irq_chip = &rk817_irq_chip;
                pre_init_reg = rk817_pre_init_reg;
                nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
@@ -726,97 +657,64 @@ static int rk808_probe(struct i2c_client *client)
                nr_cells = ARRAY_SIZE(rk817s);
                break;
        default:
-               dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
-                       rk808->variant);
+               dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
                return -EINVAL;
        }
 
-       rk808->i2c = client;
-       i2c_set_clientdata(client, rk808);
-
-       rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
-       if (IS_ERR(rk808->regmap)) {
-               dev_err(&client->dev, "regmap initialization failed\n");
-               return PTR_ERR(rk808->regmap);
-       }
-
-       if (!client->irq) {
-               dev_err(&client->dev, "No interrupt support, no core IRQ\n");
-               return -EINVAL;
-       }
+       if (!irq)
+               return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
 
-       ret = regmap_add_irq_chip(rk808->regmap, client->irq,
-                                 IRQF_ONESHOT, -1,
-                                 rk808->regmap_irq_chip, &rk808->irq_data);
-       if (ret) {
-               dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
-               return ret;
-       }
+       ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
+                                      IRQF_ONESHOT | dual_support, -1,
+                                      rk808->regmap_irq_chip, &rk808->irq_data);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
 
        for (i = 0; i < nr_pre_init_regs; i++) {
                ret = regmap_update_bits(rk808->regmap,
                                        pre_init_reg[i].addr,
                                        pre_init_reg[i].mask,
                                        pre_init_reg[i].value);
-               if (ret) {
-                       dev_err(&client->dev,
-                               "0x%x write err\n",
-                               pre_init_reg[i].addr);
-                       return ret;
-               }
+               if (ret)
+                       return dev_err_probe(dev, ret, "0x%x write err\n",
+                                            pre_init_reg[i].addr);
        }
 
-       ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
-                             cells, nr_cells, NULL, 0,
+       ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0,
                              regmap_irq_get_domain(rk808->irq_data));
-       if (ret) {
-               dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
-               goto err_irq;
-       }
+       if (ret)
+               return dev_err_probe(dev, ret, "failed to add MFD devices\n");
 
-       if (of_property_read_bool(np, "rockchip,system-power-controller")) {
-               rk808_i2c_client = client;
-               pm_power_off = rk808_pm_power_off;
+       if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
+               ret = devm_register_sys_off_handler(dev,
+                                   SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
+                                   &rk808_power_off, rk808);
+               if (ret)
+                       return dev_err_probe(dev, ret,
+                                            "failed to register poweroff handler\n");
 
                switch (rk808->variant) {
                case RK809_ID:
                case RK817_ID:
-                       ret = register_restart_handler(&rk808_restart_handler);
+                       ret = devm_register_sys_off_handler(dev,
+                                                           SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
+                                                           &rk808_restart, rk808);
                        if (ret)
-                               dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
+                               dev_warn(dev, "failed to register rst handler, %d\n", ret);
                        break;
                default:
-                       dev_dbg(&client->dev, "pmic controlled board reset not supported\n");
+                       dev_dbg(dev, "pmic controlled board reset not supported\n");
                        break;
                }
        }
 
        return 0;
-
-err_irq:
-       regmap_del_irq_chip(client->irq, rk808->irq_data);
-       return ret;
 }
+EXPORT_SYMBOL_GPL(rk8xx_probe);
 
-static void rk808_remove(struct i2c_client *client)
+int rk8xx_suspend(struct device *dev)
 {
-       struct rk808 *rk808 = i2c_get_clientdata(client);
-
-       regmap_del_irq_chip(client->irq, rk808->irq_data);
-
-       /**
-        * pm_power_off may points to a function from another module.
-        * Check if the pointer is set by us and only then overwrite it.
-        */
-       if (pm_power_off == rk808_pm_power_off)
-               pm_power_off = NULL;
-
-       unregister_restart_handler(&rk808_restart_handler);
-}
-
-static int __maybe_unused rk8xx_suspend(struct device *dev)
-{
-       struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
+       struct rk808 *rk808 = dev_get_drvdata(dev);
        int ret = 0;
 
        switch (rk808->variant) {
@@ -839,10 +737,11 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(rk8xx_suspend);
 
-static int __maybe_unused rk8xx_resume(struct device *dev)
+int rk8xx_resume(struct device *dev)
 {
-       struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
+       struct rk808 *rk808 = dev_get_drvdata(dev);
        int ret = 0;
 
        switch (rk808->variant) {
@@ -859,23 +758,10 @@ static int __maybe_unused rk8xx_resume(struct device *dev)
 
        return ret;
 }
-static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
-
-static struct i2c_driver rk808_i2c_driver = {
-       .driver = {
-               .name = "rk808",
-               .of_match_table = rk808_of_match,
-               .pm = &rk8xx_pm_ops,
-       },
-       .probe_new = rk808_probe,
-       .remove   = rk808_remove,
-       .shutdown = rk8xx_shutdown,
-};
-
-module_i2c_driver(rk808_i2c_driver);
+EXPORT_SYMBOL_GPL(rk8xx_resume);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
-MODULE_DESCRIPTION("RK808/RK818 PMIC driver");
+MODULE_DESCRIPTION("RK8xx PMIC core");
diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c
new file mode 100644 (file)
index 0000000..2822bfa
--- /dev/null
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Rockchip RK808/RK818 Core (I2C) driver
+ *
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) 2016 PHYTEC Messtechnik GmbH
+ *
+ * Author: Chris Zhong <zyw@rock-chips.com>
+ * Author: Zhang Qing <zhangqing@rock-chips.com>
+ * Author: Wadim Egorov <w.egorov@phytec.de>
+ */
+
+#include <linux/i2c.h>
+#include <linux/mfd/rk808.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+struct rk8xx_i2c_platform_data {
+       const struct regmap_config *regmap_cfg;
+       int variant;
+};
+
+static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+       /*
+        * Notes:
+        * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
+        *   we don't use that feature.  It's better to cache.
+        * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
+        *   bits are cleared in case when we shutoff anyway, but better safe.
+        */
+
+       switch (reg) {
+       case RK808_SECONDS_REG ... RK808_WEEKS_REG:
+       case RK808_RTC_STATUS_REG:
+       case RK808_VB_MON_REG:
+       case RK808_THERMAL_REG:
+       case RK808_DCDC_UV_STS_REG:
+       case RK808_LDO_UV_STS_REG:
+       case RK808_DCDC_PG_REG:
+       case RK808_LDO_PG_REG:
+       case RK808_DEVCTRL_REG:
+       case RK808_INT_STS_REG1:
+       case RK808_INT_STS_REG2:
+               return true;
+       }
+
+       return false;
+}
+
+static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+       /*
+        * Notes:
+        * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
+        *   we don't use that feature.  It's better to cache.
+        */
+
+       switch (reg) {
+       case RK817_SECONDS_REG ... RK817_WEEKS_REG:
+       case RK817_RTC_STATUS_REG:
+       case RK817_CODEC_DTOP_LPT_SRST:
+       case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
+       case RK817_PMIC_CHRG_STS:
+       case RK817_PMIC_CHRG_OUT:
+       case RK817_PMIC_CHRG_IN:
+       case RK817_INT_STS_REG0:
+       case RK817_INT_STS_REG1:
+       case RK817_INT_STS_REG2:
+       case RK817_SYS_STS:
+               return true;
+       }
+
+       return false;
+}
+
+
+static const struct regmap_config rk818_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = RK818_USB_CTRL_REG,
+       .cache_type = REGCACHE_RBTREE,
+       .volatile_reg = rk808_is_volatile_reg,
+};
+
+static const struct regmap_config rk805_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = RK805_OFF_SOURCE_REG,
+       .cache_type = REGCACHE_RBTREE,
+       .volatile_reg = rk808_is_volatile_reg,
+};
+
+static const struct regmap_config rk808_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = RK808_IO_POL_REG,
+       .cache_type = REGCACHE_RBTREE,
+       .volatile_reg = rk808_is_volatile_reg,
+};
+
+static const struct regmap_config rk817_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = RK817_GPIO_INT_CFG,
+       .cache_type = REGCACHE_NONE,
+       .volatile_reg = rk817_is_volatile_reg,
+};
+
+static const struct rk8xx_i2c_platform_data rk805_data = {
+       .regmap_cfg = &rk805_regmap_config,
+       .variant = RK805_ID,
+};
+
+static const struct rk8xx_i2c_platform_data rk808_data = {
+       .regmap_cfg = &rk808_regmap_config,
+       .variant = RK808_ID,
+};
+
+static const struct rk8xx_i2c_platform_data rk809_data = {
+       .regmap_cfg = &rk817_regmap_config,
+       .variant = RK809_ID,
+};
+
+static const struct rk8xx_i2c_platform_data rk817_data = {
+       .regmap_cfg = &rk817_regmap_config,
+       .variant = RK817_ID,
+};
+
+static const struct rk8xx_i2c_platform_data rk818_data = {
+       .regmap_cfg = &rk818_regmap_config,
+       .variant = RK818_ID,
+};
+
+static int rk8xx_i2c_probe(struct i2c_client *client)
+{
+       const struct rk8xx_i2c_platform_data *data;
+       struct regmap *regmap;
+
+       data = device_get_match_data(&client->dev);
+       if (!data)
+               return -ENODEV;
+
+       regmap = devm_regmap_init_i2c(client, data->regmap_cfg);
+       if (IS_ERR(regmap))
+               return dev_err_probe(&client->dev, PTR_ERR(regmap),
+                                    "regmap initialization failed\n");
+
+       return rk8xx_probe(&client->dev, data->variant, client->irq, regmap);
+}
+
+static void rk8xx_i2c_shutdown(struct i2c_client *client)
+{
+       rk8xx_shutdown(&client->dev);
+}
+
+static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
+
+static const struct of_device_id rk8xx_i2c_of_match[] = {
+       { .compatible = "rockchip,rk805", .data = &rk805_data },
+       { .compatible = "rockchip,rk808", .data = &rk808_data },
+       { .compatible = "rockchip,rk809", .data = &rk809_data },
+       { .compatible = "rockchip,rk817", .data = &rk817_data },
+       { .compatible = "rockchip,rk818", .data = &rk818_data },
+       { },
+};
+MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match);
+
+static struct i2c_driver rk8xx_i2c_driver = {
+       .driver = {
+               .name = "rk8xx-i2c",
+               .of_match_table = rk8xx_i2c_of_match,
+               .pm = &rk8xx_i2c_pm_ops,
+       },
+       .probe_new = rk8xx_i2c_probe,
+       .shutdown  = rk8xx_i2c_shutdown,
+};
+module_i2c_driver(rk8xx_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
+MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
+MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
+MODULE_DESCRIPTION("RK8xx I2C PMIC driver");
diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c
new file mode 100644 (file)
index 0000000..fd137f3
--- /dev/null
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip RK806 Core (SPI) driver
+ *
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2023 Collabora Ltd.
+ *
+ * Author: Xu Shengfei <xsf@rock-chips.com>
+ * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rk808.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#define RK806_ADDR_SIZE 2
+#define RK806_CMD_WITH_SIZE(CMD, VALUE_BYTES) \
+       (RK806_CMD_##CMD | RK806_CMD_CRC_DIS | (VALUE_BYTES - 1))
+
+static const struct regmap_range rk806_volatile_ranges[] = {
+       regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5),
+       regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1),
+};
+
+static const struct regmap_access_table rk806_volatile_table = {
+       .yes_ranges = rk806_volatile_ranges,
+       .n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges),
+};
+
+static const struct regmap_config rk806_regmap_config_spi = {
+       .reg_bits = 16,
+       .val_bits = 8,
+       .max_register = RK806_BUCK_RSERVE_REG5,
+       .cache_type = REGCACHE_RBTREE,
+       .volatile_table = &rk806_volatile_table,
+};
+
+static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
+{
+       struct device *dev = context;
+       struct spi_device *spi = to_spi_device(dev);
+       struct spi_transfer xfer[2] = { 0 };
+       /* data and thus count includes the register address */
+       size_t val_size = count - RK806_ADDR_SIZE;
+       char cmd;
+
+       if (val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1))
+               return -EINVAL;
+
+       cmd = RK806_CMD_WITH_SIZE(WRITE, val_size);
+
+       xfer[0].tx_buf = &cmd;
+       xfer[0].len = sizeof(cmd);
+       xfer[1].tx_buf = vdata;
+       xfer[1].len = count;
+
+       return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
+}
+
+static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
+                             void *val, size_t val_size)
+{
+       struct device *dev = context;
+       struct spi_device *spi = to_spi_device(dev);
+       char txbuf[3] = { 0 };
+
+       if (reg_size != RK806_ADDR_SIZE ||
+           val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1))
+               return -EINVAL;
+
+       /* TX buffer contains command byte followed by two address bytes */
+       txbuf[0] = RK806_CMD_WITH_SIZE(READ, val_size);
+       memcpy(txbuf+1, vreg, reg_size);
+
+       return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
+}
+
+static const struct regmap_bus rk806_regmap_bus_spi = {
+       .write = rk806_spi_bus_write,
+       .read = rk806_spi_bus_read,
+       .reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
+};
+
+static int rk8xx_spi_probe(struct spi_device *spi)
+{
+       struct regmap *regmap;
+
+       regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi,
+                                 &spi->dev, &rk806_regmap_config_spi);
+       if (IS_ERR(regmap))
+               return dev_err_probe(&spi->dev, PTR_ERR(regmap),
+                                    "Failed to init regmap\n");
+
+       return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
+}
+
+static const struct of_device_id rk8xx_spi_of_match[] = {
+       { .compatible = "rockchip,rk806", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match);
+
+static const struct spi_device_id rk8xx_spi_id_table[] = {
+       { "rk806", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table);
+
+static struct spi_driver rk8xx_spi_driver = {
+       .driver         = {
+               .name   = "rk8xx-spi",
+               .of_match_table = rk8xx_spi_of_match,
+       },
+       .probe          = rk8xx_spi_probe,
+       .id_table       = rk8xx_spi_id_table,
+};
+module_spi_driver(rk8xx_spi_driver);
+
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
+MODULE_DESCRIPTION("RK8xx SPI PMIC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tps6594-core.c b/drivers/mfd/tps6594-core.c
new file mode 100644 (file)
index 0000000..15f3148
--- /dev/null
@@ -0,0 +1,462 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Core functions for TI TPS6594/TPS6593/LP8764 PMICs
+ *
+ * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
+ */
+
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/tps6594.h>
+
+#define TPS6594_CRC_SYNC_TIMEOUT_MS 150
+
+/* Completion to synchronize CRC feature enabling on all PMICs */
+static DECLARE_COMPLETION(tps6594_crc_comp);
+
+static const struct resource tps6594_regulator_resources[] = {
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK1_OV, TPS6594_IRQ_NAME_BUCK1_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK1_UV, TPS6594_IRQ_NAME_BUCK1_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK1_SC, TPS6594_IRQ_NAME_BUCK1_SC),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK1_ILIM, TPS6594_IRQ_NAME_BUCK1_ILIM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK2_OV, TPS6594_IRQ_NAME_BUCK2_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK2_UV, TPS6594_IRQ_NAME_BUCK2_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK2_SC, TPS6594_IRQ_NAME_BUCK2_SC),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK2_ILIM, TPS6594_IRQ_NAME_BUCK2_ILIM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK3_OV, TPS6594_IRQ_NAME_BUCK3_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK3_UV, TPS6594_IRQ_NAME_BUCK3_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK3_SC, TPS6594_IRQ_NAME_BUCK3_SC),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK3_ILIM, TPS6594_IRQ_NAME_BUCK3_ILIM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK4_OV, TPS6594_IRQ_NAME_BUCK4_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK4_UV, TPS6594_IRQ_NAME_BUCK4_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK4_SC, TPS6594_IRQ_NAME_BUCK4_SC),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK4_ILIM, TPS6594_IRQ_NAME_BUCK4_ILIM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK5_OV, TPS6594_IRQ_NAME_BUCK5_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK5_UV, TPS6594_IRQ_NAME_BUCK5_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK5_SC, TPS6594_IRQ_NAME_BUCK5_SC),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK5_ILIM, TPS6594_IRQ_NAME_BUCK5_ILIM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO1_OV, TPS6594_IRQ_NAME_LDO1_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO1_UV, TPS6594_IRQ_NAME_LDO1_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO1_SC, TPS6594_IRQ_NAME_LDO1_SC),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO1_ILIM, TPS6594_IRQ_NAME_LDO1_ILIM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO2_OV, TPS6594_IRQ_NAME_LDO2_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO2_UV, TPS6594_IRQ_NAME_LDO2_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO2_SC, TPS6594_IRQ_NAME_LDO2_SC),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO2_ILIM, TPS6594_IRQ_NAME_LDO2_ILIM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO3_OV, TPS6594_IRQ_NAME_LDO3_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO3_UV, TPS6594_IRQ_NAME_LDO3_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO3_SC, TPS6594_IRQ_NAME_LDO3_SC),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO3_ILIM, TPS6594_IRQ_NAME_LDO3_ILIM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO4_OV, TPS6594_IRQ_NAME_LDO4_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO4_UV, TPS6594_IRQ_NAME_LDO4_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO4_SC, TPS6594_IRQ_NAME_LDO4_SC),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO4_ILIM, TPS6594_IRQ_NAME_LDO4_ILIM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VCCA_OV, TPS6594_IRQ_NAME_VCCA_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VCCA_UV, TPS6594_IRQ_NAME_VCCA_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON1_OV, TPS6594_IRQ_NAME_VMON1_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON1_UV, TPS6594_IRQ_NAME_VMON1_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON1_RV, TPS6594_IRQ_NAME_VMON1_RV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON2_OV, TPS6594_IRQ_NAME_VMON2_OV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON2_UV, TPS6594_IRQ_NAME_VMON2_UV),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON2_RV, TPS6594_IRQ_NAME_VMON2_RV),
+};
+
+static const struct resource tps6594_pinctrl_resources[] = {
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO9, TPS6594_IRQ_NAME_GPIO9),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO10, TPS6594_IRQ_NAME_GPIO10),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO11, TPS6594_IRQ_NAME_GPIO11),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO1, TPS6594_IRQ_NAME_GPIO1),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO2, TPS6594_IRQ_NAME_GPIO2),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO3, TPS6594_IRQ_NAME_GPIO3),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO4, TPS6594_IRQ_NAME_GPIO4),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO5, TPS6594_IRQ_NAME_GPIO5),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO6, TPS6594_IRQ_NAME_GPIO6),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO7, TPS6594_IRQ_NAME_GPIO7),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO8, TPS6594_IRQ_NAME_GPIO8),
+};
+
+static const struct resource tps6594_pfsm_resources[] = {
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NPWRON_START, TPS6594_IRQ_NAME_NPWRON_START),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ENABLE, TPS6594_IRQ_NAME_ENABLE),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_FSD, TPS6594_IRQ_NAME_FSD),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_SOFT_REBOOT, TPS6594_IRQ_NAME_SOFT_REBOOT),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BIST_PASS, TPS6594_IRQ_NAME_BIST_PASS),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_EXT_CLK, TPS6594_IRQ_NAME_EXT_CLK),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_TWARN, TPS6594_IRQ_NAME_TWARN),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_TSD_ORD, TPS6594_IRQ_NAME_TSD_ORD),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BIST_FAIL, TPS6594_IRQ_NAME_BIST_FAIL),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_REG_CRC_ERR, TPS6594_IRQ_NAME_REG_CRC_ERR),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_RECOV_CNT, TPS6594_IRQ_NAME_RECOV_CNT),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_SPMI_ERR, TPS6594_IRQ_NAME_SPMI_ERR),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NPWRON_LONG, TPS6594_IRQ_NAME_NPWRON_LONG),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NINT_READBACK, TPS6594_IRQ_NAME_NINT_READBACK),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NRSTOUT_READBACK, TPS6594_IRQ_NAME_NRSTOUT_READBACK),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_TSD_IMM, TPS6594_IRQ_NAME_TSD_IMM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VCCA_OVP, TPS6594_IRQ_NAME_VCCA_OVP),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_PFSM_ERR, TPS6594_IRQ_NAME_PFSM_ERR),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_IMM_SHUTDOWN, TPS6594_IRQ_NAME_IMM_SHUTDOWN),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ORD_SHUTDOWN, TPS6594_IRQ_NAME_ORD_SHUTDOWN),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_MCU_PWR_ERR, TPS6594_IRQ_NAME_MCU_PWR_ERR),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_SOC_PWR_ERR, TPS6594_IRQ_NAME_SOC_PWR_ERR),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_COMM_FRM_ERR, TPS6594_IRQ_NAME_COMM_FRM_ERR),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_COMM_CRC_ERR, TPS6594_IRQ_NAME_COMM_CRC_ERR),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_COMM_ADR_ERR, TPS6594_IRQ_NAME_COMM_ADR_ERR),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_EN_DRV_READBACK, TPS6594_IRQ_NAME_EN_DRV_READBACK),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NRSTOUT_SOC_READBACK,
+                            TPS6594_IRQ_NAME_NRSTOUT_SOC_READBACK),
+};
+
+static const struct resource tps6594_esm_resources[] = {
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ESM_SOC_PIN, TPS6594_IRQ_NAME_ESM_SOC_PIN),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ESM_SOC_FAIL, TPS6594_IRQ_NAME_ESM_SOC_FAIL),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ESM_SOC_RST, TPS6594_IRQ_NAME_ESM_SOC_RST),
+};
+
+static const struct resource tps6594_rtc_resources[] = {
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_TIMER, TPS6594_IRQ_NAME_TIMER),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ALARM, TPS6594_IRQ_NAME_ALARM),
+       DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_POWER_UP, TPS6594_IRQ_NAME_POWERUP),
+};
+
+static const struct mfd_cell tps6594_common_cells[] = {
+       MFD_CELL_RES("tps6594-regulator", tps6594_regulator_resources),
+       MFD_CELL_RES("tps6594-pinctrl", tps6594_pinctrl_resources),
+       MFD_CELL_RES("tps6594-pfsm", tps6594_pfsm_resources),
+       MFD_CELL_RES("tps6594-esm", tps6594_esm_resources),
+};
+
+static const struct mfd_cell tps6594_rtc_cells[] = {
+       MFD_CELL_RES("tps6594-rtc", tps6594_rtc_resources),
+};
+
+static const struct regmap_irq tps6594_irqs[] = {
+       /* INT_BUCK1_2 register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK1_OV, 0, TPS6594_BIT_BUCKX_OV_INT(0)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK1_UV, 0, TPS6594_BIT_BUCKX_UV_INT(0)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK1_SC, 0, TPS6594_BIT_BUCKX_SC_INT(0)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK1_ILIM, 0, TPS6594_BIT_BUCKX_ILIM_INT(0)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK2_OV, 0, TPS6594_BIT_BUCKX_OV_INT(1)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK2_UV, 0, TPS6594_BIT_BUCKX_UV_INT(1)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK2_SC, 0, TPS6594_BIT_BUCKX_SC_INT(1)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK2_ILIM, 0, TPS6594_BIT_BUCKX_ILIM_INT(1)),
+
+       /* INT_BUCK3_4 register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK3_OV, 1, TPS6594_BIT_BUCKX_OV_INT(2)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK3_UV, 1, TPS6594_BIT_BUCKX_UV_INT(2)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK3_SC, 1, TPS6594_BIT_BUCKX_SC_INT(2)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK3_ILIM, 1, TPS6594_BIT_BUCKX_ILIM_INT(2)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK4_OV, 1, TPS6594_BIT_BUCKX_OV_INT(3)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK4_UV, 1, TPS6594_BIT_BUCKX_UV_INT(3)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK4_SC, 1, TPS6594_BIT_BUCKX_SC_INT(3)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK4_ILIM, 1, TPS6594_BIT_BUCKX_ILIM_INT(3)),
+
+       /* INT_BUCK5 register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK5_OV, 2, TPS6594_BIT_BUCKX_OV_INT(4)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK5_UV, 2, TPS6594_BIT_BUCKX_UV_INT(4)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK5_SC, 2, TPS6594_BIT_BUCKX_SC_INT(4)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BUCK5_ILIM, 2, TPS6594_BIT_BUCKX_ILIM_INT(4)),
+
+       /* INT_LDO1_2 register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO1_OV, 3, TPS6594_BIT_LDOX_OV_INT(0)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO1_UV, 3, TPS6594_BIT_LDOX_UV_INT(0)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO1_SC, 3, TPS6594_BIT_LDOX_SC_INT(0)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO1_ILIM, 3, TPS6594_BIT_LDOX_ILIM_INT(0)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO2_OV, 3, TPS6594_BIT_LDOX_OV_INT(1)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO2_UV, 3, TPS6594_BIT_LDOX_UV_INT(1)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO2_SC, 3, TPS6594_BIT_LDOX_SC_INT(1)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO2_ILIM, 3, TPS6594_BIT_LDOX_ILIM_INT(1)),
+
+       /* INT_LDO3_4 register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO3_OV, 4, TPS6594_BIT_LDOX_OV_INT(2)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO3_UV, 4, TPS6594_BIT_LDOX_UV_INT(2)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO3_SC, 4, TPS6594_BIT_LDOX_SC_INT(2)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO3_ILIM, 4, TPS6594_BIT_LDOX_ILIM_INT(2)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO4_OV, 4, TPS6594_BIT_LDOX_OV_INT(3)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO4_UV, 4, TPS6594_BIT_LDOX_UV_INT(3)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO4_SC, 4, TPS6594_BIT_LDOX_SC_INT(3)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_LDO4_ILIM, 4, TPS6594_BIT_LDOX_ILIM_INT(3)),
+
+       /* INT_VMON register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_VCCA_OV, 5, TPS6594_BIT_VCCA_OV_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_VCCA_UV, 5, TPS6594_BIT_VCCA_UV_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_VMON1_OV, 5, TPS6594_BIT_VMON1_OV_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_VMON1_UV, 5, TPS6594_BIT_VMON1_UV_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_VMON1_RV, 5, TPS6594_BIT_VMON1_RV_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_VMON2_OV, 5, TPS6594_BIT_VMON2_OV_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_VMON2_UV, 5, TPS6594_BIT_VMON2_UV_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_VMON2_RV, 5, TPS6594_BIT_VMON2_RV_INT),
+
+       /* INT_GPIO register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO9, 6, TPS6594_BIT_GPIO9_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO10, 6, TPS6594_BIT_GPIO10_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO11, 6, TPS6594_BIT_GPIO11_INT),
+
+       /* INT_GPIO1_8 register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO1, 7, TPS6594_BIT_GPIOX_INT(0)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO2, 7, TPS6594_BIT_GPIOX_INT(1)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO3, 7, TPS6594_BIT_GPIOX_INT(2)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO4, 7, TPS6594_BIT_GPIOX_INT(3)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO5, 7, TPS6594_BIT_GPIOX_INT(4)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO6, 7, TPS6594_BIT_GPIOX_INT(5)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO7, 7, TPS6594_BIT_GPIOX_INT(6)),
+       REGMAP_IRQ_REG(TPS6594_IRQ_GPIO8, 7, TPS6594_BIT_GPIOX_INT(7)),
+
+       /* INT_STARTUP register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_NPWRON_START, 8, TPS6594_BIT_NPWRON_START_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_ENABLE, 8, TPS6594_BIT_ENABLE_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_FSD, 8, TPS6594_BIT_FSD_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_SOFT_REBOOT, 8, TPS6594_BIT_SOFT_REBOOT_INT),
+
+       /* INT_MISC register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_BIST_PASS, 9, TPS6594_BIT_BIST_PASS_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_EXT_CLK, 9, TPS6594_BIT_EXT_CLK_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_TWARN, 9, TPS6594_BIT_TWARN_INT),
+
+       /* INT_MODERATE_ERR register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_TSD_ORD, 10, TPS6594_BIT_TSD_ORD_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_BIST_FAIL, 10, TPS6594_BIT_BIST_FAIL_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_REG_CRC_ERR, 10, TPS6594_BIT_REG_CRC_ERR_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_RECOV_CNT, 10, TPS6594_BIT_RECOV_CNT_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_SPMI_ERR, 10, TPS6594_BIT_SPMI_ERR_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_NPWRON_LONG, 10, TPS6594_BIT_NPWRON_LONG_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_NINT_READBACK, 10, TPS6594_BIT_NINT_READBACK_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_NRSTOUT_READBACK, 10, TPS6594_BIT_NRSTOUT_READBACK_INT),
+
+       /* INT_SEVERE_ERR register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_TSD_IMM, 11, TPS6594_BIT_TSD_IMM_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_VCCA_OVP, 11, TPS6594_BIT_VCCA_OVP_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_PFSM_ERR, 11, TPS6594_BIT_PFSM_ERR_INT),
+
+       /* INT_FSM_ERR register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_IMM_SHUTDOWN, 12, TPS6594_BIT_IMM_SHUTDOWN_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_ORD_SHUTDOWN, 12, TPS6594_BIT_ORD_SHUTDOWN_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_MCU_PWR_ERR, 12, TPS6594_BIT_MCU_PWR_ERR_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_SOC_PWR_ERR, 12, TPS6594_BIT_SOC_PWR_ERR_INT),
+
+       /* INT_COMM_ERR register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_COMM_FRM_ERR, 13, TPS6594_BIT_COMM_FRM_ERR_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_COMM_CRC_ERR, 13, TPS6594_BIT_COMM_CRC_ERR_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_COMM_ADR_ERR, 13, TPS6594_BIT_COMM_ADR_ERR_INT),
+
+       /* INT_READBACK_ERR register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_EN_DRV_READBACK, 14, TPS6594_BIT_EN_DRV_READBACK_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_NRSTOUT_SOC_READBACK, 14, TPS6594_BIT_NRSTOUT_SOC_READBACK_INT),
+
+       /* INT_ESM register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_ESM_SOC_PIN, 15, TPS6594_BIT_ESM_SOC_PIN_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_ESM_SOC_FAIL, 15, TPS6594_BIT_ESM_SOC_FAIL_INT),
+       REGMAP_IRQ_REG(TPS6594_IRQ_ESM_SOC_RST, 15, TPS6594_BIT_ESM_SOC_RST_INT),
+
+       /* RTC_STATUS register */
+       REGMAP_IRQ_REG(TPS6594_IRQ_TIMER, 16, TPS6594_BIT_TIMER),
+       REGMAP_IRQ_REG(TPS6594_IRQ_ALARM, 16, TPS6594_BIT_ALARM),
+       REGMAP_IRQ_REG(TPS6594_IRQ_POWER_UP, 16, TPS6594_BIT_POWER_UP),
+};
+
+static const unsigned int tps6594_irq_reg[] = {
+       TPS6594_REG_INT_BUCK1_2,
+       TPS6594_REG_INT_BUCK3_4,
+       TPS6594_REG_INT_BUCK5,
+       TPS6594_REG_INT_LDO1_2,
+       TPS6594_REG_INT_LDO3_4,
+       TPS6594_REG_INT_VMON,
+       TPS6594_REG_INT_GPIO,
+       TPS6594_REG_INT_GPIO1_8,
+       TPS6594_REG_INT_STARTUP,
+       TPS6594_REG_INT_MISC,
+       TPS6594_REG_INT_MODERATE_ERR,
+       TPS6594_REG_INT_SEVERE_ERR,
+       TPS6594_REG_INT_FSM_ERR,
+       TPS6594_REG_INT_COMM_ERR,
+       TPS6594_REG_INT_READBACK_ERR,
+       TPS6594_REG_INT_ESM,
+       TPS6594_REG_RTC_STATUS,
+};
+
+static inline unsigned int tps6594_get_irq_reg(struct regmap_irq_chip_data *data,
+                                              unsigned int base, int index)
+{
+       return tps6594_irq_reg[index];
+};
+
+static int tps6594_handle_post_irq(void *irq_drv_data)
+{
+       struct tps6594 *tps = irq_drv_data;
+       int ret = 0;
+
+       /*
+        * When CRC is enabled, writing to a read-only bit triggers an error,
+        * and COMM_ADR_ERR_INT bit is set. Besides, bits indicating interrupts
+        * (that must be cleared) and read-only bits are sometimes grouped in
+        * the same register.
+        * Since regmap clears interrupts by doing a write per register, clearing
+        * an interrupt bit in a register containing also a read-only bit makes
+        * COMM_ADR_ERR_INT bit set. Clear immediately this bit to avoid raising
+        * a new interrupt.
+        */
+       if (tps->use_crc)
+               ret = regmap_write_bits(tps->regmap, TPS6594_REG_INT_COMM_ERR,
+                                       TPS6594_BIT_COMM_ADR_ERR_INT,
+                                       TPS6594_BIT_COMM_ADR_ERR_INT);
+
+       return ret;
+};
+
+static struct regmap_irq_chip tps6594_irq_chip = {
+       .ack_base = TPS6594_REG_INT_BUCK1_2,
+       .ack_invert = 1,
+       .clear_ack = 1,
+       .init_ack_masked = 1,
+       .num_regs = ARRAY_SIZE(tps6594_irq_reg),
+       .irqs = tps6594_irqs,
+       .num_irqs = ARRAY_SIZE(tps6594_irqs),
+       .get_irq_reg = tps6594_get_irq_reg,
+       .handle_post_irq = tps6594_handle_post_irq,
+};
+
+bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+       return (reg >= TPS6594_REG_INT_TOP && reg <= TPS6594_REG_STAT_READBACK_ERR) ||
+              reg == TPS6594_REG_RTC_STATUS;
+}
+EXPORT_SYMBOL_GPL(tps6594_is_volatile_reg);
+
+static int tps6594_check_crc_mode(struct tps6594 *tps, bool primary_pmic)
+{
+       int ret;
+
+       /*
+        * Check if CRC is enabled.
+        * Once CRC is enabled, it can't be disabled until next power cycle.
+        */
+       tps->use_crc = true;
+       ret = regmap_test_bits(tps->regmap, TPS6594_REG_SERIAL_IF_CONFIG,
+                              TPS6594_BIT_I2C1_SPI_CRC_EN);
+       if (ret == 0) {
+               ret = -EIO;
+       } else if (ret > 0) {
+               dev_info(tps->dev, "CRC feature enabled on %s PMIC",
+                        primary_pmic ? "primary" : "secondary");
+               ret = 0;
+       }
+
+       return ret;
+}
+
+static int tps6594_set_crc_feature(struct tps6594 *tps)
+{
+       int ret;
+
+       ret = tps6594_check_crc_mode(tps, true);
+       if (ret) {
+               /*
+                * If CRC is not already enabled, force PFSM I2C_2 trigger to enable it
+                * on primary PMIC.
+                */
+               tps->use_crc = false;
+               ret = regmap_write_bits(tps->regmap, TPS6594_REG_FSM_I2C_TRIGGERS,
+                                       TPS6594_BIT_TRIGGER_I2C(2), TPS6594_BIT_TRIGGER_I2C(2));
+               if (ret)
+                       return ret;
+
+               /*
+                * Wait for PFSM to process trigger.
+                * The datasheet indicates 2 ms, and clock specification is +/-5%.
+                * 4 ms should provide sufficient margin.
+                */
+               usleep_range(4000, 5000);
+
+               ret = tps6594_check_crc_mode(tps, true);
+       }
+
+       return ret;
+}
+
+static int tps6594_enable_crc(struct tps6594 *tps)
+{
+       struct device *dev = tps->dev;
+       unsigned int is_primary;
+       unsigned long timeout = msecs_to_jiffies(TPS6594_CRC_SYNC_TIMEOUT_MS);
+       int ret;
+
+       /*
+        * CRC mode can be used with I2C or SPI protocols.
+        * If this mode is specified for primary PMIC, it will also be applied to secondary PMICs
+        * through SPMI serial interface.
+        * In this multi-PMIC synchronization scheme, the primary PMIC is the controller device
+        * on the SPMI bus, and the secondary PMICs are the target devices on the SPMI bus.
+        */
+       is_primary = of_property_read_bool(dev->of_node, "ti,primary-pmic");
+       if (is_primary) {
+               /* Enable CRC feature on primary PMIC */
+               ret = tps6594_set_crc_feature(tps);
+               if (ret)
+                       return ret;
+
+               /* Notify secondary PMICs that CRC feature is enabled */
+               complete_all(&tps6594_crc_comp);
+       } else {
+               /* Wait for CRC feature enabling event from primary PMIC */
+               ret = wait_for_completion_interruptible_timeout(&tps6594_crc_comp, timeout);
+               if (ret == 0)
+                       ret = -ETIMEDOUT;
+               else if (ret > 0)
+                       ret = tps6594_check_crc_mode(tps, false);
+       }
+
+       return ret;
+}
+
+int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
+{
+       struct device *dev = tps->dev;
+       int ret;
+
+       if (enable_crc) {
+               ret = tps6594_enable_crc(tps);
+               if (ret)
+                       return dev_err_probe(dev, ret, "Failed to enable CRC\n");
+       }
+
+       /* Keep PMIC in ACTIVE state */
+       ret = regmap_set_bits(tps->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
+                             TPS6594_BIT_NSLEEP1B | TPS6594_BIT_NSLEEP2B);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to set PMIC state\n");
+
+       tps6594_irq_chip.irq_drv_data = tps;
+       tps6594_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL, "%s-%ld-0x%02x",
+                                              dev->driver->name, tps->chip_id, tps->reg);
+
+       ret = devm_regmap_add_irq_chip(dev, tps->regmap, tps->irq, IRQF_SHARED | IRQF_ONESHOT,
+                                      0, &tps6594_irq_chip, &tps->irq_data);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to add regmap IRQ\n");
+
+       ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_common_cells,
+                                  ARRAY_SIZE(tps6594_common_cells), NULL, 0,
+                                  regmap_irq_get_domain(tps->irq_data));
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to add common child devices\n");
+
+       /* No RTC for LP8764 */
+       if (tps->chip_id != LP8764) {
+               ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_rtc_cells,
+                                          ARRAY_SIZE(tps6594_rtc_cells), NULL, 0,
+                                          regmap_irq_get_domain(tps->irq_data));
+               if (ret)
+                       return dev_err_probe(dev, ret, "Failed to add RTC child device\n");
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tps6594_device_init);
+
+MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
+MODULE_DESCRIPTION("TPS6594 Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c
new file mode 100644 (file)
index 0000000..449d5c6
--- /dev/null
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * I2C access driver for TI TPS6594/TPS6593/LP8764 PMICs
+ *
+ * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
+ */
+
+#include <linux/crc8.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/tps6594.h>
+
+static bool enable_crc;
+module_param(enable_crc, bool, 0444);
+MODULE_PARM_DESC(enable_crc, "Enable CRC feature for I2C interface");
+
+DECLARE_CRC8_TABLE(tps6594_i2c_crc_table);
+
+static int tps6594_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+       int ret = i2c_transfer(adap, msgs, num);
+
+       if (ret == num)
+               return 0;
+       else if (ret < 0)
+               return ret;
+       else
+               return -EIO;
+}
+
+static int tps6594_i2c_reg_read_with_crc(struct i2c_client *client, u8 page, u8 reg, u8 *val)
+{
+       struct i2c_msg msgs[2];
+       u8 buf_rx[] = { 0, 0 };
+       /* I2C address = I2C base address + Page index */
+       const u8 addr = client->addr + page;
+       /*
+        * CRC is calculated from every bit included in the protocol
+        * except the ACK bits from the target. Byte stream is:
+        * - B0: (I2C_addr_7bits << 1) | WR_bit, with WR_bit = 0
+        * - B1: reg
+        * - B2: (I2C_addr_7bits << 1) | RD_bit, with RD_bit = 1
+        * - B3: val
+        * - B4: CRC from B0-B1-B2-B3
+        */
+       u8 crc_data[] = { addr << 1, reg, addr << 1 | 1, 0 };
+       int ret;
+
+       /* Write register */
+       msgs[0].addr = addr;
+       msgs[0].flags = 0;
+       msgs[0].len = 1;
+       msgs[0].buf = &reg;
+
+       /* Read data and CRC */
+       msgs[1].addr = msgs[0].addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = 2;
+       msgs[1].buf = buf_rx;
+
+       ret = tps6594_i2c_transfer(client->adapter, msgs, 2);
+       if (ret < 0)
+               return ret;
+
+       crc_data[sizeof(crc_data) - 1] = *val = buf_rx[0];
+       if (buf_rx[1] != crc8(tps6594_i2c_crc_table, crc_data, sizeof(crc_data), CRC8_INIT_VALUE))
+               return -EIO;
+
+       return ret;
+}
+
+static int tps6594_i2c_reg_write_with_crc(struct i2c_client *client, u8 page, u8 reg, u8 val)
+{
+       struct i2c_msg msg;
+       u8 buf[] = { reg, val, 0 };
+       /* I2C address = I2C base address + Page index */
+       const u8 addr = client->addr + page;
+       /*
+        * CRC is calculated from every bit included in the protocol
+        * except the ACK bits from the target. Byte stream is:
+        * - B0: (I2C_addr_7bits << 1) | WR_bit, with WR_bit = 0
+        * - B1: reg
+        * - B2: val
+        * - B3: CRC from B0-B1-B2
+        */
+       const u8 crc_data[] = { addr << 1, reg, val };
+
+       /* Write register, data and CRC */
+       msg.addr = addr;
+       msg.flags = client->flags & I2C_M_TEN;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       buf[msg.len - 1] = crc8(tps6594_i2c_crc_table, crc_data, sizeof(crc_data), CRC8_INIT_VALUE);
+
+       return tps6594_i2c_transfer(client->adapter, &msg, 1);
+}
+
+static int tps6594_i2c_read(void *context, const void *reg_buf, size_t reg_size,
+                           void *val_buf, size_t val_size)
+{
+       struct i2c_client *client = context;
+       struct tps6594 *tps = i2c_get_clientdata(client);
+       struct i2c_msg msgs[2];
+       const u8 *reg_bytes = reg_buf;
+       u8 *val_bytes = val_buf;
+       const u8 page = reg_bytes[1];
+       u8 reg = reg_bytes[0];
+       int ret = 0;
+       int i;
+
+       if (tps->use_crc) {
+               /*
+                * Auto-increment feature does not support CRC protocol.
+                * Converts the bulk read operation into a series of single read operations.
+                */
+               for (i = 0 ; ret == 0 && i < val_size ; i++)
+                       ret = tps6594_i2c_reg_read_with_crc(client, page, reg + i, val_bytes + i);
+
+               return ret;
+       }
+
+       /* Write register: I2C address = I2C base address + Page index */
+       msgs[0].addr = client->addr + page;
+       msgs[0].flags = 0;
+       msgs[0].len = 1;
+       msgs[0].buf = &reg;
+
+       /* Read data */
+       msgs[1].addr = msgs[0].addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = val_size;
+       msgs[1].buf = val_bytes;
+
+       return tps6594_i2c_transfer(client->adapter, msgs, 2);
+}
+
+static int tps6594_i2c_write(void *context, const void *data, size_t count)
+{
+       struct i2c_client *client = context;
+       struct tps6594 *tps = i2c_get_clientdata(client);
+       struct i2c_msg msg;
+       const u8 *bytes = data;
+       u8 *buf;
+       const u8 page = bytes[1];
+       const u8 reg = bytes[0];
+       int ret = 0;
+       int i;
+
+       if (tps->use_crc) {
+               /*
+                * Auto-increment feature does not support CRC protocol.
+                * Converts the bulk write operation into a series of single write operations.
+                */
+               for (i = 0 ; ret == 0 && i < count - 2 ; i++)
+                       ret = tps6594_i2c_reg_write_with_crc(client, page, reg + i, bytes[i + 2]);
+
+               return ret;
+       }
+
+       /* Setup buffer: page byte is not sent */
+       buf = kzalloc(--count, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       buf[0] = reg;
+       for (i = 0 ; i < count - 1 ; i++)
+               buf[i + 1] = bytes[i + 2];
+
+       /* Write register and data: I2C address = I2C base address + Page index */
+       msg.addr = client->addr + page;
+       msg.flags = client->flags & I2C_M_TEN;
+       msg.len = count;
+       msg.buf = buf;
+
+       ret = tps6594_i2c_transfer(client->adapter, &msg, 1);
+
+       kfree(buf);
+       return ret;
+}
+
+static const struct regmap_config tps6594_i2c_regmap_config = {
+       .reg_bits = 16,
+       .val_bits = 8,
+       .max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
+       .volatile_reg = tps6594_is_volatile_reg,
+       .read = tps6594_i2c_read,
+       .write = tps6594_i2c_write,
+};
+
+static const struct of_device_id tps6594_i2c_of_match_table[] = {
+       { .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
+       { .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
+       { .compatible = "ti,lp8764-q1",  .data = (void *)LP8764,  },
+       {}
+};
+MODULE_DEVICE_TABLE(of, tps6594_i2c_of_match_table);
+
+static int tps6594_i2c_probe(struct i2c_client *client)
+{
+       struct device *dev = &client->dev;
+       struct tps6594 *tps;
+       const struct of_device_id *match;
+
+       tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
+       if (!tps)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, tps);
+
+       tps->dev = dev;
+       tps->reg = client->addr;
+       tps->irq = client->irq;
+
+       tps->regmap = devm_regmap_init(dev, NULL, client, &tps6594_i2c_regmap_config);
+       if (IS_ERR(tps->regmap))
+               return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
+
+       match = of_match_device(tps6594_i2c_of_match_table, dev);
+       if (!match)
+               return dev_err_probe(dev, PTR_ERR(match), "Failed to find matching chip ID\n");
+       tps->chip_id = (unsigned long)match->data;
+
+       crc8_populate_msb(tps6594_i2c_crc_table, TPS6594_CRC8_POLYNOMIAL);
+
+       return tps6594_device_init(tps, enable_crc);
+}
+
+static struct i2c_driver tps6594_i2c_driver = {
+       .driver = {
+               .name = "tps6594",
+               .of_match_table = tps6594_i2c_of_match_table,
+       },
+       .probe_new = tps6594_i2c_probe,
+};
+module_i2c_driver(tps6594_i2c_driver);
+
+MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
+MODULE_DESCRIPTION("TPS6594 I2C Interface Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
new file mode 100644 (file)
index 0000000..a938a19
--- /dev/null
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SPI access driver for TI TPS6594/TPS6593/LP8764 PMICs
+ *
+ * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
+ */
+
+#include <linux/crc8.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mfd/tps6594.h>
+
+#define TPS6594_SPI_PAGE_SHIFT 5
+#define TPS6594_SPI_READ_BIT   BIT(4)
+
+static bool enable_crc;
+module_param(enable_crc, bool, 0444);
+MODULE_PARM_DESC(enable_crc, "Enable CRC feature for SPI interface");
+
+DECLARE_CRC8_TABLE(tps6594_spi_crc_table);
+
+static int tps6594_spi_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+       struct spi_device *spi = context;
+       struct tps6594 *tps = spi_get_drvdata(spi);
+       u8 buf[4] = { 0 };
+       size_t count_rx = 1;
+       int ret;
+
+       buf[0] = reg;
+       buf[1] = TPS6594_REG_TO_PAGE(reg) << TPS6594_SPI_PAGE_SHIFT | TPS6594_SPI_READ_BIT;
+
+       if (tps->use_crc)
+               count_rx++;
+
+       ret = spi_write_then_read(spi, buf, 2, buf + 2, count_rx);
+       if (ret < 0)
+               return ret;
+
+       if (tps->use_crc && buf[3] != crc8(tps6594_spi_crc_table, buf, 3, CRC8_INIT_VALUE))
+               return -EIO;
+
+       *val = buf[2];
+
+       return 0;
+}
+
+static int tps6594_spi_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+       struct spi_device *spi = context;
+       struct tps6594 *tps = spi_get_drvdata(spi);
+       u8 buf[4] = { 0 };
+       size_t count = 3;
+
+       buf[0] = reg;
+       buf[1] = TPS6594_REG_TO_PAGE(reg) << TPS6594_SPI_PAGE_SHIFT;
+       buf[2] = val;
+
+       if (tps->use_crc)
+               buf[3] = crc8(tps6594_spi_crc_table, buf, count++, CRC8_INIT_VALUE);
+
+       return spi_write(spi, buf, count);
+}
+
+static const struct regmap_config tps6594_spi_regmap_config = {
+       .reg_bits = 16,
+       .val_bits = 8,
+       .max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
+       .volatile_reg = tps6594_is_volatile_reg,
+       .reg_read = tps6594_spi_reg_read,
+       .reg_write = tps6594_spi_reg_write,
+       .use_single_read = true,
+       .use_single_write = true,
+};
+
+static const struct of_device_id tps6594_spi_of_match_table[] = {
+       { .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
+       { .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
+       { .compatible = "ti,lp8764-q1",  .data = (void *)LP8764,  },
+       {}
+};
+MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);
+
+static int tps6594_spi_probe(struct spi_device *spi)
+{
+       struct device *dev = &spi->dev;
+       struct tps6594 *tps;
+       const struct of_device_id *match;
+
+       tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
+       if (!tps)
+               return -ENOMEM;
+
+       spi_set_drvdata(spi, tps);
+
+       tps->dev = dev;
+       tps->reg = spi->chip_select;
+       tps->irq = spi->irq;
+
+       tps->regmap = devm_regmap_init(dev, NULL, spi, &tps6594_spi_regmap_config);
+       if (IS_ERR(tps->regmap))
+               return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
+
+       match = of_match_device(tps6594_spi_of_match_table, dev);
+       if (!match)
+               return dev_err_probe(dev, PTR_ERR(match), "Failed to find matching chip ID\n");
+       tps->chip_id = (unsigned long)match->data;
+
+       crc8_populate_msb(tps6594_spi_crc_table, TPS6594_CRC8_POLYNOMIAL);
+
+       return tps6594_device_init(tps, enable_crc);
+}
+
+static struct spi_driver tps6594_spi_driver = {
+       .driver = {
+               .name = "tps6594",
+               .of_match_table = tps6594_spi_of_match_table,
+       },
+       .probe = tps6594_spi_probe,
+};
+module_spi_driver(tps6594_spi_driver);
+
+MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
+MODULE_DESCRIPTION("TPS6594 SPI Interface Driver");
+MODULE_LICENSE("GPL");
index 5787c579dcf672c3072f11791b0ad3e172edb73d..77ff9a641aebfe963aecc477413c0f2ed5127c75 100644 (file)
@@ -407,7 +407,7 @@ config PINCTRL_PISTACHIO
 
 config PINCTRL_RK805
        tristate "Pinctrl and GPIO driver for RK805 PMIC"
-       depends on MFD_RK808
+       depends on MFD_RK8XX
        select GPIOLIB
        select PINMUX
        select GENERIC_PINCONF
index 7c1f7408fb9af9e5e418e053767e501717743c4b..2639a9ee82cd0fa150c021cfa089551bafd7a096 100644 (file)
@@ -1,10 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- * Pinctrl driver for Rockchip RK805 PMIC
+ * Pinctrl driver for Rockchip RK805/RK806 PMIC
  *
  * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
  *
  * Author: Joseph Chen <chenjh@rock-chips.com>
+ * Author: Xu Shengfei <xsf@rock-chips.com>
  *
  * Based on the pinctrl-as3722 driver
  */
@@ -44,6 +46,7 @@ struct rk805_pin_group {
 
 /*
  * @reg: gpio setting register;
+ * @fun_reg: functions select register;
  * @fun_mask: functions select mask value, when set is gpio;
  * @dir_mask: input or output mask value, when set is output, otherwise input;
  * @val_mask: gpio set value, when set is level high, otherwise low;
@@ -56,6 +59,7 @@ struct rk805_pin_group {
  */
 struct rk805_pin_config {
        u8 reg;
+       u8 fun_reg;
        u8 fun_msk;
        u8 dir_msk;
        u8 val_msk;
@@ -80,22 +84,50 @@ enum rk805_pinmux_option {
        RK805_PINMUX_GPIO,
 };
 
+enum rk806_pinmux_option {
+       RK806_PINMUX_FUN0 = 0,
+       RK806_PINMUX_FUN1,
+       RK806_PINMUX_FUN2,
+       RK806_PINMUX_FUN3,
+       RK806_PINMUX_FUN4,
+       RK806_PINMUX_FUN5,
+};
+
 enum {
        RK805_GPIO0,
        RK805_GPIO1,
 };
 
+enum {
+       RK806_GPIO_DVS1,
+       RK806_GPIO_DVS2,
+       RK806_GPIO_DVS3
+};
+
 static const char *const rk805_gpio_groups[] = {
        "gpio0",
        "gpio1",
 };
 
+static const char *const rk806_gpio_groups[] = {
+       "gpio_pwrctrl1",
+       "gpio_pwrctrl2",
+       "gpio_pwrctrl3",
+};
+
 /* RK805: 2 output only GPIOs */
 static const struct pinctrl_pin_desc rk805_pins_desc[] = {
        PINCTRL_PIN(RK805_GPIO0, "gpio0"),
        PINCTRL_PIN(RK805_GPIO1, "gpio1"),
 };
 
+/* RK806 */
+static const struct pinctrl_pin_desc rk806_pins_desc[] = {
+       PINCTRL_PIN(RK806_GPIO_DVS1, "gpio_pwrctrl1"),
+       PINCTRL_PIN(RK806_GPIO_DVS2, "gpio_pwrctrl2"),
+       PINCTRL_PIN(RK806_GPIO_DVS3, "gpio_pwrctrl3"),
+};
+
 static const struct rk805_pin_function rk805_pin_functions[] = {
        {
                .name = "gpio",
@@ -105,6 +137,45 @@ static const struct rk805_pin_function rk805_pin_functions[] = {
        },
 };
 
+static const struct rk805_pin_function rk806_pin_functions[] = {
+       {
+               .name = "pin_fun0",
+               .groups = rk806_gpio_groups,
+               .ngroups = ARRAY_SIZE(rk806_gpio_groups),
+               .mux_option = RK806_PINMUX_FUN0,
+       },
+       {
+               .name = "pin_fun1",
+               .groups = rk806_gpio_groups,
+               .ngroups = ARRAY_SIZE(rk806_gpio_groups),
+               .mux_option = RK806_PINMUX_FUN1,
+       },
+       {
+               .name = "pin_fun2",
+               .groups = rk806_gpio_groups,
+               .ngroups = ARRAY_SIZE(rk806_gpio_groups),
+               .mux_option = RK806_PINMUX_FUN2,
+       },
+       {
+               .name = "pin_fun3",
+               .groups = rk806_gpio_groups,
+               .ngroups = ARRAY_SIZE(rk806_gpio_groups),
+               .mux_option = RK806_PINMUX_FUN3,
+       },
+       {
+               .name = "pin_fun4",
+               .groups = rk806_gpio_groups,
+               .ngroups = ARRAY_SIZE(rk806_gpio_groups),
+               .mux_option = RK806_PINMUX_FUN4,
+       },
+       {
+               .name = "pin_fun5",
+               .groups = rk806_gpio_groups,
+               .ngroups = ARRAY_SIZE(rk806_gpio_groups),
+               .mux_option = RK806_PINMUX_FUN5,
+       },
+};
+
 static const struct rk805_pin_group rk805_pin_groups[] = {
        {
                .name = "gpio0",
@@ -118,6 +189,24 @@ static const struct rk805_pin_group rk805_pin_groups[] = {
        },
 };
 
+static const struct rk805_pin_group rk806_pin_groups[] = {
+       {
+               .name = "gpio_pwrctrl1",
+               .pins = { RK806_GPIO_DVS1 },
+               .npins = 1,
+       },
+       {
+               .name = "gpio_pwrctrl2",
+               .pins = { RK806_GPIO_DVS2 },
+               .npins = 1,
+       },
+       {
+               .name = "gpio_pwrctrl3",
+               .pins = { RK806_GPIO_DVS3 },
+               .npins = 1,
+       }
+};
+
 #define RK805_GPIO0_VAL_MSK    BIT(0)
 #define RK805_GPIO1_VAL_MSK    BIT(1)
 
@@ -132,6 +221,40 @@ static const struct rk805_pin_config rk805_gpio_cfgs[] = {
        },
 };
 
+#define RK806_PWRCTRL1_DR      BIT(0)
+#define RK806_PWRCTRL2_DR      BIT(1)
+#define RK806_PWRCTRL3_DR      BIT(2)
+#define RK806_PWRCTRL1_DATA    BIT(4)
+#define RK806_PWRCTRL2_DATA    BIT(5)
+#define RK806_PWRCTRL3_DATA    BIT(6)
+#define RK806_PWRCTRL1_FUN     GENMASK(2, 0)
+#define RK806_PWRCTRL2_FUN     GENMASK(6, 4)
+#define RK806_PWRCTRL3_FUN     GENMASK(2, 0)
+
+static struct rk805_pin_config rk806_gpio_cfgs[] = {
+       {
+               .fun_reg = RK806_SLEEP_CONFIG0,
+               .fun_msk = RK806_PWRCTRL1_FUN,
+               .reg = RK806_SLEEP_GPIO,
+               .val_msk = RK806_PWRCTRL1_DATA,
+               .dir_msk = RK806_PWRCTRL1_DR,
+       },
+       {
+               .fun_reg = RK806_SLEEP_CONFIG0,
+               .fun_msk = RK806_PWRCTRL2_FUN,
+               .reg = RK806_SLEEP_GPIO,
+               .val_msk = RK806_PWRCTRL2_DATA,
+               .dir_msk = RK806_PWRCTRL2_DR,
+       },
+       {
+               .fun_reg = RK806_SLEEP_CONFIG1,
+               .fun_msk = RK806_PWRCTRL3_FUN,
+               .reg = RK806_SLEEP_GPIO,
+               .val_msk = RK806_PWRCTRL3_DATA,
+               .dir_msk = RK806_PWRCTRL3_DR,
+       }
+};
+
 /* generic gpio chip */
 static int rk805_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
@@ -289,19 +412,13 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
        if (!pci->pin_cfg[offset].fun_msk)
                return 0;
 
-       if (mux == RK805_PINMUX_GPIO) {
-               ret = regmap_update_bits(pci->rk808->regmap,
-                                        pci->pin_cfg[offset].reg,
-                                        pci->pin_cfg[offset].fun_msk,
-                                        pci->pin_cfg[offset].fun_msk);
-               if (ret) {
-                       dev_err(pci->dev, "set gpio%d GPIO failed\n", offset);
-                       return ret;
-               }
-       } else {
-               dev_err(pci->dev, "Couldn't find function mux %d\n", mux);
-               return -EINVAL;
-       }
+       mux <<= ffs(pci->pin_cfg[offset].fun_msk) - 1;
+       ret = regmap_update_bits(pci->rk808->regmap,
+                                pci->pin_cfg[offset].fun_reg,
+                                pci->pin_cfg[offset].fun_msk, mux);
+
+       if (ret)
+               dev_err(pci->dev, "set gpio%d func%d failed\n", offset, mux);
 
        return 0;
 }
@@ -317,6 +434,22 @@ static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
        return _rk805_pinctrl_set_mux(pctldev, offset, mux);
 }
 
+static int rk805_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
+                                            struct pinctrl_gpio_range *range,
+                                            unsigned int offset)
+{
+       struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+
+       switch (pci->rk808->variant) {
+       case RK805_ID:
+               return _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
+       case RK806_ID:
+               return _rk805_pinctrl_set_mux(pctldev, offset, RK806_PINMUX_FUN5);
+       }
+
+       return -ENOTSUPP;
+}
+
 static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
                                        struct pinctrl_gpio_range *range,
                                        unsigned int offset, bool input)
@@ -324,13 +457,6 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
        struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
        int ret;
 
-       /* switch to gpio function */
-       ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
-       if (ret) {
-               dev_err(pci->dev, "set gpio%d mux failed\n", offset);
-               return ret;
-       }
-
        /* set direction */
        if (!pci->pin_cfg[offset].dir_msk)
                return 0;
@@ -352,6 +478,7 @@ static const struct pinmux_ops rk805_pinmux_ops = {
        .get_function_name      = rk805_pinctrl_get_func_name,
        .get_function_groups    = rk805_pinctrl_get_func_groups,
        .set_mux                = rk805_pinctrl_set_mux,
+       .gpio_request_enable    = rk805_pinctrl_gpio_request_enable,
        .gpio_set_direction     = rk805_pmx_gpio_set_direction,
 };
 
@@ -364,6 +491,7 @@ static int rk805_pinconf_get(struct pinctrl_dev *pctldev,
 
        switch (param) {
        case PIN_CONFIG_OUTPUT:
+       case PIN_CONFIG_INPUT_ENABLE:
                arg = rk805_gpio_get(&pci->gpio_chip, pin);
                break;
        default:
@@ -393,6 +521,12 @@ static int rk805_pinconf_set(struct pinctrl_dev *pctldev,
                        rk805_gpio_set(&pci->gpio_chip, pin, arg);
                        rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false);
                        break;
+               case PIN_CONFIG_INPUT_ENABLE:
+                       if (pci->rk808->variant != RK805_ID && arg) {
+                               rk805_pmx_gpio_set_direction(pctldev, NULL, pin, true);
+                               break;
+                       }
+                       fallthrough;
                default:
                        dev_err(pci->dev, "Properties not supported\n");
                        return -ENOTSUPP;
@@ -448,6 +582,18 @@ static int rk805_pinctrl_probe(struct platform_device *pdev)
                pci->pin_cfg = rk805_gpio_cfgs;
                pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs);
                break;
+       case RK806_ID:
+               pci->pins = rk806_pins_desc;
+               pci->num_pins = ARRAY_SIZE(rk806_pins_desc);
+               pci->functions = rk806_pin_functions;
+               pci->num_functions = ARRAY_SIZE(rk806_pin_functions);
+               pci->groups = rk806_pin_groups;
+               pci->num_pin_groups = ARRAY_SIZE(rk806_pin_groups);
+               pci->pinctrl_desc.pins = rk806_pins_desc;
+               pci->pinctrl_desc.npins = ARRAY_SIZE(rk806_pins_desc);
+               pci->pin_cfg = rk806_gpio_cfgs;
+               pci->gpio_chip.ngpio = ARRAY_SIZE(rk806_gpio_cfgs);
+               break;
        default:
                dev_err(&pdev->dev, "unsupported RK805 ID %lu\n",
                        pci->rk808->variant);
@@ -488,5 +634,6 @@ static struct platform_driver rk805_pinctrl_driver = {
 module_platform_driver(rk805_pinctrl_driver);
 
 MODULE_DESCRIPTION("RK805 pin control and GPIO driver");
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
 MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
 MODULE_LICENSE("GPL v2");
index c78be9f322e6c6002fb06f87db1e0dd1c15b99c4..4a5e8e1d12374cb938ee6e494e1206225e2d6e1b 100644 (file)
@@ -706,7 +706,7 @@ config CHARGER_BQ256XX
 
 config CHARGER_RK817
        tristate "Rockchip RK817 PMIC Battery Charger"
-       depends on MFD_RK808
+       depends on MFD_RK8XX
        help
          Say Y to include support for Rockchip RK817 Battery Charger.
 
index 74275b681f460b7cc797dc1c85422bace914e9ca..e6598e74ec94e4a7b25edbed233ccc2090f7bed3 100644 (file)
@@ -104,7 +104,7 @@ static struct i2c_driver pg86x_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(pg86x_dt_ids),
        },
-       .probe_new = pg86x_i2c_probe,
+       .probe = pg86x_i2c_probe,
        .id_table = pg86x_i2c_id,
 };
 
index e5f3613c15fa5b06a9903583c948962db3a9afda..2c2405024acec32381323fc8f7f7074092f58bdf 100644 (file)
@@ -1033,6 +1033,13 @@ config REGULATOR_QCOM_USB_VBUS
          Say M here if you want to include support for enabling the VBUS output
          as a module. The module will be named "qcom_usb_vbus_regulator".
 
+config REGULATOR_RAA215300
+       tristate "Renesas RAA215300 driver"
+       select REGMAP_I2C
+       depends on I2C
+       help
+         Support for the Renesas RAA215300 PMIC.
+
 config REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY
        tristate "Raspberry Pi 7-inch touchscreen panel ATTINY regulator"
        depends on BACKLIGHT_CLASS_DEVICE
@@ -1056,7 +1063,7 @@ config REGULATOR_RC5T583
 
 config REGULATOR_RK808
        tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
-       depends on MFD_RK808
+       depends on MFD_RK8XX
        help
          Select this option to enable the power regulator of ROCKCHIP
          PMIC RK805,RK809&RK817,RK808 and RK818.
@@ -1397,6 +1404,17 @@ config REGULATOR_TPS6286X
          high-frequency synchronous step-down converters with an I2C
          interface.
 
+config REGULATOR_TPS6287X
+       tristate "TI TPS6287x Power Regulator"
+       depends on I2C && OF
+       select REGMAP_I2C
+       help
+         This driver supports TPS6287x voltage regulator chips. These are
+         pin-to-pin high-frequency synchronous step-down dc-dc converters
+         with an I2C interface.
+
+         If built as a module it will be called tps6287x-regulator.
+
 config REGULATOR_TPS65023
        tristate "TI TPS65023 Power regulators"
        depends on I2C
@@ -1463,6 +1481,19 @@ config REGULATOR_TPS65219
          voltage regulators. It supports software based voltage control
          for different voltage domains.
 
+config REGULATOR_TPS6594
+       tristate "TI TPS6594 Power regulators"
+       depends on MFD_TPS6594 && OF
+       default MFD_TPS6594
+       help
+         This driver supports TPS6594 voltage regulator chips.
+         TPS6594 series of PMICs have 5 BUCKs and 4 LDOs
+         voltage regulators.
+         BUCKs 1,2,3,4 can be used in single phase or multiphase mode.
+         Part number defines which single or multiphase mode is i used.
+         It supports software based voltage control
+         for different voltage domains.
+
 config REGULATOR_TPS6524X
        tristate "TI TPS6524X Power regulators"
        depends on SPI
index 58dfe0147cd431cd824f27624a6ac683cfb2aed2..ebfa75379c20d3b910cd76a811d7e4385ab97dde 100644 (file)
@@ -124,6 +124,7 @@ obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o
 obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o
 obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
 obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
+obj-$(CONFIG_REGULATOR_RAA215300) += raa215300.o
 obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY)  += rpi-panel-attiny-regulator.o
 obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
@@ -163,6 +164,7 @@ obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6286X) += tps6286x-regulator.o
+obj-$(CONFIG_REGULATOR_TPS6287X) += tps6287x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65086) += tps65086-regulator.o
@@ -174,6 +176,7 @@ obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
+obj-$(CONFIG_REGULATOR_TPS6594) += tps6594-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o
 obj-$(CONFIG_REGULATOR_TPS68470) += tps68470-regulator.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
index 5c409ff4aa991bb65b494f293297b92f6ca4f2b3..a504b01dd99c8ffe1735bcf8087c54e85cfd7d03 100644 (file)
@@ -791,7 +791,7 @@ static struct i2c_driver act8865_pmic_driver = {
                .name   = "act8865",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
-       .probe_new      = act8865_pmic_probe,
+       .probe          = act8865_pmic_probe,
        .id_table       = act8865_ids,
 };
 
index c228cf6956d10aaffd0ded4cddaa659ffa347b83..40f7dba42b5ad7c95a3e2643b3ad6e076cf2cbb4 100644 (file)
@@ -254,7 +254,7 @@ static int ad5398_probe(struct i2c_client *client)
 }
 
 static struct i2c_driver ad5398_driver = {
-       .probe_new = ad5398_probe,
+       .probe = ad5398_probe,
        .driver         = {
                .name   = "ad5398",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
index 943172b197226248c9a687038b7874e07729a287..810f90f3e2a1b3a43e799ed225a491a9948be7e7 100644 (file)
 #define AXP22X_PWR_OUT_DLDO4_MASK      BIT_MASK(6)
 #define AXP22X_PWR_OUT_ALDO3_MASK      BIT_MASK(7)
 
+#define AXP313A_DCDC1_NUM_VOLTAGES     107
+#define AXP313A_DCDC23_NUM_VOLTAGES    88
+#define AXP313A_DCDC_V_OUT_MASK                GENMASK(6, 0)
+#define AXP313A_LDO_V_OUT_MASK         GENMASK(4, 0)
+
 #define AXP803_PWR_OUT_DCDC1_MASK      BIT_MASK(0)
 #define AXP803_PWR_OUT_DCDC2_MASK      BIT_MASK(1)
 #define AXP803_PWR_OUT_DCDC3_MASK      BIT_MASK(2)
 
 #define AXP813_PWR_OUT_DCDC7_MASK      BIT_MASK(6)
 
+#define AXP15060_DCDC1_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_DCDC2_V_CTRL_MASK             GENMASK(6, 0)
+#define AXP15060_DCDC3_V_CTRL_MASK             GENMASK(6, 0)
+#define AXP15060_DCDC4_V_CTRL_MASK             GENMASK(6, 0)
+#define AXP15060_DCDC5_V_CTRL_MASK             GENMASK(6, 0)
+#define AXP15060_DCDC6_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_ALDO1_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_ALDO2_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_ALDO3_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_ALDO4_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_ALDO5_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_BLDO1_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_BLDO2_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_BLDO3_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_BLDO4_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_BLDO5_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_CLDO1_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_CLDO2_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_CLDO3_V_CTRL_MASK             GENMASK(4, 0)
+#define AXP15060_CLDO4_V_CTRL_MASK             GENMASK(5, 0)
+#define AXP15060_CPUSLDO_V_CTRL_MASK           GENMASK(3, 0)
+
+#define AXP15060_PWR_OUT_DCDC1_MASK    BIT_MASK(0)
+#define AXP15060_PWR_OUT_DCDC2_MASK    BIT_MASK(1)
+#define AXP15060_PWR_OUT_DCDC3_MASK    BIT_MASK(2)
+#define AXP15060_PWR_OUT_DCDC4_MASK    BIT_MASK(3)
+#define AXP15060_PWR_OUT_DCDC5_MASK    BIT_MASK(4)
+#define AXP15060_PWR_OUT_DCDC6_MASK    BIT_MASK(5)
+#define AXP15060_PWR_OUT_ALDO1_MASK    BIT_MASK(0)
+#define AXP15060_PWR_OUT_ALDO2_MASK    BIT_MASK(1)
+#define AXP15060_PWR_OUT_ALDO3_MASK    BIT_MASK(2)
+#define AXP15060_PWR_OUT_ALDO4_MASK    BIT_MASK(3)
+#define AXP15060_PWR_OUT_ALDO5_MASK    BIT_MASK(4)
+#define AXP15060_PWR_OUT_BLDO1_MASK    BIT_MASK(5)
+#define AXP15060_PWR_OUT_BLDO2_MASK    BIT_MASK(6)
+#define AXP15060_PWR_OUT_BLDO3_MASK    BIT_MASK(7)
+#define AXP15060_PWR_OUT_BLDO4_MASK    BIT_MASK(0)
+#define AXP15060_PWR_OUT_BLDO5_MASK    BIT_MASK(1)
+#define AXP15060_PWR_OUT_CLDO1_MASK    BIT_MASK(2)
+#define AXP15060_PWR_OUT_CLDO2_MASK    BIT_MASK(3)
+#define AXP15060_PWR_OUT_CLDO3_MASK    BIT_MASK(4)
+#define AXP15060_PWR_OUT_CLDO4_MASK    BIT_MASK(5)
+#define AXP15060_PWR_OUT_CPUSLDO_MASK  BIT_MASK(6)
+#define AXP15060_PWR_OUT_SW_MASK               BIT_MASK(7)
+
+#define AXP15060_DCDC23_POLYPHASE_DUAL_MASK            BIT_MASK(6)
+#define AXP15060_DCDC46_POLYPHASE_DUAL_MASK            BIT_MASK(7)
+
+#define AXP15060_DCDC234_500mV_START   0x00
+#define AXP15060_DCDC234_500mV_STEPS   70
+#define AXP15060_DCDC234_500mV_END             \
+       (AXP15060_DCDC234_500mV_START + AXP15060_DCDC234_500mV_STEPS)
+#define AXP15060_DCDC234_1220mV_START  0x47
+#define AXP15060_DCDC234_1220mV_STEPS  16
+#define AXP15060_DCDC234_1220mV_END            \
+       (AXP15060_DCDC234_1220mV_START + AXP15060_DCDC234_1220mV_STEPS)
+#define AXP15060_DCDC234_NUM_VOLTAGES  88
+
+#define AXP15060_DCDC5_800mV_START     0x00
+#define AXP15060_DCDC5_800mV_STEPS     32
+#define AXP15060_DCDC5_800mV_END               \
+       (AXP15060_DCDC5_800mV_START + AXP15060_DCDC5_800mV_STEPS)
+#define AXP15060_DCDC5_1140mV_START    0x21
+#define AXP15060_DCDC5_1140mV_STEPS    35
+#define AXP15060_DCDC5_1140mV_END              \
+       (AXP15060_DCDC5_1140mV_START + AXP15060_DCDC5_1140mV_STEPS)
+#define AXP15060_DCDC5_NUM_VOLTAGES    69
+
 #define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg,   \
                    _vmask, _ereg, _emask, _enable_val, _disable_val)           \
        [_family##_##_id] = {                                                   \
@@ -638,6 +711,48 @@ static const struct regulator_desc axp22x_drivevbus_regulator = {
        .ops            = &axp20x_ops_sw,
 };
 
+static const struct linear_range axp313a_dcdc1_ranges[] = {
+       REGULATOR_LINEAR_RANGE(500000,   0,  70,  10000),
+       REGULATOR_LINEAR_RANGE(1220000, 71,  87,  20000),
+       REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000),
+};
+
+static const struct linear_range axp313a_dcdc2_ranges[] = {
+       REGULATOR_LINEAR_RANGE(500000,   0, 70, 10000),
+       REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
+};
+
+/*
+ * This is deviating from the datasheet. The values here are taken from the
+ * BSP driver and have been confirmed by measurements.
+ */
+static const struct linear_range axp313a_dcdc3_ranges[] = {
+       REGULATOR_LINEAR_RANGE(500000,   0,  70, 10000),
+       REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000),
+};
+
+static const struct regulator_desc axp313a_regulators[] = {
+       AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1",
+                       axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES,
+                       AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
+                       AXP313A_OUTPUT_CONTROL, BIT(0)),
+       AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2",
+                       axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
+                       AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
+                       AXP313A_OUTPUT_CONTROL, BIT(1)),
+       AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3",
+                       axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
+                       AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
+                       AXP313A_OUTPUT_CONTROL, BIT(2)),
+       AXP_DESC(AXP313A, ALDO1, "aldo1", "vin1", 500, 3500, 100,
+                AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
+                AXP313A_OUTPUT_CONTROL, BIT(3)),
+       AXP_DESC(AXP313A, DLDO1, "dldo1", "vin1", 500, 3500, 100,
+                AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
+                AXP313A_OUTPUT_CONTROL, BIT(4)),
+       AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800),
+};
+
 /* DCDC ranges shared with AXP813 */
 static const struct linear_range axp803_dcdc234_ranges[] = {
        REGULATOR_LINEAR_RANGE(500000,
@@ -1001,6 +1116,104 @@ static const struct regulator_desc axp813_regulators[] = {
                    AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK),
 };
 
+static const struct linear_range axp15060_dcdc234_ranges[] = {
+       REGULATOR_LINEAR_RANGE(500000,
+                              AXP15060_DCDC234_500mV_START,
+                              AXP15060_DCDC234_500mV_END,
+                              10000),
+       REGULATOR_LINEAR_RANGE(1220000,
+                              AXP15060_DCDC234_1220mV_START,
+                              AXP15060_DCDC234_1220mV_END,
+                              20000),
+};
+
+static const struct linear_range axp15060_dcdc5_ranges[] = {
+       REGULATOR_LINEAR_RANGE(800000,
+                              AXP15060_DCDC5_800mV_START,
+                              AXP15060_DCDC5_800mV_END,
+                              10000),
+       REGULATOR_LINEAR_RANGE(1140000,
+                              AXP15060_DCDC5_1140mV_START,
+                              AXP15060_DCDC5_1140mV_END,
+                              20000),
+};
+
+static const struct regulator_desc axp15060_regulators[] = {
+       AXP_DESC(AXP15060, DCDC1, "dcdc1", "vin1", 1500, 3400, 100,
+                AXP15060_DCDC1_V_CTRL, AXP15060_DCDC1_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC1_MASK),
+       AXP_DESC_RANGES(AXP15060, DCDC2, "dcdc2", "vin2",
+                       axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES,
+                       AXP15060_DCDC2_V_CTRL, AXP15060_DCDC2_V_CTRL_MASK,
+                       AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC2_MASK),
+       AXP_DESC_RANGES(AXP15060, DCDC3, "dcdc3", "vin3",
+                       axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES,
+                       AXP15060_DCDC3_V_CTRL, AXP15060_DCDC3_V_CTRL_MASK,
+                       AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC3_MASK),
+       AXP_DESC_RANGES(AXP15060, DCDC4, "dcdc4", "vin4",
+                       axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES,
+                       AXP15060_DCDC4_V_CTRL, AXP15060_DCDC4_V_CTRL_MASK,
+                       AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC4_MASK),
+       AXP_DESC_RANGES(AXP15060, DCDC5, "dcdc5", "vin5",
+                       axp15060_dcdc5_ranges, AXP15060_DCDC5_NUM_VOLTAGES,
+                       AXP15060_DCDC5_V_CTRL, AXP15060_DCDC5_V_CTRL_MASK,
+                       AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC5_MASK),
+       AXP_DESC(AXP15060, DCDC6, "dcdc6", "vin6", 500, 3400, 100,
+                AXP15060_DCDC6_V_CTRL, AXP15060_DCDC6_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC6_MASK),
+       AXP_DESC(AXP15060, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
+                AXP15060_ALDO1_V_CTRL, AXP15060_ALDO1_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO1_MASK),
+       AXP_DESC(AXP15060, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
+                AXP15060_ALDO2_V_CTRL, AXP15060_ALDO2_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO2_MASK),
+       AXP_DESC(AXP15060, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
+                AXP15060_ALDO3_V_CTRL, AXP15060_ALDO3_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO3_MASK),
+       AXP_DESC(AXP15060, ALDO4, "aldo4", "aldoin", 700, 3300, 100,
+                AXP15060_ALDO4_V_CTRL, AXP15060_ALDO4_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO4_MASK),
+       AXP_DESC(AXP15060, ALDO5, "aldo5", "aldoin", 700, 3300, 100,
+                AXP15060_ALDO5_V_CTRL, AXP15060_ALDO5_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO5_MASK),
+       AXP_DESC(AXP15060, BLDO1, "bldo1", "bldoin", 700, 3300, 100,
+                AXP15060_BLDO1_V_CTRL, AXP15060_BLDO1_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO1_MASK),
+       AXP_DESC(AXP15060, BLDO2, "bldo2", "bldoin", 700, 3300, 100,
+                AXP15060_BLDO2_V_CTRL, AXP15060_BLDO2_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO2_MASK),
+       AXP_DESC(AXP15060, BLDO3, "bldo3", "bldoin", 700, 3300, 100,
+                AXP15060_BLDO3_V_CTRL, AXP15060_BLDO3_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO3_MASK),
+       AXP_DESC(AXP15060, BLDO4, "bldo4", "bldoin", 700, 3300, 100,
+                AXP15060_BLDO4_V_CTRL, AXP15060_BLDO4_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_BLDO4_MASK),
+       AXP_DESC(AXP15060, BLDO5, "bldo5", "bldoin", 700, 3300, 100,
+                AXP15060_BLDO5_V_CTRL, AXP15060_BLDO5_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_BLDO5_MASK),
+       AXP_DESC(AXP15060, CLDO1, "cldo1", "cldoin", 700, 3300, 100,
+                AXP15060_CLDO1_V_CTRL, AXP15060_CLDO1_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO1_MASK),
+       AXP_DESC(AXP15060, CLDO2, "cldo2", "cldoin", 700, 3300, 100,
+                AXP15060_CLDO2_V_CTRL, AXP15060_CLDO2_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO2_MASK),
+       AXP_DESC(AXP15060, CLDO3, "cldo3", "cldoin", 700, 3300, 100,
+                AXP15060_CLDO3_V_CTRL, AXP15060_CLDO3_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO3_MASK),
+       AXP_DESC(AXP15060, CLDO4, "cldo4", "cldoin", 700, 4200, 100,
+                AXP15060_CLDO4_V_CTRL, AXP15060_CLDO4_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO4_MASK),
+       /* Supply comes from DCDC5 */
+       AXP_DESC(AXP15060, CPUSLDO, "cpusldo", NULL, 700, 1400, 50,
+                AXP15060_CPUSLDO_V_CTRL, AXP15060_CPUSLDO_V_CTRL_MASK,
+                AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CPUSLDO_MASK),
+       /* Supply comes from DCDC1 */
+       AXP_DESC_SW(AXP15060, SW, "sw", NULL,
+                   AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_SW_MASK),
+       /* Supply comes from ALDO1 */
+       AXP_DESC_FIXED(AXP15060, RTC_LDO, "rtc-ldo", NULL, 1800),
+};
+
 static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
 {
        struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
@@ -1040,6 +1253,16 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
                def = 3000;
                step = 150;
                break;
+       case AXP313A_ID:
+       case AXP15060_ID:
+               /* The DCDC PWM frequency seems to be fixed to 3 MHz. */
+               if (dcdcfreq != 0) {
+                       dev_err(&pdev->dev,
+                               "DCDC frequency on this PMIC is fixed to 3 MHz.\n");
+                       return -EINVAL;
+               }
+
+               return 0;
        default:
                dev_err(&pdev->dev,
                        "Setting DCDC frequency for unsupported AXP variant\n");
@@ -1145,6 +1368,15 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
                workmode <<= id - AXP813_DCDC1;
                break;
 
+       case AXP15060_ID:
+               reg = AXP15060_DCDC_MODE_CTRL2;
+               if (id < AXP15060_DCDC1 || id > AXP15060_DCDC6)
+                       return -EINVAL;
+
+               mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP15060_DCDC1);
+               workmode <<= id - AXP15060_DCDC1;
+               break;
+
        default:
                /* should not happen */
                WARN_ON(1);
@@ -1164,7 +1396,7 @@ static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
 
        /*
         * Currently in our supported AXP variants, only AXP803, AXP806,
-        * and AXP813 have polyphase regulators.
+        * AXP813 and AXP15060 have polyphase regulators.
         */
        switch (axp20x->variant) {
        case AXP803_ID:
@@ -1196,6 +1428,17 @@ static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
                }
                break;
 
+       case AXP15060_ID:
+               regmap_read(axp20x->regmap, AXP15060_DCDC_MODE_CTRL1, &reg);
+
+               switch (id) {
+               case AXP15060_DCDC3:
+                       return !!(reg & AXP15060_DCDC23_POLYPHASE_DUAL_MASK);
+               case AXP15060_DCDC6:
+                       return !!(reg & AXP15060_DCDC46_POLYPHASE_DUAL_MASK);
+               }
+               break;
+
        default:
                return false;
        }
@@ -1217,6 +1460,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
        u32 workmode;
        const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name;
        const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name;
+       const char *aldo1_name = axp15060_regulators[AXP15060_ALDO1].name;
        bool drivevbus = false;
 
        switch (axp20x->variant) {
@@ -1232,6 +1476,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
                drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
                                                  "x-powers,drive-vbus-en");
                break;
+       case AXP313A_ID:
+               regulators = axp313a_regulators;
+               nregulators = AXP313A_REG_ID_MAX;
+               break;
        case AXP803_ID:
                regulators = axp803_regulators;
                nregulators = AXP803_REG_ID_MAX;
@@ -1252,6 +1500,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
                drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
                                                  "x-powers,drive-vbus-en");
                break;
+       case AXP15060_ID:
+               regulators = axp15060_regulators;
+               nregulators = AXP15060_REG_ID_MAX;
+               break;
        default:
                dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
                        axp20x->variant);
@@ -1278,8 +1530,9 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
                        continue;
 
                /*
-                * Regulators DC1SW and DC5LDO are connected internally,
-                * so we have to handle their supply names separately.
+                * Regulators DC1SW, DC5LDO and RTCLDO on AXP15060 are
+                * connected internally, so we have to handle their supply
+                * names separately.
                 *
                 * We always register the regulators in proper sequence,
                 * so the supply names are correctly read. See the last
@@ -1288,7 +1541,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
                 */
                if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) ||
                    (regulators == axp803_regulators && i == AXP803_DC1SW) ||
-                   (regulators == axp809_regulators && i == AXP809_DC1SW)) {
+                   (regulators == axp809_regulators && i == AXP809_DC1SW) ||
+                   (regulators == axp15060_regulators && i == AXP15060_SW)) {
                        new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
                                                GFP_KERNEL);
                        if (!new_desc)
@@ -1300,7 +1554,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
                }
 
                if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) ||
-                   (regulators == axp809_regulators && i == AXP809_DC5LDO)) {
+                   (regulators == axp809_regulators && i == AXP809_DC5LDO) ||
+                   (regulators == axp15060_regulators && i == AXP15060_CPUSLDO)) {
                        new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
                                                GFP_KERNEL);
                        if (!new_desc)
@@ -1311,6 +1566,18 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
                        desc = new_desc;
                }
 
+
+               if (regulators == axp15060_regulators && i == AXP15060_RTC_LDO) {
+                       new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
+                                               GFP_KERNEL);
+                       if (!new_desc)
+                               return -ENOMEM;
+
+                       *new_desc = regulators[i];
+                       new_desc->supply_name = aldo1_name;
+                       desc = new_desc;
+               }
+
                rdev = devm_regulator_register(&pdev->dev, desc, &config);
                if (IS_ERR(rdev)) {
                        dev_err(&pdev->dev, "Failed to register %s\n",
@@ -1329,19 +1596,26 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
                }
 
                /*
-                * Save AXP22X DCDC1 / DCDC5 regulator names for later.
+                * Save AXP22X DCDC1 / DCDC5 / AXP15060 ALDO1 regulator names for later.
                 */
                if ((regulators == axp22x_regulators && i == AXP22X_DCDC1) ||
-                   (regulators == axp809_regulators && i == AXP809_DCDC1))
+                   (regulators == axp809_regulators && i == AXP809_DCDC1) ||
+                   (regulators == axp15060_regulators && i == AXP15060_DCDC1))
                        of_property_read_string(rdev->dev.of_node,
                                                "regulator-name",
                                                &dcdc1_name);
 
                if ((regulators == axp22x_regulators && i == AXP22X_DCDC5) ||
-                   (regulators == axp809_regulators && i == AXP809_DCDC5))
+                   (regulators == axp809_regulators && i == AXP809_DCDC5) ||
+                   (regulators == axp15060_regulators && i == AXP15060_DCDC5))
                        of_property_read_string(rdev->dev.of_node,
                                                "regulator-name",
                                                &dcdc5_name);
+
+               if (regulators == axp15060_regulators && i == AXP15060_ALDO1)
+                       of_property_read_string(rdev->dev.of_node,
+                                               "regulator-name",
+                                               &aldo1_name);
        }
 
        if (drivevbus) {
index 698ab7f5004bf6b74e2e57ac224f6138139f4666..d8e1caaf207e108f124988b7a9f1ee3780a12e8c 100644 (file)
@@ -1911,19 +1911,17 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
 
        if (err != -EEXIST)
                regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
-       if (!regulator->debugfs) {
+       if (IS_ERR(regulator->debugfs))
                rdev_dbg(rdev, "Failed to create debugfs directory\n");
-       } else {
-               debugfs_create_u32("uA_load", 0444, regulator->debugfs,
-                                  &regulator->uA_load);
-               debugfs_create_u32("min_uV", 0444, regulator->debugfs,
-                                  &regulator->voltage[PM_SUSPEND_ON].min_uV);
-               debugfs_create_u32("max_uV", 0444, regulator->debugfs,
-                                  &regulator->voltage[PM_SUSPEND_ON].max_uV);
-               debugfs_create_file("constraint_flags", 0444,
-                                   regulator->debugfs, regulator,
-                                   &constraint_flags_fops);
-       }
+
+       debugfs_create_u32("uA_load", 0444, regulator->debugfs,
+                          &regulator->uA_load);
+       debugfs_create_u32("min_uV", 0444, regulator->debugfs,
+                          &regulator->voltage[PM_SUSPEND_ON].min_uV);
+       debugfs_create_u32("max_uV", 0444, regulator->debugfs,
+                          &regulator->voltage[PM_SUSPEND_ON].max_uV);
+       debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
+                           regulator, &constraint_flags_fops);
 
        /*
         * Check now if the regulator is an always on regulator - if
@@ -5256,10 +5254,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
        }
 
        rdev->debugfs = debugfs_create_dir(rname, debugfs_root);
-       if (IS_ERR(rdev->debugfs)) {
-               rdev_warn(rdev, "Failed to create debugfs directory\n");
-               return;
-       }
+       if (IS_ERR(rdev->debugfs))
+               rdev_dbg(rdev, "Failed to create debugfs directory\n");
 
        debugfs_create_u32("use_count", 0444, rdev->debugfs,
                           &rdev->use_count);
@@ -6179,7 +6175,7 @@ static int __init regulator_init(void)
 
        debugfs_root = debugfs_create_dir("regulator", NULL);
        if (IS_ERR(debugfs_root))
-               pr_warn("regulator: Failed to create debugfs directory\n");
+               pr_debug("regulator: Failed to create debugfs directory\n");
 
 #ifdef CONFIG_DEBUG_FS
        debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
index 6ce0fdc18b9c1516b8aee94f3eab2d53c171f0c5..122124944749e345f0edf665e5cb57bed6fa9069 100644 (file)
@@ -1197,7 +1197,7 @@ static struct i2c_driver da9121_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(da9121_dt_ids),
        },
-       .probe_new = da9121_i2c_probe,
+       .probe = da9121_i2c_probe,
        .remove = da9121_i2c_remove,
        .id_table = da9121_i2c_id,
 };
index 4332a3b8a6723cda46dc2e7527b864abebfefcd1..252f74ab9bc01c8a056ae8dae3b1856ba22a3c5d 100644 (file)
@@ -224,7 +224,7 @@ static struct i2c_driver da9210_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(da9210_dt_ids),
        },
-       .probe_new = da9210_i2c_probe,
+       .probe = da9210_i2c_probe,
        .id_table = da9210_i2c_id,
 };
 
index a2b4f6f1e34b826bd14df7d6a71401a02a692ff7..af383ff0fe5733a8f3d5d3c57204fdbacb06bd27 100644 (file)
@@ -555,7 +555,7 @@ static struct i2c_driver da9211_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(da9211_dt_ids),
        },
-       .probe_new = da9211_i2c_probe,
+       .probe = da9211_i2c_probe,
        .id_table = da9211_i2c_id,
 };
 
index 130f3dbe98404aa61828841e0c5f3ee33c6be2df..289c06e09f47bdc7bb10146947c87008b64ec0db 100644 (file)
@@ -775,7 +775,7 @@ static struct i2c_driver fan53555_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(fan53555_dt_ids),
        },
-       .probe_new = fan53555_regulator_probe,
+       .probe = fan53555_regulator_probe,
        .id_table = fan53555_id,
 };
 
index a3bebdee570ec6961f95504ecfda5d10071b0795..6cb5656845f9e8dad92f9dd784bdf78faa8fa247 100644 (file)
@@ -175,7 +175,7 @@ static struct i2c_driver fan53880_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = fan53880_dt_ids,
        },
-       .probe_new = fan53880_i2c_probe,
+       .probe = fan53880_i2c_probe,
        .id_table = fan53880_i2c_id,
 };
 module_i2c_driver(fan53880_regulator_driver);
index ad2237a95572a7b21d1b11d324da1f5e9e86ad9d..e6c999ba3fa23ff36c02c9d67556f0b2ab69fcc0 100644 (file)
@@ -902,8 +902,21 @@ bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
 }
 EXPORT_SYMBOL_GPL(regulator_is_equal);
 
-static int find_closest_bigger(unsigned int target, const unsigned int *table,
-                              unsigned int num_sel, unsigned int *sel)
+/**
+ * regulator_find_closest_bigger - helper to find offset in ramp delay table
+ *
+ * @target: targeted ramp_delay
+ * @table: table with supported ramp delays
+ * @num_sel: number of entries in the table
+ * @sel: Pointer to store table offset
+ *
+ * This is the internal helper used by regulator_set_ramp_delay_regmap to
+ * map ramp delay to register value. It should only be used directly if
+ * regulator_set_ramp_delay_regmap cannot handle a specific device setup
+ * (e.g. because the value is split over multiple registers).
+ */
+int regulator_find_closest_bigger(unsigned int target, const unsigned int *table,
+                                 unsigned int num_sel, unsigned int *sel)
 {
        unsigned int s, tmp, max, maxsel = 0;
        bool found = false;
@@ -933,11 +946,13 @@ static int find_closest_bigger(unsigned int target, const unsigned int *table,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(regulator_find_closest_bigger);
 
 /**
  * regulator_set_ramp_delay_regmap - set_ramp_delay() helper
  *
  * @rdev: regulator to operate on
+ * @ramp_delay: ramp-rate value given in units V/S (uV/uS)
  *
  * Regulators that use regmap for their register I/O can set the ramp_reg
  * and ramp_mask fields in their descriptor and then use this as their
@@ -951,8 +966,8 @@ int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay)
        if (WARN_ON(!rdev->desc->n_ramp_values || !rdev->desc->ramp_delay_table))
                return -EINVAL;
 
-       ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
-                                 rdev->desc->n_ramp_values, &sel);
+       ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
+                                           rdev->desc->n_ramp_values, &sel);
 
        if (ret) {
                dev_warn(rdev_get_dev(rdev),
index 3c37c4de1d82105aa8c1cb3607a8c506e9294235..69b4afe95e66bf2bc5725baad3d8e8f82667245e 100644 (file)
@@ -149,7 +149,7 @@ static struct i2c_driver isl6271a_i2c_driver = {
                .name = "isl6271a",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
-       .probe_new = isl6271a_probe,
+       .probe = isl6271a_probe,
        .id_table = isl6271a_id,
 };
 
index 90bc8d054304a3adb30f21865314d75d7b4d6578..0f7560093091a18a93330c903413e55e97c375dd 100644 (file)
@@ -198,7 +198,7 @@ static struct i2c_driver isl9305_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(isl9305_dt_ids),
        },
-       .probe_new = isl9305_i2c_probe,
+       .probe = isl9305_i2c_probe,
        .id_table = isl9305_i2c_id,
 };
 
index e06f2a092b8935e49c701fe6f3b6d163d27bef37..e1b5c45f97f41b0b59ef08634a86e3b13b558961 100644 (file)
@@ -449,7 +449,7 @@ static struct i2c_driver lp3971_i2c_driver = {
                .name = "LP3971",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
-       .probe_new = lp3971_i2c_probe,
+       .probe = lp3971_i2c_probe,
        .id_table = lp3971_i2c_id,
 };
 
index edacca8e14af6b29a886dece71343d9dc8707eda..7bd6f05edd8d914f97d29ffa68f3674eb1560abe 100644 (file)
@@ -547,7 +547,7 @@ static struct i2c_driver lp3972_i2c_driver = {
                .name = "lp3972",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
-       .probe_new = lp3972_i2c_probe,
+       .probe = lp3972_i2c_probe,
        .id_table = lp3972_i2c_id,
 };
 
index a8b0969d4f31e84f74810813b41c1f96280ebd69..63aa227b18132b0a5670b51d425dd9dfa9dfed10 100644 (file)
@@ -947,7 +947,7 @@ static struct i2c_driver lp872x_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(lp872x_dt_ids),
        },
-       .probe_new = lp872x_probe,
+       .probe = lp872x_probe,
        .id_table = lp872x_ids,
 };
 
index 37b51b94fb5a4bd9f67f8bfb65a0ea46edd912ec..4bc310f972edb431f3f06cfade72af61c3bdfc15 100644 (file)
@@ -442,7 +442,7 @@ static struct i2c_driver lp8755_i2c_driver = {
                   .name = LP8755_NAME,
                   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                   },
-       .probe_new = lp8755_probe,
+       .probe = lp8755_probe,
        .remove = lp8755_remove,
        .id_table = lp8755_id,
 };
index 359b534d8c70f762e2e9170b2f2f6efb21351f0a..e9751c206d951246b485517fa32a77ded412a7fd 100644 (file)
@@ -348,7 +348,7 @@ static const struct regmap_config ltc3589_regmap_config = {
        .num_reg_defaults = ARRAY_SIZE(ltc3589_reg_defaults),
        .use_single_read = true,
        .use_single_write = true,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_MAPLE,
 };
 
 static irqreturn_t ltc3589_isr(int irq, void *dev_id)
@@ -477,7 +477,7 @@ static struct i2c_driver ltc3589_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(ltc3589_of_match),
        },
-       .probe_new = ltc3589_probe,
+       .probe = ltc3589_probe,
        .id_table = ltc3589_i2c_id,
 };
 module_i2c_driver(ltc3589_driver);
index a28e6c3460f167e3f6a8c57b321bfd6c9caed110..73d511eb1c1dceff75217b9dbc702246a1e309c7 100644 (file)
@@ -261,7 +261,7 @@ static const struct regmap_config ltc3676_regmap_config = {
        .max_register = LTC3676_CLIRQ,
        .use_single_read = true,
        .use_single_write = true,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_MAPLE,
 };
 
 static irqreturn_t ltc3676_isr(int irq, void *dev_id)
@@ -374,7 +374,7 @@ static struct i2c_driver ltc3676_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(ltc3676_of_match),
        },
-       .probe_new = ltc3676_regulator_probe,
+       .probe = ltc3676_regulator_probe,
        .id_table = ltc3676_i2c_id,
 };
 module_i2c_driver(ltc3676_driver);
index 5d8852b2c168c1112ed78eb4f6ad575928509353..90aa5b723c034b7aa05d96538fbbe639d28206fe 100644 (file)
@@ -289,7 +289,7 @@ static const struct i2c_device_id max1586_id[] = {
 MODULE_DEVICE_TABLE(i2c, max1586_id);
 
 static struct i2c_driver max1586_pmic_driver = {
-       .probe_new = max1586_pmic_probe,
+       .probe = max1586_pmic_probe,
        .driver         = {
                .name   = "max1586",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
index ace1d582a191c88169c6ec0c90883c11c43d83bf..fad31f5f435e147dd87b5e37e4aaa9da68e25fe3 100644 (file)
@@ -323,7 +323,7 @@ static struct i2c_driver max20086_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(max20086_dt_ids),
        },
-       .probe_new = max20086_i2c_probe,
+       .probe = max20086_i2c_probe,
        .id_table = max20086_i2c_id,
 };
 
index be8169b86a89301fb133186e7c3ff09527a21ecc..8c09dc71b16db5a92425b97e0e777de4da454f75 100644 (file)
@@ -156,7 +156,7 @@ static struct i2c_driver max20411_i2c_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_max20411_match_tbl,
        },
-       .probe_new = max20411_probe,
+       .probe = max20411_probe,
        .id_table = max20411_id,
 };
 module_i2c_driver(max20411_i2c_driver);
index ea5d4b18b464dd4b7c41e4ead9356b8b22647b8d..3855f5e686d8acd5bc568b8ed2cbe0b402ab9d0d 100644 (file)
@@ -292,7 +292,7 @@ static struct i2c_driver max77826_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(max77826_of_match),
        },
-       .probe_new = max77826_i2c_probe,
+       .probe = max77826_i2c_probe,
        .id_table = max77826_id,
 };
 module_i2c_driver(max77826_regulator_driver);
index a517fb4e3669b184716338ecbd3a9e0c9211f2e6..24e1dfba78c8b56c27f3050a3a3d5506ceeaf30e 100644 (file)
@@ -246,7 +246,7 @@ static const struct i2c_device_id max8649_id[] = {
 MODULE_DEVICE_TABLE(i2c, max8649_id);
 
 static struct i2c_driver max8649_driver = {
-       .probe_new      = max8649_regulator_probe,
+       .probe          = max8649_regulator_probe,
        .driver         = {
                .name   = "max8649",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
index d6b89f07ae9ebab56ad6671b1819ab2742024f6a..ede17099b727499713989f1270f2d5284981e8fd 100644 (file)
@@ -503,7 +503,7 @@ static const struct i2c_device_id max8660_id[] = {
 MODULE_DEVICE_TABLE(i2c, max8660_id);
 
 static struct i2c_driver max8660_driver = {
-       .probe_new = max8660_probe,
+       .probe = max8660_probe,
        .driver         = {
                .name   = "max8660",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
index 10ffd77828b784843124377e48fb4c02936cf849..cb0e72948dd41c81e5c64f6e1d639ce0e0e43484 100644 (file)
@@ -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_new      = max8893_probe_new,
+       .probe          = max8893_probe_new,
        .driver         = {
                .name   = "max8893",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
index 8ad8fe7fd263e85f89754a437287d5e526270103..0b0b841d214afae28b79bd71e795684d5f486a9b 100644 (file)
@@ -313,7 +313,7 @@ static const struct i2c_device_id max8952_ids[] = {
 MODULE_DEVICE_TABLE(i2c, max8952_ids);
 
 static struct i2c_driver max8952_pmic_driver = {
-       .probe_new      = max8952_pmic_probe,
+       .probe          = max8952_pmic_probe,
        .driver         = {
                .name   = "max8952",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
index a991a884a31bbfafe22fd8c826aa74f91835acd0..8d5193207552360eeadea34bb050402ddb4f6bcb 100644 (file)
@@ -807,7 +807,7 @@ static struct i2c_driver max8973_i2c_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_max8973_match_tbl,
        },
-       .probe_new = max8973_probe,
+       .probe = max8973_probe,
        .id_table = max8973_id,
 };
 
index 3a6d795569423b85239bdf53ab1660d25f562555..6c6f5a21362bec1414d9da7f45dbbf41a8102b42 100644 (file)
@@ -584,7 +584,7 @@ static const struct i2c_device_id mcp16502_i2c_id[] = {
 MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);
 
 static struct i2c_driver mcp16502_drv = {
-       .probe_new      = mcp16502_probe,
+       .probe          = mcp16502_probe,
        .driver         = {
                .name   = "mcp16502-regulator",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
index 91e9019430b864e1f23ca8a3f7ebc085d85a6c14..3886b252fbe7bad8c4713d094bd5fa30f8c478fc 100644 (file)
@@ -240,7 +240,7 @@ static struct i2c_driver mp5416_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(mp5416_of_match),
        },
-       .probe_new = mp5416_i2c_probe,
+       .probe = mp5416_i2c_probe,
        .id_table = mp5416_id,
 };
 module_i2c_driver(mp5416_regulator_driver);
index b968a682f38a0c9c35b58885ed565f1cbc220de0..b820bd6043e53bf217f0d60f2d57f0355319315b 100644 (file)
@@ -147,7 +147,7 @@ static struct i2c_driver mp8859_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(mp8859_dt_id),
        },
-       .probe_new = mp8859_i2c_probe,
+       .probe = mp8859_i2c_probe,
        .id_table = mp8859_i2c_id,
 };
 
index 250c27e462f15a6a32e9cd718016bd5802c70649..ede1b1e58002614bdb3996af5362d36936ae02fe 100644 (file)
@@ -365,7 +365,7 @@ static struct i2c_driver mp886x_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = mp886x_dt_ids,
        },
-       .probe_new = mp886x_i2c_probe,
+       .probe = mp886x_i2c_probe,
        .id_table = mp886x_id,
 };
 module_i2c_driver(mp886x_regulator_driver);
index 544d41b885144681b167b5c33770a9c6360abf96..bf677c535edc4b3dfb8bc4ed8592fdc81507c9dd 100644 (file)
@@ -321,7 +321,7 @@ static struct i2c_driver mpq7920_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(mpq7920_of_match),
        },
-       .probe_new = mpq7920_i2c_probe,
+       .probe = mpq7920_i2c_probe,
        .id_table = mpq7920_id,
 };
 module_i2c_driver(mpq7920_regulator_driver);
index a9f0c9f725d42f5e855343b10990634e4a488f2f..b0771770cc2652a8a6aa10b5cbb04022798e475c 100644 (file)
@@ -154,7 +154,7 @@ static struct i2c_driver mt6311_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(mt6311_dt_ids),
        },
-       .probe_new = mt6311_i2c_probe,
+       .probe = mt6311_i2c_probe,
        .id_table = mt6311_i2c_id,
 };
 
index c9e16bd092f6b988b5fa3d76badc79e3008f15f9..31a16fb28ecde52b8e9af37018db32f19d588e54 100644 (file)
@@ -34,8 +34,10 @@ struct mt6358_regulator_info {
        u32 modeset_mask;
 };
 
+#define to_regulator_info(x) container_of((x), struct mt6358_regulator_info, desc)
+
 #define MT6358_BUCK(match, vreg, min, max, step,               \
-       volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask,   \
+       vosel_mask, _da_vsel_reg, _da_vsel_mask,        \
        _modeset_reg, _modeset_shift)           \
 [MT6358_ID_##vreg] = { \
        .desc = {       \
@@ -46,8 +48,8 @@ struct mt6358_regulator_info {
                .id = MT6358_ID_##vreg,         \
                .owner = THIS_MODULE,           \
                .n_voltages = ((max) - (min)) / (step) + 1,     \
-               .linear_ranges = volt_ranges,           \
-               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .min_uV = (min),                \
+               .uV_step = (step),              \
                .vsel_reg = MT6358_BUCK_##vreg##_ELR0,  \
                .vsel_mask = vosel_mask,        \
                .enable_reg = MT6358_BUCK_##vreg##_CON0,        \
@@ -87,7 +89,7 @@ struct mt6358_regulator_info {
 }
 
 #define MT6358_LDO1(match, vreg, min, max, step,       \
-       volt_ranges, _da_vsel_reg, _da_vsel_mask,       \
+       _da_vsel_reg, _da_vsel_mask,    \
        vosel, vosel_mask)      \
 [MT6358_ID_##vreg] = { \
        .desc = {       \
@@ -98,8 +100,8 @@ struct mt6358_regulator_info {
                .id = MT6358_ID_##vreg, \
                .owner = THIS_MODULE,   \
                .n_voltages = ((max) - (min)) / (step) + 1,     \
-               .linear_ranges = volt_ranges,   \
-               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .min_uV = (min),                \
+               .uV_step = (step),              \
                .vsel_reg = vosel,      \
                .vsel_mask = vosel_mask,        \
                .enable_reg = MT6358_LDO_##vreg##_CON0, \
@@ -131,7 +133,7 @@ struct mt6358_regulator_info {
 }
 
 #define MT6366_BUCK(match, vreg, min, max, step,               \
-       volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask,   \
+       vosel_mask, _da_vsel_reg, _da_vsel_mask,        \
        _modeset_reg, _modeset_shift)           \
 [MT6366_ID_##vreg] = { \
        .desc = {       \
@@ -142,8 +144,8 @@ struct mt6358_regulator_info {
                .id = MT6366_ID_##vreg,         \
                .owner = THIS_MODULE,           \
                .n_voltages = ((max) - (min)) / (step) + 1,     \
-               .linear_ranges = volt_ranges,           \
-               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .min_uV = (min),                \
+               .uV_step = (step),              \
                .vsel_reg = MT6358_BUCK_##vreg##_ELR0,  \
                .vsel_mask = vosel_mask,        \
                .enable_reg = MT6358_BUCK_##vreg##_CON0,        \
@@ -183,7 +185,7 @@ struct mt6358_regulator_info {
 }
 
 #define MT6366_LDO1(match, vreg, min, max, step,       \
-       volt_ranges, _da_vsel_reg, _da_vsel_mask,       \
+       _da_vsel_reg, _da_vsel_mask,    \
        vosel, vosel_mask)      \
 [MT6366_ID_##vreg] = { \
        .desc = {       \
@@ -194,8 +196,8 @@ struct mt6358_regulator_info {
                .id = MT6366_ID_##vreg, \
                .owner = THIS_MODULE,   \
                .n_voltages = ((max) - (min)) / (step) + 1,     \
-               .linear_ranges = volt_ranges,   \
-               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .min_uV = (min),                \
+               .uV_step = (step),              \
                .vsel_reg = vosel,      \
                .vsel_mask = vosel_mask,        \
                .enable_reg = MT6358_LDO_##vreg##_CON0, \
@@ -226,21 +228,6 @@ struct mt6358_regulator_info {
        .qi = BIT(15),                                                  \
 }
 
-static const struct linear_range buck_volt_range1[] = {
-       REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
-};
-
-static const struct linear_range buck_volt_range2[] = {
-       REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500),
-};
-
-static const struct linear_range buck_volt_range3[] = {
-       REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
-};
-
-static const struct linear_range buck_volt_range4[] = {
-       REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500),
-};
 
 static const unsigned int vdram2_voltages[] = {
        600000, 1800000,
@@ -277,7 +264,7 @@ static const unsigned int vcama_voltages[] = {
        2800000, 2900000, 3000000,
 };
 
-static const unsigned int vcn33_bt_wifi_voltages[] = {
+static const unsigned int vcn33_voltages[] = {
        3300000, 3400000, 3500000,
 };
 
@@ -321,7 +308,7 @@ static const u32 vcama_idx[] = {
        0, 7, 9, 10, 11, 12,
 };
 
-static const u32 vcn33_bt_wifi_idx[] = {
+static const u32 vcn33_idx[] = {
        1, 2, 3,
 };
 
@@ -342,9 +329,9 @@ static unsigned int mt6358_map_mode(unsigned int mode)
 static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
                                  unsigned int selector)
 {
+       const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
        int idx, ret;
        const u32 *pvol;
-       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
 
        pvol = info->index_table;
 
@@ -358,9 +345,9 @@ static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
 
 static int mt6358_get_voltage_sel(struct regulator_dev *rdev)
 {
+       const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
        int idx, ret;
        u32 selector;
-       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
        const u32 *pvol;
 
        ret = regmap_read(rdev->regmap, info->desc.vsel_reg, &selector);
@@ -384,8 +371,8 @@ static int mt6358_get_voltage_sel(struct regulator_dev *rdev)
 
 static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
 {
+       const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
        int ret, regval;
-       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
 
        ret = regmap_read(rdev->regmap, info->da_vsel_reg, &regval);
        if (ret != 0) {
@@ -402,9 +389,9 @@ static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
 
 static int mt6358_get_status(struct regulator_dev *rdev)
 {
+       const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
        int ret;
        u32 regval;
-       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
 
        ret = regmap_read(rdev->regmap, info->status_reg, &regval);
        if (ret != 0) {
@@ -418,7 +405,7 @@ static int mt6358_get_status(struct regulator_dev *rdev)
 static int mt6358_regulator_set_mode(struct regulator_dev *rdev,
                                     unsigned int mode)
 {
-       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+       const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
        int val;
 
        switch (mode) {
@@ -443,7 +430,7 @@ static int mt6358_regulator_set_mode(struct regulator_dev *rdev,
 
 static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
 {
-       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+       const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
        int ret, regval;
 
        ret = regmap_read(rdev->regmap, info->modeset_reg, &regval);
@@ -464,8 +451,8 @@ static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
 }
 
 static const struct regulator_ops mt6358_volt_range_ops = {
-       .list_voltage = regulator_list_voltage_linear_range,
-       .map_voltage = regulator_map_voltage_linear_range,
+       .list_voltage = regulator_list_voltage_linear,
+       .map_voltage = regulator_map_voltage_linear,
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
        .get_voltage_sel = mt6358_get_buck_voltage_sel,
        .set_voltage_time_sel = regulator_set_voltage_time_sel,
@@ -498,37 +485,25 @@ static const struct regulator_ops mt6358_volt_fixed_ops = {
 };
 
 /* The array is indexed by id(MT6358_ID_XXX) */
-static struct mt6358_regulator_info mt6358_regulators[] = {
+static const struct mt6358_regulator_info mt6358_regulators[] = {
        MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
-                   buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
-                   MT6358_VDRAM1_ANA_CON0, 8),
+                   0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
        MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
-                   MT6358_VCORE_VGPU_ANA_CON0, 1),
-       MT6358_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
-                   MT6358_VCORE_VGPU_ANA_CON0, 1),
+                   0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
        MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
-                   buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
-                   MT6358_VPA_ANA_CON0, 3),
+                   0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
        MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
-                   MT6358_VPROC_ANA_CON0, 1),
+                   0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
        MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
-                   MT6358_VPROC_ANA_CON0, 2),
+                   0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
        MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f,
-                   MT6358_VCORE_VGPU_ANA_CON0, 2),
+                   0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
        MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
-                   buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f,
-                   MT6358_VS2_ANA_CON0, 8),
+                   0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
        MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
-                   MT6358_VMODEM_ANA_CON0, 8),
+                   0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
        MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
-                   buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f,
-                   MT6358_VS1_ANA_CON0, 8),
+                   0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
        MT6358_REG_FIXED("ldo_vrf12", VRF12,
                         MT6358_LDO_VRF12_CON0, 0, 1200000),
        MT6358_REG_FIXED("ldo_vio18", VIO18,
@@ -566,12 +541,8 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
                   MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00),
        MT6358_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
                   MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
-       MT6358_LDO("ldo_vcn33_bt", VCN33_BT, vcn33_bt_wifi_voltages,
-                  vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_0,
-                  0, MT6358_VCN33_ANA_CON0, 0x300),
-       MT6358_LDO("ldo_vcn33_wifi", VCN33_WIFI, vcn33_bt_wifi_voltages,
-                  vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_1,
-                  0, MT6358_VCN33_ANA_CON0, 0x300),
+       MT6358_LDO("ldo_vcn33", VCN33, vcn33_voltages, vcn33_idx,
+                  MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),
        MT6358_LDO("ldo_vcama2", VCAMA2, vcama_voltages, vcama_idx,
                   MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00),
        MT6358_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
@@ -582,55 +553,35 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
        MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
                   MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
        MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
-                   buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00,
-                   MT6358_LDO_VSRAM_CON0, 0x7f),
+                   MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
        MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
-                   buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
-                   MT6358_LDO_VSRAM_CON2, 0x7f),
-       MT6358_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
-                   1293750, 6250, buck_volt_range1,
-                   MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
-                   MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
+                   MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
        MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
-                   buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
-                   MT6358_LDO_VSRAM_CON3, 0x7f),
+                   MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
        MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
-                   buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00,
-                   MT6358_LDO_VSRAM_CON1, 0x7f),
+                   MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
 };
 
 /* The array is indexed by id(MT6366_ID_XXX) */
-static struct mt6358_regulator_info mt6366_regulators[] = {
+static const struct mt6358_regulator_info mt6366_regulators[] = {
        MT6366_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
-                   buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
-                   MT6358_VDRAM1_ANA_CON0, 8),
+                   0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
        MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
-                   MT6358_VCORE_VGPU_ANA_CON0, 1),
-       MT6366_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
-                   MT6358_VCORE_VGPU_ANA_CON0, 1),
+                   0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
        MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
-                   buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
-                   MT6358_VPA_ANA_CON0, 3),
+                   0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
        MT6366_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
-                   MT6358_VPROC_ANA_CON0, 1),
+                   0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
        MT6366_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
-                   MT6358_VPROC_ANA_CON0, 2),
+                   0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
        MT6366_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f,
-                   MT6358_VCORE_VGPU_ANA_CON0, 2),
+                   0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
        MT6366_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
-                   buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f,
-                   MT6358_VS2_ANA_CON0, 8),
+                   0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
        MT6366_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
-                   buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
-                   MT6358_VMODEM_ANA_CON0, 8),
+                   0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
        MT6366_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
-                   buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f,
-                   MT6358_VS1_ANA_CON0, 8),
+                   0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
        MT6366_REG_FIXED("ldo_vrf12", VRF12,
                         MT6358_LDO_VRF12_CON0, 0, 1200000),
        MT6366_REG_FIXED("ldo_vio18", VIO18,
@@ -662,41 +613,72 @@ static struct mt6358_regulator_info mt6366_regulators[] = {
                   MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),
        MT6366_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
                   MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
-       MT6366_LDO("ldo_vcn33_bt", VCN33_BT, vcn33_bt_wifi_voltages,
-                  vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_0,
-                  0, MT6358_VCN33_ANA_CON0, 0x300),
-       MT6366_LDO("ldo_vcn33_wifi", VCN33_WIFI, vcn33_bt_wifi_voltages,
-                  vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_1,
-                  0, MT6358_VCN33_ANA_CON0, 0x300),
+       MT6366_LDO("ldo_vcn33", VCN33, vcn33_voltages, vcn33_idx,
+                  MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),
        MT6366_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
                   MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),
        MT6366_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
                   MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
        MT6366_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
-                   buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00,
-                   MT6358_LDO_VSRAM_CON0, 0x7f),
+                   MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
        MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
-                   buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
-                   MT6358_LDO_VSRAM_CON2, 0x7f),
-       MT6366_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
-                   1293750, 6250, buck_volt_range1,
-                   MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
-                   MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
+                   MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
        MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
-                   buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
-                   MT6358_LDO_VSRAM_CON3, 0x7f),
+                   MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
        MT6366_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
-                   buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00,
-                   MT6358_LDO_VSRAM_CON1, 0x7f),
+                   MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
 };
 
+static int mt6358_sync_vcn33_setting(struct device *dev)
+{
+       struct mt6397_chip *mt6397 = dev_get_drvdata(dev->parent);
+       unsigned int val;
+       int ret;
+
+       /*
+        * VCN33_WIFI and VCN33_BT are two separate enable bits for the same
+        * regulator. They share the same voltage setting and output pin.
+        * Instead of having two potentially conflicting regulators, just have
+        * one VCN33 regulator. Sync the two enable bits and only use one in
+        * the regulator device.
+        */
+       ret = regmap_read(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, &val);
+       if (ret) {
+               dev_err(dev, "Failed to read VCN33_WIFI setting\n");
+               return ret;
+       }
+
+       if (!(val & BIT(0)))
+               return 0;
+
+       /* Sync VCN33_WIFI enable status to VCN33_BT */
+       ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_0, BIT(0), BIT(0));
+       if (ret) {
+               dev_err(dev, "Failed to sync VCN33_WIFI setting to VCN33_BT\n");
+               return ret;
+       }
+
+       /* Disable VCN33_WIFI */
+       ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, BIT(0), 0);
+       if (ret) {
+               dev_err(dev, "Failed to disable VCN33_BT\n");
+               return ret;
+       }
+
+       return 0;
+}
+
 static int mt6358_regulator_probe(struct platform_device *pdev)
 {
        struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
        struct regulator_config config = {};
        struct regulator_dev *rdev;
-       struct mt6358_regulator_info *mt6358_info;
-       int i, max_regulator;
+       const struct mt6358_regulator_info *mt6358_info;
+       int i, max_regulator, ret;
+
+       ret = mt6358_sync_vcn33_setting(&pdev->dev);
+       if (ret)
+               return ret;
 
        if (mt6397->chip_id == MT6366_CHIP_ID) {
                max_regulator = MT6366_MAX_REGULATOR;
@@ -708,7 +690,6 @@ static int mt6358_regulator_probe(struct platform_device *pdev)
 
        for (i = 0; i < max_regulator; i++) {
                config.dev = &pdev->dev;
-               config.driver_data = &mt6358_info[i];
                config.regmap = mt6397->regmap;
 
                rdev = devm_regulator_register(&pdev->dev,
index e75dd92f86ca728435247b1523a1a3283e0e0efc..91bfb7e026c90b32eec4c1606119cea169d83c49 100644 (file)
@@ -875,7 +875,7 @@ static struct i2c_driver pca9450_i2c_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = pca9450_of_match,
        },
-       .probe_new = pca9450_i2c_probe,
+       .probe = pca9450_i2c_probe,
 };
 
 module_i2c_driver(pca9450_i2c_driver);
index 99a15c3be39656b3278efe741273bf6f90394a28..b0781d9a1058f89dd531d3f22d9ed4fc525257f0 100644 (file)
@@ -610,7 +610,7 @@ static struct i2c_driver pf8x00_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = pf8x00_dt_ids,
        },
-       .probe_new = pf8x00_i2c_probe,
+       .probe = pf8x00_i2c_probe,
 };
 module_i2c_driver(pf8x00_regulator_driver);
 
index a9fcf6a41494a640357e31a09055ff3fc3358334..8d7e6c3233243f0d414a08db93b43ac43f9fa052 100644 (file)
@@ -848,7 +848,7 @@ static struct i2c_driver pfuze_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = pfuze_dt_ids,
        },
-       .probe_new = pfuze100_regulator_probe,
+       .probe = pfuze100_regulator_probe,
 };
 module_i2c_driver(pfuze_driver);
 
index f170e0dd18198562c0e00a71ccf195a2ffc704e0..aa90360fa046af1abce2b9d66327cfe2f01e3f89 100644 (file)
@@ -379,7 +379,7 @@ static struct i2c_driver pv88060_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(pv88060_dt_ids),
        },
-       .probe_new = pv88060_i2c_probe,
+       .probe = pv88060_i2c_probe,
        .id_table = pv88060_i2c_id,
 };
 
index 133b89d5215c0d42d0be7fe22957629ba3c65682..7ab3e4a9bd28ccf441fe5756ada9cffac7dffe46 100644 (file)
@@ -560,7 +560,7 @@ static struct i2c_driver pv88080_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(pv88080_dt_ids),
        },
-       .probe_new = pv88080_i2c_probe,
+       .probe = pv88080_i2c_probe,
        .id_table = pv88080_i2c_id,
 };
 
index 1bc33bc1099288caa595cc3e99aa748b0f73905b..f4acde4d56c81c2b4444480f6fe01437f252cca3 100644 (file)
@@ -400,7 +400,7 @@ static struct i2c_driver pv88090_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(pv88090_dt_ids),
        },
-       .probe_new = pv88090_i2c_probe,
+       .probe = pv88090_i2c_probe,
        .id_table = pv88090_i2c_id,
 };
 
diff --git a/drivers/regulator/raa215300.c b/drivers/regulator/raa215300.c
new file mode 100644 (file)
index 0000000..24a1c89
--- /dev/null
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Renesas RAA215300 PMIC driver
+//
+// Copyright (C) 2023 Renesas Electronics Corporation
+//
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#define RAA215300_FAULT_LATCHED_STATUS_1       0x59
+#define RAA215300_FAULT_LATCHED_STATUS_2       0x5a
+#define RAA215300_FAULT_LATCHED_STATUS_3       0x5b
+#define RAA215300_FAULT_LATCHED_STATUS_4       0x5c
+#define RAA215300_FAULT_LATCHED_STATUS_6       0x5e
+
+#define RAA215300_INT_MASK_1   0x64
+#define RAA215300_INT_MASK_2   0x65
+#define RAA215300_INT_MASK_3   0x66
+#define RAA215300_INT_MASK_4   0x67
+#define RAA215300_INT_MASK_6   0x68
+
+#define RAA215300_REG_BLOCK_EN 0x6c
+#define RAA215300_HW_REV       0xf8
+
+#define RAA215300_INT_MASK_1_ALL       GENMASK(5, 0)
+#define RAA215300_INT_MASK_2_ALL       GENMASK(3, 0)
+#define RAA215300_INT_MASK_3_ALL       GENMASK(5, 0)
+#define RAA215300_INT_MASK_4_ALL       BIT(0)
+#define RAA215300_INT_MASK_6_ALL       GENMASK(7, 0)
+
+#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,
+       .max_register = 0xff,
+};
+
+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)
+{
+       struct clk *clk;
+
+       clk = devm_clk_get_optional(&client->dev, name);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       return !!clk;
+}
+
+static int raa215300_i2c_probe(struct i2c_client *client)
+{
+       struct device *dev = &client->dev;
+       const char *clk_name = xin_name;
+       unsigned int pmic_version, val;
+       struct regmap *regmap;
+       int ret;
+
+       regmap = devm_regmap_init_i2c(client, &raa215300_regmap_config);
+       if (IS_ERR(regmap))
+               return dev_err_probe(dev, PTR_ERR(regmap),
+                                    "regmap i2c init failed\n");
+
+       ret = regmap_read(regmap, RAA215300_HW_REV, &pmic_version);
+       if (ret < 0)
+               return dev_err_probe(dev, ret, "HW rev read failed\n");
+
+       dev_dbg(dev, "RAA215300 PMIC version 0x%04x\n", pmic_version);
+
+       /* Clear all blocks except RTC, if enabled */
+       regmap_read(regmap, RAA215300_REG_BLOCK_EN, &val);
+       val &= RAA215300_REG_BLOCK_EN_RTC_EN;
+       regmap_write(regmap, RAA215300_REG_BLOCK_EN, val);
+
+       /*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);
+       regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_2, val);
+       regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_3, &val);
+       regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_3, val);
+       regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_4, &val);
+       regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_4, val);
+       regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_6, &val);
+       regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_6, val);
+
+       /* Mask all the PMIC interrupts */
+       regmap_write(regmap, RAA215300_INT_MASK_1, RAA215300_INT_MASK_1_ALL);
+       regmap_write(regmap, RAA215300_INT_MASK_2, RAA215300_INT_MASK_2_ALL);
+       regmap_write(regmap, RAA215300_INT_MASK_3, RAA215300_INT_MASK_3_ALL);
+       regmap_write(regmap, RAA215300_INT_MASK_4, RAA215300_INT_MASK_4_ALL);
+       regmap_write(regmap, RAA215300_INT_MASK_6, RAA215300_INT_MASK_6_ALL);
+
+       ret = raa215300_clk_present(client, xin_name);
+       if (ret < 0) {
+               return ret;
+       } else if (!ret) {
+               ret = raa215300_clk_present(client, clkin_name);
+               if (ret < 0)
+                       return ret;
+
+               clk_name = clkin_name;
+       }
+
+       if (ret) {
+               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;
+               ssize_t size;
+
+               clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, 32000);
+               clk_register_clkdev(clk, clk_name, NULL);
+
+               if (np) {
+                       int i;
+
+                       i = of_property_match_string(np, "reg-names", "rtc");
+                       if (i >= 0)
+                               of_property_read_u32_index(np, "reg", i, &addr);
+               }
+
+               info.addr = addr;
+               if (client->irq > 0)
+                       info.irq = client->irq;
+
+               size = strscpy(info.type, name, sizeof(info.type));
+               if (size < 0)
+                       return dev_err_probe(dev, size,
+                                            "Invalid device name: %s\n", name);
+
+               /* Enable RTC block */
+               regmap_update_bits(regmap, RAA215300_REG_BLOCK_EN,
+                                  RAA215300_REG_BLOCK_EN_RTC_EN,
+                                  RAA215300_REG_BLOCK_EN_RTC_EN);
+
+               rtc_client = i2c_new_client_device(client->adapter, &info);
+               if (IS_ERR(rtc_client))
+                       return PTR_ERR(rtc_client);
+
+               ret = devm_add_action_or_reset(dev,
+                                              raa215300_rtc_unregister_device,
+                                              rtc_client);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static const struct of_device_id raa215300_dt_match[] = {
+       { .compatible = "renesas,raa215300" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, raa215300_dt_match);
+
+static struct i2c_driver raa215300_i2c_driver = {
+       .driver = {
+               .name = "raa215300",
+               .of_match_table = raa215300_dt_match,
+       },
+       .probe_new = raa215300_i2c_probe,
+};
+module_i2c_driver(raa215300_i2c_driver);
+
+MODULE_DESCRIPTION("Renesas RAA215300 PMIC driver");
+MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro.jz@renesas.com>");
+MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
+MODULE_LICENSE("GPL");
index 3637e81654a8ecaa9b31db3ae2133a36f6aa52df..460525ed006c70e2bee5eb3647b43faabc1c7292 100644 (file)
@@ -3,9 +3,11 @@
  * Regulator driver for Rockchip RK805/RK808/RK818
  *
  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
  *
  * Author: Chris Zhong <zyw@rock-chips.com>
  * Author: Zhang Qing <zhangqing@rock-chips.com>
+ * Author: Xu Shengfei <xsf@rock-chips.com>
  *
  * Copyright (C) 2016 PHYTEC Messtechnik GmbH
  *
 #define RK818_LDO3_ON_VSEL_MASK                0xf
 #define RK818_BOOST_ON_VSEL_MASK       0xe0
 
+#define RK806_DCDC_SLP_REG_OFFSET      0x0A
+#define RK806_NLDO_SLP_REG_OFFSET      0x05
+#define RK806_PLDO_SLP_REG_OFFSET      0x06
+
+#define RK806_BUCK_SEL_CNT             0xff
+#define RK806_LDO_SEL_CNT              0xff
+
 /* Ramp rate definitions for buck1 / buck2 only */
 #define RK808_RAMP_RATE_OFFSET         3
 #define RK808_RAMP_RATE_MASK           (3 << RK808_RAMP_RATE_OFFSET)
        RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,  \
        _vmask, _ereg, _emask, 0, 0, _etime, &rk805_reg_ops)
 
+#define RK806_REGULATOR(_name, _supply_name, _id, _ops,\
+                       _n_voltages, _vr, _er, _lr, ctrl_bit,\
+                       _rr, _rm, _rt)\
+[_id] = {\
+               .name = _name,\
+               .supply_name = _supply_name,\
+               .of_match = of_match_ptr(_name),\
+               .regulators_node = of_match_ptr("regulators"),\
+               .id = _id,\
+               .ops = &_ops,\
+               .type = REGULATOR_VOLTAGE,\
+               .n_voltages = _n_voltages,\
+               .linear_ranges = _lr,\
+               .n_linear_ranges = ARRAY_SIZE(_lr),\
+               .vsel_reg = _vr,\
+               .vsel_mask = 0xff,\
+               .enable_reg = _er,\
+               .enable_mask = ENABLE_MASK(ctrl_bit),\
+               .enable_val = ENABLE_MASK(ctrl_bit),\
+               .disable_val = DISABLE_VAL(ctrl_bit),\
+               .of_map_mode = rk8xx_regulator_of_map_mode,\
+               .ramp_reg = _rr,\
+               .ramp_mask = _rm,\
+               .ramp_delay_table = _rt, \
+               .n_ramp_values = ARRAY_SIZE(_rt), \
+               .owner = THIS_MODULE,\
+       }
+
 #define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg,     \
        _vmask, _ereg, _emask, _etime)                                  \
        RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,  \
        RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask,       \
        0, 0, &rk808_switch_ops)
 
+struct rk8xx_register_bit {
+       u8 reg;
+       u8 bit;
+};
+
+#define RK8XX_REG_BIT(_reg, _bit)                                      \
+       {                                                               \
+               .reg = _reg,                                            \
+               .bit = BIT(_bit),                                               \
+       }
+
 struct rk808_regulator_data {
        struct gpio_desc *dvs_gpio[2];
 };
@@ -216,6 +264,133 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
        3000, 6300, 12500, 25000
 };
 
+static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
+{
+       int rid = rdev_get_id(rdev);
+       int ctr_bit, reg;
+
+       reg = RK806_POWER_FPWM_EN0 + rid / 8;
+       ctr_bit = rid % 8;
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+               return regmap_update_bits(rdev->regmap, reg,
+                                         PWM_MODE_MSK << ctr_bit,
+                                         FPWM_MODE << ctr_bit);
+       case REGULATOR_MODE_NORMAL:
+               return regmap_update_bits(rdev->regmap, reg,
+                                         PWM_MODE_MSK << ctr_bit,
+                                         AUTO_PWM_MODE << ctr_bit);
+       default:
+               dev_err(rdev_get_dev(rdev), "mode unsupported: %u\n", mode);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static unsigned int rk806_get_mode_dcdc(struct regulator_dev *rdev)
+{
+       int rid = rdev_get_id(rdev);
+       int ctr_bit, reg;
+       unsigned int val;
+       int err;
+
+       reg = RK806_POWER_FPWM_EN0 + rid / 8;
+       ctr_bit = rid % 8;
+
+       err = regmap_read(rdev->regmap, reg, &val);
+       if (err)
+               return err;
+
+       if ((val >> ctr_bit) & FPWM_MODE)
+               return REGULATOR_MODE_FAST;
+       else
+               return REGULATOR_MODE_NORMAL;
+}
+
+static const struct rk8xx_register_bit rk806_dcdc_rate2[] = {
+       RK8XX_REG_BIT(0xEB, 0),
+       RK8XX_REG_BIT(0xEB, 1),
+       RK8XX_REG_BIT(0xEB, 2),
+       RK8XX_REG_BIT(0xEB, 3),
+       RK8XX_REG_BIT(0xEB, 4),
+       RK8XX_REG_BIT(0xEB, 5),
+       RK8XX_REG_BIT(0xEB, 6),
+       RK8XX_REG_BIT(0xEB, 7),
+       RK8XX_REG_BIT(0xEA, 0),
+       RK8XX_REG_BIT(0xEA, 1),
+};
+
+static const unsigned int rk806_ramp_delay_table_dcdc[] = {
+       50000, 25000, 12500, 6250, 3125, 1560, 961, 390
+};
+
+static int rk806_set_ramp_delay_dcdc(struct regulator_dev *rdev, int ramp_delay)
+{
+       int rid = rdev_get_id(rdev);
+       int regval, ramp_value, ret;
+
+       ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
+                                           rdev->desc->n_ramp_values, &ramp_value);
+       if (ret) {
+               dev_warn(rdev_get_dev(rdev),
+                        "Can't set ramp-delay %u, setting %u\n", ramp_delay,
+                        rdev->desc->ramp_delay_table[ramp_value]);
+       }
+
+       regval = ramp_value << (ffs(rdev->desc->ramp_mask) - 1);
+
+       ret = regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg,
+                                rdev->desc->ramp_mask, regval);
+       if (ret)
+               return ret;
+
+       /*
+        * The above is effectively a copy of regulator_set_ramp_delay_regmap(),
+        * but that only stores the lower 2 bits for rk806 DCDC ramp. The MSB must
+        * be stored in a separate register, so this open codes the implementation
+        * to have access to the ramp_value.
+        */
+
+       regval = (ramp_value >> 2) & 0x1 ? rk806_dcdc_rate2[rid].bit : 0;
+       return regmap_update_bits(rdev->regmap, rk806_dcdc_rate2[rid].reg,
+                                 rk806_dcdc_rate2[rid].bit,
+                                 regval);
+}
+
+static const unsigned int rk806_ramp_delay_table_ldo[] = {
+       100000, 50000, 25000, 12500, 6280, 3120, 1900, 780
+};
+
+static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int reg_offset, int uv)
+{
+       int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
+       unsigned int reg;
+
+       if (sel < 0)
+               return -EINVAL;
+
+       reg = rdev->desc->vsel_reg + reg_offset;
+
+       return regmap_update_bits(rdev->regmap, reg, rdev->desc->vsel_mask, sel);
+}
+
+static int rk806_set_suspend_voltage_range_dcdc(struct regulator_dev *rdev, int uv)
+{
+       return rk806_set_suspend_voltage_range(rdev, RK806_DCDC_SLP_REG_OFFSET, uv);
+}
+
+static int rk806_set_suspend_voltage_range_nldo(struct regulator_dev *rdev, int uv)
+{
+       return rk806_set_suspend_voltage_range(rdev, RK806_NLDO_SLP_REG_OFFSET, uv);
+}
+
+static int rk806_set_suspend_voltage_range_pldo(struct regulator_dev *rdev, int uv)
+{
+       return rk806_set_suspend_voltage_range(rdev, RK806_PLDO_SLP_REG_OFFSET, uv);
+}
+
 static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
 {
        struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
@@ -393,6 +568,47 @@ static int rk805_set_suspend_disable(struct regulator_dev *rdev)
                                  0);
 }
 
+static const struct rk8xx_register_bit rk806_suspend_bits[] = {
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 0),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 1),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 2),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 3),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 4),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 5),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 6),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 7),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 6),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 7),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 0),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 1),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 2),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 3),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 4),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 1),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 2),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 3),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 4),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 5),
+       RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 0),
+};
+
+static int rk806_set_suspend_enable(struct regulator_dev *rdev)
+{
+       int rid = rdev_get_id(rdev);
+
+       return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg,
+                                 rk806_suspend_bits[rid].bit,
+                                 rk806_suspend_bits[rid].bit);
+}
+
+static int rk806_set_suspend_disable(struct regulator_dev *rdev)
+{
+       int rid = rdev_get_id(rdev);
+
+       return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg,
+                                 rk806_suspend_bits[rid].bit, 0);
+}
+
 static int rk808_set_suspend_enable(struct regulator_dev *rdev)
 {
        unsigned int reg;
@@ -561,6 +777,64 @@ static const struct regulator_ops rk805_switch_ops = {
        .set_suspend_disable    = rk805_set_suspend_disable,
 };
 
+static const struct regulator_ops rk806_ops_dcdc = {
+       .list_voltage           = regulator_list_voltage_linear_range,
+       .map_voltage            = regulator_map_voltage_linear_range,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .set_voltage_time_sel   = regulator_set_voltage_time_sel,
+       .set_mode               = rk806_set_mode_dcdc,
+       .get_mode               = rk806_get_mode_dcdc,
+
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .is_enabled             = rk8xx_is_enabled_wmsk_regmap,
+
+       .set_suspend_mode       = rk806_set_mode_dcdc,
+       .set_ramp_delay         = rk806_set_ramp_delay_dcdc,
+
+       .set_suspend_voltage    = rk806_set_suspend_voltage_range_dcdc,
+       .set_suspend_enable     = rk806_set_suspend_enable,
+       .set_suspend_disable    = rk806_set_suspend_disable,
+};
+
+static const struct regulator_ops rk806_ops_nldo = {
+       .list_voltage           = regulator_list_voltage_linear_range,
+       .map_voltage            = regulator_map_voltage_linear_range,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .set_voltage_time_sel   = regulator_set_voltage_time_sel,
+
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .is_enabled             = regulator_is_enabled_regmap,
+
+       .set_ramp_delay         = regulator_set_ramp_delay_regmap,
+
+       .set_suspend_voltage    = rk806_set_suspend_voltage_range_nldo,
+       .set_suspend_enable     = rk806_set_suspend_enable,
+       .set_suspend_disable    = rk806_set_suspend_disable,
+};
+
+static const struct regulator_ops rk806_ops_pldo = {
+       .list_voltage           = regulator_list_voltage_linear_range,
+       .map_voltage            = regulator_map_voltage_linear_range,
+
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .set_voltage_time_sel   = regulator_set_voltage_time_sel,
+
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .is_enabled             = regulator_is_enabled_regmap,
+
+       .set_ramp_delay         = regulator_set_ramp_delay_regmap,
+
+       .set_suspend_voltage    = rk806_set_suspend_voltage_range_pldo,
+       .set_suspend_enable     = rk806_set_suspend_enable,
+       .set_suspend_disable    = rk806_set_suspend_disable,
+};
+
 static const struct regulator_ops rk808_buck1_2_ops = {
        .list_voltage           = regulator_list_voltage_linear,
        .map_voltage            = regulator_map_voltage_linear,
@@ -743,6 +1017,112 @@ static const struct regulator_desc rk805_reg[] = {
                BIT(2), 400),
 };
 
+static const struct linear_range rk806_buck_voltage_ranges[] = {
+       REGULATOR_LINEAR_RANGE(500000, 0, 160, 6250), /* 500mV ~ 1500mV */
+       REGULATOR_LINEAR_RANGE(1500000, 161, 237, 25000), /* 1500mV ~ 3400mV */
+       REGULATOR_LINEAR_RANGE(3400000, 238, 255, 0),
+};
+
+static const struct linear_range rk806_ldo_voltage_ranges[] = {
+       REGULATOR_LINEAR_RANGE(500000, 0, 232, 12500), /* 500mV ~ 3400mV */
+       REGULATOR_LINEAR_RANGE(3400000, 233, 255, 0), /* 500mV ~ 3400mV */
+};
+
+static const struct regulator_desc rk806_reg[] = {
+       RK806_REGULATOR("dcdc-reg1", "vcc1", RK806_ID_DCDC1, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK1_ON_VSEL,
+                       RK806_POWER_EN0, rk806_buck_voltage_ranges, 0,
+                       RK806_BUCK1_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+       RK806_REGULATOR("dcdc-reg2", "vcc2", RK806_ID_DCDC2, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK2_ON_VSEL,
+                       RK806_POWER_EN0, rk806_buck_voltage_ranges, 1,
+                       RK806_BUCK2_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+       RK806_REGULATOR("dcdc-reg3", "vcc3", RK806_ID_DCDC3, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK3_ON_VSEL,
+                       RK806_POWER_EN0, rk806_buck_voltage_ranges, 2,
+                       RK806_BUCK3_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+       RK806_REGULATOR("dcdc-reg4", "vcc4", RK806_ID_DCDC4, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK4_ON_VSEL,
+                       RK806_POWER_EN0, rk806_buck_voltage_ranges, 3,
+                       RK806_BUCK4_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+       RK806_REGULATOR("dcdc-reg5", "vcc5", RK806_ID_DCDC5, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK5_ON_VSEL,
+                       RK806_POWER_EN1, rk806_buck_voltage_ranges, 0,
+                       RK806_BUCK5_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+       RK806_REGULATOR("dcdc-reg6", "vcc6", RK806_ID_DCDC6, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK6_ON_VSEL,
+                       RK806_POWER_EN1, rk806_buck_voltage_ranges, 1,
+                       RK806_BUCK6_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+       RK806_REGULATOR("dcdc-reg7", "vcc7", RK806_ID_DCDC7, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK7_ON_VSEL,
+                       RK806_POWER_EN1, rk806_buck_voltage_ranges, 2,
+                       RK806_BUCK7_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+       RK806_REGULATOR("dcdc-reg8", "vcc8", RK806_ID_DCDC8, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK8_ON_VSEL,
+                       RK806_POWER_EN1, rk806_buck_voltage_ranges, 3,
+                       RK806_BUCK8_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+       RK806_REGULATOR("dcdc-reg9", "vcc9", RK806_ID_DCDC9, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK9_ON_VSEL,
+                       RK806_POWER_EN2, rk806_buck_voltage_ranges, 0,
+                       RK806_BUCK9_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+       RK806_REGULATOR("dcdc-reg10", "vcc10", RK806_ID_DCDC10, rk806_ops_dcdc,
+                       RK806_BUCK_SEL_CNT, RK806_BUCK10_ON_VSEL,
+                       RK806_POWER_EN2, rk806_buck_voltage_ranges, 1,
+                       RK806_BUCK10_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+       RK806_REGULATOR("nldo-reg1", "vcc13", RK806_ID_NLDO1, rk806_ops_nldo,
+                       RK806_LDO_SEL_CNT, RK806_NLDO1_ON_VSEL,
+                       RK806_POWER_EN3, rk806_ldo_voltage_ranges, 0,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+       RK806_REGULATOR("nldo-reg2", "vcc13", RK806_ID_NLDO2, rk806_ops_nldo,
+                       RK806_LDO_SEL_CNT, RK806_NLDO2_ON_VSEL,
+                       RK806_POWER_EN3, rk806_ldo_voltage_ranges, 1,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+       RK806_REGULATOR("nldo-reg3", "vcc13", RK806_ID_NLDO3, rk806_ops_nldo,
+                       RK806_LDO_SEL_CNT, RK806_NLDO3_ON_VSEL,
+                       RK806_POWER_EN3, rk806_ldo_voltage_ranges, 2,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+       RK806_REGULATOR("nldo-reg4", "vcc14", RK806_ID_NLDO4, rk806_ops_nldo,
+                       RK806_LDO_SEL_CNT, RK806_NLDO4_ON_VSEL,
+                       RK806_POWER_EN3, rk806_ldo_voltage_ranges, 3,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+       RK806_REGULATOR("nldo-reg5", "vcc14", RK806_ID_NLDO5, rk806_ops_nldo,
+                       RK806_LDO_SEL_CNT, RK806_NLDO5_ON_VSEL,
+                       RK806_POWER_EN5, rk806_ldo_voltage_ranges, 2,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+       RK806_REGULATOR("pldo-reg1", "vcc11", RK806_ID_PLDO1, rk806_ops_pldo,
+                       RK806_LDO_SEL_CNT, RK806_PLDO1_ON_VSEL,
+                       RK806_POWER_EN4, rk806_ldo_voltage_ranges, 1,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+       RK806_REGULATOR("pldo-reg2", "vcc11", RK806_ID_PLDO2, rk806_ops_pldo,
+                       RK806_LDO_SEL_CNT, RK806_PLDO2_ON_VSEL,
+                       RK806_POWER_EN4, rk806_ldo_voltage_ranges, 2,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+       RK806_REGULATOR("pldo-reg3", "vcc11", RK806_ID_PLDO3, rk806_ops_pldo,
+                       RK806_LDO_SEL_CNT, RK806_PLDO3_ON_VSEL,
+                       RK806_POWER_EN4, rk806_ldo_voltage_ranges, 3,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+       RK806_REGULATOR("pldo-reg4", "vcc12", RK806_ID_PLDO4, rk806_ops_pldo,
+                       RK806_LDO_SEL_CNT, RK806_PLDO4_ON_VSEL,
+                       RK806_POWER_EN5, rk806_ldo_voltage_ranges, 0,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+       RK806_REGULATOR("pldo-reg5", "vcc12", RK806_ID_PLDO5, rk806_ops_pldo,
+                       RK806_LDO_SEL_CNT, RK806_PLDO5_ON_VSEL,
+                       RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+       RK806_REGULATOR("pldo-reg6", "vcca", RK806_ID_PLDO6, rk806_ops_pldo,
+                       RK806_LDO_SEL_CNT, RK806_PLDO6_ON_VSEL,
+                       RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0,
+                       0xEA, 0x38, rk806_ramp_delay_table_ldo),
+};
+
+
 static const struct regulator_desc rk808_reg[] = {
        {
                .name = "DCDC_REG1",
@@ -1245,20 +1625,19 @@ static const struct regulator_desc rk818_reg[] = {
 };
 
 static int rk808_regulator_dt_parse_pdata(struct device *dev,
-                                  struct device *client_dev,
                                   struct regmap *map,
                                   struct rk808_regulator_data *pdata)
 {
        struct device_node *np;
        int tmp, ret = 0, i;
 
-       np = of_get_child_by_name(client_dev->of_node, "regulators");
+       np = of_get_child_by_name(dev->of_node, "regulators");
        if (!np)
                return -ENXIO;
 
        for (i = 0; i < ARRAY_SIZE(pdata->dvs_gpio); i++) {
                pdata->dvs_gpio[i] =
-                       devm_gpiod_get_index_optional(client_dev, "dvs", i,
+                       devm_gpiod_get_index_optional(dev, "dvs", i,
                                                      GPIOD_OUT_LOW);
                if (IS_ERR(pdata->dvs_gpio[i])) {
                        ret = PTR_ERR(pdata->dvs_gpio[i]);
@@ -1292,6 +1671,9 @@ static int rk808_regulator_probe(struct platform_device *pdev)
        struct regmap *regmap;
        int ret, i, nregulators;
 
+       pdev->dev.of_node = pdev->dev.parent->of_node;
+       pdev->dev.of_node_reused = true;
+
        regmap = dev_get_regmap(pdev->dev.parent, NULL);
        if (!regmap)
                return -ENODEV;
@@ -1300,8 +1682,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
        if (!pdata)
                return -ENOMEM;
 
-       ret = rk808_regulator_dt_parse_pdata(&pdev->dev, pdev->dev.parent,
-                                            regmap, pdata);
+       ret = rk808_regulator_dt_parse_pdata(&pdev->dev, regmap, pdata);
        if (ret < 0)
                return ret;
 
@@ -1312,6 +1693,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
                regulators = rk805_reg;
                nregulators = RK805_NUM_REGULATORS;
                break;
+       case RK806_ID:
+               regulators = rk806_reg;
+               nregulators = ARRAY_SIZE(rk806_reg);
+               break;
        case RK808_ID:
                regulators = rk808_reg;
                nregulators = RK808_NUM_REGULATORS;
@@ -1335,7 +1720,6 @@ static int rk808_regulator_probe(struct platform_device *pdev)
        }
 
        config.dev = &pdev->dev;
-       config.dev->of_node = pdev->dev.parent->of_node;
        config.driver_data = pdata;
        config.regmap = regmap;
 
@@ -1355,7 +1739,7 @@ static struct platform_driver rk808_regulator_driver = {
        .probe = rk808_regulator_probe,
        .driver = {
                .name = "rk808-regulator",
-               .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+               .probe_type = PROBE_FORCE_SYNCHRONOUS,
        },
 };
 
@@ -1366,5 +1750,6 @@ MODULE_AUTHOR("Tony xie <tony.xie@rock-chips.com>");
 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:rk808-regulator");
index 9afe961a87f1eb864e83fcc84130721378c627fc..e9719a378a0bc10d9333b8f9674b3496ce2250d5 100644 (file)
@@ -399,7 +399,7 @@ static struct i2c_driver attiny_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(attiny_dt_ids),
        },
-       .probe_new = attiny_i2c_probe,
+       .probe = attiny_i2c_probe,
        .remove = attiny_i2c_remove,
 };
 
index be3dc981195cfb657a897ff29145e405161ecc14..4955bfea4e844ce41dcaaa24a461f1f8bb081a33 100644 (file)
@@ -242,7 +242,7 @@ static struct i2c_driver rt4801_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(rt4801_of_id),
        },
-       .probe_new = rt4801_probe,
+       .probe = rt4801_probe,
 };
 module_i2c_driver(rt4801_driver);
 
index f6c12f87fb8d47103955fb18edcd4160d428170f..a53ed523b5d7d5f02c1d303eaf9ef684af9be514 100644 (file)
@@ -508,7 +508,7 @@ static struct i2c_driver rt5190a_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = rt5190a_device_table,
        },
-       .probe_new = rt5190a_probe,
+       .probe = rt5190a_probe,
 };
 module_i2c_driver(rt5190a_driver);
 
index 74fc5bf6d87e00e831d1c2a4f4e7b70638df5faa..0ce6a1666752cd3a9bf1364703622943bd88445c 100644 (file)
@@ -282,7 +282,7 @@ static struct i2c_driver rt5739_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = rt5739_device_table,
        },
-       .probe_new = rt5739_probe,
+       .probe = rt5739_probe,
 };
 module_i2c_driver(rt5739_driver);
 
index d5a42ad21a9a4797768a3031b68722e0fbc12c02..90555a9ef1b0c2845e1eaf1b3bcf44822880c7fa 100644 (file)
@@ -362,7 +362,7 @@ static struct i2c_driver rt5759_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(rt5759_device_table),
        },
-       .probe_new = rt5759_probe,
+       .probe = rt5759_probe,
 };
 module_i2c_driver(rt5759_driver);
 
index 8990dac234605eb45019510ae53fd1967845b8b1..e2a0eee95c617694d2ea1db2e12c599797285c2e 100644 (file)
@@ -311,7 +311,7 @@ static struct i2c_driver rt6160_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = rt6160_of_match_table,
        },
-       .probe_new = rt6160_probe,
+       .probe = rt6160_probe,
 };
 module_i2c_driver(rt6160_driver);
 
index ca91a1f6d3c817e8b8e84fd345d8560420988136..3883440295edf8acbe91e2b89d77841ad2c2c302 100644 (file)
@@ -487,7 +487,7 @@ static struct i2c_driver rt6190_driver = {
                .of_match_table = rt6190_of_dev_table,
                .pm = pm_ptr(&rt6190_dev_pm),
        },
-       .probe_new = rt6190_probe,
+       .probe = rt6190_probe,
 };
 module_i2c_driver(rt6190_driver);
 
index 8721d11c796422019a9be1e1c6f508e480a63888..1843ecec19229f09951be14d89e5b8b8f71da845 100644 (file)
@@ -246,7 +246,7 @@ static struct i2c_driver rt6245_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = rt6245_of_match_table,
        },
-       .probe_new = rt6245_probe,
+       .probe = rt6245_probe,
 };
 module_i2c_driver(rt6245_driver);
 
index 7cbb812477e181e184f3934342ef404e05d94ff2..dfd1522637e433a301ee80d697d68ccc675326da 100644 (file)
@@ -429,7 +429,7 @@ static struct i2c_driver rtmv20_driver = {
                .of_match_table = of_match_ptr(rtmv20_of_id),
                .pm = &rtmv20_pm,
        },
-       .probe_new = rtmv20_probe,
+       .probe = rtmv20_probe,
 };
 module_i2c_driver(rtmv20_driver);
 
index ee1577dc3cfc0c8dc58932016b402c0914d2aa41..b7372cb2b97d7e1148e158fdbd84ac55764b2a50 100644 (file)
@@ -366,7 +366,7 @@ static struct i2c_driver rtq2134_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = rtq2134_device_tables,
        },
-       .probe_new = rtq2134_probe,
+       .probe = rtq2134_probe,
 };
 module_i2c_driver(rtq2134_driver);
 
index 8559a266a7eb6e96c7fd4879bd176c58d413ec0c..8176e5ab068359d9094a4bcc511e18cd7e6764c1 100644 (file)
@@ -281,7 +281,7 @@ static struct i2c_driver rtq6752_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = rtq6752_device_table,
        },
-       .probe_new = rtq6752_probe,
+       .probe = rtq6752_probe,
 };
 module_i2c_driver(rtq6752_driver);
 
index 559ae031010f23ae75eea00f90f9c142a0251625..59aa16825d8a607fed750e19baa7f5eeb37c7072 100644 (file)
@@ -507,7 +507,7 @@ static struct i2c_driver slg51000_regulator_driver = {
                .name = "slg51000-regulator",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
-       .probe_new = slg51000_i2c_probe,
+       .probe = slg51000_i2c_probe,
        .id_table = slg51000_i2c_id,
 };
 
index 0e101dff6ddadc069d9a0483393899a1bdc06e72..4c60eddad60d0a392804a6d996911f8bf6f66de6 100644 (file)
@@ -93,7 +93,7 @@ static int stm32_pwr_reg_disable(struct regulator_dev *rdev)
        writel_relaxed(val, priv->base + REG_PWR_CR3);
 
        /* use an arbitrary timeout of 20ms */
-       ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, !val,
+       ret = readx_poll_timeout(stm32_pwr_reg_is_enabled, rdev, val, !val,
                                 100, 20 * 1000);
        if (ret)
                dev_err(&rdev->dev, "regulator disable timed out!\n");
index e3c753986309ce729152f633330a2c8c8355a315..1bcfdd6dcfc164d071077bddf03668dabf63b991 100644 (file)
@@ -141,7 +141,7 @@ static struct i2c_driver sy8106a_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = sy8106a_i2c_of_match,
        },
-       .probe_new = sy8106a_i2c_probe,
+       .probe = sy8106a_i2c_probe,
        .id_table = sy8106a_i2c_id,
 };
 
index c327ad69f676b213c719f52ae9c6eacddeb587fb..d0703105c43993b840356fd70b48b26c459c9261 100644 (file)
@@ -236,7 +236,7 @@ static struct i2c_driver sy8824_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = sy8824_dt_ids,
        },
-       .probe_new = sy8824_i2c_probe,
+       .probe = sy8824_i2c_probe,
        .id_table = sy8824_id,
 };
 module_i2c_driver(sy8824_regulator_driver);
index 99ca08cc3a6aef6c6ad9eab1ec13baf08ca9c846..433959b43549137312632793efd784ff08ce1f69 100644 (file)
@@ -190,7 +190,7 @@ static struct i2c_driver sy8827n_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = sy8827n_dt_ids,
        },
-       .probe_new = sy8827n_i2c_probe,
+       .probe = sy8827n_i2c_probe,
        .id_table = sy8827n_id,
 };
 module_i2c_driver(sy8827n_regulator_driver);
index 9bd4e72914ed426d5ccb162e052d04fc58bb10df..d8a856c1587a36aeb147da79e5d6e72d008dff35 100644 (file)
@@ -354,7 +354,7 @@ static struct i2c_driver tps51632_i2c_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(tps51632_of_match),
        },
-       .probe_new = tps51632_probe,
+       .probe = tps51632_probe,
        .id_table = tps51632_id,
 };
 
index 65cc08d1a67d644d34cc0f39d5246995aa9f9a1f..32e1a05a57fd6e1e82e35fd9a43706b432cba4e9 100644 (file)
@@ -491,7 +491,7 @@ static struct i2c_driver tps62360_i2c_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(tps62360_of_match),
        },
-       .probe_new = tps62360_probe,
+       .probe = tps62360_probe,
        .shutdown = tps62360_shutdown,
        .id_table = tps62360_id,
 };
index f92e7649d0a064048aa2605b41a6f9e81f20220e..b1c4b5120745cc74b84c53432c4337a5a6765e39 100644 (file)
@@ -150,7 +150,7 @@ static struct i2c_driver tps6286x_regulator_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(tps6286x_dt_ids),
        },
-       .probe_new = tps6286x_i2c_probe,
+       .probe = tps6286x_i2c_probe,
        .id_table = tps6286x_i2c_id,
 };
 
diff --git a/drivers/regulator/tps6287x-regulator.c b/drivers/regulator/tps6287x-regulator.c
new file mode 100644 (file)
index 0000000..b1c0963
--- /dev/null
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 Axis Communications AB
+ *
+ * Driver for Texas Instruments TPS6287x PMIC.
+ * Datasheet: https://www.ti.com/lit/ds/symlink/tps62873.pdf
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.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>
+#include <linux/regulator/driver.h>
+#include <linux/bitfield.h>
+#include <linux/linear_range.h>
+
+#define TPS6287X_VSET          0x00
+#define TPS6287X_CTRL1         0x01
+#define TPS6287X_CTRL1_VRAMP   GENMASK(1, 0)
+#define TPS6287X_CTRL1_FPWMEN  BIT(4)
+#define TPS6287X_CTRL1_SWEN    BIT(5)
+#define TPS6287X_CTRL2         0x02
+#define TPS6287X_CTRL2_VRANGE  GENMASK(3, 2)
+#define TPS6287X_CTRL3         0x03
+#define TPS6287X_STATUS                0x04
+
+static const struct regmap_config tps6287x_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = TPS6287X_STATUS,
+};
+
+static const struct linear_range tps6287x_voltage_ranges[] = {
+       LINEAR_RANGE(400000, 0, 0xFF, 1250),
+       LINEAR_RANGE(400000, 0, 0xFF, 2500),
+       LINEAR_RANGE(400000, 0, 0xFF, 5000),
+       LINEAR_RANGE(800000, 0, 0xFF, 10000),
+};
+
+static const unsigned int tps6287x_voltage_range_sel[] = {
+       0x0, 0x4, 0x8, 0xC
+};
+
+static const unsigned int tps6287x_ramp_table[] = {
+       10000, 5000, 1250, 500
+};
+
+static int tps6287x_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       unsigned int val;
+
+       switch (mode) {
+       case REGULATOR_MODE_NORMAL:
+               val = 0;
+               break;
+       case REGULATOR_MODE_FAST:
+               val = TPS6287X_CTRL1_FPWMEN;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return regmap_update_bits(rdev->regmap, TPS6287X_CTRL1,
+                                 TPS6287X_CTRL1_FPWMEN, val);
+}
+
+static unsigned int tps6287x_get_mode(struct regulator_dev *rdev)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(rdev->regmap, TPS6287X_CTRL1, &val);
+       if (ret < 0)
+               return 0;
+
+       return (val & TPS6287X_CTRL1_FPWMEN) ? REGULATOR_MODE_FAST :
+           REGULATOR_MODE_NORMAL;
+}
+
+static unsigned int tps6287x_of_map_mode(unsigned int mode)
+{
+       switch (mode) {
+       case REGULATOR_MODE_NORMAL:
+       case REGULATOR_MODE_FAST:
+               return mode;
+       default:
+               return REGULATOR_MODE_INVALID;
+       }
+}
+
+static const struct regulator_ops tps6287x_regulator_ops = {
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .set_mode = tps6287x_set_mode,
+       .get_mode = tps6287x_get_mode,
+       .is_enabled = regulator_is_enabled_regmap,
+       .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
+       .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,
+       .list_voltage = regulator_list_voltage_pickable_linear_range,
+       .set_ramp_delay = regulator_set_ramp_delay_regmap,
+};
+
+static struct regulator_desc tps6287x_reg = {
+       .name = "tps6287x",
+       .owner = THIS_MODULE,
+       .ops = &tps6287x_regulator_ops,
+       .of_map_mode = tps6287x_of_map_mode,
+       .type = REGULATOR_VOLTAGE,
+       .enable_reg = TPS6287X_CTRL1,
+       .enable_mask = TPS6287X_CTRL1_SWEN,
+       .vsel_reg = TPS6287X_VSET,
+       .vsel_mask = 0xFF,
+       .vsel_range_reg = TPS6287X_CTRL2,
+       .vsel_range_mask = TPS6287X_CTRL2_VRANGE,
+       .ramp_reg = TPS6287X_CTRL1,
+       .ramp_mask = TPS6287X_CTRL1_VRAMP,
+       .ramp_delay_table = tps6287x_ramp_table,
+       .n_ramp_values = ARRAY_SIZE(tps6287x_ramp_table),
+       .n_voltages = 256,
+       .linear_ranges = tps6287x_voltage_ranges,
+       .n_linear_ranges = ARRAY_SIZE(tps6287x_voltage_ranges),
+       .linear_range_selectors = tps6287x_voltage_range_sel,
+};
+
+static int tps6287x_i2c_probe(struct i2c_client *i2c)
+{
+       struct device *dev = &i2c->dev;
+       struct regulator_config config = {};
+       struct regulator_dev *rdev;
+
+       config.regmap = devm_regmap_init_i2c(i2c, &tps6287x_regmap_config);
+       if (IS_ERR(config.regmap)) {
+               dev_err(dev, "Failed to init i2c\n");
+               return PTR_ERR(config.regmap);
+       }
+
+       config.dev = dev;
+       config.of_node = dev->of_node;
+       config.init_data = of_get_regulator_init_data(dev, dev->of_node,
+                                                     &tps6287x_reg);
+
+       rdev = devm_regulator_register(dev, &tps6287x_reg, &config);
+       if (IS_ERR(rdev)) {
+               dev_err(dev, "Failed to register regulator\n");
+               return PTR_ERR(rdev);
+       }
+
+       dev_dbg(dev, "Probed regulator\n");
+
+       return 0;
+}
+
+static const struct of_device_id tps6287x_dt_ids[] = {
+       { .compatible = "ti,tps62870", },
+       { .compatible = "ti,tps62871", },
+       { .compatible = "ti,tps62872", },
+       { .compatible = "ti,tps62873", },
+       { }
+};
+
+MODULE_DEVICE_TABLE(of, tps6287x_dt_ids);
+
+static const struct i2c_device_id tps6287x_i2c_id[] = {
+       { "tps62870", 0 },
+       { "tps62871", 0 },
+       { "tps62872", 0 },
+       { "tps62873", 0 },
+       {},
+};
+
+MODULE_DEVICE_TABLE(i2c, tps6287x_i2c_id);
+
+static struct i2c_driver tps6287x_regulator_driver = {
+       .driver = {
+               .name = "tps6287x",
+               .of_match_table = tps6287x_dt_ids,
+       },
+       .probe = tps6287x_i2c_probe,
+       .id_table = tps6287x_i2c_id,
+};
+
+module_i2c_driver(tps6287x_regulator_driver);
+
+MODULE_AUTHOR("MÃ¥rten Lindahl <marten.lindahl@axis.com>");
+MODULE_DESCRIPTION("Regulator driver for TI TPS6287X PMIC");
+MODULE_LICENSE("GPL");
index d87cac63f346a8af13b47c3e18ec005a8c414a06..d5757fd9a65bb1d0ecc1e398482b47288e520263 100644 (file)
@@ -337,7 +337,7 @@ static struct i2c_driver tps_65023_i2c_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = of_match_ptr(tps65023_of_match),
        },
-       .probe_new = tps_65023_probe,
+       .probe = tps_65023_probe,
        .id_table = tps_65023_id,
 };
 
index d4b02ee791d1386d0dce1ac2873e7cf87f28a29c..a06f5f2d79329d615807fcc51064705accfdcc63 100644 (file)
@@ -272,7 +272,7 @@ static struct i2c_driver tps65132_i2c_driver = {
                .name = "tps65132",
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
-       .probe_new = tps65132_probe,
+       .probe = tps65132_probe,
        .id_table = tps65132_id,
 };
 
index b1719ee990ab40b665c87b397fbfe85e14acd04c..8971b507a79ac15b721d237e58dd28a79235ad3f 100644 (file)
@@ -289,13 +289,13 @@ static irqreturn_t tps65219_regulator_irq_handler(int irq, void *data)
 
 static int tps65219_get_rdev_by_name(const char *regulator_name,
                                     struct regulator_dev *rdevtbl[7],
-                                    struct regulator_dev *dev)
+                                    struct regulator_dev **dev)
 {
        int i;
 
        for (i = 0; i < ARRAY_SIZE(regulators); i++) {
                if (strcmp(regulator_name, regulators[i].name) == 0) {
-                       dev = rdevtbl[i];
+                       *dev = rdevtbl[i];
                        return 0;
                }
        }
@@ -348,7 +348,7 @@ static int tps65219_regulator_probe(struct platform_device *pdev)
                irq_data[i].dev = tps->dev;
                irq_data[i].type = irq_type;
 
-               tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, rdev);
+               tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, &rdev);
                if (IS_ERR(rdev)) {
                        dev_err(tps->dev, "Failed to get rdev for %s\n",
                                irq_type->regulator_name);
diff --git a/drivers/regulator/tps6594-regulator.c b/drivers/regulator/tps6594-regulator.c
new file mode 100644 (file)
index 0000000..d5a574e
--- /dev/null
@@ -0,0 +1,615 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Regulator driver for tps6594 PMIC
+//
+// Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.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>
+
+#include <linux/mfd/tps6594.h>
+
+#define BUCK_NB                5
+#define LDO_NB         4
+#define MULTI_PHASE_NB 4
+#define REGS_INT_NB    4
+
+enum tps6594_regulator_id {
+       /* DCDC's */
+       TPS6594_BUCK_1,
+       TPS6594_BUCK_2,
+       TPS6594_BUCK_3,
+       TPS6594_BUCK_4,
+       TPS6594_BUCK_5,
+
+       /* LDOs */
+       TPS6594_LDO_1,
+       TPS6594_LDO_2,
+       TPS6594_LDO_3,
+       TPS6594_LDO_4,
+};
+
+enum tps6594_multi_regulator_id {
+       /* Multi-phase DCDC's */
+       TPS6594_BUCK_12,
+       TPS6594_BUCK_34,
+       TPS6594_BUCK_123,
+       TPS6594_BUCK_1234,
+};
+
+struct tps6594_regulator_irq_type {
+       const char *irq_name;
+       const char *regulator_name;
+       const char *event_name;
+       unsigned long event;
+};
+
+static struct tps6594_regulator_irq_type tps6594_ext_regulator_irq_types[] = {
+       { TPS6594_IRQ_NAME_VCCA_OV, "VCCA", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_VCCA_UV, "VCCA", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_VMON1_OV, "VMON1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_VMON1_UV, "VMON1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_VMON1_RV, "VMON1", "residual voltage",
+         REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_VMON2_OV, "VMON2", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_VMON2_UV, "VMON2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_VMON2_RV, "VMON2", "residual voltage",
+         REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+struct tps6594_regulator_irq_data {
+       struct device *dev;
+       struct tps6594_regulator_irq_type *type;
+       struct regulator_dev *rdev;
+};
+
+struct tps6594_ext_regulator_irq_data {
+       struct device *dev;
+       struct tps6594_regulator_irq_type *type;
+};
+
+#define TPS6594_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \
+                          _em, _cr, _cm, _lr, _nlr, _delay, _fuv, \
+                          _ct, _ncl, _bpm) \
+       {                                                               \
+               .name                   = _name,                        \
+               .of_match               = _of,                          \
+               .regulators_node        = of_match_ptr("regulators"),   \
+               .supply_name            = _of,                          \
+               .id                     = _id,                          \
+               .ops                    = &(_ops),                      \
+               .n_voltages             = _n,                           \
+               .type                   = _type,                        \
+               .owner                  = THIS_MODULE,                  \
+               .vsel_reg               = _vr,                          \
+               .vsel_mask              = _vm,                          \
+               .csel_reg               = _cr,                          \
+               .csel_mask              = _cm,                          \
+               .curr_table             = _ct,                          \
+               .n_current_limits       = _ncl,                         \
+               .enable_reg             = _er,                          \
+               .enable_mask            = _em,                          \
+               .volt_table             = NULL,                         \
+               .linear_ranges          = _lr,                          \
+               .n_linear_ranges        = _nlr,                         \
+               .ramp_delay             = _delay,                       \
+               .fixed_uV               = _fuv,                         \
+               .bypass_reg             = _vr,                          \
+               .bypass_mask            = _bpm,                         \
+       }                                                               \
+
+static const struct linear_range bucks_ranges[] = {
+       REGULATOR_LINEAR_RANGE(300000, 0x0, 0xe, 20000),
+       REGULATOR_LINEAR_RANGE(600000, 0xf, 0x72, 5000),
+       REGULATOR_LINEAR_RANGE(1100000, 0x73, 0xaa, 10000),
+       REGULATOR_LINEAR_RANGE(1660000, 0xab, 0xff, 20000),
+};
+
+static const struct linear_range ldos_1_2_3_ranges[] = {
+       REGULATOR_LINEAR_RANGE(600000, 0x4, 0x3a, 50000),
+};
+
+static const struct linear_range ldos_4_ranges[] = {
+       REGULATOR_LINEAR_RANGE(1200000, 0x20, 0x74, 25000),
+};
+
+/* Operations permitted on BUCK1/2/3/4/5 */
+static const struct regulator_ops tps6594_bucks_ops = {
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .list_voltage           = regulator_list_voltage_linear_range,
+       .map_voltage            = regulator_map_voltage_linear_range,
+       .set_voltage_time_sel   = regulator_set_voltage_time_sel,
+
+};
+
+/* Operations permitted on LDO1/2/3 */
+static const struct regulator_ops tps6594_ldos_1_2_3_ops = {
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .list_voltage           = regulator_list_voltage_linear_range,
+       .map_voltage            = regulator_map_voltage_linear_range,
+       .set_bypass             = regulator_set_bypass_regmap,
+       .get_bypass             = regulator_get_bypass_regmap,
+};
+
+/* Operations permitted on LDO4 */
+static const struct regulator_ops tps6594_ldos_4_ops = {
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .list_voltage           = regulator_list_voltage_linear_range,
+       .map_voltage            = regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_desc buck_regs[] = {
+       TPS6594_REGULATOR("BUCK1", "buck1", TPS6594_BUCK_1,
+                         REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_VOUT_1(0),
+                         TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_CTRL(0),
+                         TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
+                         4, 0, 0, NULL, 0, 0),
+       TPS6594_REGULATOR("BUCK2", "buck2", TPS6594_BUCK_2,
+                         REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_VOUT_1(1),
+                         TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_CTRL(1),
+                         TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
+                         4, 0, 0, NULL, 0, 0),
+       TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,
+                         REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_VOUT_1(2),
+                         TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_CTRL(2),
+                         TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
+                         4, 0, 0, NULL, 0, 0),
+       TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,
+                         REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_VOUT_1(3),
+                         TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_CTRL(3),
+                         TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
+                         4, 0, 0, NULL, 0, 0),
+       TPS6594_REGULATOR("BUCK5", "buck5", TPS6594_BUCK_5,
+                         REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_VOUT_1(4),
+                         TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_CTRL(4),
+                         TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
+                         4, 0, 0, NULL, 0, 0),
+};
+
+static struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = {
+       { TPS6594_IRQ_NAME_BUCK1_OV, "BUCK1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_BUCK1_UV, "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_BUCK1_SC, "BUCK1", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
+       { TPS6594_IRQ_NAME_BUCK1_ILIM, "BUCK1", "reach ilim, overcurrent",
+         REGULATOR_EVENT_OVER_CURRENT },
+};
+
+static struct tps6594_regulator_irq_type tps6594_buck2_irq_types[] = {
+       { TPS6594_IRQ_NAME_BUCK2_OV, "BUCK2", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_BUCK2_UV, "BUCK2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_BUCK2_SC, "BUCK2", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
+       { TPS6594_IRQ_NAME_BUCK2_ILIM, "BUCK2", "reach ilim, overcurrent",
+         REGULATOR_EVENT_OVER_CURRENT },
+};
+
+static struct tps6594_regulator_irq_type tps6594_buck3_irq_types[] = {
+       { TPS6594_IRQ_NAME_BUCK3_OV, "BUCK3", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_BUCK3_UV, "BUCK3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_BUCK3_SC, "BUCK3", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
+       { TPS6594_IRQ_NAME_BUCK3_ILIM, "BUCK3", "reach ilim, overcurrent",
+         REGULATOR_EVENT_OVER_CURRENT },
+};
+
+static struct tps6594_regulator_irq_type tps6594_buck4_irq_types[] = {
+       { TPS6594_IRQ_NAME_BUCK4_OV, "BUCK4", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_BUCK4_UV, "BUCK4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_BUCK4_SC, "BUCK4", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
+       { TPS6594_IRQ_NAME_BUCK4_ILIM, "BUCK4", "reach ilim, overcurrent",
+         REGULATOR_EVENT_OVER_CURRENT },
+};
+
+static struct tps6594_regulator_irq_type tps6594_buck5_irq_types[] = {
+       { TPS6594_IRQ_NAME_BUCK5_OV, "BUCK5", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_BUCK5_UV, "BUCK5", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_BUCK5_SC, "BUCK5", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
+       { TPS6594_IRQ_NAME_BUCK5_ILIM, "BUCK5", "reach ilim, overcurrent",
+         REGULATOR_EVENT_OVER_CURRENT },
+};
+
+static struct tps6594_regulator_irq_type tps6594_ldo1_irq_types[] = {
+       { TPS6594_IRQ_NAME_LDO1_OV, "LDO1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_LDO1_UV, "LDO1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_LDO1_SC, "LDO1", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
+       { TPS6594_IRQ_NAME_LDO1_ILIM, "LDO1", "reach ilim, overcurrent",
+         REGULATOR_EVENT_OVER_CURRENT },
+};
+
+static struct tps6594_regulator_irq_type tps6594_ldo2_irq_types[] = {
+       { TPS6594_IRQ_NAME_LDO2_OV, "LDO2", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_LDO2_UV, "LDO2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_LDO2_SC, "LDO2", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
+       { TPS6594_IRQ_NAME_LDO2_ILIM, "LDO2", "reach ilim, overcurrent",
+         REGULATOR_EVENT_OVER_CURRENT },
+};
+
+static struct tps6594_regulator_irq_type tps6594_ldo3_irq_types[] = {
+       { TPS6594_IRQ_NAME_LDO3_OV, "LDO3", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_LDO3_UV, "LDO3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_LDO3_SC, "LDO3", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
+       { TPS6594_IRQ_NAME_LDO3_ILIM, "LDO3", "reach ilim, overcurrent",
+         REGULATOR_EVENT_OVER_CURRENT },
+};
+
+static struct tps6594_regulator_irq_type tps6594_ldo4_irq_types[] = {
+       { TPS6594_IRQ_NAME_LDO4_OV, "LDO4", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+       { TPS6594_IRQ_NAME_LDO4_UV, "LDO4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+       { TPS6594_IRQ_NAME_LDO4_SC, "LDO4", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
+       { TPS6594_IRQ_NAME_LDO4_ILIM, "LDO4", "reach ilim, overcurrent",
+         REGULATOR_EVENT_OVER_CURRENT },
+};
+
+static struct tps6594_regulator_irq_type *tps6594_bucks_irq_types[] = {
+       tps6594_buck1_irq_types,
+       tps6594_buck2_irq_types,
+       tps6594_buck3_irq_types,
+       tps6594_buck4_irq_types,
+       tps6594_buck5_irq_types,
+};
+
+static struct tps6594_regulator_irq_type *tps6594_ldos_irq_types[] = {
+       tps6594_ldo1_irq_types,
+       tps6594_ldo2_irq_types,
+       tps6594_ldo3_irq_types,
+       tps6594_ldo4_irq_types,
+};
+
+static const struct regulator_desc multi_regs[] = {
+       TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
+                         REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_VOUT_1(1),
+                         TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_CTRL(1),
+                         TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
+                         4, 4000, 0, NULL, 0, 0),
+       TPS6594_REGULATOR("BUCK34", "buck34", TPS6594_BUCK_3,
+                         REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_VOUT_1(3),
+                         TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_CTRL(3),
+                         TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
+                         4, 0, 0, NULL, 0, 0),
+       TPS6594_REGULATOR("BUCK123", "buck123", TPS6594_BUCK_1,
+                         REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_VOUT_1(1),
+                         TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_CTRL(1),
+                         TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
+                         4, 4000, 0, NULL, 0, 0),
+       TPS6594_REGULATOR("BUCK1234", "buck1234", TPS6594_BUCK_1,
+                         REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_VOUT_1(1),
+                         TPS6594_MASK_BUCKS_VSET,
+                         TPS6594_REG_BUCKX_CTRL(1),
+                         TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
+                         4, 4000, 0, NULL, 0, 0),
+};
+
+static const struct regulator_desc ldo_regs[] = {
+       TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
+                         REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+                         TPS6594_REG_LDOX_VOUT(0),
+                         TPS6594_MASK_LDO123_VSET,
+                         TPS6594_REG_LDOX_CTRL(0),
+                         TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,
+                         1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+       TPS6594_REGULATOR("LDO2", "ldo2", TPS6594_LDO_2,
+                         REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+                         TPS6594_REG_LDOX_VOUT(1),
+                         TPS6594_MASK_LDO123_VSET,
+                         TPS6594_REG_LDOX_CTRL(1),
+                         TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,
+                         1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+       TPS6594_REGULATOR("LDO3", "ldo3", TPS6594_LDO_3,
+                         REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+                         TPS6594_REG_LDOX_VOUT(2),
+                         TPS6594_MASK_LDO123_VSET,
+                         TPS6594_REG_LDOX_CTRL(2),
+                         TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,
+                         1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+       TPS6594_REGULATOR("LDO4", "ldo4", TPS6594_LDO_4,
+                         REGULATOR_VOLTAGE, tps6594_ldos_4_ops, TPS6594_MASK_LDO4_VSET >> 1,
+                         TPS6594_REG_LDOX_VOUT(3),
+                         TPS6594_MASK_LDO4_VSET,
+                         TPS6594_REG_LDOX_CTRL(3),
+                         TPS6594_BIT_LDO_EN, 0, 0, ldos_4_ranges,
+                         1, 0, 0, NULL, 0, 0),
+};
+
+static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data)
+{
+       struct tps6594_regulator_irq_data *irq_data = data;
+
+       if (irq_data->type->event_name[0] == '\0') {
+               /* This is the timeout interrupt no specific regulator */
+               dev_err(irq_data->dev,
+                       "System was put in shutdown due to timeout during an active or standby transition.\n");
+               return IRQ_HANDLED;
+       }
+
+       dev_err(irq_data->dev, "Error IRQ trap %s for %s\n",
+               irq_data->type->event_name, irq_data->type->regulator_name);
+
+       regulator_notifier_call_chain(irq_data->rdev,
+                                     irq_data->type->event, NULL);
+
+       return IRQ_HANDLED;
+}
+
+static int tps6594_request_reg_irqs(struct platform_device *pdev,
+                                   struct regulator_dev *rdev,
+                                   struct tps6594_regulator_irq_data *irq_data,
+                                   struct tps6594_regulator_irq_type *tps6594_regs_irq_types,
+                                   int *irq_idx)
+{
+       struct tps6594_regulator_irq_type *irq_type;
+       struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
+       int j;
+       int irq;
+       int error;
+
+       for (j = 0; j < REGS_INT_NB; j++) {
+               irq_type = &tps6594_regs_irq_types[j];
+               irq = platform_get_irq_byname(pdev, irq_type->irq_name);
+               if (irq < 0)
+                       return -EINVAL;
+
+               irq_data[*irq_idx + j].dev = tps->dev;
+               irq_data[*irq_idx + j].type = irq_type;
+               irq_data[*irq_idx + j].rdev = rdev;
+
+               error = devm_request_threaded_irq(tps->dev, irq, NULL,
+                                                 tps6594_regulator_irq_handler,
+                                                 IRQF_ONESHOT,
+                                                 irq_type->irq_name,
+                                                 &irq_data[*irq_idx]);
+               (*irq_idx)++;
+               if (error) {
+                       dev_err(tps->dev, "tps6594 failed to request %s IRQ %d: %d\n",
+                               irq_type->irq_name, irq, error);
+                       return error;
+               }
+       }
+       return 0;
+}
+
+static int tps6594_regulator_probe(struct platform_device *pdev)
+{
+       struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
+       struct regulator_dev *rdev;
+       struct device_node *np = NULL;
+       struct device_node *np_pmic_parent = NULL;
+       struct regulator_config config = {};
+       struct tps6594_regulator_irq_data *irq_data;
+       struct tps6594_ext_regulator_irq_data *irq_ext_reg_data;
+       struct tps6594_regulator_irq_type *irq_type;
+       u8 buck_configured[BUCK_NB] = { 0 };
+       u8 buck_multi[MULTI_PHASE_NB] = { 0 };
+       static const char * const multiphases[] = {"buck12", "buck123", "buck1234", "buck34"};
+       static const char *npname;
+       int error, i, irq, multi, delta;
+       int irq_idx = 0;
+       int buck_idx = 0;
+       int ext_reg_irq_nb = 2;
+
+       enum {
+               MULTI_BUCK12,
+               MULTI_BUCK123,
+               MULTI_BUCK1234,
+               MULTI_BUCK12_34,
+               MULTI_FIRST = MULTI_BUCK12,
+               MULTI_LAST = MULTI_BUCK12_34,
+               MULTI_NUM = MULTI_LAST - MULTI_FIRST + 1
+       };
+
+       config.dev = tps->dev;
+       config.driver_data = tps;
+       config.regmap = tps->regmap;
+
+       /*
+        * Switch case defines different possible multi phase config
+        * This is based on dts buck node name.
+        * Buck node name must be chosen accordingly.
+        * Default case is no Multiphase buck.
+        * In case of Multiphase configuration, value should be defined for
+        * buck_configured to avoid creating bucks for every buck in multiphase
+        */
+       for (multi = MULTI_FIRST; multi < MULTI_NUM; multi++) {
+               np = of_find_node_by_name(tps->dev->of_node, multiphases[multi]);
+               npname = of_node_full_name(np);
+               np_pmic_parent = of_get_parent(of_get_parent(np));
+               if (of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name))
+                       continue;
+               delta = strcmp(npname, multiphases[multi]);
+               if (!delta) {
+                       switch (multi) {
+                       case MULTI_BUCK12:
+                               buck_multi[0] = 1;
+                               buck_configured[0] = 1;
+                               buck_configured[1] = 1;
+                               break;
+                       /* multiphase buck34 is supported only with buck12 */
+                       case MULTI_BUCK12_34:
+                               buck_multi[0] = 1;
+                               buck_multi[1] = 1;
+                               buck_configured[0] = 1;
+                               buck_configured[1] = 1;
+                               buck_configured[2] = 1;
+                               buck_configured[3] = 1;
+                               break;
+                       case MULTI_BUCK123:
+                               buck_multi[2] = 1;
+                               buck_configured[0] = 1;
+                               buck_configured[1] = 1;
+                               buck_configured[2] = 1;
+                               break;
+                       case MULTI_BUCK1234:
+                               buck_multi[3] = 1;
+                               buck_configured[0] = 1;
+                               buck_configured[1] = 1;
+                               buck_configured[2] = 1;
+                               buck_configured[3] = 1;
+                               break;
+                       }
+               }
+       }
+
+       if (tps->chip_id == LP8764)
+               /* There is only 4 buck on LP8764 */
+               buck_configured[4] = 1;
+
+       irq_data = devm_kmalloc_array(tps->dev,
+                               REGS_INT_NB * sizeof(struct tps6594_regulator_irq_data),
+                               ARRAY_SIZE(tps6594_bucks_irq_types) +
+                               ARRAY_SIZE(tps6594_ldos_irq_types),
+                               GFP_KERNEL);
+       if (!irq_data)
+               return -ENOMEM;
+
+       for (i = 0; i < MULTI_PHASE_NB; i++) {
+               if (buck_multi[i] == 0)
+                       continue;
+
+               rdev = devm_regulator_register(&pdev->dev, &multi_regs[i], &config);
+               if (IS_ERR(rdev))
+                       return dev_err_probe(tps->dev, PTR_ERR(rdev),
+                                            "failed to register %s regulator\n",
+                                            pdev->name);
+
+               /* config multiphase buck12+buck34 */
+               if (i == 1)
+                       buck_idx = 2;
+               error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
+                                                tps6594_bucks_irq_types[buck_idx], &irq_idx);
+               if (error)
+                       return error;
+               error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
+                                                tps6594_bucks_irq_types[buck_idx + 1], &irq_idx);
+               if (error)
+                       return error;
+
+               if (i == 2 || i == 3) {
+                       error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
+                                                        tps6594_bucks_irq_types[buck_idx + 2],
+                                                        &irq_idx);
+                       if (error)
+                               return error;
+               }
+               if (i == 3) {
+                       error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
+                                                        tps6594_bucks_irq_types[buck_idx + 3],
+                                                        &irq_idx);
+                       if (error)
+                               return error;
+               }
+       }
+
+       for (i = 0; i < BUCK_NB; i++) {
+               if (buck_configured[i] == 1)
+                       continue;
+
+               rdev = devm_regulator_register(&pdev->dev, &buck_regs[i], &config);
+               if (IS_ERR(rdev))
+                       return dev_err_probe(tps->dev, PTR_ERR(rdev),
+                                            "failed to register %s regulator\n",
+                                            pdev->name);
+
+               error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
+                                                tps6594_bucks_irq_types[i], &irq_idx);
+               if (error)
+                       return error;
+       }
+
+       /* LP8764 dosen't have LDO */
+       if (tps->chip_id != LP8764) {
+               for (i = 0; i < ARRAY_SIZE(ldo_regs); i++) {
+                       rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config);
+                       if (IS_ERR(rdev))
+                               return dev_err_probe(tps->dev, PTR_ERR(rdev),
+                                                    "failed to register %s regulator\n",
+                                                    pdev->name);
+
+                       error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
+                                                        tps6594_ldos_irq_types[i],
+                                                        &irq_idx);
+                       if (error)
+                               return error;
+               }
+       }
+
+       if (tps->chip_id == LP8764)
+               ext_reg_irq_nb = ARRAY_SIZE(tps6594_ext_regulator_irq_types);
+
+       irq_ext_reg_data = devm_kmalloc_array(tps->dev,
+                                       ext_reg_irq_nb,
+                                       sizeof(struct tps6594_ext_regulator_irq_data),
+                                       GFP_KERNEL);
+       if (!irq_ext_reg_data)
+               return -ENOMEM;
+
+       for (i = 0; i < ext_reg_irq_nb; ++i) {
+               irq_type = &tps6594_ext_regulator_irq_types[i];
+
+               irq = platform_get_irq_byname(pdev, irq_type->irq_name);
+               if (irq < 0)
+                       return -EINVAL;
+
+               irq_ext_reg_data[i].dev = tps->dev;
+               irq_ext_reg_data[i].type = irq_type;
+
+               error = devm_request_threaded_irq(tps->dev, irq, NULL,
+                                                 tps6594_regulator_irq_handler,
+                                                 IRQF_ONESHOT,
+                                                 irq_type->irq_name,
+                                                 &irq_ext_reg_data[i]);
+               if (error)
+                       return dev_err_probe(tps->dev, error,
+                                            "failed to request %s IRQ %d\n",
+                                            irq_type->irq_name, irq);
+       }
+       return 0;
+}
+
+static struct platform_driver tps6594_regulator_driver = {
+       .driver = {
+               .name = "tps6594-regulator",
+       },
+       .probe = tps6594_regulator_probe,
+};
+
+module_platform_driver(tps6594_regulator_driver);
+
+MODULE_ALIAS("platform:tps6594-regulator");
+MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
+MODULE_DESCRIPTION("TPS6594 voltage regulator driver");
+MODULE_LICENSE("GPL");
index 75387240861564405577aaf05c9150ef6aa91e54..ffca9a8bb878f221d513d8be02c063e0c8dc489f 100644 (file)
@@ -395,7 +395,7 @@ config RTC_DRV_NCT3018Y
 
 config RTC_DRV_RK808
        tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
-       depends on MFD_RK808
+       depends on MFD_RK8XX
        help
          If you say yes here you will get support for the
          RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
index 795a2e1d59b3abc47b9a9a9f9130e607fb00666f..dd50a255fa6cbc86d789d6977529c0e22d06faf8 100644 (file)
@@ -682,6 +682,30 @@ EXPORT_SYMBOL(geni_se_clk_freq_match);
 #define GENI_SE_DMA_EOT_EN BIT(1)
 #define GENI_SE_DMA_AHB_ERR_EN BIT(2)
 #define GENI_SE_DMA_EOT_BUF BIT(0)
+
+/**
+ * geni_se_tx_init_dma() - Initiate TX DMA transfer on the serial engine
+ * @se:                        Pointer to the concerned serial engine.
+ * @iova:              Mapped DMA address.
+ * @len:               Length of the TX buffer.
+ *
+ * This function is used to initiate DMA TX transfer.
+ */
+void geni_se_tx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len)
+{
+       u32 val;
+
+       val = GENI_SE_DMA_DONE_EN;
+       val |= GENI_SE_DMA_EOT_EN;
+       val |= GENI_SE_DMA_AHB_ERR_EN;
+       writel_relaxed(val, se->base + SE_DMA_TX_IRQ_EN_SET);
+       writel_relaxed(lower_32_bits(iova), se->base + SE_DMA_TX_PTR_L);
+       writel_relaxed(upper_32_bits(iova), se->base + SE_DMA_TX_PTR_H);
+       writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
+       writel(len, se->base + SE_DMA_TX_LEN);
+}
+EXPORT_SYMBOL(geni_se_tx_init_dma);
+
 /**
  * geni_se_tx_dma_prep() - Prepare the serial engine for TX DMA transfer
  * @se:                        Pointer to the concerned serial engine.
@@ -697,7 +721,6 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
                        dma_addr_t *iova)
 {
        struct geni_wrapper *wrapper = se->wrapper;
-       u32 val;
 
        if (!wrapper)
                return -EINVAL;
@@ -706,17 +729,34 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
        if (dma_mapping_error(wrapper->dev, *iova))
                return -EIO;
 
+       geni_se_tx_init_dma(se, *iova, len);
+       return 0;
+}
+EXPORT_SYMBOL(geni_se_tx_dma_prep);
+
+/**
+ * geni_se_rx_init_dma() - Initiate RX DMA transfer on the serial engine
+ * @se:                        Pointer to the concerned serial engine.
+ * @iova:              Mapped DMA address.
+ * @len:               Length of the RX buffer.
+ *
+ * This function is used to initiate DMA RX transfer.
+ */
+void geni_se_rx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len)
+{
+       u32 val;
+
        val = GENI_SE_DMA_DONE_EN;
        val |= GENI_SE_DMA_EOT_EN;
        val |= GENI_SE_DMA_AHB_ERR_EN;
-       writel_relaxed(val, se->base + SE_DMA_TX_IRQ_EN_SET);
-       writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_TX_PTR_L);
-       writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_TX_PTR_H);
-       writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
-       writel(len, se->base + SE_DMA_TX_LEN);
-       return 0;
+       writel_relaxed(val, se->base + SE_DMA_RX_IRQ_EN_SET);
+       writel_relaxed(lower_32_bits(iova), se->base + SE_DMA_RX_PTR_L);
+       writel_relaxed(upper_32_bits(iova), se->base + SE_DMA_RX_PTR_H);
+       /* RX does not have EOT buffer type bit. So just reset RX_ATTR */
+       writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
+       writel(len, se->base + SE_DMA_RX_LEN);
 }
-EXPORT_SYMBOL(geni_se_tx_dma_prep);
+EXPORT_SYMBOL(geni_se_rx_init_dma);
 
 /**
  * geni_se_rx_dma_prep() - Prepare the serial engine for RX DMA transfer
@@ -733,7 +773,6 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
                        dma_addr_t *iova)
 {
        struct geni_wrapper *wrapper = se->wrapper;
-       u32 val;
 
        if (!wrapper)
                return -EINVAL;
@@ -742,15 +781,7 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
        if (dma_mapping_error(wrapper->dev, *iova))
                return -EIO;
 
-       val = GENI_SE_DMA_DONE_EN;
-       val |= GENI_SE_DMA_EOT_EN;
-       val |= GENI_SE_DMA_AHB_ERR_EN;
-       writel_relaxed(val, se->base + SE_DMA_RX_IRQ_EN_SET);
-       writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_RX_PTR_L);
-       writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_RX_PTR_H);
-       /* RX does not have EOT buffer type bit. So just reset RX_ATTR */
-       writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
-       writel(len, se->base + SE_DMA_RX_LEN);
+       geni_se_rx_init_dma(se, *iova, len);
        return 0;
 }
 EXPORT_SYMBOL(geni_se_rx_dma_prep);
index b293428760bc6479025b8821b57628a6992a8d95..135cdf394b760ed5bdd39d2481f57532239e121f 100644 (file)
@@ -97,8 +97,6 @@ struct spi_geni_master {
        struct dma_chan *tx;
        struct dma_chan *rx;
        int cur_xfer_mode;
-       dma_addr_t tx_se_dma;
-       dma_addr_t rx_se_dma;
 };
 
 static int get_spi_clk_cfg(unsigned int speed_hz,
@@ -174,7 +172,7 @@ static void handle_se_timeout(struct spi_master *spi,
 unmap_if_dma:
        if (mas->cur_xfer_mode == GENI_SE_DMA) {
                if (xfer) {
-                       if (xfer->tx_buf && mas->tx_se_dma) {
+                       if (xfer->tx_buf) {
                                spin_lock_irq(&mas->lock);
                                reinit_completion(&mas->tx_reset_done);
                                writel(1, se->base + SE_DMA_TX_FSM_RST);
@@ -182,9 +180,8 @@ unmap_if_dma:
                                time_left = wait_for_completion_timeout(&mas->tx_reset_done, HZ);
                                if (!time_left)
                                        dev_err(mas->dev, "DMA TX RESET failed\n");
-                               geni_se_tx_dma_unprep(se, mas->tx_se_dma, xfer->len);
                        }
-                       if (xfer->rx_buf && mas->rx_se_dma) {
+                       if (xfer->rx_buf) {
                                spin_lock_irq(&mas->lock);
                                reinit_completion(&mas->rx_reset_done);
                                writel(1, se->base + SE_DMA_RX_FSM_RST);
@@ -192,7 +189,6 @@ unmap_if_dma:
                                time_left = wait_for_completion_timeout(&mas->rx_reset_done, HZ);
                                if (!time_left)
                                        dev_err(mas->dev, "DMA RX RESET failed\n");
-                               geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len);
                        }
                } else {
                        /*
@@ -523,17 +519,36 @@ static int setup_gsi_xfer(struct spi_transfer *xfer, struct spi_geni_master *mas
        return 1;
 }
 
+static u32 get_xfer_len_in_words(struct spi_transfer *xfer,
+                               struct spi_geni_master *mas)
+{
+       u32 len;
+
+       if (!(mas->cur_bits_per_word % MIN_WORD_LEN))
+               len = xfer->len * BITS_PER_BYTE / mas->cur_bits_per_word;
+       else
+               len = xfer->len / (mas->cur_bits_per_word / BITS_PER_BYTE + 1);
+       len &= TRANS_LEN_MSK;
+
+       return len;
+}
+
 static bool geni_can_dma(struct spi_controller *ctlr,
                         struct spi_device *slv, struct spi_transfer *xfer)
 {
        struct spi_geni_master *mas = spi_master_get_devdata(slv->master);
+       u32 len, fifo_size;
 
-       /*
-        * Return true if transfer needs to be mapped prior to
-        * calling transfer_one which is the case only for GPI_DMA.
-        * For SE_DMA mode, map/unmap is done in geni_se_*x_dma_prep.
-        */
-       return mas->cur_xfer_mode == GENI_GPI_DMA;
+       if (mas->cur_xfer_mode == GENI_GPI_DMA)
+               return true;
+
+       len = get_xfer_len_in_words(xfer, mas);
+       fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits / mas->cur_bits_per_word;
+
+       if (len > fifo_size)
+               return true;
+       else
+               return false;
 }
 
 static int spi_geni_prepare_message(struct spi_master *spi,
@@ -774,7 +789,7 @@ static int setup_se_xfer(struct spi_transfer *xfer,
                                u16 mode, struct spi_master *spi)
 {
        u32 m_cmd = 0;
-       u32 len, fifo_size;
+       u32 len;
        struct geni_se *se = &mas->se;
        int ret;
 
@@ -806,11 +821,7 @@ static int setup_se_xfer(struct spi_transfer *xfer,
        mas->tx_rem_bytes = 0;
        mas->rx_rem_bytes = 0;
 
-       if (!(mas->cur_bits_per_word % MIN_WORD_LEN))
-               len = xfer->len * BITS_PER_BYTE / mas->cur_bits_per_word;
-       else
-               len = xfer->len / (mas->cur_bits_per_word / BITS_PER_BYTE + 1);
-       len &= TRANS_LEN_MSK;
+       len = get_xfer_len_in_words(xfer, mas);
 
        mas->cur_xfer = xfer;
        if (xfer->tx_buf) {
@@ -825,9 +836,20 @@ static int setup_se_xfer(struct spi_transfer *xfer,
                mas->rx_rem_bytes = xfer->len;
        }
 
-       /* Select transfer mode based on transfer length */
-       fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits / mas->cur_bits_per_word;
-       mas->cur_xfer_mode = (len <= fifo_size) ? GENI_SE_FIFO : GENI_SE_DMA;
+       /*
+        * Select DMA mode if sgt are present; and with only 1 entry
+        * This is not a serious limitation because the xfer buffers are
+        * expected to fit into in 1 entry almost always, and if any
+        * doesn't for any reason we fall back to FIFO mode anyway
+        */
+       if (!xfer->tx_sg.nents && !xfer->rx_sg.nents)
+               mas->cur_xfer_mode = GENI_SE_FIFO;
+       else if (xfer->tx_sg.nents > 1 || xfer->rx_sg.nents > 1) {
+               dev_warn_once(mas->dev, "Doing FIFO, cannot handle tx_nents-%d, rx_nents-%d\n",
+                       xfer->tx_sg.nents, xfer->rx_sg.nents);
+               mas->cur_xfer_mode = GENI_SE_FIFO;
+       } else
+               mas->cur_xfer_mode = GENI_SE_DMA;
        geni_se_select_mode(se, mas->cur_xfer_mode);
 
        /*
@@ -838,35 +860,17 @@ static int setup_se_xfer(struct spi_transfer *xfer,
        geni_se_setup_m_cmd(se, m_cmd, FRAGMENTATION);
 
        if (mas->cur_xfer_mode == GENI_SE_DMA) {
-               if (m_cmd & SPI_RX_ONLY) {
-                       ret =  geni_se_rx_dma_prep(se, xfer->rx_buf,
-                               xfer->len, &mas->rx_se_dma);
-                       if (ret) {
-                               dev_err(mas->dev, "Failed to setup Rx dma %d\n", ret);
-                               mas->rx_se_dma = 0;
-                               goto unlock_and_return;
-                       }
-               }
-               if (m_cmd & SPI_TX_ONLY) {
-                       ret =  geni_se_tx_dma_prep(se, (void *)xfer->tx_buf,
-                               xfer->len, &mas->tx_se_dma);
-                       if (ret) {
-                               dev_err(mas->dev, "Failed to setup Tx dma %d\n", ret);
-                               mas->tx_se_dma = 0;
-                               if (m_cmd & SPI_RX_ONLY) {
-                                       /* Unmap rx buffer if duplex transfer */
-                                       geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len);
-                                       mas->rx_se_dma = 0;
-                               }
-                               goto unlock_and_return;
-                       }
-               }
+               if (m_cmd & SPI_RX_ONLY)
+                       geni_se_rx_init_dma(se, sg_dma_address(xfer->rx_sg.sgl),
+                               sg_dma_len(xfer->rx_sg.sgl));
+               if (m_cmd & SPI_TX_ONLY)
+                       geni_se_tx_init_dma(se, sg_dma_address(xfer->tx_sg.sgl),
+                               sg_dma_len(xfer->tx_sg.sgl));
        } else if (m_cmd & SPI_TX_ONLY) {
                if (geni_spi_handle_tx(mas))
                        writel(mas->tx_wm, se->base + SE_GENI_TX_WATERMARK_REG);
        }
 
-unlock_and_return:
        spin_unlock_irq(&mas->lock);
        return ret;
 }
@@ -967,14 +971,6 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
                if (dma_rx_status & RX_RESET_DONE)
                        complete(&mas->rx_reset_done);
                if (!mas->tx_rem_bytes && !mas->rx_rem_bytes && xfer) {
-                       if (xfer->tx_buf && mas->tx_se_dma) {
-                               geni_se_tx_dma_unprep(se, mas->tx_se_dma, xfer->len);
-                               mas->tx_se_dma = 0;
-                       }
-                       if (xfer->rx_buf && mas->rx_se_dma) {
-                               geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len);
-                               mas->rx_se_dma = 0;
-                       }
                        spi_finalize_current_transfer(spi);
                        mas->cur_xfer = NULL;
                }
@@ -1059,6 +1055,7 @@ static int spi_geni_probe(struct platform_device *pdev)
        spi->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
        spi->num_chipselect = 4;
        spi->max_speed_hz = 50000000;
+       spi->max_dma_len = 0xffff0; /* 24 bits for tx/rx dma length */
        spi->prepare_message = spi_geni_prepare_message;
        spi->transfer_one = spi_geni_transfer_one;
        spi->can_dma = geni_can_dma;
index beb3f44f85c50cfca5dbeb1a3e5743f81da5485e..fff7fa6b7c5dc659782b33cf5869ece683fbc1b9 100644 (file)
@@ -17,6 +17,7 @@ enum axp20x_variants {
        AXP221_ID,
        AXP223_ID,
        AXP288_ID,
+       AXP313A_ID,
        AXP803_ID,
        AXP806_ID,
        AXP809_ID,
@@ -92,6 +93,17 @@ enum axp20x_variants {
 #define AXP22X_ALDO3_V_OUT             0x2a
 #define AXP22X_CHRG_CTRL3              0x35
 
+#define AXP313A_ON_INDICATE            0x00
+#define AXP313A_OUTPUT_CONTROL         0x10
+#define AXP313A_DCDC1_CONRTOL          0x13
+#define AXP313A_DCDC2_CONRTOL          0x14
+#define AXP313A_DCDC3_CONRTOL          0x15
+#define AXP313A_ALDO1_CONRTOL          0x16
+#define AXP313A_DLDO1_CONRTOL          0x17
+#define AXP313A_SHUTDOWN_CTRL          0x1a
+#define AXP313A_IRQ_EN                 0x20
+#define AXP313A_IRQ_STATE              0x21
+
 #define AXP806_STARTUP_SRC             0x00
 #define AXP806_CHIP_ID                 0x03
 #define AXP806_PWR_OUT_CTRL1           0x10
@@ -363,6 +375,16 @@ enum {
        AXP22X_REG_ID_MAX,
 };
 
+enum {
+       AXP313A_DCDC1 = 0,
+       AXP313A_DCDC2,
+       AXP313A_DCDC3,
+       AXP313A_ALDO1,
+       AXP313A_DLDO1,
+       AXP313A_RTC_LDO,
+       AXP313A_REG_ID_MAX,
+};
+
 enum {
        AXP806_DCDCA = 0,
        AXP806_DCDCB,
@@ -616,6 +638,16 @@ enum axp288_irqs {
        AXP288_IRQ_BC_USB_CHNG,
 };
 
+enum axp313a_irqs {
+       AXP313A_IRQ_DIE_TEMP_HIGH,
+       AXP313A_IRQ_DCDC2_V_LOW = 2,
+       AXP313A_IRQ_DCDC3_V_LOW,
+       AXP313A_IRQ_PEK_LONG,
+       AXP313A_IRQ_PEK_SHORT,
+       AXP313A_IRQ_PEK_FAL_EDGE,
+       AXP313A_IRQ_PEK_RIS_EDGE,
+};
+
 enum axp803_irqs {
        AXP803_IRQ_ACIN_OVER_V = 1,
        AXP803_IRQ_ACIN_PLUGIN,
index 9af1f3105f80782634651e30949c0898db24ec89..78e167a9248338071dc3cf8e11e08e5a50eac1b1 100644 (file)
@@ -289,6 +289,414 @@ enum rk805_reg {
 #define RK805_INT_ALARM_EN             (1 << 3)
 #define RK805_INT_TIMER_EN             (1 << 2)
 
+/* RK806 */
+#define RK806_POWER_EN0                        0x0
+#define RK806_POWER_EN1                        0x1
+#define RK806_POWER_EN2                        0x2
+#define RK806_POWER_EN3                        0x3
+#define RK806_POWER_EN4                        0x4
+#define RK806_POWER_EN5                        0x5
+#define RK806_POWER_SLP_EN0            0x6
+#define RK806_POWER_SLP_EN1            0x7
+#define RK806_POWER_SLP_EN2            0x8
+#define RK806_POWER_DISCHRG_EN0                0x9
+#define RK806_POWER_DISCHRG_EN1                0xA
+#define RK806_POWER_DISCHRG_EN2                0xB
+#define RK806_BUCK_FB_CONFIG           0xC
+#define RK806_SLP_LP_CONFIG            0xD
+#define RK806_POWER_FPWM_EN0           0xE
+#define RK806_POWER_FPWM_EN1           0xF
+#define RK806_BUCK1_CONFIG             0x10
+#define RK806_BUCK2_CONFIG             0x11
+#define RK806_BUCK3_CONFIG             0x12
+#define RK806_BUCK4_CONFIG             0x13
+#define RK806_BUCK5_CONFIG             0x14
+#define RK806_BUCK6_CONFIG             0x15
+#define RK806_BUCK7_CONFIG             0x16
+#define RK806_BUCK8_CONFIG             0x17
+#define RK806_BUCK9_CONFIG             0x18
+#define RK806_BUCK10_CONFIG            0x19
+#define RK806_BUCK1_ON_VSEL            0x1A
+#define RK806_BUCK2_ON_VSEL            0x1B
+#define RK806_BUCK3_ON_VSEL            0x1C
+#define RK806_BUCK4_ON_VSEL            0x1D
+#define RK806_BUCK5_ON_VSEL            0x1E
+#define RK806_BUCK6_ON_VSEL            0x1F
+#define RK806_BUCK7_ON_VSEL            0x20
+#define RK806_BUCK8_ON_VSEL            0x21
+#define RK806_BUCK9_ON_VSEL            0x22
+#define RK806_BUCK10_ON_VSEL           0x23
+#define RK806_BUCK1_SLP_VSEL           0x24
+#define RK806_BUCK2_SLP_VSEL           0x25
+#define RK806_BUCK3_SLP_VSEL           0x26
+#define RK806_BUCK4_SLP_VSEL           0x27
+#define RK806_BUCK5_SLP_VSEL           0x28
+#define RK806_BUCK6_SLP_VSEL           0x29
+#define RK806_BUCK7_SLP_VSEL           0x2A
+#define RK806_BUCK8_SLP_VSEL           0x2B
+#define RK806_BUCK9_SLP_VSEL           0x2D
+#define RK806_BUCK10_SLP_VSEL          0x2E
+#define RK806_BUCK_DEBUG1              0x30
+#define RK806_BUCK_DEBUG2              0x31
+#define RK806_BUCK_DEBUG3              0x32
+#define RK806_BUCK_DEBUG4              0x33
+#define RK806_BUCK_DEBUG5              0x34
+#define RK806_BUCK_DEBUG6              0x35
+#define RK806_BUCK_DEBUG7              0x36
+#define RK806_BUCK_DEBUG8              0x37
+#define RK806_BUCK_DEBUG9              0x38
+#define RK806_BUCK_DEBUG10             0x39
+#define RK806_BUCK_DEBUG11             0x3A
+#define RK806_BUCK_DEBUG12             0x3B
+#define RK806_BUCK_DEBUG13             0x3C
+#define RK806_BUCK_DEBUG14             0x3D
+#define RK806_BUCK_DEBUG15             0x3E
+#define RK806_BUCK_DEBUG16             0x3F
+#define RK806_BUCK_DEBUG17             0x40
+#define RK806_BUCK_DEBUG18             0x41
+#define RK806_NLDO_IMAX                        0x42
+#define RK806_NLDO1_ON_VSEL            0x43
+#define RK806_NLDO2_ON_VSEL            0x44
+#define RK806_NLDO3_ON_VSEL            0x45
+#define RK806_NLDO4_ON_VSEL            0x46
+#define RK806_NLDO5_ON_VSEL            0x47
+#define RK806_NLDO1_SLP_VSEL           0x48
+#define RK806_NLDO2_SLP_VSEL           0x49
+#define RK806_NLDO3_SLP_VSEL           0x4A
+#define RK806_NLDO4_SLP_VSEL           0x4B
+#define RK806_NLDO5_SLP_VSEL           0x4C
+#define RK806_PLDO_IMAX                        0x4D
+#define RK806_PLDO1_ON_VSEL            0x4E
+#define RK806_PLDO2_ON_VSEL            0x4F
+#define RK806_PLDO3_ON_VSEL            0x50
+#define RK806_PLDO4_ON_VSEL            0x51
+#define RK806_PLDO5_ON_VSEL            0x52
+#define RK806_PLDO6_ON_VSEL            0x53
+#define RK806_PLDO1_SLP_VSEL           0x54
+#define RK806_PLDO2_SLP_VSEL           0x55
+#define RK806_PLDO3_SLP_VSEL           0x56
+#define RK806_PLDO4_SLP_VSEL           0x57
+#define RK806_PLDO5_SLP_VSEL           0x58
+#define RK806_PLDO6_SLP_VSEL           0x59
+#define RK806_CHIP_NAME                        0x5A
+#define RK806_CHIP_VER                 0x5B
+#define RK806_OTP_VER                  0x5C
+#define RK806_SYS_STS                  0x5D
+#define RK806_SYS_CFG0                 0x5E
+#define RK806_SYS_CFG1                 0x5F
+#define RK806_SYS_OPTION               0x61
+#define RK806_SLEEP_CONFIG0            0x62
+#define RK806_SLEEP_CONFIG1            0x63
+#define RK806_SLEEP_CTR_SEL0           0x64
+#define RK806_SLEEP_CTR_SEL1           0x65
+#define RK806_SLEEP_CTR_SEL2           0x66
+#define RK806_SLEEP_CTR_SEL3           0x67
+#define RK806_SLEEP_CTR_SEL4           0x68
+#define RK806_SLEEP_CTR_SEL5           0x69
+#define RK806_DVS_CTRL_SEL0            0x6A
+#define RK806_DVS_CTRL_SEL1            0x6B
+#define RK806_DVS_CTRL_SEL2            0x6C
+#define RK806_DVS_CTRL_SEL3            0x6D
+#define RK806_DVS_CTRL_SEL4            0x6E
+#define RK806_DVS_CTRL_SEL5            0x6F
+#define RK806_DVS_START_CTRL           0x70
+#define RK806_SLEEP_GPIO               0x71
+#define RK806_SYS_CFG3                 0x72
+#define RK806_ON_SOURCE                        0x74
+#define RK806_OFF_SOURCE               0x75
+#define RK806_PWRON_KEY                        0x76
+#define RK806_INT_STS0                 0x77
+#define RK806_INT_MSK0                 0x78
+#define RK806_INT_STS1                 0x79
+#define RK806_INT_MSK1                 0x7A
+#define RK806_GPIO_INT_CONFIG          0x7B
+#define RK806_DATA_REG0                        0x7C
+#define RK806_DATA_REG1                        0x7D
+#define RK806_DATA_REG2                        0x7E
+#define RK806_DATA_REG3                        0x7F
+#define RK806_DATA_REG4                        0x80
+#define RK806_DATA_REG5                        0x81
+#define RK806_DATA_REG6                        0x82
+#define RK806_DATA_REG7                        0x83
+#define RK806_DATA_REG8                        0x84
+#define RK806_DATA_REG9                        0x85
+#define RK806_DATA_REG10               0x86
+#define RK806_DATA_REG11               0x87
+#define RK806_DATA_REG12               0x88
+#define RK806_DATA_REG13               0x89
+#define RK806_DATA_REG14               0x8A
+#define RK806_DATA_REG15               0x8B
+#define RK806_TM_REG                   0x8C
+#define RK806_OTP_EN_REG               0x8D
+#define RK806_FUNC_OTP_EN_REG          0x8E
+#define RK806_TEST_REG1                        0x8F
+#define RK806_TEST_REG2                        0x90
+#define RK806_TEST_REG3                        0x91
+#define RK806_TEST_REG4                        0x92
+#define RK806_TEST_REG5                        0x93
+#define RK806_BUCK_VSEL_OTP_REG0       0x94
+#define RK806_BUCK_VSEL_OTP_REG1       0x95
+#define RK806_BUCK_VSEL_OTP_REG2       0x96
+#define RK806_BUCK_VSEL_OTP_REG3       0x97
+#define RK806_BUCK_VSEL_OTP_REG4       0x98
+#define RK806_BUCK_VSEL_OTP_REG5       0x99
+#define RK806_BUCK_VSEL_OTP_REG6       0x9A
+#define RK806_BUCK_VSEL_OTP_REG7       0x9B
+#define RK806_BUCK_VSEL_OTP_REG8       0x9C
+#define RK806_BUCK_VSEL_OTP_REG9       0x9D
+#define RK806_NLDO1_VSEL_OTP_REG0      0x9E
+#define RK806_NLDO1_VSEL_OTP_REG1      0x9F
+#define RK806_NLDO1_VSEL_OTP_REG2      0xA0
+#define RK806_NLDO1_VSEL_OTP_REG3      0xA1
+#define RK806_NLDO1_VSEL_OTP_REG4      0xA2
+#define RK806_PLDO_VSEL_OTP_REG0       0xA3
+#define RK806_PLDO_VSEL_OTP_REG1       0xA4
+#define RK806_PLDO_VSEL_OTP_REG2       0xA5
+#define RK806_PLDO_VSEL_OTP_REG3       0xA6
+#define RK806_PLDO_VSEL_OTP_REG4       0xA7
+#define RK806_PLDO_VSEL_OTP_REG5       0xA8
+#define RK806_BUCK_EN_OTP_REG1         0xA9
+#define RK806_NLDO_EN_OTP_REG1         0xAA
+#define RK806_PLDO_EN_OTP_REG1         0xAB
+#define RK806_BUCK_FB_RES_OTP_REG1     0xAC
+#define RK806_OTP_RESEV_REG0           0xAD
+#define RK806_OTP_RESEV_REG1           0xAE
+#define RK806_OTP_RESEV_REG2           0xAF
+#define RK806_OTP_RESEV_REG3           0xB0
+#define RK806_OTP_RESEV_REG4           0xB1
+#define RK806_BUCK_SEQ_REG0            0xB2
+#define RK806_BUCK_SEQ_REG1            0xB3
+#define RK806_BUCK_SEQ_REG2            0xB4
+#define RK806_BUCK_SEQ_REG3            0xB5
+#define RK806_BUCK_SEQ_REG4            0xB6
+#define RK806_BUCK_SEQ_REG5            0xB7
+#define RK806_BUCK_SEQ_REG6            0xB8
+#define RK806_BUCK_SEQ_REG7            0xB9
+#define RK806_BUCK_SEQ_REG8            0xBA
+#define RK806_BUCK_SEQ_REG9            0xBB
+#define RK806_BUCK_SEQ_REG10           0xBC
+#define RK806_BUCK_SEQ_REG11           0xBD
+#define RK806_BUCK_SEQ_REG12           0xBE
+#define RK806_BUCK_SEQ_REG13           0xBF
+#define RK806_BUCK_SEQ_REG14           0xC0
+#define RK806_BUCK_SEQ_REG15           0xC1
+#define RK806_BUCK_SEQ_REG16           0xC2
+#define RK806_BUCK_SEQ_REG17           0xC3
+#define RK806_HK_TRIM_REG1             0xC4
+#define RK806_HK_TRIM_REG2             0xC5
+#define RK806_BUCK_REF_TRIM_REG1       0xC6
+#define RK806_BUCK_REF_TRIM_REG2       0xC7
+#define RK806_BUCK_REF_TRIM_REG3       0xC8
+#define RK806_BUCK_REF_TRIM_REG4       0xC9
+#define RK806_BUCK_REF_TRIM_REG5       0xCA
+#define RK806_BUCK_OSC_TRIM_REG1       0xCB
+#define RK806_BUCK_OSC_TRIM_REG2       0xCC
+#define RK806_BUCK_OSC_TRIM_REG3       0xCD
+#define RK806_BUCK_OSC_TRIM_REG4       0xCE
+#define RK806_BUCK_OSC_TRIM_REG5       0xCF
+#define RK806_BUCK_TRIM_ZCDIOS_REG1    0xD0
+#define RK806_BUCK_TRIM_ZCDIOS_REG2    0xD1
+#define RK806_NLDO_TRIM_REG1           0xD2
+#define RK806_NLDO_TRIM_REG2           0xD3
+#define RK806_NLDO_TRIM_REG3           0xD4
+#define RK806_PLDO_TRIM_REG1           0xD5
+#define RK806_PLDO_TRIM_REG2           0xD6
+#define RK806_PLDO_TRIM_REG3           0xD7
+#define RK806_TRIM_ICOMP_REG1          0xD8
+#define RK806_TRIM_ICOMP_REG2          0xD9
+#define RK806_EFUSE_CONTROL_REGH       0xDA
+#define RK806_FUSE_PROG_REG            0xDB
+#define RK806_MAIN_FSM_STS_REG         0xDD
+#define RK806_FSM_REG                  0xDE
+#define RK806_TOP_RESEV_OFFR           0xEC
+#define RK806_TOP_RESEV_POR            0xED
+#define RK806_BUCK_VRSN_REG1           0xEE
+#define RK806_BUCK_VRSN_REG2           0xEF
+#define RK806_NLDO_RLOAD_SEL_REG1      0xF0
+#define RK806_PLDO_RLOAD_SEL_REG1      0xF1
+#define RK806_PLDO_RLOAD_SEL_REG2      0xF2
+#define RK806_BUCK_CMIN_MX_REG1                0xF3
+#define RK806_BUCK_CMIN_MX_REG2                0xF4
+#define RK806_BUCK_FREQ_SET_REG1       0xF5
+#define RK806_BUCK_FREQ_SET_REG2       0xF6
+#define RK806_BUCK_RS_MEABS_REG1       0xF7
+#define RK806_BUCK_RS_MEABS_REG2       0xF8
+#define RK806_BUCK_RS_ZDLEB_REG1       0xF9
+#define RK806_BUCK_RS_ZDLEB_REG2       0xFA
+#define RK806_BUCK_RSERVE_REG1         0xFB
+#define RK806_BUCK_RSERVE_REG2         0xFC
+#define RK806_BUCK_RSERVE_REG3         0xFD
+#define RK806_BUCK_RSERVE_REG4         0xFE
+#define RK806_BUCK_RSERVE_REG5         0xFF
+
+/* INT_STS Register field definitions */
+#define RK806_INT_STS_PWRON_FALL       BIT(0)
+#define RK806_INT_STS_PWRON_RISE       BIT(1)
+#define RK806_INT_STS_PWRON            BIT(2)
+#define RK806_INT_STS_PWRON_LP         BIT(3)
+#define RK806_INT_STS_HOTDIE           BIT(4)
+#define RK806_INT_STS_VDC_RISE         BIT(5)
+#define RK806_INT_STS_VDC_FALL         BIT(6)
+#define RK806_INT_STS_VB_LO            BIT(7)
+#define RK806_INT_STS_REV0             BIT(0)
+#define RK806_INT_STS_REV1             BIT(1)
+#define RK806_INT_STS_REV2             BIT(2)
+#define RK806_INT_STS_CRC_ERROR                BIT(3)
+#define RK806_INT_STS_SLP3_GPIO                BIT(4)
+#define RK806_INT_STS_SLP2_GPIO                BIT(5)
+#define RK806_INT_STS_SLP1_GPIO                BIT(6)
+#define RK806_INT_STS_WDT              BIT(7)
+
+/* SPI command */
+#define RK806_CMD_READ                 0
+#define RK806_CMD_WRITE                        BIT(7)
+#define RK806_CMD_CRC_EN               BIT(6)
+#define RK806_CMD_CRC_DIS              0
+#define RK806_CMD_LEN_MSK              0x0f
+#define RK806_REG_H                    0x00
+
+#define VERSION_AB             0x01
+
+enum rk806_reg_id {
+       RK806_ID_DCDC1 = 0,
+       RK806_ID_DCDC2,
+       RK806_ID_DCDC3,
+       RK806_ID_DCDC4,
+       RK806_ID_DCDC5,
+       RK806_ID_DCDC6,
+       RK806_ID_DCDC7,
+       RK806_ID_DCDC8,
+       RK806_ID_DCDC9,
+       RK806_ID_DCDC10,
+
+       RK806_ID_NLDO1,
+       RK806_ID_NLDO2,
+       RK806_ID_NLDO3,
+       RK806_ID_NLDO4,
+       RK806_ID_NLDO5,
+
+       RK806_ID_PLDO1,
+       RK806_ID_PLDO2,
+       RK806_ID_PLDO3,
+       RK806_ID_PLDO4,
+       RK806_ID_PLDO5,
+       RK806_ID_PLDO6,
+       RK806_ID_END,
+};
+
+/* Define the RK806 IRQ numbers */
+enum rk806_irqs {
+       /* INT_STS0 registers */
+       RK806_IRQ_PWRON_FALL,
+       RK806_IRQ_PWRON_RISE,
+       RK806_IRQ_PWRON,
+       RK806_IRQ_PWRON_LP,
+       RK806_IRQ_HOTDIE,
+       RK806_IRQ_VDC_RISE,
+       RK806_IRQ_VDC_FALL,
+       RK806_IRQ_VB_LO,
+
+       /* INT_STS0 registers */
+       RK806_IRQ_REV0,
+       RK806_IRQ_REV1,
+       RK806_IRQ_REV2,
+       RK806_IRQ_CRC_ERROR,
+       RK806_IRQ_SLP3_GPIO,
+       RK806_IRQ_SLP2_GPIO,
+       RK806_IRQ_SLP1_GPIO,
+       RK806_IRQ_WDT,
+};
+
+/* VCC1 Low Voltage Threshold */
+enum rk806_lv_sel {
+       VB_LO_SEL_2800,
+       VB_LO_SEL_2900,
+       VB_LO_SEL_3000,
+       VB_LO_SEL_3100,
+       VB_LO_SEL_3200,
+       VB_LO_SEL_3300,
+       VB_LO_SEL_3400,
+       VB_LO_SEL_3500,
+};
+
+/* System Shutdown Voltage Select */
+enum rk806_uv_sel {
+       VB_UV_SEL_2700,
+       VB_UV_SEL_2800,
+       VB_UV_SEL_2900,
+       VB_UV_SEL_3000,
+       VB_UV_SEL_3100,
+       VB_UV_SEL_3200,
+       VB_UV_SEL_3300,
+       VB_UV_SEL_3400,
+};
+
+/* Pin Function */
+enum rk806_pwrctrl_fun {
+       PWRCTRL_NULL_FUN,
+       PWRCTRL_SLP_FUN,
+       PWRCTRL_POWOFF_FUN,
+       PWRCTRL_RST_FUN,
+       PWRCTRL_DVS_FUN,
+       PWRCTRL_GPIO_FUN,
+};
+
+/* Pin Polarity */
+enum rk806_pin_level {
+       POL_LOW,
+       POL_HIGH,
+};
+
+enum rk806_vsel_ctr_sel {
+       CTR_BY_NO_EFFECT,
+       CTR_BY_PWRCTRL1,
+       CTR_BY_PWRCTRL2,
+       CTR_BY_PWRCTRL3,
+};
+
+enum rk806_dvs_ctr_sel {
+       CTR_SEL_NO_EFFECT,
+       CTR_SEL_DVS_START1,
+       CTR_SEL_DVS_START2,
+       CTR_SEL_DVS_START3,
+};
+
+enum rk806_pin_dr_sel {
+       RK806_PIN_INPUT,
+       RK806_PIN_OUTPUT,
+};
+
+#define RK806_INT_POL_MSK              BIT(1)
+#define RK806_INT_POL_H                        BIT(1)
+#define RK806_INT_POL_L                        0
+
+#define RK806_SLAVE_RESTART_FUN_MSK    BIT(1)
+#define RK806_SLAVE_RESTART_FUN_EN     BIT(1)
+#define RK806_SLAVE_RESTART_FUN_OFF    0
+
+#define RK806_SYS_ENB2_2M_MSK          BIT(1)
+#define RK806_SYS_ENB2_2M_EN           BIT(1)
+#define RK806_SYS_ENB2_2M_OFF          0
+
+enum rk806_int_fun {
+       RK806_INT_ONLY,
+       RK806_INT_ADN_WKUP,
+};
+
+enum rk806_dvs_mode {
+       RK806_DVS_NOT_SUPPORT,
+       RK806_DVS_START1,
+       RK806_DVS_START2,
+       RK806_DVS_START3,
+       RK806_DVS_PWRCTRL1,
+       RK806_DVS_PWRCTRL2,
+       RK806_DVS_PWRCTRL3,
+       RK806_DVS_START_PWRCTR1,
+       RK806_DVS_START_PWRCTR2,
+       RK806_DVS_START_PWRCTR3,
+       RK806_DVS_END,
+};
+
 /* RK808 IRQ Definitions */
 #define RK808_IRQ_VOUT_LO      0
 #define RK808_IRQ_VB_LO                1
@@ -780,6 +1188,7 @@ enum {
 
 enum {
        RK805_ID = 0x8050,
+       RK806_ID = 0x8060,
        RK808_ID = 0x0000,
        RK809_ID = 0x8090,
        RK817_ID = 0x8170,
@@ -787,11 +1196,17 @@ enum {
 };
 
 struct rk808 {
-       struct i2c_client               *i2c;
+       struct device                   *dev;
        struct regmap_irq_chip_data     *irq_data;
        struct regmap                   *regmap;
        long                            variant;
        const struct regmap_config      *regmap_cfg;
        const struct regmap_irq_chip    *regmap_irq_chip;
 };
+
+void rk8xx_shutdown(struct device *dev);
+int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap);
+int rk8xx_suspend(struct device *dev);
+int rk8xx_resume(struct device *dev);
+
 #endif /* __LINUX_REGULATOR_RK808_H */
diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h
new file mode 100644 (file)
index 0000000..3f7c5e2
--- /dev/null
@@ -0,0 +1,1020 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Functions to access TPS6594 Power Management IC
+ *
+ * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
+ */
+
+#ifndef __LINUX_MFD_TPS6594_H
+#define __LINUX_MFD_TPS6594_H
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+struct regmap_irq_chip_data;
+
+/* Chip id list */
+enum pmic_id {
+       TPS6594,
+       TPS6593,
+       LP8764,
+};
+
+/* Macro to get page index from register address */
+#define TPS6594_REG_TO_PAGE(reg)       ((reg) >> 8)
+
+/* Registers for page 0 of TPS6594 */
+#define TPS6594_REG_DEV_REV                            0x01
+
+#define TPS6594_REG_NVM_CODE_1                         0x02
+#define TPS6594_REG_NVM_CODE_2                         0x03
+
+#define TPS6594_REG_BUCKX_CTRL(buck_inst)              (0x04 + ((buck_inst) << 1))
+#define TPS6594_REG_BUCKX_CONF(buck_inst)              (0x05 + ((buck_inst) << 1))
+#define TPS6594_REG_BUCKX_VOUT_1(buck_inst)            (0x0e + ((buck_inst) << 1))
+#define TPS6594_REG_BUCKX_VOUT_2(buck_inst)            (0x0f + ((buck_inst) << 1))
+#define TPS6594_REG_BUCKX_PG_WINDOW(buck_inst)         (0x18 + (buck_inst))
+
+#define TPS6594_REG_LDOX_CTRL(ldo_inst)                        (0x1d + (ldo_inst))
+#define TPS6594_REG_LDORTC_CTRL                                0x22
+#define TPS6594_REG_LDOX_VOUT(ldo_inst)                        (0x23 + (ldo_inst))
+#define TPS6594_REG_LDOX_PG_WINDOW(ldo_inst)           (0x27 + (ldo_inst))
+
+#define TPS6594_REG_VCCA_VMON_CTRL                     0x2b
+#define TPS6594_REG_VCCA_PG_WINDOW                     0x2c
+#define TPS6594_REG_VMON1_PG_WINDOW                    0x2d
+#define TPS6594_REG_VMON1_PG_LEVEL                     0x2e
+#define TPS6594_REG_VMON2_PG_WINDOW                    0x2f
+#define TPS6594_REG_VMON2_PG_LEVEL                     0x30
+
+#define TPS6594_REG_GPIOX_CONF(gpio_inst)              (0x31 + (gpio_inst))
+#define TPS6594_REG_NPWRON_CONF                                0x3c
+#define TPS6594_REG_GPIO_OUT_1                         0x3d
+#define TPS6594_REG_GPIO_OUT_2                         0x3e
+#define TPS6594_REG_GPIO_IN_1                          0x3f
+#define TPS6594_REG_GPIO_IN_2                          0x40
+#define TPS6594_REG_GPIOX_OUT(gpio_inst)               (TPS6594_REG_GPIO_OUT_1 + (gpio_inst) / 8)
+#define TPS6594_REG_GPIOX_IN(gpio_inst)                        (TPS6594_REG_GPIO_IN_1 + (gpio_inst) / 8)
+
+#define TPS6594_REG_GPIO_IN_1                          0x3f
+#define TPS6594_REG_GPIO_IN_2                          0x40
+
+#define TPS6594_REG_RAIL_SEL_1                         0x41
+#define TPS6594_REG_RAIL_SEL_2                         0x42
+#define TPS6594_REG_RAIL_SEL_3                         0x43
+
+#define TPS6594_REG_FSM_TRIG_SEL_1                     0x44
+#define TPS6594_REG_FSM_TRIG_SEL_2                     0x45
+#define TPS6594_REG_FSM_TRIG_MASK_1                    0x46
+#define TPS6594_REG_FSM_TRIG_MASK_2                    0x47
+#define TPS6594_REG_FSM_TRIG_MASK_3                    0x48
+
+#define TPS6594_REG_MASK_BUCK1_2                       0x49
+#define TPS6594_REG_MASK_BUCK3_4                       0x4a
+#define TPS6594_REG_MASK_BUCK5                         0x4b
+#define TPS6594_REG_MASK_LDO1_2                                0x4c
+#define TPS6594_REG_MASK_LDO3_4                                0x4d
+#define TPS6594_REG_MASK_VMON                          0x4e
+#define TPS6594_REG_MASK_GPIO1_8_FALL                  0x4f
+#define TPS6594_REG_MASK_GPIO1_8_RISE                  0x50
+#define TPS6594_REG_MASK_GPIO9_11                      0x51
+#define TPS6594_REG_MASK_STARTUP                       0x52
+#define TPS6594_REG_MASK_MISC                          0x53
+#define TPS6594_REG_MASK_MODERATE_ERR                  0x54
+#define TPS6594_REG_MASK_FSM_ERR                       0x56
+#define TPS6594_REG_MASK_COMM_ERR                      0x57
+#define TPS6594_REG_MASK_READBACK_ERR                  0x58
+#define TPS6594_REG_MASK_ESM                           0x59
+
+#define TPS6594_REG_INT_TOP                            0x5a
+#define TPS6594_REG_INT_BUCK                           0x5b
+#define TPS6594_REG_INT_BUCK1_2                                0x5c
+#define TPS6594_REG_INT_BUCK3_4                                0x5d
+#define TPS6594_REG_INT_BUCK5                          0x5e
+#define TPS6594_REG_INT_LDO_VMON                       0x5f
+#define TPS6594_REG_INT_LDO1_2                         0x60
+#define TPS6594_REG_INT_LDO3_4                         0x61
+#define TPS6594_REG_INT_VMON                           0x62
+#define TPS6594_REG_INT_GPIO                           0x63
+#define TPS6594_REG_INT_GPIO1_8                                0x64
+#define TPS6594_REG_INT_STARTUP                                0x65
+#define TPS6594_REG_INT_MISC                           0x66
+#define TPS6594_REG_INT_MODERATE_ERR                   0x67
+#define TPS6594_REG_INT_SEVERE_ERR                     0x68
+#define TPS6594_REG_INT_FSM_ERR                                0x69
+#define TPS6594_REG_INT_COMM_ERR                       0x6a
+#define TPS6594_REG_INT_READBACK_ERR                   0x6b
+#define TPS6594_REG_INT_ESM                            0x6c
+
+#define TPS6594_REG_STAT_BUCK1_2                       0x6d
+#define TPS6594_REG_STAT_BUCK3_4                       0x6e
+#define TPS6594_REG_STAT_BUCK5                         0x6f
+#define TPS6594_REG_STAT_LDO1_2                                0x70
+#define TPS6594_REG_STAT_LDO3_4                                0x71
+#define TPS6594_REG_STAT_VMON                          0x72
+#define TPS6594_REG_STAT_STARTUP                       0x73
+#define TPS6594_REG_STAT_MISC                          0x74
+#define TPS6594_REG_STAT_MODERATE_ERR                  0x75
+#define TPS6594_REG_STAT_SEVERE_ERR                    0x76
+#define TPS6594_REG_STAT_READBACK_ERR                  0x77
+
+#define TPS6594_REG_PGOOD_SEL_1                                0x78
+#define TPS6594_REG_PGOOD_SEL_2                                0x79
+#define TPS6594_REG_PGOOD_SEL_3                                0x7a
+#define TPS6594_REG_PGOOD_SEL_4                                0x7b
+
+#define TPS6594_REG_PLL_CTRL                           0x7c
+
+#define TPS6594_REG_CONFIG_1                           0x7d
+#define TPS6594_REG_CONFIG_2                           0x7e
+
+#define TPS6594_REG_ENABLE_DRV_REG                     0x80
+
+#define TPS6594_REG_MISC_CTRL                          0x81
+
+#define TPS6594_REG_ENABLE_DRV_STAT                    0x82
+
+#define TPS6594_REG_RECOV_CNT_REG_1                    0x83
+#define TPS6594_REG_RECOV_CNT_REG_2                    0x84
+
+#define TPS6594_REG_FSM_I2C_TRIGGERS                   0x85
+#define TPS6594_REG_FSM_NSLEEP_TRIGGERS                        0x86
+
+#define TPS6594_REG_BUCK_RESET_REG                     0x87
+
+#define TPS6594_REG_SPREAD_SPECTRUM_1                  0x88
+
+#define TPS6594_REG_FREQ_SEL                           0x8a
+
+#define TPS6594_REG_FSM_STEP_SIZE                      0x8b
+
+#define TPS6594_REG_LDO_RV_TIMEOUT_REG_1               0x8c
+#define TPS6594_REG_LDO_RV_TIMEOUT_REG_2               0x8d
+
+#define TPS6594_REG_USER_SPARE_REGS                    0x8e
+
+#define TPS6594_REG_ESM_MCU_START_REG                  0x8f
+#define TPS6594_REG_ESM_MCU_DELAY1_REG                 0x90
+#define TPS6594_REG_ESM_MCU_DELAY2_REG                 0x91
+#define TPS6594_REG_ESM_MCU_MODE_CFG                   0x92
+#define TPS6594_REG_ESM_MCU_HMAX_REG                   0x93
+#define TPS6594_REG_ESM_MCU_HMIN_REG                   0x94
+#define TPS6594_REG_ESM_MCU_LMAX_REG                   0x95
+#define TPS6594_REG_ESM_MCU_LMIN_REG                   0x96
+#define TPS6594_REG_ESM_MCU_ERR_CNT_REG                        0x97
+#define TPS6594_REG_ESM_SOC_START_REG                  0x98
+#define TPS6594_REG_ESM_SOC_DELAY1_REG                 0x99
+#define TPS6594_REG_ESM_SOC_DELAY2_REG                 0x9a
+#define TPS6594_REG_ESM_SOC_MODE_CFG                   0x9b
+#define TPS6594_REG_ESM_SOC_HMAX_REG                   0x9c
+#define TPS6594_REG_ESM_SOC_HMIN_REG                   0x9d
+#define TPS6594_REG_ESM_SOC_LMAX_REG                   0x9e
+#define TPS6594_REG_ESM_SOC_LMIN_REG                   0x9f
+#define TPS6594_REG_ESM_SOC_ERR_CNT_REG                        0xa0
+
+#define TPS6594_REG_REGISTER_LOCK                      0xa1
+
+#define TPS6594_REG_MANUFACTURING_VER                  0xa6
+
+#define TPS6594_REG_CUSTOMER_NVM_ID_REG                        0xa7
+
+#define TPS6594_REG_VMON_CONF_REG                      0xa8
+
+#define TPS6594_REG_SOFT_REBOOT_REG                    0xab
+
+#define TPS6594_REG_RTC_SECONDS                                0xb5
+#define TPS6594_REG_RTC_MINUTES                                0xb6
+#define TPS6594_REG_RTC_HOURS                          0xb7
+#define TPS6594_REG_RTC_DAYS                           0xb8
+#define TPS6594_REG_RTC_MONTHS                         0xb9
+#define TPS6594_REG_RTC_YEARS                          0xba
+#define TPS6594_REG_RTC_WEEKS                          0xbb
+
+#define TPS6594_REG_ALARM_SECONDS                      0xbc
+#define TPS6594_REG_ALARM_MINUTES                      0xbd
+#define TPS6594_REG_ALARM_HOURS                                0xbe
+#define TPS6594_REG_ALARM_DAYS                         0xbf
+#define TPS6594_REG_ALARM_MONTHS                       0xc0
+#define TPS6594_REG_ALARM_YEARS                                0xc1
+
+#define TPS6594_REG_RTC_CTRL_1                         0xc2
+#define TPS6594_REG_RTC_CTRL_2                         0xc3
+#define TPS6594_REG_RTC_STATUS                         0xc4
+#define TPS6594_REG_RTC_INTERRUPTS                     0xc5
+#define TPS6594_REG_RTC_COMP_LSB                       0xc6
+#define TPS6594_REG_RTC_COMP_MSB                       0xc7
+#define TPS6594_REG_RTC_RESET_STATUS                   0xc8
+
+#define TPS6594_REG_SCRATCH_PAD_REG_1                  0xc9
+#define TPS6594_REG_SCRATCH_PAD_REG_2                  0xca
+#define TPS6594_REG_SCRATCH_PAD_REG_3                  0xcb
+#define TPS6594_REG_SCRATCH_PAD_REG_4                  0xcc
+
+#define TPS6594_REG_PFSM_DELAY_REG_1                   0xcd
+#define TPS6594_REG_PFSM_DELAY_REG_2                   0xce
+#define TPS6594_REG_PFSM_DELAY_REG_3                   0xcf
+#define TPS6594_REG_PFSM_DELAY_REG_4                   0xd0
+
+/* Registers for page 1 of TPS6594 */
+#define TPS6594_REG_SERIAL_IF_CONFIG                   0x11a
+#define TPS6594_REG_I2C1_ID                            0x122
+#define TPS6594_REG_I2C2_ID                            0x123
+
+/* Registers for page 4 of TPS6594 */
+#define TPS6594_REG_WD_ANSWER_REG                      0x401
+#define TPS6594_REG_WD_QUESTION_ANSW_CNT               0x402
+#define TPS6594_REG_WD_WIN1_CFG                                0x403
+#define TPS6594_REG_WD_WIN2_CFG                                0x404
+#define TPS6594_REG_WD_LONGWIN_CFG                     0x405
+#define TPS6594_REG_WD_MODE_REG                                0x406
+#define TPS6594_REG_WD_QA_CFG                          0x407
+#define TPS6594_REG_WD_ERR_STATUS                      0x408
+#define TPS6594_REG_WD_THR_CFG                         0x409
+#define TPS6594_REG_DWD_FAIL_CNT_REG                   0x40a
+
+/* BUCKX_CTRL register field definition */
+#define TPS6594_BIT_BUCK_EN                            BIT(0)
+#define TPS6594_BIT_BUCK_FPWM                          BIT(1)
+#define TPS6594_BIT_BUCK_FPWM_MP                       BIT(2)
+#define TPS6594_BIT_BUCK_VSEL                          BIT(3)
+#define TPS6594_BIT_BUCK_VMON_EN                       BIT(4)
+#define TPS6594_BIT_BUCK_PLDN                          BIT(5)
+#define TPS6594_BIT_BUCK_RV_SEL                                BIT(7)
+
+/* BUCKX_CONF register field definition */
+#define TPS6594_MASK_BUCK_SLEW_RATE                    GENMASK(2, 0)
+#define TPS6594_MASK_BUCK_ILIM                         GENMASK(5, 3)
+
+/* BUCKX_PG_WINDOW register field definition */
+#define TPS6594_MASK_BUCK_OV_THR                       GENMASK(2, 0)
+#define TPS6594_MASK_BUCK_UV_THR                       GENMASK(5, 3)
+
+/* BUCKX VSET */
+#define TPS6594_MASK_BUCKS_VSET GENMASK(7, 0)
+
+/* LDOX_CTRL register field definition */
+#define TPS6594_BIT_LDO_EN                             BIT(0)
+#define TPS6594_BIT_LDO_SLOW_RAMP                      BIT(1)
+#define TPS6594_BIT_LDO_VMON_EN                                BIT(4)
+#define TPS6594_MASK_LDO_PLDN                          GENMASK(6, 5)
+#define TPS6594_BIT_LDO_RV_SEL                         BIT(7)
+
+/* LDORTC_CTRL register field definition */
+#define TPS6594_BIT_LDORTC_DIS                         BIT(0)
+
+/* LDOX_VOUT register field definition */
+#define TPS6594_MASK_LDO123_VSET                       GENMASK(6, 1)
+#define TPS6594_MASK_LDO4_VSET                         GENMASK(6, 0)
+#define TPS6594_BIT_LDO_BYPASS                         BIT(7)
+
+/* LDOX_PG_WINDOW register field definition */
+#define TPS6594_MASK_LDO_OV_THR                                GENMASK(2, 0)
+#define TPS6594_MASK_LDO_UV_THR                                GENMASK(5, 3)
+
+/* VCCA_VMON_CTRL register field definition */
+#define TPS6594_BIT_VMON_EN                            BIT(0)
+#define TPS6594_BIT_VMON1_EN                           BIT(1)
+#define TPS6594_BIT_VMON1_RV_SEL                       BIT(2)
+#define TPS6594_BIT_VMON2_EN                           BIT(3)
+#define TPS6594_BIT_VMON2_RV_SEL                       BIT(4)
+#define TPS6594_BIT_VMON_DEGLITCH_SEL                  BIT(5)
+
+/* VCCA_PG_WINDOW register field definition */
+#define TPS6594_MASK_VCCA_OV_THR                       GENMASK(2, 0)
+#define TPS6594_MASK_VCCA_UV_THR                       GENMASK(5, 3)
+#define TPS6594_BIT_VCCA_PG_SET                                BIT(6)
+
+/* VMONX_PG_WINDOW register field definition */
+#define TPS6594_MASK_VMONX_OV_THR                      GENMASK(2, 0)
+#define TPS6594_MASK_VMONX_UV_THR                      GENMASK(5, 3)
+#define TPS6594_BIT_VMONX_RANGE                                BIT(6)
+
+/* GPIOX_CONF register field definition */
+#define TPS6594_BIT_GPIO_DIR                           BIT(0)
+#define TPS6594_BIT_GPIO_OD                            BIT(1)
+#define TPS6594_BIT_GPIO_PU_SEL                                BIT(2)
+#define TPS6594_BIT_GPIO_PU_PD_EN                      BIT(3)
+#define TPS6594_BIT_GPIO_DEGLITCH_EN                   BIT(4)
+#define TPS6594_MASK_GPIO_SEL                          GENMASK(7, 5)
+
+/* NPWRON_CONF register field definition */
+#define TPS6594_BIT_NRSTOUT_OD                         BIT(0)
+#define TPS6594_BIT_ENABLE_PU_SEL                      BIT(2)
+#define TPS6594_BIT_ENABLE_PU_PD_EN                    BIT(3)
+#define TPS6594_BIT_ENABLE_DEGLITCH_EN                 BIT(4)
+#define TPS6594_BIT_ENABLE_POL                         BIT(5)
+#define TPS6594_MASK_NPWRON_SEL                                GENMASK(7, 6)
+
+/* GPIO_OUT_X register field definition */
+#define TPS6594_BIT_GPIOX_OUT(gpio_inst)               BIT((gpio_inst) % 8)
+
+/* GPIO_IN_X register field definition */
+#define TPS6594_BIT_GPIOX_IN(gpio_inst)                        BIT((gpio_inst) % 8)
+#define TPS6594_BIT_NPWRON_IN                          BIT(3)
+
+/* RAIL_SEL_1 register field definition */
+#define TPS6594_MASK_BUCK1_GRP_SEL                     GENMASK(1, 0)
+#define TPS6594_MASK_BUCK2_GRP_SEL                     GENMASK(3, 2)
+#define TPS6594_MASK_BUCK3_GRP_SEL                     GENMASK(5, 4)
+#define TPS6594_MASK_BUCK4_GRP_SEL                     GENMASK(7, 6)
+
+/* RAIL_SEL_2 register field definition */
+#define TPS6594_MASK_BUCK5_GRP_SEL                     GENMASK(1, 0)
+#define TPS6594_MASK_LDO1_GRP_SEL                      GENMASK(3, 2)
+#define TPS6594_MASK_LDO2_GRP_SEL                      GENMASK(5, 4)
+#define TPS6594_MASK_LDO3_GRP_SEL                      GENMASK(7, 6)
+
+/* RAIL_SEL_3 register field definition */
+#define TPS6594_MASK_LDO4_GRP_SEL                      GENMASK(1, 0)
+#define TPS6594_MASK_VCCA_GRP_SEL                      GENMASK(3, 2)
+#define TPS6594_MASK_VMON1_GRP_SEL                     GENMASK(5, 4)
+#define TPS6594_MASK_VMON2_GRP_SEL                     GENMASK(7, 6)
+
+/* FSM_TRIG_SEL_1 register field definition */
+#define TPS6594_MASK_MCU_RAIL_TRIG                     GENMASK(1, 0)
+#define TPS6594_MASK_SOC_RAIL_TRIG                     GENMASK(3, 2)
+#define TPS6594_MASK_OTHER_RAIL_TRIG                   GENMASK(5, 4)
+#define TPS6594_MASK_SEVERE_ERR_TRIG                   GENMASK(7, 6)
+
+/* FSM_TRIG_SEL_2 register field definition */
+#define TPS6594_MASK_MODERATE_ERR_TRIG                 GENMASK(1, 0)
+
+/* FSM_TRIG_MASK_X register field definition */
+#define TPS6594_BIT_GPIOX_FSM_MASK(gpio_inst)          BIT(((gpio_inst) << 1) % 8)
+#define TPS6594_BIT_GPIOX_FSM_MASK_POL(gpio_inst)      BIT(((gpio_inst) << 1) % 8 + 1)
+
+/* MASK_BUCKX register field definition */
+#define TPS6594_BIT_BUCKX_OV_MASK(buck_inst)           BIT(((buck_inst) << 2) % 8)
+#define TPS6594_BIT_BUCKX_UV_MASK(buck_inst)           BIT(((buck_inst) << 2) % 8 + 1)
+#define TPS6594_BIT_BUCKX_ILIM_MASK(buck_inst)         BIT(((buck_inst) << 2) % 8 + 3)
+
+/* MASK_LDOX register field definition */
+#define TPS6594_BIT_LDOX_OV_MASK(ldo_inst)             BIT(((ldo_inst) << 2) % 8)
+#define TPS6594_BIT_LDOX_UV_MASK(ldo_inst)             BIT(((ldo_inst) << 2) % 8 + 1)
+#define TPS6594_BIT_LDOX_ILIM_MASK(ldo_inst)           BIT(((ldo_inst) << 2) % 8 + 3)
+
+/* MASK_VMON register field definition */
+#define TPS6594_BIT_VCCA_OV_MASK                       BIT(0)
+#define TPS6594_BIT_VCCA_UV_MASK                       BIT(1)
+#define TPS6594_BIT_VMON1_OV_MASK                      BIT(2)
+#define TPS6594_BIT_VMON1_UV_MASK                      BIT(3)
+#define TPS6594_BIT_VMON2_OV_MASK                      BIT(5)
+#define TPS6594_BIT_VMON2_UV_MASK                      BIT(6)
+
+/* MASK_GPIOX register field definition */
+#define TPS6594_BIT_GPIOX_FALL_MASK(gpio_inst)         BIT((gpio_inst) < 8 ? \
+                                                           (gpio_inst) : (gpio_inst) % 8)
+#define TPS6594_BIT_GPIOX_RISE_MASK(gpio_inst)         BIT((gpio_inst) < 8 ? \
+                                                           (gpio_inst) : (gpio_inst) % 8 + 3)
+
+/* MASK_STARTUP register field definition */
+#define TPS6594_BIT_NPWRON_START_MASK                  BIT(0)
+#define TPS6594_BIT_ENABLE_MASK                                BIT(1)
+#define TPS6594_BIT_FSD_MASK                           BIT(4)
+#define TPS6594_BIT_SOFT_REBOOT_MASK                   BIT(5)
+
+/* MASK_MISC register field definition */
+#define TPS6594_BIT_BIST_PASS_MASK                     BIT(0)
+#define TPS6594_BIT_EXT_CLK_MASK                       BIT(1)
+#define TPS6594_BIT_TWARN_MASK                         BIT(3)
+
+/* MASK_MODERATE_ERR register field definition */
+#define TPS6594_BIT_BIST_FAIL_MASK                     BIT(1)
+#define TPS6594_BIT_REG_CRC_ERR_MASK                   BIT(2)
+#define TPS6594_BIT_SPMI_ERR_MASK                      BIT(4)
+#define TPS6594_BIT_NPWRON_LONG_MASK                   BIT(5)
+#define TPS6594_BIT_NINT_READBACK_MASK                 BIT(6)
+#define TPS6594_BIT_NRSTOUT_READBACK_MASK              BIT(7)
+
+/* MASK_FSM_ERR register field definition */
+#define TPS6594_BIT_IMM_SHUTDOWN_MASK                  BIT(0)
+#define TPS6594_BIT_ORD_SHUTDOWN_MASK                  BIT(1)
+#define TPS6594_BIT_MCU_PWR_ERR_MASK                   BIT(2)
+#define TPS6594_BIT_SOC_PWR_ERR_MASK                   BIT(3)
+
+/* MASK_COMM_ERR register field definition */
+#define TPS6594_BIT_COMM_FRM_ERR_MASK                  BIT(0)
+#define TPS6594_BIT_COMM_CRC_ERR_MASK                  BIT(1)
+#define TPS6594_BIT_COMM_ADR_ERR_MASK                  BIT(3)
+#define TPS6594_BIT_I2C2_CRC_ERR_MASK                  BIT(5)
+#define TPS6594_BIT_I2C2_ADR_ERR_MASK                  BIT(7)
+
+/* MASK_READBACK_ERR register field definition */
+#define TPS6594_BIT_EN_DRV_READBACK_MASK               BIT(0)
+#define TPS6594_BIT_NRSTOUT_SOC_READBACK_MASK          BIT(3)
+
+/* MASK_ESM register field definition */
+#define TPS6594_BIT_ESM_SOC_PIN_MASK                   BIT(0)
+#define TPS6594_BIT_ESM_SOC_FAIL_MASK                  BIT(1)
+#define TPS6594_BIT_ESM_SOC_RST_MASK                   BIT(2)
+#define TPS6594_BIT_ESM_MCU_PIN_MASK                   BIT(3)
+#define TPS6594_BIT_ESM_MCU_FAIL_MASK                  BIT(4)
+#define TPS6594_BIT_ESM_MCU_RST_MASK                   BIT(5)
+
+/* INT_TOP register field definition */
+#define TPS6594_BIT_BUCK_INT                           BIT(0)
+#define TPS6594_BIT_LDO_VMON_INT                       BIT(1)
+#define TPS6594_BIT_GPIO_INT                           BIT(2)
+#define TPS6594_BIT_STARTUP_INT                                BIT(3)
+#define TPS6594_BIT_MISC_INT                           BIT(4)
+#define TPS6594_BIT_MODERATE_ERR_INT                   BIT(5)
+#define TPS6594_BIT_SEVERE_ERR_INT                     BIT(6)
+#define TPS6594_BIT_FSM_ERR_INT                                BIT(7)
+
+/* INT_BUCK register field definition */
+#define TPS6594_BIT_BUCK1_2_INT                                BIT(0)
+#define TPS6594_BIT_BUCK3_4_INT                                BIT(1)
+#define TPS6594_BIT_BUCK5_INT                          BIT(2)
+
+/* INT_BUCKX register field definition */
+#define TPS6594_BIT_BUCKX_OV_INT(buck_inst)            BIT(((buck_inst) << 2) % 8)
+#define TPS6594_BIT_BUCKX_UV_INT(buck_inst)            BIT(((buck_inst) << 2) % 8 + 1)
+#define TPS6594_BIT_BUCKX_SC_INT(buck_inst)            BIT(((buck_inst) << 2) % 8 + 2)
+#define TPS6594_BIT_BUCKX_ILIM_INT(buck_inst)          BIT(((buck_inst) << 2) % 8 + 3)
+
+/* INT_LDO_VMON register field definition */
+#define TPS6594_BIT_LDO1_2_INT                         BIT(0)
+#define TPS6594_BIT_LDO3_4_INT                         BIT(1)
+#define TPS6594_BIT_VCCA_INT                           BIT(4)
+
+/* INT_LDOX register field definition */
+#define TPS6594_BIT_LDOX_OV_INT(ldo_inst)              BIT(((ldo_inst) << 2) % 8)
+#define TPS6594_BIT_LDOX_UV_INT(ldo_inst)              BIT(((ldo_inst) << 2) % 8 + 1)
+#define TPS6594_BIT_LDOX_SC_INT(ldo_inst)              BIT(((ldo_inst) << 2) % 8 + 2)
+#define TPS6594_BIT_LDOX_ILIM_INT(ldo_inst)            BIT(((ldo_inst) << 2) % 8 + 3)
+
+/* INT_VMON register field definition */
+#define TPS6594_BIT_VCCA_OV_INT                                BIT(0)
+#define TPS6594_BIT_VCCA_UV_INT                                BIT(1)
+#define TPS6594_BIT_VMON1_OV_INT                       BIT(2)
+#define TPS6594_BIT_VMON1_UV_INT                       BIT(3)
+#define TPS6594_BIT_VMON1_RV_INT                       BIT(4)
+#define TPS6594_BIT_VMON2_OV_INT                       BIT(5)
+#define TPS6594_BIT_VMON2_UV_INT                       BIT(6)
+#define TPS6594_BIT_VMON2_RV_INT                       BIT(7)
+
+/* INT_GPIO register field definition */
+#define TPS6594_BIT_GPIO9_INT                          BIT(0)
+#define TPS6594_BIT_GPIO10_INT                         BIT(1)
+#define TPS6594_BIT_GPIO11_INT                         BIT(2)
+#define TPS6594_BIT_GPIO1_8_INT                                BIT(3)
+
+/* INT_GPIOX register field definition */
+#define TPS6594_BIT_GPIOX_INT(gpio_inst)               BIT(gpio_inst)
+
+/* INT_STARTUP register field definition */
+#define TPS6594_BIT_NPWRON_START_INT                   BIT(0)
+#define TPS6594_BIT_ENABLE_INT                         BIT(1)
+#define TPS6594_BIT_RTC_INT                            BIT(2)
+#define TPS6594_BIT_FSD_INT                            BIT(4)
+#define TPS6594_BIT_SOFT_REBOOT_INT                    BIT(5)
+
+/* INT_MISC register field definition */
+#define TPS6594_BIT_BIST_PASS_INT                      BIT(0)
+#define TPS6594_BIT_EXT_CLK_INT                                BIT(1)
+#define TPS6594_BIT_TWARN_INT                          BIT(3)
+
+/* INT_MODERATE_ERR register field definition */
+#define TPS6594_BIT_TSD_ORD_INT                                BIT(0)
+#define TPS6594_BIT_BIST_FAIL_INT                      BIT(1)
+#define TPS6594_BIT_REG_CRC_ERR_INT                    BIT(2)
+#define TPS6594_BIT_RECOV_CNT_INT                      BIT(3)
+#define TPS6594_BIT_SPMI_ERR_INT                       BIT(4)
+#define TPS6594_BIT_NPWRON_LONG_INT                    BIT(5)
+#define TPS6594_BIT_NINT_READBACK_INT                  BIT(6)
+#define TPS6594_BIT_NRSTOUT_READBACK_INT               BIT(7)
+
+/* INT_SEVERE_ERR register field definition */
+#define TPS6594_BIT_TSD_IMM_INT                                BIT(0)
+#define TPS6594_BIT_VCCA_OVP_INT                       BIT(1)
+#define TPS6594_BIT_PFSM_ERR_INT                       BIT(2)
+
+/* INT_FSM_ERR register field definition */
+#define TPS6594_BIT_IMM_SHUTDOWN_INT                   BIT(0)
+#define TPS6594_BIT_ORD_SHUTDOWN_INT                   BIT(1)
+#define TPS6594_BIT_MCU_PWR_ERR_INT                    BIT(2)
+#define TPS6594_BIT_SOC_PWR_ERR_INT                    BIT(3)
+#define TPS6594_BIT_COMM_ERR_INT                       BIT(4)
+#define TPS6594_BIT_READBACK_ERR_INT                   BIT(5)
+#define TPS6594_BIT_ESM_INT                            BIT(6)
+#define TPS6594_BIT_WD_INT                             BIT(7)
+
+/* INT_COMM_ERR register field definition */
+#define TPS6594_BIT_COMM_FRM_ERR_INT                   BIT(0)
+#define TPS6594_BIT_COMM_CRC_ERR_INT                   BIT(1)
+#define TPS6594_BIT_COMM_ADR_ERR_INT                   BIT(3)
+#define TPS6594_BIT_I2C2_CRC_ERR_INT                   BIT(5)
+#define TPS6594_BIT_I2C2_ADR_ERR_INT                   BIT(7)
+
+/* INT_READBACK_ERR register field definition */
+#define TPS6594_BIT_EN_DRV_READBACK_INT                        BIT(0)
+#define TPS6594_BIT_NRSTOUT_SOC_READBACK_INT           BIT(3)
+
+/* INT_ESM register field definition */
+#define TPS6594_BIT_ESM_SOC_PIN_INT                    BIT(0)
+#define TPS6594_BIT_ESM_SOC_FAIL_INT                   BIT(1)
+#define TPS6594_BIT_ESM_SOC_RST_INT                    BIT(2)
+#define TPS6594_BIT_ESM_MCU_PIN_INT                    BIT(3)
+#define TPS6594_BIT_ESM_MCU_FAIL_INT                   BIT(4)
+#define TPS6594_BIT_ESM_MCU_RST_INT                    BIT(5)
+
+/* STAT_BUCKX register field definition */
+#define TPS6594_BIT_BUCKX_OV_STAT(buck_inst)           BIT(((buck_inst) << 2) % 8)
+#define TPS6594_BIT_BUCKX_UV_STAT(buck_inst)           BIT(((buck_inst) << 2) % 8 + 1)
+#define TPS6594_BIT_BUCKX_ILIM_STAT(buck_inst)         BIT(((buck_inst) << 2) % 8 + 3)
+
+/* STAT_LDOX register field definition */
+#define TPS6594_BIT_LDOX_OV_STAT(ldo_inst)             BIT(((ldo_inst) << 2) % 8)
+#define TPS6594_BIT_LDOX_UV_STAT(ldo_inst)             BIT(((ldo_inst) << 2) % 8 + 1)
+#define TPS6594_BIT_LDOX_ILIM_STAT(ldo_inst)           BIT(((ldo_inst) << 2) % 8 + 3)
+
+/* STAT_VMON register field definition */
+#define TPS6594_BIT_VCCA_OV_STAT                       BIT(0)
+#define TPS6594_BIT_VCCA_UV_STAT                       BIT(1)
+#define TPS6594_BIT_VMON1_OV_STAT                      BIT(2)
+#define TPS6594_BIT_VMON1_UV_STAT                      BIT(3)
+#define TPS6594_BIT_VMON2_OV_STAT                      BIT(5)
+#define TPS6594_BIT_VMON2_UV_STAT                      BIT(6)
+
+/* STAT_STARTUP register field definition */
+#define TPS6594_BIT_ENABLE_STAT                                BIT(1)
+
+/* STAT_MISC register field definition */
+#define TPS6594_BIT_EXT_CLK_STAT                       BIT(1)
+#define TPS6594_BIT_TWARN_STAT                         BIT(3)
+
+/* STAT_MODERATE_ERR register field definition */
+#define TPS6594_BIT_TSD_ORD_STAT                       BIT(0)
+
+/* STAT_SEVERE_ERR register field definition */
+#define TPS6594_BIT_TSD_IMM_STAT                       BIT(0)
+#define TPS6594_BIT_VCCA_OVP_STAT                      BIT(1)
+
+/* STAT_READBACK_ERR register field definition */
+#define TPS6594_BIT_EN_DRV_READBACK_STAT               BIT(0)
+#define TPS6594_BIT_NINT_READBACK_STAT                 BIT(1)
+#define TPS6594_BIT_NRSTOUT_READBACK_STAT              BIT(2)
+#define TPS6594_BIT_NRSTOUT_SOC_READBACK_STAT          BIT(3)
+
+/* PGOOD_SEL_1 register field definition */
+#define TPS6594_MASK_PGOOD_SEL_BUCK1                   GENMASK(1, 0)
+#define TPS6594_MASK_PGOOD_SEL_BUCK2                   GENMASK(3, 2)
+#define TPS6594_MASK_PGOOD_SEL_BUCK3                   GENMASK(5, 4)
+#define TPS6594_MASK_PGOOD_SEL_BUCK4                   GENMASK(7, 6)
+
+/* PGOOD_SEL_2 register field definition */
+#define TPS6594_MASK_PGOOD_SEL_BUCK5                   GENMASK(1, 0)
+
+/* PGOOD_SEL_3 register field definition */
+#define TPS6594_MASK_PGOOD_SEL_LDO1                    GENMASK(1, 0)
+#define TPS6594_MASK_PGOOD_SEL_LDO2                    GENMASK(3, 2)
+#define TPS6594_MASK_PGOOD_SEL_LDO3                    GENMASK(5, 4)
+#define TPS6594_MASK_PGOOD_SEL_LDO4                    GENMASK(7, 6)
+
+/* PGOOD_SEL_4 register field definition */
+#define TPS6594_BIT_PGOOD_SEL_VCCA                     BIT(0)
+#define TPS6594_BIT_PGOOD_SEL_VMON1                    BIT(1)
+#define TPS6594_BIT_PGOOD_SEL_VMON2                    BIT(2)
+#define TPS6594_BIT_PGOOD_SEL_TDIE_WARN                        BIT(3)
+#define TPS6594_BIT_PGOOD_SEL_NRSTOUT                  BIT(4)
+#define TPS6594_BIT_PGOOD_SEL_NRSTOUT_SOC              BIT(5)
+#define TPS6594_BIT_PGOOD_POL                          BIT(6)
+#define TPS6594_BIT_PGOOD_WINDOW                       BIT(7)
+
+/* PLL_CTRL register field definition */
+#define TPS6594_MASK_EXT_CLK_FREQ                      GENMASK(1, 0)
+
+/* CONFIG_1 register field definition */
+#define TPS6594_BIT_TWARN_LEVEL                                BIT(0)
+#define TPS6594_BIT_TSD_ORD_LEVEL                      BIT(1)
+#define TPS6594_BIT_I2C1_HS                            BIT(3)
+#define TPS6594_BIT_I2C2_HS                            BIT(4)
+#define TPS6594_BIT_EN_ILIM_FSM_CTRL                   BIT(5)
+#define TPS6594_BIT_NSLEEP1_MASK                       BIT(6)
+#define TPS6594_BIT_NSLEEP2_MASK                       BIT(7)
+
+/* CONFIG_2 register field definition */
+#define TPS6594_BIT_BB_CHARGER_EN                      BIT(0)
+#define TPS6594_BIT_BB_ICHR                            BIT(1)
+#define TPS6594_MASK_BB_VEOC                           GENMASK(3, 2)
+#define TPS6594_BB_EOC_RDY                             BIT(7)
+
+/* ENABLE_DRV_REG register field definition */
+#define TPS6594_BIT_ENABLE_DRV                         BIT(0)
+
+/* MISC_CTRL register field definition */
+#define TPS6594_BIT_NRSTOUT                            BIT(0)
+#define TPS6594_BIT_NRSTOUT_SOC                                BIT(1)
+#define TPS6594_BIT_LPM_EN                             BIT(2)
+#define TPS6594_BIT_CLKMON_EN                          BIT(3)
+#define TPS6594_BIT_AMUXOUT_EN                         BIT(4)
+#define TPS6594_BIT_SEL_EXT_CLK                                BIT(5)
+#define TPS6594_MASK_SYNCCLKOUT_FREQ_SEL               GENMASK(7, 6)
+
+/* ENABLE_DRV_STAT register field definition */
+#define TPS6594_BIT_EN_DRV_IN                          BIT(0)
+#define TPS6594_BIT_NRSTOUT_IN                         BIT(1)
+#define TPS6594_BIT_NRSTOUT_SOC_IN                     BIT(2)
+#define TPS6594_BIT_FORCE_EN_DRV_LOW                   BIT(3)
+#define TPS6594_BIT_SPMI_LPM_EN                                BIT(4)
+
+/* RECOV_CNT_REG_1 register field definition */
+#define TPS6594_MASK_RECOV_CNT                         GENMASK(3, 0)
+
+/* RECOV_CNT_REG_2 register field definition */
+#define TPS6594_MASK_RECOV_CNT_THR                     GENMASK(3, 0)
+#define TPS6594_BIT_RECOV_CNT_CLR                      BIT(4)
+
+/* FSM_I2C_TRIGGERS register field definition */
+#define TPS6594_BIT_TRIGGER_I2C(bit)                   BIT(bit)
+
+/* FSM_NSLEEP_TRIGGERS register field definition */
+#define TPS6594_BIT_NSLEEP1B                           BIT(0)
+#define TPS6594_BIT_NSLEEP2B                           BIT(1)
+
+/* BUCK_RESET_REG register field definition */
+#define TPS6594_BIT_BUCKX_RESET(buck_inst)             BIT(buck_inst)
+
+/* SPREAD_SPECTRUM_1 register field definition */
+#define TPS6594_MASK_SS_DEPTH                          GENMASK(1, 0)
+#define TPS6594_BIT_SS_EN                              BIT(2)
+
+/* FREQ_SEL register field definition */
+#define TPS6594_BIT_BUCKX_FREQ_SEL(buck_inst)          BIT(buck_inst)
+
+/* FSM_STEP_SIZE register field definition */
+#define TPS6594_MASK_PFSM_DELAY_STEP                   GENMASK(4, 0)
+
+/* LDO_RV_TIMEOUT_REG_1 register field definition */
+#define TPS6594_MASK_LDO1_RV_TIMEOUT                   GENMASK(3, 0)
+#define TPS6594_MASK_LDO2_RV_TIMEOUT                   GENMASK(7, 4)
+
+/* LDO_RV_TIMEOUT_REG_2 register field definition */
+#define TPS6594_MASK_LDO3_RV_TIMEOUT                   GENMASK(3, 0)
+#define TPS6594_MASK_LDO4_RV_TIMEOUT                   GENMASK(7, 4)
+
+/* USER_SPARE_REGS register field definition */
+#define TPS6594_BIT_USER_SPARE(bit)                    BIT(bit)
+
+/* ESM_MCU_START_REG register field definition */
+#define TPS6594_BIT_ESM_MCU_START                      BIT(0)
+
+/* ESM_MCU_MODE_CFG register field definition */
+#define TPS6594_MASK_ESM_MCU_ERR_CNT_TH                        GENMASK(3, 0)
+#define TPS6594_BIT_ESM_MCU_ENDRV                      BIT(5)
+#define TPS6594_BIT_ESM_MCU_EN                         BIT(6)
+#define TPS6594_BIT_ESM_MCU_MODE                       BIT(7)
+
+/* ESM_MCU_ERR_CNT_REG register field definition */
+#define TPS6594_MASK_ESM_MCU_ERR_CNT                   GENMASK(4, 0)
+
+/* ESM_SOC_START_REG register field definition */
+#define TPS6594_BIT_ESM_SOC_START                      BIT(0)
+
+/* ESM_SOC_MODE_CFG register field definition */
+#define TPS6594_MASK_ESM_SOC_ERR_CNT_TH                        GENMASK(3, 0)
+#define TPS6594_BIT_ESM_SOC_ENDRV                      BIT(5)
+#define TPS6594_BIT_ESM_SOC_EN                         BIT(6)
+#define TPS6594_BIT_ESM_SOC_MODE                       BIT(7)
+
+/* ESM_SOC_ERR_CNT_REG register field definition */
+#define TPS6594_MASK_ESM_SOC_ERR_CNT                   GENMASK(4, 0)
+
+/* REGISTER_LOCK register field definition */
+#define TPS6594_BIT_REGISTER_LOCK_STATUS               BIT(0)
+
+/* VMON_CONF register field definition */
+#define TPS6594_MASK_VMON1_SLEW_RATE                   GENMASK(2, 0)
+#define TPS6594_MASK_VMON2_SLEW_RATE                   GENMASK(5, 3)
+
+/* SOFT_REBOOT_REG register field definition */
+#define TPS6594_BIT_SOFT_REBOOT                                BIT(0)
+
+/* RTC_SECONDS & ALARM_SECONDS register field definition */
+#define TPS6594_MASK_SECOND_0                          GENMASK(3, 0)
+#define TPS6594_MASK_SECOND_1                          GENMASK(6, 4)
+
+/* RTC_MINUTES & ALARM_MINUTES register field definition */
+#define TPS6594_MASK_MINUTE_0                          GENMASK(3, 0)
+#define TPS6594_MASK_MINUTE_1                          GENMASK(6, 4)
+
+/* RTC_HOURS & ALARM_HOURS register field definition */
+#define TPS6594_MASK_HOUR_0                            GENMASK(3, 0)
+#define TPS6594_MASK_HOUR_1                            GENMASK(5, 4)
+#define TPS6594_BIT_PM_NAM                             BIT(7)
+
+/* RTC_DAYS & ALARM_DAYS register field definition */
+#define TPS6594_MASK_DAY_0                             GENMASK(3, 0)
+#define TPS6594_MASK_DAY_1                             GENMASK(5, 4)
+
+/* RTC_MONTHS & ALARM_MONTHS register field definition */
+#define TPS6594_MASK_MONTH_0                           GENMASK(3, 0)
+#define TPS6594_BIT_MONTH_1                            BIT(4)
+
+/* RTC_YEARS & ALARM_YEARS register field definition */
+#define TPS6594_MASK_YEAR_0                            GENMASK(3, 0)
+#define TPS6594_MASK_YEAR_1                            GENMASK(7, 4)
+
+/* RTC_WEEKS register field definition */
+#define TPS6594_MASK_WEEK                              GENMASK(2, 0)
+
+/* RTC_CTRL_1 register field definition */
+#define TPS6594_BIT_STOP_RTC                           BIT(0)
+#define TPS6594_BIT_ROUND_30S                          BIT(1)
+#define TPS6594_BIT_AUTO_COMP                          BIT(2)
+#define TPS6594_BIT_MODE_12_24                         BIT(3)
+#define TPS6594_BIT_SET_32_COUNTER                     BIT(5)
+#define TPS6594_BIT_GET_TIME                           BIT(6)
+#define TPS6594_BIT_RTC_V_OPT                          BIT(7)
+
+/* RTC_CTRL_2 register field definition */
+#define TPS6594_BIT_XTAL_EN                            BIT(0)
+#define TPS6594_MASK_XTAL_SEL                          GENMASK(2, 1)
+#define TPS6594_BIT_LP_STANDBY_SEL                     BIT(3)
+#define TPS6594_BIT_FAST_BIST                          BIT(4)
+#define TPS6594_MASK_STARTUP_DEST                      GENMASK(6, 5)
+#define TPS6594_BIT_FIRST_STARTUP_DONE                 BIT(7)
+
+/* RTC_STATUS register field definition */
+#define TPS6594_BIT_RUN                                        BIT(1)
+#define TPS6594_BIT_TIMER                              BIT(5)
+#define TPS6594_BIT_ALARM                              BIT(6)
+#define TPS6594_BIT_POWER_UP                           BIT(7)
+
+/* RTC_INTERRUPTS register field definition */
+#define TPS6594_MASK_EVERY                             GENMASK(1, 0)
+#define TPS6594_BIT_IT_TIMER                           BIT(2)
+#define TPS6594_BIT_IT_ALARM                           BIT(3)
+
+/* RTC_RESET_STATUS register field definition */
+#define TPS6594_BIT_RESET_STATUS_RTC                   BIT(0)
+
+/* SERIAL_IF_CONFIG register field definition */
+#define TPS6594_BIT_I2C_SPI_SEL                                BIT(0)
+#define TPS6594_BIT_I2C1_SPI_CRC_EN                    BIT(1)
+#define TPS6594_BIT_I2C2_CRC_EN                                BIT(2)
+#define TPS6594_MASK_T_CRC                             GENMASK(7, 3)
+
+/* WD_QUESTION_ANSW_CNT register field definition */
+#define TPS6594_MASK_WD_QUESTION                       GENMASK(3, 0)
+#define TPS6594_MASK_WD_ANSW_CNT                       GENMASK(5, 4)
+
+/* WD_MODE_REG register field definition */
+#define TPS6594_BIT_WD_RETURN_LONGWIN                  BIT(0)
+#define TPS6594_BIT_WD_MODE_SELECT                     BIT(1)
+#define TPS6594_BIT_WD_PWRHOLD                         BIT(2)
+
+/* WD_QA_CFG register field definition */
+#define TPS6594_MASK_WD_QUESTION_SEED                  GENMASK(3, 0)
+#define TPS6594_MASK_WD_QA_LFSR                                GENMASK(5, 4)
+#define TPS6594_MASK_WD_QA_FDBK                                GENMASK(7, 6)
+
+/* WD_ERR_STATUS register field definition */
+#define TPS6594_BIT_WD_LONGWIN_TIMEOUT_INT             BIT(0)
+#define TPS6594_BIT_WD_TIMEOUT                         BIT(1)
+#define TPS6594_BIT_WD_TRIG_EARLY                      BIT(2)
+#define TPS6594_BIT_WD_ANSW_EARLY                      BIT(3)
+#define TPS6594_BIT_WD_SEQ_ERR                         BIT(4)
+#define TPS6594_BIT_WD_ANSW_ERR                                BIT(5)
+#define TPS6594_BIT_WD_FAIL_INT                                BIT(6)
+#define TPS6594_BIT_WD_RST_INT                         BIT(7)
+
+/* WD_THR_CFG register field definition */
+#define TPS6594_MASK_WD_RST_TH                         GENMASK(2, 0)
+#define TPS6594_MASK_WD_FAIL_TH                                GENMASK(5, 3)
+#define TPS6594_BIT_WD_EN                              BIT(6)
+#define TPS6594_BIT_WD_RST_EN                          BIT(7)
+
+/* WD_FAIL_CNT_REG register field definition */
+#define TPS6594_MASK_WD_FAIL_CNT                       GENMASK(3, 0)
+#define TPS6594_BIT_WD_FIRST_OK                                BIT(5)
+#define TPS6594_BIT_WD_BAD_EVENT                       BIT(6)
+
+/* CRC8 polynomial for I2C & SPI protocols */
+#define TPS6594_CRC8_POLYNOMIAL        0x07
+
+/* IRQs */
+enum tps6594_irqs {
+       /* INT_BUCK1_2 register */
+       TPS6594_IRQ_BUCK1_OV,
+       TPS6594_IRQ_BUCK1_UV,
+       TPS6594_IRQ_BUCK1_SC,
+       TPS6594_IRQ_BUCK1_ILIM,
+       TPS6594_IRQ_BUCK2_OV,
+       TPS6594_IRQ_BUCK2_UV,
+       TPS6594_IRQ_BUCK2_SC,
+       TPS6594_IRQ_BUCK2_ILIM,
+       /* INT_BUCK3_4 register */
+       TPS6594_IRQ_BUCK3_OV,
+       TPS6594_IRQ_BUCK3_UV,
+       TPS6594_IRQ_BUCK3_SC,
+       TPS6594_IRQ_BUCK3_ILIM,
+       TPS6594_IRQ_BUCK4_OV,
+       TPS6594_IRQ_BUCK4_UV,
+       TPS6594_IRQ_BUCK4_SC,
+       TPS6594_IRQ_BUCK4_ILIM,
+       /* INT_BUCK5 register */
+       TPS6594_IRQ_BUCK5_OV,
+       TPS6594_IRQ_BUCK5_UV,
+       TPS6594_IRQ_BUCK5_SC,
+       TPS6594_IRQ_BUCK5_ILIM,
+       /* INT_LDO1_2 register */
+       TPS6594_IRQ_LDO1_OV,
+       TPS6594_IRQ_LDO1_UV,
+       TPS6594_IRQ_LDO1_SC,
+       TPS6594_IRQ_LDO1_ILIM,
+       TPS6594_IRQ_LDO2_OV,
+       TPS6594_IRQ_LDO2_UV,
+       TPS6594_IRQ_LDO2_SC,
+       TPS6594_IRQ_LDO2_ILIM,
+       /* INT_LDO3_4 register */
+       TPS6594_IRQ_LDO3_OV,
+       TPS6594_IRQ_LDO3_UV,
+       TPS6594_IRQ_LDO3_SC,
+       TPS6594_IRQ_LDO3_ILIM,
+       TPS6594_IRQ_LDO4_OV,
+       TPS6594_IRQ_LDO4_UV,
+       TPS6594_IRQ_LDO4_SC,
+       TPS6594_IRQ_LDO4_ILIM,
+       /* INT_VMON register */
+       TPS6594_IRQ_VCCA_OV,
+       TPS6594_IRQ_VCCA_UV,
+       TPS6594_IRQ_VMON1_OV,
+       TPS6594_IRQ_VMON1_UV,
+       TPS6594_IRQ_VMON1_RV,
+       TPS6594_IRQ_VMON2_OV,
+       TPS6594_IRQ_VMON2_UV,
+       TPS6594_IRQ_VMON2_RV,
+       /* INT_GPIO register */
+       TPS6594_IRQ_GPIO9,
+       TPS6594_IRQ_GPIO10,
+       TPS6594_IRQ_GPIO11,
+       /* INT_GPIO1_8 register */
+       TPS6594_IRQ_GPIO1,
+       TPS6594_IRQ_GPIO2,
+       TPS6594_IRQ_GPIO3,
+       TPS6594_IRQ_GPIO4,
+       TPS6594_IRQ_GPIO5,
+       TPS6594_IRQ_GPIO6,
+       TPS6594_IRQ_GPIO7,
+       TPS6594_IRQ_GPIO8,
+       /* INT_STARTUP register */
+       TPS6594_IRQ_NPWRON_START,
+       TPS6594_IRQ_ENABLE,
+       TPS6594_IRQ_FSD,
+       TPS6594_IRQ_SOFT_REBOOT,
+       /* INT_MISC register */
+       TPS6594_IRQ_BIST_PASS,
+       TPS6594_IRQ_EXT_CLK,
+       TPS6594_IRQ_TWARN,
+       /* INT_MODERATE_ERR register */
+       TPS6594_IRQ_TSD_ORD,
+       TPS6594_IRQ_BIST_FAIL,
+       TPS6594_IRQ_REG_CRC_ERR,
+       TPS6594_IRQ_RECOV_CNT,
+       TPS6594_IRQ_SPMI_ERR,
+       TPS6594_IRQ_NPWRON_LONG,
+       TPS6594_IRQ_NINT_READBACK,
+       TPS6594_IRQ_NRSTOUT_READBACK,
+       /* INT_SEVERE_ERR register */
+       TPS6594_IRQ_TSD_IMM,
+       TPS6594_IRQ_VCCA_OVP,
+       TPS6594_IRQ_PFSM_ERR,
+       /* INT_FSM_ERR register */
+       TPS6594_IRQ_IMM_SHUTDOWN,
+       TPS6594_IRQ_ORD_SHUTDOWN,
+       TPS6594_IRQ_MCU_PWR_ERR,
+       TPS6594_IRQ_SOC_PWR_ERR,
+       /* INT_COMM_ERR register */
+       TPS6594_IRQ_COMM_FRM_ERR,
+       TPS6594_IRQ_COMM_CRC_ERR,
+       TPS6594_IRQ_COMM_ADR_ERR,
+       TPS6594_IRQ_I2C2_CRC_ERR,
+       TPS6594_IRQ_I2C2_ADR_ERR,
+       /* INT_READBACK_ERR register */
+       TPS6594_IRQ_EN_DRV_READBACK,
+       TPS6594_IRQ_NRSTOUT_SOC_READBACK,
+       /* INT_ESM register */
+       TPS6594_IRQ_ESM_SOC_PIN,
+       TPS6594_IRQ_ESM_SOC_FAIL,
+       TPS6594_IRQ_ESM_SOC_RST,
+       /* RTC_STATUS register */
+       TPS6594_IRQ_TIMER,
+       TPS6594_IRQ_ALARM,
+       TPS6594_IRQ_POWER_UP,
+};
+
+#define TPS6594_IRQ_NAME_BUCK1_OV              "buck1_ov"
+#define TPS6594_IRQ_NAME_BUCK1_UV              "buck1_uv"
+#define TPS6594_IRQ_NAME_BUCK1_SC              "buck1_sc"
+#define TPS6594_IRQ_NAME_BUCK1_ILIM            "buck1_ilim"
+#define TPS6594_IRQ_NAME_BUCK2_OV              "buck2_ov"
+#define TPS6594_IRQ_NAME_BUCK2_UV              "buck2_uv"
+#define TPS6594_IRQ_NAME_BUCK2_SC              "buck2_sc"
+#define TPS6594_IRQ_NAME_BUCK2_ILIM            "buck2_ilim"
+#define TPS6594_IRQ_NAME_BUCK3_OV              "buck3_ov"
+#define TPS6594_IRQ_NAME_BUCK3_UV              "buck3_uv"
+#define TPS6594_IRQ_NAME_BUCK3_SC              "buck3_sc"
+#define TPS6594_IRQ_NAME_BUCK3_ILIM            "buck3_ilim"
+#define TPS6594_IRQ_NAME_BUCK4_OV              "buck4_ov"
+#define TPS6594_IRQ_NAME_BUCK4_UV              "buck4_uv"
+#define TPS6594_IRQ_NAME_BUCK4_SC              "buck4_sc"
+#define TPS6594_IRQ_NAME_BUCK4_ILIM            "buck4_ilim"
+#define TPS6594_IRQ_NAME_BUCK5_OV              "buck5_ov"
+#define TPS6594_IRQ_NAME_BUCK5_UV              "buck5_uv"
+#define TPS6594_IRQ_NAME_BUCK5_SC              "buck5_sc"
+#define TPS6594_IRQ_NAME_BUCK5_ILIM            "buck5_ilim"
+#define TPS6594_IRQ_NAME_LDO1_OV               "ldo1_ov"
+#define TPS6594_IRQ_NAME_LDO1_UV               "ldo1_uv"
+#define TPS6594_IRQ_NAME_LDO1_SC               "ldo1_sc"
+#define TPS6594_IRQ_NAME_LDO1_ILIM             "ldo1_ilim"
+#define TPS6594_IRQ_NAME_LDO2_OV               "ldo2_ov"
+#define TPS6594_IRQ_NAME_LDO2_UV               "ldo2_uv"
+#define TPS6594_IRQ_NAME_LDO2_SC               "ldo2_sc"
+#define TPS6594_IRQ_NAME_LDO2_ILIM             "ldo2_ilim"
+#define TPS6594_IRQ_NAME_LDO3_OV               "ldo3_ov"
+#define TPS6594_IRQ_NAME_LDO3_UV               "ldo3_uv"
+#define TPS6594_IRQ_NAME_LDO3_SC               "ldo3_sc"
+#define TPS6594_IRQ_NAME_LDO3_ILIM             "ldo3_ilim"
+#define TPS6594_IRQ_NAME_LDO4_OV               "ldo4_ov"
+#define TPS6594_IRQ_NAME_LDO4_UV               "ldo4_uv"
+#define TPS6594_IRQ_NAME_LDO4_SC               "ldo4_sc"
+#define TPS6594_IRQ_NAME_LDO4_ILIM             "ldo4_ilim"
+#define TPS6594_IRQ_NAME_VCCA_OV               "vcca_ov"
+#define TPS6594_IRQ_NAME_VCCA_UV               "vcca_uv"
+#define TPS6594_IRQ_NAME_VMON1_OV              "vmon1_ov"
+#define TPS6594_IRQ_NAME_VMON1_UV              "vmon1_uv"
+#define TPS6594_IRQ_NAME_VMON1_RV              "vmon1_rv"
+#define TPS6594_IRQ_NAME_VMON2_OV              "vmon2_ov"
+#define TPS6594_IRQ_NAME_VMON2_UV              "vmon2_uv"
+#define TPS6594_IRQ_NAME_VMON2_RV              "vmon2_rv"
+#define TPS6594_IRQ_NAME_GPIO9                 "gpio9"
+#define TPS6594_IRQ_NAME_GPIO10                        "gpio10"
+#define TPS6594_IRQ_NAME_GPIO11                        "gpio11"
+#define TPS6594_IRQ_NAME_GPIO1                 "gpio1"
+#define TPS6594_IRQ_NAME_GPIO2                 "gpio2"
+#define TPS6594_IRQ_NAME_GPIO3                 "gpio3"
+#define TPS6594_IRQ_NAME_GPIO4                 "gpio4"
+#define TPS6594_IRQ_NAME_GPIO5                 "gpio5"
+#define TPS6594_IRQ_NAME_GPIO6                 "gpio6"
+#define TPS6594_IRQ_NAME_GPIO7                 "gpio7"
+#define TPS6594_IRQ_NAME_GPIO8                 "gpio8"
+#define TPS6594_IRQ_NAME_NPWRON_START          "npwron_start"
+#define TPS6594_IRQ_NAME_ENABLE                        "enable"
+#define TPS6594_IRQ_NAME_FSD                   "fsd"
+#define TPS6594_IRQ_NAME_SOFT_REBOOT           "soft_reboot"
+#define TPS6594_IRQ_NAME_BIST_PASS             "bist_pass"
+#define TPS6594_IRQ_NAME_EXT_CLK               "ext_clk"
+#define TPS6594_IRQ_NAME_TWARN                 "twarn"
+#define TPS6594_IRQ_NAME_TSD_ORD               "tsd_ord"
+#define TPS6594_IRQ_NAME_BIST_FAIL             "bist_fail"
+#define TPS6594_IRQ_NAME_REG_CRC_ERR           "reg_crc_err"
+#define TPS6594_IRQ_NAME_RECOV_CNT             "recov_cnt"
+#define TPS6594_IRQ_NAME_SPMI_ERR              "spmi_err"
+#define TPS6594_IRQ_NAME_NPWRON_LONG           "npwron_long"
+#define TPS6594_IRQ_NAME_NINT_READBACK         "nint_readback"
+#define TPS6594_IRQ_NAME_NRSTOUT_READBACK      "nrstout_readback"
+#define TPS6594_IRQ_NAME_TSD_IMM               "tsd_imm"
+#define TPS6594_IRQ_NAME_VCCA_OVP              "vcca_ovp"
+#define TPS6594_IRQ_NAME_PFSM_ERR              "pfsm_err"
+#define TPS6594_IRQ_NAME_IMM_SHUTDOWN          "imm_shutdown"
+#define TPS6594_IRQ_NAME_ORD_SHUTDOWN          "ord_shutdown"
+#define TPS6594_IRQ_NAME_MCU_PWR_ERR           "mcu_pwr_err"
+#define TPS6594_IRQ_NAME_SOC_PWR_ERR           "soc_pwr_err"
+#define TPS6594_IRQ_NAME_COMM_FRM_ERR          "comm_frm_err"
+#define TPS6594_IRQ_NAME_COMM_CRC_ERR          "comm_crc_err"
+#define TPS6594_IRQ_NAME_COMM_ADR_ERR          "comm_adr_err"
+#define TPS6594_IRQ_NAME_EN_DRV_READBACK       "en_drv_readback"
+#define TPS6594_IRQ_NAME_NRSTOUT_SOC_READBACK  "nrstout_soc_readback"
+#define TPS6594_IRQ_NAME_ESM_SOC_PIN           "esm_soc_pin"
+#define TPS6594_IRQ_NAME_ESM_SOC_FAIL          "esm_soc_fail"
+#define TPS6594_IRQ_NAME_ESM_SOC_RST           "esm_soc_rst"
+#define TPS6594_IRQ_NAME_TIMER                 "timer"
+#define TPS6594_IRQ_NAME_ALARM                 "alarm"
+#define TPS6594_IRQ_NAME_POWERUP               "powerup"
+
+/**
+ * struct tps6594 - device private data structure
+ *
+ * @dev:      MFD parent device
+ * @chip_id:  chip ID
+ * @reg:      I2C slave address or SPI chip select number
+ * @use_crc:  if true, use CRC for I2C and SPI interface protocols
+ * @regmap:   regmap for accessing the device registers
+ * @irq:      irq generated by the device
+ * @irq_data: regmap irq data used for the irq chip
+ */
+struct tps6594 {
+       struct device *dev;
+       unsigned long chip_id;
+       unsigned short reg;
+       bool use_crc;
+       struct regmap *regmap;
+       int irq;
+       struct regmap_irq_chip_data *irq_data;
+};
+
+bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg);
+int tps6594_device_init(struct tps6594 *tps, bool enable_crc);
+
+#endif /*  __LINUX_MFD_TPS6594_H */
index d3b4a3d4514aba340650c673b8a34c05132cb348..c6ef7d68eb9abb6f9a1269e48913766ceb09cc9e 100644 (file)
@@ -758,6 +758,8 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
                                       int min_uA, int max_uA);
 int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
 void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
+int regulator_find_closest_bigger(unsigned int target, const unsigned int *table,
+                                 unsigned int num_sel, unsigned int *sel);
 int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay);
 int regulator_sync_voltage_rdev(struct regulator_dev *rdev);
 
index bdcf83cd719ef522babe97261f3578bb76e6fe1e..c71a6a9fce7ae77e8834c31b9d8291b5da442e06 100644 (file)
@@ -41,15 +41,12 @@ enum {
        MT6358_ID_VIO28,
        MT6358_ID_VA12,
        MT6358_ID_VRF18,
-       MT6358_ID_VCN33_BT,
-       MT6358_ID_VCN33_WIFI,
+       MT6358_ID_VCN33,
        MT6358_ID_VCAMA2,
        MT6358_ID_VMC,
        MT6358_ID_VLDO28,
        MT6358_ID_VAUD28,
        MT6358_ID_VSIM2,
-       MT6358_ID_VCORE_SSHUB,
-       MT6358_ID_VSRAM_OTHERS_SSHUB,
        MT6358_ID_RG_MAX,
 };
 
@@ -85,13 +82,10 @@ enum {
        MT6366_ID_VIO28,
        MT6366_ID_VA12,
        MT6366_ID_VRF18,
-       MT6366_ID_VCN33_BT,
-       MT6366_ID_VCN33_WIFI,
+       MT6366_ID_VCN33,
        MT6366_ID_VMC,
        MT6366_ID_VAUD28,
        MT6366_ID_VSIM2,
-       MT6366_ID_VCORE_SSHUB,
-       MT6366_ID_VSRAM_OTHERS_SSHUB,
        MT6366_ID_RG_MAX,
 };
 
index c55a0bc8cb0e908f41f04d746fb6d00cf49938e7..821a19135bb66f59ee43c8332fa52f1734d8a2ab 100644 (file)
@@ -490,9 +490,13 @@ int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq,
                           unsigned int *index, unsigned long *res_freq,
                           bool exact);
 
+void geni_se_tx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len);
+
 int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
                        dma_addr_t *iova);
 
+void geni_se_rx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len);
+
 int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
                        dma_addr_t *iova);
 
index 8020097d4e4c8078c9bb00c8ae87d96c96ab7c7e..0c4c5cbaa809a3d8ec9b5e5494a2a37ef10f4704 100644 (file)
@@ -1313,7 +1313,7 @@ config SND_SOC_RK3328
 
 config SND_SOC_RK817
        tristate "Rockchip RK817 audio CODEC"
-       depends on MFD_RK808 || COMPILE_TEST
+       depends on MFD_RK8XX || COMPILE_TEST
 
 config SND_SOC_RL6231
        tristate