Merge tag 'regulator-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 Sep 2019 20:58:43 +0000 (13:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 Sep 2019 20:58:43 +0000 (13:58 -0700)
Pull regulator updates from Mark Brown:
 "A small update for the regualtor API for this cycle, some small fixes
  and a bunch of new devices but none of them very big.

  The most stand out thing is the regulator-fixed-clock driver which is
  for regulators where the enable control is done by using a clock
  instead of a GPIO or register write, a novel hardware design that had
  not previously come up.

  Summary:

   - Added a keyword pattern for regulator_get_optional() since usage of
     that API generally needs extra review.

   - Operating mode and suspend state support for act8865.

   - New device support for Active Semiconductor ACT8600 chargers,
     Mediatek MT6358, Qualcomm SM8150, regulator-fixed-clock, and
     Synoptics SY20276, SY20278 and SY8824E"

* tag 'regulator-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (52 commits)
  regulator: core: Fix error return for /sys access
  regulator: da9211: fix obtaining "enable" GPIO
  regulator: max77686: fix obtaining "maxim,ena" GPIO
  regulator: uniphier: Add Pro5 USB3 VBUS support
  dt-bindings: regulator: add regulator-fixed-clock binding
  regulator: fixed: add possibility to enable by clock
  regulator: s2mps11: Consistently use local variable
  regulator: lp87565: Simplify lp87565_buck_set_ramp_delay
  regulator: slg51000: use devm_gpiod_get_optional() in probe
  regulator: lp8788-ldo: make array en_mask static const, makes object smaller
  regulator: tps65132: Stop parsing DT when gpio is not found
  regulator: Defer init completion for a while after late_initcall
  regulator: add missing 'static inline' to a helper's stub
  regulator: provide regulator_bulk_set_supply_names()
  MAINTAINERS: Add keyword pattern on regulator_get_optional()
  regulator: sy8824x: add prefixes to BUCK_EN and MODE macros
  regulator: sy8824x: use c++style for the comment block near SPDX
  regulator: mt6358: Add BROKEN dependency while waiting for MFD to merge
  regulator: mt6358: Add support for MT6358 regulator
  regulator: Add document for MT6358 regulator
  ...

35 files changed:
Documentation/devicetree/bindings/regulator/act8865-regulator.txt
Documentation/devicetree/bindings/regulator/fixed-regulator.yaml
Documentation/devicetree/bindings/regulator/mt6358-regulator.txt [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
Documentation/devicetree/bindings/regulator/sy8824x.txt [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/twl-regulator.txt
Documentation/devicetree/bindings/regulator/uniphier-regulator.txt
MAINTAINERS
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/act8865-regulator.c
drivers/regulator/core.c
drivers/regulator/da9062-regulator.c
drivers/regulator/da9063-regulator.c
drivers/regulator/da9211-regulator.c
drivers/regulator/fixed.c
drivers/regulator/helpers.c
drivers/regulator/lm363x-regulator.c
drivers/regulator/lp87565-regulator.c
drivers/regulator/lp8788-ldo.c
drivers/regulator/max77686-regulator.c
drivers/regulator/max8660.c
drivers/regulator/mt6358-regulator.c [new file with mode: 0644]
drivers/regulator/qcom-rpmh-regulator.c
drivers/regulator/rk808-regulator.c
drivers/regulator/s2mps11.c
drivers/regulator/slg51000-regulator.c
drivers/regulator/stm32-booster.c
drivers/regulator/sy8824x.c [new file with mode: 0644]
drivers/regulator/tps65132-regulator.c
drivers/regulator/twl6030-regulator.c
drivers/regulator/uniphier-regulator.c
include/dt-bindings/regulator/active-semi,8865-regulator.h [new file with mode: 0644]
include/linux/regulator/consumer.h
include/linux/regulator/mt6358-regulator.h [new file with mode: 0644]

index 3ae9f1088845ba4fecf43b90102256317f4b71e8..b9f58e480349896655d2d6d97881c641a2666fcb 100644 (file)
@@ -34,6 +34,9 @@ Optional input supply properties:
   - inl67-supply: The input supply for LDO_REG3 and LDO_REG4
 
 Any standard regulator properties can be used to configure the single regulator.
+regulator-initial-mode, regulator-allowed-modes and regulator-mode could be specified
+for act8865 using mode values from dt-bindings/regulator/active-semi,8865-regulator.h
+file.
 
 The valid names for regulators are:
        - for act8846:
@@ -47,6 +50,8 @@ The valid names for regulators are:
 Example:
 --------
 
+#include <dt-bindings/regulator/active-semi,8865-regulator.h>
+
                i2c1: i2c@f0018000 {
                        pmic: act8865@5b {
                                compatible = "active-semi,act8865";
@@ -65,9 +70,19 @@ Example:
                                                regulator-name = "VCC_1V2";
                                                regulator-min-microvolt = <1100000>;
                                                regulator-max-microvolt = <1300000>;
-                                               regulator-suspend-mem-microvolt = <1150000>;
-                                               regulator-suspend-standby-microvolt = <1150000>;
                                                regulator-always-on;
+
+                                               regulator-allowed-modes = <ACT8865_REGULATOR_MODE_FIXED>,
+                                                                         <ACT8865_REGULATOR_MODE_LOWPOWER>;
+                                               regulator-initial-mode = <ACT8865_REGULATOR_MODE_FIXED>;
+
+                                               regulator-state-mem {
+                                                       regulator-on-in-suspend;
+                                                       regulator-suspend-min-microvolt = <1150000>;
+                                                       regulator-suspend-max-microvolt = <1150000>;
+                                                       regulator-changeable-in-suspend;
+                                                       regulator-mode = <ACT8865_REGULATOR_MODE_LOWPOWER>;
+                                               };
                                        };
 
                                        vcc_3v3_reg: DCDC_REG3 {
@@ -82,6 +97,14 @@ Example:
                                                regulator-min-microvolt = <3300000>;
                                                regulator-max-microvolt = <3300000>;
                                                regulator-always-on;
+
+                                               regulator-allowed-modes = <ACT8865_REGULATOR_MODE_NORMAL>,
+                                                                         <ACT8865_REGULATOR_MODE_LOWPOWER>;
+                                               regulator-initial-mode = <ACT8865_REGULATOR_MODE_NORMAL>;
+
+                                               regulator-state-mem {
+                                                       regulator-off-in-suspend;
+                                               };
                                        };
 
                                        vddfuse_reg: LDO_REG2 {
index a650b457085de27f96a56dffd0026e8016cafb66..a78150c47aa2a67b8759c7a7c450e9edd20a375b 100644 (file)
@@ -19,9 +19,19 @@ description:
 allOf:
   - $ref: "regulator.yaml#"
 
+if:
+  properties:
+    compatible:
+      contains:
+        const: regulator-fixed-clock
+  required:
+    - clocks
+
 properties:
   compatible:
-    const: regulator-fixed
+    enum:
+      - const: regulator-fixed
+      - const: regulator-fixed-clock
 
   regulator-name: true
 
@@ -29,6 +39,13 @@ properties:
     description: gpio to use for enable control
     maxItems: 1
 
+  clocks:
+    description:
+      clock to use for enable control. This binding is only available if
+      the compatible is chosen to regulator-fixed-clock. The clock binding
+      is mandatory if compatible is chosen to regulator-fixed-clock.
+    maxItems: 1
+
   startup-delay-us:
     description: startup time in microseconds
     $ref: /schemas/types.yaml#/definitions/uint32
diff --git a/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
new file mode 100644 (file)
index 0000000..9a90a92
--- /dev/null
@@ -0,0 +1,358 @@
+MediaTek MT6358 Regulator
+
+All voltage regulators provided by the MT6358 PMIC are described as the
+subnodes of the MT6358 regulators node. Each regulator is named according
+to its regulator type, buck_<name> and ldo_<name>. The definition for each
+of these nodes is defined using the standard binding for regulators at
+Documentation/devicetree/bindings/regulator/regulator.txt.
+
+The valid names for regulators are::
+BUCK:
+  buck_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_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28,
+  ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18,
+  ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
+  ldo_vsim2
+
+Example:
+
+       pmic {
+               compatible = "mediatek,mt6358";
+
+               mt6358regulator: mt6358regulator {
+                       compatible = "mediatek,mt6358-regulator";
+
+                       mt6358_vdram1_reg: buck_vdram1 {
+                               regulator-compatible = "buck_vdram1";
+                               regulator-name = "vdram1";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <2087500>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-enable-ramp-delay = <0>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vcore_reg: buck_vcore {
+                               regulator-name = "vcore";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <200>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vpa_reg: buck_vpa {
+                               regulator-name = "vpa";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <3650000>;
+                               regulator-ramp-delay = <50000>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       mt6358_vproc11_reg: buck_vproc11 {
+                               regulator-name = "vproc11";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <200>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vproc12_reg: buck_vproc12 {
+                               regulator-name = "vproc12";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <200>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vgpu_reg: buck_vgpu {
+                               regulator-name = "vgpu";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <200>;
+                       };
+
+                       mt6358_vs2_reg: buck_vs2 {
+                               regulator-name = "vs2";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <2087500>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-enable-ramp-delay = <0>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vmodem_reg: buck_vmodem {
+                               regulator-name = "vmodem";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <900>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vs1_reg: buck_vs1 {
+                               regulator-name = "vs1";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <2587500>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-enable-ramp-delay = <0>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vdram2_reg: ldo_vdram2 {
+                               regulator-name = "vdram2";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <3300>;
+                       };
+
+                       mt6358_vsim1_reg: ldo_vsim1 {
+                               regulator-name = "vsim1";
+                               regulator-min-microvolt = <1700000>;
+                               regulator-max-microvolt = <3100000>;
+                               regulator-enable-ramp-delay = <540>;
+                       };
+
+                       mt6358_vibr_reg: ldo_vibr {
+                               regulator-name = "vibr";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-enable-ramp-delay = <60>;
+                       };
+
+                       mt6358_vrf12_reg: ldo_vrf12 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vrf12";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-enable-ramp-delay = <120>;
+                       };
+
+                       mt6358_vio18_reg: ldo_vio18 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vio18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <2700>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vusb_reg: ldo_vusb {
+                               regulator-name = "vusb";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3100000>;
+                               regulator-enable-ramp-delay = <270>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vcamio_reg: ldo_vcamio {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vcamio";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vcamd_reg: ldo_vcamd {
+                               regulator-name = "vcamd";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vcn18_reg: ldo_vcn18 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vcn18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vfe28_reg: ldo_vfe28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vfe28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vsram_proc11_reg: ldo_vsram_proc11 {
+                               regulator-name = "vsram_proc11";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <240>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vcn28_reg: ldo_vcn28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vcn28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vsram_others_reg: ldo_vsram_others {
+                               regulator-name = "vsram_others";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <240>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vsram_gpu_reg: ldo_vsram_gpu {
+                               regulator-name = "vsram_gpu";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <240>;
+                       };
+
+                       mt6358_vxo22_reg: ldo_vxo22 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vxo22";
+                               regulator-min-microvolt = <2200000>;
+                               regulator-max-microvolt = <2200000>;
+                               regulator-enable-ramp-delay = <120>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vefuse_reg: ldo_vefuse {
+                               regulator-name = "vefuse";
+                               regulator-min-microvolt = <1700000>;
+                               regulator-max-microvolt = <1900000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vaux18_reg: ldo_vaux18 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vaux18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vmch_reg: ldo_vmch {
+                               regulator-name = "vmch";
+                               regulator-min-microvolt = <2900000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-enable-ramp-delay = <60>;
+                       };
+
+                       mt6358_vbif28_reg: ldo_vbif28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vbif28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vsram_proc12_reg: ldo_vsram_proc12 {
+                               regulator-name = "vsram_proc12";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <240>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vcama1_reg: ldo_vcama1 {
+                               regulator-name = "vcama1";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vemc_reg: ldo_vemc {
+                               regulator-name = "vemc";
+                               regulator-min-microvolt = <2900000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-enable-ramp-delay = <60>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vio28_reg: ldo_vio28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vio28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_va12_reg: ldo_va12 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "va12";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-enable-ramp-delay = <270>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vrf18_reg: ldo_vrf18 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vrf18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               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";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3500000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vcama2_reg: ldo_vcama2 {
+                               regulator-name = "vcama2";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vmc_reg: ldo_vmc {
+                               regulator-name = "vmc";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-enable-ramp-delay = <60>;
+                       };
+
+                       mt6358_vldo28_reg: ldo_vldo28 {
+                               regulator-name = "vldo28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vaud28_reg: ldo_vaud28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vaud28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vsim2_reg: ldo_vsim2 {
+                               regulator-name = "vsim2";
+                               regulator-min-microvolt = <1700000>;
+                               regulator-max-microvolt = <3100000>;
+                               regulator-enable-ramp-delay = <540>;
+                       };
+               };
+       };
index 14d2eee96b3d5e075ed90af0ca9e042eae0ee065..bab9f71140b835161fba4895c7fddca8df786598 100644 (file)
@@ -22,9 +22,12 @@ RPMh resource.
 
 The names used for regulator nodes must match those supported by a given PMIC.
 Supported regulator node names:
+       PM8005:         smps1 - smps4
+       PM8009:         smps1 - smps2, ldo1 - ldo7
+       PM8150:         smps1 - smps10, ldo1 - ldo18
+       PM8150L:        smps1 - smps8, ldo1 - ldo11, bob, flash, rgb
        PM8998:         smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
        PMI8998:        bob
-       PM8005:         smps1 - smps4
 
 ========================
 First Level Nodes - PMIC
@@ -33,9 +36,13 @@ First Level Nodes - PMIC
 - compatible
        Usage:      required
        Value type: <string>
-       Definition: Must be one of: "qcom,pm8998-rpmh-regulators",
-                   "qcom,pmi8998-rpmh-regulators" or
-                   "qcom,pm8005-rpmh-regulators".
+       Definition: Must be one of below:
+                   "qcom,pm8005-rpmh-regulators"
+                   "qcom,pm8009-rpmh-regulators"
+                   "qcom,pm8150-rpmh-regulators"
+                   "qcom,pm8150l-rpmh-regulators"
+                   "qcom,pm8998-rpmh-regulators"
+                   "qcom,pmi8998-rpmh-regulators"
 
 - qcom,pmic-id
        Usage:      required
diff --git a/Documentation/devicetree/bindings/regulator/sy8824x.txt b/Documentation/devicetree/bindings/regulator/sy8824x.txt
new file mode 100644 (file)
index 0000000..c5e9585
--- /dev/null
@@ -0,0 +1,24 @@
+SY8824C/SY8824E/SY20276 Voltage regulator
+
+Required properties:
+- compatible: Must be one of the following.
+       "silergy,sy8824c"
+       "silergy,sy8824e"
+       "silergy,sy20276"
+       "silergy,sy20278"
+- reg: I2C slave address
+
+Any property defined as part of the core regulator binding, defined in
+./regulator.txt, can also be used.
+
+Example:
+
+       vcore: regulator@00 {
+               compatible = "silergy,sy8824c";
+               reg = <0x66>;
+               regulator-name = "vcore";
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1150000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
index 74a91c4f8530a4cd17cb5d184554c6cd283163e8..549f80436debca8eed1558f547264967cba89a42 100644 (file)
@@ -71,3 +71,10 @@ Example:
                regulator-min-microvolt  = <1000000>;
                regulator-max-microvolt  = <3000000>;
        };
+
+For twl6030 regulators/LDOs:
+
+ - ti,retain-on-reset: Does not turn off the supplies during warm
+                       reset. Could be needed for VMMC, as TWL6030
+                       reset sequence for this signal does not comply
+                       with the SD specification.
index c9919f4b92d2121ef25471c1f22df69f621a911c..94fd38b0d163fdcedc20085c442e3c510ed4f292 100644 (file)
@@ -13,6 +13,7 @@ this layer. These clocks and resets should be described in each property.
 Required properties:
 - compatible: Should be
     "socionext,uniphier-pro4-usb3-regulator" - for Pro4 SoC
+    "socionext,uniphier-pro5-usb3-regulator" - for Pro5 SoC
     "socionext,uniphier-pxs2-usb3-regulator" - for PXs2 SoC
     "socionext,uniphier-ld20-usb3-regulator" - for LD20 SoC
     "socionext,uniphier-pxs3-usb3-regulator" - for PXs3 SoC
@@ -20,12 +21,12 @@ Required properties:
 - clocks: A list of phandles to the clock gate for USB3 glue layer.
        According to the clock-names, appropriate clocks are required.
 - clock-names: Should contain
-    "gio", "link" - for Pro4 SoC
+    "gio", "link" - for Pro4 and Pro5 SoCs
     "link"        - for others
 - resets: A list of phandles to the reset control for USB3 glue layer.
        According to the reset-names, appropriate resets are required.
 - reset-names: Should contain
-    "gio", "link" - for Pro4 SoC
+    "gio", "link" - for Pro4 and Pro5 SoCs
     "link"        - for others
 
 See Documentation/devicetree/bindings/regulator/regulator.txt
index 97be6abb05eab3f7e2c0c7d5063ac0294ebb2546..67b776c624ae09609931edd2c22a93220dfcd8d2 100644 (file)
@@ -17261,6 +17261,7 @@ F:      Documentation/power/regulator/
 F:     drivers/regulator/
 F:     include/dt-bindings/regulator/
 F:     include/linux/regulator/
+K:     regulator_get_optional
 
 VRF
 M:     David Ahern <dsa@cumulusnetworks.com>
index b57093d7c01f660ff65da897f64133944f5058e1..3ee63531f6d5c36d36ffd24b2e7477cf1290e439 100644 (file)
@@ -83,6 +83,7 @@ config REGULATOR_88PM8607
 config REGULATOR_ACT8865
        tristate "Active-semi act8865 voltage regulator"
        depends on I2C
+       depends on POWER_SUPPLY
        select REGMAP_I2C
        help
          This driver controls a active-semi act8865 voltage output
@@ -618,6 +619,15 @@ config REGULATOR_MT6323
          This driver supports the control of different power rails of device
          through regulator interface.
 
+config REGULATOR_MT6358
+       tristate "MediaTek MT6358 PMIC"
+       depends on MFD_MT6397 && BROKEN
+       help
+         Say y here to select this option to enable the power regulator of
+         MediaTek MT6358 PMIC.
+         This driver supports the control of different power rails of device
+         through regulator interface.
+
 config REGULATOR_MT6380
        tristate "MediaTek MT6380 PMIC"
        depends on MTK_PMIC_WRAP
@@ -906,6 +916,13 @@ config REGULATOR_SY8106A
        help
          This driver supports SY8106A single output regulator.
 
+config REGULATOR_SY8824X
+       tristate "Silergy SY8824C/SY8824E regulator"
+       depends on I2C && (OF || COMPILE_TEST)
+       select REGMAP_I2C
+       help
+         This driver supports SY8824C single output regulator.
+
 config REGULATOR_TPS51632
        tristate "TI TPS51632 Power Regulator"
        depends on I2C
index eef73b5a35a4dd1e467a26e6f07e4f7e8b8f6635..2210ba56f9bd115e6229e02861d7009358d977dd 100644 (file)
@@ -79,6 +79,7 @@ obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
 obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
+obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
@@ -111,6 +112,7 @@ obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
 obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o
 obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
 obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
+obj-$(CONFIG_REGULATOR_SY8824X) += sy8824x.o
 obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
index cf72d7c6b8c9fb75eb06cdf0575cf85945a939c5..0fa97f934df49b0f3998fd7ee51287085ae9f2f5 100644 (file)
 #include <linux/regulator/act8865.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/power_supply.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regmap.h>
+#include <dt-bindings/regulator/active-semi,8865-regulator.h>
 
 /*
  * ACT8600 Global Register Map.
  */
 #define        ACT8865_SYS_MODE        0x00
 #define        ACT8865_SYS_CTRL        0x01
+#define        ACT8865_SYS_UNLK_REGS   0x0b
 #define        ACT8865_DCDC1_VSET1     0x20
 #define        ACT8865_DCDC1_VSET2     0x21
 #define        ACT8865_DCDC1_CTRL      0x22
+#define        ACT8865_DCDC1_SUS       0x24
 #define        ACT8865_DCDC2_VSET1     0x30
 #define        ACT8865_DCDC2_VSET2     0x31
 #define        ACT8865_DCDC2_CTRL      0x32
+#define        ACT8865_DCDC2_SUS       0x34
 #define        ACT8865_DCDC3_VSET1     0x40
 #define        ACT8865_DCDC3_VSET2     0x41
 #define        ACT8865_DCDC3_CTRL      0x42
+#define        ACT8865_DCDC3_SUS       0x44
 #define        ACT8865_LDO1_VSET       0x50
 #define        ACT8865_LDO1_CTRL       0x51
+#define        ACT8865_LDO1_SUS        0x52
 #define        ACT8865_LDO2_VSET       0x54
 #define        ACT8865_LDO2_CTRL       0x55
+#define        ACT8865_LDO2_SUS        0x56
 #define        ACT8865_LDO3_VSET       0x60
 #define        ACT8865_LDO3_CTRL       0x61
+#define        ACT8865_LDO3_SUS        0x62
 #define        ACT8865_LDO4_VSET       0x64
 #define        ACT8865_LDO4_CTRL       0x65
+#define        ACT8865_LDO4_SUS        0x66
 #define        ACT8865_MSTROFF         0x20
 
 /*
  * Field Definitions.
  */
 #define        ACT8865_ENA             0x80    /* ON - [7] */
+#define        ACT8865_DIS             0x40    /* DIS - [6] */
+
 #define        ACT8865_VSEL_MASK       0x3F    /* VSET - [5:0] */
 
 
 #define ACT8600_LDO10_ENA              0x40    /* ON - [6] */
 #define ACT8600_SUDCDC_VSEL_MASK       0xFF    /* SUDCDC VSET - [7:0] */
 
+#define ACT8600_APCH_CHG_ACIN          BIT(7)
+#define ACT8600_APCH_CHG_USB           BIT(6)
+#define ACT8600_APCH_CSTATE0           BIT(5)
+#define ACT8600_APCH_CSTATE1           BIT(4)
+
 /*
  * ACT8865 voltage number
  */
@@ -217,6 +234,171 @@ static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = {
        REGULATOR_LINEAR_RANGE(41400000, 248, 255, 0),
 };
 
+static int act8865_set_suspend_state(struct regulator_dev *rdev, bool enable)
+{
+       struct regmap *regmap = rdev->regmap;
+       int id = rdev->desc->id, reg, val;
+
+       switch (id) {
+       case ACT8865_ID_DCDC1:
+               reg = ACT8865_DCDC1_SUS;
+               val = 0xa8;
+               break;
+       case ACT8865_ID_DCDC2:
+               reg = ACT8865_DCDC2_SUS;
+               val = 0xa8;
+               break;
+       case ACT8865_ID_DCDC3:
+               reg = ACT8865_DCDC3_SUS;
+               val = 0xa8;
+               break;
+       case ACT8865_ID_LDO1:
+               reg = ACT8865_LDO1_SUS;
+               val = 0xe8;
+               break;
+       case ACT8865_ID_LDO2:
+               reg = ACT8865_LDO2_SUS;
+               val = 0xe8;
+               break;
+       case ACT8865_ID_LDO3:
+               reg = ACT8865_LDO3_SUS;
+               val = 0xe8;
+               break;
+       case ACT8865_ID_LDO4:
+               reg = ACT8865_LDO4_SUS;
+               val = 0xe8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (enable)
+               val |= BIT(4);
+
+       /*
+        * Ask the PMIC to enable/disable this output when entering hibernate
+        * mode.
+        */
+       return regmap_write(regmap, reg, val);
+}
+
+static int act8865_set_suspend_enable(struct regulator_dev *rdev)
+{
+       return act8865_set_suspend_state(rdev, true);
+}
+
+static int act8865_set_suspend_disable(struct regulator_dev *rdev)
+{
+       return act8865_set_suspend_state(rdev, false);
+}
+
+static unsigned int act8865_of_map_mode(unsigned int mode)
+{
+       switch (mode) {
+       case ACT8865_REGULATOR_MODE_FIXED:
+               return REGULATOR_MODE_FAST;
+       case ACT8865_REGULATOR_MODE_NORMAL:
+               return REGULATOR_MODE_NORMAL;
+       case ACT8865_REGULATOR_MODE_LOWPOWER:
+               return REGULATOR_MODE_STANDBY;
+       default:
+               return REGULATOR_MODE_INVALID;
+       }
+}
+
+static int act8865_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       struct regmap *regmap = rdev->regmap;
+       int id = rdev_get_id(rdev);
+       int reg, val = 0;
+
+       switch (id) {
+       case ACT8865_ID_DCDC1:
+               reg = ACT8865_DCDC1_CTRL;
+               break;
+       case ACT8865_ID_DCDC2:
+               reg = ACT8865_DCDC2_CTRL;
+               break;
+       case ACT8865_ID_DCDC3:
+               reg = ACT8865_DCDC3_CTRL;
+               break;
+       case ACT8865_ID_LDO1:
+               reg = ACT8865_LDO1_CTRL;
+               break;
+       case ACT8865_ID_LDO2:
+               reg = ACT8865_LDO2_CTRL;
+               break;
+       case ACT8865_ID_LDO3:
+               reg = ACT8865_LDO3_CTRL;
+               break;
+       case ACT8865_ID_LDO4:
+               reg = ACT8865_LDO4_CTRL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+       case REGULATOR_MODE_NORMAL:
+               if (id <= ACT8865_ID_DCDC3)
+                       val = BIT(5);
+               break;
+       case REGULATOR_MODE_STANDBY:
+               if (id > ACT8865_ID_DCDC3)
+                       val = BIT(5);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return regmap_update_bits(regmap, reg, BIT(5), val);
+}
+
+static unsigned int act8865_get_mode(struct regulator_dev *rdev)
+{
+       struct regmap *regmap = rdev->regmap;
+       int id = rdev_get_id(rdev);
+       int reg, ret, val = 0;
+
+       switch (id) {
+       case ACT8865_ID_DCDC1:
+               reg = ACT8865_DCDC1_CTRL;
+               break;
+       case ACT8865_ID_DCDC2:
+               reg = ACT8865_DCDC2_CTRL;
+               break;
+       case ACT8865_ID_DCDC3:
+               reg = ACT8865_DCDC3_CTRL;
+               break;
+       case ACT8865_ID_LDO1:
+               reg = ACT8865_LDO1_CTRL;
+               break;
+       case ACT8865_ID_LDO2:
+               reg = ACT8865_LDO2_CTRL;
+               break;
+       case ACT8865_ID_LDO3:
+               reg = ACT8865_LDO3_CTRL;
+               break;
+       case ACT8865_ID_LDO4:
+               reg = ACT8865_LDO4_CTRL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = regmap_read(regmap, reg, &val);
+       if (ret)
+               return ret;
+
+       if (id <= ACT8865_ID_DCDC3 && (val & BIT(5)))
+               return REGULATOR_MODE_FAST;
+       else if (id > ACT8865_ID_DCDC3 && !(val & BIT(5)))
+               return REGULATOR_MODE_NORMAL;
+       else
+               return REGULATOR_MODE_STANDBY;
+}
+
 static const struct regulator_ops act8865_ops = {
        .list_voltage           = regulator_list_voltage_linear_range,
        .map_voltage            = regulator_map_voltage_linear_range,
@@ -224,24 +406,44 @@ static const struct regulator_ops act8865_ops = {
        .set_voltage_sel        = regulator_set_voltage_sel_regmap,
        .enable                 = regulator_enable_regmap,
        .disable                = regulator_disable_regmap,
+       .set_mode               = act8865_set_mode,
+       .get_mode               = act8865_get_mode,
        .is_enabled             = regulator_is_enabled_regmap,
+       .set_suspend_enable     = act8865_set_suspend_enable,
+       .set_suspend_disable    = act8865_set_suspend_disable,
 };
 
 static const struct regulator_ops act8865_ldo_ops = {
+       .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,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .set_mode               = act8865_set_mode,
+       .get_mode               = act8865_get_mode,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .set_suspend_enable     = act8865_set_suspend_enable,
+       .set_suspend_disable    = act8865_set_suspend_disable,
+       .set_pull_down          = regulator_set_pull_down_regmap,
+};
+
+static const struct regulator_ops act8865_fixed_ldo_ops = {
        .enable                 = regulator_enable_regmap,
        .disable                = regulator_disable_regmap,
        .is_enabled             = regulator_is_enabled_regmap,
 };
 
-#define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply)           \
+#define ACT88xx_REG_(_name, _family, _id, _vsel_reg, _supply, _ops)    \
        [_family##_ID_##_id] = {                                        \
                .name                   = _name,                        \
                .of_match               = of_match_ptr(_name),          \
+               .of_map_mode            = act8865_of_map_mode,          \
                .regulators_node        = of_match_ptr("regulators"),   \
                .supply_name            = _supply,                      \
                .id                     = _family##_ID_##_id,           \
                .type                   = REGULATOR_VOLTAGE,            \
-               .ops                    = &act8865_ops,                 \
+               .ops                    = _ops,                         \
                .n_voltages             = ACT8865_VOLTAGE_NUM,          \
                .linear_ranges          = act8865_voltage_ranges,       \
                .n_linear_ranges        = ARRAY_SIZE(act8865_voltage_ranges), \
@@ -249,9 +451,17 @@ static const struct regulator_ops act8865_ldo_ops = {
                .vsel_mask              = ACT8865_VSEL_MASK,            \
                .enable_reg             = _family##_##_id##_CTRL,       \
                .enable_mask            = ACT8865_ENA,                  \
+               .pull_down_reg          = _family##_##_id##_CTRL,       \
+               .pull_down_mask         = ACT8865_DIS,                  \
                .owner                  = THIS_MODULE,                  \
        }
 
+#define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply) \
+       ACT88xx_REG_(_name, _family, _id, _vsel_reg, _supply, &act8865_ops)
+
+#define ACT88xx_LDO(_name, _family, _id, _vsel_reg, _supply) \
+       ACT88xx_REG_(_name, _family, _id, _vsel_reg, _supply, &act8865_ldo_ops)
+
 static const struct regulator_desc act8600_regulators[] = {
        ACT88xx_REG("DCDC1", ACT8600, DCDC1, VSET, "vp1"),
        ACT88xx_REG("DCDC2", ACT8600, DCDC2, VSET, "vp2"),
@@ -281,7 +491,7 @@ static const struct regulator_desc act8600_regulators[] = {
                .of_match = of_match_ptr("LDO_REG9"),
                .regulators_node = of_match_ptr("regulators"),
                .id = ACT8600_ID_LDO9,
-               .ops = &act8865_ldo_ops,
+               .ops = &act8865_fixed_ldo_ops,
                .type = REGULATOR_VOLTAGE,
                .n_voltages = 1,
                .fixed_uV = 3300000,
@@ -294,7 +504,7 @@ static const struct regulator_desc act8600_regulators[] = {
                .of_match = of_match_ptr("LDO_REG10"),
                .regulators_node = of_match_ptr("regulators"),
                .id = ACT8600_ID_LDO10,
-               .ops = &act8865_ldo_ops,
+               .ops = &act8865_fixed_ldo_ops,
                .type = REGULATOR_VOLTAGE,
                .n_voltages = 1,
                .fixed_uV = 1200000,
@@ -323,20 +533,20 @@ static const struct regulator_desc act8865_regulators[] = {
        ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1, "vp1"),
        ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1, "vp2"),
        ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1, "vp3"),
-       ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
-       ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
-       ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
-       ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
+       ACT88xx_LDO("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
+       ACT88xx_LDO("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
+       ACT88xx_LDO("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
+       ACT88xx_LDO("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
 };
 
 static const struct regulator_desc act8865_alt_regulators[] = {
        ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET2, "vp1"),
        ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET2, "vp2"),
        ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET2, "vp3"),
-       ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
-       ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
-       ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
-       ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
+       ACT88xx_LDO("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
+       ACT88xx_LDO("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
+       ACT88xx_LDO("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
+       ACT88xx_LDO("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
 };
 
 #ifdef CONFIG_OF
@@ -372,6 +582,75 @@ static void act8865_power_off(void)
        while (1);
 }
 
+static int act8600_charger_get_status(struct regmap *map)
+{
+       unsigned int val;
+       int ret;
+       u8 state0, state1;
+
+       ret = regmap_read(map, ACT8600_APCH_STAT, &val);
+       if (ret < 0)
+               return ret;
+
+       state0 = val & ACT8600_APCH_CSTATE0;
+       state1 = val & ACT8600_APCH_CSTATE1;
+
+       if (state0 && !state1)
+               return POWER_SUPPLY_STATUS_CHARGING;
+       if (!state0 && state1)
+               return POWER_SUPPLY_STATUS_NOT_CHARGING;
+       if (!state0 && !state1)
+               return POWER_SUPPLY_STATUS_DISCHARGING;
+
+       return POWER_SUPPLY_STATUS_UNKNOWN;
+}
+
+static int act8600_charger_get_property(struct power_supply *psy,
+               enum power_supply_property psp, union power_supply_propval *val)
+{
+       struct regmap *map = power_supply_get_drvdata(psy);
+       int ret;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+               ret = act8600_charger_get_status(map);
+               if (ret < 0)
+                       return ret;
+
+               val->intval = ret;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static enum power_supply_property act8600_charger_properties[] = {
+       POWER_SUPPLY_PROP_STATUS,
+};
+
+static const struct power_supply_desc act8600_charger_desc = {
+       .name = "act8600-charger",
+       .type = POWER_SUPPLY_TYPE_BATTERY,
+       .properties = act8600_charger_properties,
+       .num_properties = ARRAY_SIZE(act8600_charger_properties),
+       .get_property = act8600_charger_get_property,
+};
+
+static int act8600_charger_probe(struct device *dev, struct regmap *regmap)
+{
+       struct power_supply *charger;
+       struct power_supply_config cfg = {
+               .drv_data = regmap,
+               .of_node = dev->of_node,
+       };
+
+       charger = devm_power_supply_register(dev, &act8600_charger_desc, &cfg);
+
+       return PTR_ERR_OR_ZERO(charger);
+}
+
 static int act8865_pmic_probe(struct i2c_client *client,
                              const struct i2c_device_id *i2c_id)
 {
@@ -483,9 +762,20 @@ static int act8865_pmic_probe(struct i2c_client *client,
                }
        }
 
+       if (type == ACT8600) {
+               ret = act8600_charger_probe(dev, act8865->regmap);
+               if (ret < 0) {
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(dev, "Failed to probe charger");
+                       return ret;
+               }
+       }
+
        i2c_set_clientdata(client, act8865);
 
-       return 0;
+       /* Unlock expert registers for ACT8865. */
+       return type != ACT8865 ? 0 : regmap_write(act8865->regmap,
+                                                 ACT8865_SYS_UNLK_REGS, 0xef);
 }
 
 static const struct i2c_device_id act8865_ids[] = {
index e0c0cf462004958635420a95d11ca00eb2b9d472..afe94470b67f7588a28930731d3a4ab6f4d2a331 100644 (file)
@@ -381,12 +381,16 @@ static struct device_node *of_get_child_regulator(struct device_node *parent,
                if (!regnode) {
                        regnode = of_get_child_regulator(child, prop_name);
                        if (regnode)
-                               return regnode;
+                               goto err_node_put;
                } else {
-                       return regnode;
+                       goto err_node_put;
                }
        }
        return NULL;
+
+err_node_put:
+       of_node_put(child);
+       return regnode;
 }
 
 /**
@@ -564,13 +568,15 @@ static ssize_t regulator_uV_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
        struct regulator_dev *rdev = dev_get_drvdata(dev);
-       ssize_t ret;
+       int uV;
 
        regulator_lock(rdev);
-       ret = sprintf(buf, "%d\n", regulator_get_voltage_rdev(rdev));
+       uV = regulator_get_voltage_rdev(rdev);
        regulator_unlock(rdev);
 
-       return ret;
+       if (uV < 0)
+               return uV;
+       return sprintf(buf, "%d\n", uV);
 }
 static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
 
@@ -5640,7 +5646,7 @@ static int __init regulator_init(void)
 /* init early to allow our consumers to complete system booting */
 core_initcall(regulator_init);
 
-static int __init regulator_late_cleanup(struct device *dev, void *data)
+static int regulator_late_cleanup(struct device *dev, void *data)
 {
        struct regulator_dev *rdev = dev_to_rdev(dev);
        const struct regulator_ops *ops = rdev->desc->ops;
@@ -5689,17 +5695,8 @@ unlock:
        return 0;
 }
 
-static int __init regulator_init_complete(void)
+static void regulator_init_complete_work_function(struct work_struct *work)
 {
-       /*
-        * Since DT doesn't provide an idiomatic mechanism for
-        * enabling full constraints and since it's much more natural
-        * with DT to provide them just assume that a DT enabled
-        * system has full constraints.
-        */
-       if (of_have_populated_dt())
-               has_full_constraints = true;
-
        /*
         * Regulators may had failed to resolve their input supplies
         * when were registered, either because the input supply was
@@ -5717,6 +5714,35 @@ static int __init regulator_init_complete(void)
         */
        class_for_each_device(&regulator_class, NULL, NULL,
                              regulator_late_cleanup);
+}
+
+static DECLARE_DELAYED_WORK(regulator_init_complete_work,
+                           regulator_init_complete_work_function);
+
+static int __init regulator_init_complete(void)
+{
+       /*
+        * Since DT doesn't provide an idiomatic mechanism for
+        * enabling full constraints and since it's much more natural
+        * with DT to provide them just assume that a DT enabled
+        * system has full constraints.
+        */
+       if (of_have_populated_dt())
+               has_full_constraints = true;
+
+       /*
+        * We punt completion for an arbitrary amount of time since
+        * systems like distros will load many drivers from userspace
+        * so consumers might not always be ready yet, this is
+        * particularly an issue with laptops where this might bounce
+        * the display off then on.  Ideally we'd get a notification
+        * from userspace when this happens but we don't so just wait
+        * a bit and hope we waited long enough.  It'd be better if
+        * we'd only do this on systems that need it, and a kernel
+        * command line option might be useful.
+        */
+       schedule_delayed_work(&regulator_init_complete_work,
+                             msecs_to_jiffies(30000));
 
        return 0;
 }
index 2ffc64622451e0cdacae463f62a7dd27b5207276..56f3f72d77075e01e61beb9592acbbc221750fd7 100644 (file)
@@ -1032,10 +1032,8 @@ static int da9062_regulator_probe(struct platform_device *pdev)
 
        /* LDOs overcurrent event support */
        irq = platform_get_irq_byname(pdev, "LDO_LIM");
-       if (irq < 0) {
-               dev_err(&pdev->dev, "Failed to get IRQ.\n");
+       if (irq < 0)
                return irq;
-       }
        regulators->irq_ldo_lim = irq;
 
        ret = devm_request_threaded_irq(&pdev->dev, irq,
index 02f816318fba9762862af0536b401a3818118ba5..28b1b20f45bd1a1fbcedc92143ea6650fd510830 100644 (file)
@@ -863,10 +863,8 @@ static int da9063_regulator_probe(struct platform_device *pdev)
 
        /* LDOs overcurrent event support */
        irq = platform_get_irq_byname(pdev, "LDO_LIM");
-       if (irq < 0) {
-               dev_err(&pdev->dev, "Failed to get IRQ.\n");
+       if (irq < 0)
                return irq;
-       }
 
        ret = devm_request_threaded_irq(&pdev->dev, irq,
                                NULL, da9063_ldo_lim_event,
index 0309823d2c726035b0598b09b3add990c35a8363..bf80748f1ccc2a80ab014ae84bde52696e117a41 100644 (file)
@@ -285,7 +285,7 @@ static struct da9211_pdata *da9211_parse_regulators_dt(
                pdata->reg_node[n] = da9211_matches[i].of_node;
                pdata->gpiod_ren[n] = devm_gpiod_get_from_of_node(dev,
                                  da9211_matches[i].of_node,
-                                 "enable",
+                                 "enable-gpios",
                                  0,
                                  GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
                                  "da9211-enable");
index 999547dde99d2726e01b17ff7252393686326abe..d90a6fd8cbc7468f67324322443254388eff2d17 100644 (file)
 #include <linux/gpio/consumer.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/machine.h>
+#include <linux/clk.h>
+
 
 struct fixed_voltage_data {
        struct regulator_desc desc;
        struct regulator_dev *dev;
+
+       struct clk *enable_clock;
+       unsigned int clk_enable_counter;
 };
 
+struct fixed_dev_type {
+       bool has_enable_clock;
+};
+
+static const struct fixed_dev_type fixed_voltage_data = {
+       .has_enable_clock = false,
+};
+
+static const struct fixed_dev_type fixed_clkenable_data = {
+       .has_enable_clock = true,
+};
+
+static int reg_clock_enable(struct regulator_dev *rdev)
+{
+       struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
+       int ret = 0;
+
+       ret = clk_prepare_enable(priv->enable_clock);
+       if (ret)
+               return ret;
+
+       priv->clk_enable_counter++;
+
+       return ret;
+}
+
+static int reg_clock_disable(struct regulator_dev *rdev)
+{
+       struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
+
+       clk_disable_unprepare(priv->enable_clock);
+       priv->clk_enable_counter--;
+
+       return 0;
+}
+
+static int reg_clock_is_enabled(struct regulator_dev *rdev)
+{
+       struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
+
+       return priv->clk_enable_counter > 0;
+}
+
 
 /**
  * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
@@ -84,10 +133,19 @@ of_get_fixed_voltage_config(struct device *dev,
 static struct regulator_ops fixed_voltage_ops = {
 };
 
+static struct regulator_ops fixed_voltage_clkenabled_ops = {
+       .enable = reg_clock_enable,
+       .disable = reg_clock_disable,
+       .is_enabled = reg_clock_is_enabled,
+};
+
 static int reg_fixed_voltage_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        struct fixed_voltage_config *config;
        struct fixed_voltage_data *drvdata;
+       const struct fixed_dev_type *drvtype =
+               of_match_device(dev->driver->of_match_table, dev)->data;
        struct regulator_config cfg = { };
        enum gpiod_flags gflags;
        int ret;
@@ -118,7 +176,18 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
        }
        drvdata->desc.type = REGULATOR_VOLTAGE;
        drvdata->desc.owner = THIS_MODULE;
-       drvdata->desc.ops = &fixed_voltage_ops;
+
+       if (drvtype->has_enable_clock) {
+               drvdata->desc.ops = &fixed_voltage_clkenabled_ops;
+
+               drvdata->enable_clock = devm_clk_get(dev, NULL);
+               if (IS_ERR(drvdata->enable_clock)) {
+                       dev_err(dev, "Cant get enable-clock from devicetree\n");
+                       return -ENOENT;
+               }
+       } else {
+               drvdata->desc.ops = &fixed_voltage_ops;
+       }
 
        drvdata->desc.enable_time = config->startup_delay;
 
@@ -191,8 +260,16 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
 
 #if defined(CONFIG_OF)
 static const struct of_device_id fixed_of_match[] = {
-       { .compatible = "regulator-fixed", },
-       {},
+       {
+               .compatible = "regulator-fixed",
+               .data = &fixed_voltage_data,
+       },
+       {
+               .compatible = "regulator-fixed-clock",
+               .data = &fixed_clkenable_data,
+       },
+       {
+       },
 };
 MODULE_DEVICE_TABLE(of, fixed_of_match);
 #endif
index 4986cc5064a1fbed266ada36b54303814d628693..ca3dc3f3bb292c679e8521d12b082b5e82447349 100644 (file)
@@ -860,3 +860,24 @@ int regulator_get_current_limit_regmap(struct regulator_dev *rdev)
        return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(regulator_get_current_limit_regmap);
+
+/**
+ * regulator_bulk_set_supply_names - initialize the 'supply' fields in an array
+ *                                   of regulator_bulk_data structs
+ *
+ * @consumers: array of regulator_bulk_data entries to initialize
+ * @supply_names: array of supply name strings
+ * @num_supplies: number of supply names to initialize
+ *
+ * Note: the 'consumers' array must be the size of 'num_supplies'.
+ */
+void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
+                                    const char *const *supply_names,
+                                    unsigned int num_supplies)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_supplies; i++)
+               consumers[i].supply = supply_names[i];
+}
+EXPORT_SYMBOL_GPL(regulator_bulk_set_supply_names);
index 5647e2f97ff8d5fca78b9ef610055bf61bb96b7e..4b9f618b07e971682a5704c83f78e5632952b6f8 100644 (file)
 
 /* LM3632 */
 #define LM3632_BOOST_VSEL_MAX          0x26
-#define LM3632_LDO_VSEL_MAX            0x29
+#define LM3632_LDO_VSEL_MAX            0x28
 #define LM3632_VBOOST_MIN              4500000
 #define LM3632_VLDO_MIN                        4000000
 
 /* LM36274 */
 #define LM36274_BOOST_VSEL_MAX         0x3f
-#define LM36274_LDO_VSEL_MAX           0x34
+#define LM36274_LDO_VSEL_MAX           0x32
 #define LM36274_VOLTAGE_MIN            4000000
 
 /* Common */
@@ -226,7 +226,7 @@ static const struct regulator_desc lm363x_regulator_desc[] = {
                .of_match       = "vboost",
                .id             = LM36274_BOOST,
                .ops            = &lm363x_boost_voltage_table_ops,
-               .n_voltages     = LM36274_BOOST_VSEL_MAX,
+               .n_voltages     = LM36274_BOOST_VSEL_MAX + 1,
                .min_uV         = LM36274_VOLTAGE_MIN,
                .uV_step        = LM363X_STEP_50mV,
                .type           = REGULATOR_VOLTAGE,
@@ -239,7 +239,7 @@ static const struct regulator_desc lm363x_regulator_desc[] = {
                .of_match       = "vpos",
                .id             = LM36274_LDO_POS,
                .ops            = &lm363x_regulator_voltage_table_ops,
-               .n_voltages     = LM36274_LDO_VSEL_MAX,
+               .n_voltages     = LM36274_LDO_VSEL_MAX + 1,
                .min_uV         = LM36274_VOLTAGE_MIN,
                .uV_step        = LM363X_STEP_50mV,
                .type           = REGULATOR_VOLTAGE,
@@ -254,7 +254,7 @@ static const struct regulator_desc lm363x_regulator_desc[] = {
                .of_match       = "vneg",
                .id             = LM36274_LDO_NEG,
                .ops            = &lm363x_regulator_voltage_table_ops,
-               .n_voltages     = LM36274_LDO_VSEL_MAX,
+               .n_voltages     = LM36274_LDO_VSEL_MAX + 1,
                .min_uV         = LM36274_VOLTAGE_MIN,
                .uV_step        = LM363X_STEP_50mV,
                .type           = REGULATOR_VOLTAGE,
index 0c440c5e28327c80b596f0996c3ef6b122021a6d..4ae12ac1f4c64452368034cd672b7f7eeea9172b 100644 (file)
@@ -65,7 +65,6 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev,
                                       int ramp_delay)
 {
        int id = rdev_get_id(rdev);
-       struct lp87565 *lp87565 = rdev_get_drvdata(rdev);
        unsigned int reg;
        int ret;
 
@@ -86,11 +85,11 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev,
        else
                reg = 0;
 
-       ret = regmap_update_bits(lp87565->regmap, regulators[id].ctrl2_reg,
+       ret = regmap_update_bits(rdev->regmap, regulators[id].ctrl2_reg,
                                 LP87565_BUCK_CTRL_2_SLEW_RATE,
                                 reg << __ffs(LP87565_BUCK_CTRL_2_SLEW_RATE));
        if (ret) {
-               dev_err(lp87565->dev, "SLEW RATE write failed: %d\n", ret);
+               dev_err(&rdev->dev, "SLEW RATE write failed: %d\n", ret);
                return ret;
        }
 
index 1b00f363899660d08926ac8ec02a83d7617283af..00e9bb92c326b223a769328713e533010f87bb3b 100644 (file)
@@ -464,7 +464,7 @@ static int lp8788_config_ldo_enable_mode(struct platform_device *pdev,
 {
        struct lp8788 *lp = ldo->lp;
        enum lp8788_ext_ldo_en_id enable_id;
-       u8 en_mask[] = {
+       static const u8 en_mask[] = {
                [EN_ALDO1]   = LP8788_EN_SEL_ALDO1_M,
                [EN_ALDO234] = LP8788_EN_SEL_ALDO234_M,
                [EN_ALDO5]   = LP8788_EN_SEL_ALDO5_M,
index 8020eb57374a1b32d3a1c322483c5a0bb308c514..c8e579e993160d9ac8424ee1f63a11461d3e1732 100644 (file)
@@ -257,7 +257,7 @@ static int max77686_of_parse_cb(struct device_node *np,
        case MAX77686_BUCK9:
        case MAX77686_LDO20 ... MAX77686_LDO22:
                config->ena_gpiod = gpiod_get_from_of_node(np,
-                               "maxim,ena",
+                               "maxim,ena-gpios",
                                0,
                                GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
                                "max77686-regulator");
index 4bca54446287363464c92af84c2347865ebd6271..347043a5a9a7df999722fd73870cda070123abbd 100644 (file)
@@ -485,7 +485,6 @@ static int max8660_probe(struct i2c_client *client,
                rdev = devm_regulator_register(&client->dev,
                                                  &max8660_reg[id], &config);
                if (IS_ERR(rdev)) {
-                       ret = PTR_ERR(rdev);
                        dev_err(&client->dev, "failed to register %s\n",
                                max8660_reg[id].name);
                        return PTR_ERR(rdev);
diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c
new file mode 100644 (file)
index 0000000..ba42682
--- /dev/null
@@ -0,0 +1,549 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2019 MediaTek Inc.
+
+#include <linux/mfd/mt6358/registers.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/mt6358-regulator.h>
+#include <linux/regulator/of_regulator.h>
+
+#define MT6358_BUCK_MODE_AUTO  0
+#define MT6358_BUCK_MODE_FORCE_PWM     1
+
+/*
+ * MT6358 regulators' information
+ *
+ * @desc: standard fields of regulator description.
+ * @qi: Mask for query enable signal status of regulators
+ */
+struct mt6358_regulator_info {
+       struct regulator_desc desc;
+       u32 status_reg;
+       u32 qi;
+       const u32 *index_table;
+       unsigned int n_table;
+       u32 vsel_shift;
+       u32 da_vsel_reg;
+       u32 da_vsel_mask;
+       u32 da_vsel_shift;
+       u32 modeset_reg;
+       u32 modeset_mask;
+       u32 modeset_shift;
+};
+
+#define MT6358_BUCK(match, vreg, min, max, step,               \
+       volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask,   \
+       _da_vsel_shift, _modeset_reg, _modeset_shift)           \
+[MT6358_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_range_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6358_ID_##vreg,         \
+               .owner = THIS_MODULE,           \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+               .linear_ranges = volt_ranges,           \
+               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .vsel_reg = MT6358_BUCK_##vreg##_ELR0,  \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_BUCK_##vreg##_CON0,        \
+               .enable_mask = BIT(0),  \
+               .of_map_mode = mt6358_map_mode, \
+       },      \
+       .status_reg = MT6358_BUCK_##vreg##_DBG1,        \
+       .qi = BIT(0),   \
+       .da_vsel_reg = _da_vsel_reg,    \
+       .da_vsel_mask = _da_vsel_mask,  \
+       .da_vsel_shift = _da_vsel_shift,        \
+       .modeset_reg = _modeset_reg,    \
+       .modeset_mask = BIT(_modeset_shift),    \
+       .modeset_shift = _modeset_shift \
+}
+
+#define MT6358_LDO(match, vreg, ldo_volt_table,        \
+       ldo_index_table, enreg, enbit, vosel,   \
+       vosel_mask, vosel_shift)        \
+[MT6358_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_table_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6358_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = ARRAY_SIZE(ldo_volt_table),       \
+               .volt_table = ldo_volt_table,   \
+               .vsel_reg = vosel,      \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = enreg,    \
+               .enable_mask = BIT(enbit),      \
+       },      \
+       .status_reg = MT6358_LDO_##vreg##_CON1, \
+       .qi = BIT(15),  \
+       .index_table = ldo_index_table, \
+       .n_table = ARRAY_SIZE(ldo_index_table), \
+       .vsel_shift = vosel_shift,      \
+}
+
+#define MT6358_LDO1(match, vreg, min, max, step,       \
+       volt_ranges, _da_vsel_reg, _da_vsel_mask,       \
+       _da_vsel_shift, vosel, vosel_mask)      \
+[MT6358_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_range_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6358_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+               .linear_ranges = volt_ranges,   \
+               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .vsel_reg = vosel,      \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_LDO_##vreg##_CON0, \
+               .enable_mask = BIT(0),  \
+       },      \
+       .da_vsel_reg = _da_vsel_reg,    \
+       .da_vsel_mask = _da_vsel_mask,  \
+       .da_vsel_shift = _da_vsel_shift,        \
+       .status_reg = MT6358_LDO_##vreg##_DBG1, \
+       .qi = BIT(0),   \
+}
+
+#define MT6358_REG_FIXED(match, vreg,  \
+       enreg, enbit, volt)     \
+[MT6358_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_fixed_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6358_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = 1,        \
+               .enable_reg = enreg,    \
+               .enable_mask = BIT(enbit),      \
+               .min_uV = volt, \
+       },      \
+       .status_reg = MT6358_LDO_##vreg##_CON1, \
+       .qi = BIT(15),                                                  \
+}
+
+static const struct regulator_linear_range buck_volt_range1[] = {
+       REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
+};
+
+static const struct regulator_linear_range buck_volt_range2[] = {
+       REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500),
+};
+
+static const struct regulator_linear_range buck_volt_range3[] = {
+       REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
+};
+
+static const struct regulator_linear_range buck_volt_range4[] = {
+       REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500),
+};
+
+static const u32 vdram2_voltages[] = {
+       600000, 1800000,
+};
+
+static const u32 vsim_voltages[] = {
+       1700000, 1800000, 2700000, 3000000, 3100000,
+};
+
+static const u32 vibr_voltages[] = {
+       1200000, 1300000, 1500000, 1800000,
+       2000000, 2800000, 3000000, 3300000,
+};
+
+static const u32 vusb_voltages[] = {
+       3000000, 3100000,
+};
+
+static const u32 vcamd_voltages[] = {
+       900000, 1000000, 1100000, 1200000,
+       1300000, 1500000, 1800000,
+};
+
+static const u32 vefuse_voltages[] = {
+       1700000, 1800000, 1900000,
+};
+
+static const u32 vmch_vemc_voltages[] = {
+       2900000, 3000000, 3300000,
+};
+
+static const u32 vcama_voltages[] = {
+       1800000, 2500000, 2700000,
+       2800000, 2900000, 3000000,
+};
+
+static const u32 vcn33_bt_wifi_voltages[] = {
+       3300000, 3400000, 3500000,
+};
+
+static const u32 vmc_voltages[] = {
+       1800000, 2900000, 3000000, 3300000,
+};
+
+static const u32 vldo28_voltages[] = {
+       2800000, 3000000,
+};
+
+static const u32 vdram2_idx[] = {
+       0, 12,
+};
+
+static const u32 vsim_idx[] = {
+       3, 4, 8, 11, 12,
+};
+
+static const u32 vibr_idx[] = {
+       0, 1, 2, 4, 5, 9, 11, 13,
+};
+
+static const u32 vusb_idx[] = {
+       3, 4,
+};
+
+static const u32 vcamd_idx[] = {
+       3, 4, 5, 6, 7, 9, 12,
+};
+
+static const u32 vefuse_idx[] = {
+       11, 12, 13,
+};
+
+static const u32 vmch_vemc_idx[] = {
+       2, 3, 5,
+};
+
+static const u32 vcama_idx[] = {
+       0, 7, 9, 10, 11, 12,
+};
+
+static const u32 vcn33_bt_wifi_idx[] = {
+       1, 2, 3,
+};
+
+static const u32 vmc_idx[] = {
+       4, 10, 11, 13,
+};
+
+static const u32 vldo28_idx[] = {
+       1, 3,
+};
+
+static unsigned int mt6358_map_mode(unsigned int mode)
+{
+       return mode == MT6358_BUCK_MODE_AUTO ?
+               REGULATOR_MODE_NORMAL : REGULATOR_MODE_FAST;
+}
+
+static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
+                                 unsigned int selector)
+{
+       int idx, ret;
+       const u32 *pvol;
+       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+
+       pvol = info->index_table;
+
+       idx = pvol[selector];
+       ret = regmap_update_bits(rdev->regmap, info->desc.vsel_reg,
+                                info->desc.vsel_mask,
+                                idx << info->vsel_shift);
+
+       return ret;
+}
+
+static int mt6358_get_voltage_sel(struct regulator_dev *rdev)
+{
+       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);
+       if (ret != 0) {
+               dev_info(&rdev->dev,
+                        "Failed to get mt6358 %s vsel reg: %d\n",
+                        info->desc.name, ret);
+               return ret;
+       }
+
+       selector = (selector & info->desc.vsel_mask) >> info->vsel_shift;
+       pvol = info->index_table;
+       for (idx = 0; idx < info->desc.n_voltages; idx++) {
+               if (pvol[idx] == selector)
+                       return idx;
+       }
+
+       return -EINVAL;
+}
+
+static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
+{
+       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) {
+               dev_err(&rdev->dev,
+                       "Failed to get mt6358 Buck %s vsel reg: %d\n",
+                       info->desc.name, ret);
+               return ret;
+       }
+
+       ret = (regval >> info->da_vsel_shift) & info->da_vsel_mask;
+
+       return ret;
+}
+
+static int mt6358_get_status(struct regulator_dev *rdev)
+{
+       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) {
+               dev_info(&rdev->dev, "Failed to get enable reg: %d\n", ret);
+               return ret;
+       }
+
+       return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
+}
+
+static int mt6358_regulator_set_mode(struct regulator_dev *rdev,
+                                    unsigned int mode)
+{
+       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+       int val;
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+               val = MT6358_BUCK_MODE_FORCE_PWM;
+               break;
+       case REGULATOR_MODE_NORMAL:
+               val = MT6358_BUCK_MODE_AUTO;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       dev_dbg(&rdev->dev, "mt6358 buck set_mode %#x, %#x, %#x, %#x\n",
+               info->modeset_reg, info->modeset_mask,
+               info->modeset_shift, val);
+
+       val <<= info->modeset_shift;
+
+       return regmap_update_bits(rdev->regmap, info->modeset_reg,
+                                 info->modeset_mask, val);
+}
+
+static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
+{
+       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+       int ret, regval;
+
+       ret = regmap_read(rdev->regmap, info->modeset_reg, &regval);
+       if (ret != 0) {
+               dev_err(&rdev->dev,
+                       "Failed to get mt6358 buck mode: %d\n", ret);
+               return ret;
+       }
+
+       switch ((regval & info->modeset_mask) >> info->modeset_shift) {
+       case MT6358_BUCK_MODE_AUTO:
+               return REGULATOR_MODE_NORMAL;
+       case MT6358_BUCK_MODE_FORCE_PWM:
+               return REGULATOR_MODE_FAST;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct regulator_ops mt6358_volt_range_ops = {
+       .list_voltage = regulator_list_voltage_linear_range,
+       .map_voltage = regulator_map_voltage_linear_range,
+       .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,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .get_status = mt6358_get_status,
+       .set_mode = mt6358_regulator_set_mode,
+       .get_mode = mt6358_regulator_get_mode,
+};
+
+static const struct regulator_ops mt6358_volt_table_ops = {
+       .list_voltage = regulator_list_voltage_table,
+       .map_voltage = regulator_map_voltage_iterate,
+       .set_voltage_sel = mt6358_set_voltage_sel,
+       .get_voltage_sel = mt6358_get_voltage_sel,
+       .set_voltage_time_sel = regulator_set_voltage_time_sel,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .get_status = mt6358_get_status,
+};
+
+static const struct regulator_ops mt6358_volt_fixed_ops = {
+       .list_voltage = regulator_list_voltage_linear,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .get_status = mt6358_get_status,
+};
+
+/* The array is indexed by id(MT6358_ID_XXX) */
+static struct mt6358_regulator_info mt6358_regulators[] = {
+       MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
+                   buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
+                   0, MT6358_VDRAM1_ANA_CON0, 8),
+       MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
+                   0, MT6358_VCORE_VGPU_ANA_CON0, 1),
+       MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
+                   buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, 0,
+                   MT6358_VPA_ANA_CON0, 3),
+       MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
+                   0, MT6358_VPROC_ANA_CON0, 1),
+       MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
+                   0, MT6358_VPROC_ANA_CON0, 2),
+       MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, 0,
+                   MT6358_VCORE_VGPU_ANA_CON0, 2),
+       MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
+                   buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, 0,
+                   MT6358_VS2_ANA_CON0, 8),
+       MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
+                   0, MT6358_VMODEM_ANA_CON0, 8),
+       MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
+                   buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, 0,
+                   MT6358_VS1_ANA_CON0, 8),
+       MT6358_REG_FIXED("ldo_vrf12", VRF12,
+                        MT6358_LDO_VRF12_CON0, 0, 1200000),
+       MT6358_REG_FIXED("ldo_vio18", VIO18,
+                        MT6358_LDO_VIO18_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vcamio", VCAMIO,
+                        MT6358_LDO_VCAMIO_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
+       MT6358_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
+       MT6358_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
+       MT6358_REG_FIXED("ldo_vaux18", VAUX18,
+                        MT6358_LDO_VAUX18_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vbif28", VBIF28,
+                        MT6358_LDO_VBIF28_CON0, 0, 2800000),
+       MT6358_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
+       MT6358_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
+       MT6358_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vaud28", VAUD28,
+                        MT6358_LDO_VAUD28_CON0, 0, 2800000),
+       MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
+                  MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10, 0),
+       MT6358_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
+                  MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
+                  MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
+                  MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700, 8),
+       MT6358_LDO("ldo_vcamd", VCAMD, vcamd_voltages, vcamd_idx,
+                  MT6358_LDO_VCAMD_CON0, 0, MT6358_VCAMD_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
+                  MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vmch", VMCH, vmch_vemc_voltages, vmch_vemc_idx,
+                  MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700, 8),
+       MT6358_LDO("ldo_vcama1", VCAMA1, vcama_voltages, vcama_idx,
+                  MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
+                  MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700, 8),
+       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, 8),
+       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, 8),
+       MT6358_LDO("ldo_vcama2", VCAMA2, vcama_voltages, vcama_idx,
+                  MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
+                  MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vldo28", VLDO28, vldo28_voltages, vldo28_idx,
+                  MT6358_LDO_VLDO28_CON0_0, 0,
+                  MT6358_VLDO28_ANA_CON0, 0x300, 8),
+       MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
+                  MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00, 8),
+       MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f, 8,
+                   MT6358_LDO_VSRAM_CON0, 0x7f),
+       MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f, 8,
+                   MT6358_LDO_VSRAM_CON2, 0x7f),
+       MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f, 8,
+                   MT6358_LDO_VSRAM_CON3, 0x7f),
+       MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f, 8,
+                   MT6358_LDO_VSRAM_CON1, 0x7f),
+};
+
+static int mt6358_regulator_probe(struct platform_device *pdev)
+{
+       struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
+       struct regulator_config config = {};
+       struct regulator_dev *rdev;
+       int i;
+
+       for (i = 0; i < MT6358_MAX_REGULATOR; i++) {
+               config.dev = &pdev->dev;
+               config.driver_data = &mt6358_regulators[i];
+               config.regmap = mt6397->regmap;
+
+               rdev = devm_regulator_register(&pdev->dev,
+                                              &mt6358_regulators[i].desc,
+                                              &config);
+               if (IS_ERR(rdev)) {
+                       dev_err(&pdev->dev, "failed to register %s\n",
+                               mt6358_regulators[i].desc.name);
+                       return PTR_ERR(rdev);
+               }
+       }
+
+       return 0;
+}
+
+static const struct platform_device_id mt6358_platform_ids[] = {
+       {"mt6358-regulator", 0},
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, mt6358_platform_ids);
+
+static struct platform_driver mt6358_regulator_driver = {
+       .driver = {
+               .name = "mt6358-regulator",
+       },
+       .probe = mt6358_regulator_probe,
+       .id_table = mt6358_platform_ids,
+};
+
+module_platform_driver(mt6358_regulator_driver);
+
+MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6358 PMIC");
+MODULE_LICENSE("GPL");
index b2c2d01d1637060192f0d1554f201d276ef1b901..db6c085da65ecf742daeca83824072ab70a3834b 100644 (file)
@@ -50,6 +50,20 @@ enum rpmh_regulator_type {
 #define PMIC4_BOB_MODE_AUTO                    2
 #define PMIC4_BOB_MODE_PWM                     3
 
+#define PMIC5_LDO_MODE_RETENTION               3
+#define PMIC5_LDO_MODE_LPM                     4
+#define PMIC5_LDO_MODE_HPM                     7
+
+#define PMIC5_SMPS_MODE_RETENTION              3
+#define PMIC5_SMPS_MODE_PFM                    4
+#define PMIC5_SMPS_MODE_AUTO                   6
+#define PMIC5_SMPS_MODE_PWM                    7
+
+#define PMIC5_BOB_MODE_PASS                    2
+#define PMIC5_BOB_MODE_PFM                     4
+#define PMIC5_BOB_MODE_AUTO                    6
+#define PMIC5_BOB_MODE_PWM                     7
+
 /**
  * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations
  * @regulator_type:            RPMh accelerator type used to manage this
@@ -488,6 +502,14 @@ static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
        [REGULATOR_MODE_FAST]    = -EINVAL,
 };
 
+static const int pmic_mode_map_pmic5_ldo[REGULATOR_MODE_STANDBY + 1] = {
+       [REGULATOR_MODE_INVALID] = -EINVAL,
+       [REGULATOR_MODE_STANDBY] = PMIC5_LDO_MODE_RETENTION,
+       [REGULATOR_MODE_IDLE]    = PMIC5_LDO_MODE_LPM,
+       [REGULATOR_MODE_NORMAL]  = PMIC5_LDO_MODE_HPM,
+       [REGULATOR_MODE_FAST]    = -EINVAL,
+};
+
 static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode)
 {
        unsigned int mode;
@@ -518,6 +540,14 @@ static const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = {
        [REGULATOR_MODE_FAST]    = PMIC4_SMPS_MODE_PWM,
 };
 
+static const int pmic_mode_map_pmic5_smps[REGULATOR_MODE_STANDBY + 1] = {
+       [REGULATOR_MODE_INVALID] = -EINVAL,
+       [REGULATOR_MODE_STANDBY] = PMIC5_SMPS_MODE_RETENTION,
+       [REGULATOR_MODE_IDLE]    = PMIC5_SMPS_MODE_PFM,
+       [REGULATOR_MODE_NORMAL]  = PMIC5_SMPS_MODE_AUTO,
+       [REGULATOR_MODE_FAST]    = PMIC5_SMPS_MODE_PWM,
+};
+
 static unsigned int
 rpmh_regulator_pmic4_smps_of_map_mode(unsigned int rpmh_mode)
 {
@@ -552,6 +582,14 @@ static const int pmic_mode_map_pmic4_bob[REGULATOR_MODE_STANDBY + 1] = {
        [REGULATOR_MODE_FAST]    = PMIC4_BOB_MODE_PWM,
 };
 
+static const int pmic_mode_map_pmic5_bob[REGULATOR_MODE_STANDBY + 1] = {
+       [REGULATOR_MODE_INVALID] = -EINVAL,
+       [REGULATOR_MODE_STANDBY] = -EINVAL,
+       [REGULATOR_MODE_IDLE]    = PMIC5_BOB_MODE_PFM,
+       [REGULATOR_MODE_NORMAL]  = PMIC5_BOB_MODE_AUTO,
+       [REGULATOR_MODE_FAST]    = PMIC5_BOB_MODE_PWM,
+};
+
 static unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int rpmh_mode)
 {
        unsigned int mode;
@@ -637,6 +675,72 @@ static const struct rpmh_vreg_hw_data pmic4_lvs = {
        /* LVS hardware does not support voltage or mode configuration. */
 };
 
+static const struct rpmh_vreg_hw_data pmic5_pldo = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_drms_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000),
+       .n_voltages = 256,
+       .hpm_min_load_uA = 10000,
+       .pmic_mode_map = pmic_mode_map_pmic5_ldo,
+       .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_pldo_lv = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_drms_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 62, 8000),
+       .n_voltages = 63,
+       .hpm_min_load_uA = 10000,
+       .pmic_mode_map = pmic_mode_map_pmic5_ldo,
+       .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_nldo = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_drms_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 123, 8000),
+       .n_voltages = 124,
+       .hpm_min_load_uA = 30000,
+       .pmic_mode_map = pmic_mode_map_pmic5_ldo,
+       .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_hfsmps510 = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
+       .n_voltages = 216,
+       .pmic_mode_map = pmic_mode_map_pmic5_smps,
+       .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
+       .n_voltages = 264,
+       .pmic_mode_map = pmic_mode_map_pmic5_smps,
+       .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 1600),
+       .n_voltages = 5,
+       .pmic_mode_map = pmic_mode_map_pmic5_smps,
+       .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_bob = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_bypass_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 135, 32000),
+       .n_voltages = 136,
+       .pmic_mode_map = pmic_mode_map_pmic5_bob,
+       .of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
+};
+
 #define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
 { \
        .name           = _name, \
@@ -705,6 +809,75 @@ static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
        {},
 };
 
+static const struct rpmh_vreg_init_data pm8150_vreg_data[] = {
+       RPMH_VREG("smps1",  "smp%s1",  &pmic5_ftsmps510, "vdd-s1"),
+       RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps510, "vdd-s2"),
+       RPMH_VREG("smps3",  "smp%s3",  &pmic5_ftsmps510, "vdd-s3"),
+       RPMH_VREG("smps4",  "smp%s4",  &pmic5_hfsmps510,   "vdd-s4"),
+       RPMH_VREG("smps5",  "smp%s5",  &pmic5_hfsmps510,   "vdd-s5"),
+       RPMH_VREG("smps6",  "smp%s6",  &pmic5_ftsmps510, "vdd-s6"),
+       RPMH_VREG("smps7",  "smp%s7",  &pmic5_ftsmps510, "vdd-s7"),
+       RPMH_VREG("smps8",  "smp%s8",  &pmic5_ftsmps510, "vdd-s8"),
+       RPMH_VREG("smps9",  "smp%s9",  &pmic5_ftsmps510, "vdd-s9"),
+       RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps510, "vdd-s10"),
+       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,      "vdd-l1-l8-l11"),
+       RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_pldo,      "vdd-l2-l10"),
+       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
+       RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
+       RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
+       RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_nldo,      "vdd-l6-l9"),
+       RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo,      "vdd-l7-l12-l14-l15"),
+       RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_nldo,      "vdd-l1-l8-l11"),
+       RPMH_VREG("ldo9",   "ldo%s9",  &pmic5_nldo,      "vdd-l6-l9"),
+       RPMH_VREG("ldo10",  "ldo%s10", &pmic5_pldo,      "vdd-l2-l10"),
+       RPMH_VREG("ldo11",  "ldo%s11", &pmic5_nldo,      "vdd-l1-l8-l11"),
+       RPMH_VREG("ldo12",  "ldo%s12", &pmic5_pldo_lv,   "vdd-l7-l12-l14-l15"),
+       RPMH_VREG("ldo13",  "ldo%s13", &pmic5_pldo,      "vdd-l13-l6-l17"),
+       RPMH_VREG("ldo14",  "ldo%s14", &pmic5_pldo_lv,   "vdd-l7-l12-l14-l15"),
+       RPMH_VREG("ldo15",  "ldo%s15", &pmic5_pldo_lv,   "vdd-l7-l12-l14-l15"),
+       RPMH_VREG("ldo16",  "ldo%s16", &pmic5_pldo,      "vdd-l13-l6-l17"),
+       RPMH_VREG("ldo17",  "ldo%s17", &pmic5_pldo,      "vdd-l13-l6-l17"),
+       RPMH_VREG("ldo18",  "ldo%s18", &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
+       {},
+};
+
+static const struct rpmh_vreg_init_data pm8150l_vreg_data[] = {
+       RPMH_VREG("smps1",  "smp%s1",  &pmic5_ftsmps510, "vdd-s1"),
+       RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps510, "vdd-s2"),
+       RPMH_VREG("smps3",  "smp%s3",  &pmic5_ftsmps510, "vdd-s3"),
+       RPMH_VREG("smps4",  "smp%s4",  &pmic5_ftsmps510, "vdd-s4"),
+       RPMH_VREG("smps5",  "smp%s5",  &pmic5_ftsmps510, "vdd-s5"),
+       RPMH_VREG("smps6",  "smp%s6",  &pmic5_ftsmps510, "vdd-s6"),
+       RPMH_VREG("smps7",  "smp%s7",  &pmic5_ftsmps510, "vdd-s7"),
+       RPMH_VREG("smps8",  "smp%s8",  &pmic5_hfsmps510, "vdd-s8"),
+       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_pldo_lv,   "vdd-l1-l8"),
+       RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l2-l3"),
+       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l2-l3"),
+       RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_pldo,      "vdd-l4-l5-l6"),
+       RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,      "vdd-l4-l5-l6"),
+       RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo,      "vdd-l4-l5-l6"),
+       RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo,      "vdd-l7-l11"),
+       RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_pldo_lv,   "vdd-l1-l8-l11"),
+       RPMH_VREG("ldo9",   "ldo%s9",  &pmic5_pldo,      "vdd-l9-l10"),
+       RPMH_VREG("ldo10",  "ldo%s10", &pmic5_pldo,      "vdd-l9-l10"),
+       RPMH_VREG("ldo11",  "ldo%s11", &pmic5_pldo,      "vdd-l7-l11"),
+       RPMH_VREG("bob",    "bob%s1",  &pmic5_bob,       "vdd-bob"),
+       {},
+};
+
+static const struct rpmh_vreg_init_data pm8009_vreg_data[] = {
+       RPMH_VREG("smps1",  "smp%s1",  &pmic5_hfsmps510, "vdd-s1"),
+       RPMH_VREG("smps2",  "smp%s2",  &pmic5_hfsmps515, "vdd-s2"),
+       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,      "vdd-l1"),
+       RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l2"),
+       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l3"),
+       RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo,      "vdd-l4"),
+       RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,      "vdd-l5-l6"),
+       RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo,      "vdd-l5-l6"),
+       RPMH_VREG("ldo7",   "ldo%s6",  &pmic5_pldo_lv,   "vdd-l7"),
+       {},
+};
+
 static int rpmh_regulator_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -743,6 +916,22 @@ static int rpmh_regulator_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id rpmh_regulator_match_table[] = {
+       {
+               .compatible = "qcom,pm8005-rpmh-regulators",
+               .data = pm8005_vreg_data,
+       },
+       {
+               .compatible = "qcom,pm8009-rpmh-regulators",
+               .data = pm8009_vreg_data,
+       },
+       {
+               .compatible = "qcom,pm8150-rpmh-regulators",
+               .data = pm8150_vreg_data,
+       },
+       {
+               .compatible = "qcom,pm8150l-rpmh-regulators",
+               .data = pm8150l_vreg_data,
+       },
        {
                .compatible = "qcom,pm8998-rpmh-regulators",
                .data = pm8998_vreg_data,
@@ -751,10 +940,6 @@ static const struct of_device_id rpmh_regulator_match_table[] = {
                .compatible = "qcom,pmi8998-rpmh-regulators",
                .data = pmi8998_vreg_data,
        },
-       {
-               .compatible = "qcom,pm8005-rpmh-regulators",
-               .data = pm8005_vreg_data,
-       },
        {}
 };
 MODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
index e7af0c53d4496f5ddafdfad971ff1c9aa66dc4dc..61bd5ef0806c22f4eba2f530a9264d9ee7fdd26b 100644 (file)
@@ -606,7 +606,7 @@ static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
        case 2:
                return REGULATOR_MODE_NORMAL;
        default:
-               return -EINVAL;
+               return REGULATOR_MODE_INVALID;
        }
 }
 
index 054baaadfdfddc39c83f7ffd1fa58c6a29f2eb7f..5bc00884cf512d4ebecfe470603a97f9a3827a43 100644 (file)
@@ -1226,7 +1226,7 @@ common_reg:
                        goto out;
                }
 
-               if (s2mps11->ext_control_gpiod[i]) {
+               if (config.ena_gpiod) {
                        ret = s2mps14_pmic_enable_ext_control(s2mps11,
                                        regulator);
                        if (ret < 0) {
index 4d859fef55e681e81701fb023f0842b23f2413ff..a0565daecacef3bbf9971f23286e7f0151bea89a 100644 (file)
@@ -447,19 +447,20 @@ static int slg51000_i2c_probe(struct i2c_client *client,
 {
        struct device *dev = &client->dev;
        struct slg51000 *chip;
-       struct gpio_desc *cs_gpiod = NULL;
+       struct gpio_desc *cs_gpiod;
        int error, ret;
 
        chip = devm_kzalloc(dev, sizeof(struct slg51000), GFP_KERNEL);
        if (!chip)
                return -ENOMEM;
 
-       cs_gpiod = devm_gpiod_get_from_of_node(dev, dev->of_node,
-                                              "dlg,cs-gpios", 0,
-                                              GPIOD_OUT_HIGH
-                                              | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
-                                              "slg51000-cs");
-       if (!IS_ERR(cs_gpiod)) {
+       cs_gpiod = devm_gpiod_get_optional(dev, "dlg,cs",
+                                          GPIOD_OUT_HIGH |
+                                               GPIOD_FLAGS_BIT_NONEXCLUSIVE);
+       if (IS_ERR(cs_gpiod))
+               return PTR_ERR(cs_gpiod);
+
+       if (cs_gpiod) {
                dev_info(dev, "Found chip selector property\n");
                chip->cs_gpiod = cs_gpiod;
        }
index 2a897666c65064b42ac69f49c32be3f1d5a21454..03f162ffd1440f7b0aad52b62dbdd52b75b6f56b 100644 (file)
@@ -20,7 +20,6 @@
 #define STM32MP1_SYSCFG_EN_BOOSTER_MASK        BIT(8)
 
 static const struct regulator_ops stm32h7_booster_ops = {
-       .list_voltage   = regulator_list_voltage_linear,
        .enable         = regulator_enable_regmap,
        .disable        = regulator_disable_regmap,
        .is_enabled     = regulator_is_enabled_regmap,
@@ -31,7 +30,6 @@ static const struct regulator_desc stm32h7_booster_desc = {
        .supply_name = "vdda",
        .n_voltages = 1,
        .type = REGULATOR_VOLTAGE,
-       .min_uV = 3300000,
        .fixed_uV = 3300000,
        .ramp_delay = 66000, /* up to 50us to stabilize */
        .ops = &stm32h7_booster_ops,
@@ -53,7 +51,6 @@ static int stm32mp1_booster_disable(struct regulator_dev *rdev)
 }
 
 static const struct regulator_ops stm32mp1_booster_ops = {
-       .list_voltage   = regulator_list_voltage_linear,
        .enable         = stm32mp1_booster_enable,
        .disable        = stm32mp1_booster_disable,
        .is_enabled     = regulator_is_enabled_regmap,
@@ -64,7 +61,6 @@ static const struct regulator_desc stm32mp1_booster_desc = {
        .supply_name = "vdda",
        .n_voltages = 1,
        .type = REGULATOR_VOLTAGE,
-       .min_uV = 3300000,
        .fixed_uV = 3300000,
        .ramp_delay = 66000,
        .ops = &stm32mp1_booster_ops,
diff --git a/drivers/regulator/sy8824x.c b/drivers/regulator/sy8824x.c
new file mode 100644 (file)
index 0000000..92adb4f
--- /dev/null
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// SY8824C/SY8824E regulator driver
+//
+// Copyright (C) 2019 Synaptics Incorporated
+//
+// Author: Jisheng Zhang <jszhang@kernel.org>
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#define SY8824C_BUCK_EN                (1 << 7)
+#define SY8824C_MODE           (1 << 6)
+
+struct sy8824_config {
+       /* registers */
+       unsigned int vol_reg;
+       unsigned int mode_reg;
+       unsigned int enable_reg;
+       /* Voltage range and step(linear) */
+       unsigned int vsel_min;
+       unsigned int vsel_step;
+       unsigned int vsel_count;
+};
+
+struct sy8824_device_info {
+       struct device *dev;
+       struct regulator_desc desc;
+       struct regulator_init_data *regulator;
+       const struct sy8824_config *cfg;
+};
+
+static int sy8824_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       struct sy8824_device_info *di = rdev_get_drvdata(rdev);
+       const struct sy8824_config *cfg = di->cfg;
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+               regmap_update_bits(rdev->regmap, cfg->mode_reg,
+                                  SY8824C_MODE, SY8824C_MODE);
+               break;
+       case REGULATOR_MODE_NORMAL:
+               regmap_update_bits(rdev->regmap, cfg->mode_reg,
+                                  SY8824C_MODE, 0);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static unsigned int sy8824_get_mode(struct regulator_dev *rdev)
+{
+       struct sy8824_device_info *di = rdev_get_drvdata(rdev);
+       const struct sy8824_config *cfg = di->cfg;
+       u32 val;
+       int ret = 0;
+
+       ret = regmap_read(rdev->regmap, cfg->mode_reg, &val);
+       if (ret < 0)
+               return ret;
+       if (val & SY8824C_MODE)
+               return REGULATOR_MODE_FAST;
+       else
+               return REGULATOR_MODE_NORMAL;
+}
+
+static const struct regulator_ops sy8824_regulator_ops = {
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .set_voltage_time_sel = regulator_set_voltage_time_sel,
+       .map_voltage = regulator_map_voltage_linear,
+       .list_voltage = regulator_list_voltage_linear,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .set_mode = sy8824_set_mode,
+       .get_mode = sy8824_get_mode,
+};
+
+static int sy8824_regulator_register(struct sy8824_device_info *di,
+                       struct regulator_config *config)
+{
+       struct regulator_desc *rdesc = &di->desc;
+       const struct sy8824_config *cfg = di->cfg;
+       struct regulator_dev *rdev;
+
+       rdesc->name = "sy8824-reg";
+       rdesc->supply_name = "vin";
+       rdesc->ops = &sy8824_regulator_ops;
+       rdesc->type = REGULATOR_VOLTAGE;
+       rdesc->n_voltages = cfg->vsel_count;
+       rdesc->enable_reg = cfg->enable_reg;
+       rdesc->enable_mask = SY8824C_BUCK_EN;
+       rdesc->min_uV = cfg->vsel_min;
+       rdesc->uV_step = cfg->vsel_step;
+       rdesc->vsel_reg = cfg->vol_reg;
+       rdesc->vsel_mask = cfg->vsel_count - 1;
+       rdesc->owner = THIS_MODULE;
+
+       rdev = devm_regulator_register(di->dev, &di->desc, config);
+       return PTR_ERR_OR_ZERO(rdev);
+}
+
+static const struct regmap_config sy8824_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
+static int sy8824_i2c_probe(struct i2c_client *client,
+                           const struct i2c_device_id *id)
+{
+       struct device *dev = &client->dev;
+       struct device_node *np = dev->of_node;
+       struct sy8824_device_info *di;
+       struct regulator_config config = { };
+       struct regmap *regmap;
+       int ret;
+
+       di = devm_kzalloc(dev, sizeof(struct sy8824_device_info), GFP_KERNEL);
+       if (!di)
+               return -ENOMEM;
+
+       di->regulator = of_get_regulator_init_data(dev, np, &di->desc);
+       if (!di->regulator) {
+               dev_err(dev, "Platform data not found!\n");
+               return -EINVAL;
+       }
+
+       di->dev = dev;
+       di->cfg = of_device_get_match_data(dev);
+
+       regmap = devm_regmap_init_i2c(client, &sy8824_regmap_config);
+       if (IS_ERR(regmap)) {
+               dev_err(dev, "Failed to allocate regmap!\n");
+               return PTR_ERR(regmap);
+       }
+       i2c_set_clientdata(client, di);
+
+       config.dev = di->dev;
+       config.init_data = di->regulator;
+       config.regmap = regmap;
+       config.driver_data = di;
+       config.of_node = np;
+
+       ret = sy8824_regulator_register(di, &config);
+       if (ret < 0)
+               dev_err(dev, "Failed to register regulator!\n");
+       return ret;
+}
+
+static const struct sy8824_config sy8824c_cfg = {
+       .vol_reg = 0x00,
+       .mode_reg = 0x00,
+       .enable_reg = 0x00,
+       .vsel_min = 762500,
+       .vsel_step = 12500,
+       .vsel_count = 64,
+};
+
+static const struct sy8824_config sy8824e_cfg = {
+       .vol_reg = 0x00,
+       .mode_reg = 0x00,
+       .enable_reg = 0x00,
+       .vsel_min = 700000,
+       .vsel_step = 12500,
+       .vsel_count = 64,
+};
+
+static const struct sy8824_config sy20276_cfg = {
+       .vol_reg = 0x00,
+       .mode_reg = 0x01,
+       .enable_reg = 0x01,
+       .vsel_min = 600000,
+       .vsel_step = 10000,
+       .vsel_count = 128,
+};
+
+static const struct sy8824_config sy20278_cfg = {
+       .vol_reg = 0x00,
+       .mode_reg = 0x01,
+       .enable_reg = 0x01,
+       .vsel_min = 762500,
+       .vsel_step = 12500,
+       .vsel_count = 64,
+};
+
+static const struct of_device_id sy8824_dt_ids[] = {
+       {
+               .compatible = "silergy,sy8824c",
+               .data = &sy8824c_cfg
+       },
+       {
+               .compatible = "silergy,sy8824e",
+               .data = &sy8824e_cfg
+       },
+       {
+               .compatible = "silergy,sy20276",
+               .data = &sy20276_cfg
+       },
+       {
+               .compatible = "silergy,sy20278",
+               .data = &sy20278_cfg
+       },
+       { }
+};
+MODULE_DEVICE_TABLE(of, sy8824_dt_ids);
+
+static const struct i2c_device_id sy8824_id[] = {
+       { "sy8824", },
+       { },
+};
+MODULE_DEVICE_TABLE(i2c, sy8824_id);
+
+static struct i2c_driver sy8824_regulator_driver = {
+       .driver = {
+               .name = "sy8824-regulator",
+               .of_match_table = of_match_ptr(sy8824_dt_ids),
+       },
+       .probe = sy8824_i2c_probe,
+       .id_table = sy8824_id,
+};
+module_i2c_driver(sy8824_regulator_driver);
+
+MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>");
+MODULE_DESCRIPTION("SY8824C/SY8824E regulator driver");
+MODULE_LICENSE("GPL v2");
index 6e22f5ebba2e84358839731452e6b61d5549620e..e302bd01a0849e261e40b5024ff6836f449557ea 100644 (file)
@@ -138,7 +138,7 @@ static int tps65132_of_parse_cb(struct device_node *np,
 
        rpdata->en_gpiod = devm_fwnode_get_index_gpiod_from_child(tps->dev,
                                        "enable", 0, &np->fwnode, 0, "enable");
-       if (IS_ERR(rpdata->en_gpiod)) {
+       if (IS_ERR_OR_NULL(rpdata->en_gpiod)) {
                ret = PTR_ERR(rpdata->en_gpiod);
 
                /* Ignore the error other than probe defer */
@@ -150,7 +150,7 @@ static int tps65132_of_parse_cb(struct device_node *np,
        rpdata->act_dis_gpiod = devm_fwnode_get_index_gpiod_from_child(
                                        tps->dev, "active-discharge", 0,
                                        &np->fwnode, 0, "active-discharge");
-       if (IS_ERR(rpdata->act_dis_gpiod)) {
+       if (IS_ERR_OR_NULL(rpdata->act_dis_gpiod)) {
                ret = PTR_ERR(rpdata->act_dis_gpiod);
 
                /* Ignore the error other than probe defer */
index 5fe208b381eb26ab8ae55d2f6be3c0fc656c45ce..b8100c3cedad3fc91bebe9c2f09fb09b85d15b28 100644 (file)
@@ -57,6 +57,9 @@ struct twlreg_info {
 #define VREG_BC_PROC           3
 #define VREG_BC_CLK_RST                4
 
+/* TWL6030 LDO register values for VREG_VOLTAGE */
+#define TWL6030_VREG_VOLTAGE_WR_S   BIT(7)
+
 /* TWL6030 LDO register values for CFG_STATE */
 #define TWL6030_CFG_STATE_OFF  0x00
 #define TWL6030_CFG_STATE_ON   0x01
@@ -68,9 +71,10 @@ struct twlreg_info {
 #define TWL6030_CFG_STATE_APP(v)       (((v) & TWL6030_CFG_STATE_APP_MASK) >>\
                                                TWL6030_CFG_STATE_APP_SHIFT)
 
-/* Flags for SMPS Voltage reading */
+/* Flags for SMPS Voltage reading and LDO reading*/
 #define SMPS_OFFSET_EN         BIT(0)
 #define SMPS_EXTENDED_EN       BIT(1)
+#define TWL_6030_WARM_RESET    BIT(3)
 
 /* twl6032 SMPS EPROM values */
 #define TWL6030_SMPS_OFFSET            0xB0
@@ -250,6 +254,9 @@ twl6030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
 {
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
 
+       if (info->flags & TWL_6030_WARM_RESET)
+               selector |= TWL6030_VREG_VOLTAGE_WR_S;
+
        return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE,
                            selector);
 }
@@ -259,6 +266,9 @@ static int twl6030ldo_get_voltage_sel(struct regulator_dev *rdev)
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
        int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE);
 
+       if (info->flags & TWL_6030_WARM_RESET)
+               vsel &= ~TWL6030_VREG_VOLTAGE_WR_S;
+
        return vsel;
 }
 
@@ -665,14 +675,14 @@ static int twlreg_probe(struct platform_device *pdev)
        struct regulation_constraints   *c;
        struct regulator_dev            *rdev;
        struct regulator_config         config = { };
+       struct device_node              *np = pdev->dev.of_node;
 
        template = of_device_get_match_data(&pdev->dev);
        if (!template)
                return -ENODEV;
 
        id = template->desc.id;
-       initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
-                                               &template->desc);
+       initdata = of_get_regulator_init_data(&pdev->dev, np, &template->desc);
        if (!initdata)
                return -EINVAL;
 
@@ -710,10 +720,13 @@ static int twlreg_probe(struct platform_device *pdev)
                break;
        }
 
+       if (of_get_property(np, "ti,retain-on-reset", NULL))
+               info->flags |= TWL_6030_WARM_RESET;
+
        config.dev = &pdev->dev;
        config.init_data = initdata;
        config.driver_data = info;
-       config.of_node = pdev->dev.of_node;
+       config.of_node = np;
 
        rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
        if (IS_ERR(rdev)) {
index 9026d5a3e964811cd1c7108903dc850c81b7e6ed..2311924c31039423652b71150614a617c0031504 100644 (file)
@@ -185,6 +185,10 @@ static const struct of_device_id uniphier_regulator_match[] = {
                .compatible = "socionext,uniphier-pro4-usb3-regulator",
                .data = &uniphier_pro4_usb3_data,
        },
+       {
+               .compatible = "socionext,uniphier-pro5-usb3-regulator",
+               .data = &uniphier_pro4_usb3_data,
+       },
        {
                .compatible = "socionext,uniphier-pxs2-usb3-regulator",
                .data = &uniphier_pxs2_usb3_data,
diff --git a/include/dt-bindings/regulator/active-semi,8865-regulator.h b/include/dt-bindings/regulator/active-semi,8865-regulator.h
new file mode 100644 (file)
index 0000000..15473db
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Device Tree binding constants for the ACT8865 PMIC regulators
+ */
+
+#ifndef _DT_BINDINGS_REGULATOR_ACT8865_H
+#define _DT_BINDINGS_REGULATOR_ACT8865_H
+
+/*
+ * These constants should be used to specify regulator modes in device tree for
+ * ACT8865 regulators as follows:
+ * ACT8865_REGULATOR_MODE_FIXED:       It is specific to DCDC regulators and it
+ *                                     specifies the usage of fixed-frequency
+ *                                     PWM.
+ *
+ * ACT8865_REGULATOR_MODE_NORMAL:      It is specific to LDO regulators and it
+ *                                     specifies the usage of normal mode.
+ *
+ * ACT8865_REGULATOR_MODE_LOWPOWER:    For DCDC and LDO regulators; it specify
+ *                                     the usage of proprietary power-saving
+ *                                     mode.
+ */
+
+#define ACT8865_REGULATOR_MODE_FIXED           1
+#define ACT8865_REGULATOR_MODE_NORMAL          2
+#define ACT8865_REGULATOR_MODE_LOWPOWER        3
+
+#endif
index 815983419375a28fb5db6d87843d7acc2d193501..337a463915278cc000cbdb0d47b40ea4e5645a7d 100644 (file)
@@ -281,6 +281,12 @@ void devm_regulator_unregister_notifier(struct regulator *regulator,
 void *regulator_get_drvdata(struct regulator *regulator);
 void regulator_set_drvdata(struct regulator *regulator, void *data);
 
+/* misc helpers */
+
+void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
+                                    const char *const *supply_names,
+                                    unsigned int num_supplies);
+
 #else
 
 /*
@@ -580,6 +586,13 @@ static inline int regulator_list_voltage(struct regulator *regulator, unsigned s
        return -EINVAL;
 }
 
+static inline void
+regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
+                               const char *const *supply_names,
+                               unsigned int num_supplies)
+{
+}
+
 #endif
 
 static inline int regulator_set_voltage_triplet(struct regulator *regulator,
diff --git a/include/linux/regulator/mt6358-regulator.h b/include/linux/regulator/mt6358-regulator.h
new file mode 100644 (file)
index 0000000..1cc3049
--- /dev/null
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef __LINUX_REGULATOR_MT6358_H
+#define __LINUX_REGULATOR_MT6358_H
+
+enum {
+       MT6358_ID_VDRAM1 = 0,
+       MT6358_ID_VCORE,
+       MT6358_ID_VPA,
+       MT6358_ID_VPROC11,
+       MT6358_ID_VPROC12,
+       MT6358_ID_VGPU,
+       MT6358_ID_VS2,
+       MT6358_ID_VMODEM,
+       MT6358_ID_VS1,
+       MT6358_ID_VDRAM2 = 9,
+       MT6358_ID_VSIM1,
+       MT6358_ID_VIBR,
+       MT6358_ID_VRF12,
+       MT6358_ID_VIO18,
+       MT6358_ID_VUSB,
+       MT6358_ID_VCAMIO,
+       MT6358_ID_VCAMD,
+       MT6358_ID_VCN18,
+       MT6358_ID_VFE28,
+       MT6358_ID_VSRAM_PROC11,
+       MT6358_ID_VCN28,
+       MT6358_ID_VSRAM_OTHERS,
+       MT6358_ID_VSRAM_GPU,
+       MT6358_ID_VXO22,
+       MT6358_ID_VEFUSE,
+       MT6358_ID_VAUX18,
+       MT6358_ID_VMCH,
+       MT6358_ID_VBIF28,
+       MT6358_ID_VSRAM_PROC12,
+       MT6358_ID_VCAMA1,
+       MT6358_ID_VEMC,
+       MT6358_ID_VIO28,
+       MT6358_ID_VA12,
+       MT6358_ID_VRF18,
+       MT6358_ID_VCN33_BT,
+       MT6358_ID_VCN33_WIFI,
+       MT6358_ID_VCAMA2,
+       MT6358_ID_VMC,
+       MT6358_ID_VLDO28,
+       MT6358_ID_VAUD28,
+       MT6358_ID_VSIM2,
+       MT6358_ID_RG_MAX,
+};
+
+#define MT6358_MAX_REGULATOR   MT6358_ID_RG_MAX
+
+#endif /* __LINUX_REGULATOR_MT6358_H */