regulator: Updates for v5.14

The main core change this release is generic support for handling of
 hardware errors from Matti Vaittinen, including some small updates to
 the reboot and thermal code so we can share support for powering off the
 system if things are going wrong enough.  Otherwise this release we've
 mainly seen the addition of new drivers, including MT6359 which has
 pulled in some small changes from the MFD tree for build dependencies.
 
  - Support for controlling the trigger points for hardware error
    detection, and shared handlers for this.
  - Support for Maxim MAX8993, Mediatek MT6359 and MT6359P, Qualcomm
    PM8226 and SA8115P-ADP, and Sylergy TCS4526.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmDZ0awACgkQJNaLcl1U
 h9CQ4QgAgF9bejmNcBDIDBoGd1OlO2HIZeamVyvVEbzy1eG0vU1dxmatrS09ccfZ
 1r4uHYjSwoWoggvOhdlIglqOTsTxM5zHEtz00lXR1iOd9Y6nPkCztT9HGV/bjn3E
 It42MNnbStIZ+XuQDzGxzEaFr9O2AKyA6u54iSSaiIIjUA7Ndg6SEcw3BqOMTk2J
 pueebhbznawYUkwxT8mKJY3eJG6rh3+cy/Vpm1yL97x4C0435Fm/xfjrVcELSsaF
 e+I+XZZsaGQwOouQl05nbHpcU1agsH33e6rgsThReNRLRKl116Zz+GIZvmawlE7T
 AZaZeI3cQZu0oVRT4iA3nV8MY0LlnA==
 =XB/O
 -----END PGP SIGNATURE-----

Merge tag 'regulator-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "The main core change this release is generic support for handling of
  hardware errors from Matti Vaittinen, including some small updates to
  the reboot and thermal code so we can share support for powering off
  the system if things are going wrong enough.

  Otherwise this release we've mainly seen the addition of new drivers,
  including MT6359 which has pulled in some small changes from the MFD
  tree for build dependencies.

   - Support for controlling the trigger points for hardware error
     detection, and shared handlers for this.

   - Support for Maxim MAX8993, Mediatek MT6359 and MT6359P, Qualcomm
     PM8226 and SA8115P-ADP, and Sylergy TCS4526"

* tag 'regulator-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (91 commits)
  regulator: bd9576: Fix uninitializes variable may_have_irqs
  regulator: max8893: Select REGMAP_I2C to fix build error
  regulator: da9052: Ensure enough delay time for .set_voltage_time_sel
  regulator: mt6358: Fix vdram2 .vsel_mask
  regulator: hi6421v600: Fix setting wrong driver_data
  MAINTAINERS: Add reviewer for regulator irq_helpers
  regulator: bd9576: Fix the driver name in id table
  regulator: bd9576: Support error reporting
  regulator: bd9576 add FET ON-resistance for OCW
  regulator: add property parsing and callbacks to set protection limits
  regulator: IRQ based event/error notification helpers
  regulator: move rdev_print helpers to internal.h
  regulator: add warning flags
  thermal: Use generic HW-protection shutdown API
  reboot: Add hardware protection power-off
  regulator: Add protection limit properties
  regulator: hi6421v600: Fix setting idle mode
  regulator: Add MAX8893 bindings
  regulator: max8893: add regulator driver
  regulator: hi6421: Use correct variable type for regmap api val argument
  ...
This commit is contained in:
Linus Torvalds 2021-06-28 11:06:10 -07:00
commit c10383b3fb
71 changed files with 6269 additions and 1253 deletions

View File

@ -21,6 +21,7 @@ Required properties:
compatible:
"mediatek,mt6323" for PMIC MT6323
"mediatek,mt6358" for PMIC MT6358
"mediatek,mt6359" for PMIC MT6359
"mediatek,mt6397" for PMIC MT6397
Optional subnodes:

View File

@ -0,0 +1,88 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/max8893.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Regulator driver for MAX8893 PMIC from Maxim Integrated.
maintainers:
- Sergey Larin <cerg2010cerg2010@mail.ru>
description: |
The device has 5 LDO regulators and a single BUCK regulator.
Programming is done through I2C bus.
properties:
compatible:
const: maxim,max8893
reg:
maxItems: 1
regulators:
type: object
patternProperties:
"^(ldo[1-5]|buck)$":
$ref: "regulator.yaml#"
additionalProperties: false
additionalProperties: false
required:
- compatible
- reg
- regulators
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@3e {
compatible = "maxim,max8893";
reg = <0x3e>;
regulators {
/* Front camera - s5k6aafx, back - m5mo */
/* Numbers used to indicate the sequence */
front_1_back_1: buck {
regulator-name = "cam_isp_core_1v2";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
};
front_4_back_5: ldo1 {
regulator-name = "vt_io_1v8,cam_isp_1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
front_3_back_4: ldo2 {
regulator-name = "vt_core_1v5";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
};
front_5_back_6: ldo3 {
regulator-name = "vt_cam_1v8,vt_sensor_io_1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
ldo4 {
/* not used */
};
back_7: ldo5 {
regulator-name = "cam_sensor_io_1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
};
};
};
...

View File

@ -0,0 +1,385 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/mt6359-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MT6359 Regulator from MediaTek Integrated
maintainers:
- Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
description: |
List of regulators provided by this controller. It is named
according to its regulator type, buck_<name> and ldo_<name>.
MT6359 regulators node should be sub node of the MT6397 MFD node.
patternProperties:
"^buck_v(s1|gpu11|modem|pu|core|s2|pa|proc2|proc1|core_sshub)$":
type: object
$ref: "regulator.yaml#"
properties:
regulator-name:
pattern: "^v(s1|gpu11|modem|pu|core|s2|pa|proc2|proc1|core_sshub)$"
unevaluatedProperties: false
"^ldo_v(ibr|rf12|usb|camio|efuse|xo22)$":
type: object
$ref: "regulator.yaml#"
properties:
regulator-name:
pattern: "^v(ibr|rf12|usb|camio|efuse|xo22)$"
unevaluatedProperties: false
"^ldo_v(rfck|emc|a12|a09|ufs|bbck)$":
type: object
$ref: "regulator.yaml#"
properties:
regulator-name:
pattern: "^v(rfck|emc|a12|a09|ufs|bbck)$"
unevaluatedProperties: false
"^ldo_vcn(18|13|33_1_bt|13_1_wifi|33_2_bt|33_2_wifi)$":
type: object
$ref: "regulator.yaml#"
properties:
regulator-name:
pattern: "^vcn(18|13|33_1_bt|13_1_wifi|33_2_bt|33_2_wifi)$"
unevaluatedProperties: false
"^ldo_vsram_(proc2|others|md|proc1|others_sshub)$":
type: object
$ref: "regulator.yaml#"
properties:
regulator-name:
pattern: "^vsram_(proc2|others|md|proc1|others_sshub)$"
unevaluatedProperties: false
"^ldo_v(fe|bif|io)28$":
type: object
$ref: "regulator.yaml#"
properties:
regulator-name:
pattern: "^v(fe|bif|io)28$"
unevaluatedProperties: false
"^ldo_v(aud|io|aux|rf|m)18$":
type: object
$ref: "regulator.yaml#"
properties:
regulator-name:
pattern: "^v(aud|io|aux|rf|m)18$"
unevaluatedProperties: false
"^ldo_vsim[12]$":
type: object
$ref: "regulator.yaml#"
properties:
regulator-name:
pattern: "^vsim[12]$"
required:
- regulator-name
unevaluatedProperties: false
additionalProperties: false
examples:
- |
pmic {
regulators {
mt6359_vs1_buck_reg: buck_vs1 {
regulator-name = "vs1";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <2200000>;
regulator-enable-ramp-delay = <0>;
regulator-always-on;
};
mt6359_vgpu11_buck_reg: buck_vgpu11 {
regulator-name = "vgpu11";
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <1193750>;
regulator-ramp-delay = <5000>;
regulator-enable-ramp-delay = <200>;
regulator-allowed-modes = <0 1 2>;
};
mt6359_vmodem_buck_reg: buck_vmodem {
regulator-name = "vmodem";
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <1100000>;
regulator-ramp-delay = <10760>;
regulator-enable-ramp-delay = <200>;
};
mt6359_vpu_buck_reg: buck_vpu {
regulator-name = "vpu";
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <1193750>;
regulator-ramp-delay = <5000>;
regulator-enable-ramp-delay = <200>;
regulator-allowed-modes = <0 1 2>;
};
mt6359_vcore_buck_reg: buck_vcore {
regulator-name = "vcore";
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <1300000>;
regulator-ramp-delay = <5000>;
regulator-enable-ramp-delay = <200>;
regulator-allowed-modes = <0 1 2>;
};
mt6359_vs2_buck_reg: buck_vs2 {
regulator-name = "vs2";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1600000>;
regulator-enable-ramp-delay = <0>;
regulator-always-on;
};
mt6359_vpa_buck_reg: buck_vpa {
regulator-name = "vpa";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <3650000>;
regulator-enable-ramp-delay = <300>;
};
mt6359_vproc2_buck_reg: buck_vproc2 {
regulator-name = "vproc2";
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <1193750>;
regulator-ramp-delay = <7500>;
regulator-enable-ramp-delay = <200>;
regulator-allowed-modes = <0 1 2>;
};
mt6359_vproc1_buck_reg: buck_vproc1 {
regulator-name = "vproc1";
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <1193750>;
regulator-ramp-delay = <7500>;
regulator-enable-ramp-delay = <200>;
regulator-allowed-modes = <0 1 2>;
};
mt6359_vcore_sshub_buck_reg: buck_vcore_sshub {
regulator-name = "vcore_sshub";
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <1193750>;
};
mt6359_vgpu11_sshub_buck_reg: buck_vgpu11_sshub {
regulator-name = "vgpu11_sshub";
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <1193750>;
};
mt6359_vaud18_ldo_reg: ldo_vaud18 {
regulator-name = "vaud18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <240>;
};
mt6359_vsim1_ldo_reg: ldo_vsim1 {
regulator-name = "vsim1";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <3100000>;
};
mt6359_vibr_ldo_reg: ldo_vibr {
regulator-name = "vibr";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
};
mt6359_vrf12_ldo_reg: ldo_vrf12 {
regulator-name = "vrf12";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1300000>;
};
mt6359_vusb_ldo_reg: ldo_vusb {
regulator-name = "vusb";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-enable-ramp-delay = <960>;
regulator-always-on;
};
mt6359_vsram_proc2_ldo_reg: ldo_vsram_proc2 {
regulator-name = "vsram_proc2";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1293750>;
regulator-ramp-delay = <7500>;
regulator-enable-ramp-delay = <240>;
regulator-always-on;
};
mt6359_vio18_ldo_reg: ldo_vio18 {
regulator-name = "vio18";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
regulator-enable-ramp-delay = <960>;
regulator-always-on;
};
mt6359_vcamio_ldo_reg: ldo_vcamio {
regulator-name = "vcamio";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
};
mt6359_vcn18_ldo_reg: ldo_vcn18 {
regulator-name = "vcn18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <240>;
};
mt6359_vfe28_ldo_reg: ldo_vfe28 {
regulator-name = "vfe28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <120>;
};
mt6359_vcn13_ldo_reg: ldo_vcn13 {
regulator-name = "vcn13";
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1300000>;
};
mt6359_vcn33_1_bt_ldo_reg: ldo_vcn33_1_bt {
regulator-name = "vcn33_1_bt";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3500000>;
};
mt6359_vcn33_1_wifi_ldo_reg: ldo_vcn33_1_wifi {
regulator-name = "vcn33_1_wifi";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3500000>;
};
mt6359_vaux18_ldo_reg: ldo_vaux18 {
regulator-name = "vaux18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <240>;
regulator-always-on;
};
mt6359_vsram_others_ldo_reg: ldo_vsram_others {
regulator-name = "vsram_others";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1293750>;
regulator-ramp-delay = <5000>;
regulator-enable-ramp-delay = <240>;
};
mt6359_vefuse_ldo_reg: ldo_vefuse {
regulator-name = "vefuse";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <2000000>;
};
mt6359_vxo22_ldo_reg: ldo_vxo22 {
regulator-name = "vxo22";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2200000>;
regulator-always-on;
};
mt6359_vrfck_ldo_reg: ldo_vrfck {
regulator-name = "vrfck";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1700000>;
};
mt6359_vrfck_1_ldo_reg: ldo_vrfck_1 {
regulator-name = "vrfck";
regulator-min-microvolt = <1240000>;
regulator-max-microvolt = <1600000>;
};
mt6359_vbif28_ldo_reg: ldo_vbif28 {
regulator-name = "vbif28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <240>;
};
mt6359_vio28_ldo_reg: ldo_vio28 {
regulator-name = "vio28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
mt6359_vemc_ldo_reg: ldo_vemc {
regulator-name = "vemc";
regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <3300000>;
};
mt6359_vemc_1_ldo_reg: ldo_vemc_1 {
regulator-name = "vemc";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <3300000>;
};
mt6359_vcn33_2_bt_ldo_reg: ldo_vcn33_2_bt {
regulator-name = "vcn33_2_bt";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3500000>;
};
mt6359_vcn33_2_wifi_ldo_reg: ldo_vcn33_2_wifi {
regulator-name = "vcn33_2_wifi";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3500000>;
};
mt6359_va12_ldo_reg: ldo_va12 {
regulator-name = "va12";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
};
mt6359_va09_ldo_reg: ldo_va09 {
regulator-name = "va09";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1200000>;
};
mt6359_vrf18_ldo_reg: ldo_vrf18 {
regulator-name = "vrf18";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1810000>;
};
mt6359_vsram_md_ldo_reg: ldo_vsram_md {
regulator-name = "vsram_md";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1293750>;
regulator-ramp-delay = <10760>;
regulator-enable-ramp-delay = <240>;
};
mt6359_vufs_ldo_reg: ldo_vufs {
regulator-name = "vufs";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
};
mt6359_vm18_ldo_reg: ldo_vm18 {
regulator-name = "vm18";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
regulator-always-on;
};
mt6359_vbbck_ldo_reg: ldo_vbbck {
regulator-name = "vbbck";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1200000>;
};
mt6359_vsram_proc1_ldo_reg: ldo_vsram_proc1 {
regulator-name = "vsram_proc1";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1293750>;
regulator-ramp-delay = <7500>;
regulator-enable-ramp-delay = <240>;
regulator-always-on;
};
mt6359_vsim2_ldo_reg: ldo_vsim2 {
regulator-name = "vsim2";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <3100000>;
};
mt6359_vsram_others_sshub_ldo: ldo_vsram_others_sshub {
regulator-name = "vsram_others_sshub";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1293750>;
};
};
};
...

View File

@ -33,6 +33,9 @@ description: |
The names used for regulator nodes must match those supported by a given
PMIC. Supported regulator node names are
For PM6150, smps1 - smps5, ldo1 - ldo19
For PM6150L, smps1 - smps8, ldo1 - ldo11, bob
For PM7325, smps1 - smps8, ldo1 - ldo19
For PM8005, smps1 - smps4
For PM8009, smps1 - smps2, ldo1 - ldo7
For PM8150, smps1 - smps10, ldo1 - ldo18
@ -41,15 +44,15 @@ description: |
For PM8350C, smps1 - smps10, ldo1 - ldo13, bob
For PM8998, smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
For PMI8998, bob
For PM6150, smps1 - smps5, ldo1 - ldo19
For PM6150L, smps1 - smps8, ldo1 - ldo11, bob
For PMX55, smps1 - smps7, ldo1 - ldo16
For PM7325, smps1 - smps8, ldo1 - ldo19
For PMR735A, smps1 - smps3, ldo1 - ldo7
For PMX55, smps1 - smps7, ldo1 - ldo16
properties:
compatible:
enum:
- qcom,pm6150-rpmh-regulators
- qcom,pm6150l-rpmh-regulators
- qcom,pm7325-rpmh-regulators
- qcom,pm8005-rpmh-regulators
- qcom,pm8009-rpmh-regulators
- qcom,pm8009-1-rpmh-regulators
@ -59,11 +62,9 @@ properties:
- qcom,pm8350c-rpmh-regulators
- qcom,pm8998-rpmh-regulators
- qcom,pmi8998-rpmh-regulators
- qcom,pm6150-rpmh-regulators
- qcom,pm6150l-rpmh-regulators
- qcom,pmx55-rpmh-regulators
- qcom,pm7325-rpmh-regulators
- qcom,pmm8155au-rpmh-regulators
- qcom,pmr735a-rpmh-regulators
- qcom,pmx55-rpmh-regulators
qcom,pmic-id:
description: |

View File

@ -24,6 +24,10 @@ description:
For mp5496, s2
For pm8226, s1, s2, s3, s4, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10,
l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, l25,
l26, l27, l28, lvs1
For pm8841, s1, s2, s3, s4, s5, s6, s7, s8
For pm8916, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
@ -68,6 +72,7 @@ properties:
compatible:
enum:
- qcom,rpm-mp5496-regulators
- qcom,rpm-pm8226-regulators
- qcom,rpm-pm8841-regulators
- qcom,rpm-pm8916-regulators
- qcom,rpm-pm8941-regulators

View File

@ -117,6 +117,88 @@ properties:
description: Enable over current protection.
type: boolean
regulator-oc-protection-microamp:
description: Set over current protection limit. This is a limit where
hardware performs emergency shutdown. Zero can be passed to disable
protection and value '1' indicates that protection should be enabled but
limit setting can be omitted.
regulator-oc-error-microamp:
description: Set over current error limit. This is a limit where part of
the hardware propably is malfunctional and damage prevention is requested.
Zero can be passed to disable error detection and value '1' indicates
that detection should be enabled but limit setting can be omitted.
regulator-oc-warn-microamp:
description: Set over current warning limit. This is a limit where hardware
is assumed still to be functional but approaching limit where it gets
damaged. Recovery actions should be initiated. Zero can be passed to
disable detection and value '1' indicates that detection should
be enabled but limit setting can be omitted.
regulator-ov-protection-microvolt:
description: Set over voltage protection limit. This is a limit where
hardware performs emergency shutdown. Zero can be passed to disable
protection and value '1' indicates that protection should be enabled but
limit setting can be omitted. Limit is given as microvolt offset from
voltage set to regulator.
regulator-ov-error-microvolt:
description: Set over voltage error limit. This is a limit where part of
the hardware propably is malfunctional and damage prevention is requested
Zero can be passed to disable error detection and value '1' indicates
that detection should be enabled but limit setting can be omitted. Limit
is given as microvolt offset from voltage set to regulator.
regulator-ov-warn-microvolt:
description: Set over voltage warning limit. This is a limit where hardware
is assumed still to be functional but approaching limit where it gets
damaged. Recovery actions should be initiated. Zero can be passed to
disable detection and value '1' indicates that detection should
be enabled but limit setting can be omitted. Limit is given as microvolt
offset from voltage set to regulator.
regulator-uv-protection-microvolt:
description: Set over under voltage protection limit. This is a limit where
hardware performs emergency shutdown. Zero can be passed to disable
protection and value '1' indicates that protection should be enabled but
limit setting can be omitted. Limit is given as microvolt offset from
voltage set to regulator.
regulator-uv-error-microvolt:
description: Set under voltage error limit. This is a limit where part of
the hardware propably is malfunctional and damage prevention is requested
Zero can be passed to disable error detection and value '1' indicates
that detection should be enabled but limit setting can be omitted. Limit
is given as microvolt offset from voltage set to regulator.
regulator-uv-warn-microvolt:
description: Set over under voltage warning limit. This is a limit where
hardware is assumed still to be functional but approaching limit where
it gets damaged. Recovery actions should be initiated. Zero can be passed
to disable detection and value '1' indicates that detection should
be enabled but limit setting can be omitted. Limit is given as microvolt
offset from voltage set to regulator.
regulator-temp-protection-kelvin:
description: Set over temperature protection limit. This is a limit where
hardware performs emergency shutdown. Zero can be passed to disable
protection and value '1' indicates that protection should be enabled but
limit setting can be omitted.
regulator-temp-error-kelvin:
description: Set over temperature error limit. This is a limit where part of
the hardware propably is malfunctional and damage prevention is requested
Zero can be passed to disable error detection and value '1' indicates
that detection should be enabled but limit setting can be omitted.
regulator-temp-warn-kelvin:
description: Set over temperature warning limit. This is a limit where
hardware is assumed still to be functional but approaching limit where it
gets damaged. Recovery actions should be initiated. Zero can be passed to
disable detection and value '1' indicates that detection should
be enabled but limit setting can be omitted.
regulator-active-discharge:
description: |
tristate, enable/disable active discharge of regulators. The values are:

View File

@ -0,0 +1,61 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/richtek,rt6160-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Richtek RT6160 BuckBoost converter
maintainers:
- ChiYuan Huang <cy_huang@richtek.com>
description: |
The RT6160 is a high-efficiency buck-boost converter that can provide
up to 3A output current from 2025mV to 5200mV. And it support the wide
input voltage range from 2200mV to 5500mV.
Datasheet is available at
https://www.richtek.com/assets/product_file/RT6160A/DS6160A-00.pdf
allOf:
- $ref: regulator.yaml#
properties:
compatible:
enum:
- richtek,rt6160
reg:
maxItems: 1
enable-gpios:
description: A connection of the 'enable' gpio line.
maxItems: 1
richtek,vsel-active-low:
description: |
Used to indicate the 'vsel' pin active level. if not specified, use
high active level as the default.
type: boolean
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
rt6160@75 {
compatible = "richtek,rt6160";
reg = <0x75>;
enable-gpios = <&gpio26 2 0>;
regulator-name = "rt6160-buckboost";
regulator-min-microvolt = <2025000>;
regulator-max-microvolt = <5200000>;
};
};

View File

@ -0,0 +1,89 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/richtek,rt6245-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Richtek RT6245 High Current Voltage Regulator
maintainers:
- ChiYuan Huang <cy_huang@richtek.com>
description: |
The RT6245 is a high-performance, synchronous step-down converter
that can deliver up to 14A output current with an input supply
voltage range of 4.5V to 17V.
allOf:
- $ref: regulator.yaml#
properties:
compatible:
enum:
- richtek,rt6245
reg:
maxItems: 1
enable-gpios:
description: |
A connection of the chip 'enable' gpio line. If not provided,
it will be treat as a default-on power.
maxItems: 1
richtek,oc-level-select:
$ref: "/schemas/types.yaml#/definitions/uint8"
enum: [0, 1, 2, 3]
description: |
Over current level selection. Each respective value means the current
limit 8A, 14A, 12A, 10A. If this property is missing then keep in
in chip default.
richtek,ot-level-select:
$ref: "/schemas/types.yaml#/definitions/uint8"
enum: [0, 1, 2]
description: |
Over temperature level selection. Each respective value means the degree
150'c, 130'c, 170'c. If this property is missing then keep in chip
default.
richtek,pgdly-time-select:
$ref: "/schemas/types.yaml#/definitions/uint8"
enum: [0, 1, 2, 3]
description: |
Power good signal delay time selection. Each respective value means the
delay time 0us, 10us, 20us, 40us. If this property is missing then keep
in chip default.
richtek,switch-freq-select:
$ref: "/schemas/types.yaml#/definitions/uint8"
enum: [0, 1, 2]
description: |
Buck switch frequency selection. Each respective value means 400KHz,
800KHz, 1200KHz. If this property is missing then keep in chip default.
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
rt6245@34 {
compatible = "richtek,rt6245";
status = "okay";
reg = <0x34>;
enable-gpios = <&gpio26 2 0>;
regulator-name = "rt6245-regulator";
regulator-min-microvolt = <437500>;
regulator-max-microvolt = <1387500>;
regulator-boot-on;
};
};

View File

@ -27,6 +27,12 @@ patternProperties:
Properties for single regulator.
$ref: "regulator.yaml#"
properties:
rohm,ocw-fet-ron-micro-ohms:
description: |
External FET's ON-resistance. Required if VoutS1 OCP/OCW is
to be set.
required:
- regulator-name

View File

@ -740,21 +740,15 @@ possible.
5. thermal_emergency_poweroff
=============================
On an event of critical trip temperature crossing. Thermal framework
allows the system to shutdown gracefully by calling orderly_poweroff().
In the event of a failure of orderly_poweroff() to shut down the system
we are in danger of keeping the system alive at undesirably high
temperatures. To mitigate this high risk scenario we program a work
queue to fire after a pre-determined number of seconds to start
an emergency shutdown of the device using the kernel_power_off()
function. In case kernel_power_off() fails then finally
emergency_restart() is called in the worst case.
On an event of critical trip temperature crossing the thermal framework
shuts down the system by calling hw_protection_shutdown(). The
hw_protection_shutdown() first attempts to perform an orderly shutdown
but accepts a delay after which it proceeds doing a forced power-off
or as last resort an emergency_restart.
The delay should be carefully profiled so as to give adequate time for
orderly_poweroff(). In case of failure of an orderly_poweroff() the
emergency poweroff kicks in after the delay has elapsed and shuts down
the system.
orderly poweroff.
If set to 0 emergency poweroff will not be supported. So a carefully
profiled non-zero positive value is a must for emergency poweroff to be
triggered.
If the delay is set to 0 emergency poweroff will not be supported. So a
carefully profiled non-zero positive value is a must for emergency
poweroff to be triggered.

View File

@ -19561,6 +19561,10 @@ F: include/dt-bindings/regulator/
F: include/linux/regulator/
K: regulator_get_optional
VOLTAGE AND CURRENT REGULATOR IRQ HELPERS
R: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
F: drivers/regulator/irq_helpers.c
VRF
M: David Ahern <dsahern@kernel.org>
L: netdev@vger.kernel.org

View File

@ -5,6 +5,8 @@
#include <linux/interrupt.h>
#include <linux/mfd/mt6358/core.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6359/core.h>
#include <linux/mfd/mt6359/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/module.h>
#include <linux/of.h>
@ -13,7 +15,9 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
static struct irq_top_t mt6358_ints[] = {
#define MTK_PMIC_REG_WIDTH 16
static const struct irq_top_t mt6358_ints[] = {
MT6358_TOP_GEN(BUCK),
MT6358_TOP_GEN(LDO),
MT6358_TOP_GEN(PSC),
@ -24,6 +28,31 @@ static struct irq_top_t mt6358_ints[] = {
MT6358_TOP_GEN(MISC),
};
static const struct irq_top_t mt6359_ints[] = {
MT6359_TOP_GEN(BUCK),
MT6359_TOP_GEN(LDO),
MT6359_TOP_GEN(PSC),
MT6359_TOP_GEN(SCK),
MT6359_TOP_GEN(BM),
MT6359_TOP_GEN(HK),
MT6359_TOP_GEN(AUD),
MT6359_TOP_GEN(MISC),
};
static struct pmic_irq_data mt6358_irqd = {
.num_top = ARRAY_SIZE(mt6358_ints),
.num_pmic_irqs = MT6358_IRQ_NR,
.top_int_status_reg = MT6358_TOP_INT_STATUS0,
.pmic_ints = mt6358_ints,
};
static struct pmic_irq_data mt6359_irqd = {
.num_top = ARRAY_SIZE(mt6359_ints),
.num_pmic_irqs = MT6359_IRQ_NR,
.top_int_status_reg = MT6359_TOP_INT_STATUS0,
.pmic_ints = mt6359_ints,
};
static void pmic_irq_enable(struct irq_data *data)
{
unsigned int hwirq = irqd_to_hwirq(data);
@ -62,15 +91,15 @@ static void pmic_irq_sync_unlock(struct irq_data *data)
/* Find out the IRQ group */
top_gp = 0;
while ((top_gp + 1) < irqd->num_top &&
i >= mt6358_ints[top_gp + 1].hwirq_base)
i >= irqd->pmic_ints[top_gp + 1].hwirq_base)
top_gp++;
/* Find the IRQ registers */
gp_offset = i - mt6358_ints[top_gp].hwirq_base;
int_regs = gp_offset / MT6358_REG_WIDTH;
shift = gp_offset % MT6358_REG_WIDTH;
en_reg = mt6358_ints[top_gp].en_reg +
(mt6358_ints[top_gp].en_reg_shift * int_regs);
gp_offset = i - irqd->pmic_ints[top_gp].hwirq_base;
int_regs = gp_offset / MTK_PMIC_REG_WIDTH;
shift = gp_offset % MTK_PMIC_REG_WIDTH;
en_reg = irqd->pmic_ints[top_gp].en_reg +
(irqd->pmic_ints[top_gp].en_reg_shift * int_regs);
regmap_update_bits(chip->regmap, en_reg, BIT(shift),
irqd->enable_hwirq[i] << shift);
@ -95,10 +124,11 @@ static void mt6358_irq_sp_handler(struct mt6397_chip *chip,
unsigned int irq_status, sta_reg, status;
unsigned int hwirq, virq;
int i, j, ret;
struct pmic_irq_data *irqd = chip->irq_data;
for (i = 0; i < mt6358_ints[top_gp].num_int_regs; i++) {
sta_reg = mt6358_ints[top_gp].sta_reg +
mt6358_ints[top_gp].sta_reg_shift * i;
for (i = 0; i < irqd->pmic_ints[top_gp].num_int_regs; i++) {
sta_reg = irqd->pmic_ints[top_gp].sta_reg +
irqd->pmic_ints[top_gp].sta_reg_shift * i;
ret = regmap_read(chip->regmap, sta_reg, &irq_status);
if (ret) {
@ -114,8 +144,8 @@ static void mt6358_irq_sp_handler(struct mt6397_chip *chip,
do {
j = __ffs(status);
hwirq = mt6358_ints[top_gp].hwirq_base +
MT6358_REG_WIDTH * i + j;
hwirq = irqd->pmic_ints[top_gp].hwirq_base +
MTK_PMIC_REG_WIDTH * i + j;
virq = irq_find_mapping(chip->irq_domain, hwirq);
if (virq)
@ -131,12 +161,12 @@ static void mt6358_irq_sp_handler(struct mt6397_chip *chip,
static irqreturn_t mt6358_irq_handler(int irq, void *data)
{
struct mt6397_chip *chip = data;
struct pmic_irq_data *mt6358_irq_data = chip->irq_data;
struct pmic_irq_data *irqd = chip->irq_data;
unsigned int bit, i, top_irq_status = 0;
int ret;
ret = regmap_read(chip->regmap,
mt6358_irq_data->top_int_status_reg,
irqd->top_int_status_reg,
&top_irq_status);
if (ret) {
dev_err(chip->dev,
@ -144,8 +174,8 @@ static irqreturn_t mt6358_irq_handler(int irq, void *data)
return IRQ_NONE;
}
for (i = 0; i < mt6358_irq_data->num_top; i++) {
bit = BIT(mt6358_ints[i].top_offset);
for (i = 0; i < irqd->num_top; i++) {
bit = BIT(irqd->pmic_ints[i].top_offset);
if (top_irq_status & bit) {
mt6358_irq_sp_handler(chip, i);
top_irq_status &= ~bit;
@ -180,17 +210,22 @@ int mt6358_irq_init(struct mt6397_chip *chip)
int i, j, ret;
struct pmic_irq_data *irqd;
irqd = devm_kzalloc(chip->dev, sizeof(*irqd), GFP_KERNEL);
if (!irqd)
return -ENOMEM;
switch (chip->chip_id) {
case MT6358_CHIP_ID:
chip->irq_data = &mt6358_irqd;
break;
chip->irq_data = irqd;
case MT6359_CHIP_ID:
chip->irq_data = &mt6359_irqd;
break;
default:
dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
return -ENODEV;
}
mutex_init(&chip->irqlock);
irqd->top_int_status_reg = MT6358_TOP_INT_STATUS0;
irqd->num_pmic_irqs = MT6358_IRQ_NR;
irqd->num_top = ARRAY_SIZE(mt6358_ints);
irqd = chip->irq_data;
irqd->enable_hwirq = devm_kcalloc(chip->dev,
irqd->num_pmic_irqs,
sizeof(*irqd->enable_hwirq),
@ -207,10 +242,10 @@ int mt6358_irq_init(struct mt6397_chip *chip)
/* Disable all interrupts for initializing */
for (i = 0; i < irqd->num_top; i++) {
for (j = 0; j < mt6358_ints[i].num_int_regs; j++)
for (j = 0; j < irqd->pmic_ints[i].num_int_regs; j++)
regmap_write(chip->regmap,
mt6358_ints[i].en_reg +
mt6358_ints[i].en_reg_shift * j, 0);
irqd->pmic_ints[i].en_reg +
irqd->pmic_ints[i].en_reg_shift * j, 0);
}
chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,

View File

@ -13,9 +13,11 @@
#include <linux/mfd/core.h>
#include <linux/mfd/mt6323/core.h>
#include <linux/mfd/mt6358/core.h>
#include <linux/mfd/mt6359/core.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/registers.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6359/registers.h>
#include <linux/mfd/mt6397/registers.h>
#define MT6323_RTC_BASE 0x8000
@ -99,6 +101,17 @@ static const struct mfd_cell mt6358_devs[] = {
},
};
static const struct mfd_cell mt6359_devs[] = {
{ .name = "mt6359-regulator", },
{
.name = "mt6359-rtc",
.num_resources = ARRAY_SIZE(mt6358_rtc_resources),
.resources = mt6358_rtc_resources,
.of_compatible = "mediatek,mt6358-rtc",
},
{ .name = "mt6359-sound", },
};
static const struct mfd_cell mt6397_devs[] = {
{
.name = "mt6397-rtc",
@ -149,6 +162,14 @@ static const struct chip_data mt6358_core = {
.irq_init = mt6358_irq_init,
};
static const struct chip_data mt6359_core = {
.cid_addr = MT6359_SWCID,
.cid_shift = 8,
.cells = mt6359_devs,
.cell_size = ARRAY_SIZE(mt6359_devs),
.irq_init = mt6358_irq_init,
};
static const struct chip_data mt6397_core = {
.cid_addr = MT6397_CID,
.cid_shift = 0,
@ -218,6 +239,9 @@ static const struct of_device_id mt6397_of_match[] = {
}, {
.compatible = "mediatek,mt6358",
.data = &mt6358_core,
}, {
.compatible = "mediatek,mt6359",
.data = &mt6359_core,
}, {
.compatible = "mediatek,mt6397",
.data = &mt6397_core,

View File

@ -193,20 +193,10 @@ config REGULATOR_BCM590XX
BCM590xx PMUs. This will enable support for the software
controllable LDO/Switching regulators.
config REGULATOR_BD70528
tristate "ROHM BD70528 Power Regulator"
depends on MFD_ROHM_BD70528
help
This driver supports voltage regulators on ROHM BD70528 PMIC.
This will enable support for the software controllable buck
and LDO regulators.
This driver can also be built as a module. If so, the module
will be called bd70528-regulator.
config REGULATOR_BD71815
tristate "ROHM BD71815 Power Regulator"
depends on MFD_ROHM_BD71828
select REGULATOR_ROHM
help
This driver supports voltage regulators on ROHM BD71815 PMIC.
This will enable support for the software controllable buck
@ -588,6 +578,14 @@ config REGULATOR_MAX8660
This driver controls a Maxim 8660/8661 voltage output
regulator via I2C bus.
config REGULATOR_MAX8893
tristate "Maxim 8893 voltage regulator"
depends on I2C
select REGMAP_I2C
help
This driver controls a Maxim 8893 voltage output
regulator via I2C bus.
config REGULATOR_MAX8907
tristate "Maxim 8907 voltage regulator"
depends on MFD_MAX8907 || COMPILE_TEST
@ -779,6 +777,15 @@ config REGULATOR_MT6358
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6359
tristate "MediaTek MT6359 PMIC"
depends on MFD_MT6397
help
Say y here to select this option to enable the power regulator of
MediaTek MT6359 PMIC.
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6360
tristate "MT6360 SubPMIC Regulator"
depends on MFD_MT6360
@ -1030,6 +1037,26 @@ config REGULATOR_RT5033
RT5033 PMIC. The device supports multiple regulators like
current source, LDO and Buck.
config REGULATOR_RT6160
tristate "Richtek RT6160 BuckBoost voltage regulator"
depends on I2C
select REGMAP_I2C
help
This adds support for voltage regulator in Richtek RT6160.
This device automatically change voltage output mode from
Buck or Boost. The mode transistion depend on the input source voltage.
The wide output range is from 2025mV to 5200mV and can be used on most
common application scenario.
config REGULATOR_RT6245
tristate "Richtek RT6245 voltage regulator"
depends on I2C
select REGMAP_I2C
help
This adds supprot for Richtek RT6245 voltage regulator.
It can support up to 14A output current and adjustable output voltage
from 0.4375V to 1.3875V, per step 12.5mV.
config REGULATOR_RTMV20
tristate "Richtek RTMV20 Laser Diode Regulator"
depends on I2C
@ -1150,6 +1177,12 @@ config REGULATOR_STW481X_VMMC
This driver supports the internal VMMC regulator in the STw481x
PMIC chips.
config REGULATOR_SY7636A
tristate "Silergy SY7636A voltage regulator"
depends on MFD_SY7636A
help
This driver supports Silergy SY3686A voltage regulator.
config REGULATOR_SY8106A
tristate "Silergy SY8106A regulator"
depends on I2C && (OF || COMPILE_TEST)

View File

@ -4,7 +4,7 @@
#
obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o devres.o
obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o devres.o irq_helpers.o
obj-$(CONFIG_OF) += of_regulator.o
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
@ -29,7 +29,6 @@ obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
obj-$(CONFIG_REGULATOR_ATC260X) += atc260x-regulator.o
obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o
obj-$(CONFIG_REGULATOR_BD71815) += bd71815-regulator.o
obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o
obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
@ -72,6 +71,7 @@ obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
obj-$(CONFIG_REGULATOR_MAX8893) += max8893.o
obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o
obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o
@ -94,6 +94,7 @@ obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
obj-$(CONFIG_REGULATOR_MT6315) += mt6315-regulator.o
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
obj-$(CONFIG_REGULATOR_MT6359) += mt6359-regulator.o
obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
@ -124,6 +125,8 @@ obj-$(CONFIG_REGULATOR_ROHM) += rohm-regulator.o
obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o
obj-$(CONFIG_REGULATOR_RT4831) += rt4831-regulator.o
obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o
obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o
obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
@ -136,6 +139,7 @@ obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
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_SY7636A) += sy7636a-regulator.o
obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
obj-$(CONFIG_REGULATOR_SY8824X) += sy8824x.o
obj-$(CONFIG_REGULATOR_SY8827N) += sy8827n.o

View File

@ -1,283 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2018 ROHM Semiconductors
// bd70528-regulator.c ROHM BD70528MWV regulator driver
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/rohm-bd70528.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
#define BUCK_RAMPRATE_250MV 0
#define BUCK_RAMPRATE_125MV 1
#define BUCK_RAMP_MAX 250
static const struct linear_range bd70528_buck1_volts[] = {
REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000),
REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000),
};
static const struct linear_range bd70528_buck2_volts[] = {
REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 300000),
REGULATOR_LINEAR_RANGE(1550000, 0x2, 0xd, 50000),
REGULATOR_LINEAR_RANGE(3000000, 0xe, 0xf, 300000),
};
static const struct linear_range bd70528_buck3_volts[] = {
REGULATOR_LINEAR_RANGE(800000, 0x00, 0xd, 50000),
REGULATOR_LINEAR_RANGE(1800000, 0xe, 0xf, 0),
};
/* All LDOs have same voltage ranges */
static const struct linear_range bd70528_ldo_volts[] = {
REGULATOR_LINEAR_RANGE(1650000, 0x0, 0x07, 50000),
REGULATOR_LINEAR_RANGE(2100000, 0x8, 0x0f, 100000),
REGULATOR_LINEAR_RANGE(2850000, 0x10, 0x19, 50000),
REGULATOR_LINEAR_RANGE(3300000, 0x19, 0x1f, 0),
};
/* Also both LEDs support same voltages */
static const unsigned int led_volts[] = {
20000, 30000
};
static int bd70528_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
if (ramp_delay > 0 && ramp_delay <= BUCK_RAMP_MAX) {
unsigned int ramp_value = BUCK_RAMPRATE_250MV;
if (ramp_delay <= 125)
ramp_value = BUCK_RAMPRATE_125MV;
return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
BD70528_MASK_BUCK_RAMP,
ramp_value << BD70528_SIFT_BUCK_RAMP);
}
dev_err(&rdev->dev, "%s: ramp_delay: %d not supported\n",
rdev->desc->name, ramp_delay);
return -EINVAL;
}
static int bd70528_led_set_voltage_sel(struct regulator_dev *rdev,
unsigned int sel)
{
int ret;
ret = regulator_is_enabled_regmap(rdev);
if (ret < 0)
return ret;
if (ret == 0)
return regulator_set_voltage_sel_regmap(rdev, sel);
dev_err(&rdev->dev,
"LED voltage change not allowed when led is enabled\n");
return -EBUSY;
}
static const struct regulator_ops bd70528_buck_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = bd70528_set_ramp_delay,
};
static const struct regulator_ops bd70528_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
};
static const struct regulator_ops bd70528_led_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_table,
.set_voltage_sel = bd70528_led_set_voltage_sel,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
static const struct regulator_desc bd70528_desc[] = {
{
.name = "buck1",
.of_match = of_match_ptr("BUCK1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_BUCK1,
.ops = &bd70528_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_buck1_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_buck1_volts),
.n_voltages = BD70528_BUCK_VOLTS,
.enable_reg = BD70528_REG_BUCK1_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_BUCK1_VOLT,
.vsel_mask = BD70528_MASK_BUCK_VOLT,
.owner = THIS_MODULE,
},
{
.name = "buck2",
.of_match = of_match_ptr("BUCK2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_BUCK2,
.ops = &bd70528_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_buck2_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_buck2_volts),
.n_voltages = BD70528_BUCK_VOLTS,
.enable_reg = BD70528_REG_BUCK2_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_BUCK2_VOLT,
.vsel_mask = BD70528_MASK_BUCK_VOLT,
.owner = THIS_MODULE,
},
{
.name = "buck3",
.of_match = of_match_ptr("BUCK3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_BUCK3,
.ops = &bd70528_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_buck3_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_buck3_volts),
.n_voltages = BD70528_BUCK_VOLTS,
.enable_reg = BD70528_REG_BUCK3_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_BUCK3_VOLT,
.vsel_mask = BD70528_MASK_BUCK_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo1",
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LDO1,
.ops = &bd70528_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
.n_voltages = BD70528_LDO_VOLTS,
.enable_reg = BD70528_REG_LDO1_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_LDO1_VOLT,
.vsel_mask = BD70528_MASK_LDO_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo2",
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LDO2,
.ops = &bd70528_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
.n_voltages = BD70528_LDO_VOLTS,
.enable_reg = BD70528_REG_LDO2_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_LDO2_VOLT,
.vsel_mask = BD70528_MASK_LDO_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo3",
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LDO3,
.ops = &bd70528_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
.n_voltages = BD70528_LDO_VOLTS,
.enable_reg = BD70528_REG_LDO3_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_LDO3_VOLT,
.vsel_mask = BD70528_MASK_LDO_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo_led1",
.of_match = of_match_ptr("LDO_LED1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LED1,
.ops = &bd70528_led_ops,
.type = REGULATOR_VOLTAGE,
.volt_table = &led_volts[0],
.n_voltages = ARRAY_SIZE(led_volts),
.enable_reg = BD70528_REG_LED_EN,
.enable_mask = BD70528_MASK_LED1_EN,
.vsel_reg = BD70528_REG_LED_VOLT,
.vsel_mask = BD70528_MASK_LED1_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo_led2",
.of_match = of_match_ptr("LDO_LED2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LED2,
.ops = &bd70528_led_ops,
.type = REGULATOR_VOLTAGE,
.volt_table = &led_volts[0],
.n_voltages = ARRAY_SIZE(led_volts),
.enable_reg = BD70528_REG_LED_EN,
.enable_mask = BD70528_MASK_LED2_EN,
.vsel_reg = BD70528_REG_LED_VOLT,
.vsel_mask = BD70528_MASK_LED2_VOLT,
.owner = THIS_MODULE,
},
};
static int bd70528_probe(struct platform_device *pdev)
{
int i;
struct regulator_config config = {
.dev = pdev->dev.parent,
};
config.regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!config.regmap)
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(bd70528_desc); i++) {
struct regulator_dev *rdev;
rdev = devm_regulator_register(&pdev->dev, &bd70528_desc[i],
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
bd70528_desc[i].name);
return PTR_ERR(rdev);
}
}
return 0;
}
static struct platform_driver bd70528_regulator = {
.driver = {
.name = "bd70528-pmic"
},
.probe = bd70528_probe,
};
module_platform_driver(bd70528_regulator);
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
MODULE_DESCRIPTION("BD70528 voltage regulator driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:bd70528-pmic");

View File

@ -13,6 +13,8 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/delay.h>
#include <linux/slab.h>
@ -26,14 +28,6 @@ struct bd71815_regulator {
const struct rohm_dvs_config *dvs;
};
struct bd71815_pmic {
struct bd71815_regulator descs[BD71815_REGULATOR_CNT];
struct regmap *regmap;
struct device *dev;
struct gpio_descs *gps;
struct regulator_dev *rdev[BD71815_REGULATOR_CNT];
};
static const int bd7181x_wled_currents[] = {
10, 20, 30, 50, 70, 100, 200, 300, 500, 700, 1000, 2000, 3000, 4000,
5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000,
@ -300,14 +294,13 @@ static int bd7181x_led_set_current_limit(struct regulator_dev *rdev,
static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)
{
struct bd71815_pmic *pmic = rdev_get_drvdata(rdev);
int rid = rdev_get_id(rdev);
int ret, regh, regl, val;
regh = BD71815_REG_BUCK1_VOLT_H + rid * 0x2;
regl = BD71815_REG_BUCK1_VOLT_L + rid * 0x2;
ret = regmap_read(pmic->regmap, regh, &val);
ret = regmap_read(rdev->regmap, regh, &val);
if (ret)
return ret;
@ -319,7 +312,7 @@ static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)
* by BD71815_BUCK_DVSSEL bit
*/
if ((!(val & BD71815_BUCK_STBY_DVS)) && (!(val & BD71815_BUCK_DVSSEL)))
ret = regmap_read(pmic->regmap, regl, &val);
ret = regmap_read(rdev->regmap, regl, &val);
if (ret)
return ret;
@ -333,14 +326,13 @@ static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)
static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,
unsigned int sel)
{
struct bd71815_pmic *pmic = rdev_get_drvdata(rdev);
int rid = rdev_get_id(rdev);
int ret, val, reg, regh, regl;
regh = BD71815_REG_BUCK1_VOLT_H + rid*0x2;
regl = BD71815_REG_BUCK1_VOLT_L + rid*0x2;
ret = regmap_read(pmic->regmap, regh, &val);
ret = regmap_read(rdev->regmap, regh, &val);
if (ret)
return ret;
@ -350,7 +342,7 @@ static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,
* voltages at runtime is not supported by this driver.
*/
if (((val & BD71815_BUCK_STBY_DVS))) {
return regmap_update_bits(pmic->regmap, regh, BD71815_VOLT_MASK,
return regmap_update_bits(rdev->regmap, regh, BD71815_VOLT_MASK,
sel);
}
/* Update new voltage to the register which is not selected now */
@ -359,12 +351,13 @@ static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,
else
reg = regh;
ret = regmap_update_bits(pmic->regmap, reg, BD71815_VOLT_MASK, sel);
ret = regmap_update_bits(rdev->regmap, reg, BD71815_VOLT_MASK, sel);
if (ret)
return ret;
/* Select the other DVS register to be used */
return regmap_update_bits(pmic->regmap, regh, BD71815_BUCK_DVSSEL, ~val);
return regmap_update_bits(rdev->regmap, regh, BD71815_BUCK_DVSSEL,
~val);
}
static const struct regulator_ops bd7181x_ldo_regulator_ops = {
@ -522,7 +515,7 @@ static const struct regulator_ops bd7181x_led_regulator_ops = {
.dvs = (_dvs), \
}
static struct bd71815_regulator bd71815_regulators[] = {
static const struct bd71815_regulator bd71815_regulators[] = {
BD71815_BUCK12_REG(buck1, BD71815_BUCK1, BD71815_REG_BUCK1_VOLT_H,
BD71815_REG_BUCK1_MODE, 800000, 2000000, 25000,
&buck1_dvs),
@ -568,24 +561,16 @@ static struct bd71815_regulator bd71815_regulators[] = {
static int bd7181x_probe(struct platform_device *pdev)
{
struct bd71815_pmic *pmic;
struct regulator_config config = {};
int i, ret;
struct gpio_desc *ldo4_en;
struct regmap *regmap;
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
memcpy(pmic->descs, bd71815_regulators, sizeof(pmic->descs));
pmic->dev = &pdev->dev;
pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!pmic->regmap) {
dev_err(pmic->dev, "No parent regmap\n");
regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!regmap) {
dev_err(&pdev->dev, "No parent regmap\n");
return -ENODEV;
}
platform_set_drvdata(pdev, pmic);
ldo4_en = devm_gpiod_get_from_of_node(&pdev->dev,
pdev->dev.parent->of_node,
"rohm,vsel-gpios", 0,
@ -599,23 +584,23 @@ static int bd7181x_probe(struct platform_device *pdev)
}
/* Disable to go to ship-mode */
ret = regmap_update_bits(pmic->regmap, BD71815_REG_PWRCTRL,
RESTARTEN, 0);
ret = regmap_update_bits(regmap, BD71815_REG_PWRCTRL, RESTARTEN, 0);
if (ret)
return ret;
config.dev = pdev->dev.parent;
config.regmap = pmic->regmap;
config.regmap = regmap;
for (i = 0; i < BD71815_REGULATOR_CNT; i++) {
struct regulator_desc *desc;
const struct regulator_desc *desc;
struct regulator_dev *rdev;
desc = &pmic->descs[i].desc;
desc = &bd71815_regulators[i].desc;
if (i == BD71815_LDO4)
config.ena_gpiod = ldo4_en;
config.driver_data = pmic;
else
config.ena_gpiod = NULL;
rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev)) {
@ -624,8 +609,6 @@ static int bd7181x_probe(struct platform_device *pdev)
desc->name);
return PTR_ERR(rdev);
}
config.ena_gpiod = NULL;
pmic->rdev[i] = rdev;
}
return 0;
}
@ -639,7 +622,6 @@ MODULE_DEVICE_TABLE(platform, bd7181x_pmic_id);
static struct platform_driver bd7181x_regulator = {
.driver = {
.name = "bd7181x-pmic",
.owner = THIS_MODULE,
},
.probe = bd7181x_probe,
.id_table = bd7181x_pmic_id,

File diff suppressed because it is too large Load Diff

View File

@ -33,17 +33,6 @@
#include "dummy.h"
#include "internal.h"
#define rdev_crit(rdev, fmt, ...) \
pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_err(rdev, fmt, ...) \
pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_warn(rdev, fmt, ...) \
pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_info(rdev, fmt, ...) \
pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_dbg(rdev, fmt, ...) \
pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
static DEFINE_WW_CLASS(regulator_ww_class);
static DEFINE_MUTEX(regulator_nesting_mutex);
static DEFINE_MUTEX(regulator_list_mutex);
@ -117,6 +106,7 @@ const char *rdev_get_name(struct regulator_dev *rdev)
else
return "";
}
EXPORT_SYMBOL_GPL(rdev_get_name);
static bool have_full_constraints(void)
{
@ -591,7 +581,7 @@ regulator_get_suspend_state_check(struct regulator_dev *rdev, suspend_state_t st
return rstate;
}
static ssize_t regulator_uV_show(struct device *dev,
static ssize_t microvolts_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -605,16 +595,16 @@ static ssize_t regulator_uV_show(struct device *dev,
return uV;
return sprintf(buf, "%d\n", uV);
}
static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
static DEVICE_ATTR_RO(microvolts);
static ssize_t regulator_uA_show(struct device *dev,
static ssize_t microamps_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", _regulator_get_current_limit(rdev));
}
static DEVICE_ATTR(microamps, 0444, regulator_uA_show, NULL);
static DEVICE_ATTR_RO(microamps);
static ssize_t name_show(struct device *dev, struct device_attribute *attr,
char *buf)
@ -645,14 +635,14 @@ static ssize_t regulator_print_opmode(char *buf, int mode)
return sprintf(buf, "%s\n", regulator_opmode_to_str(mode));
}
static ssize_t regulator_opmode_show(struct device *dev,
static ssize_t opmode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
return regulator_print_opmode(buf, _regulator_get_mode(rdev));
}
static DEVICE_ATTR(opmode, 0444, regulator_opmode_show, NULL);
static DEVICE_ATTR_RO(opmode);
static ssize_t regulator_print_state(char *buf, int state)
{
@ -664,7 +654,7 @@ static ssize_t regulator_print_state(char *buf, int state)
return sprintf(buf, "unknown\n");
}
static ssize_t regulator_state_show(struct device *dev,
static ssize_t state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -676,9 +666,9 @@ static ssize_t regulator_state_show(struct device *dev,
return ret;
}
static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
static DEVICE_ATTR_RO(state);
static ssize_t regulator_status_show(struct device *dev,
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -723,9 +713,9 @@ static ssize_t regulator_status_show(struct device *dev,
return sprintf(buf, "%s\n", label);
}
static DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
static DEVICE_ATTR_RO(status);
static ssize_t regulator_min_uA_show(struct device *dev,
static ssize_t min_microamps_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -735,9 +725,9 @@ static ssize_t regulator_min_uA_show(struct device *dev,
return sprintf(buf, "%d\n", rdev->constraints->min_uA);
}
static DEVICE_ATTR(min_microamps, 0444, regulator_min_uA_show, NULL);
static DEVICE_ATTR_RO(min_microamps);
static ssize_t regulator_max_uA_show(struct device *dev,
static ssize_t max_microamps_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -747,9 +737,9 @@ static ssize_t regulator_max_uA_show(struct device *dev,
return sprintf(buf, "%d\n", rdev->constraints->max_uA);
}
static DEVICE_ATTR(max_microamps, 0444, regulator_max_uA_show, NULL);
static DEVICE_ATTR_RO(max_microamps);
static ssize_t regulator_min_uV_show(struct device *dev,
static ssize_t min_microvolts_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -759,9 +749,9 @@ static ssize_t regulator_min_uV_show(struct device *dev,
return sprintf(buf, "%d\n", rdev->constraints->min_uV);
}
static DEVICE_ATTR(min_microvolts, 0444, regulator_min_uV_show, NULL);
static DEVICE_ATTR_RO(min_microvolts);
static ssize_t regulator_max_uV_show(struct device *dev,
static ssize_t max_microvolts_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -771,9 +761,9 @@ static ssize_t regulator_max_uV_show(struct device *dev,
return sprintf(buf, "%d\n", rdev->constraints->max_uV);
}
static DEVICE_ATTR(max_microvolts, 0444, regulator_max_uV_show, NULL);
static DEVICE_ATTR_RO(max_microvolts);
static ssize_t regulator_total_uA_show(struct device *dev,
static ssize_t requested_microamps_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -788,7 +778,7 @@ static ssize_t regulator_total_uA_show(struct device *dev,
regulator_unlock(rdev);
return sprintf(buf, "%d\n", uA);
}
static DEVICE_ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL);
static DEVICE_ATTR_RO(requested_microamps);
static ssize_t num_users_show(struct device *dev, struct device_attribute *attr,
char *buf)
@ -813,37 +803,34 @@ static ssize_t type_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(type);
static ssize_t regulator_suspend_mem_uV_show(struct device *dev,
static ssize_t suspend_mem_microvolts_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", rdev->constraints->state_mem.uV);
}
static DEVICE_ATTR(suspend_mem_microvolts, 0444,
regulator_suspend_mem_uV_show, NULL);
static DEVICE_ATTR_RO(suspend_mem_microvolts);
static ssize_t regulator_suspend_disk_uV_show(struct device *dev,
static ssize_t suspend_disk_microvolts_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", rdev->constraints->state_disk.uV);
}
static DEVICE_ATTR(suspend_disk_microvolts, 0444,
regulator_suspend_disk_uV_show, NULL);
static DEVICE_ATTR_RO(suspend_disk_microvolts);
static ssize_t regulator_suspend_standby_uV_show(struct device *dev,
static ssize_t suspend_standby_microvolts_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", rdev->constraints->state_standby.uV);
}
static DEVICE_ATTR(suspend_standby_microvolts, 0444,
regulator_suspend_standby_uV_show, NULL);
static DEVICE_ATTR_RO(suspend_standby_microvolts);
static ssize_t regulator_suspend_mem_mode_show(struct device *dev,
static ssize_t suspend_mem_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -851,10 +838,9 @@ static ssize_t regulator_suspend_mem_mode_show(struct device *dev,
return regulator_print_opmode(buf,
rdev->constraints->state_mem.mode);
}
static DEVICE_ATTR(suspend_mem_mode, 0444,
regulator_suspend_mem_mode_show, NULL);
static DEVICE_ATTR_RO(suspend_mem_mode);
static ssize_t regulator_suspend_disk_mode_show(struct device *dev,
static ssize_t suspend_disk_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -862,10 +848,9 @@ static ssize_t regulator_suspend_disk_mode_show(struct device *dev,
return regulator_print_opmode(buf,
rdev->constraints->state_disk.mode);
}
static DEVICE_ATTR(suspend_disk_mode, 0444,
regulator_suspend_disk_mode_show, NULL);
static DEVICE_ATTR_RO(suspend_disk_mode);
static ssize_t regulator_suspend_standby_mode_show(struct device *dev,
static ssize_t suspend_standby_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -873,10 +858,9 @@ static ssize_t regulator_suspend_standby_mode_show(struct device *dev,
return regulator_print_opmode(buf,
rdev->constraints->state_standby.mode);
}
static DEVICE_ATTR(suspend_standby_mode, 0444,
regulator_suspend_standby_mode_show, NULL);
static DEVICE_ATTR_RO(suspend_standby_mode);
static ssize_t regulator_suspend_mem_state_show(struct device *dev,
static ssize_t suspend_mem_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -884,10 +868,9 @@ static ssize_t regulator_suspend_mem_state_show(struct device *dev,
return regulator_print_state(buf,
rdev->constraints->state_mem.enabled);
}
static DEVICE_ATTR(suspend_mem_state, 0444,
regulator_suspend_mem_state_show, NULL);
static DEVICE_ATTR_RO(suspend_mem_state);
static ssize_t regulator_suspend_disk_state_show(struct device *dev,
static ssize_t suspend_disk_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -895,10 +878,9 @@ static ssize_t regulator_suspend_disk_state_show(struct device *dev,
return regulator_print_state(buf,
rdev->constraints->state_disk.enabled);
}
static DEVICE_ATTR(suspend_disk_state, 0444,
regulator_suspend_disk_state_show, NULL);
static DEVICE_ATTR_RO(suspend_disk_state);
static ssize_t regulator_suspend_standby_state_show(struct device *dev,
static ssize_t suspend_standby_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -906,10 +888,9 @@ static ssize_t regulator_suspend_standby_state_show(struct device *dev,
return regulator_print_state(buf,
rdev->constraints->state_standby.enabled);
}
static DEVICE_ATTR(suspend_standby_state, 0444,
regulator_suspend_standby_state_show, NULL);
static DEVICE_ATTR_RO(suspend_standby_state);
static ssize_t regulator_bypass_show(struct device *dev,
static ssize_t bypass_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
@ -928,8 +909,7 @@ static ssize_t regulator_bypass_show(struct device *dev,
return sprintf(buf, "%s\n", report);
}
static DEVICE_ATTR(bypass, 0444,
regulator_bypass_show, NULL);
static DEVICE_ATTR_RO(bypass);
/* Calculate the new optimum regulator operating mode based on the new total
* consumer load. All locks held by caller
@ -1315,6 +1295,52 @@ static int machine_constraints_current(struct regulator_dev *rdev,
static int _regulator_do_enable(struct regulator_dev *rdev);
static int notif_set_limit(struct regulator_dev *rdev,
int (*set)(struct regulator_dev *, int, int, bool),
int limit, int severity)
{
bool enable;
if (limit == REGULATOR_NOTIF_LIMIT_DISABLE) {
enable = false;
limit = 0;
} else {
enable = true;
}
if (limit == REGULATOR_NOTIF_LIMIT_ENABLE)
limit = 0;
return set(rdev, limit, severity, enable);
}
static int handle_notify_limits(struct regulator_dev *rdev,
int (*set)(struct regulator_dev *, int, int, bool),
struct notification_limit *limits)
{
int ret = 0;
if (!set)
return -EOPNOTSUPP;
if (limits->prot)
ret = notif_set_limit(rdev, set, limits->prot,
REGULATOR_SEVERITY_PROT);
if (ret)
return ret;
if (limits->err)
ret = notif_set_limit(rdev, set, limits->err,
REGULATOR_SEVERITY_ERR);
if (ret)
return ret;
if (limits->warn)
ret = notif_set_limit(rdev, set, limits->warn,
REGULATOR_SEVERITY_WARN);
return ret;
}
/**
* set_machine_constraints - sets regulator constraints
* @rdev: regulator source
@ -1400,9 +1426,27 @@ static int set_machine_constraints(struct regulator_dev *rdev)
}
}
/*
* Existing logic does not warn if over_current_protection is given as
* a constraint but driver does not support that. I think we should
* warn about this type of issues as it is possible someone changes
* PMIC on board to another type - and the another PMIC's driver does
* not support setting protection. Board composer may happily believe
* the DT limits are respected - especially if the new PMIC HW also
* supports protection but the driver does not. I won't change the logic
* without hearing more experienced opinion on this though.
*
* If warning is seen as a good idea then we can merge handling the
* over-curret protection and detection and get rid of this special
* handling.
*/
if (rdev->constraints->over_current_protection
&& ops->set_over_current_protection) {
ret = ops->set_over_current_protection(rdev);
int lim = rdev->constraints->over_curr_limits.prot;
ret = ops->set_over_current_protection(rdev, lim,
REGULATOR_SEVERITY_PROT,
true);
if (ret < 0) {
rdev_err(rdev, "failed to set over current protection: %pe\n",
ERR_PTR(ret));
@ -1410,6 +1454,62 @@ static int set_machine_constraints(struct regulator_dev *rdev)
}
}
if (rdev->constraints->over_current_detection)
ret = handle_notify_limits(rdev,
ops->set_over_current_protection,
&rdev->constraints->over_curr_limits);
if (ret) {
if (ret != -EOPNOTSUPP) {
rdev_err(rdev, "failed to set over current limits: %pe\n",
ERR_PTR(ret));
return ret;
}
rdev_warn(rdev,
"IC does not support requested over-current limits\n");
}
if (rdev->constraints->over_voltage_detection)
ret = handle_notify_limits(rdev,
ops->set_over_voltage_protection,
&rdev->constraints->over_voltage_limits);
if (ret) {
if (ret != -EOPNOTSUPP) {
rdev_err(rdev, "failed to set over voltage limits %pe\n",
ERR_PTR(ret));
return ret;
}
rdev_warn(rdev,
"IC does not support requested over voltage limits\n");
}
if (rdev->constraints->under_voltage_detection)
ret = handle_notify_limits(rdev,
ops->set_under_voltage_protection,
&rdev->constraints->under_voltage_limits);
if (ret) {
if (ret != -EOPNOTSUPP) {
rdev_err(rdev, "failed to set under voltage limits %pe\n",
ERR_PTR(ret));
return ret;
}
rdev_warn(rdev,
"IC does not support requested under voltage limits\n");
}
if (rdev->constraints->over_temp_detection)
ret = handle_notify_limits(rdev,
ops->set_thermal_protection,
&rdev->constraints->temp_limits);
if (ret) {
if (ret != -EOPNOTSUPP) {
rdev_err(rdev, "failed to set temperature limits %pe\n",
ERR_PTR(ret));
return ret;
}
rdev_warn(rdev,
"IC does not support requested temperature limits\n");
}
if (rdev->constraints->active_discharge && ops->set_active_discharge) {
bool ad_state = (rdev->constraints->active_discharge ==
REGULATOR_ACTIVE_DISCHARGE_ENABLE) ? true : false;
@ -4111,6 +4211,29 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
}
EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);
int regulator_sync_voltage_rdev(struct regulator_dev *rdev)
{
int ret;
regulator_lock(rdev);
if (!rdev->desc->ops->set_voltage &&
!rdev->desc->ops->set_voltage_sel) {
ret = -EINVAL;
goto out;
}
/* balance only, if regulator is coupled */
if (rdev->coupling_desc.n_coupled > 1)
ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON);
else
ret = -EOPNOTSUPP;
out:
regulator_unlock(rdev);
return ret;
}
/**
* regulator_sync_voltage - re-apply last regulator output voltage
* @regulator: regulator source
@ -4386,22 +4509,36 @@ unsigned int regulator_get_mode(struct regulator *regulator)
}
EXPORT_SYMBOL_GPL(regulator_get_mode);
static int rdev_get_cached_err_flags(struct regulator_dev *rdev)
{
int ret = 0;
if (rdev->use_cached_err) {
spin_lock(&rdev->err_lock);
ret = rdev->cached_err;
spin_unlock(&rdev->err_lock);
}
return ret;
}
static int _regulator_get_error_flags(struct regulator_dev *rdev,
unsigned int *flags)
{
int ret;
int cached_flags, ret = 0;
regulator_lock(rdev);
/* sanity check */
if (!rdev->desc->ops->get_error_flags) {
ret = -EINVAL;
goto out;
}
cached_flags = rdev_get_cached_err_flags(rdev);
if (rdev->desc->ops->get_error_flags)
ret = rdev->desc->ops->get_error_flags(rdev, flags);
out:
else if (!rdev->use_cached_err)
ret = -EINVAL;
*flags |= cached_flags;
regulator_unlock(rdev);
return ret;
}
@ -5234,6 +5371,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
goto rinse;
}
device_initialize(&rdev->dev);
spin_lock_init(&rdev->err_lock);
/*
* Duplicate the config so the driver could override it after

View File

@ -250,7 +250,8 @@ static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
case DA9052_ID_BUCK3:
case DA9052_ID_LDO2:
case DA9052_ID_LDO3:
ret = (new_sel - old_sel) * info->step_uV / 6250;
ret = DIV_ROUND_UP(abs(new_sel - old_sel) * info->step_uV,
6250);
break;
}

View File

@ -481,3 +481,55 @@ void devm_regulator_unregister_notifier(struct regulator *regulator,
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier);
static void regulator_irq_helper_drop(void *res)
{
regulator_irq_helper_cancel(&res);
}
/**
* devm_regulator_irq_helper - resource managed registration of IRQ based
* regulator event/error notifier
*
* @dev: device to which lifetime the helper's lifetime is
* bound.
* @d: IRQ helper descriptor.
* @irq: IRQ used to inform events/errors to be notified.
* @irq_flags: Extra IRQ flags to be OR'ed with the default
* IRQF_ONESHOT when requesting the (threaded) irq.
* @common_errs: Errors which can be flagged by this IRQ for all rdevs.
* When IRQ is re-enabled these errors will be cleared
* from all associated regulators
* @per_rdev_errs: Optional error flag array describing errors specific
* for only some of the regulators. These errors will be
* or'ed with common errors. If this is given the array
* should contain rdev_amount flags. Can be set to NULL
* if there is no regulator specific error flags for this
* IRQ.
* @rdev: Array of pointers to regulators associated with this
* IRQ.
* @rdev_amount: Amount of regulators associated with this IRQ.
*
* Return: handle to irq_helper or an ERR_PTR() encoded error code.
*/
void *devm_regulator_irq_helper(struct device *dev,
const struct regulator_irq_desc *d, int irq,
int irq_flags, int common_errs,
int *per_rdev_errs,
struct regulator_dev **rdev, int rdev_amount)
{
void *ptr;
int ret;
ptr = regulator_irq_helper(dev, d, irq, irq_flags, common_errs,
per_rdev_errs, rdev, rdev_amount);
if (IS_ERR(ptr))
return ptr;
ret = devm_add_action_or_reset(dev, regulator_irq_helper_drop, ptr);
if (ret)
return ERR_PTR(ret);
return ptr;
}
EXPORT_SYMBOL_GPL(devm_regulator_irq_helper);

View File

@ -56,7 +56,6 @@
#define FAN53555_NVOLTAGES 64 /* Numbers of voltages */
#define FAN53526_NVOLTAGES 128
#define TCS_VSEL_NSEL_MASK 0x7f
#define TCS_VSEL0_MODE (1 << 7)
#define TCS_VSEL1_MODE (1 << 6)
@ -67,7 +66,7 @@ enum fan53555_vendor {
FAN53526_VENDOR_FAIRCHILD = 0,
FAN53555_VENDOR_FAIRCHILD,
FAN53555_VENDOR_SILERGY,
FAN53555_VENDOR_TCS,
FAN53526_VENDOR_TCS,
};
enum {
@ -89,6 +88,14 @@ enum {
FAN53555_CHIP_ID_08 = 8,
};
enum {
TCS4525_CHIP_ID_12 = 12,
};
enum {
TCS4526_CHIP_ID_00 = 0,
};
/* IC mask revision */
enum {
FAN53555_CHIP_REV_00 = 0x3,
@ -123,7 +130,8 @@ struct fan53555_device_info {
/* Slew rate */
unsigned int slew_reg;
unsigned int slew_mask;
unsigned int slew_shift;
const unsigned int *ramp_delay_table;
unsigned int n_ramp_values;
unsigned int slew_rate;
};
@ -197,7 +205,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL;
}
static const int slew_rates[] = {
static const unsigned int slew_rates[] = {
64000,
32000,
16000,
@ -208,51 +216,13 @@ static const int slew_rates[] = {
500,
};
static const int tcs_slew_rates[] = {
static const unsigned int tcs_slew_rates[] = {
18700,
9300,
4600,
2300,
};
static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
{
struct fan53555_device_info *di = rdev_get_drvdata(rdev);
int regval = -1, i;
const int *slew_rate_t;
int slew_rate_n;
switch (di->vendor) {
case FAN53526_VENDOR_FAIRCHILD:
case FAN53555_VENDOR_FAIRCHILD:
case FAN53555_VENDOR_SILERGY:
slew_rate_t = slew_rates;
slew_rate_n = ARRAY_SIZE(slew_rates);
break;
case FAN53555_VENDOR_TCS:
slew_rate_t = tcs_slew_rates;
slew_rate_n = ARRAY_SIZE(tcs_slew_rates);
break;
default:
return -EINVAL;
}
for (i = 0; i < slew_rate_n; i++) {
if (ramp <= slew_rate_t[i])
regval = i;
else
break;
}
if (regval < 0) {
dev_err(di->dev, "unsupported ramp value %d\n", ramp);
return -EINVAL;
}
return regmap_update_bits(rdev->regmap, di->slew_reg,
di->slew_mask, regval << di->slew_shift);
}
static const struct regulator_ops fan53555_regulator_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@ -265,7 +235,7 @@ static const struct regulator_ops fan53555_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
.set_mode = fan53555_set_mode,
.get_mode = fan53555_get_mode,
.set_ramp_delay = fan53555_set_ramp,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_enable = fan53555_set_suspend_enable,
.set_suspend_disable = fan53555_set_suspend_disable,
};
@ -293,6 +263,10 @@ static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di)
return -EINVAL;
}
di->slew_reg = FAN53555_CONTROL;
di->slew_mask = CTL_SLEW_MASK;
di->ramp_delay_table = slew_rates;
di->n_ramp_values = ARRAY_SIZE(slew_rates);
di->vsel_count = FAN53526_NVOLTAGES;
return 0;
@ -337,7 +311,8 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
}
di->slew_reg = FAN53555_CONTROL;
di->slew_mask = CTL_SLEW_MASK;
di->slew_shift = CTL_SLEW_SHIFT;
di->ramp_delay_table = slew_rates;
di->n_ramp_values = ARRAY_SIZE(slew_rates);
di->vsel_count = FAN53555_NVOLTAGES;
return 0;
@ -358,24 +333,33 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
return -EINVAL;
}
di->slew_reg = FAN53555_CONTROL;
di->slew_reg = FAN53555_CONTROL;
di->slew_mask = CTL_SLEW_MASK;
di->slew_shift = CTL_SLEW_SHIFT;
di->ramp_delay_table = slew_rates;
di->n_ramp_values = ARRAY_SIZE(slew_rates);
di->vsel_count = FAN53555_NVOLTAGES;
return 0;
}
static int fan53555_voltages_setup_tcs(struct fan53555_device_info *di)
static int fan53526_voltages_setup_tcs(struct fan53555_device_info *di)
{
switch (di->chip_id) {
case TCS4525_CHIP_ID_12:
case TCS4526_CHIP_ID_00:
di->slew_reg = TCS4525_TIME;
di->slew_mask = TCS_SLEW_MASK;
di->slew_shift = TCS_SLEW_MASK;
di->ramp_delay_table = tcs_slew_rates;
di->n_ramp_values = ARRAY_SIZE(tcs_slew_rates);
/* Init voltage range and step */
di->vsel_min = 600000;
di->vsel_step = 6250;
di->vsel_count = FAN53526_NVOLTAGES;
break;
default:
dev_err(di->dev, "Chip ID %d not supported!\n", di->chip_id);
return -EINVAL;
}
return 0;
}
@ -409,7 +393,7 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
return -EINVAL;
}
break;
case FAN53555_VENDOR_TCS:
case FAN53526_VENDOR_TCS:
switch (pdata->sleep_vsel_id) {
case FAN53555_VSEL_ID_0:
di->sleep_reg = TCS4525_VSEL0;
@ -448,7 +432,7 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
di->mode_reg = di->vol_reg;
di->mode_mask = VSEL_MODE;
break;
case FAN53555_VENDOR_TCS:
case FAN53526_VENDOR_TCS:
di->mode_reg = TCS4525_COMMAND;
switch (pdata->sleep_vsel_id) {
@ -476,8 +460,8 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
case FAN53555_VENDOR_SILERGY:
ret = fan53555_voltages_setup_silergy(di);
break;
case FAN53555_VENDOR_TCS:
ret = fan53555_voltages_setup_tcs(di);
case FAN53526_VENDOR_TCS:
ret = fan53526_voltages_setup_tcs(di);
break;
default:
dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
@ -504,6 +488,10 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
rdesc->uV_step = di->vsel_step;
rdesc->vsel_reg = di->vol_reg;
rdesc->vsel_mask = di->vsel_count - 1;
rdesc->ramp_reg = di->slew_reg;
rdesc->ramp_mask = di->slew_mask;
rdesc->ramp_delay_table = di->ramp_delay_table;
rdesc->n_ramp_values = di->n_ramp_values;
rdesc->owner = THIS_MODULE;
rdev = devm_regulator_register(di->dev, &di->desc, config);
@ -552,7 +540,10 @@ static const struct of_device_id __maybe_unused fan53555_dt_ids[] = {
.data = (void *)FAN53555_VENDOR_SILERGY,
}, {
.compatible = "tcs,tcs4525",
.data = (void *)FAN53555_VENDOR_TCS
.data = (void *)FAN53526_VENDOR_TCS
}, {
.compatible = "tcs,tcs4526",
.data = (void *)FAN53526_VENDOR_TCS
},
{ }
};
@ -660,7 +651,10 @@ static const struct i2c_device_id fan53555_id[] = {
.driver_data = FAN53555_VENDOR_SILERGY
}, {
.name = "tcs4525",
.driver_data = FAN53555_VENDOR_TCS
.driver_data = FAN53526_VENDOR_TCS
}, {
.name = "tcs4526",
.driver_data = FAN53526_VENDOR_TCS
},
{ },
};

View File

@ -79,7 +79,7 @@ static const struct regulator_desc fan53880_regulators[] = {
.n_linear_ranges = 2,
.n_voltages = 0xf8,
.vsel_reg = FAN53880_BUCKVOUT,
.vsel_mask = 0x7f,
.vsel_mask = 0xff,
.enable_reg = FAN53880_ENABLE,
.enable_mask = 0x10,
.enable_time = 480,
@ -114,8 +114,7 @@ static const struct regmap_config fan53880_regmap = {
.max_register = FAN53880_ENABLE_BOOST,
};
static int fan53880_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int fan53880_i2c_probe(struct i2c_client *i2c)
{
struct regulator_config config = { };
struct regulator_dev *rdev;
@ -177,7 +176,7 @@ static struct i2c_driver fan53880_regulator_driver = {
.name = "fan53880",
.of_match_table = of_match_ptr(fan53880_dt_ids),
},
.probe = fan53880_i2c_probe,
.probe_new = fan53880_i2c_probe,
.id_table = fan53880_i2c_id,
};
module_i2c_driver(fan53880_regulator_driver);

View File

@ -276,7 +276,8 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
*/
cfg.ena_gpiod = gpiod_get_optional(&pdev->dev, NULL, gflags);
if (IS_ERR(cfg.ena_gpiod))
return PTR_ERR(cfg.ena_gpiod);
return dev_err_probe(&pdev->dev, PTR_ERR(cfg.ena_gpiod),
"can't get GPIO\n");
cfg.dev = &pdev->dev;
cfg.init_data = config->init_data;

View File

@ -386,7 +386,7 @@ static int hi6421_regulator_enable(struct regulator_dev *rdev)
static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev)
{
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
u32 reg_val;
unsigned int reg_val;
regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
if (reg_val & info->mode_mask)
@ -398,7 +398,7 @@ static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev)
static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev)
{
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
u32 reg_val;
unsigned int reg_val;
regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
if (reg_val & info->mode_mask)
@ -411,7 +411,7 @@ static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
u32 new_mode;
unsigned int new_mode;
switch (mode) {
case REGULATOR_MODE_NORMAL:
@ -435,7 +435,7 @@ static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
u32 new_mode;
unsigned int new_mode;
switch (mode) {
case REGULATOR_MODE_NORMAL:

View File

@ -16,16 +16,17 @@
#include <linux/regulator/driver.h>
#include <linux/spmi.h>
struct hi6421_spmi_reg_info {
struct regulator_desc desc;
struct hi6421_spmi_pmic *pmic;
u8 eco_mode_mask;
u32 eco_uA;
struct hi6421_spmi_reg_priv {
/* Serialize regulator enable logic */
struct mutex enable_mutex;
};
struct hi6421_spmi_reg_info {
struct regulator_desc desc;
u8 eco_mode_mask;
u32 eco_uA;
};
static const unsigned int ldo3_voltages[] = {
1500000, 1550000, 1600000, 1650000,
1700000, 1725000, 1750000, 1775000,
@ -97,41 +98,31 @@ static const unsigned int ldo34_voltages[] = {
static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev)
{
struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
struct hi6421_spmi_pmic *pmic = sreg->pmic;
struct hi6421_spmi_reg_priv *priv;
int ret;
priv = dev_get_drvdata(rdev->dev.parent);
/* cannot enable more than one regulator at one time */
mutex_lock(&sreg->enable_mutex);
mutex_lock(&priv->enable_mutex);
ret = regmap_update_bits(pmic->regmap, rdev->desc->enable_reg,
ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask,
rdev->desc->enable_mask);
/* Avoid powering up multiple devices at the same time */
usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 60);
mutex_unlock(&sreg->enable_mutex);
mutex_unlock(&priv->enable_mutex);
return ret;
}
static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev)
{
struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
struct hi6421_spmi_pmic *pmic = sreg->pmic;
return regmap_update_bits(pmic->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, 0);
}
static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
{
struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
struct hi6421_spmi_pmic *pmic = sreg->pmic;
u32 reg_val;
unsigned int reg_val;
regmap_read(pmic->regmap, rdev->desc->enable_reg, &reg_val);
regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
if (reg_val & sreg->eco_mode_mask)
return REGULATOR_MODE_IDLE;
@ -143,21 +134,23 @@ static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
struct hi6421_spmi_pmic *pmic = sreg->pmic;
u32 val;
unsigned int val;
switch (mode) {
case REGULATOR_MODE_NORMAL:
val = 0;
break;
case REGULATOR_MODE_IDLE:
val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1);
if (!sreg->eco_mode_mask)
return -EINVAL;
val = sreg->eco_mode_mask;
break;
default:
return -EINVAL;
}
return regmap_update_bits(pmic->regmap, rdev->desc->enable_reg,
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
sreg->eco_mode_mask, val);
}
@ -177,9 +170,9 @@ hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev,
static const struct regulator_ops hi6421_spmi_ldo_rops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = hi6421_spmi_regulator_enable,
.disable = hi6421_spmi_regulator_disable,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_iterate,
.map_voltage = regulator_map_voltage_ascend,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_mode = hi6421_spmi_regulator_get_mode,
@ -238,7 +231,7 @@ static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
{
struct device *pmic_dev = pdev->dev.parent;
struct regulator_config config = { };
struct hi6421_spmi_reg_info *sreg;
struct hi6421_spmi_reg_priv *priv;
struct hi6421_spmi_reg_info *info;
struct device *dev = &pdev->dev;
struct hi6421_spmi_pmic *pmic;
@ -254,18 +247,18 @@ static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
if (WARN_ON(!pmic))
return -ENODEV;
sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
if (!sreg)
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
sreg->pmic = pmic;
mutex_init(&sreg->enable_mutex);
mutex_init(&priv->enable_mutex);
platform_set_drvdata(pdev, priv);
for (i = 0; i < ARRAY_SIZE(regulator_info); i++) {
info = &regulator_info[i];
config.dev = pdev->dev.parent;
config.driver_data = sreg;
config.driver_data = info;
config.regmap = pmic->regmap;
rdev = devm_regulator_register(dev, &info->desc, &config);

View File

@ -72,7 +72,7 @@ enum hi655x_regulator_id {
static int hi655x_is_enabled(struct regulator_dev *rdev)
{
unsigned int value = 0;
struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
regmap_read(rdev->regmap, regulator->status_reg, &value);
return (value & rdev->desc->enable_mask);
@ -80,7 +80,7 @@ static int hi655x_is_enabled(struct regulator_dev *rdev)
static int hi655x_disable(struct regulator_dev *rdev)
{
struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
return regmap_write(rdev->regmap, regulator->disable_reg,
rdev->desc->enable_mask);
@ -169,7 +169,6 @@ static const struct hi655x_regulator regulators[] = {
static int hi655x_regulator_probe(struct platform_device *pdev)
{
unsigned int i;
struct hi655x_regulator *regulator;
struct hi655x_pmic *pmic;
struct regulator_config config = { };
struct regulator_dev *rdev;
@ -180,22 +179,17 @@ static int hi655x_regulator_probe(struct platform_device *pdev)
return -ENODEV;
}
regulator = devm_kzalloc(&pdev->dev, sizeof(*regulator), GFP_KERNEL);
if (!regulator)
return -ENOMEM;
platform_set_drvdata(pdev, regulator);
config.dev = pdev->dev.parent;
config.regmap = pmic->regmap;
config.driver_data = regulator;
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
config.driver_data = (void *) &regulators[i];
rdev = devm_regulator_register(&pdev->dev,
&regulators[i].rdesc,
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
regulator->rdesc.name);
regulators[i].rdesc.name);
return PTR_ERR(rdev);
}
}

View File

@ -15,6 +15,17 @@
#define REGULATOR_STATES_NUM (PM_SUSPEND_MAX + 1)
#define rdev_crit(rdev, fmt, ...) \
pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_err(rdev, fmt, ...) \
pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_warn(rdev, fmt, ...) \
pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_info(rdev, fmt, ...) \
pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_dbg(rdev, fmt, ...) \
pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
struct regulator_voltage {
int min_uV;
int max_uV;

View File

@ -0,0 +1,397 @@
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (C) 2021 ROHM Semiconductors
// regulator IRQ based event notification helpers
//
// Logic has been partially adapted from qcom-labibb driver.
//
// Author: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/regulator/driver.h>
#include "internal.h"
#define REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS 10000
struct regulator_irq {
struct regulator_irq_data rdata;
struct regulator_irq_desc desc;
int irq;
int retry_cnt;
struct delayed_work isr_work;
};
/*
* Should only be called from threaded handler to prevent potential deadlock
*/
static void rdev_flag_err(struct regulator_dev *rdev, int err)
{
spin_lock(&rdev->err_lock);
rdev->cached_err |= err;
spin_unlock(&rdev->err_lock);
}
static void rdev_clear_err(struct regulator_dev *rdev, int err)
{
spin_lock(&rdev->err_lock);
rdev->cached_err &= ~err;
spin_unlock(&rdev->err_lock);
}
static void regulator_notifier_isr_work(struct work_struct *work)
{
struct regulator_irq *h;
struct regulator_irq_desc *d;
struct regulator_irq_data *rid;
int ret = 0;
int tmo, i;
int num_rdevs;
h = container_of(work, struct regulator_irq,
isr_work.work);
d = &h->desc;
rid = &h->rdata;
num_rdevs = rid->num_states;
reread:
if (d->fatal_cnt && h->retry_cnt > d->fatal_cnt) {
if (!d->die)
return hw_protection_shutdown("Regulator HW failure? - no IC recovery",
REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS);
ret = d->die(rid);
/*
* If the 'last resort' IC recovery failed we will have
* nothing else left to do...
*/
if (ret)
return hw_protection_shutdown("Regulator HW failure. IC recovery failed",
REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS);
/*
* If h->die() was implemented we assume recovery has been
* attempted (probably regulator was shut down) and we
* just enable IRQ and bail-out.
*/
goto enable_out;
}
if (d->renable) {
ret = d->renable(rid);
if (ret == REGULATOR_FAILED_RETRY) {
/* Driver could not get current status */
h->retry_cnt++;
if (!d->reread_ms)
goto reread;
tmo = d->reread_ms;
goto reschedule;
}
if (ret) {
/*
* IC status reading succeeded. update error info
* just in case the renable changed it.
*/
for (i = 0; i < num_rdevs; i++) {
struct regulator_err_state *stat;
struct regulator_dev *rdev;
stat = &rid->states[i];
rdev = stat->rdev;
rdev_clear_err(rdev, (~stat->errors) &
stat->possible_errs);
}
h->retry_cnt++;
/*
* The IC indicated problem is still ON - no point in
* re-enabling the IRQ. Retry later.
*/
tmo = d->irq_off_ms;
goto reschedule;
}
}
/*
* Either IC reported problem cleared or no status checker was provided.
* If problems are gone - good. If not - then the IRQ will fire again
* and we'll have a new nice loop. In any case we should clear error
* flags here and re-enable IRQs.
*/
for (i = 0; i < num_rdevs; i++) {
struct regulator_err_state *stat;
struct regulator_dev *rdev;
stat = &rid->states[i];
rdev = stat->rdev;
rdev_clear_err(rdev, stat->possible_errs);
}
/*
* Things have been seemingly successful => zero retry-counter.
*/
h->retry_cnt = 0;
enable_out:
enable_irq(h->irq);
return;
reschedule:
if (!d->high_prio)
mod_delayed_work(system_wq, &h->isr_work,
msecs_to_jiffies(tmo));
else
mod_delayed_work(system_highpri_wq, &h->isr_work,
msecs_to_jiffies(tmo));
}
static irqreturn_t regulator_notifier_isr(int irq, void *data)
{
struct regulator_irq *h = data;
struct regulator_irq_desc *d;
struct regulator_irq_data *rid;
unsigned long rdev_map = 0;
int num_rdevs;
int ret, i;
d = &h->desc;
rid = &h->rdata;
num_rdevs = rid->num_states;
if (d->fatal_cnt)
h->retry_cnt++;
/*
* we spare a few cycles by not clearing statuses prior to this call.
* The IC driver must initialize the status buffers for rdevs
* which it indicates having active events via rdev_map.
*
* Maybe we should just to be on a safer side(?)
*/
ret = d->map_event(irq, rid, &rdev_map);
/*
* If status reading fails (which is unlikely) we don't ack/disable
* IRQ but just increase fail count and retry when IRQ fires again.
* If retry_count exceeds the given safety limit we call IC specific die
* handler which can try disabling regulator(s).
*
* If no die handler is given we will just bug() as a last resort.
*
* We could try disabling all associated rdevs - but we might shoot
* ourselves in the head and leave the problematic regulator enabled. So
* if IC has no die-handler populated we just assume the regulator
* can't be disabled.
*/
if (unlikely(ret == REGULATOR_FAILED_RETRY))
goto fail_out;
h->retry_cnt = 0;
/*
* Let's not disable IRQ if there were no status bits for us. We'd
* better leave spurious IRQ handling to genirq
*/
if (ret || !rdev_map)
return IRQ_NONE;
/*
* Some events are bogus if the regulator is disabled. Skip such events
* if all relevant regulators are disabled
*/
if (d->skip_off) {
for_each_set_bit(i, &rdev_map, num_rdevs) {
struct regulator_dev *rdev;
const struct regulator_ops *ops;
rdev = rid->states[i].rdev;
ops = rdev->desc->ops;
/*
* If any of the flagged regulators is enabled we do
* handle this
*/
if (ops->is_enabled(rdev))
break;
}
if (i == num_rdevs)
return IRQ_NONE;
}
/* Disable IRQ if HW keeps line asserted */
if (d->irq_off_ms)
disable_irq_nosync(irq);
/*
* IRQ seems to be for us. Let's fire correct notifiers / store error
* flags
*/
for_each_set_bit(i, &rdev_map, num_rdevs) {
struct regulator_err_state *stat;
struct regulator_dev *rdev;
stat = &rid->states[i];
rdev = stat->rdev;
rdev_dbg(rdev, "Sending regulator notification EVT 0x%lx\n",
stat->notifs);
regulator_notifier_call_chain(rdev, stat->notifs, NULL);
rdev_flag_err(rdev, stat->errors);
}
if (d->irq_off_ms) {
if (!d->high_prio)
schedule_delayed_work(&h->isr_work,
msecs_to_jiffies(d->irq_off_ms));
else
mod_delayed_work(system_highpri_wq,
&h->isr_work,
msecs_to_jiffies(d->irq_off_ms));
}
return IRQ_HANDLED;
fail_out:
if (d->fatal_cnt && h->retry_cnt > d->fatal_cnt) {
/* If we have no recovery, just try shut down straight away */
if (!d->die) {
hw_protection_shutdown("Regulator failure. Retry count exceeded",
REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS);
} else {
ret = d->die(rid);
/* If die() failed shut down as a last attempt to save the HW */
if (ret)
hw_protection_shutdown("Regulator failure. Recovery failed",
REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS);
}
}
return IRQ_NONE;
}
static int init_rdev_state(struct device *dev, struct regulator_irq *h,
struct regulator_dev **rdev, int common_err,
int *rdev_err, int rdev_amount)
{
int i;
h->rdata.states = devm_kzalloc(dev, sizeof(*h->rdata.states) *
rdev_amount, GFP_KERNEL);
if (!h->rdata.states)
return -ENOMEM;
h->rdata.num_states = rdev_amount;
h->rdata.data = h->desc.data;
for (i = 0; i < rdev_amount; i++) {
h->rdata.states[i].possible_errs = common_err;
if (rdev_err)
h->rdata.states[i].possible_errs |= *rdev_err++;
h->rdata.states[i].rdev = *rdev++;
}
return 0;
}
static void init_rdev_errors(struct regulator_irq *h)
{
int i;
for (i = 0; i < h->rdata.num_states; i++)
if (h->rdata.states[i].possible_errs)
h->rdata.states[i].rdev->use_cached_err = true;
}
/**
* regulator_irq_helper - register IRQ based regulator event/error notifier
*
* @dev: device providing the IRQs
* @d: IRQ helper descriptor.
* @irq: IRQ used to inform events/errors to be notified.
* @irq_flags: Extra IRQ flags to be OR'ed with the default
* IRQF_ONESHOT when requesting the (threaded) irq.
* @common_errs: Errors which can be flagged by this IRQ for all rdevs.
* When IRQ is re-enabled these errors will be cleared
* from all associated regulators
* @per_rdev_errs: Optional error flag array describing errors specific
* for only some of the regulators. These errors will be
* or'ed with common errors. If this is given the array
* should contain rdev_amount flags. Can be set to NULL
* if there is no regulator specific error flags for this
* IRQ.
* @rdev: Array of pointers to regulators associated with this
* IRQ.
* @rdev_amount: Amount of regulators associated with this IRQ.
*
* Return: handle to irq_helper or an ERR_PTR() encoded error code.
*/
void *regulator_irq_helper(struct device *dev,
const struct regulator_irq_desc *d, int irq,
int irq_flags, int common_errs, int *per_rdev_errs,
struct regulator_dev **rdev, int rdev_amount)
{
struct regulator_irq *h;
int ret;
if (!rdev_amount || !d || !d->map_event || !d->name)
return ERR_PTR(-EINVAL);
h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
if (!h)
return ERR_PTR(-ENOMEM);
h->irq = irq;
h->desc = *d;
ret = init_rdev_state(dev, h, rdev, common_errs, per_rdev_errs,
rdev_amount);
if (ret)
return ERR_PTR(ret);
init_rdev_errors(h);
if (h->desc.irq_off_ms)
INIT_DELAYED_WORK(&h->isr_work, regulator_notifier_isr_work);
ret = request_threaded_irq(h->irq, NULL, regulator_notifier_isr,
IRQF_ONESHOT | irq_flags, h->desc.name, h);
if (ret) {
dev_err(dev, "Failed to request IRQ %d\n", irq);
return ERR_PTR(ret);
}
return h;
}
EXPORT_SYMBOL_GPL(regulator_irq_helper);
/**
* regulator_irq_helper_cancel - drop IRQ based regulator event/error notifier
*
* @handle: Pointer to handle returned by a successful call to
* regulator_irq_helper(). Will be NULLed upon return.
*
* The associated IRQ is released and work is cancelled when the function
* returns.
*/
void regulator_irq_helper_cancel(void **handle)
{
if (handle && *handle) {
struct regulator_irq *h = *handle;
free_irq(h->irq, h);
if (h->desc.irq_off_ms)
cancel_delayed_work_sync(&h->isr_work);
h = NULL;
}
}
EXPORT_SYMBOL_GPL(regulator_irq_helper_cancel);

View File

@ -136,52 +136,9 @@ err_i2c:
return 0;
}
static int lp8755_buck_set_ramp(struct regulator_dev *rdev, int ramp)
{
int ret;
unsigned int regval = 0x00;
enum lp8755_bucks id = rdev_get_id(rdev);
/* uV/us */
switch (ramp) {
case 0 ... 230:
regval = 0x07;
break;
case 231 ... 470:
regval = 0x06;
break;
case 471 ... 940:
regval = 0x05;
break;
case 941 ... 1900:
regval = 0x04;
break;
case 1901 ... 3800:
regval = 0x03;
break;
case 3801 ... 7500:
regval = 0x02;
break;
case 7501 ... 15000:
regval = 0x01;
break;
case 15001 ... 30000:
regval = 0x00;
break;
default:
dev_err(&rdev->dev,
"Not supported ramp value %d %s\n", ramp, __func__);
return -EINVAL;
}
ret = regmap_update_bits(rdev->regmap, 0x07 + id, 0x07, regval);
if (ret < 0)
goto err_i2c;
return ret;
err_i2c:
dev_err(&rdev->dev, "i2c access error %s\n", __func__);
return ret;
}
static const unsigned int lp8755_buck_ramp_table[] = {
30000, 15000, 7500, 3800, 1900, 940, 470, 230
};
static const struct regulator_ops lp8755_buck_ops = {
.map_voltage = regulator_map_voltage_linear,
@ -194,7 +151,7 @@ static const struct regulator_ops lp8755_buck_ops = {
.enable_time = lp8755_buck_enable_time,
.set_mode = lp8755_buck_set_mode,
.get_mode = lp8755_buck_get_mode,
.set_ramp_delay = lp8755_buck_set_ramp,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
#define lp8755_rail(_id) "lp8755_buck"#_id
@ -269,6 +226,10 @@ out_i2c_error:
.enable_mask = LP8755_BUCK_EN_M,\
.vsel_reg = LP8755_REG_BUCK##_id,\
.vsel_mask = LP8755_BUCK_VOUT_M,\
.ramp_reg = (LP8755_BUCK##_id) + 0x7,\
.ramp_mask = 0x7,\
.ramp_delay_table = lp8755_buck_ramp_table,\
.n_ramp_values = ARRAY_SIZE(lp8755_buck_ramp_table),\
}
static const struct regulator_desc lp8755_regulators[] = {

View File

@ -54,6 +54,11 @@
#define LTC3589_VCCR_SW3_GO BIT(4)
#define LTC3589_VCCR_LDO2_GO BIT(6)
#define LTC3589_VRRCR_SW1_RAMP_MASK GENMASK(1, 0)
#define LTC3589_VRRCR_SW2_RAMP_MASK GENMASK(3, 2)
#define LTC3589_VRRCR_SW3_RAMP_MASK GENMASK(5, 4)
#define LTC3589_VRRCR_LDO2_RAMP_MASK GENMASK(7, 6)
enum ltc3589_variant {
LTC3589,
LTC3589_1,
@ -88,27 +93,9 @@ static const int ltc3589_12_ldo4[] = {
1200000, 1800000, 2500000, 3200000,
};
static int ltc3589_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
struct ltc3589 *ltc3589 = rdev_get_drvdata(rdev);
int sel, shift;
if (unlikely(ramp_delay <= 0))
return -EINVAL;
/* VRRCR slew rate offsets are the same as VCCR go bit offsets */
shift = ffs(rdev->desc->apply_bit) - 1;
/* The slew rate can be set to 0.88, 1.75, 3.5, or 7 mV/uS */
for (sel = 0; sel < 4; sel++) {
if ((880 << sel) >= ramp_delay) {
return regmap_update_bits(ltc3589->regmap,
LTC3589_VRRCR,
0x3 << shift, sel << shift);
}
}
return -EINVAL;
}
static const unsigned int ltc3589_ramp_table[] = {
880, 1750, 3500, 7000
};
static int ltc3589_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{
@ -149,7 +136,7 @@ static const struct regulator_ops ltc3589_linear_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_ramp_delay = ltc3589_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_suspend_voltage = ltc3589_set_suspend_voltage,
.set_suspend_mode = ltc3589_set_suspend_mode,
@ -218,16 +205,13 @@ static int ltc3589_of_parse_cb(struct device_node *np,
return 0;
}
#define LTC3589_REG(_name, _of_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit)\
#define LTC3589_REG(_name, _of_name, _ops, en_bit, dtv1_reg, dtv_mask) \
[LTC3589_ ## _name] = { \
.name = #_name, \
.of_match = of_match_ptr(#_of_name), \
.regulators_node = of_match_ptr("regulators"), \
.of_parse_cb = ltc3589_of_parse_cb, \
.n_voltages = (dtv_mask) + 1, \
.min_uV = (go_bit) ? 362500 : 0, \
.uV_step = (go_bit) ? 12500 : 0, \
.ramp_delay = (go_bit) ? 1750 : 0, \
.fixed_uV = (dtv_mask) ? 0 : 800000, \
.ops = &ltc3589_ ## _ops ## _regulator_ops, \
.type = REGULATOR_VOLTAGE, \
@ -235,30 +219,49 @@ static int ltc3589_of_parse_cb(struct device_node *np,
.owner = THIS_MODULE, \
.vsel_reg = (dtv1_reg), \
.vsel_mask = (dtv_mask), \
.apply_reg = (go_bit) ? LTC3589_VCCR : 0, \
.apply_bit = (go_bit), \
.enable_reg = (en_bit) ? LTC3589_OVEN : 0, \
.enable_mask = (en_bit), \
}
#define LTC3589_LINEAR_REG(_name, _of_name, _dtv1) \
LTC3589_REG(_name, _of_name, linear, LTC3589_OVEN_ ## _name, \
LTC3589_ ## _dtv1, 0x1f, \
LTC3589_VCCR_ ## _name ## _GO)
[LTC3589_ ## _name] = { \
.name = #_name, \
.of_match = of_match_ptr(#_of_name), \
.regulators_node = of_match_ptr("regulators"), \
.of_parse_cb = ltc3589_of_parse_cb, \
.n_voltages = 32, \
.min_uV = 362500, \
.uV_step = 12500, \
.ramp_delay = 1750, \
.ops = &ltc3589_linear_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = LTC3589_ ## _name, \
.owner = THIS_MODULE, \
.vsel_reg = LTC3589_ ## _dtv1, \
.vsel_mask = 0x1f, \
.apply_reg = LTC3589_VCCR, \
.apply_bit = LTC3589_VCCR_ ## _name ## _GO, \
.enable_reg = LTC3589_OVEN, \
.enable_mask = (LTC3589_OVEN_ ## _name), \
.ramp_reg = LTC3589_VRRCR, \
.ramp_mask = LTC3589_VRRCR_ ## _name ## _RAMP_MASK, \
.ramp_delay_table = ltc3589_ramp_table, \
.n_ramp_values = ARRAY_SIZE(ltc3589_ramp_table), \
}
#define LTC3589_FIXED_REG(_name, _of_name) \
LTC3589_REG(_name, _of_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0)
LTC3589_REG(_name, _of_name, fixed, LTC3589_OVEN_ ## _name, 0, 0)
static const struct regulator_desc ltc3589_regulators[] = {
LTC3589_LINEAR_REG(SW1, sw1, B1DTV1),
LTC3589_LINEAR_REG(SW2, sw2, B2DTV1),
LTC3589_LINEAR_REG(SW3, sw3, B3DTV1),
LTC3589_FIXED_REG(BB_OUT, bb-out),
LTC3589_REG(LDO1, ldo1, fixed_standby, 0, 0, 0, 0),
LTC3589_REG(LDO1, ldo1, fixed_standby, 0, 0, 0),
LTC3589_LINEAR_REG(LDO2, ldo2, L2DTV1),
LTC3589_FIXED_REG(LDO3, ldo3),
LTC3589_REG(LDO4, ldo4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2,
0x60, 0),
LTC3589_REG(LDO4, ldo4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, 0x60),
};
static bool ltc3589_writeable_reg(struct device *dev, unsigned int reg)

View File

@ -67,13 +67,6 @@
#define MAX77686_REGULATORS MAX77686_REG_MAX
#define MAX77686_LDOS 26
enum max77686_ramp_rate {
RAMP_RATE_13P75MV,
RAMP_RATE_27P5MV,
RAMP_RATE_55MV,
RAMP_RATE_NO_CTRL, /* 100mV/us */
};
struct max77686_data {
struct device *dev;
DECLARE_BITMAP(gpio_enabled, MAX77686_REGULATORS);
@ -220,31 +213,6 @@ static int max77686_enable(struct regulator_dev *rdev)
max77686->opmode[id] << shift);
}
static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_value = RAMP_RATE_NO_CTRL;
switch (ramp_delay) {
case 1 ... 13750:
ramp_value = RAMP_RATE_13P75MV;
break;
case 13751 ... 27500:
ramp_value = RAMP_RATE_27P5MV;
break;
case 27501 ... 55000:
ramp_value = RAMP_RATE_55MV;
break;
case 55001 ... 100000:
break;
default:
pr_warn("%s: ramp_delay: %d not supported, setting 100000\n",
rdev->desc->name, ramp_delay);
}
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77686_RAMP_RATE_MASK, ramp_value << 6);
}
static int max77686_of_parse_cb(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *config)
@ -284,6 +252,10 @@ static int max77686_of_parse_cb(struct device_node *np,
return 0;
}
static const unsigned int max77686_buck_dvs_ramp_table[] = {
13750, 27500, 55000, 100000
};
static const struct regulator_ops max77686_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
@ -330,7 +302,7 @@ static const struct regulator_ops max77686_buck_dvs_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77686_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_disable = max77686_set_suspend_disable,
};
@ -462,6 +434,10 @@ static const struct regulator_ops max77686_buck_dvs_ops = {
.enable_reg = MAX77686_REG_BUCK2CTRL1 + (num - 2) * 10, \
.enable_mask = MAX77686_OPMODE_MASK \
<< MAX77686_OPMODE_BUCK234_SHIFT, \
.ramp_reg = MAX77686_REG_BUCK2CTRL1 + (num - 2) * 10, \
.ramp_mask = MAX77686_RAMP_RATE_MASK, \
.ramp_delay_table = max77686_buck_dvs_ramp_table, \
.n_ramp_values = ARRAY_SIZE(max77686_buck_dvs_ramp_table), \
}
static const struct regulator_desc regulators[] = {

View File

@ -43,15 +43,14 @@
#define MAX77802_OFF_PWRREQ 0x1
#define MAX77802_LP_PWRREQ 0x2
/* MAX77802 has two register formats: 2-bit and 4-bit */
static const unsigned int ramp_table_77802_2bit[] = {
static const unsigned int max77802_buck234_ramp_table[] = {
12500,
25000,
50000,
100000,
};
static unsigned int ramp_table_77802_4bit[] = {
static const unsigned int max77802_buck16_ramp_table[] = {
1000, 2000, 3030, 4000,
5000, 5880, 7140, 8330,
9090, 10000, 11110, 12500,
@ -221,58 +220,6 @@ static int max77802_enable(struct regulator_dev *rdev)
max77802->opmode[id] << shift);
}
static int max77802_find_ramp_value(struct regulator_dev *rdev,
const unsigned int limits[], int size,
unsigned int ramp_delay)
{
int i;
for (i = 0; i < size; i++) {
if (ramp_delay <= limits[i])
return i;
}
/* Use maximum value for no ramp control */
dev_warn(&rdev->dev, "%s: ramp_delay: %d not supported, setting 100000\n",
rdev->desc->name, ramp_delay);
return size - 1;
}
/* Used for BUCKs 2-4 */
static int max77802_set_ramp_delay_2bit(struct regulator_dev *rdev,
int ramp_delay)
{
int id = rdev_get_id(rdev);
unsigned int ramp_value;
if (id > MAX77802_BUCK4) {
dev_warn(&rdev->dev,
"%s: regulator: ramp delay not supported\n",
rdev->desc->name);
return -EINVAL;
}
ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_2bit,
ARRAY_SIZE(ramp_table_77802_2bit), ramp_delay);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77802_RAMP_RATE_MASK_2BIT,
ramp_value << MAX77802_RAMP_RATE_SHIFT_2BIT);
}
/* For BUCK1, 6 */
static int max77802_set_ramp_delay_4bit(struct regulator_dev *rdev,
int ramp_delay)
{
unsigned int ramp_value;
ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_4bit,
ARRAY_SIZE(ramp_table_77802_4bit), ramp_delay);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77802_RAMP_RATE_MASK_4BIT,
ramp_value << MAX77802_RAMP_RATE_SHIFT_4BIT);
}
/*
* LDOs 2, 4-19, 22-35
*/
@ -316,7 +263,7 @@ static const struct regulator_ops max77802_buck_16_dvs_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_4bit,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_disable = max77802_set_suspend_disable,
};
@ -330,7 +277,7 @@ static const struct regulator_ops max77802_buck_234_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_2bit,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_disable = max77802_set_suspend_disable,
.set_suspend_mode = max77802_set_suspend_mode,
};
@ -345,7 +292,6 @@ static const struct regulator_ops max77802_buck_dvs_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_2bit,
.set_suspend_disable = max77802_set_suspend_disable,
};
@ -409,6 +355,10 @@ static const struct regulator_ops max77802_buck_dvs_ops = {
.vsel_mask = MAX77802_DVS_VSEL_MASK, \
.enable_reg = MAX77802_REG_BUCK ## num ## CTRL, \
.enable_mask = MAX77802_OPMODE_MASK, \
.ramp_reg = MAX77802_REG_BUCK ## num ## CTRL, \
.ramp_mask = MAX77802_RAMP_RATE_MASK_4BIT, \
.ramp_delay_table = max77802_buck16_ramp_table, \
.n_ramp_values = ARRAY_SIZE(max77802_buck16_ramp_table), \
.of_map_mode = max77802_map_mode, \
}
@ -431,6 +381,10 @@ static const struct regulator_ops max77802_buck_dvs_ops = {
.enable_reg = MAX77802_REG_BUCK ## num ## CTRL1, \
.enable_mask = MAX77802_OPMODE_MASK << \
MAX77802_OPMODE_BUCK234_SHIFT, \
.ramp_reg = MAX77802_REG_BUCK ## num ## CTRL1, \
.ramp_mask = MAX77802_RAMP_RATE_MASK_2BIT, \
.ramp_delay_table = max77802_buck234_ramp_table, \
.n_ramp_values = ARRAY_SIZE(max77802_buck234_ramp_table), \
.of_map_mode = max77802_map_mode, \
}

183
drivers/regulator/max8893.c Normal file
View File

@ -0,0 +1,183 @@
// SPDX-License-Identifier: GPL-2.0+
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
static const struct regulator_ops max8893_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
};
static const struct regulator_desc max8893_regulators[] = {
{
.name = "BUCK",
.supply_name = "in-buck",
.of_match = of_match_ptr("buck"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x11,
.id = 6,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 800000,
.uV_step = 100000,
.vsel_reg = 0x4,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(7),
},
{
.name = "LDO1",
.supply_name = "in-ldo1",
.of_match = of_match_ptr("ldo1"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x12,
.id = 1,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 1600000,
.uV_step = 100000,
.vsel_reg = 0x5,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(5),
},
{
.name = "LDO2",
.supply_name = "in-ldo2",
.of_match = of_match_ptr("ldo2"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x16,
.id = 2,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 1200000,
.uV_step = 100000,
.vsel_reg = 0x6,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(4),
},
{
.name = "LDO3",
.supply_name = "in-ldo3",
.of_match = of_match_ptr("ldo3"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x12,
.id = 3,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 1600000,
.uV_step = 100000,
.vsel_reg = 0x7,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(3),
},
{
.name = "LDO4",
.supply_name = "in-ldo4",
.of_match = of_match_ptr("ldo4"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x1a,
.id = 4,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 800000,
.uV_step = 100000,
.vsel_reg = 0x8,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(2),
},
{
.name = "LDO5",
.supply_name = "in-ldo5",
.of_match = of_match_ptr("ldo5"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x1a,
.id = 5,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 800000,
.uV_step = 100000,
.vsel_reg = 0x9,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(1),
}
};
static const struct regmap_config max8893_regmap = {
.reg_bits = 8,
.val_bits = 8,
};
static int max8893_probe_new(struct i2c_client *i2c)
{
int id, ret;
struct regulator_config config = {.dev = &i2c->dev};
struct regmap *regmap = devm_regmap_init_i2c(i2c, &max8893_regmap);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
return ret;
}
for (id = 0; id < ARRAY_SIZE(max8893_regulators); id++) {
struct regulator_dev *rdev;
rdev = devm_regulator_register(&i2c->dev,
&max8893_regulators[id],
&config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&i2c->dev, "failed to register %s: %d\n",
max8893_regulators[id].name, ret);
return ret;
}
}
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id max8893_dt_match[] = {
{ .compatible = "maxim,max8893" },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, max8893_dt_match);
#endif
static const struct i2c_device_id max8893_ids[] = {
{ "max8893", 0 },
{ },
};
MODULE_DEVICE_TABLE(i2c, max8893_ids);
static struct i2c_driver max8893_driver = {
.probe_new = max8893_probe_new,
.driver = {
.name = "max8893",
.of_match_table = of_match_ptr(max8893_dt_match),
},
.id_table = max8893_ids,
};
module_i2c_driver(max8893_driver);
MODULE_DESCRIPTION("Maxim MAX8893 PMIC driver");
MODULE_AUTHOR("Sergey Larin <cerg2010cerg2010@mail.ru>");
MODULE_LICENSE("GPL");

View File

@ -265,33 +265,6 @@ static unsigned int max8973_dcdc_get_mode(struct regulator_dev *rdev)
REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
}
static int max8973_set_ramp_delay(struct regulator_dev *rdev,
int ramp_delay)
{
struct max8973_chip *max = rdev_get_drvdata(rdev);
unsigned int control;
int ret;
/* Set ramp delay */
if (ramp_delay <= 12000)
control = MAX8973_RAMP_12mV_PER_US;
else if (ramp_delay <= 25000)
control = MAX8973_RAMP_25mV_PER_US;
else if (ramp_delay <= 50000)
control = MAX8973_RAMP_50mV_PER_US;
else if (ramp_delay <= 200000)
control = MAX8973_RAMP_200mV_PER_US;
else
return -EINVAL;
ret = regmap_update_bits(max->regmap, MAX8973_CONTROL1,
MAX8973_RAMP_MASK, control);
if (ret < 0)
dev_err(max->dev, "register %d update failed, %d",
MAX8973_CONTROL1, ret);
return ret;
}
static int max8973_set_current_limit(struct regulator_dev *rdev,
int min_ua, int max_ua)
{
@ -341,6 +314,10 @@ static int max8973_get_current_limit(struct regulator_dev *rdev)
return 9000000;
}
static const unsigned int max8973_buck_ramp_table[] = {
12000, 25000, 50000, 200000
};
static const struct regulator_ops max8973_dcdc_ops = {
.get_voltage_sel = max8973_dcdc_get_voltage_sel,
.set_voltage_sel = max8973_dcdc_set_voltage_sel,
@ -348,7 +325,7 @@ static const struct regulator_ops max8973_dcdc_ops = {
.set_mode = max8973_dcdc_set_mode,
.get_mode = max8973_dcdc_get_mode,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max8973_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
static int max8973_init_dcdc(struct max8973_chip *max,
@ -694,6 +671,10 @@ static int max8973_probe(struct i2c_client *client,
max->desc.min_uV = MAX8973_MIN_VOLATGE;
max->desc.uV_step = MAX8973_VOLATGE_STEP;
max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE;
max->desc.ramp_reg = MAX8973_CONTROL1;
max->desc.ramp_mask = MAX8973_RAMP_MASK;
max->desc.ramp_delay_table = max8973_buck_ramp_table;
max->desc.n_ramp_values = ARRAY_SIZE(max8973_buck_ramp_table);
max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL;
max->enable_external_control = pdata->enable_ext_control;

View File

@ -90,10 +90,14 @@ enum mcp16502_reg {
};
/* Ramp delay (uV/us) for buck1, ldo1, ldo2. */
static const int mcp16502_ramp_b1l12[] = { 6250, 3125, 2083, 1563 };
static const unsigned int mcp16502_ramp_b1l12[] = {
6250, 3125, 2083, 1563
};
/* Ramp delay (uV/us) for buck2, buck3, buck4. */
static const int mcp16502_ramp_b234[] = { 3125, 1563, 1042, 781 };
static const unsigned int mcp16502_ramp_b234[] = {
3125, 1563, 1042, 781
};
static unsigned int mcp16502_of_map_mode(unsigned int mode)
{
@ -103,7 +107,7 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode)
return REGULATOR_MODE_INVALID;
}
#define MCP16502_REGULATOR(_name, _id, _ranges, _ops) \
#define MCP16502_REGULATOR(_name, _id, _ranges, _ops, _ramp_table) \
[_id] = { \
.name = _name, \
.regulators_node = of_match_ptr("regulators"), \
@ -121,6 +125,10 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode)
.vsel_mask = MCP16502_VSEL, \
.enable_reg = (((_id) + 1) << 4), \
.enable_mask = MCP16502_EN, \
.ramp_reg = MCP16502_REG_BASE(_id, CFG), \
.ramp_mask = MCP16502_DVSR, \
.ramp_delay_table = _ramp_table, \
.n_ramp_values = ARRAY_SIZE(_ramp_table), \
}
enum {
@ -314,42 +322,6 @@ static int mcp16502_set_voltage_time_sel(struct regulator_dev *rdev,
return ret;
}
static int mcp16502_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
const int *ramp;
int id = rdev_get_id(rdev);
unsigned int i, size;
switch (id) {
case BUCK1:
case LDO1:
case LDO2:
ramp = mcp16502_ramp_b1l12;
size = ARRAY_SIZE(mcp16502_ramp_b1l12);
break;
case BUCK2:
case BUCK3:
case BUCK4:
ramp = mcp16502_ramp_b234;
size = ARRAY_SIZE(mcp16502_ramp_b234);
break;
default:
return -EINVAL;
}
for (i = 0; i < size; i++) {
if (ramp[i] == ramp_delay)
break;
}
if (i == size)
return -EINVAL;
return regmap_update_bits(rdev->regmap, MCP16502_REG_BASE(id, CFG),
MCP16502_DVSR, (i << 2));
}
#ifdef CONFIG_SUSPEND
/*
* mcp16502_suspend_get_target_reg() - get the reg of the target suspend PMIC
@ -445,7 +417,7 @@ static const struct regulator_ops mcp16502_buck_ops = {
.is_enabled = regulator_is_enabled_regmap,
.get_status = mcp16502_get_status,
.set_voltage_time_sel = mcp16502_set_voltage_time_sel,
.set_ramp_delay = mcp16502_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_mode = mcp16502_set_mode,
.get_mode = mcp16502_get_mode,
@ -471,7 +443,7 @@ static const struct regulator_ops mcp16502_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.get_status = mcp16502_get_status,
.set_voltage_time_sel = mcp16502_set_voltage_time_sel,
.set_ramp_delay = mcp16502_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
#ifdef CONFIG_SUSPEND
.set_suspend_voltage = mcp16502_set_suspend_voltage,
@ -495,13 +467,19 @@ static const struct linear_range b234_ranges[] = {
};
static const struct regulator_desc mcp16502_desc[] = {
/* MCP16502_REGULATOR(_name, _id, ranges, regulator_ops) */
MCP16502_REGULATOR("VDD_IO", BUCK1, b1l12_ranges, mcp16502_buck_ops),
MCP16502_REGULATOR("VDD_DDR", BUCK2, b234_ranges, mcp16502_buck_ops),
MCP16502_REGULATOR("VDD_CORE", BUCK3, b234_ranges, mcp16502_buck_ops),
MCP16502_REGULATOR("VDD_OTHER", BUCK4, b234_ranges, mcp16502_buck_ops),
MCP16502_REGULATOR("LDO1", LDO1, b1l12_ranges, mcp16502_ldo_ops),
MCP16502_REGULATOR("LDO2", LDO2, b1l12_ranges, mcp16502_ldo_ops)
/* MCP16502_REGULATOR(_name, _id, ranges, regulator_ops, ramp_table) */
MCP16502_REGULATOR("VDD_IO", BUCK1, b1l12_ranges, mcp16502_buck_ops,
mcp16502_ramp_b1l12),
MCP16502_REGULATOR("VDD_DDR", BUCK2, b234_ranges, mcp16502_buck_ops,
mcp16502_ramp_b234),
MCP16502_REGULATOR("VDD_CORE", BUCK3, b234_ranges, mcp16502_buck_ops,
mcp16502_ramp_b234),
MCP16502_REGULATOR("VDD_OTHER", BUCK4, b234_ranges, mcp16502_buck_ops,
mcp16502_ramp_b234),
MCP16502_REGULATOR("LDO1", LDO1, b1l12_ranges, mcp16502_ldo_ops,
mcp16502_ramp_b1l12),
MCP16502_REGULATOR("LDO2", LDO2, b1l12_ranges, mcp16502_ldo_ops,
mcp16502_ramp_b1l12)
};
static const struct regmap_range mcp16502_ranges[] = {
@ -522,8 +500,7 @@ static const struct regmap_config mcp16502_regmap_config = {
.wr_table = &mcp16502_yes_reg_table,
};
static int mcp16502_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int mcp16502_probe(struct i2c_client *client)
{
struct regulator_config config = { };
struct regulator_dev *rdev;
@ -606,7 +583,7 @@ static const struct i2c_device_id mcp16502_i2c_id[] = {
MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);
static struct i2c_driver mcp16502_drv = {
.probe = mcp16502_probe,
.probe_new = mcp16502_probe,
.driver = {
.name = "mcp16502-regulator",
.of_match_table = of_match_ptr(mcp16502_ids),

View File

@ -67,6 +67,10 @@
.vsel_mask = MP5416_MASK_VSET, \
.enable_reg = MP5416_REG_BUCK ## _id, \
.enable_mask = MP5416_REGULATOR_EN, \
.ramp_reg = MP5416_REG_CTL2, \
.ramp_mask = MP5416_MASK_DVS_SLEWRATE, \
.ramp_delay_table = mp5416_buck_ramp_table, \
.n_ramp_values = ARRAY_SIZE(mp5416_buck_ramp_table), \
.active_discharge_on = _dval, \
.active_discharge_reg = _dreg, \
.active_discharge_mask = _dval, \
@ -123,7 +127,16 @@ static const unsigned int mp5416_I_limits2[] = {
2200000, 3200000, 4200000, 5200000
};
static int mp5416_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay);
/*
* DVS ramp rate BUCK1 to BUCK4
* 00: 32mV/us
* 01: 16mV/us
* 10: 8mV/us
* 11: 4mV/us
*/
static const unsigned int mp5416_buck_ramp_table[] = {
32000, 16000, 8000, 4000
};
static const struct regulator_ops mp5416_ldo_ops = {
.enable = regulator_enable_regmap,
@ -147,7 +160,7 @@ static const struct regulator_ops mp5416_buck_ops = {
.set_active_discharge = regulator_set_active_discharge_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
.set_ramp_delay = mp5416_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
static struct regulator_desc mp5416_regulators_desc[MP5416_MAX_REGULATORS] = {
@ -161,33 +174,6 @@ static struct regulator_desc mp5416_regulators_desc[MP5416_MAX_REGULATORS] = {
MP5416LDO("ldo4", 4, BIT(1)),
};
/*
* DVS ramp rate BUCK1 to BUCK4
* 00: 32mV/us
* 01: 16mV/us
* 10: 8mV/us
* 11: 4mV/us
*/
static int mp5416_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_val;
if (ramp_delay > 32000 || ramp_delay < 0)
return -EINVAL;
if (ramp_delay <= 4000)
ramp_val = 3;
else if (ramp_delay <= 8000)
ramp_val = 2;
else if (ramp_delay <= 16000)
ramp_val = 1;
else
ramp_val = 0;
return regmap_update_bits(rdev->regmap, MP5416_REG_CTL2,
MP5416_MASK_DVS_SLEWRATE, ramp_val << 6);
}
static int mp5416_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;

View File

@ -26,7 +26,7 @@
struct mp886x_cfg_info {
const struct regulator_ops *rops;
const int slew_rates[8];
const unsigned int slew_rates[8];
const int switch_freq[4];
const u8 fs_reg;
const u8 fs_shift;
@ -42,28 +42,6 @@ struct mp886x_device_info {
unsigned int sel;
};
static int mp886x_set_ramp(struct regulator_dev *rdev, int ramp)
{
struct mp886x_device_info *di = rdev_get_drvdata(rdev);
const struct mp886x_cfg_info *ci = di->ci;
int reg = -1, i;
for (i = 0; i < ARRAY_SIZE(ci->slew_rates); i++) {
if (ramp <= ci->slew_rates[i])
reg = i;
else
break;
}
if (reg < 0) {
dev_err(di->dev, "unsupported ramp value %d\n", ramp);
return -EINVAL;
}
return regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1,
MP886X_SLEW_MASK, reg << MP886X_SLEW_SHIFT);
}
static void mp886x_set_switch_freq(struct mp886x_device_info *di,
struct regmap *regmap,
u32 freq)
@ -169,7 +147,7 @@ static const struct regulator_ops mp8869_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
.set_mode = mp886x_set_mode,
.get_mode = mp886x_get_mode,
.set_ramp_delay = mp886x_set_ramp,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
static const struct mp886x_cfg_info mp8869_ci = {
@ -248,7 +226,7 @@ static const struct regulator_ops mp8867_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
.set_mode = mp886x_set_mode,
.get_mode = mp886x_get_mode,
.set_ramp_delay = mp886x_set_ramp,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
static const struct mp886x_cfg_info mp8867_ci = {
@ -290,6 +268,10 @@ static int mp886x_regulator_register(struct mp886x_device_info *di,
rdesc->uV_step = 10000;
rdesc->vsel_reg = MP886X_VSEL;
rdesc->vsel_mask = 0x3f;
rdesc->ramp_reg = MP886X_SYSCNTLREG1;
rdesc->ramp_mask = MP886X_SLEW_MASK;
rdesc->ramp_delay_table = di->ci->slew_rates;
rdesc->n_ramp_values = ARRAY_SIZE(di->ci->slew_rates);
rdesc->owner = THIS_MODULE;
rdev = devm_regulator_register(di->dev, &di->desc, config);

View File

@ -84,7 +84,7 @@ static unsigned int mt6315_regulator_get_mode(struct regulator_dev *rdev)
modeset_mask = init->modeset_mask[rdev_get_id(rdev)];
ret = regmap_read(rdev->regmap, MT6315_BUCK_TOP_4PHASE_ANA_CON42, &regval);
if (ret != 0) {
dev_notice(&rdev->dev, "Failed to get mode: %d\n", ret);
dev_err(&rdev->dev, "Failed to get mode: %d\n", ret);
return ret;
}
@ -93,7 +93,7 @@ static unsigned int mt6315_regulator_get_mode(struct regulator_dev *rdev)
ret = regmap_read(rdev->regmap, MT6315_BUCK_TOP_CON1, &regval);
if (ret != 0) {
dev_notice(&rdev->dev, "Failed to get lp mode: %d\n", ret);
dev_err(&rdev->dev, "Failed to get lp mode: %d\n", ret);
return ret;
}
@ -147,12 +147,12 @@ static int mt6315_regulator_set_mode(struct regulator_dev *rdev,
break;
default:
ret = -EINVAL;
dev_notice(&rdev->dev, "Unsupported mode: %d\n", mode);
dev_err(&rdev->dev, "Unsupported mode: %d\n", mode);
break;
}
if (ret != 0) {
dev_notice(&rdev->dev, "Failed to set mode: %d\n", ret);
dev_err(&rdev->dev, "Failed to set mode: %d\n", ret);
return ret;
}
@ -168,7 +168,7 @@ static int mt6315_get_status(struct regulator_dev *rdev)
info = container_of(rdev->desc, struct mt6315_regulator_info, desc);
ret = regmap_read(rdev->regmap, info->status_reg, &regval);
if (ret < 0) {
dev_notice(&rdev->dev, "Failed to get enable reg: %d\n", ret);
dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
return ret;
}
@ -223,8 +223,8 @@ static int mt6315_regulator_probe(struct spmi_device *pdev)
int i;
regmap = devm_regmap_init_spmi_ext(pdev, &mt6315_regmap_config);
if (!regmap)
return -ENODEV;
if (IS_ERR(regmap))
return PTR_ERR(regmap);
chip = devm_kzalloc(dev, sizeof(struct mt6315_chip), GFP_KERNEL);
if (!chip)
@ -260,8 +260,9 @@ static int mt6315_regulator_probe(struct spmi_device *pdev)
config.driver_data = init_data;
rdev = devm_regulator_register(dev, &mt6315_regulators[i].desc, &config);
if (IS_ERR(rdev)) {
dev_notice(dev, "Failed to register %s\n", mt6315_regulators[i].desc.name);
continue;
dev_err(dev, "Failed to register %s\n",
mt6315_regulators[i].desc.name);
return PTR_ERR(rdev);
}
}
@ -279,7 +280,7 @@ static void mt6315_regulator_shutdown(struct spmi_device *pdev)
ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY, 0);
ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY_H, 0);
if (ret < 0)
dev_notice(&pdev->dev, "[%#x] Failed to enable power off sequence. %d\n",
dev_err(&pdev->dev, "[%#x] Failed to enable power off sequence. %d\n",
pdev->usid, ret);
}

View File

@ -153,50 +153,50 @@ static const struct linear_range buck_volt_range4[] = {
REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500),
};
static const u32 vdram2_voltages[] = {
static const unsigned int vdram2_voltages[] = {
600000, 1800000,
};
static const u32 vsim_voltages[] = {
static const unsigned int vsim_voltages[] = {
1700000, 1800000, 2700000, 3000000, 3100000,
};
static const u32 vibr_voltages[] = {
static const unsigned int vibr_voltages[] = {
1200000, 1300000, 1500000, 1800000,
2000000, 2800000, 3000000, 3300000,
};
static const u32 vusb_voltages[] = {
static const unsigned int vusb_voltages[] = {
3000000, 3100000,
};
static const u32 vcamd_voltages[] = {
static const unsigned int vcamd_voltages[] = {
900000, 1000000, 1100000, 1200000,
1300000, 1500000, 1800000,
};
static const u32 vefuse_voltages[] = {
static const unsigned int vefuse_voltages[] = {
1700000, 1800000, 1900000,
};
static const u32 vmch_vemc_voltages[] = {
static const unsigned int vmch_vemc_voltages[] = {
2900000, 3000000, 3300000,
};
static const u32 vcama_voltages[] = {
static const unsigned int vcama_voltages[] = {
1800000, 2500000, 2700000,
2800000, 2900000, 3000000,
};
static const u32 vcn33_bt_wifi_voltages[] = {
static const unsigned int vcn33_bt_wifi_voltages[] = {
3300000, 3400000, 3500000,
};
static const u32 vmc_voltages[] = {
static const unsigned int vmc_voltages[] = {
1800000, 2900000, 3000000, 3300000,
};
static const u32 vldo28_voltages[] = {
static const unsigned int vldo28_voltages[] = {
2800000, 3000000,
};
@ -457,7 +457,7 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
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_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0xf, 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,

View File

@ -0,0 +1,997 @@
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2021 MediaTek Inc.
#include <linux/platform_device.h>
#include <linux/mfd/mt6359/registers.h>
#include <linux/mfd/mt6359p/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/mt6359-regulator.h>
#include <linux/regulator/of_regulator.h>
#define MT6359_BUCK_MODE_AUTO 0
#define MT6359_BUCK_MODE_FORCE_PWM 1
#define MT6359_BUCK_MODE_NORMAL 0
#define MT6359_BUCK_MODE_LP 2
/*
* MT6359 regulators' information
*
* @desc: standard fields of regulator description.
* @status_reg: for query status of regulators.
* @qi: Mask for query enable signal status of regulators.
* @modeset_reg: for operating AUTO/PWM mode register.
* @modeset_mask: MASK for operating modeset register.
* @modeset_shift: SHIFT for operating modeset register.
*/
struct mt6359_regulator_info {
struct regulator_desc desc;
u32 status_reg;
u32 qi;
u32 modeset_reg;
u32 modeset_mask;
u32 modeset_shift;
u32 lp_mode_reg;
u32 lp_mode_mask;
u32 lp_mode_shift;
};
#define MT6359_BUCK(match, _name, min, max, step, \
_enable_reg, _status_reg, \
_vsel_reg, _vsel_mask, \
_lp_mode_reg, _lp_mode_shift, \
_modeset_reg, _modeset_shift) \
[MT6359_ID_##_name] = { \
.desc = { \
.name = #_name, \
.of_match = of_match_ptr(match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &mt6359_volt_linear_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6359_ID_##_name, \
.owner = THIS_MODULE, \
.uV_step = (step), \
.n_voltages = ((max) - (min)) / (step) + 1, \
.min_uV = (min), \
.vsel_reg = _vsel_reg, \
.vsel_mask = _vsel_mask, \
.enable_reg = _enable_reg, \
.enable_mask = BIT(0), \
.of_map_mode = mt6359_map_mode, \
}, \
.status_reg = _status_reg, \
.qi = BIT(0), \
.lp_mode_reg = _lp_mode_reg, \
.lp_mode_mask = BIT(_lp_mode_shift), \
.lp_mode_shift = _lp_mode_shift, \
.modeset_reg = _modeset_reg, \
.modeset_mask = BIT(_modeset_shift), \
.modeset_shift = _modeset_shift \
}
#define MT6359_LDO_LINEAR(match, _name, min, max, step, \
_enable_reg, _status_reg, _vsel_reg, _vsel_mask) \
[MT6359_ID_##_name] = { \
.desc = { \
.name = #_name, \
.of_match = of_match_ptr(match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &mt6359_volt_linear_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6359_ID_##_name, \
.owner = THIS_MODULE, \
.uV_step = (step), \
.n_voltages = ((max) - (min)) / (step) + 1, \
.min_uV = (min), \
.vsel_reg = _vsel_reg, \
.vsel_mask = _vsel_mask, \
.enable_reg = _enable_reg, \
.enable_mask = BIT(0), \
}, \
.status_reg = _status_reg, \
.qi = BIT(0), \
}
#define MT6359_LDO(match, _name, _volt_table, \
_enable_reg, _enable_mask, _status_reg, \
_vsel_reg, _vsel_mask, _en_delay) \
[MT6359_ID_##_name] = { \
.desc = { \
.name = #_name, \
.of_match = of_match_ptr(match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &mt6359_volt_table_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6359_ID_##_name, \
.owner = THIS_MODULE, \
.n_voltages = ARRAY_SIZE(_volt_table), \
.volt_table = _volt_table, \
.vsel_reg = _vsel_reg, \
.vsel_mask = _vsel_mask, \
.enable_reg = _enable_reg, \
.enable_mask = BIT(_enable_mask), \
.enable_time = _en_delay, \
}, \
.status_reg = _status_reg, \
.qi = BIT(0), \
}
#define MT6359_REG_FIXED(match, _name, _enable_reg, \
_status_reg, _fixed_volt) \
[MT6359_ID_##_name] = { \
.desc = { \
.name = #_name, \
.of_match = of_match_ptr(match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &mt6359_volt_fixed_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6359_ID_##_name, \
.owner = THIS_MODULE, \
.n_voltages = 1, \
.enable_reg = _enable_reg, \
.enable_mask = BIT(0), \
.fixed_uV = (_fixed_volt), \
}, \
.status_reg = _status_reg, \
.qi = BIT(0), \
}
#define MT6359P_LDO1(match, _name, _ops, _volt_table, \
_enable_reg, _enable_mask, _status_reg, \
_vsel_reg, _vsel_mask) \
[MT6359_ID_##_name] = { \
.desc = { \
.name = #_name, \
.of_match = of_match_ptr(match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6359_ID_##_name, \
.owner = THIS_MODULE, \
.n_voltages = ARRAY_SIZE(_volt_table), \
.volt_table = _volt_table, \
.vsel_reg = _vsel_reg, \
.vsel_mask = _vsel_mask, \
.enable_reg = _enable_reg, \
.enable_mask = BIT(_enable_mask), \
}, \
.status_reg = _status_reg, \
.qi = BIT(0), \
}
static const unsigned int vsim1_voltages[] = {
0, 0, 0, 1700000, 1800000, 0, 0, 0, 2700000, 0, 0, 3000000, 3100000,
};
static const unsigned int vibr_voltages[] = {
1200000, 1300000, 1500000, 0, 1800000, 2000000, 0, 0, 2700000, 2800000,
0, 3000000, 0, 3300000,
};
static const unsigned int vrf12_voltages[] = {
0, 0, 1100000, 1200000, 1300000,
};
static const unsigned int volt18_voltages[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1700000, 1800000, 1900000,
};
static const unsigned int vcn13_voltages[] = {
900000, 1000000, 0, 1200000, 1300000,
};
static const unsigned int vcn33_voltages[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 2800000, 0, 0, 0, 3300000, 3400000, 3500000,
};
static const unsigned int vefuse_voltages[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1700000, 1800000, 1900000, 2000000,
};
static const unsigned int vxo22_voltages[] = {
1800000, 0, 0, 0, 2200000,
};
static const unsigned int vrfck_voltages[] = {
0, 0, 1500000, 0, 0, 0, 0, 1600000, 0, 0, 0, 0, 1700000,
};
static const unsigned int vrfck_voltages_1[] = {
1240000, 1600000,
};
static const unsigned int vio28_voltages[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 2800000, 2900000, 3000000, 3100000, 3300000,
};
static const unsigned int vemc_voltages[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2900000, 3000000, 0, 3300000,
};
static const unsigned int vemc_voltages_1[] = {
0, 0, 0, 0, 0, 0, 0, 0, 2500000, 2800000, 2900000, 3000000, 3100000,
3300000,
};
static const unsigned int va12_voltages[] = {
0, 0, 0, 0, 0, 0, 1200000, 1300000,
};
static const unsigned int va09_voltages[] = {
0, 0, 800000, 900000, 0, 0, 1200000,
};
static const unsigned int vrf18_voltages[] = {
0, 0, 0, 0, 0, 1700000, 1800000, 1810000,
};
static const unsigned int vbbck_voltages[] = {
0, 0, 0, 0, 1100000, 0, 0, 0, 1150000, 0, 0, 0, 1200000,
};
static const unsigned int vsim2_voltages[] = {
0, 0, 0, 1700000, 1800000, 0, 0, 0, 2700000, 0, 0, 3000000, 3100000,
};
static inline unsigned int mt6359_map_mode(unsigned int mode)
{
switch (mode) {
case MT6359_BUCK_MODE_NORMAL:
return REGULATOR_MODE_NORMAL;
case MT6359_BUCK_MODE_FORCE_PWM:
return REGULATOR_MODE_FAST;
case MT6359_BUCK_MODE_LP:
return REGULATOR_MODE_IDLE;
default:
return REGULATOR_MODE_INVALID;
}
}
static int mt6359_get_status(struct regulator_dev *rdev)
{
int ret;
u32 regval;
struct mt6359_regulator_info *info = rdev_get_drvdata(rdev);
ret = regmap_read(rdev->regmap, info->status_reg, &regval);
if (ret != 0) {
dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
return ret;
}
if (regval & info->qi)
return REGULATOR_STATUS_ON;
else
return REGULATOR_STATUS_OFF;
}
static unsigned int mt6359_regulator_get_mode(struct regulator_dev *rdev)
{
struct mt6359_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 mt6359 buck mode: %d\n", ret);
return ret;
}
if ((regval & info->modeset_mask) >> info->modeset_shift ==
MT6359_BUCK_MODE_FORCE_PWM)
return REGULATOR_MODE_FAST;
ret = regmap_read(rdev->regmap, info->lp_mode_reg, &regval);
if (ret != 0) {
dev_err(&rdev->dev,
"Failed to get mt6359 buck lp mode: %d\n", ret);
return ret;
}
if (regval & info->lp_mode_mask)
return REGULATOR_MODE_IDLE;
else
return REGULATOR_MODE_NORMAL;
}
static int mt6359_regulator_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
struct mt6359_regulator_info *info = rdev_get_drvdata(rdev);
int ret = 0, val;
int curr_mode;
curr_mode = mt6359_regulator_get_mode(rdev);
switch (mode) {
case REGULATOR_MODE_FAST:
val = MT6359_BUCK_MODE_FORCE_PWM;
val <<= info->modeset_shift;
ret = regmap_update_bits(rdev->regmap,
info->modeset_reg,
info->modeset_mask,
val);
break;
case REGULATOR_MODE_NORMAL:
if (curr_mode == REGULATOR_MODE_FAST) {
val = MT6359_BUCK_MODE_AUTO;
val <<= info->modeset_shift;
ret = regmap_update_bits(rdev->regmap,
info->modeset_reg,
info->modeset_mask,
val);
} else if (curr_mode == REGULATOR_MODE_IDLE) {
val = MT6359_BUCK_MODE_NORMAL;
val <<= info->lp_mode_shift;
ret = regmap_update_bits(rdev->regmap,
info->lp_mode_reg,
info->lp_mode_mask,
val);
udelay(100);
}
break;
case REGULATOR_MODE_IDLE:
val = MT6359_BUCK_MODE_LP >> 1;
val <<= info->lp_mode_shift;
ret = regmap_update_bits(rdev->regmap,
info->lp_mode_reg,
info->lp_mode_mask,
val);
break;
default:
return -EINVAL;
}
if (ret != 0) {
dev_err(&rdev->dev,
"Failed to set mt6359 buck mode: %d\n", ret);
}
return ret;
}
static int mt6359p_vemc_set_voltage_sel(struct regulator_dev *rdev,
u32 sel)
{
struct mt6359_regulator_info *info = rdev_get_drvdata(rdev);
int ret;
u32 val = 0;
sel <<= ffs(info->desc.vsel_mask) - 1;
ret = regmap_write(rdev->regmap, MT6359P_TMA_KEY_ADDR, TMA_KEY);
if (ret)
return ret;
ret = regmap_read(rdev->regmap, MT6359P_VM_MODE_ADDR, &val);
if (ret)
return ret;
switch (val) {
case 0:
/* If HW trapping is 0, use VEMC_VOSEL_0 */
ret = regmap_update_bits(rdev->regmap,
info->desc.vsel_reg,
info->desc.vsel_mask, sel);
break;
case 1:
/* If HW trapping is 1, use VEMC_VOSEL_1 */
ret = regmap_update_bits(rdev->regmap,
info->desc.vsel_reg + 0x2,
info->desc.vsel_mask, sel);
break;
default:
return -EINVAL;
}
if (ret)
return ret;
ret = regmap_write(rdev->regmap, MT6359P_TMA_KEY_ADDR, 0);
return ret;
}
static int mt6359p_vemc_get_voltage_sel(struct regulator_dev *rdev)
{
struct mt6359_regulator_info *info = rdev_get_drvdata(rdev);
int ret;
u32 val = 0;
ret = regmap_read(rdev->regmap, MT6359P_VM_MODE_ADDR, &val);
if (ret)
return ret;
switch (val) {
case 0:
/* If HW trapping is 0, use VEMC_VOSEL_0 */
ret = regmap_read(rdev->regmap,
info->desc.vsel_reg, &val);
break;
case 1:
/* If HW trapping is 1, use VEMC_VOSEL_1 */
ret = regmap_read(rdev->regmap,
info->desc.vsel_reg + 0x2, &val);
break;
default:
return -EINVAL;
}
if (ret)
return ret;
val &= info->desc.vsel_mask;
val >>= ffs(info->desc.vsel_mask) - 1;
return val;
}
static const struct regulator_ops mt6359_volt_linear_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.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,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_status = mt6359_get_status,
.set_mode = mt6359_regulator_set_mode,
.get_mode = mt6359_regulator_get_mode,
};
static const struct regulator_ops mt6359_volt_table_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_iterate,
.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,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_status = mt6359_get_status,
};
static const struct regulator_ops mt6359_volt_fixed_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_status = mt6359_get_status,
};
static const struct regulator_ops mt6359p_vemc_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_iterate,
.set_voltage_sel = mt6359p_vemc_set_voltage_sel,
.get_voltage_sel = mt6359p_vemc_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 = mt6359_get_status,
};
/* The array is indexed by id(MT6359_ID_XXX) */
static struct mt6359_regulator_info mt6359_regulators[] = {
MT6359_BUCK("buck_vs1", VS1, 800000, 2200000, 12500,
MT6359_RG_BUCK_VS1_EN_ADDR,
MT6359_DA_VS1_EN_ADDR, MT6359_RG_BUCK_VS1_VOSEL_ADDR,
MT6359_RG_BUCK_VS1_VOSEL_MASK <<
MT6359_RG_BUCK_VS1_VOSEL_SHIFT,
MT6359_RG_BUCK_VS1_LP_ADDR, MT6359_RG_BUCK_VS1_LP_SHIFT,
MT6359_RG_VS1_FPWM_ADDR, MT6359_RG_VS1_FPWM_SHIFT),
MT6359_BUCK("buck_vgpu11", VGPU11, 400000, 1193750, 6250,
MT6359_RG_BUCK_VGPU11_EN_ADDR,
MT6359_DA_VGPU11_EN_ADDR, MT6359_RG_BUCK_VGPU11_VOSEL_ADDR,
MT6359_RG_BUCK_VGPU11_VOSEL_MASK <<
MT6359_RG_BUCK_VGPU11_VOSEL_SHIFT,
MT6359_RG_BUCK_VGPU11_LP_ADDR,
MT6359_RG_BUCK_VGPU11_LP_SHIFT,
MT6359_RG_VGPU11_FCCM_ADDR, MT6359_RG_VGPU11_FCCM_SHIFT),
MT6359_BUCK("buck_vmodem", VMODEM, 400000, 1100000, 6250,
MT6359_RG_BUCK_VMODEM_EN_ADDR,
MT6359_DA_VMODEM_EN_ADDR, MT6359_RG_BUCK_VMODEM_VOSEL_ADDR,
MT6359_RG_BUCK_VMODEM_VOSEL_MASK <<
MT6359_RG_BUCK_VMODEM_VOSEL_SHIFT,
MT6359_RG_BUCK_VMODEM_LP_ADDR,
MT6359_RG_BUCK_VMODEM_LP_SHIFT,
MT6359_RG_VMODEM_FCCM_ADDR, MT6359_RG_VMODEM_FCCM_SHIFT),
MT6359_BUCK("buck_vpu", VPU, 400000, 1193750, 6250,
MT6359_RG_BUCK_VPU_EN_ADDR,
MT6359_DA_VPU_EN_ADDR, MT6359_RG_BUCK_VPU_VOSEL_ADDR,
MT6359_RG_BUCK_VPU_VOSEL_MASK <<
MT6359_RG_BUCK_VPU_VOSEL_SHIFT,
MT6359_RG_BUCK_VPU_LP_ADDR, MT6359_RG_BUCK_VPU_LP_SHIFT,
MT6359_RG_VPU_FCCM_ADDR, MT6359_RG_VPU_FCCM_SHIFT),
MT6359_BUCK("buck_vcore", VCORE, 400000, 1193750, 6250,
MT6359_RG_BUCK_VCORE_EN_ADDR,
MT6359_DA_VCORE_EN_ADDR, MT6359_RG_BUCK_VCORE_VOSEL_ADDR,
MT6359_RG_BUCK_VCORE_VOSEL_MASK <<
MT6359_RG_BUCK_VCORE_VOSEL_SHIFT,
MT6359_RG_BUCK_VCORE_LP_ADDR, MT6359_RG_BUCK_VCORE_LP_SHIFT,
MT6359_RG_VCORE_FCCM_ADDR, MT6359_RG_VCORE_FCCM_SHIFT),
MT6359_BUCK("buck_vs2", VS2, 800000, 1600000, 12500,
MT6359_RG_BUCK_VS2_EN_ADDR,
MT6359_DA_VS2_EN_ADDR, MT6359_RG_BUCK_VS2_VOSEL_ADDR,
MT6359_RG_BUCK_VS2_VOSEL_MASK <<
MT6359_RG_BUCK_VS2_VOSEL_SHIFT,
MT6359_RG_BUCK_VS2_LP_ADDR, MT6359_RG_BUCK_VS2_LP_SHIFT,
MT6359_RG_VS2_FPWM_ADDR, MT6359_RG_VS2_FPWM_SHIFT),
MT6359_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
MT6359_RG_BUCK_VPA_EN_ADDR,
MT6359_DA_VPA_EN_ADDR, MT6359_RG_BUCK_VPA_VOSEL_ADDR,
MT6359_RG_BUCK_VPA_VOSEL_MASK <<
MT6359_RG_BUCK_VPA_VOSEL_SHIFT,
MT6359_RG_BUCK_VPA_LP_ADDR, MT6359_RG_BUCK_VPA_LP_SHIFT,
MT6359_RG_VPA_MODESET_ADDR, MT6359_RG_VPA_MODESET_SHIFT),
MT6359_BUCK("buck_vproc2", VPROC2, 400000, 1193750, 6250,
MT6359_RG_BUCK_VPROC2_EN_ADDR,
MT6359_DA_VPROC2_EN_ADDR, MT6359_RG_BUCK_VPROC2_VOSEL_ADDR,
MT6359_RG_BUCK_VPROC2_VOSEL_MASK <<
MT6359_RG_BUCK_VPROC2_VOSEL_SHIFT,
MT6359_RG_BUCK_VPROC2_LP_ADDR,
MT6359_RG_BUCK_VPROC2_LP_SHIFT,
MT6359_RG_VPROC2_FCCM_ADDR, MT6359_RG_VPROC2_FCCM_SHIFT),
MT6359_BUCK("buck_vproc1", VPROC1, 400000, 1193750, 6250,
MT6359_RG_BUCK_VPROC1_EN_ADDR,
MT6359_DA_VPROC1_EN_ADDR, MT6359_RG_BUCK_VPROC1_VOSEL_ADDR,
MT6359_RG_BUCK_VPROC1_VOSEL_MASK <<
MT6359_RG_BUCK_VPROC1_VOSEL_SHIFT,
MT6359_RG_BUCK_VPROC1_LP_ADDR,
MT6359_RG_BUCK_VPROC1_LP_SHIFT,
MT6359_RG_VPROC1_FCCM_ADDR, MT6359_RG_VPROC1_FCCM_SHIFT),
MT6359_BUCK("buck_vcore_sshub", VCORE_SSHUB, 400000, 1193750, 6250,
MT6359_RG_BUCK_VCORE_SSHUB_EN_ADDR,
MT6359_DA_VCORE_EN_ADDR,
MT6359_RG_BUCK_VCORE_SSHUB_VOSEL_ADDR,
MT6359_RG_BUCK_VCORE_SSHUB_VOSEL_MASK <<
MT6359_RG_BUCK_VCORE_SSHUB_VOSEL_SHIFT,
MT6359_RG_BUCK_VCORE_LP_ADDR, MT6359_RG_BUCK_VCORE_LP_SHIFT,
MT6359_RG_VCORE_FCCM_ADDR, MT6359_RG_VCORE_FCCM_SHIFT),
MT6359_REG_FIXED("ldo_vaud18", VAUD18, MT6359_RG_LDO_VAUD18_EN_ADDR,
MT6359_DA_VAUD18_B_EN_ADDR, 1800000),
MT6359_LDO("ldo_vsim1", VSIM1, vsim1_voltages,
MT6359_RG_LDO_VSIM1_EN_ADDR, MT6359_RG_LDO_VSIM1_EN_SHIFT,
MT6359_DA_VSIM1_B_EN_ADDR, MT6359_RG_VSIM1_VOSEL_ADDR,
MT6359_RG_VSIM1_VOSEL_MASK << MT6359_RG_VSIM1_VOSEL_SHIFT,
480),
MT6359_LDO("ldo_vibr", VIBR, vibr_voltages,
MT6359_RG_LDO_VIBR_EN_ADDR, MT6359_RG_LDO_VIBR_EN_SHIFT,
MT6359_DA_VIBR_B_EN_ADDR, MT6359_RG_VIBR_VOSEL_ADDR,
MT6359_RG_VIBR_VOSEL_MASK << MT6359_RG_VIBR_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_vrf12", VRF12, vrf12_voltages,
MT6359_RG_LDO_VRF12_EN_ADDR, MT6359_RG_LDO_VRF12_EN_SHIFT,
MT6359_DA_VRF12_B_EN_ADDR, MT6359_RG_VRF12_VOSEL_ADDR,
MT6359_RG_VRF12_VOSEL_MASK << MT6359_RG_VRF12_VOSEL_SHIFT,
120),
MT6359_REG_FIXED("ldo_vusb", VUSB, MT6359_RG_LDO_VUSB_EN_0_ADDR,
MT6359_DA_VUSB_B_EN_ADDR, 3000000),
MT6359_LDO_LINEAR("ldo_vsram_proc2", VSRAM_PROC2, 500000, 1293750, 6250,
MT6359_RG_LDO_VSRAM_PROC2_EN_ADDR,
MT6359_DA_VSRAM_PROC2_B_EN_ADDR,
MT6359_RG_LDO_VSRAM_PROC2_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_PROC2_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_PROC2_VOSEL_SHIFT),
MT6359_LDO("ldo_vio18", VIO18, volt18_voltages,
MT6359_RG_LDO_VIO18_EN_ADDR, MT6359_RG_LDO_VIO18_EN_SHIFT,
MT6359_DA_VIO18_B_EN_ADDR, MT6359_RG_VIO18_VOSEL_ADDR,
MT6359_RG_VIO18_VOSEL_MASK << MT6359_RG_VIO18_VOSEL_SHIFT,
960),
MT6359_LDO("ldo_vcamio", VCAMIO, volt18_voltages,
MT6359_RG_LDO_VCAMIO_EN_ADDR, MT6359_RG_LDO_VCAMIO_EN_SHIFT,
MT6359_DA_VCAMIO_B_EN_ADDR, MT6359_RG_VCAMIO_VOSEL_ADDR,
MT6359_RG_VCAMIO_VOSEL_MASK << MT6359_RG_VCAMIO_VOSEL_SHIFT,
1290),
MT6359_REG_FIXED("ldo_vcn18", VCN18, MT6359_RG_LDO_VCN18_EN_ADDR,
MT6359_DA_VCN18_B_EN_ADDR, 1800000),
MT6359_REG_FIXED("ldo_vfe28", VFE28, MT6359_RG_LDO_VFE28_EN_ADDR,
MT6359_DA_VFE28_B_EN_ADDR, 2800000),
MT6359_LDO("ldo_vcn13", VCN13, vcn13_voltages,
MT6359_RG_LDO_VCN13_EN_ADDR, MT6359_RG_LDO_VCN13_EN_SHIFT,
MT6359_DA_VCN13_B_EN_ADDR, MT6359_RG_VCN13_VOSEL_ADDR,
MT6359_RG_VCN13_VOSEL_MASK << MT6359_RG_VCN13_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_vcn33_1_bt", VCN33_1_BT, vcn33_voltages,
MT6359_RG_LDO_VCN33_1_EN_0_ADDR,
MT6359_RG_LDO_VCN33_1_EN_0_SHIFT,
MT6359_DA_VCN33_1_B_EN_ADDR, MT6359_RG_VCN33_1_VOSEL_ADDR,
MT6359_RG_VCN33_1_VOSEL_MASK <<
MT6359_RG_VCN33_1_VOSEL_SHIFT, 240),
MT6359_LDO("ldo_vcn33_1_wifi", VCN33_1_WIFI, vcn33_voltages,
MT6359_RG_LDO_VCN33_1_EN_1_ADDR,
MT6359_RG_LDO_VCN33_1_EN_1_SHIFT,
MT6359_DA_VCN33_1_B_EN_ADDR, MT6359_RG_VCN33_1_VOSEL_ADDR,
MT6359_RG_VCN33_1_VOSEL_MASK <<
MT6359_RG_VCN33_1_VOSEL_SHIFT, 240),
MT6359_REG_FIXED("ldo_vaux18", VAUX18, MT6359_RG_LDO_VAUX18_EN_ADDR,
MT6359_DA_VAUX18_B_EN_ADDR, 1800000),
MT6359_LDO_LINEAR("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750,
6250,
MT6359_RG_LDO_VSRAM_OTHERS_EN_ADDR,
MT6359_DA_VSRAM_OTHERS_B_EN_ADDR,
MT6359_RG_LDO_VSRAM_OTHERS_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_OTHERS_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_OTHERS_VOSEL_SHIFT),
MT6359_LDO("ldo_vefuse", VEFUSE, vefuse_voltages,
MT6359_RG_LDO_VEFUSE_EN_ADDR, MT6359_RG_LDO_VEFUSE_EN_SHIFT,
MT6359_DA_VEFUSE_B_EN_ADDR, MT6359_RG_VEFUSE_VOSEL_ADDR,
MT6359_RG_VEFUSE_VOSEL_MASK << MT6359_RG_VEFUSE_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_vxo22", VXO22, vxo22_voltages,
MT6359_RG_LDO_VXO22_EN_ADDR, MT6359_RG_LDO_VXO22_EN_SHIFT,
MT6359_DA_VXO22_B_EN_ADDR, MT6359_RG_VXO22_VOSEL_ADDR,
MT6359_RG_VXO22_VOSEL_MASK << MT6359_RG_VXO22_VOSEL_SHIFT,
120),
MT6359_LDO("ldo_vrfck", VRFCK, vrfck_voltages,
MT6359_RG_LDO_VRFCK_EN_ADDR, MT6359_RG_LDO_VRFCK_EN_SHIFT,
MT6359_DA_VRFCK_B_EN_ADDR, MT6359_RG_VRFCK_VOSEL_ADDR,
MT6359_RG_VRFCK_VOSEL_MASK << MT6359_RG_VRFCK_VOSEL_SHIFT,
480),
MT6359_REG_FIXED("ldo_vbif28", VBIF28, MT6359_RG_LDO_VBIF28_EN_ADDR,
MT6359_DA_VBIF28_B_EN_ADDR, 2800000),
MT6359_LDO("ldo_vio28", VIO28, vio28_voltages,
MT6359_RG_LDO_VIO28_EN_ADDR, MT6359_RG_LDO_VIO28_EN_SHIFT,
MT6359_DA_VIO28_B_EN_ADDR, MT6359_RG_VIO28_VOSEL_ADDR,
MT6359_RG_VIO28_VOSEL_MASK << MT6359_RG_VIO28_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_vemc", VEMC, vemc_voltages,
MT6359_RG_LDO_VEMC_EN_ADDR, MT6359_RG_LDO_VEMC_EN_SHIFT,
MT6359_DA_VEMC_B_EN_ADDR, MT6359_RG_VEMC_VOSEL_ADDR,
MT6359_RG_VEMC_VOSEL_MASK << MT6359_RG_VEMC_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_vcn33_2_bt", VCN33_2_BT, vcn33_voltages,
MT6359_RG_LDO_VCN33_2_EN_0_ADDR,
MT6359_RG_LDO_VCN33_2_EN_0_SHIFT,
MT6359_DA_VCN33_2_B_EN_ADDR, MT6359_RG_VCN33_2_VOSEL_ADDR,
MT6359_RG_VCN33_2_VOSEL_MASK <<
MT6359_RG_VCN33_2_VOSEL_SHIFT, 240),
MT6359_LDO("ldo_vcn33_2_wifi", VCN33_2_WIFI, vcn33_voltages,
MT6359_RG_LDO_VCN33_2_EN_1_ADDR,
MT6359_RG_LDO_VCN33_2_EN_1_SHIFT,
MT6359_DA_VCN33_2_B_EN_ADDR, MT6359_RG_VCN33_2_VOSEL_ADDR,
MT6359_RG_VCN33_2_VOSEL_MASK <<
MT6359_RG_VCN33_2_VOSEL_SHIFT, 240),
MT6359_LDO("ldo_va12", VA12, va12_voltages,
MT6359_RG_LDO_VA12_EN_ADDR, MT6359_RG_LDO_VA12_EN_SHIFT,
MT6359_DA_VA12_B_EN_ADDR, MT6359_RG_VA12_VOSEL_ADDR,
MT6359_RG_VA12_VOSEL_MASK << MT6359_RG_VA12_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_va09", VA09, va09_voltages,
MT6359_RG_LDO_VA09_EN_ADDR, MT6359_RG_LDO_VA09_EN_SHIFT,
MT6359_DA_VA09_B_EN_ADDR, MT6359_RG_VA09_VOSEL_ADDR,
MT6359_RG_VA09_VOSEL_MASK << MT6359_RG_VA09_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_vrf18", VRF18, vrf18_voltages,
MT6359_RG_LDO_VRF18_EN_ADDR, MT6359_RG_LDO_VRF18_EN_SHIFT,
MT6359_DA_VRF18_B_EN_ADDR, MT6359_RG_VRF18_VOSEL_ADDR,
MT6359_RG_VRF18_VOSEL_MASK << MT6359_RG_VRF18_VOSEL_SHIFT,
120),
MT6359_LDO_LINEAR("ldo_vsram_md", VSRAM_MD, 500000, 1100000, 6250,
MT6359_RG_LDO_VSRAM_MD_EN_ADDR,
MT6359_DA_VSRAM_MD_B_EN_ADDR,
MT6359_RG_LDO_VSRAM_MD_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_MD_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_MD_VOSEL_SHIFT),
MT6359_LDO("ldo_vufs", VUFS, volt18_voltages,
MT6359_RG_LDO_VUFS_EN_ADDR, MT6359_RG_LDO_VUFS_EN_SHIFT,
MT6359_DA_VUFS_B_EN_ADDR, MT6359_RG_VUFS_VOSEL_ADDR,
MT6359_RG_VUFS_VOSEL_MASK << MT6359_RG_VUFS_VOSEL_SHIFT,
1920),
MT6359_LDO("ldo_vm18", VM18, volt18_voltages,
MT6359_RG_LDO_VM18_EN_ADDR, MT6359_RG_LDO_VM18_EN_SHIFT,
MT6359_DA_VM18_B_EN_ADDR, MT6359_RG_VM18_VOSEL_ADDR,
MT6359_RG_VM18_VOSEL_MASK << MT6359_RG_VM18_VOSEL_SHIFT,
1920),
MT6359_LDO("ldo_vbbck", VBBCK, vbbck_voltages,
MT6359_RG_LDO_VBBCK_EN_ADDR, MT6359_RG_LDO_VBBCK_EN_SHIFT,
MT6359_DA_VBBCK_B_EN_ADDR, MT6359_RG_VBBCK_VOSEL_ADDR,
MT6359_RG_VBBCK_VOSEL_MASK << MT6359_RG_VBBCK_VOSEL_SHIFT,
240),
MT6359_LDO_LINEAR("ldo_vsram_proc1", VSRAM_PROC1, 500000, 1293750, 6250,
MT6359_RG_LDO_VSRAM_PROC1_EN_ADDR,
MT6359_DA_VSRAM_PROC1_B_EN_ADDR,
MT6359_RG_LDO_VSRAM_PROC1_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_PROC1_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_PROC1_VOSEL_SHIFT),
MT6359_LDO("ldo_vsim2", VSIM2, vsim2_voltages,
MT6359_RG_LDO_VSIM2_EN_ADDR, MT6359_RG_LDO_VSIM2_EN_SHIFT,
MT6359_DA_VSIM2_B_EN_ADDR, MT6359_RG_VSIM2_VOSEL_ADDR,
MT6359_RG_VSIM2_VOSEL_MASK << MT6359_RG_VSIM2_VOSEL_SHIFT,
480),
MT6359_LDO_LINEAR("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB,
500000, 1293750, 6250,
MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_EN_ADDR,
MT6359_DA_VSRAM_OTHERS_B_EN_ADDR,
MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_SHIFT),
};
static struct mt6359_regulator_info mt6359p_regulators[] = {
MT6359_BUCK("buck_vs1", VS1, 800000, 2200000, 12500,
MT6359_RG_BUCK_VS1_EN_ADDR,
MT6359_DA_VS1_EN_ADDR, MT6359_RG_BUCK_VS1_VOSEL_ADDR,
MT6359_RG_BUCK_VS1_VOSEL_MASK <<
MT6359_RG_BUCK_VS1_VOSEL_SHIFT,
MT6359_RG_BUCK_VS1_LP_ADDR, MT6359_RG_BUCK_VS1_LP_SHIFT,
MT6359_RG_VS1_FPWM_ADDR, MT6359_RG_VS1_FPWM_SHIFT),
MT6359_BUCK("buck_vgpu11", VGPU11, 400000, 1193750, 6250,
MT6359_RG_BUCK_VGPU11_EN_ADDR,
MT6359_DA_VGPU11_EN_ADDR, MT6359P_RG_BUCK_VGPU11_VOSEL_ADDR,
MT6359_RG_BUCK_VGPU11_VOSEL_MASK <<
MT6359_RG_BUCK_VGPU11_VOSEL_SHIFT,
MT6359_RG_BUCK_VGPU11_LP_ADDR,
MT6359_RG_BUCK_VGPU11_LP_SHIFT,
MT6359_RG_VGPU11_FCCM_ADDR, MT6359_RG_VGPU11_FCCM_SHIFT),
MT6359_BUCK("buck_vmodem", VMODEM, 400000, 1100000, 6250,
MT6359_RG_BUCK_VMODEM_EN_ADDR,
MT6359_DA_VMODEM_EN_ADDR, MT6359_RG_BUCK_VMODEM_VOSEL_ADDR,
MT6359_RG_BUCK_VMODEM_VOSEL_MASK <<
MT6359_RG_BUCK_VMODEM_VOSEL_SHIFT,
MT6359_RG_BUCK_VMODEM_LP_ADDR,
MT6359_RG_BUCK_VMODEM_LP_SHIFT,
MT6359_RG_VMODEM_FCCM_ADDR, MT6359_RG_VMODEM_FCCM_SHIFT),
MT6359_BUCK("buck_vpu", VPU, 400000, 1193750, 6250,
MT6359_RG_BUCK_VPU_EN_ADDR,
MT6359_DA_VPU_EN_ADDR, MT6359_RG_BUCK_VPU_VOSEL_ADDR,
MT6359_RG_BUCK_VPU_VOSEL_MASK <<
MT6359_RG_BUCK_VPU_VOSEL_SHIFT,
MT6359_RG_BUCK_VPU_LP_ADDR, MT6359_RG_BUCK_VPU_LP_SHIFT,
MT6359_RG_VPU_FCCM_ADDR, MT6359_RG_VPU_FCCM_SHIFT),
MT6359_BUCK("buck_vcore", VCORE, 506250, 1300000, 6250,
MT6359_RG_BUCK_VCORE_EN_ADDR,
MT6359_DA_VCORE_EN_ADDR, MT6359P_RG_BUCK_VCORE_VOSEL_ADDR,
MT6359_RG_BUCK_VCORE_VOSEL_MASK <<
MT6359_RG_BUCK_VCORE_VOSEL_SHIFT,
MT6359_RG_BUCK_VCORE_LP_ADDR, MT6359_RG_BUCK_VCORE_LP_SHIFT,
MT6359_RG_VCORE_FCCM_ADDR, MT6359_RG_VCORE_FCCM_SHIFT),
MT6359_BUCK("buck_vs2", VS2, 800000, 1600000, 12500,
MT6359_RG_BUCK_VS2_EN_ADDR,
MT6359_DA_VS2_EN_ADDR, MT6359_RG_BUCK_VS2_VOSEL_ADDR,
MT6359_RG_BUCK_VS2_VOSEL_MASK <<
MT6359_RG_BUCK_VS2_VOSEL_SHIFT,
MT6359_RG_BUCK_VS2_LP_ADDR, MT6359_RG_BUCK_VS2_LP_SHIFT,
MT6359_RG_VS2_FPWM_ADDR, MT6359_RG_VS2_FPWM_SHIFT),
MT6359_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
MT6359_RG_BUCK_VPA_EN_ADDR,
MT6359_DA_VPA_EN_ADDR, MT6359_RG_BUCK_VPA_VOSEL_ADDR,
MT6359_RG_BUCK_VPA_VOSEL_MASK <<
MT6359_RG_BUCK_VPA_VOSEL_SHIFT,
MT6359_RG_BUCK_VPA_LP_ADDR, MT6359_RG_BUCK_VPA_LP_SHIFT,
MT6359_RG_VPA_MODESET_ADDR, MT6359_RG_VPA_MODESET_SHIFT),
MT6359_BUCK("buck_vproc2", VPROC2, 400000, 1193750, 6250,
MT6359_RG_BUCK_VPROC2_EN_ADDR,
MT6359_DA_VPROC2_EN_ADDR, MT6359_RG_BUCK_VPROC2_VOSEL_ADDR,
MT6359_RG_BUCK_VPROC2_VOSEL_MASK <<
MT6359_RG_BUCK_VPROC2_VOSEL_SHIFT,
MT6359_RG_BUCK_VPROC2_LP_ADDR,
MT6359_RG_BUCK_VPROC2_LP_SHIFT,
MT6359_RG_VPROC2_FCCM_ADDR, MT6359_RG_VPROC2_FCCM_SHIFT),
MT6359_BUCK("buck_vproc1", VPROC1, 400000, 1193750, 6250,
MT6359_RG_BUCK_VPROC1_EN_ADDR,
MT6359_DA_VPROC1_EN_ADDR, MT6359_RG_BUCK_VPROC1_VOSEL_ADDR,
MT6359_RG_BUCK_VPROC1_VOSEL_MASK <<
MT6359_RG_BUCK_VPROC1_VOSEL_SHIFT,
MT6359_RG_BUCK_VPROC1_LP_ADDR,
MT6359_RG_BUCK_VPROC1_LP_SHIFT,
MT6359_RG_VPROC1_FCCM_ADDR, MT6359_RG_VPROC1_FCCM_SHIFT),
MT6359_BUCK("buck_vgpu11_sshub", VGPU11_SSHUB, 400000, 1193750, 6250,
MT6359P_RG_BUCK_VGPU11_SSHUB_EN_ADDR,
MT6359_DA_VGPU11_EN_ADDR,
MT6359P_RG_BUCK_VGPU11_SSHUB_VOSEL_ADDR,
MT6359P_RG_BUCK_VGPU11_SSHUB_VOSEL_MASK <<
MT6359P_RG_BUCK_VGPU11_SSHUB_VOSEL_SHIFT,
MT6359_RG_BUCK_VGPU11_LP_ADDR,
MT6359_RG_BUCK_VGPU11_LP_SHIFT,
MT6359_RG_VGPU11_FCCM_ADDR, MT6359_RG_VGPU11_FCCM_SHIFT),
MT6359_REG_FIXED("ldo_vaud18", VAUD18, MT6359P_RG_LDO_VAUD18_EN_ADDR,
MT6359P_DA_VAUD18_B_EN_ADDR, 1800000),
MT6359_LDO("ldo_vsim1", VSIM1, vsim1_voltages,
MT6359P_RG_LDO_VSIM1_EN_ADDR, MT6359P_RG_LDO_VSIM1_EN_SHIFT,
MT6359P_DA_VSIM1_B_EN_ADDR, MT6359P_RG_VSIM1_VOSEL_ADDR,
MT6359_RG_VSIM1_VOSEL_MASK << MT6359_RG_VSIM1_VOSEL_SHIFT,
480),
MT6359_LDO("ldo_vibr", VIBR, vibr_voltages,
MT6359P_RG_LDO_VIBR_EN_ADDR, MT6359P_RG_LDO_VIBR_EN_SHIFT,
MT6359P_DA_VIBR_B_EN_ADDR, MT6359P_RG_VIBR_VOSEL_ADDR,
MT6359_RG_VIBR_VOSEL_MASK << MT6359_RG_VIBR_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_vrf12", VRF12, vrf12_voltages,
MT6359P_RG_LDO_VRF12_EN_ADDR, MT6359P_RG_LDO_VRF12_EN_SHIFT,
MT6359P_DA_VRF12_B_EN_ADDR, MT6359P_RG_VRF12_VOSEL_ADDR,
MT6359_RG_VRF12_VOSEL_MASK << MT6359_RG_VRF12_VOSEL_SHIFT,
480),
MT6359_REG_FIXED("ldo_vusb", VUSB, MT6359P_RG_LDO_VUSB_EN_0_ADDR,
MT6359P_DA_VUSB_B_EN_ADDR, 3000000),
MT6359_LDO_LINEAR("ldo_vsram_proc2", VSRAM_PROC2, 500000, 1293750, 6250,
MT6359P_RG_LDO_VSRAM_PROC2_EN_ADDR,
MT6359P_DA_VSRAM_PROC2_B_EN_ADDR,
MT6359P_RG_LDO_VSRAM_PROC2_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_PROC2_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_PROC2_VOSEL_SHIFT),
MT6359_LDO("ldo_vio18", VIO18, volt18_voltages,
MT6359P_RG_LDO_VIO18_EN_ADDR, MT6359P_RG_LDO_VIO18_EN_SHIFT,
MT6359P_DA_VIO18_B_EN_ADDR, MT6359P_RG_VIO18_VOSEL_ADDR,
MT6359_RG_VIO18_VOSEL_MASK << MT6359_RG_VIO18_VOSEL_SHIFT,
960),
MT6359_LDO("ldo_vcamio", VCAMIO, volt18_voltages,
MT6359P_RG_LDO_VCAMIO_EN_ADDR,
MT6359P_RG_LDO_VCAMIO_EN_SHIFT,
MT6359P_DA_VCAMIO_B_EN_ADDR, MT6359P_RG_VCAMIO_VOSEL_ADDR,
MT6359_RG_VCAMIO_VOSEL_MASK << MT6359_RG_VCAMIO_VOSEL_SHIFT,
1290),
MT6359_REG_FIXED("ldo_vcn18", VCN18, MT6359P_RG_LDO_VCN18_EN_ADDR,
MT6359P_DA_VCN18_B_EN_ADDR, 1800000),
MT6359_REG_FIXED("ldo_vfe28", VFE28, MT6359P_RG_LDO_VFE28_EN_ADDR,
MT6359P_DA_VFE28_B_EN_ADDR, 2800000),
MT6359_LDO("ldo_vcn13", VCN13, vcn13_voltages,
MT6359P_RG_LDO_VCN13_EN_ADDR, MT6359P_RG_LDO_VCN13_EN_SHIFT,
MT6359P_DA_VCN13_B_EN_ADDR, MT6359P_RG_VCN13_VOSEL_ADDR,
MT6359_RG_VCN13_VOSEL_MASK << MT6359_RG_VCN13_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_vcn33_1_bt", VCN33_1_BT, vcn33_voltages,
MT6359P_RG_LDO_VCN33_1_EN_0_ADDR,
MT6359_RG_LDO_VCN33_1_EN_0_SHIFT,
MT6359P_DA_VCN33_1_B_EN_ADDR, MT6359P_RG_VCN33_1_VOSEL_ADDR,
MT6359_RG_VCN33_1_VOSEL_MASK <<
MT6359_RG_VCN33_1_VOSEL_SHIFT, 240),
MT6359_LDO("ldo_vcn33_1_wifi", VCN33_1_WIFI, vcn33_voltages,
MT6359P_RG_LDO_VCN33_1_EN_1_ADDR,
MT6359P_RG_LDO_VCN33_1_EN_1_SHIFT,
MT6359P_DA_VCN33_1_B_EN_ADDR, MT6359P_RG_VCN33_1_VOSEL_ADDR,
MT6359_RG_VCN33_1_VOSEL_MASK <<
MT6359_RG_VCN33_1_VOSEL_SHIFT, 240),
MT6359_REG_FIXED("ldo_vaux18", VAUX18, MT6359P_RG_LDO_VAUX18_EN_ADDR,
MT6359P_DA_VAUX18_B_EN_ADDR, 1800000),
MT6359_LDO_LINEAR("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750,
6250,
MT6359P_RG_LDO_VSRAM_OTHERS_EN_ADDR,
MT6359P_DA_VSRAM_OTHERS_B_EN_ADDR,
MT6359P_RG_LDO_VSRAM_OTHERS_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_OTHERS_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_OTHERS_VOSEL_SHIFT),
MT6359_LDO("ldo_vefuse", VEFUSE, vefuse_voltages,
MT6359P_RG_LDO_VEFUSE_EN_ADDR,
MT6359P_RG_LDO_VEFUSE_EN_SHIFT,
MT6359P_DA_VEFUSE_B_EN_ADDR, MT6359P_RG_VEFUSE_VOSEL_ADDR,
MT6359_RG_VEFUSE_VOSEL_MASK << MT6359_RG_VEFUSE_VOSEL_SHIFT,
240),
MT6359_LDO("ldo_vxo22", VXO22, vxo22_voltages,
MT6359P_RG_LDO_VXO22_EN_ADDR, MT6359P_RG_LDO_VXO22_EN_SHIFT,
MT6359P_DA_VXO22_B_EN_ADDR, MT6359P_RG_VXO22_VOSEL_ADDR,
MT6359_RG_VXO22_VOSEL_MASK << MT6359_RG_VXO22_VOSEL_SHIFT,
480),
MT6359_LDO("ldo_vrfck_1", VRFCK, vrfck_voltages_1,
MT6359P_RG_LDO_VRFCK_EN_ADDR, MT6359P_RG_LDO_VRFCK_EN_SHIFT,
MT6359P_DA_VRFCK_B_EN_ADDR, MT6359P_RG_VRFCK_VOSEL_ADDR,
MT6359_RG_VRFCK_VOSEL_MASK << MT6359_RG_VRFCK_VOSEL_SHIFT,
480),
MT6359_REG_FIXED("ldo_vbif28", VBIF28, MT6359P_RG_LDO_VBIF28_EN_ADDR,
MT6359P_DA_VBIF28_B_EN_ADDR, 2800000),
MT6359_LDO("ldo_vio28", VIO28, vio28_voltages,
MT6359P_RG_LDO_VIO28_EN_ADDR, MT6359P_RG_LDO_VIO28_EN_SHIFT,
MT6359P_DA_VIO28_B_EN_ADDR, MT6359P_RG_VIO28_VOSEL_ADDR,
MT6359_RG_VIO28_VOSEL_MASK << MT6359_RG_VIO28_VOSEL_SHIFT,
1920),
MT6359P_LDO1("ldo_vemc_1", VEMC, mt6359p_vemc_ops, vemc_voltages_1,
MT6359P_RG_LDO_VEMC_EN_ADDR, MT6359P_RG_LDO_VEMC_EN_SHIFT,
MT6359P_DA_VEMC_B_EN_ADDR,
MT6359P_RG_LDO_VEMC_VOSEL_0_ADDR,
MT6359P_RG_LDO_VEMC_VOSEL_0_MASK <<
MT6359P_RG_LDO_VEMC_VOSEL_0_SHIFT),
MT6359_LDO("ldo_vcn33_2_bt", VCN33_2_BT, vcn33_voltages,
MT6359P_RG_LDO_VCN33_2_EN_0_ADDR,
MT6359P_RG_LDO_VCN33_2_EN_0_SHIFT,
MT6359P_DA_VCN33_2_B_EN_ADDR, MT6359P_RG_VCN33_2_VOSEL_ADDR,
MT6359_RG_VCN33_2_VOSEL_MASK <<
MT6359_RG_VCN33_2_VOSEL_SHIFT, 240),
MT6359_LDO("ldo_vcn33_2_wifi", VCN33_2_WIFI, vcn33_voltages,
MT6359P_RG_LDO_VCN33_2_EN_1_ADDR,
MT6359_RG_LDO_VCN33_2_EN_1_SHIFT,
MT6359P_DA_VCN33_2_B_EN_ADDR, MT6359P_RG_VCN33_2_VOSEL_ADDR,
MT6359_RG_VCN33_2_VOSEL_MASK <<
MT6359_RG_VCN33_2_VOSEL_SHIFT, 240),
MT6359_LDO("ldo_va12", VA12, va12_voltages,
MT6359P_RG_LDO_VA12_EN_ADDR, MT6359P_RG_LDO_VA12_EN_SHIFT,
MT6359P_DA_VA12_B_EN_ADDR, MT6359P_RG_VA12_VOSEL_ADDR,
MT6359_RG_VA12_VOSEL_MASK << MT6359_RG_VA12_VOSEL_SHIFT,
960),
MT6359_LDO("ldo_va09", VA09, va09_voltages,
MT6359P_RG_LDO_VA09_EN_ADDR, MT6359P_RG_LDO_VA09_EN_SHIFT,
MT6359P_DA_VA09_B_EN_ADDR, MT6359P_RG_VA09_VOSEL_ADDR,
MT6359_RG_VA09_VOSEL_MASK << MT6359_RG_VA09_VOSEL_SHIFT,
960),
MT6359_LDO("ldo_vrf18", VRF18, vrf18_voltages,
MT6359P_RG_LDO_VRF18_EN_ADDR, MT6359P_RG_LDO_VRF18_EN_SHIFT,
MT6359P_DA_VRF18_B_EN_ADDR, MT6359P_RG_VRF18_VOSEL_ADDR,
MT6359_RG_VRF18_VOSEL_MASK << MT6359_RG_VRF18_VOSEL_SHIFT,
240),
MT6359_LDO_LINEAR("ldo_vsram_md", VSRAM_MD, 500000, 1293750, 6250,
MT6359P_RG_LDO_VSRAM_MD_EN_ADDR,
MT6359P_DA_VSRAM_MD_B_EN_ADDR,
MT6359P_RG_LDO_VSRAM_MD_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_MD_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_MD_VOSEL_SHIFT),
MT6359_LDO("ldo_vufs", VUFS, volt18_voltages,
MT6359P_RG_LDO_VUFS_EN_ADDR, MT6359P_RG_LDO_VUFS_EN_SHIFT,
MT6359P_DA_VUFS_B_EN_ADDR, MT6359P_RG_VUFS_VOSEL_ADDR,
MT6359_RG_VUFS_VOSEL_MASK << MT6359_RG_VUFS_VOSEL_SHIFT,
1920),
MT6359_LDO("ldo_vm18", VM18, volt18_voltages,
MT6359P_RG_LDO_VM18_EN_ADDR, MT6359P_RG_LDO_VM18_EN_SHIFT,
MT6359P_DA_VM18_B_EN_ADDR, MT6359P_RG_VM18_VOSEL_ADDR,
MT6359_RG_VM18_VOSEL_MASK << MT6359_RG_VM18_VOSEL_SHIFT,
1920),
MT6359_LDO("ldo_vbbck", VBBCK, vbbck_voltages,
MT6359P_RG_LDO_VBBCK_EN_ADDR, MT6359P_RG_LDO_VBBCK_EN_SHIFT,
MT6359P_DA_VBBCK_B_EN_ADDR, MT6359P_RG_VBBCK_VOSEL_ADDR,
MT6359P_RG_VBBCK_VOSEL_MASK << MT6359P_RG_VBBCK_VOSEL_SHIFT,
480),
MT6359_LDO_LINEAR("ldo_vsram_proc1", VSRAM_PROC1, 500000, 1293750, 6250,
MT6359P_RG_LDO_VSRAM_PROC1_EN_ADDR,
MT6359P_DA_VSRAM_PROC1_B_EN_ADDR,
MT6359P_RG_LDO_VSRAM_PROC1_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_PROC1_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_PROC1_VOSEL_SHIFT),
MT6359_LDO("ldo_vsim2", VSIM2, vsim2_voltages,
MT6359P_RG_LDO_VSIM2_EN_ADDR, MT6359P_RG_LDO_VSIM2_EN_SHIFT,
MT6359P_DA_VSIM2_B_EN_ADDR, MT6359P_RG_VSIM2_VOSEL_ADDR,
MT6359_RG_VSIM2_VOSEL_MASK << MT6359_RG_VSIM2_VOSEL_SHIFT,
480),
MT6359_LDO_LINEAR("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB,
500000, 1293750, 6250,
MT6359P_RG_LDO_VSRAM_OTHERS_SSHUB_EN_ADDR,
MT6359P_DA_VSRAM_OTHERS_B_EN_ADDR,
MT6359P_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_ADDR,
MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_MASK <<
MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_SHIFT),
};
static int mt6359_regulator_probe(struct platform_device *pdev)
{
struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = {};
struct regulator_dev *rdev;
struct mt6359_regulator_info *mt6359_info;
int i, hw_ver;
regmap_read(mt6397->regmap, MT6359P_HWCID, &hw_ver);
if (hw_ver >= MT6359P_CHIP_VER)
mt6359_info = mt6359p_regulators;
else
mt6359_info = mt6359_regulators;
config.dev = mt6397->dev;
config.regmap = mt6397->regmap;
for (i = 0; i < MT6359_MAX_REGULATOR; i++, mt6359_info++) {
config.driver_data = mt6359_info;
rdev = devm_regulator_register(&pdev->dev, &mt6359_info->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register %s\n", mt6359_info->desc.name);
return PTR_ERR(rdev);
}
}
return 0;
}
static const struct platform_device_id mt6359_platform_ids[] = {
{"mt6359-regulator", 0},
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(platform, mt6359_platform_ids);
static struct platform_driver mt6359_regulator_driver = {
.driver = {
.name = "mt6359-regulator",
},
.probe = mt6359_regulator_probe,
.id_table = mt6359_platform_ids,
};
module_platform_driver(mt6359_regulator_driver);
MODULE_AUTHOR("Wen Su <wen.su@mediatek.com>");
MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6359 PMIC");
MODULE_LICENSE("GPL");

View File

@ -21,6 +21,62 @@ static const char *const regulator_states[PM_SUSPEND_MAX + 1] = {
[PM_SUSPEND_MAX] = "regulator-state-disk",
};
static void fill_limit(int *limit, int val)
{
if (val)
if (val == 1)
*limit = REGULATOR_NOTIF_LIMIT_ENABLE;
else
*limit = val;
else
*limit = REGULATOR_NOTIF_LIMIT_DISABLE;
}
static void of_get_regulator_prot_limits(struct device_node *np,
struct regulation_constraints *constraints)
{
u32 pval;
int i;
static const char *const props[] = {
"regulator-oc-%s-microamp",
"regulator-ov-%s-microvolt",
"regulator-temp-%s-kelvin",
"regulator-uv-%s-microvolt",
};
struct notification_limit *limits[] = {
&constraints->over_curr_limits,
&constraints->over_voltage_limits,
&constraints->temp_limits,
&constraints->under_voltage_limits,
};
bool set[4] = {0};
/* Protection limits: */
for (i = 0; i < ARRAY_SIZE(props); i++) {
char prop[255];
bool found;
int j;
static const char *const lvl[] = {
"protection", "error", "warn"
};
int *l[] = {
&limits[i]->prot, &limits[i]->err, &limits[i]->warn,
};
for (j = 0; j < ARRAY_SIZE(lvl); j++) {
snprintf(prop, 255, props[i], lvl[j]);
found = !of_property_read_u32(np, prop, &pval);
if (found)
fill_limit(l[j], pval);
set[i] |= found;
}
}
constraints->over_current_detection = set[0];
constraints->over_voltage_detection = set[1];
constraints->over_temp_detection = set[2];
constraints->under_voltage_detection = set[3];
}
static int of_get_regulation_constraints(struct device *dev,
struct device_node *np,
struct regulator_init_data **init_data,
@ -188,6 +244,8 @@ static int of_get_regulation_constraints(struct device *dev,
constraints->over_current_protection = of_property_read_bool(np,
"regulator-over-current-protection");
of_get_regulator_prot_limits(np, constraints);
for (i = 0; i < ARRAY_SIZE(regulator_states); i++) {
switch (i) {
case PM_SUSPEND_MEM:

View File

@ -65,32 +65,9 @@ static const struct regmap_config pca9450_regmap_config = {
* 10: 25mV/4usec
* 11: 25mV/8usec
*/
static int pca9450_dvs_set_ramp_delay(struct regulator_dev *rdev,
int ramp_delay)
{
int id = rdev_get_id(rdev);
unsigned int ramp_value;
switch (ramp_delay) {
case 1 ... 3125:
ramp_value = BUCK1_RAMP_3P125MV;
break;
case 3126 ... 6250:
ramp_value = BUCK1_RAMP_6P25MV;
break;
case 6251 ... 12500:
ramp_value = BUCK1_RAMP_12P5MV;
break;
case 12501 ... 25000:
ramp_value = BUCK1_RAMP_25MV;
break;
default:
ramp_value = BUCK1_RAMP_25MV;
}
return regmap_update_bits(rdev->regmap, PCA9450_REG_BUCK1CTRL + id * 3,
BUCK1_RAMP_MASK, ramp_value << 6);
}
static const unsigned int pca9450_dvs_buck_ramp_table[] = {
25000, 12500, 6250, 3125
};
static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
.enable = regulator_enable_regmap,
@ -100,7 +77,7 @@ static const struct regulator_ops pca9450_dvs_buck_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,
.set_ramp_delay = pca9450_dvs_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
static const struct regulator_ops pca9450_buck_regulator_ops = {
@ -251,6 +228,10 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
.vsel_mask = BUCK1OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK1CTRL,
.enable_mask = BUCK1_ENMODE_MASK,
.ramp_reg = PCA9450_REG_BUCK1CTRL,
.ramp_mask = BUCK1_RAMP_MASK,
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},
@ -276,6 +257,10 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
.vsel_mask = BUCK2OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK2CTRL,
.enable_mask = BUCK1_ENMODE_MASK,
.ramp_reg = PCA9450_REG_BUCK2CTRL,
.ramp_mask = BUCK2_RAMP_MASK,
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},
@ -301,6 +286,10 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
.vsel_mask = BUCK3OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK3CTRL,
.enable_mask = BUCK3_ENMODE_MASK,
.ramp_reg = PCA9450_REG_BUCK3CTRL,
.ramp_mask = BUCK3_RAMP_MASK,
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},
@ -477,6 +466,10 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
.vsel_mask = BUCK1OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK1CTRL,
.enable_mask = BUCK1_ENMODE_MASK,
.ramp_reg = PCA9450_REG_BUCK1CTRL,
.ramp_mask = BUCK1_RAMP_MASK,
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},
@ -502,6 +495,10 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
.vsel_mask = BUCK2OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK2CTRL,
.enable_mask = BUCK1_ENMODE_MASK,
.ramp_reg = PCA9450_REG_BUCK2CTRL,
.ramp_mask = BUCK2_RAMP_MASK,
.ramp_delay_table = pca9450_dvs_buck_ramp_table,
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},

View File

@ -307,13 +307,21 @@ end:
return IRQ_HANDLED;
}
static int qcom_labibb_set_ocp(struct regulator_dev *rdev)
static int qcom_labibb_set_ocp(struct regulator_dev *rdev, int lim,
int severity, bool enable)
{
struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
char *ocp_irq_name;
u32 irq_flags = IRQF_ONESHOT;
int irq_trig_low, ret;
/*
* labibb supports only protection - and does not support setting
* limit. Furthermore, we don't support disabling protection.
*/
if (lim || severity != REGULATOR_SEVERITY_PROT || !enable)
return -EINVAL;
/* If there is no OCP interrupt, there's nothing to set */
if (vreg->ocp_irq <= 0)
return -EINVAL;

View File

@ -811,12 +811,12 @@ static const struct rpmh_vreg_init_data pm8998_vreg_data[] = {
RPMH_VREG("ldo28", "ldo%s28", &pmic4_pldo, "vdd-l16-l28"),
RPMH_VREG("lvs1", "vs%s1", &pmic4_lvs, "vin-lvs-1-2"),
RPMH_VREG("lvs2", "vs%s2", &pmic4_lvs, "vin-lvs-1-2"),
{},
{}
};
static const struct rpmh_vreg_init_data pmi8998_vreg_data[] = {
RPMH_VREG("bob", "bob%s1", &pmic4_bob, "vdd-bob"),
{},
{}
};
static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
@ -824,7 +824,7 @@ static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"),
RPMH_VREG("smps3", "smp%s3", &pmic4_ftsmps426, "vdd-s3"),
RPMH_VREG("smps4", "smp%s4", &pmic4_ftsmps426, "vdd-s4"),
{},
{}
};
static const struct rpmh_vreg_init_data pm8150_vreg_data[] = {
@ -856,7 +856,7 @@ static const struct rpmh_vreg_init_data pm8150_vreg_data[] = {
RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l13-l16-l17"),
RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l13-l16-l17"),
RPMH_VREG("ldo18", "ldo%s18", &pmic5_nldo, "vdd-l3-l4-l5-l18"),
{},
{}
};
static const struct rpmh_vreg_init_data pm8150l_vreg_data[] = {
@ -880,7 +880,39 @@ static const struct rpmh_vreg_init_data pm8150l_vreg_data[] = {
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 pmm8155au_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_lv, "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-l16-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-l16-l17"),
RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l13-l16-l17"),
RPMH_VREG("ldo18", "ldo%s18", &pmic5_nldo, "vdd-l3-l4-l5-l18"),
{}
};
static const struct rpmh_vreg_init_data pm8350_vreg_data[] = {
@ -906,7 +938,7 @@ static const struct rpmh_vreg_init_data pm8350_vreg_data[] = {
RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l8"),
RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l6-l9-l10"),
RPMH_VREG("ldo10", "ldo%s10", &pmic5_nldo, "vdd-l6-l9-l10"),
{},
{}
};
static const struct rpmh_vreg_init_data pm8350c_vreg_data[] = {
@ -934,7 +966,7 @@ static const struct rpmh_vreg_init_data pm8350c_vreg_data[] = {
RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo_lv, "vdd-l1-l12"),
RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"),
RPMH_VREG("bob", "bob%s1", &pmic5_bob, "vdd-bob"),
{},
{}
};
static const struct rpmh_vreg_init_data pm8009_vreg_data[] = {
@ -947,7 +979,7 @@ static const struct rpmh_vreg_init_data pm8009_vreg_data[] = {
RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6"),
RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6"),
RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo_lv, "vdd-l7"),
{},
{}
};
static const struct rpmh_vreg_init_data pm8009_1_vreg_data[] = {
@ -960,7 +992,7 @@ static const struct rpmh_vreg_init_data pm8009_1_vreg_data[] = {
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 const struct rpmh_vreg_init_data pm6150_vreg_data[] = {
@ -988,7 +1020,7 @@ static const struct rpmh_vreg_init_data pm6150_vreg_data[] = {
RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"),
RPMH_VREG("ldo18", "ldo%s18", &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"),
RPMH_VREG("ldo19", "ldo%s19", &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"),
{},
{}
};
static const struct rpmh_vreg_init_data pm6150l_vreg_data[] = {
@ -1012,7 +1044,7 @@ static const struct rpmh_vreg_init_data pm6150l_vreg_data[] = {
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 pmx55_vreg_data[] = {
@ -1039,7 +1071,7 @@ static const struct rpmh_vreg_init_data pmx55_vreg_data[] = {
RPMH_VREG("ldo14", "ldo%s14", &pmic5_nldo, "vdd-l14"),
RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo, "vdd-l15"),
RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l16"),
{},
{}
};
static const struct rpmh_vreg_init_data pm7325_vreg_data[] = {
@ -1070,6 +1102,7 @@ static const struct rpmh_vreg_init_data pm7325_vreg_data[] = {
RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
RPMH_VREG("ldo18", "ldo%s18", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
RPMH_VREG("ldo19", "ldo%s19", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
{}
};
static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = {
@ -1083,6 +1116,7 @@ static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = {
RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l5-l6"),
RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l5-l6"),
RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-bob"),
{}
};
static int rpmh_regulator_probe(struct platform_device *pdev)
@ -1175,6 +1209,10 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
.compatible = "qcom,pmc8180c-rpmh-regulators",
.data = pm8150l_vreg_data,
},
{
.compatible = "qcom,pmm8155au-rpmh-regulators",
.data = pmm8155au_vreg_data,
},
{
.compatible = "qcom,pmx55-rpmh-regulators",
.data = pmx55_vreg_data,

View File

@ -251,6 +251,50 @@ static const struct regulator_desc pma8084_switch = {
.ops = &rpm_switch_ops,
};
static const struct regulator_desc pm8226_hfsmps = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500),
REGULATOR_LINEAR_RANGE(1575000, 96, 158, 25000),
},
.n_linear_ranges = 2,
.n_voltages = 159,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8226_ftsmps = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000),
REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000),
},
.n_linear_ranges = 2,
.n_voltages = 262,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8226_pldo = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000),
REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000),
},
.n_linear_ranges = 3,
.n_voltages = 164,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8226_nldo = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
},
.n_linear_ranges = 1,
.n_voltages = 64,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8226_switch = {
.ops = &rpm_switch_ops,
};
static const struct regulator_desc pm8x41_hfsmps = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500),
@ -405,8 +449,8 @@ static const struct regulator_desc pm8950_pldo = {
static const struct regulator_desc pm8953_lnldo = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(1380000, 8, 15, 120000),
REGULATOR_LINEAR_RANGE(690000, 0, 7, 60000),
REGULATOR_LINEAR_RANGE(1380000, 8, 15, 120000),
},
.n_linear_ranges = 2,
.n_voltages = 16,
@ -746,6 +790,44 @@ static const struct rpm_regulator_data rpm_pm8916_regulators[] = {
{}
};
static const struct rpm_regulator_data rpm_pm8226_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pm8226_hfsmps, "vdd_s1" },
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pm8226_ftsmps, "vdd_s2" },
{ "s3", QCOM_SMD_RPM_SMPA, 3, &pm8226_hfsmps, "vdd_s3" },
{ "s4", QCOM_SMD_RPM_SMPA, 4, &pm8226_hfsmps, "vdd_s4" },
{ "s5", QCOM_SMD_RPM_SMPA, 5, &pm8226_hfsmps, "vdd_s5" },
{ "l1", QCOM_SMD_RPM_LDOA, 1, &pm8226_nldo, "vdd_l1_l2_l4_l5" },
{ "l2", QCOM_SMD_RPM_LDOA, 2, &pm8226_nldo, "vdd_l1_l2_l4_l5" },
{ "l3", QCOM_SMD_RPM_LDOA, 3, &pm8226_nldo, "vdd_l3_l24_l26" },
{ "l4", QCOM_SMD_RPM_LDOA, 4, &pm8226_nldo, "vdd_l1_l2_l4_l5" },
{ "l5", QCOM_SMD_RPM_LDOA, 5, &pm8226_nldo, "vdd_l1_l2_l4_l5" },
{ "l6", QCOM_SMD_RPM_LDOA, 6, &pm8226_pldo, "vdd_l6_l7_l8_l9_l27" },
{ "l7", QCOM_SMD_RPM_LDOA, 7, &pm8226_pldo, "vdd_l6_l7_l8_l9_l27" },
{ "l8", QCOM_SMD_RPM_LDOA, 8, &pm8226_pldo, "vdd_l6_l7_l8_l9_l27" },
{ "l9", QCOM_SMD_RPM_LDOA, 9, &pm8226_pldo, "vdd_l6_l7_l8_l9_l27" },
{ "l10", QCOM_SMD_RPM_LDOA, 10, &pm8226_pldo, "vdd_l10_l11_l13" },
{ "l11", QCOM_SMD_RPM_LDOA, 11, &pm8226_pldo, "vdd_l10_l11_l13" },
{ "l12", QCOM_SMD_RPM_LDOA, 12, &pm8226_pldo, "vdd_l12_l14" },
{ "l13", QCOM_SMD_RPM_LDOA, 13, &pm8226_pldo, "vdd_l10_l11_l13" },
{ "l14", QCOM_SMD_RPM_LDOA, 14, &pm8226_pldo, "vdd_l12_l14" },
{ "l15", QCOM_SMD_RPM_LDOA, 15, &pm8226_pldo, "vdd_l15_l16_l17_l18" },
{ "l16", QCOM_SMD_RPM_LDOA, 16, &pm8226_pldo, "vdd_l15_l16_l17_l18" },
{ "l17", QCOM_SMD_RPM_LDOA, 17, &pm8226_pldo, "vdd_l15_l16_l17_l18" },
{ "l18", QCOM_SMD_RPM_LDOA, 18, &pm8226_pldo, "vdd_l15_l16_l17_l18" },
{ "l19", QCOM_SMD_RPM_LDOA, 19, &pm8226_pldo, "vdd_l19_l20_l21_l22_l23_l28" },
{ "l20", QCOM_SMD_RPM_LDOA, 20, &pm8226_pldo, "vdd_l19_l20_l21_l22_l23_l28" },
{ "l21", QCOM_SMD_RPM_LDOA, 21, &pm8226_pldo, "vdd_l19_l20_l21_l22_l23_l28" },
{ "l22", QCOM_SMD_RPM_LDOA, 22, &pm8226_pldo, "vdd_l19_l20_l21_l22_l23_l28" },
{ "l23", QCOM_SMD_RPM_LDOA, 23, &pm8226_pldo, "vdd_l19_l20_l21_l22_l23_l28" },
{ "l24", QCOM_SMD_RPM_LDOA, 24, &pm8226_nldo, "vdd_l3_l24_l26" },
{ "l25", QCOM_SMD_RPM_LDOA, 25, &pm8226_pldo, "vdd_l25" },
{ "l26", QCOM_SMD_RPM_LDOA, 26, &pm8226_nldo, "vdd_l3_l24_l26" },
{ "l27", QCOM_SMD_RPM_LDOA, 27, &pm8226_pldo, "vdd_l6_l7_l8_l9_l27" },
{ "l28", QCOM_SMD_RPM_LDOA, 28, &pm8226_pldo, "vdd_l19_l20_l21_l22_l23_l28" },
{ "lvs1", QCOM_SMD_RPM_VSA, 1, &pm8226_switch, "vdd_lvs1" },
{}
};
static const struct rpm_regulator_data rpm_pm8941_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pm8x41_hfsmps, "vdd_s1" },
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pm8x41_hfsmps, "vdd_s2" },
@ -1092,6 +1174,7 @@ static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-mp5496-regulators", .data = &rpm_mp5496_regulators },
{ .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators },
{ .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators },
{ .compatible = "qcom,rpm-pm8226-regulators", .data = &rpm_pm8226_regulators },
{ .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators },
{ .compatible = "qcom,rpm-pm8950-regulators", .data = &rpm_pm8950_regulators },
{ .compatible = "qcom,rpm-pm8953-regulators", .data = &rpm_pm8953_regulators },

View File

@ -595,11 +595,15 @@ static int spmi_regulator_vs_enable(struct regulator_dev *rdev)
return regulator_enable_regmap(rdev);
}
static int spmi_regulator_vs_ocp(struct regulator_dev *rdev)
static int spmi_regulator_vs_ocp(struct regulator_dev *rdev, int lim_uA,
int severity, bool enable)
{
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
u8 reg = SPMI_VS_OCP_OVERRIDE;
if (lim_uA || !enable || severity != REGULATOR_SEVERITY_PROT)
return -EINVAL;
return spmi_vreg_write(vreg, SPMI_VS_REG_OCP, &reg, 1);
}

View File

@ -16,13 +16,21 @@
#define CMD_OTG 0x40
#define OTG_EN BIT(0)
#define OTG_CURRENT_LIMIT_CFG 0x52
#define OTG_CURRENT_LIMIT_MASK GENMASK(2, 0)
#define OTG_CFG 0x53
#define OTG_EN_SRC_CFG BIT(1)
static const unsigned int curr_table[] = {
500000, 1000000, 1500000, 2000000, 2500000, 3000000,
};
static const struct regulator_ops qcom_usb_vbus_reg_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
};
static struct regulator_desc qcom_usb_vbus_rdesc = {
@ -30,6 +38,8 @@ static struct regulator_desc qcom_usb_vbus_rdesc = {
.ops = &qcom_usb_vbus_reg_ops,
.owner = THIS_MODULE,
.type = REGULATOR_VOLTAGE,
.curr_table = curr_table,
.n_current_limits = ARRAY_SIZE(curr_table),
};
static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
@ -61,6 +71,8 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG;
qcom_usb_vbus_rdesc.enable_mask = OTG_EN;
qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG;
qcom_usb_vbus_rdesc.csel_mask = OTG_CURRENT_LIMIT_MASK;
config.dev = dev;
config.init_data = init_data;
config.of_node = dev->of_node;

View File

@ -158,13 +158,6 @@ struct rk808_regulator_data {
struct gpio_desc *dvs_gpio[2];
};
static const int rk808_buck_config_regs[] = {
RK808_BUCK1_CONFIG_REG,
RK808_BUCK2_CONFIG_REG,
RK808_BUCK3_CONFIG_REG,
RK808_BUCK4_CONFIG_REG,
};
static const struct linear_range rk808_ldo3_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000),
REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
@ -215,6 +208,15 @@ static const struct linear_range rk817_buck3_voltage_ranges[] = {
RK817_BUCK3_SEL_CNT, RK817_BUCK1_STP1),
};
static const unsigned int rk808_buck1_2_ramp_table[] = {
2000, 4000, 6000, 10000
};
/* RK817 RK809 */
static const unsigned int rk817_buck1_4_ramp_table[] = {
3000, 6300, 12500, 25000
};
static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
{
struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
@ -340,62 +342,6 @@ static int rk808_buck1_2_set_voltage_time_sel(struct regulator_dev *rdev,
return regulator_set_voltage_time_sel(rdev, old_selector, new_selector);
}
static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_value = RK808_RAMP_RATE_10MV_PER_US;
unsigned int reg = rk808_buck_config_regs[rdev_get_id(rdev)];
switch (ramp_delay) {
case 1 ... 2000:
ramp_value = RK808_RAMP_RATE_2MV_PER_US;
break;
case 2001 ... 4000:
ramp_value = RK808_RAMP_RATE_4MV_PER_US;
break;
case 4001 ... 6000:
ramp_value = RK808_RAMP_RATE_6MV_PER_US;
break;
case 6001 ... 10000:
break;
default:
pr_warn("%s ramp_delay: %d not supported, setting 10000\n",
rdev->desc->name, ramp_delay);
}
return regmap_update_bits(rdev->regmap, reg,
RK808_RAMP_RATE_MASK, ramp_value);
}
/*
* RK817 RK809
*/
static int rk817_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_value = RK817_RAMP_RATE_25MV_PER_US;
unsigned int reg = RK817_BUCK_CONFIG_REG(rdev_get_id(rdev));
switch (ramp_delay) {
case 0 ... 3000:
ramp_value = RK817_RAMP_RATE_3MV_PER_US;
break;
case 3001 ... 6300:
ramp_value = RK817_RAMP_RATE_6_3MV_PER_US;
break;
case 6301 ... 12500:
ramp_value = RK817_RAMP_RATE_12_5MV_PER_US;
break;
case 12501 ... 25000:
break;
default:
dev_warn(&rdev->dev,
"%s ramp_delay: %d not supported, setting 25000\n",
rdev->desc->name, ramp_delay);
}
return regmap_update_bits(rdev->regmap, reg,
RK817_RAMP_RATE_MASK, ramp_value);
}
static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
{
unsigned int reg;
@ -625,7 +571,7 @@ static const struct regulator_ops rk808_buck1_2_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_ramp_delay = rk808_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_voltage = rk808_set_suspend_voltage,
.set_suspend_enable = rk808_set_suspend_enable,
.set_suspend_disable = rk808_set_suspend_disable,
@ -722,7 +668,7 @@ static const struct regulator_ops rk817_buck_ops_range = {
.set_mode = rk8xx_set_mode,
.get_mode = rk8xx_get_mode,
.set_suspend_mode = rk8xx_set_suspend_mode,
.set_ramp_delay = rk817_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_voltage = rk808_set_suspend_voltage_range,
.set_suspend_enable = rk817_set_suspend_enable,
.set_suspend_disable = rk817_set_suspend_disable,
@ -814,6 +760,10 @@ static const struct regulator_desc rk808_reg[] = {
.vsel_mask = RK808_BUCK_VSEL_MASK,
.enable_reg = RK808_DCDC_EN_REG,
.enable_mask = BIT(0),
.ramp_reg = RK808_BUCK1_CONFIG_REG,
.ramp_mask = RK808_RAMP_RATE_MASK,
.ramp_delay_table = rk808_buck1_2_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk808_buck1_2_ramp_table),
.owner = THIS_MODULE,
}, {
.name = "DCDC_REG2",
@ -830,6 +780,10 @@ static const struct regulator_desc rk808_reg[] = {
.vsel_mask = RK808_BUCK_VSEL_MASK,
.enable_reg = RK808_DCDC_EN_REG,
.enable_mask = BIT(1),
.ramp_reg = RK808_BUCK2_CONFIG_REG,
.ramp_mask = RK808_RAMP_RATE_MASK,
.ramp_delay_table = rk808_buck1_2_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk808_buck1_2_ramp_table),
.owner = THIS_MODULE,
}, {
.name = "DCDC_REG3",
@ -910,6 +864,10 @@ static const struct regulator_desc rk809_reg[] = {
.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
.ramp_reg = RK817_BUCK_CONFIG_REG(RK817_ID_DCDC1),
.ramp_mask = RK817_RAMP_RATE_MASK,
.ramp_delay_table = rk817_buck1_4_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
}, {
@ -929,6 +887,10 @@ static const struct regulator_desc rk809_reg[] = {
.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
.ramp_reg = RK817_BUCK_CONFIG_REG(RK817_ID_DCDC2),
.ramp_mask = RK817_RAMP_RATE_MASK,
.ramp_delay_table = rk817_buck1_4_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
}, {
@ -948,6 +910,10 @@ static const struct regulator_desc rk809_reg[] = {
.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
.ramp_reg = RK817_BUCK_CONFIG_REG(RK817_ID_DCDC3),
.ramp_mask = RK817_RAMP_RATE_MASK,
.ramp_delay_table = rk817_buck1_4_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
}, {
@ -967,6 +933,10 @@ static const struct regulator_desc rk809_reg[] = {
.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
.ramp_reg = RK817_BUCK_CONFIG_REG(RK817_ID_DCDC4),
.ramp_mask = RK817_RAMP_RATE_MASK,
.ramp_delay_table = rk817_buck1_4_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
},
@ -1052,6 +1022,10 @@ static const struct regulator_desc rk817_reg[] = {
.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
.ramp_reg = RK817_BUCK_CONFIG_REG(RK817_ID_DCDC1),
.ramp_mask = RK817_RAMP_RATE_MASK,
.ramp_delay_table = rk817_buck1_4_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
}, {
@ -1071,6 +1045,10 @@ static const struct regulator_desc rk817_reg[] = {
.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
.ramp_reg = RK817_BUCK_CONFIG_REG(RK817_ID_DCDC2),
.ramp_mask = RK817_RAMP_RATE_MASK,
.ramp_delay_table = rk817_buck1_4_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
}, {
@ -1090,6 +1068,10 @@ static const struct regulator_desc rk817_reg[] = {
.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
.ramp_reg = RK817_BUCK_CONFIG_REG(RK817_ID_DCDC3),
.ramp_mask = RK817_RAMP_RATE_MASK,
.ramp_delay_table = rk817_buck1_4_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
}, {
@ -1109,6 +1091,10 @@ static const struct regulator_desc rk817_reg[] = {
.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
.ramp_reg = RK817_BUCK_CONFIG_REG(RK817_ID_DCDC4),
.ramp_mask = RK817_RAMP_RATE_MASK,
.ramp_delay_table = rk817_buck1_4_ramp_table,
.n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
},

View File

@ -108,6 +108,7 @@ static const struct regulator_desc rt4831_regulator_descs[] = {
.bypass_reg = RT4831_REG_DSVEN,
.bypass_val_on = DSV_MODE_BYPASS,
.bypass_val_off = DSV_MODE_NORMAL,
.owner = THIS_MODULE,
},
{
.name = "DSVP",
@ -125,6 +126,7 @@ static const struct regulator_desc rt4831_regulator_descs[] = {
.enable_mask = RT4831_POSEN_MASK,
.active_discharge_reg = RT4831_REG_DSVEN,
.active_discharge_mask = RT4831_POSADEN_MASK,
.owner = THIS_MODULE,
},
{
.name = "DSVN",
@ -142,6 +144,7 @@ static const struct regulator_desc rt4831_regulator_descs[] = {
.enable_mask = RT4831_NEGEN_MASK,
.active_discharge_reg = RT4831_REG_DSVEN,
.active_discharge_mask = RT4831_NEGADEN_MASK,
.owner = THIS_MODULE,
}
};

View File

@ -0,0 +1,319 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#define RT6160_MODE_AUTO 0
#define RT6160_MODE_FPWM 1
#define RT6160_REG_CNTL 0x01
#define RT6160_REG_STATUS 0x02
#define RT6160_REG_DEVID 0x03
#define RT6160_REG_VSELL 0x04
#define RT6160_REG_VSELH 0x05
#define RT6160_NUM_REGS (RT6160_REG_VSELH + 1)
#define RT6160_FPWM_MASK BIT(3)
#define RT6160_RAMPRATE_MASK GENMASK(1, 0)
#define RT6160_VID_MASK GENMASK(7, 4)
#define RT6160_VSEL_MASK GENMASK(6, 0)
#define RT6160_HDSTAT_MASK BIT(4)
#define RT6160_UVSTAT_MASK BIT(3)
#define RT6160_OCSTAT_MASK BIT(2)
#define RT6160_TSDSTAT_MASK BIT(1)
#define RT6160_PGSTAT_MASK BIT(0)
#define RT6160_VENDOR_ID 0xA0
#define RT6160_VOUT_MINUV 2025000
#define RT6160_VOUT_MAXUV 5200000
#define RT6160_VOUT_STPUV 25000
#define RT6160_N_VOUTS ((RT6160_VOUT_MAXUV - RT6160_VOUT_MINUV) / RT6160_VOUT_STPUV + 1)
#define RT6160_I2CRDY_TIMEUS 100
struct rt6160_priv {
struct regulator_desc desc;
struct gpio_desc *enable_gpio;
struct regmap *regmap;
bool enable_state;
};
static const unsigned int rt6160_ramp_tables[] = {
1000, 2500, 5000, 10000
};
static int rt6160_enable(struct regulator_dev *rdev)
{
struct rt6160_priv *priv = rdev_get_drvdata(rdev);
if (!priv->enable_gpio)
return 0;
gpiod_set_value_cansleep(priv->enable_gpio, 1);
priv->enable_state = true;
usleep_range(RT6160_I2CRDY_TIMEUS, RT6160_I2CRDY_TIMEUS + 100);
regcache_cache_only(priv->regmap, false);
return regcache_sync(priv->regmap);
}
static int rt6160_disable(struct regulator_dev *rdev)
{
struct rt6160_priv *priv = rdev_get_drvdata(rdev);
if (!priv->enable_gpio)
return -EINVAL;
/* Mark regcache as dirty and cache only before HW disabled */
regcache_cache_only(priv->regmap, true);
regcache_mark_dirty(priv->regmap);
priv->enable_state = false;
gpiod_set_value_cansleep(priv->enable_gpio, 0);
return 0;
}
static int rt6160_is_enabled(struct regulator_dev *rdev)
{
struct rt6160_priv *priv = rdev_get_drvdata(rdev);
return priv->enable_state ? 1 : 0;
}
static int rt6160_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
struct regmap *regmap = rdev_get_regmap(rdev);
unsigned int mode_val;
switch (mode) {
case REGULATOR_MODE_FAST:
mode_val = RT6160_FPWM_MASK;
break;
case REGULATOR_MODE_NORMAL:
mode_val = 0;
break;
default:
dev_err(&rdev->dev, "mode not supported\n");
return -EINVAL;
}
return regmap_update_bits(regmap, RT6160_REG_CNTL, RT6160_FPWM_MASK, mode_val);
}
static unsigned int rt6160_get_mode(struct regulator_dev *rdev)
{
struct regmap *regmap = rdev_get_regmap(rdev);
unsigned int val;
int ret;
ret = regmap_read(regmap, RT6160_REG_CNTL, &val);
if (ret)
return ret;
if (val & RT6160_FPWM_MASK)
return REGULATOR_MODE_FAST;
return REGULATOR_MODE_NORMAL;
}
static int rt6160_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{
struct regmap *regmap = rdev_get_regmap(rdev);
unsigned int suspend_vsel_reg;
int vsel;
vsel = regulator_map_voltage_linear(rdev, uV, uV);
if (vsel < 0)
return vsel;
if (rdev->desc->vsel_reg == RT6160_REG_VSELL)
suspend_vsel_reg = RT6160_REG_VSELH;
else
suspend_vsel_reg = RT6160_REG_VSELL;
return regmap_update_bits(regmap, suspend_vsel_reg,
RT6160_VSEL_MASK, vsel);
}
static int rt6160_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
{
struct regmap *regmap = rdev_get_regmap(rdev);
unsigned int val, events = 0;
int ret;
ret = regmap_read(regmap, RT6160_REG_STATUS, &val);
if (ret)
return ret;
if (val & (RT6160_HDSTAT_MASK | RT6160_TSDSTAT_MASK))
events |= REGULATOR_ERROR_OVER_TEMP;
if (val & RT6160_UVSTAT_MASK)
events |= REGULATOR_ERROR_UNDER_VOLTAGE;
if (val & RT6160_OCSTAT_MASK)
events |= REGULATOR_ERROR_OVER_CURRENT;
if (val & RT6160_PGSTAT_MASK)
events |= REGULATOR_ERROR_FAIL;
*flags = events;
return 0;
}
static const struct regulator_ops rt6160_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.enable = rt6160_enable,
.disable = rt6160_disable,
.is_enabled = rt6160_is_enabled,
.set_mode = rt6160_set_mode,
.get_mode = rt6160_get_mode,
.set_suspend_voltage = rt6160_set_suspend_voltage,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.get_error_flags = rt6160_get_error_flags,
};
static unsigned int rt6160_of_map_mode(unsigned int mode)
{
switch (mode) {
case RT6160_MODE_FPWM:
return REGULATOR_MODE_FAST;
case RT6160_MODE_AUTO:
return REGULATOR_MODE_NORMAL;
}
return REGULATOR_MODE_INVALID;
}
static bool rt6160_is_accessible_reg(struct device *dev, unsigned int reg)
{
if (reg >= RT6160_REG_CNTL && reg <= RT6160_REG_VSELH)
return true;
return false;
}
static bool rt6160_is_volatile_reg(struct device *dev, unsigned int reg)
{
if (reg == RT6160_REG_STATUS)
return true;
return false;
}
static const struct regmap_config rt6160_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = RT6160_REG_VSELH,
.num_reg_defaults_raw = RT6160_NUM_REGS,
.cache_type = REGCACHE_FLAT,
.writeable_reg = rt6160_is_accessible_reg,
.readable_reg = rt6160_is_accessible_reg,
.volatile_reg = rt6160_is_volatile_reg,
};
static int rt6160_probe(struct i2c_client *i2c)
{
struct rt6160_priv *priv;
struct regulator_config regulator_cfg = {};
struct regulator_dev *rdev;
bool vsel_active_low;
unsigned int devid;
int ret;
priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
vsel_active_low =
device_property_present(&i2c->dev, "richtek,vsel-active-low");
priv->enable_gpio = devm_gpiod_get_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
if (IS_ERR(priv->enable_gpio)) {
dev_err(&i2c->dev, "Failed to get 'enable' gpio\n");
return PTR_ERR(priv->enable_gpio);
}
priv->enable_state = true;
usleep_range(RT6160_I2CRDY_TIMEUS, RT6160_I2CRDY_TIMEUS + 100);
priv->regmap = devm_regmap_init_i2c(i2c, &rt6160_regmap_config);
if (IS_ERR(priv->regmap)) {
ret = PTR_ERR(priv->regmap);
dev_err(&i2c->dev, "Failed to init regmap (%d)\n", ret);
return ret;
}
ret = regmap_read(priv->regmap, RT6160_REG_DEVID, &devid);
if (ret)
return ret;
if ((devid & RT6160_VID_MASK) != RT6160_VENDOR_ID) {
dev_err(&i2c->dev, "VID not correct [0x%02x]\n", devid);
return -ENODEV;
}
priv->desc.name = "rt6160-buckboost";
priv->desc.type = REGULATOR_VOLTAGE;
priv->desc.owner = THIS_MODULE;
priv->desc.min_uV = RT6160_VOUT_MINUV;
priv->desc.uV_step = RT6160_VOUT_STPUV;
if (vsel_active_low)
priv->desc.vsel_reg = RT6160_REG_VSELL;
else
priv->desc.vsel_reg = RT6160_REG_VSELH;
priv->desc.vsel_mask = RT6160_VSEL_MASK;
priv->desc.n_voltages = RT6160_N_VOUTS;
priv->desc.ramp_reg = RT6160_REG_CNTL;
priv->desc.ramp_mask = RT6160_RAMPRATE_MASK;
priv->desc.ramp_delay_table = rt6160_ramp_tables;
priv->desc.n_ramp_values = ARRAY_SIZE(rt6160_ramp_tables);
priv->desc.of_map_mode = rt6160_of_map_mode;
priv->desc.ops = &rt6160_regulator_ops;
regulator_cfg.dev = &i2c->dev;
regulator_cfg.of_node = i2c->dev.of_node;
regulator_cfg.regmap = priv->regmap;
regulator_cfg.driver_data = priv;
regulator_cfg.init_data = of_get_regulator_init_data(&i2c->dev, i2c->dev.of_node,
&priv->desc);
rdev = devm_regulator_register(&i2c->dev, &priv->desc, &regulator_cfg);
if (IS_ERR(rdev)) {
dev_err(&i2c->dev, "Failed to register regulator\n");
return PTR_ERR(rdev);
}
return 0;
}
static const struct of_device_id __maybe_unused rt6160_of_match_table[] = {
{ .compatible = "richtek,rt6160", },
{}
};
MODULE_DEVICE_TABLE(of, rt6160_of_match_table);
static struct i2c_driver rt6160_driver = {
.driver = {
.name = "rt6160",
.of_match_table = rt6160_of_match_table,
},
.probe_new = rt6160_probe,
};
module_i2c_driver(rt6160_driver);
MODULE_DESCRIPTION("Richtek RT6160 voltage regulator driver");
MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,254 @@
// SPDX-License-Identifier: GPL-2.0+
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#define RT6245_VIRT_OCLIMIT 0x00
#define RT6245_VIRT_OTLEVEL 0x01
#define RT6245_VIRT_PGDLYTIME 0x02
#define RT6245_VIRT_SLEWRATE 0x03
#define RT6245_VIRT_SWFREQ 0x04
#define RT6245_VIRT_VOUT 0x05
#define RT6245_VOUT_MASK GENMASK(6, 0)
#define RT6245_SLEW_MASK GENMASK(2, 0)
#define RT6245_CHKSUM_MASK BIT(7)
#define RT6245_CODE_MASK GENMASK(6, 0)
/* HW Enable + Soft start time */
#define RT6245_ENTIME_IN_US 5000
#define RT6245_VOUT_MINUV 437500
#define RT6245_VOUT_MAXUV 1387500
#define RT6245_VOUT_STEPUV 12500
#define RT6245_NUM_VOUT ((RT6245_VOUT_MAXUV - RT6245_VOUT_MINUV) / RT6245_VOUT_STEPUV + 1)
struct rt6245_priv {
struct gpio_desc *enable_gpio;
bool enable_state;
};
static int rt6245_enable(struct regulator_dev *rdev)
{
struct rt6245_priv *priv = rdev_get_drvdata(rdev);
struct regmap *regmap = rdev_get_regmap(rdev);
int ret;
if (!priv->enable_gpio)
return 0;
gpiod_direction_output(priv->enable_gpio, 1);
usleep_range(RT6245_ENTIME_IN_US, RT6245_ENTIME_IN_US + 1000);
regcache_cache_only(regmap, false);
ret = regcache_sync(regmap);
if (ret)
return ret;
priv->enable_state = true;
return 0;
}
static int rt6245_disable(struct regulator_dev *rdev)
{
struct rt6245_priv *priv = rdev_get_drvdata(rdev);
struct regmap *regmap = rdev_get_regmap(rdev);
if (!priv->enable_gpio)
return -EINVAL;
regcache_cache_only(regmap, true);
regcache_mark_dirty(regmap);
gpiod_direction_output(priv->enable_gpio, 0);
priv->enable_state = false;
return 0;
}
static int rt6245_is_enabled(struct regulator_dev *rdev)
{
struct rt6245_priv *priv = rdev_get_drvdata(rdev);
return priv->enable_state ? 1 : 0;
}
static const struct regulator_ops rt6245_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.enable = rt6245_enable,
.disable = rt6245_disable,
.is_enabled = rt6245_is_enabled,
};
/* ramp delay dividend is 12500 uV/uS, and divisor from 1 to 8 */
static const unsigned int rt6245_ramp_delay_table[] = {
12500, 6250, 4167, 3125, 2500, 2083, 1786, 1562
};
static const struct regulator_desc rt6245_regulator_desc = {
.name = "rt6245-regulator",
.ops = &rt6245_regulator_ops,
.type = REGULATOR_VOLTAGE,
.min_uV = RT6245_VOUT_MINUV,
.uV_step = RT6245_VOUT_STEPUV,
.n_voltages = RT6245_NUM_VOUT,
.ramp_delay_table = rt6245_ramp_delay_table,
.n_ramp_values = ARRAY_SIZE(rt6245_ramp_delay_table),
.owner = THIS_MODULE,
.vsel_reg = RT6245_VIRT_VOUT,
.vsel_mask = RT6245_VOUT_MASK,
.ramp_reg = RT6245_VIRT_SLEWRATE,
.ramp_mask = RT6245_SLEW_MASK,
};
static int rt6245_init_device_properties(struct device *dev)
{
const struct {
const char *name;
unsigned int reg;
} rt6245_props[] = {
{ "richtek,oc-level-select", RT6245_VIRT_OCLIMIT },
{ "richtek,ot-level-select", RT6245_VIRT_OTLEVEL },
{ "richtek,pgdly-time-select", RT6245_VIRT_PGDLYTIME },
{ "richtek,switch-freq-select", RT6245_VIRT_SWFREQ }
};
struct regmap *regmap = dev_get_regmap(dev, NULL);
u8 propval;
int i, ret;
for (i = 0; i < ARRAY_SIZE(rt6245_props); i++) {
ret = device_property_read_u8(dev, rt6245_props[i].name, &propval);
if (ret)
continue;
ret = regmap_write(regmap, rt6245_props[i].reg, propval);
if (ret) {
dev_err(dev, "Fail to apply [%s:%d]\n", rt6245_props[i].name, propval);
return ret;
}
}
return 0;
}
static int rt6245_reg_write(void *context, unsigned int reg, unsigned int val)
{
struct i2c_client *i2c = context;
const u8 func_base[] = { 0x6F, 0x73, 0x78, 0x61, 0x7C, 0 };
unsigned int code, bit_count;
code = func_base[reg];
code += val;
/* xor checksum for bit 6 to 0 */
bit_count = hweight8(code & RT6245_CODE_MASK);
if (bit_count % 2)
code |= RT6245_CHKSUM_MASK;
else
code &= ~RT6245_CHKSUM_MASK;
return i2c_smbus_write_byte(i2c, code);
}
static const struct reg_default rt6245_reg_defaults[] = {
/* Default over current 14A */
{ RT6245_VIRT_OCLIMIT, 2 },
/* Default over temperature 150'c */
{ RT6245_VIRT_OTLEVEL, 0 },
/* Default power good delay time 10us */
{ RT6245_VIRT_PGDLYTIME, 1 },
/* Default slewrate 12.5mV/uS */
{ RT6245_VIRT_SLEWRATE, 0 },
/* Default switch frequency 800KHz */
{ RT6245_VIRT_SWFREQ, 1 },
/* Default voltage 750mV */
{ RT6245_VIRT_VOUT, 0x19 }
};
static const struct regmap_config rt6245_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = RT6245_VIRT_VOUT,
.cache_type = REGCACHE_FLAT,
.reg_defaults = rt6245_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(rt6245_reg_defaults),
.reg_write = rt6245_reg_write,
};
static int rt6245_probe(struct i2c_client *i2c)
{
struct rt6245_priv *priv;
struct regmap *regmap;
struct regulator_config regulator_cfg = {};
struct regulator_dev *rdev;
int ret;
priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->enable_state = true;
priv->enable_gpio = devm_gpiod_get_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
if (IS_ERR(priv->enable_gpio)) {
dev_err(&i2c->dev, "Failed to get 'enable' gpio\n");
return PTR_ERR(priv->enable_gpio);
}
usleep_range(RT6245_ENTIME_IN_US, RT6245_ENTIME_IN_US + 1000);
regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt6245_regmap_config);
if (IS_ERR(regmap)) {
dev_err(&i2c->dev, "Failed to initialize the regmap\n");
return PTR_ERR(regmap);
}
ret = rt6245_init_device_properties(&i2c->dev);
if (ret) {
dev_err(&i2c->dev, "Failed to initialize device properties\n");
return ret;
}
regulator_cfg.dev = &i2c->dev;
regulator_cfg.of_node = i2c->dev.of_node;
regulator_cfg.regmap = regmap;
regulator_cfg.driver_data = priv;
regulator_cfg.init_data = of_get_regulator_init_data(&i2c->dev, i2c->dev.of_node,
&rt6245_regulator_desc);
rdev = devm_regulator_register(&i2c->dev, &rt6245_regulator_desc, &regulator_cfg);
if (IS_ERR(rdev)) {
dev_err(&i2c->dev, "Failed to register regulator\n");
return PTR_ERR(rdev);
}
return 0;
}
static const struct of_device_id __maybe_unused rt6245_of_match_table[] = {
{ .compatible = "richtek,rt6245", },
{}
};
MODULE_DEVICE_TABLE(of, rt6245_of_match_table);
static struct i2c_driver rt6245_driver = {
.driver = {
.name = "rt6245",
.of_match_table = rt6245_of_match_table,
},
.probe_new = rt6245_probe,
};
module_i2c_driver(rt6245_driver);
MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
MODULE_DESCRIPTION("Richtek RT6245 Regulator Driver");
MODULE_LICENSE("GPL v2");

View File

@ -32,7 +32,8 @@ struct stpmic1_regulator_cfg {
static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode);
static unsigned int stpmic1_get_mode(struct regulator_dev *rdev);
static int stpmic1_set_icc(struct regulator_dev *rdev);
static int stpmic1_set_icc(struct regulator_dev *rdev, int lim, int severity,
bool enable);
static unsigned int stpmic1_map_mode(unsigned int mode);
enum {
@ -491,11 +492,26 @@ static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode)
STPMIC1_BUCK_MODE_LP, value);
}
static int stpmic1_set_icc(struct regulator_dev *rdev)
static int stpmic1_set_icc(struct regulator_dev *rdev, int lim, int severity,
bool enable)
{
struct stpmic1_regulator_cfg *cfg = rdev_get_drvdata(rdev);
struct regmap *regmap = rdev_get_regmap(rdev);
/*
* The code seems like one bit in a register controls whether OCP is
* enabled. So we might be able to turn it off here is if that
* was requested. I won't support this because I don't have the HW.
* Feel free to try and implement if you have the HW and need kernel
* to disable this.
*
* Also, I don't know if limit can be configured or if we support
* error/warning instead of protect. So I just keep existing logic
* and assume no.
*/
if (lim || severity != REGULATOR_SEVERITY_PROT || !enable)
return -EINVAL;
/* enable switch off in case of over current */
return regmap_update_bits(regmap, cfg->icc_reg, cfg->icc_mask,
cfg->icc_mask);

View File

@ -0,0 +1,128 @@
// SPDX-License-Identifier: GPL-2.0+
//
// Functions to access SY3686A power management chip voltages
//
// Copyright (C) 2019 reMarkable AS - http://www.remarkable.com/
//
// Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com>
// Alistair Francis <alistair@alistair23.me>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/gpio/consumer.h>
#include <linux/mfd/sy7636a.h>
#define SY7636A_POLL_ENABLED_TIME 500
static int sy7636a_get_vcom_voltage_op(struct regulator_dev *rdev)
{
int ret;
unsigned int val, val_h;
ret = regmap_read(rdev->regmap, SY7636A_REG_VCOM_ADJUST_CTRL_L, &val);
if (ret)
return ret;
ret = regmap_read(rdev->regmap, SY7636A_REG_VCOM_ADJUST_CTRL_H, &val_h);
if (ret)
return ret;
val |= (val_h << VCOM_ADJUST_CTRL_SHIFT);
return (val & VCOM_ADJUST_CTRL_MASK) * VCOM_ADJUST_CTRL_SCAL;
}
static int sy7636a_get_status(struct regulator_dev *rdev)
{
struct sy7636a *sy7636a = rdev_get_drvdata(rdev);
int ret = 0;
ret = gpiod_get_value_cansleep(sy7636a->pgood_gpio);
if (ret < 0)
dev_err(&rdev->dev, "Failed to read pgood gpio: %d\n", ret);
return ret;
}
static const struct regulator_ops sy7636a_vcom_volt_ops = {
.get_voltage = sy7636a_get_vcom_voltage_op,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_status = sy7636a_get_status,
};
static const struct regulator_desc desc = {
.name = "vcom",
.id = 0,
.ops = &sy7636a_vcom_volt_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.enable_reg = SY7636A_REG_OPERATION_MODE_CRL,
.enable_mask = SY7636A_OPERATION_MODE_CRL_ONOFF,
.poll_enabled_time = SY7636A_POLL_ENABLED_TIME,
.regulators_node = of_match_ptr("regulators"),
.of_match = of_match_ptr("vcom"),
};
static int sy7636a_regulator_probe(struct platform_device *pdev)
{
struct sy7636a *sy7636a = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
struct regulator_dev *rdev;
struct gpio_desc *gdp;
int ret;
if (!sy7636a)
return -EPROBE_DEFER;
platform_set_drvdata(pdev, sy7636a);
gdp = devm_gpiod_get(sy7636a->dev, "epd-pwr-good", GPIOD_IN);
if (IS_ERR(gdp)) {
dev_err(sy7636a->dev, "Power good GPIO fault %ld\n", PTR_ERR(gdp));
return PTR_ERR(gdp);
}
sy7636a->pgood_gpio = gdp;
ret = regmap_write(sy7636a->regmap, SY7636A_REG_POWER_ON_DELAY_TIME, 0x0);
if (ret) {
dev_err(sy7636a->dev, "Failed to initialize regulator: %d\n", ret);
return ret;
}
config.dev = &pdev->dev;
config.dev->of_node = sy7636a->dev->of_node;
config.driver_data = sy7636a;
config.regmap = sy7636a->regmap;
rdev = devm_regulator_register(&pdev->dev, &desc, &config);
if (IS_ERR(rdev)) {
dev_err(sy7636a->dev, "Failed to register %s regulator\n",
pdev->name);
return PTR_ERR(rdev);
}
return 0;
}
static const struct platform_device_id sy7636a_regulator_id_table[] = {
{ "sy7636a-regulator", },
{ }
};
MODULE_DEVICE_TABLE(platform, sy7636a_regulator_id_table);
static struct platform_driver sy7636a_regulator_driver = {
.driver = {
.name = "sy7636a-regulator",
},
.probe = sy7636a_regulator_probe,
.id_table = sy7636a_regulator_id_table,
};
module_platform_driver(sy7636a_regulator_driver);
MODULE_AUTHOR("Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com>");
MODULE_DESCRIPTION("SY7636A voltage regulator driver");
MODULE_LICENSE("GPL v2");

View File

@ -201,6 +201,7 @@ static const struct of_device_id uniphier_regulator_match[] = {
},
{ /* Sentinel */ },
};
MODULE_DEVICE_TABLE(of, uniphier_regulator_match);
static struct platform_driver uniphier_regulator_driver = {
.probe = uniphier_regulator_probe,

View File

@ -29,7 +29,7 @@ struct userspace_consumer_data {
struct regulator_bulk_data *supplies;
};
static ssize_t reg_show_name(struct device *dev,
static ssize_t name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct userspace_consumer_data *data = dev_get_drvdata(dev);
@ -37,7 +37,7 @@ static ssize_t reg_show_name(struct device *dev,
return sprintf(buf, "%s\n", data->name);
}
static ssize_t reg_show_state(struct device *dev,
static ssize_t state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct userspace_consumer_data *data = dev_get_drvdata(dev);
@ -48,7 +48,7 @@ static ssize_t reg_show_state(struct device *dev,
return sprintf(buf, "disabled\n");
}
static ssize_t reg_set_state(struct device *dev, struct device_attribute *attr,
static ssize_t state_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct userspace_consumer_data *data = dev_get_drvdata(dev);
@ -87,8 +87,8 @@ static ssize_t reg_set_state(struct device *dev, struct device_attribute *attr,
return count;
}
static DEVICE_ATTR(name, 0444, reg_show_name, NULL);
static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state);
static DEVICE_ATTR_RO(name);
static DEVICE_ATTR_RW(state);
static struct attribute *attributes[] = {
&dev_attr_name.attr,

View File

@ -75,7 +75,7 @@ static int __mtk_rtc_read_time(struct mt6397_rtc *rtc,
tm->tm_min = data[RTC_OFFSET_MIN];
tm->tm_hour = data[RTC_OFFSET_HOUR];
tm->tm_mday = data[RTC_OFFSET_DOM];
tm->tm_mon = data[RTC_OFFSET_MTH];
tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_TC_MTH_MASK;
tm->tm_year = data[RTC_OFFSET_YEAR];
ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, sec);

View File

@ -36,10 +36,8 @@ static LIST_HEAD(thermal_governor_list);
static DEFINE_MUTEX(thermal_list_lock);
static DEFINE_MUTEX(thermal_governor_lock);
static DEFINE_MUTEX(poweroff_lock);
static atomic_t in_suspend;
static bool power_off_triggered;
static struct thermal_governor *def_governor;
@ -327,70 +325,18 @@ static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip)
def_governor->throttle(tz, trip);
}
/**
* thermal_emergency_poweroff_func - emergency poweroff work after a known delay
* @work: work_struct associated with the emergency poweroff function
*
* This function is called in very critical situations to force
* a kernel poweroff after a configurable timeout value.
*/
static void thermal_emergency_poweroff_func(struct work_struct *work)
{
/*
* We have reached here after the emergency thermal shutdown
* Waiting period has expired. This means orderly_poweroff has
* not been able to shut off the system for some reason.
* Try to shut down the system immediately using kernel_power_off
* if populated
*/
WARN(1, "Attempting kernel_power_off: Temperature too high\n");
kernel_power_off();
/*
* Worst of the worst case trigger emergency restart
*/
WARN(1, "Attempting emergency_restart: Temperature too high\n");
emergency_restart();
}
static DECLARE_DELAYED_WORK(thermal_emergency_poweroff_work,
thermal_emergency_poweroff_func);
/**
* thermal_emergency_poweroff - Trigger an emergency system poweroff
*
* This may be called from any critical situation to trigger a system shutdown
* after a known period of time. By default this is not scheduled.
*/
static void thermal_emergency_poweroff(void)
{
int poweroff_delay_ms = CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS;
/*
* poweroff_delay_ms must be a carefully profiled positive value.
* Its a must for thermal_emergency_poweroff_work to be scheduled
*/
if (poweroff_delay_ms <= 0)
return;
schedule_delayed_work(&thermal_emergency_poweroff_work,
msecs_to_jiffies(poweroff_delay_ms));
}
void thermal_zone_device_critical(struct thermal_zone_device *tz)
{
/*
* poweroff_delay_ms must be a carefully profiled positive value.
* Its a must for forced_emergency_poweroff_work to be scheduled.
*/
int poweroff_delay_ms = CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS;
dev_emerg(&tz->device, "%s: critical temperature reached, "
"shutting down\n", tz->type);
mutex_lock(&poweroff_lock);
if (!power_off_triggered) {
/*
* Queue a backup emergency shutdown in the event of
* orderly_poweroff failure
*/
thermal_emergency_poweroff();
orderly_poweroff(true);
power_off_triggered = true;
}
mutex_unlock(&poweroff_lock);
hw_protection_shutdown("Temperature too high", poweroff_delay_ms);
}
EXPORT_SYMBOL(thermal_zone_device_critical);
@ -1538,7 +1484,6 @@ error:
ida_destroy(&thermal_cdev_ida);
mutex_destroy(&thermal_list_lock);
mutex_destroy(&thermal_governor_lock);
mutex_destroy(&poweroff_lock);
return result;
}
postcore_initcall(thermal_init);

View File

@ -6,12 +6,9 @@
#ifndef __MFD_MT6358_CORE_H__
#define __MFD_MT6358_CORE_H__
#define MT6358_REG_WIDTH 16
struct irq_top_t {
int hwirq_base;
unsigned int num_int_regs;
unsigned int num_int_bits;
unsigned int en_reg;
unsigned int en_reg_shift;
unsigned int sta_reg;
@ -25,6 +22,7 @@ struct pmic_irq_data {
unsigned short top_int_status_reg;
bool *enable_hwirq;
bool *cache_hwirq;
const struct irq_top_t *pmic_ints;
};
enum mt6358_irq_top_status_shift {
@ -146,8 +144,8 @@ enum mt6358_irq_numbers {
{ \
.hwirq_base = MT6358_IRQ_##sp##_BASE, \
.num_int_regs = \
((MT6358_IRQ_##sp##_BITS - 1) / MT6358_REG_WIDTH) + 1, \
.num_int_bits = MT6358_IRQ_##sp##_BITS, \
((MT6358_IRQ_##sp##_BITS - 1) / \
MTK_PMIC_REG_WIDTH) + 1, \
.en_reg = MT6358_##sp##_TOP_INT_CON0, \
.en_reg_shift = 0x6, \
.sta_reg = MT6358_##sp##_TOP_INT_STATUS0, \

View File

@ -0,0 +1,133 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#ifndef __MFD_MT6359_CORE_H__
#define __MFD_MT6359_CORE_H__
enum mt6359_irq_top_status_shift {
MT6359_BUCK_TOP = 0,
MT6359_LDO_TOP,
MT6359_PSC_TOP,
MT6359_SCK_TOP,
MT6359_BM_TOP,
MT6359_HK_TOP,
MT6359_AUD_TOP = 7,
MT6359_MISC_TOP,
};
enum mt6359_irq_numbers {
MT6359_IRQ_VCORE_OC = 1,
MT6359_IRQ_VGPU11_OC,
MT6359_IRQ_VGPU12_OC,
MT6359_IRQ_VMODEM_OC,
MT6359_IRQ_VPROC1_OC,
MT6359_IRQ_VPROC2_OC,
MT6359_IRQ_VS1_OC,
MT6359_IRQ_VS2_OC,
MT6359_IRQ_VPA_OC = 9,
MT6359_IRQ_VFE28_OC = 16,
MT6359_IRQ_VXO22_OC,
MT6359_IRQ_VRF18_OC,
MT6359_IRQ_VRF12_OC,
MT6359_IRQ_VEFUSE_OC,
MT6359_IRQ_VCN33_1_OC,
MT6359_IRQ_VCN33_2_OC,
MT6359_IRQ_VCN13_OC,
MT6359_IRQ_VCN18_OC,
MT6359_IRQ_VA09_OC,
MT6359_IRQ_VCAMIO_OC,
MT6359_IRQ_VA12_OC,
MT6359_IRQ_VAUX18_OC,
MT6359_IRQ_VAUD18_OC,
MT6359_IRQ_VIO18_OC,
MT6359_IRQ_VSRAM_PROC1_OC,
MT6359_IRQ_VSRAM_PROC2_OC,
MT6359_IRQ_VSRAM_OTHERS_OC,
MT6359_IRQ_VSRAM_MD_OC,
MT6359_IRQ_VEMC_OC,
MT6359_IRQ_VSIM1_OC,
MT6359_IRQ_VSIM2_OC,
MT6359_IRQ_VUSB_OC,
MT6359_IRQ_VRFCK_OC,
MT6359_IRQ_VBBCK_OC,
MT6359_IRQ_VBIF28_OC,
MT6359_IRQ_VIBR_OC,
MT6359_IRQ_VIO28_OC,
MT6359_IRQ_VM18_OC,
MT6359_IRQ_VUFS_OC = 45,
MT6359_IRQ_PWRKEY = 48,
MT6359_IRQ_HOMEKEY,
MT6359_IRQ_PWRKEY_R,
MT6359_IRQ_HOMEKEY_R,
MT6359_IRQ_NI_LBAT_INT,
MT6359_IRQ_CHRDET_EDGE = 53,
MT6359_IRQ_RTC = 64,
MT6359_IRQ_FG_BAT_H = 80,
MT6359_IRQ_FG_BAT_L,
MT6359_IRQ_FG_CUR_H,
MT6359_IRQ_FG_CUR_L,
MT6359_IRQ_FG_ZCV = 84,
MT6359_IRQ_FG_N_CHARGE_L = 87,
MT6359_IRQ_FG_IAVG_H,
MT6359_IRQ_FG_IAVG_L = 89,
MT6359_IRQ_FG_DISCHARGE = 91,
MT6359_IRQ_FG_CHARGE,
MT6359_IRQ_BATON_LV = 96,
MT6359_IRQ_BATON_BAT_IN = 98,
MT6359_IRQ_BATON_BAT_OU,
MT6359_IRQ_BIF = 100,
MT6359_IRQ_BAT_H = 112,
MT6359_IRQ_BAT_L,
MT6359_IRQ_BAT2_H,
MT6359_IRQ_BAT2_L,
MT6359_IRQ_BAT_TEMP_H,
MT6359_IRQ_BAT_TEMP_L,
MT6359_IRQ_THR_H,
MT6359_IRQ_THR_L,
MT6359_IRQ_AUXADC_IMP,
MT6359_IRQ_NAG_C_DLTV = 121,
MT6359_IRQ_AUDIO = 128,
MT6359_IRQ_ACCDET = 133,
MT6359_IRQ_ACCDET_EINT0,
MT6359_IRQ_ACCDET_EINT1,
MT6359_IRQ_SPI_CMD_ALERT = 144,
MT6359_IRQ_NR,
};
#define MT6359_IRQ_BUCK_BASE MT6359_IRQ_VCORE_OC
#define MT6359_IRQ_LDO_BASE MT6359_IRQ_VFE28_OC
#define MT6359_IRQ_PSC_BASE MT6359_IRQ_PWRKEY
#define MT6359_IRQ_SCK_BASE MT6359_IRQ_RTC
#define MT6359_IRQ_BM_BASE MT6359_IRQ_FG_BAT_H
#define MT6359_IRQ_HK_BASE MT6359_IRQ_BAT_H
#define MT6359_IRQ_AUD_BASE MT6359_IRQ_AUDIO
#define MT6359_IRQ_MISC_BASE MT6359_IRQ_SPI_CMD_ALERT
#define MT6359_IRQ_BUCK_BITS (MT6359_IRQ_VPA_OC - MT6359_IRQ_BUCK_BASE + 1)
#define MT6359_IRQ_LDO_BITS (MT6359_IRQ_VUFS_OC - MT6359_IRQ_LDO_BASE + 1)
#define MT6359_IRQ_PSC_BITS \
(MT6359_IRQ_CHRDET_EDGE - MT6359_IRQ_PSC_BASE + 1)
#define MT6359_IRQ_SCK_BITS (MT6359_IRQ_RTC - MT6359_IRQ_SCK_BASE + 1)
#define MT6359_IRQ_BM_BITS (MT6359_IRQ_BIF - MT6359_IRQ_BM_BASE + 1)
#define MT6359_IRQ_HK_BITS (MT6359_IRQ_NAG_C_DLTV - MT6359_IRQ_HK_BASE + 1)
#define MT6359_IRQ_AUD_BITS \
(MT6359_IRQ_ACCDET_EINT1 - MT6359_IRQ_AUD_BASE + 1)
#define MT6359_IRQ_MISC_BITS \
(MT6359_IRQ_SPI_CMD_ALERT - MT6359_IRQ_MISC_BASE + 1)
#define MT6359_TOP_GEN(sp) \
{ \
.hwirq_base = MT6359_IRQ_##sp##_BASE, \
.num_int_regs = \
((MT6359_IRQ_##sp##_BITS - 1) / \
MTK_PMIC_REG_WIDTH) + 1, \
.en_reg = MT6359_##sp##_TOP_INT_CON0, \
.en_reg_shift = 0x6, \
.sta_reg = MT6359_##sp##_TOP_INT_STATUS0, \
.sta_reg_shift = 0x2, \
.top_offset = MT6359_##sp##_TOP, \
}
#endif /* __MFD_MT6359_CORE_H__ */

View File

@ -0,0 +1,529 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#ifndef __MFD_MT6359_REGISTERS_H__
#define __MFD_MT6359_REGISTERS_H__
/* PMIC Registers */
#define MT6359_SWCID 0xa
#define MT6359_MISC_TOP_INT_CON0 0x188
#define MT6359_MISC_TOP_INT_STATUS0 0x194
#define MT6359_TOP_INT_STATUS0 0x19e
#define MT6359_SCK_TOP_INT_CON0 0x528
#define MT6359_SCK_TOP_INT_STATUS0 0x534
#define MT6359_EOSC_CALI_CON0 0x53a
#define MT6359_EOSC_CALI_CON1 0x53c
#define MT6359_RTC_MIX_CON0 0x53e
#define MT6359_RTC_MIX_CON1 0x540
#define MT6359_RTC_MIX_CON2 0x542
#define MT6359_RTC_DSN_ID 0x580
#define MT6359_RTC_DSN_REV0 0x582
#define MT6359_RTC_DBI 0x584
#define MT6359_RTC_DXI 0x586
#define MT6359_RTC_BBPU 0x588
#define MT6359_RTC_IRQ_STA 0x58a
#define MT6359_RTC_IRQ_EN 0x58c
#define MT6359_RTC_CII_EN 0x58e
#define MT6359_RTC_AL_MASK 0x590
#define MT6359_RTC_TC_SEC 0x592
#define MT6359_RTC_TC_MIN 0x594
#define MT6359_RTC_TC_HOU 0x596
#define MT6359_RTC_TC_DOM 0x598
#define MT6359_RTC_TC_DOW 0x59a
#define MT6359_RTC_TC_MTH 0x59c
#define MT6359_RTC_TC_YEA 0x59e
#define MT6359_RTC_AL_SEC 0x5a0
#define MT6359_RTC_AL_MIN 0x5a2
#define MT6359_RTC_AL_HOU 0x5a4
#define MT6359_RTC_AL_DOM 0x5a6
#define MT6359_RTC_AL_DOW 0x5a8
#define MT6359_RTC_AL_MTH 0x5aa
#define MT6359_RTC_AL_YEA 0x5ac
#define MT6359_RTC_OSC32CON 0x5ae
#define MT6359_RTC_POWERKEY1 0x5b0
#define MT6359_RTC_POWERKEY2 0x5b2
#define MT6359_RTC_PDN1 0x5b4
#define MT6359_RTC_PDN2 0x5b6
#define MT6359_RTC_SPAR0 0x5b8
#define MT6359_RTC_SPAR1 0x5ba
#define MT6359_RTC_PROT 0x5bc
#define MT6359_RTC_DIFF 0x5be
#define MT6359_RTC_CALI 0x5c0
#define MT6359_RTC_WRTGR 0x5c2
#define MT6359_RTC_CON 0x5c4
#define MT6359_RTC_SEC_CTRL 0x5c6
#define MT6359_RTC_INT_CNT 0x5c8
#define MT6359_RTC_SEC_DAT0 0x5ca
#define MT6359_RTC_SEC_DAT1 0x5cc
#define MT6359_RTC_SEC_DAT2 0x5ce
#define MT6359_RTC_SEC_DSN_ID 0x600
#define MT6359_RTC_SEC_DSN_REV0 0x602
#define MT6359_RTC_SEC_DBI 0x604
#define MT6359_RTC_SEC_DXI 0x606
#define MT6359_RTC_TC_SEC_SEC 0x608
#define MT6359_RTC_TC_MIN_SEC 0x60a
#define MT6359_RTC_TC_HOU_SEC 0x60c
#define MT6359_RTC_TC_DOM_SEC 0x60e
#define MT6359_RTC_TC_DOW_SEC 0x610
#define MT6359_RTC_TC_MTH_SEC 0x612
#define MT6359_RTC_TC_YEA_SEC 0x614
#define MT6359_RTC_SEC_CK_PDN 0x616
#define MT6359_RTC_SEC_WRTGR 0x618
#define MT6359_PSC_TOP_INT_CON0 0x910
#define MT6359_PSC_TOP_INT_STATUS0 0x91c
#define MT6359_BM_TOP_INT_CON0 0xc32
#define MT6359_BM_TOP_INT_CON1 0xc38
#define MT6359_BM_TOP_INT_STATUS0 0xc4a
#define MT6359_BM_TOP_INT_STATUS1 0xc4c
#define MT6359_HK_TOP_INT_CON0 0xf92
#define MT6359_HK_TOP_INT_STATUS0 0xf9e
#define MT6359_BUCK_TOP_INT_CON0 0x1418
#define MT6359_BUCK_TOP_INT_STATUS0 0x1424
#define MT6359_BUCK_VPU_CON0 0x1488
#define MT6359_BUCK_VPU_DBG0 0x14a6
#define MT6359_BUCK_VPU_DBG1 0x14a8
#define MT6359_BUCK_VPU_ELR0 0x14ac
#define MT6359_BUCK_VCORE_CON0 0x1508
#define MT6359_BUCK_VCORE_DBG0 0x1526
#define MT6359_BUCK_VCORE_DBG1 0x1528
#define MT6359_BUCK_VCORE_SSHUB_CON0 0x152a
#define MT6359_BUCK_VCORE_ELR0 0x1534
#define MT6359_BUCK_VGPU11_CON0 0x1588
#define MT6359_BUCK_VGPU11_DBG0 0x15a6
#define MT6359_BUCK_VGPU11_DBG1 0x15a8
#define MT6359_BUCK_VGPU11_ELR0 0x15ac
#define MT6359_BUCK_VMODEM_CON0 0x1688
#define MT6359_BUCK_VMODEM_DBG0 0x16a6
#define MT6359_BUCK_VMODEM_DBG1 0x16a8
#define MT6359_BUCK_VMODEM_ELR0 0x16ae
#define MT6359_BUCK_VPROC1_CON0 0x1708
#define MT6359_BUCK_VPROC1_DBG0 0x1726
#define MT6359_BUCK_VPROC1_DBG1 0x1728
#define MT6359_BUCK_VPROC1_ELR0 0x172e
#define MT6359_BUCK_VPROC2_CON0 0x1788
#define MT6359_BUCK_VPROC2_DBG0 0x17a6
#define MT6359_BUCK_VPROC2_DBG1 0x17a8
#define MT6359_BUCK_VPROC2_ELR0 0x17b2
#define MT6359_BUCK_VS1_CON0 0x1808
#define MT6359_BUCK_VS1_DBG0 0x1826
#define MT6359_BUCK_VS1_DBG1 0x1828
#define MT6359_BUCK_VS1_ELR0 0x1834
#define MT6359_BUCK_VS2_CON0 0x1888
#define MT6359_BUCK_VS2_DBG0 0x18a6
#define MT6359_BUCK_VS2_DBG1 0x18a8
#define MT6359_BUCK_VS2_ELR0 0x18b4
#define MT6359_BUCK_VPA_CON0 0x1908
#define MT6359_BUCK_VPA_CON1 0x190e
#define MT6359_BUCK_VPA_CFG0 0x1910
#define MT6359_BUCK_VPA_CFG1 0x1912
#define MT6359_BUCK_VPA_DBG0 0x1914
#define MT6359_BUCK_VPA_DBG1 0x1916
#define MT6359_VGPUVCORE_ANA_CON2 0x198e
#define MT6359_VGPUVCORE_ANA_CON13 0x19a4
#define MT6359_VPROC1_ANA_CON3 0x19b2
#define MT6359_VPROC2_ANA_CON3 0x1a0e
#define MT6359_VMODEM_ANA_CON3 0x1a1a
#define MT6359_VPU_ANA_CON3 0x1a26
#define MT6359_VS1_ANA_CON0 0x1a2c
#define MT6359_VS2_ANA_CON0 0x1a34
#define MT6359_VPA_ANA_CON0 0x1a3c
#define MT6359_LDO_TOP_INT_CON0 0x1b14
#define MT6359_LDO_TOP_INT_CON1 0x1b1a
#define MT6359_LDO_TOP_INT_STATUS0 0x1b28
#define MT6359_LDO_TOP_INT_STATUS1 0x1b2a
#define MT6359_LDO_VSRAM_PROC1_ELR 0x1b40
#define MT6359_LDO_VSRAM_PROC2_ELR 0x1b42
#define MT6359_LDO_VSRAM_OTHERS_ELR 0x1b44
#define MT6359_LDO_VSRAM_MD_ELR 0x1b46
#define MT6359_LDO_VFE28_CON0 0x1b88
#define MT6359_LDO_VFE28_MON 0x1b8a
#define MT6359_LDO_VXO22_CON0 0x1b98
#define MT6359_LDO_VXO22_MON 0x1b9a
#define MT6359_LDO_VRF18_CON0 0x1ba8
#define MT6359_LDO_VRF18_MON 0x1baa
#define MT6359_LDO_VRF12_CON0 0x1bb8
#define MT6359_LDO_VRF12_MON 0x1bba
#define MT6359_LDO_VEFUSE_CON0 0x1bc8
#define MT6359_LDO_VEFUSE_MON 0x1bca
#define MT6359_LDO_VCN33_1_CON0 0x1bd8
#define MT6359_LDO_VCN33_1_MON 0x1bda
#define MT6359_LDO_VCN33_1_MULTI_SW 0x1be8
#define MT6359_LDO_VCN33_2_CON0 0x1c08
#define MT6359_LDO_VCN33_2_MON 0x1c0a
#define MT6359_LDO_VCN33_2_MULTI_SW 0x1c18
#define MT6359_LDO_VCN13_CON0 0x1c1a
#define MT6359_LDO_VCN13_MON 0x1c1c
#define MT6359_LDO_VCN18_CON0 0x1c2a
#define MT6359_LDO_VCN18_MON 0x1c2c
#define MT6359_LDO_VA09_CON0 0x1c3a
#define MT6359_LDO_VA09_MON 0x1c3c
#define MT6359_LDO_VCAMIO_CON0 0x1c4a
#define MT6359_LDO_VCAMIO_MON 0x1c4c
#define MT6359_LDO_VA12_CON0 0x1c5a
#define MT6359_LDO_VA12_MON 0x1c5c
#define MT6359_LDO_VAUX18_CON0 0x1c88
#define MT6359_LDO_VAUX18_MON 0x1c8a
#define MT6359_LDO_VAUD18_CON0 0x1c98
#define MT6359_LDO_VAUD18_MON 0x1c9a
#define MT6359_LDO_VIO18_CON0 0x1ca8
#define MT6359_LDO_VIO18_MON 0x1caa
#define MT6359_LDO_VEMC_CON0 0x1cb8
#define MT6359_LDO_VEMC_MON 0x1cba
#define MT6359_LDO_VSIM1_CON0 0x1cc8
#define MT6359_LDO_VSIM1_MON 0x1cca
#define MT6359_LDO_VSIM2_CON0 0x1cd8
#define MT6359_LDO_VSIM2_MON 0x1cda
#define MT6359_LDO_VUSB_CON0 0x1d08
#define MT6359_LDO_VUSB_MON 0x1d0a
#define MT6359_LDO_VUSB_MULTI_SW 0x1d18
#define MT6359_LDO_VRFCK_CON0 0x1d1a
#define MT6359_LDO_VRFCK_MON 0x1d1c
#define MT6359_LDO_VBBCK_CON0 0x1d2a
#define MT6359_LDO_VBBCK_MON 0x1d2c
#define MT6359_LDO_VBIF28_CON0 0x1d3a
#define MT6359_LDO_VBIF28_MON 0x1d3c
#define MT6359_LDO_VIBR_CON0 0x1d4a
#define MT6359_LDO_VIBR_MON 0x1d4c
#define MT6359_LDO_VIO28_CON0 0x1d5a
#define MT6359_LDO_VIO28_MON 0x1d5c
#define MT6359_LDO_VM18_CON0 0x1d88
#define MT6359_LDO_VM18_MON 0x1d8a
#define MT6359_LDO_VUFS_CON0 0x1d98
#define MT6359_LDO_VUFS_MON 0x1d9a
#define MT6359_LDO_VSRAM_PROC1_CON0 0x1e88
#define MT6359_LDO_VSRAM_PROC1_MON 0x1e8a
#define MT6359_LDO_VSRAM_PROC1_VOSEL1 0x1e8e
#define MT6359_LDO_VSRAM_PROC2_CON0 0x1ea6
#define MT6359_LDO_VSRAM_PROC2_MON 0x1ea8
#define MT6359_LDO_VSRAM_PROC2_VOSEL1 0x1eac
#define MT6359_LDO_VSRAM_OTHERS_CON0 0x1f08
#define MT6359_LDO_VSRAM_OTHERS_MON 0x1f0a
#define MT6359_LDO_VSRAM_OTHERS_VOSEL1 0x1f0e
#define MT6359_LDO_VSRAM_OTHERS_SSHUB 0x1f26
#define MT6359_LDO_VSRAM_MD_CON0 0x1f2c
#define MT6359_LDO_VSRAM_MD_MON 0x1f2e
#define MT6359_LDO_VSRAM_MD_VOSEL1 0x1f32
#define MT6359_VFE28_ANA_CON0 0x1f88
#define MT6359_VAUX18_ANA_CON0 0x1f8c
#define MT6359_VUSB_ANA_CON0 0x1f90
#define MT6359_VBIF28_ANA_CON0 0x1f94
#define MT6359_VCN33_1_ANA_CON0 0x1f98
#define MT6359_VCN33_2_ANA_CON0 0x1f9c
#define MT6359_VEMC_ANA_CON0 0x1fa0
#define MT6359_VSIM1_ANA_CON0 0x1fa4
#define MT6359_VSIM2_ANA_CON0 0x1fa8
#define MT6359_VIO28_ANA_CON0 0x1fac
#define MT6359_VIBR_ANA_CON0 0x1fb0
#define MT6359_VRF18_ANA_CON0 0x2008
#define MT6359_VEFUSE_ANA_CON0 0x200c
#define MT6359_VCN18_ANA_CON0 0x2010
#define MT6359_VCAMIO_ANA_CON0 0x2014
#define MT6359_VAUD18_ANA_CON0 0x2018
#define MT6359_VIO18_ANA_CON0 0x201c
#define MT6359_VM18_ANA_CON0 0x2020
#define MT6359_VUFS_ANA_CON0 0x2024
#define MT6359_VRF12_ANA_CON0 0x202a
#define MT6359_VCN13_ANA_CON0 0x202e
#define MT6359_VA09_ANA_CON0 0x2032
#define MT6359_VA12_ANA_CON0 0x2036
#define MT6359_VXO22_ANA_CON0 0x2088
#define MT6359_VRFCK_ANA_CON0 0x208c
#define MT6359_VBBCK_ANA_CON0 0x2094
#define MT6359_AUD_TOP_INT_CON0 0x2328
#define MT6359_AUD_TOP_INT_STATUS0 0x2334
#define MT6359_RG_BUCK_VPU_EN_ADDR MT6359_BUCK_VPU_CON0
#define MT6359_RG_BUCK_VPU_LP_ADDR MT6359_BUCK_VPU_CON0
#define MT6359_RG_BUCK_VPU_LP_SHIFT 1
#define MT6359_DA_VPU_VOSEL_ADDR MT6359_BUCK_VPU_DBG0
#define MT6359_DA_VPU_VOSEL_MASK 0x7F
#define MT6359_DA_VPU_VOSEL_SHIFT 0
#define MT6359_DA_VPU_EN_ADDR MT6359_BUCK_VPU_DBG1
#define MT6359_RG_BUCK_VPU_VOSEL_ADDR MT6359_BUCK_VPU_ELR0
#define MT6359_RG_BUCK_VPU_VOSEL_MASK 0x7F
#define MT6359_RG_BUCK_VPU_VOSEL_SHIFT 0
#define MT6359_RG_BUCK_VCORE_EN_ADDR MT6359_BUCK_VCORE_CON0
#define MT6359_RG_BUCK_VCORE_LP_ADDR MT6359_BUCK_VCORE_CON0
#define MT6359_RG_BUCK_VCORE_LP_SHIFT 1
#define MT6359_DA_VCORE_VOSEL_ADDR MT6359_BUCK_VCORE_DBG0
#define MT6359_DA_VCORE_VOSEL_MASK 0x7F
#define MT6359_DA_VCORE_VOSEL_SHIFT 0
#define MT6359_DA_VCORE_EN_ADDR MT6359_BUCK_VCORE_DBG1
#define MT6359_RG_BUCK_VCORE_SSHUB_EN_ADDR MT6359_BUCK_VCORE_SSHUB_CON0
#define MT6359_RG_BUCK_VCORE_SSHUB_VOSEL_ADDR MT6359_BUCK_VCORE_SSHUB_CON0
#define MT6359_RG_BUCK_VCORE_SSHUB_VOSEL_MASK 0x7F
#define MT6359_RG_BUCK_VCORE_SSHUB_VOSEL_SHIFT 4
#define MT6359_RG_BUCK_VCORE_VOSEL_ADDR MT6359_BUCK_VCORE_ELR0
#define MT6359_RG_BUCK_VCORE_VOSEL_MASK 0x7F
#define MT6359_RG_BUCK_VCORE_VOSEL_SHIFT 0
#define MT6359_RG_BUCK_VGPU11_EN_ADDR MT6359_BUCK_VGPU11_CON0
#define MT6359_RG_BUCK_VGPU11_LP_ADDR MT6359_BUCK_VGPU11_CON0
#define MT6359_RG_BUCK_VGPU11_LP_SHIFT 1
#define MT6359_DA_VGPU11_VOSEL_ADDR MT6359_BUCK_VGPU11_DBG0
#define MT6359_DA_VGPU11_VOSEL_MASK 0x7F
#define MT6359_DA_VGPU11_VOSEL_SHIFT 0
#define MT6359_DA_VGPU11_EN_ADDR MT6359_BUCK_VGPU11_DBG1
#define MT6359_RG_BUCK_VGPU11_VOSEL_ADDR MT6359_BUCK_VGPU11_ELR0
#define MT6359_RG_BUCK_VGPU11_VOSEL_MASK 0x7F
#define MT6359_RG_BUCK_VGPU11_VOSEL_SHIFT 0
#define MT6359_RG_BUCK_VMODEM_EN_ADDR MT6359_BUCK_VMODEM_CON0
#define MT6359_RG_BUCK_VMODEM_LP_ADDR MT6359_BUCK_VMODEM_CON0
#define MT6359_RG_BUCK_VMODEM_LP_SHIFT 1
#define MT6359_DA_VMODEM_VOSEL_ADDR MT6359_BUCK_VMODEM_DBG0
#define MT6359_DA_VMODEM_VOSEL_MASK 0x7F
#define MT6359_DA_VMODEM_VOSEL_SHIFT 0
#define MT6359_DA_VMODEM_EN_ADDR MT6359_BUCK_VMODEM_DBG1
#define MT6359_RG_BUCK_VMODEM_VOSEL_ADDR MT6359_BUCK_VMODEM_ELR0
#define MT6359_RG_BUCK_VMODEM_VOSEL_MASK 0x7F
#define MT6359_RG_BUCK_VMODEM_VOSEL_SHIFT 0
#define MT6359_RG_BUCK_VPROC1_EN_ADDR MT6359_BUCK_VPROC1_CON0
#define MT6359_RG_BUCK_VPROC1_LP_ADDR MT6359_BUCK_VPROC1_CON0
#define MT6359_RG_BUCK_VPROC1_LP_SHIFT 1
#define MT6359_DA_VPROC1_VOSEL_ADDR MT6359_BUCK_VPROC1_DBG0
#define MT6359_DA_VPROC1_VOSEL_MASK 0x7F
#define MT6359_DA_VPROC1_VOSEL_SHIFT 0
#define MT6359_DA_VPROC1_EN_ADDR MT6359_BUCK_VPROC1_DBG1
#define MT6359_RG_BUCK_VPROC1_VOSEL_ADDR MT6359_BUCK_VPROC1_ELR0
#define MT6359_RG_BUCK_VPROC1_VOSEL_MASK 0x7F
#define MT6359_RG_BUCK_VPROC1_VOSEL_SHIFT 0
#define MT6359_RG_BUCK_VPROC2_EN_ADDR MT6359_BUCK_VPROC2_CON0
#define MT6359_RG_BUCK_VPROC2_LP_ADDR MT6359_BUCK_VPROC2_CON0
#define MT6359_RG_BUCK_VPROC2_LP_SHIFT 1
#define MT6359_DA_VPROC2_VOSEL_ADDR MT6359_BUCK_VPROC2_DBG0
#define MT6359_DA_VPROC2_VOSEL_MASK 0x7F
#define MT6359_DA_VPROC2_VOSEL_SHIFT 0
#define MT6359_DA_VPROC2_EN_ADDR MT6359_BUCK_VPROC2_DBG1
#define MT6359_RG_BUCK_VPROC2_VOSEL_ADDR MT6359_BUCK_VPROC2_ELR0
#define MT6359_RG_BUCK_VPROC2_VOSEL_MASK 0x7F
#define MT6359_RG_BUCK_VPROC2_VOSEL_SHIFT 0
#define MT6359_RG_BUCK_VS1_EN_ADDR MT6359_BUCK_VS1_CON0
#define MT6359_RG_BUCK_VS1_LP_ADDR MT6359_BUCK_VS1_CON0
#define MT6359_RG_BUCK_VS1_LP_SHIFT 1
#define MT6359_DA_VS1_VOSEL_ADDR MT6359_BUCK_VS1_DBG0
#define MT6359_DA_VS1_VOSEL_MASK 0x7F
#define MT6359_DA_VS1_VOSEL_SHIFT 0
#define MT6359_DA_VS1_EN_ADDR MT6359_BUCK_VS1_DBG1
#define MT6359_RG_BUCK_VS1_VOSEL_ADDR MT6359_BUCK_VS1_ELR0
#define MT6359_RG_BUCK_VS1_VOSEL_MASK 0x7F
#define MT6359_RG_BUCK_VS1_VOSEL_SHIFT 0
#define MT6359_RG_BUCK_VS2_EN_ADDR MT6359_BUCK_VS2_CON0
#define MT6359_RG_BUCK_VS2_LP_ADDR MT6359_BUCK_VS2_CON0
#define MT6359_RG_BUCK_VS2_LP_SHIFT 1
#define MT6359_DA_VS2_VOSEL_ADDR MT6359_BUCK_VS2_DBG0
#define MT6359_DA_VS2_VOSEL_MASK 0x7F
#define MT6359_DA_VS2_VOSEL_SHIFT 0
#define MT6359_DA_VS2_EN_ADDR MT6359_BUCK_VS2_DBG1
#define MT6359_RG_BUCK_VS2_VOSEL_ADDR MT6359_BUCK_VS2_ELR0
#define MT6359_RG_BUCK_VS2_VOSEL_MASK 0x7F
#define MT6359_RG_BUCK_VS2_VOSEL_SHIFT 0
#define MT6359_RG_BUCK_VPA_EN_ADDR MT6359_BUCK_VPA_CON0
#define MT6359_RG_BUCK_VPA_LP_ADDR MT6359_BUCK_VPA_CON0
#define MT6359_RG_BUCK_VPA_LP_SHIFT 1
#define MT6359_RG_BUCK_VPA_VOSEL_ADDR MT6359_BUCK_VPA_CON1
#define MT6359_RG_BUCK_VPA_VOSEL_MASK 0x3F
#define MT6359_RG_BUCK_VPA_VOSEL_SHIFT 0
#define MT6359_DA_VPA_VOSEL_ADDR MT6359_BUCK_VPA_DBG0
#define MT6359_DA_VPA_VOSEL_MASK 0x3F
#define MT6359_DA_VPA_VOSEL_SHIFT 0
#define MT6359_DA_VPA_EN_ADDR MT6359_BUCK_VPA_DBG1
#define MT6359_RG_VGPU11_FCCM_ADDR MT6359_VGPUVCORE_ANA_CON2
#define MT6359_RG_VGPU11_FCCM_SHIFT 9
#define MT6359_RG_VCORE_FCCM_ADDR MT6359_VGPUVCORE_ANA_CON13
#define MT6359_RG_VCORE_FCCM_SHIFT 5
#define MT6359_RG_VPROC1_FCCM_ADDR MT6359_VPROC1_ANA_CON3
#define MT6359_RG_VPROC1_FCCM_SHIFT 1
#define MT6359_RG_VPROC2_FCCM_ADDR MT6359_VPROC2_ANA_CON3
#define MT6359_RG_VPROC2_FCCM_SHIFT 1
#define MT6359_RG_VMODEM_FCCM_ADDR MT6359_VMODEM_ANA_CON3
#define MT6359_RG_VMODEM_FCCM_SHIFT 1
#define MT6359_RG_VPU_FCCM_ADDR MT6359_VPU_ANA_CON3
#define MT6359_RG_VPU_FCCM_SHIFT 1
#define MT6359_RG_VS1_FPWM_ADDR MT6359_VS1_ANA_CON0
#define MT6359_RG_VS1_FPWM_SHIFT 3
#define MT6359_RG_VS2_FPWM_ADDR MT6359_VS2_ANA_CON0
#define MT6359_RG_VS2_FPWM_SHIFT 3
#define MT6359_RG_VPA_MODESET_ADDR MT6359_VPA_ANA_CON0
#define MT6359_RG_VPA_MODESET_SHIFT 1
#define MT6359_RG_LDO_VSRAM_PROC1_VOSEL_ADDR MT6359_LDO_VSRAM_PROC1_ELR
#define MT6359_RG_LDO_VSRAM_PROC1_VOSEL_MASK 0x7F
#define MT6359_RG_LDO_VSRAM_PROC1_VOSEL_SHIFT 0
#define MT6359_RG_LDO_VSRAM_PROC2_VOSEL_ADDR MT6359_LDO_VSRAM_PROC2_ELR
#define MT6359_RG_LDO_VSRAM_PROC2_VOSEL_MASK 0x7F
#define MT6359_RG_LDO_VSRAM_PROC2_VOSEL_SHIFT 0
#define MT6359_RG_LDO_VSRAM_OTHERS_VOSEL_ADDR MT6359_LDO_VSRAM_OTHERS_ELR
#define MT6359_RG_LDO_VSRAM_OTHERS_VOSEL_MASK 0x7F
#define MT6359_RG_LDO_VSRAM_OTHERS_VOSEL_SHIFT 0
#define MT6359_RG_LDO_VSRAM_MD_VOSEL_ADDR MT6359_LDO_VSRAM_MD_ELR
#define MT6359_RG_LDO_VSRAM_MD_VOSEL_MASK 0x7F
#define MT6359_RG_LDO_VSRAM_MD_VOSEL_SHIFT 0
#define MT6359_RG_LDO_VFE28_EN_ADDR MT6359_LDO_VFE28_CON0
#define MT6359_DA_VFE28_B_EN_ADDR MT6359_LDO_VFE28_MON
#define MT6359_RG_LDO_VXO22_EN_ADDR MT6359_LDO_VXO22_CON0
#define MT6359_RG_LDO_VXO22_EN_SHIFT 0
#define MT6359_DA_VXO22_B_EN_ADDR MT6359_LDO_VXO22_MON
#define MT6359_RG_LDO_VRF18_EN_ADDR MT6359_LDO_VRF18_CON0
#define MT6359_RG_LDO_VRF18_EN_SHIFT 0
#define MT6359_DA_VRF18_B_EN_ADDR MT6359_LDO_VRF18_MON
#define MT6359_RG_LDO_VRF12_EN_ADDR MT6359_LDO_VRF12_CON0
#define MT6359_RG_LDO_VRF12_EN_SHIFT 0
#define MT6359_DA_VRF12_B_EN_ADDR MT6359_LDO_VRF12_MON
#define MT6359_RG_LDO_VEFUSE_EN_ADDR MT6359_LDO_VEFUSE_CON0
#define MT6359_RG_LDO_VEFUSE_EN_SHIFT 0
#define MT6359_DA_VEFUSE_B_EN_ADDR MT6359_LDO_VEFUSE_MON
#define MT6359_RG_LDO_VCN33_1_EN_0_ADDR MT6359_LDO_VCN33_1_CON0
#define MT6359_RG_LDO_VCN33_1_EN_0_MASK 0x1
#define MT6359_RG_LDO_VCN33_1_EN_0_SHIFT 0
#define MT6359_DA_VCN33_1_B_EN_ADDR MT6359_LDO_VCN33_1_MON
#define MT6359_RG_LDO_VCN33_1_EN_1_ADDR MT6359_LDO_VCN33_1_MULTI_SW
#define MT6359_RG_LDO_VCN33_1_EN_1_SHIFT 15
#define MT6359_RG_LDO_VCN33_2_EN_0_ADDR MT6359_LDO_VCN33_2_CON0
#define MT6359_RG_LDO_VCN33_2_EN_0_SHIFT 0
#define MT6359_DA_VCN33_2_B_EN_ADDR MT6359_LDO_VCN33_2_MON
#define MT6359_RG_LDO_VCN33_2_EN_1_ADDR MT6359_LDO_VCN33_2_MULTI_SW
#define MT6359_RG_LDO_VCN33_2_EN_1_MASK 0x1
#define MT6359_RG_LDO_VCN33_2_EN_1_SHIFT 15
#define MT6359_RG_LDO_VCN13_EN_ADDR MT6359_LDO_VCN13_CON0
#define MT6359_RG_LDO_VCN13_EN_SHIFT 0
#define MT6359_DA_VCN13_B_EN_ADDR MT6359_LDO_VCN13_MON
#define MT6359_RG_LDO_VCN18_EN_ADDR MT6359_LDO_VCN18_CON0
#define MT6359_DA_VCN18_B_EN_ADDR MT6359_LDO_VCN18_MON
#define MT6359_RG_LDO_VA09_EN_ADDR MT6359_LDO_VA09_CON0
#define MT6359_RG_LDO_VA09_EN_SHIFT 0
#define MT6359_DA_VA09_B_EN_ADDR MT6359_LDO_VA09_MON
#define MT6359_RG_LDO_VCAMIO_EN_ADDR MT6359_LDO_VCAMIO_CON0
#define MT6359_RG_LDO_VCAMIO_EN_SHIFT 0
#define MT6359_DA_VCAMIO_B_EN_ADDR MT6359_LDO_VCAMIO_MON
#define MT6359_RG_LDO_VA12_EN_ADDR MT6359_LDO_VA12_CON0
#define MT6359_RG_LDO_VA12_EN_SHIFT 0
#define MT6359_DA_VA12_B_EN_ADDR MT6359_LDO_VA12_MON
#define MT6359_RG_LDO_VAUX18_EN_ADDR MT6359_LDO_VAUX18_CON0
#define MT6359_DA_VAUX18_B_EN_ADDR MT6359_LDO_VAUX18_MON
#define MT6359_RG_LDO_VAUD18_EN_ADDR MT6359_LDO_VAUD18_CON0
#define MT6359_DA_VAUD18_B_EN_ADDR MT6359_LDO_VAUD18_MON
#define MT6359_RG_LDO_VIO18_EN_ADDR MT6359_LDO_VIO18_CON0
#define MT6359_RG_LDO_VIO18_EN_SHIFT 0
#define MT6359_DA_VIO18_B_EN_ADDR MT6359_LDO_VIO18_MON
#define MT6359_RG_LDO_VEMC_EN_ADDR MT6359_LDO_VEMC_CON0
#define MT6359_RG_LDO_VEMC_EN_SHIFT 0
#define MT6359_DA_VEMC_B_EN_ADDR MT6359_LDO_VEMC_MON
#define MT6359_RG_LDO_VSIM1_EN_ADDR MT6359_LDO_VSIM1_CON0
#define MT6359_RG_LDO_VSIM1_EN_SHIFT 0
#define MT6359_DA_VSIM1_B_EN_ADDR MT6359_LDO_VSIM1_MON
#define MT6359_RG_LDO_VSIM2_EN_ADDR MT6359_LDO_VSIM2_CON0
#define MT6359_RG_LDO_VSIM2_EN_SHIFT 0
#define MT6359_DA_VSIM2_B_EN_ADDR MT6359_LDO_VSIM2_MON
#define MT6359_RG_LDO_VUSB_EN_0_ADDR MT6359_LDO_VUSB_CON0
#define MT6359_RG_LDO_VUSB_EN_0_MASK 0x1
#define MT6359_RG_LDO_VUSB_EN_0_SHIFT 0
#define MT6359_DA_VUSB_B_EN_ADDR MT6359_LDO_VUSB_MON
#define MT6359_RG_LDO_VUSB_EN_1_ADDR MT6359_LDO_VUSB_MULTI_SW
#define MT6359_RG_LDO_VUSB_EN_1_MASK 0x1
#define MT6359_RG_LDO_VUSB_EN_1_SHIFT 15
#define MT6359_RG_LDO_VRFCK_EN_ADDR MT6359_LDO_VRFCK_CON0
#define MT6359_RG_LDO_VRFCK_EN_SHIFT 0
#define MT6359_DA_VRFCK_B_EN_ADDR MT6359_LDO_VRFCK_MON
#define MT6359_RG_LDO_VBBCK_EN_ADDR MT6359_LDO_VBBCK_CON0
#define MT6359_RG_LDO_VBBCK_EN_SHIFT 0
#define MT6359_DA_VBBCK_B_EN_ADDR MT6359_LDO_VBBCK_MON
#define MT6359_RG_LDO_VBIF28_EN_ADDR MT6359_LDO_VBIF28_CON0
#define MT6359_DA_VBIF28_B_EN_ADDR MT6359_LDO_VBIF28_MON
#define MT6359_RG_LDO_VIBR_EN_ADDR MT6359_LDO_VIBR_CON0
#define MT6359_RG_LDO_VIBR_EN_SHIFT 0
#define MT6359_DA_VIBR_B_EN_ADDR MT6359_LDO_VIBR_MON
#define MT6359_RG_LDO_VIO28_EN_ADDR MT6359_LDO_VIO28_CON0
#define MT6359_RG_LDO_VIO28_EN_SHIFT 0
#define MT6359_DA_VIO28_B_EN_ADDR MT6359_LDO_VIO28_MON
#define MT6359_RG_LDO_VM18_EN_ADDR MT6359_LDO_VM18_CON0
#define MT6359_RG_LDO_VM18_EN_SHIFT 0
#define MT6359_DA_VM18_B_EN_ADDR MT6359_LDO_VM18_MON
#define MT6359_RG_LDO_VUFS_EN_ADDR MT6359_LDO_VUFS_CON0
#define MT6359_RG_LDO_VUFS_EN_SHIFT 0
#define MT6359_DA_VUFS_B_EN_ADDR MT6359_LDO_VUFS_MON
#define MT6359_RG_LDO_VSRAM_PROC1_EN_ADDR MT6359_LDO_VSRAM_PROC1_CON0
#define MT6359_DA_VSRAM_PROC1_B_EN_ADDR MT6359_LDO_VSRAM_PROC1_MON
#define MT6359_DA_VSRAM_PROC1_VOSEL_ADDR MT6359_LDO_VSRAM_PROC1_VOSEL1
#define MT6359_DA_VSRAM_PROC1_VOSEL_MASK 0x7F
#define MT6359_DA_VSRAM_PROC1_VOSEL_SHIFT 8
#define MT6359_RG_LDO_VSRAM_PROC2_EN_ADDR MT6359_LDO_VSRAM_PROC2_CON0
#define MT6359_DA_VSRAM_PROC2_B_EN_ADDR MT6359_LDO_VSRAM_PROC2_MON
#define MT6359_DA_VSRAM_PROC2_VOSEL_ADDR MT6359_LDO_VSRAM_PROC2_VOSEL1
#define MT6359_DA_VSRAM_PROC2_VOSEL_MASK 0x7F
#define MT6359_DA_VSRAM_PROC2_VOSEL_SHIFT 8
#define MT6359_RG_LDO_VSRAM_OTHERS_EN_ADDR MT6359_LDO_VSRAM_OTHERS_CON0
#define MT6359_DA_VSRAM_OTHERS_B_EN_ADDR MT6359_LDO_VSRAM_OTHERS_MON
#define MT6359_DA_VSRAM_OTHERS_VOSEL_ADDR MT6359_LDO_VSRAM_OTHERS_VOSEL1
#define MT6359_DA_VSRAM_OTHERS_VOSEL_MASK 0x7F
#define MT6359_DA_VSRAM_OTHERS_VOSEL_SHIFT 8
#define MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_EN_ADDR MT6359_LDO_VSRAM_OTHERS_SSHUB
#define MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_ADDR MT6359_LDO_VSRAM_OTHERS_SSHUB
#define MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_MASK 0x7F
#define MT6359_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_SHIFT 1
#define MT6359_RG_LDO_VSRAM_MD_EN_ADDR MT6359_LDO_VSRAM_MD_CON0
#define MT6359_DA_VSRAM_MD_B_EN_ADDR MT6359_LDO_VSRAM_MD_MON
#define MT6359_DA_VSRAM_MD_VOSEL_ADDR MT6359_LDO_VSRAM_MD_VOSEL1
#define MT6359_DA_VSRAM_MD_VOSEL_MASK 0x7F
#define MT6359_DA_VSRAM_MD_VOSEL_SHIFT 8
#define MT6359_RG_VCN33_1_VOSEL_ADDR MT6359_VCN33_1_ANA_CON0
#define MT6359_RG_VCN33_1_VOSEL_MASK 0xF
#define MT6359_RG_VCN33_1_VOSEL_SHIFT 8
#define MT6359_RG_VCN33_2_VOSEL_ADDR MT6359_VCN33_2_ANA_CON0
#define MT6359_RG_VCN33_2_VOSEL_MASK 0xF
#define MT6359_RG_VCN33_2_VOSEL_SHIFT 8
#define MT6359_RG_VEMC_VOSEL_ADDR MT6359_VEMC_ANA_CON0
#define MT6359_RG_VEMC_VOSEL_MASK 0xF
#define MT6359_RG_VEMC_VOSEL_SHIFT 8
#define MT6359_RG_VSIM1_VOSEL_ADDR MT6359_VSIM1_ANA_CON0
#define MT6359_RG_VSIM1_VOSEL_MASK 0xF
#define MT6359_RG_VSIM1_VOSEL_SHIFT 8
#define MT6359_RG_VSIM2_VOSEL_ADDR MT6359_VSIM2_ANA_CON0
#define MT6359_RG_VSIM2_VOSEL_MASK 0xF
#define MT6359_RG_VSIM2_VOSEL_SHIFT 8
#define MT6359_RG_VIO28_VOSEL_ADDR MT6359_VIO28_ANA_CON0
#define MT6359_RG_VIO28_VOSEL_MASK 0xF
#define MT6359_RG_VIO28_VOSEL_SHIFT 8
#define MT6359_RG_VIBR_VOSEL_ADDR MT6359_VIBR_ANA_CON0
#define MT6359_RG_VIBR_VOSEL_MASK 0xF
#define MT6359_RG_VIBR_VOSEL_SHIFT 8
#define MT6359_RG_VRF18_VOSEL_ADDR MT6359_VRF18_ANA_CON0
#define MT6359_RG_VRF18_VOSEL_MASK 0xF
#define MT6359_RG_VRF18_VOSEL_SHIFT 8
#define MT6359_RG_VEFUSE_VOSEL_ADDR MT6359_VEFUSE_ANA_CON0
#define MT6359_RG_VEFUSE_VOSEL_MASK 0xF
#define MT6359_RG_VEFUSE_VOSEL_SHIFT 8
#define MT6359_RG_VCAMIO_VOSEL_ADDR MT6359_VCAMIO_ANA_CON0
#define MT6359_RG_VCAMIO_VOSEL_MASK 0xF
#define MT6359_RG_VCAMIO_VOSEL_SHIFT 8
#define MT6359_RG_VIO18_VOSEL_ADDR MT6359_VIO18_ANA_CON0
#define MT6359_RG_VIO18_VOSEL_MASK 0xF
#define MT6359_RG_VIO18_VOSEL_SHIFT 8
#define MT6359_RG_VM18_VOSEL_ADDR MT6359_VM18_ANA_CON0
#define MT6359_RG_VM18_VOSEL_MASK 0xF
#define MT6359_RG_VM18_VOSEL_SHIFT 8
#define MT6359_RG_VUFS_VOSEL_ADDR MT6359_VUFS_ANA_CON0
#define MT6359_RG_VUFS_VOSEL_MASK 0xF
#define MT6359_RG_VUFS_VOSEL_SHIFT 8
#define MT6359_RG_VRF12_VOSEL_ADDR MT6359_VRF12_ANA_CON0
#define MT6359_RG_VRF12_VOSEL_MASK 0xF
#define MT6359_RG_VRF12_VOSEL_SHIFT 8
#define MT6359_RG_VCN13_VOSEL_ADDR MT6359_VCN13_ANA_CON0
#define MT6359_RG_VCN13_VOSEL_MASK 0xF
#define MT6359_RG_VCN13_VOSEL_SHIFT 8
#define MT6359_RG_VA09_VOSEL_ADDR MT6359_VA09_ANA_CON0
#define MT6359_RG_VA09_VOSEL_MASK 0xF
#define MT6359_RG_VA09_VOSEL_SHIFT 8
#define MT6359_RG_VA12_VOSEL_ADDR MT6359_VA12_ANA_CON0
#define MT6359_RG_VA12_VOSEL_MASK 0xF
#define MT6359_RG_VA12_VOSEL_SHIFT 8
#define MT6359_RG_VXO22_VOSEL_ADDR MT6359_VXO22_ANA_CON0
#define MT6359_RG_VXO22_VOSEL_MASK 0xF
#define MT6359_RG_VXO22_VOSEL_SHIFT 8
#define MT6359_RG_VRFCK_VOSEL_ADDR MT6359_VRFCK_ANA_CON0
#define MT6359_RG_VRFCK_VOSEL_MASK 0xF
#define MT6359_RG_VRFCK_VOSEL_SHIFT 8
#define MT6359_RG_VBBCK_VOSEL_ADDR MT6359_VBBCK_ANA_CON0
#define MT6359_RG_VBBCK_VOSEL_MASK 0xF
#define MT6359_RG_VBBCK_VOSEL_SHIFT 8
#endif /* __MFD_MT6359_REGISTERS_H__ */

View File

@ -0,0 +1,249 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#ifndef __MFD_MT6359P_REGISTERS_H__
#define __MFD_MT6359P_REGISTERS_H__
#define MT6359P_CHIP_VER 0x5930
/* PMIC Registers */
#define MT6359P_HWCID 0x8
#define MT6359P_TOP_TRAP 0x50
#define MT6359P_TOP_TMA_KEY 0x3a8
#define MT6359P_BUCK_VCORE_ELR_NUM 0x152a
#define MT6359P_BUCK_VCORE_ELR0 0x152c
#define MT6359P_BUCK_VGPU11_SSHUB_CON0 0x15aa
#define MT6359P_BUCK_VGPU11_ELR0 0x15b4
#define MT6359P_LDO_VSRAM_PROC1_ELR 0x1b44
#define MT6359P_LDO_VSRAM_PROC2_ELR 0x1b46
#define MT6359P_LDO_VSRAM_OTHERS_ELR 0x1b48
#define MT6359P_LDO_VSRAM_MD_ELR 0x1b4a
#define MT6359P_LDO_VEMC_ELR_0 0x1b4c
#define MT6359P_LDO_VFE28_CON0 0x1b88
#define MT6359P_LDO_VFE28_MON 0x1b8c
#define MT6359P_LDO_VXO22_CON0 0x1b9a
#define MT6359P_LDO_VXO22_MON 0x1b9e
#define MT6359P_LDO_VRF18_CON0 0x1bac
#define MT6359P_LDO_VRF18_MON 0x1bb0
#define MT6359P_LDO_VRF12_CON0 0x1bbe
#define MT6359P_LDO_VRF12_MON 0x1bc2
#define MT6359P_LDO_VEFUSE_CON0 0x1bd0
#define MT6359P_LDO_VEFUSE_MON 0x1bd4
#define MT6359P_LDO_VCN33_1_CON0 0x1be2
#define MT6359P_LDO_VCN33_1_MON 0x1be6
#define MT6359P_LDO_VCN33_1_MULTI_SW 0x1bf4
#define MT6359P_LDO_VCN33_2_CON0 0x1c08
#define MT6359P_LDO_VCN33_2_MON 0x1c0c
#define MT6359P_LDO_VCN33_2_MULTI_SW 0x1c1a
#define MT6359P_LDO_VCN13_CON0 0x1c1c
#define MT6359P_LDO_VCN13_MON 0x1c20
#define MT6359P_LDO_VCN18_CON0 0x1c2e
#define MT6359P_LDO_VCN18_MON 0x1c32
#define MT6359P_LDO_VA09_CON0 0x1c40
#define MT6359P_LDO_VA09_MON 0x1c44
#define MT6359P_LDO_VCAMIO_CON0 0x1c52
#define MT6359P_LDO_VCAMIO_MON 0x1c56
#define MT6359P_LDO_VA12_CON0 0x1c64
#define MT6359P_LDO_VA12_MON 0x1c68
#define MT6359P_LDO_VAUX18_CON0 0x1c88
#define MT6359P_LDO_VAUX18_MON 0x1c8c
#define MT6359P_LDO_VAUD18_CON0 0x1c9a
#define MT6359P_LDO_VAUD18_MON 0x1c9e
#define MT6359P_LDO_VIO18_CON0 0x1cac
#define MT6359P_LDO_VIO18_MON 0x1cb0
#define MT6359P_LDO_VEMC_CON0 0x1cbe
#define MT6359P_LDO_VEMC_MON 0x1cc2
#define MT6359P_LDO_VSIM1_CON0 0x1cd0
#define MT6359P_LDO_VSIM1_MON 0x1cd4
#define MT6359P_LDO_VSIM2_CON0 0x1ce2
#define MT6359P_LDO_VSIM2_MON 0x1ce6
#define MT6359P_LDO_VUSB_CON0 0x1d08
#define MT6359P_LDO_VUSB_MON 0x1d0c
#define MT6359P_LDO_VUSB_MULTI_SW 0x1d1a
#define MT6359P_LDO_VRFCK_CON0 0x1d1c
#define MT6359P_LDO_VRFCK_MON 0x1d20
#define MT6359P_LDO_VBBCK_CON0 0x1d2e
#define MT6359P_LDO_VBBCK_MON 0x1d32
#define MT6359P_LDO_VBIF28_CON0 0x1d40
#define MT6359P_LDO_VBIF28_MON 0x1d44
#define MT6359P_LDO_VIBR_CON0 0x1d52
#define MT6359P_LDO_VIBR_MON 0x1d56
#define MT6359P_LDO_VIO28_CON0 0x1d64
#define MT6359P_LDO_VIO28_MON 0x1d68
#define MT6359P_LDO_VM18_CON0 0x1d88
#define MT6359P_LDO_VM18_MON 0x1d8c
#define MT6359P_LDO_VUFS_CON0 0x1d9a
#define MT6359P_LDO_VUFS_MON 0x1d9e
#define MT6359P_LDO_VSRAM_PROC1_CON0 0x1e88
#define MT6359P_LDO_VSRAM_PROC1_MON 0x1e8c
#define MT6359P_LDO_VSRAM_PROC1_VOSEL1 0x1e90
#define MT6359P_LDO_VSRAM_PROC2_CON0 0x1ea8
#define MT6359P_LDO_VSRAM_PROC2_MON 0x1eac
#define MT6359P_LDO_VSRAM_PROC2_VOSEL1 0x1eb0
#define MT6359P_LDO_VSRAM_OTHERS_CON0 0x1f08
#define MT6359P_LDO_VSRAM_OTHERS_MON 0x1f0c
#define MT6359P_LDO_VSRAM_OTHERS_VOSEL1 0x1f10
#define MT6359P_LDO_VSRAM_OTHERS_SSHUB 0x1f28
#define MT6359P_LDO_VSRAM_MD_CON0 0x1f2e
#define MT6359P_LDO_VSRAM_MD_MON 0x1f32
#define MT6359P_LDO_VSRAM_MD_VOSEL1 0x1f36
#define MT6359P_VFE28_ANA_CON0 0x1f88
#define MT6359P_VAUX18_ANA_CON0 0x1f8c
#define MT6359P_VUSB_ANA_CON0 0x1f90
#define MT6359P_VBIF28_ANA_CON0 0x1f94
#define MT6359P_VCN33_1_ANA_CON0 0x1f98
#define MT6359P_VCN33_2_ANA_CON0 0x1f9c
#define MT6359P_VEMC_ANA_CON0 0x1fa0
#define MT6359P_VSIM1_ANA_CON0 0x1fa2
#define MT6359P_VSIM2_ANA_CON0 0x1fa6
#define MT6359P_VIO28_ANA_CON0 0x1faa
#define MT6359P_VIBR_ANA_CON0 0x1fae
#define MT6359P_VFE28_ELR_4 0x1fc0
#define MT6359P_VRF18_ANA_CON0 0x2008
#define MT6359P_VEFUSE_ANA_CON0 0x200c
#define MT6359P_VCN18_ANA_CON0 0x2010
#define MT6359P_VCAMIO_ANA_CON0 0x2014
#define MT6359P_VAUD18_ANA_CON0 0x2018
#define MT6359P_VIO18_ANA_CON0 0x201c
#define MT6359P_VM18_ANA_CON0 0x2020
#define MT6359P_VUFS_ANA_CON0 0x2024
#define MT6359P_VRF12_ANA_CON0 0x202a
#define MT6359P_VCN13_ANA_CON0 0x202e
#define MT6359P_VA09_ANA_CON0 0x2032
#define MT6359P_VRF18_ELR_3 0x204e
#define MT6359P_VXO22_ANA_CON0 0x2088
#define MT6359P_VRFCK_ANA_CON0 0x208c
#define MT6359P_VBBCK_ANA_CON0 0x2096
#define MT6359P_RG_BUCK_VCORE_VOSEL_ADDR MT6359P_BUCK_VCORE_ELR0
#define MT6359P_RG_BUCK_VGPU11_SSHUB_EN_ADDR MT6359P_BUCK_VGPU11_SSHUB_CON0
#define MT6359P_RG_BUCK_VGPU11_VOSEL_ADDR MT6359P_BUCK_VGPU11_ELR0
#define MT6359P_RG_BUCK_VGPU11_SSHUB_VOSEL_ADDR MT6359P_BUCK_VGPU11_SSHUB_CON0
#define MT6359P_RG_BUCK_VGPU11_SSHUB_VOSEL_MASK 0x7F
#define MT6359P_RG_BUCK_VGPU11_SSHUB_VOSEL_SHIFT 4
#define MT6359P_RG_LDO_VSRAM_PROC1_VOSEL_ADDR MT6359P_LDO_VSRAM_PROC1_ELR
#define MT6359P_RG_LDO_VSRAM_PROC2_VOSEL_ADDR MT6359P_LDO_VSRAM_PROC2_ELR
#define MT6359P_RG_LDO_VSRAM_OTHERS_VOSEL_ADDR MT6359P_LDO_VSRAM_OTHERS_ELR
#define MT6359P_RG_LDO_VSRAM_MD_VOSEL_ADDR MT6359P_LDO_VSRAM_MD_ELR
#define MT6359P_RG_LDO_VEMC_VOSEL_0_ADDR MT6359P_LDO_VEMC_ELR_0
#define MT6359P_RG_LDO_VEMC_VOSEL_0_MASK 0xF
#define MT6359P_RG_LDO_VEMC_VOSEL_0_SHIFT 0
#define MT6359P_RG_LDO_VFE28_EN_ADDR MT6359P_LDO_VFE28_CON0
#define MT6359P_DA_VFE28_B_EN_ADDR MT6359P_LDO_VFE28_MON
#define MT6359P_RG_LDO_VXO22_EN_ADDR MT6359P_LDO_VXO22_CON0
#define MT6359P_RG_LDO_VXO22_EN_SHIFT 0
#define MT6359P_DA_VXO22_B_EN_ADDR MT6359P_LDO_VXO22_MON
#define MT6359P_RG_LDO_VRF18_EN_ADDR MT6359P_LDO_VRF18_CON0
#define MT6359P_RG_LDO_VRF18_EN_SHIFT 0
#define MT6359P_DA_VRF18_B_EN_ADDR MT6359P_LDO_VRF18_MON
#define MT6359P_RG_LDO_VRF12_EN_ADDR MT6359P_LDO_VRF12_CON0
#define MT6359P_RG_LDO_VRF12_EN_SHIFT 0
#define MT6359P_DA_VRF12_B_EN_ADDR MT6359P_LDO_VRF12_MON
#define MT6359P_RG_LDO_VEFUSE_EN_ADDR MT6359P_LDO_VEFUSE_CON0
#define MT6359P_RG_LDO_VEFUSE_EN_SHIFT 0
#define MT6359P_DA_VEFUSE_B_EN_ADDR MT6359P_LDO_VEFUSE_MON
#define MT6359P_RG_LDO_VCN33_1_EN_0_ADDR MT6359P_LDO_VCN33_1_CON0
#define MT6359P_DA_VCN33_1_B_EN_ADDR MT6359P_LDO_VCN33_1_MON
#define MT6359P_RG_LDO_VCN33_1_EN_1_ADDR MT6359P_LDO_VCN33_1_MULTI_SW
#define MT6359P_RG_LDO_VCN33_1_EN_1_SHIFT 15
#define MT6359P_RG_LDO_VCN33_2_EN_0_ADDR MT6359P_LDO_VCN33_2_CON0
#define MT6359P_RG_LDO_VCN33_2_EN_0_SHIFT 0
#define MT6359P_DA_VCN33_2_B_EN_ADDR MT6359P_LDO_VCN33_2_MON
#define MT6359P_RG_LDO_VCN33_2_EN_1_ADDR MT6359P_LDO_VCN33_2_MULTI_SW
#define MT6359P_RG_LDO_VCN13_EN_ADDR MT6359P_LDO_VCN13_CON0
#define MT6359P_RG_LDO_VCN13_EN_SHIFT 0
#define MT6359P_DA_VCN13_B_EN_ADDR MT6359P_LDO_VCN13_MON
#define MT6359P_RG_LDO_VCN18_EN_ADDR MT6359P_LDO_VCN18_CON0
#define MT6359P_DA_VCN18_B_EN_ADDR MT6359P_LDO_VCN18_MON
#define MT6359P_RG_LDO_VA09_EN_ADDR MT6359P_LDO_VA09_CON0
#define MT6359P_RG_LDO_VA09_EN_SHIFT 0
#define MT6359P_DA_VA09_B_EN_ADDR MT6359P_LDO_VA09_MON
#define MT6359P_RG_LDO_VCAMIO_EN_ADDR MT6359P_LDO_VCAMIO_CON0
#define MT6359P_RG_LDO_VCAMIO_EN_SHIFT 0
#define MT6359P_DA_VCAMIO_B_EN_ADDR MT6359P_LDO_VCAMIO_MON
#define MT6359P_RG_LDO_VA12_EN_ADDR MT6359P_LDO_VA12_CON0
#define MT6359P_RG_LDO_VA12_EN_SHIFT 0
#define MT6359P_DA_VA12_B_EN_ADDR MT6359P_LDO_VA12_MON
#define MT6359P_RG_LDO_VAUX18_EN_ADDR MT6359P_LDO_VAUX18_CON0
#define MT6359P_DA_VAUX18_B_EN_ADDR MT6359P_LDO_VAUX18_MON
#define MT6359P_RG_LDO_VAUD18_EN_ADDR MT6359P_LDO_VAUD18_CON0
#define MT6359P_DA_VAUD18_B_EN_ADDR MT6359P_LDO_VAUD18_MON
#define MT6359P_RG_LDO_VIO18_EN_ADDR MT6359P_LDO_VIO18_CON0
#define MT6359P_RG_LDO_VIO18_EN_SHIFT 0
#define MT6359P_DA_VIO18_B_EN_ADDR MT6359P_LDO_VIO18_MON
#define MT6359P_RG_LDO_VEMC_EN_ADDR MT6359P_LDO_VEMC_CON0
#define MT6359P_RG_LDO_VEMC_EN_SHIFT 0
#define MT6359P_DA_VEMC_B_EN_ADDR MT6359P_LDO_VEMC_MON
#define MT6359P_RG_LDO_VSIM1_EN_ADDR MT6359P_LDO_VSIM1_CON0
#define MT6359P_RG_LDO_VSIM1_EN_SHIFT 0
#define MT6359P_DA_VSIM1_B_EN_ADDR MT6359P_LDO_VSIM1_MON
#define MT6359P_RG_LDO_VSIM2_EN_ADDR MT6359P_LDO_VSIM2_CON0
#define MT6359P_RG_LDO_VSIM2_EN_SHIFT 0
#define MT6359P_DA_VSIM2_B_EN_ADDR MT6359P_LDO_VSIM2_MON
#define MT6359P_RG_LDO_VUSB_EN_0_ADDR MT6359P_LDO_VUSB_CON0
#define MT6359P_DA_VUSB_B_EN_ADDR MT6359P_LDO_VUSB_MON
#define MT6359P_RG_LDO_VUSB_EN_1_ADDR MT6359P_LDO_VUSB_MULTI_SW
#define MT6359P_RG_LDO_VRFCK_EN_ADDR MT6359P_LDO_VRFCK_CON0
#define MT6359P_RG_LDO_VRFCK_EN_SHIFT 0
#define MT6359P_DA_VRFCK_B_EN_ADDR MT6359P_LDO_VRFCK_MON
#define MT6359P_RG_LDO_VBBCK_EN_ADDR MT6359P_LDO_VBBCK_CON0
#define MT6359P_RG_LDO_VBBCK_EN_SHIFT 0
#define MT6359P_DA_VBBCK_B_EN_ADDR MT6359P_LDO_VBBCK_MON
#define MT6359P_RG_LDO_VBIF28_EN_ADDR MT6359P_LDO_VBIF28_CON0
#define MT6359P_DA_VBIF28_B_EN_ADDR MT6359P_LDO_VBIF28_MON
#define MT6359P_RG_LDO_VIBR_EN_ADDR MT6359P_LDO_VIBR_CON0
#define MT6359P_RG_LDO_VIBR_EN_SHIFT 0
#define MT6359P_DA_VIBR_B_EN_ADDR MT6359P_LDO_VIBR_MON
#define MT6359P_RG_LDO_VIO28_EN_ADDR MT6359P_LDO_VIO28_CON0
#define MT6359P_RG_LDO_VIO28_EN_SHIFT 0
#define MT6359P_DA_VIO28_B_EN_ADDR MT6359P_LDO_VIO28_MON
#define MT6359P_RG_LDO_VM18_EN_ADDR MT6359P_LDO_VM18_CON0
#define MT6359P_RG_LDO_VM18_EN_SHIFT 0
#define MT6359P_DA_VM18_B_EN_ADDR MT6359P_LDO_VM18_MON
#define MT6359P_RG_LDO_VUFS_EN_ADDR MT6359P_LDO_VUFS_CON0
#define MT6359P_RG_LDO_VUFS_EN_SHIFT 0
#define MT6359P_DA_VUFS_B_EN_ADDR MT6359P_LDO_VUFS_MON
#define MT6359P_RG_LDO_VSRAM_PROC1_EN_ADDR MT6359P_LDO_VSRAM_PROC1_CON0
#define MT6359P_DA_VSRAM_PROC1_B_EN_ADDR MT6359P_LDO_VSRAM_PROC1_MON
#define MT6359P_DA_VSRAM_PROC1_VOSEL_ADDR MT6359P_LDO_VSRAM_PROC1_VOSEL1
#define MT6359P_RG_LDO_VSRAM_PROC2_EN_ADDR MT6359P_LDO_VSRAM_PROC2_CON0
#define MT6359P_DA_VSRAM_PROC2_B_EN_ADDR MT6359P_LDO_VSRAM_PROC2_MON
#define MT6359P_DA_VSRAM_PROC2_VOSEL_ADDR MT6359P_LDO_VSRAM_PROC2_VOSEL1
#define MT6359P_RG_LDO_VSRAM_OTHERS_EN_ADDR MT6359P_LDO_VSRAM_OTHERS_CON0
#define MT6359P_DA_VSRAM_OTHERS_B_EN_ADDR MT6359P_LDO_VSRAM_OTHERS_MON
#define MT6359P_DA_VSRAM_OTHERS_VOSEL_ADDR MT6359P_LDO_VSRAM_OTHERS_VOSEL1
#define MT6359P_RG_LDO_VSRAM_OTHERS_SSHUB_EN_ADDR MT6359P_LDO_VSRAM_OTHERS_SSHUB
#define MT6359P_RG_LDO_VSRAM_OTHERS_SSHUB_VOSEL_ADDR MT6359P_LDO_VSRAM_OTHERS_SSHUB
#define MT6359P_RG_LDO_VSRAM_MD_EN_ADDR MT6359P_LDO_VSRAM_MD_CON0
#define MT6359P_DA_VSRAM_MD_B_EN_ADDR MT6359P_LDO_VSRAM_MD_MON
#define MT6359P_DA_VSRAM_MD_VOSEL_ADDR MT6359P_LDO_VSRAM_MD_VOSEL1
#define MT6359P_RG_VCN33_1_VOSEL_ADDR MT6359P_VCN33_1_ANA_CON0
#define MT6359P_RG_VCN33_2_VOSEL_ADDR MT6359P_VCN33_2_ANA_CON0
#define MT6359P_RG_VEMC_VOSEL_ADDR MT6359P_VEMC_ANA_CON0
#define MT6359P_RG_VSIM1_VOSEL_ADDR MT6359P_VSIM1_ANA_CON0
#define MT6359P_RG_VSIM2_VOSEL_ADDR MT6359P_VSIM2_ANA_CON0
#define MT6359P_RG_VIO28_VOSEL_ADDR MT6359P_VIO28_ANA_CON0
#define MT6359P_RG_VIBR_VOSEL_ADDR MT6359P_VIBR_ANA_CON0
#define MT6359P_RG_VRF18_VOSEL_ADDR MT6359P_VRF18_ANA_CON0
#define MT6359P_RG_VEFUSE_VOSEL_ADDR MT6359P_VEFUSE_ANA_CON0
#define MT6359P_RG_VCAMIO_VOSEL_ADDR MT6359P_VCAMIO_ANA_CON0
#define MT6359P_RG_VIO18_VOSEL_ADDR MT6359P_VIO18_ANA_CON0
#define MT6359P_RG_VM18_VOSEL_ADDR MT6359P_VM18_ANA_CON0
#define MT6359P_RG_VUFS_VOSEL_ADDR MT6359P_VUFS_ANA_CON0
#define MT6359P_RG_VRF12_VOSEL_ADDR MT6359P_VRF12_ANA_CON0
#define MT6359P_RG_VCN13_VOSEL_ADDR MT6359P_VCN13_ANA_CON0
#define MT6359P_RG_VA09_VOSEL_ADDR MT6359P_VRF18_ELR_3
#define MT6359P_RG_VA12_VOSEL_ADDR MT6359P_VFE28_ELR_4
#define MT6359P_RG_VXO22_VOSEL_ADDR MT6359P_VXO22_ANA_CON0
#define MT6359P_RG_VRFCK_VOSEL_ADDR MT6359P_VRFCK_ANA_CON0
#define MT6359P_RG_VBBCK_VOSEL_ADDR MT6359P_VBBCK_ANA_CON0
#define MT6359P_RG_VBBCK_VOSEL_MASK 0xF
#define MT6359P_RG_VBBCK_VOSEL_SHIFT 4
#define MT6359P_VM_MODE_ADDR MT6359P_TOP_TRAP
#define MT6359P_TMA_KEY_ADDR MT6359P_TOP_TMA_KEY
#define TMA_KEY 0x9CA6
#endif /* __MFD_MT6359P_REGISTERS_H__ */

View File

@ -13,6 +13,7 @@
enum chip_id {
MT6323_CHIP_ID = 0x23,
MT6358_CHIP_ID = 0x58,
MT6359_CHIP_ID = 0x59,
MT6391_CHIP_ID = 0x91,
MT6397_CHIP_ID = 0x97,
};

View File

@ -36,6 +36,7 @@
#define RTC_AL_MASK_DOW BIT(4)
#define RTC_TC_SEC 0x000a
#define RTC_TC_MTH_MASK 0x000f
/* Min, Hour, Dom... register offset to RTC_TC_SEC */
#define RTC_OFFSET_SEC 0
#define RTC_OFFSET_MIN 1

View File

@ -79,6 +79,7 @@ extern char poweroff_cmd[POWEROFF_CMD_PATH_LEN];
extern void orderly_poweroff(bool force);
extern void orderly_reboot(void);
void hw_protection_shutdown(const char *reason, int ms_until_forced);
/*
* Emergency restart, callable from an interrupt handler.

View File

@ -119,6 +119,16 @@ struct regulator_dev;
#define REGULATOR_EVENT_PRE_DISABLE 0x400
#define REGULATOR_EVENT_ABORT_DISABLE 0x800
#define REGULATOR_EVENT_ENABLE 0x1000
/*
* Following notifications should be emitted only if detected condition
* is such that the HW is likely to still be working but consumers should
* take a recovery action to prevent problems esacalating into errors.
*/
#define REGULATOR_EVENT_UNDER_VOLTAGE_WARN 0x2000
#define REGULATOR_EVENT_OVER_CURRENT_WARN 0x4000
#define REGULATOR_EVENT_OVER_VOLTAGE_WARN 0x8000
#define REGULATOR_EVENT_OVER_TEMP_WARN 0x10000
#define REGULATOR_EVENT_WARN_MASK 0x1E000
/*
* Regulator errors that can be queried using regulator_get_error_flags
@ -138,6 +148,10 @@ struct regulator_dev;
#define REGULATOR_ERROR_FAIL BIT(4)
#define REGULATOR_ERROR_OVER_TEMP BIT(5)
#define REGULATOR_ERROR_UNDER_VOLTAGE_WARN BIT(6)
#define REGULATOR_ERROR_OVER_CURRENT_WARN BIT(7)
#define REGULATOR_ERROR_OVER_VOLTAGE_WARN BIT(8)
#define REGULATOR_ERROR_OVER_TEMP_WARN BIT(9)
/**
* struct pre_voltage_change_data - Data sent with PRE_VOLTAGE_CHANGE event

View File

@ -52,7 +52,6 @@ struct regulator_coupler {
#ifdef CONFIG_REGULATOR
int regulator_coupler_register(struct regulator_coupler *coupler);
const char *rdev_get_name(struct regulator_dev *rdev);
int regulator_check_consumers(struct regulator_dev *rdev,
int *min_uV, int *max_uV,
suspend_state_t state);
@ -69,10 +68,6 @@ static inline int regulator_coupler_register(struct regulator_coupler *coupler)
{
return 0;
}
static inline const char *rdev_get_name(struct regulator_dev *rdev)
{
return NULL;
}
static inline int regulator_check_consumers(struct regulator_dev *rdev,
int *min_uV, int *max_uV,
suspend_state_t state)

View File

@ -40,6 +40,15 @@ enum regulator_status {
REGULATOR_STATUS_UNDEFINED,
};
enum regulator_detection_severity {
/* Hardware shut down voltage outputs if condition is detected */
REGULATOR_SEVERITY_PROT,
/* Hardware is probably damaged/inoperable */
REGULATOR_SEVERITY_ERR,
/* Hardware is still recoverable but recovery action must be taken */
REGULATOR_SEVERITY_WARN,
};
/* Initialize struct linear_range for regulators */
#define REGULATOR_LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV) \
{ \
@ -78,8 +87,25 @@ enum regulator_status {
* @get_current_limit: Get the configured limit for a current-limited regulator.
* @set_input_current_limit: Configure an input limit.
*
* @set_over_current_protection: Support capability of automatically shutting
* down when detecting an over current event.
* @set_over_current_protection: Support enabling of and setting limits for over
* current situation detection. Detection can be configured for three
* levels of severity.
* REGULATOR_SEVERITY_PROT should automatically shut down the regulator(s).
* REGULATOR_SEVERITY_ERR should indicate that over-current situation is
* caused by an unrecoverable error but HW does not perform
* automatic shut down.
* REGULATOR_SEVERITY_WARN should indicate situation where hardware is
* still believed to not be damaged but that a board sepcific
* recovery action is needed. If lim_uA is 0 the limit should not
* be changed but the detection should just be enabled/disabled as
* is requested.
* @set_over_voltage_protection: Support enabling of and setting limits for over
* voltage situation detection. Detection can be configured for same
* severities as over current protection.
* @set_under_voltage_protection: Support enabling of and setting limits for
* under situation detection.
* @set_thermal_protection: Support enabling of and setting limits for over
* temperature situation detection.
*
* @set_active_discharge: Set active discharge enable/disable of regulators.
*
@ -143,7 +169,14 @@ struct regulator_ops {
int (*get_current_limit) (struct regulator_dev *);
int (*set_input_current_limit) (struct regulator_dev *, int lim_uA);
int (*set_over_current_protection) (struct regulator_dev *);
int (*set_over_current_protection)(struct regulator_dev *, int lim_uA,
int severity, bool enable);
int (*set_over_voltage_protection)(struct regulator_dev *, int lim_uV,
int severity, bool enable);
int (*set_under_voltage_protection)(struct regulator_dev *, int lim_uV,
int severity, bool enable);
int (*set_thermal_protection)(struct regulator_dev *, int lim,
int severity, bool enable);
int (*set_active_discharge)(struct regulator_dev *, bool enable);
/* enable/disable regulator */
@ -413,6 +446,128 @@ struct regulator_config {
struct gpio_desc *ena_gpiod;
};
/**
* struct regulator_err_state - regulator error/notification status
*
* @rdev: Regulator which status the struct indicates.
* @notifs: Events which have occurred on the regulator.
* @errors: Errors which are active on the regulator.
* @possible_errs: Errors which can be signaled (by given IRQ).
*/
struct regulator_err_state {
struct regulator_dev *rdev;
unsigned long notifs;
unsigned long errors;
int possible_errs;
};
/**
* struct regulator_irq_data - regulator error/notification status date
*
* @states: Status structs for each of the associated regulators.
* @num_states: Amount of associated regulators.
* @data: Driver data pointer given at regulator_irq_desc.
* @opaque: Value storage for IC driver. Core does not update this. ICs
* may want to store status register value here at map_event and
* compare contents at 'renable' callback to see if new problems
* have been added to status. If that is the case it may be
* desirable to return REGULATOR_ERROR_CLEARED and not
* REGULATOR_ERROR_ON to allow IRQ fire again and to generate
* notifications also for the new issues.
*
* This structure is passed to 'map_event' and 'renable' callbacks for
* reporting regulator status to core.
*/
struct regulator_irq_data {
struct regulator_err_state *states;
int num_states;
void *data;
long opaque;
};
/**
* struct regulator_irq_desc - notification sender for IRQ based events.
*
* @name: The visible name for the IRQ
* @fatal_cnt: If this IRQ is used to signal HW damaging condition it may be
* best to shut-down regulator(s) or reboot the SOC if error
* handling is repeatedly failing. If fatal_cnt is given the IRQ
* handling is aborted if it fails for fatal_cnt times and die()
* callback (if populated) or BUG() is called to try to prevent
* further damage.
* @reread_ms: The time which is waited before attempting to re-read status
* at the worker if IC reading fails. Immediate re-read is done
* if time is not specified.
* @irq_off_ms: The time which IRQ is kept disabled before re-evaluating the
* status for devices which keep IRQ disabled for duration of the
* error. If this is not given the IRQ is left enabled and renable
* is not called.
* @skip_off: If set to true the IRQ handler will attempt to check if any of
* the associated regulators are enabled prior to taking other
* actions. If no regulators are enabled and this is set to true
* a spurious IRQ is assumed and IRQ_NONE is returned.
* @high_prio: Boolean to indicate that high priority WQ should be used.
* @data: Driver private data pointer which will be passed as such to
* the renable, map_event and die callbacks in regulator_irq_data.
* @die: Protection callback. If IC status reading or recovery actions
* fail fatal_cnt times this callback or BUG() is called. This
* callback should implement a final protection attempt like
* disabling the regulator. If protection succeeded this may
* return 0. If anything else is returned the core assumes final
* protection failed and calls BUG() as a last resort.
* @map_event: Driver callback to map IRQ status into regulator devices with
* events / errors. NOTE: callback MUST initialize both the
* errors and notifs for all rdevs which it signals having
* active events as core does not clean the map data.
* REGULATOR_FAILED_RETRY can be returned to indicate that the
* status reading from IC failed. If this is repeated for
* fatal_cnt times the core will call die() callback or BUG()
* as a last resort to protect the HW.
* @renable: Optional callback to check status (if HW supports that) before
* re-enabling IRQ. If implemented this should clear the error
* flags so that errors fetched by regulator_get_error_flags()
* are updated. If callback is not implemented then errors are
* assumed to be cleared and IRQ is re-enabled.
* REGULATOR_FAILED_RETRY can be returned to
* indicate that the status reading from IC failed. If this is
* repeated for 'fatal_cnt' times the core will call die()
* callback or BUG() as a last resort to protect the HW.
* Returning zero indicates that the problem in HW has been solved
* and IRQ will be re-enabled. Returning REGULATOR_ERROR_ON
* indicates the error condition is still active and keeps IRQ
* disabled. Please note that returning REGULATOR_ERROR_ON does
* not retrigger evaluating what events are active or resending
* notifications. If this is needed you probably want to return
* zero and allow IRQ to retrigger causing events to be
* re-evaluated and re-sent.
*
* This structure is used for registering regulator IRQ notification helper.
*/
struct regulator_irq_desc {
const char *name;
int irq_flags;
int fatal_cnt;
int reread_ms;
int irq_off_ms;
bool skip_off;
bool high_prio;
void *data;
int (*die)(struct regulator_irq_data *rid);
int (*map_event)(int irq, struct regulator_irq_data *rid,
unsigned long *dev_mask);
int (*renable)(struct regulator_irq_data *rid);
};
/*
* Return values for regulator IRQ helpers.
*/
enum {
REGULATOR_ERROR_CLEARED,
REGULATOR_FAILED_RETRY,
REGULATOR_ERROR_ON,
};
/*
* struct coupling_desc
*
@ -477,6 +632,9 @@ struct regulator_dev {
/* time when this regulator was disabled last time */
ktime_t last_off;
int cached_err;
bool use_cached_err;
spinlock_t err_lock;
};
struct regulator_dev *
@ -491,6 +649,16 @@ void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev);
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data);
void *devm_regulator_irq_helper(struct device *dev,
const struct regulator_irq_desc *d, int irq,
int irq_flags, int common_errs,
int *per_rdev_errs, struct regulator_dev **rdev,
int rdev_amount);
void *regulator_irq_helper(struct device *dev,
const struct regulator_irq_desc *d, int irq,
int irq_flags, int common_errs, int *per_rdev_errs,
struct regulator_dev **rdev, int rdev_amount);
void regulator_irq_helper_cancel(void **handle);
void *rdev_get_drvdata(struct regulator_dev *rdev);
struct device *rdev_get_dev(struct regulator_dev *rdev);
@ -540,6 +708,7 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay);
int regulator_sync_voltage_rdev(struct regulator_dev *rdev);
/*
* Helper functions intended to be used by regulator drivers prior registering
@ -550,4 +719,14 @@ int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc,
int regulator_desc_list_voltage_linear(const struct regulator_desc *desc,
unsigned int selector);
#ifdef CONFIG_REGULATOR
const char *rdev_get_name(struct regulator_dev *rdev);
#else
static inline const char *rdev_get_name(struct regulator_dev *rdev)
{
return NULL;
}
#endif
#endif

View File

@ -83,6 +83,14 @@ struct regulator_state {
bool changeable;
};
#define REGULATOR_NOTIF_LIMIT_DISABLE -1
#define REGULATOR_NOTIF_LIMIT_ENABLE -2
struct notification_limit {
int prot;
int err;
int warn;
};
/**
* struct regulation_constraints - regulator operating constraints.
*
@ -100,6 +108,11 @@ struct regulator_state {
* @ilim_uA: Maximum input current.
* @system_load: Load that isn't captured by any consumer requests.
*
* @over_curr_limits: Limits for acting on over current.
* @over_voltage_limits: Limits for acting on over voltage.
* @under_voltage_limits: Limits for acting on under voltage.
* @temp_limits: Limits for acting on over temperature.
* @max_spread: Max possible spread between coupled regulators
* @max_uV_step: Max possible step change in voltage
* @valid_modes_mask: Mask of modes which may be configured by consumers.
@ -116,6 +129,11 @@ struct regulator_state {
* @pull_down: Enable pull down when regulator is disabled.
* @over_current_protection: Auto disable on over current event.
*
* @over_current_detection: Configure over current limits.
* @over_voltage_detection: Configure over voltage limits.
* @under_voltage_detection: Configure under voltage limits.
* @over_temp_detection: Configure over temperature limits.
*
* @input_uV: Input voltage for regulator when supplied by another regulator.
*
* @state_disk: State for regulator when system is suspended in disk mode.
@ -172,6 +190,10 @@ struct regulation_constraints {
struct regulator_state state_disk;
struct regulator_state state_mem;
struct regulator_state state_standby;
struct notification_limit over_curr_limits;
struct notification_limit over_voltage_limits;
struct notification_limit under_voltage_limits;
struct notification_limit temp_limits;
suspend_state_t initial_state; /* suspend state to set at init */
/* mode to set on startup */
@ -193,6 +215,10 @@ struct regulation_constraints {
unsigned soft_start:1; /* ramp voltage slowly */
unsigned pull_down:1; /* pull down resistor when regulator off */
unsigned over_current_protection:1; /* auto disable on over current */
unsigned over_current_detection:1; /* notify on over current */
unsigned over_voltage_detection:1; /* notify on over voltage */
unsigned under_voltage_detection:1; /* notify on under voltage */
unsigned over_temp_detection:1; /* notify on over temperature */
};
/**

View File

@ -0,0 +1,59 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#ifndef __LINUX_REGULATOR_MT6359_H
#define __LINUX_REGULATOR_MT6359_H
enum {
MT6359_ID_VS1 = 0,
MT6359_ID_VGPU11,
MT6359_ID_VMODEM,
MT6359_ID_VPU,
MT6359_ID_VCORE,
MT6359_ID_VS2,
MT6359_ID_VPA,
MT6359_ID_VPROC2,
MT6359_ID_VPROC1,
MT6359_ID_VCORE_SSHUB,
MT6359_ID_VGPU11_SSHUB = MT6359_ID_VCORE_SSHUB,
MT6359_ID_VAUD18 = 10,
MT6359_ID_VSIM1,
MT6359_ID_VIBR,
MT6359_ID_VRF12,
MT6359_ID_VUSB,
MT6359_ID_VSRAM_PROC2,
MT6359_ID_VIO18,
MT6359_ID_VCAMIO,
MT6359_ID_VCN18,
MT6359_ID_VFE28,
MT6359_ID_VCN13,
MT6359_ID_VCN33_1_BT,
MT6359_ID_VCN33_1_WIFI,
MT6359_ID_VAUX18,
MT6359_ID_VSRAM_OTHERS,
MT6359_ID_VEFUSE,
MT6359_ID_VXO22,
MT6359_ID_VRFCK,
MT6359_ID_VBIF28,
MT6359_ID_VIO28,
MT6359_ID_VEMC,
MT6359_ID_VCN33_2_BT,
MT6359_ID_VCN33_2_WIFI,
MT6359_ID_VA12,
MT6359_ID_VA09,
MT6359_ID_VRF18,
MT6359_ID_VSRAM_MD,
MT6359_ID_VUFS,
MT6359_ID_VM18,
MT6359_ID_VBBCK,
MT6359_ID_VSRAM_PROC1,
MT6359_ID_VSIM2,
MT6359_ID_VSRAM_OTHERS_SSHUB,
MT6359_ID_RG_MAX,
};
#define MT6359_MAX_REGULATOR MT6359_ID_RG_MAX
#endif /* __LINUX_REGULATOR_MT6359_H */

View File

@ -7,6 +7,7 @@
#define pr_fmt(fmt) "reboot: " fmt
#include <linux/atomic.h>
#include <linux/ctype.h>
#include <linux/export.h>
#include <linux/kexec.h>
@ -518,6 +519,84 @@ void orderly_reboot(void)
}
EXPORT_SYMBOL_GPL(orderly_reboot);
/**
* hw_failure_emergency_poweroff_func - emergency poweroff work after a known delay
* @work: work_struct associated with the emergency poweroff function
*
* This function is called in very critical situations to force
* a kernel poweroff after a configurable timeout value.
*/
static void hw_failure_emergency_poweroff_func(struct work_struct *work)
{
/*
* We have reached here after the emergency shutdown waiting period has
* expired. This means orderly_poweroff has not been able to shut off
* the system for some reason.
*
* Try to shut down the system immediately using kernel_power_off
* if populated
*/
pr_emerg("Hardware protection timed-out. Trying forced poweroff\n");
kernel_power_off();
/*
* Worst of the worst case trigger emergency restart
*/
pr_emerg("Hardware protection shutdown failed. Trying emergency restart\n");
emergency_restart();
}
static DECLARE_DELAYED_WORK(hw_failure_emergency_poweroff_work,
hw_failure_emergency_poweroff_func);
/**
* hw_failure_emergency_poweroff - Trigger an emergency system poweroff
*
* This may be called from any critical situation to trigger a system shutdown
* after a given period of time. If time is negative this is not scheduled.
*/
static void hw_failure_emergency_poweroff(int poweroff_delay_ms)
{
if (poweroff_delay_ms <= 0)
return;
schedule_delayed_work(&hw_failure_emergency_poweroff_work,
msecs_to_jiffies(poweroff_delay_ms));
}
/**
* hw_protection_shutdown - Trigger an emergency system poweroff
*
* @reason: Reason of emergency shutdown to be printed.
* @ms_until_forced: Time to wait for orderly shutdown before tiggering a
* forced shudown. Negative value disables the forced
* shutdown.
*
* Initiate an emergency system shutdown in order to protect hardware from
* further damage. Usage examples include a thermal protection or a voltage or
* current regulator failures.
* NOTE: The request is ignored if protection shutdown is already pending even
* if the previous request has given a large timeout for forced shutdown.
* Can be called from any context.
*/
void hw_protection_shutdown(const char *reason, int ms_until_forced)
{
static atomic_t allow_proceed = ATOMIC_INIT(1);
pr_emerg("HARDWARE PROTECTION shutdown (%s)\n", reason);
/* Shutdown should be initiated only once. */
if (!atomic_dec_and_test(&allow_proceed))
return;
/*
* Queue a backup emergency shutdown in the event of
* orderly_poweroff failure
*/
hw_failure_emergency_poweroff(ms_until_forced);
orderly_poweroff(true);
}
EXPORT_SYMBOL_GPL(hw_protection_shutdown);
static int __init reboot_setup(char *str)
{
for (;;) {