regulator: Updates for v5.9

This time around the bulk of the work on the regulator API has been
 cleanups of various kinds, partly but not entirely inspired by the W=1
 stuff that 0day turned on.  There's also been a fairly large crop of new
 drivers, and a few bugfixes for existing drivers.
 
  - Mode setting support for MT6397 and DA9211.
  - New drivers for ChromeOS embedded controllers, Fairchild FAN53880,
    NXP PCA9450, Qualcomm LABIBB, MP5496, and VBUS booster, and Silergy
    SY8827N
 -----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCgAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAl8n+tcTHGJyb29uaWVA
 a2VybmVsLm9yZwAKCRAk1otyXVSH0AbDB/9d9/CX9OK0qy4qMew7t/+bmHNKWB4O
 jlVSp6Raj9dF3siLCaWT70jKrCEKBUIMSiA6c6UqWGHPbHLvvsTuu1aau2APIi/w
 PDrnAfcku7J6CJMl4wwkn1Sh8vobXtqeZbT0Ydfx7QRzI+AMqz7CWLrOh9ET3Z3S
 lN85GT7lqiG1hD+frep1FzpZDorzZa4Xvml7/7ns51IRn9NezdjRFBTG1dsZuKy6
 GPEFXgLCfhaYs7zY1Tk9l5sMAdG/1OU/OvT4w4xmo7PkEZGYAHLSJfHQdRu2LwZU
 r9YSVJ+COOfqaoml08XbFx1U12zWHgln+5ty+EuLxNNl4taBPpLqZDBC
 =JJHu
 -----END PGP SIGNATURE-----

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

Pull regulator updates from Mark Brown:
 "This time around the bulk of the work on the regulator API has been
  cleanups of various kinds, partly but not entirely inspired by the W=1
  stuff that 0day turned on.

  There's also been a fairly large crop of new drivers, and a few
  bugfixes for existing drivers.

   - Mode setting support for MT6397 and DA9211.

   - New drivers for ChromeOS embedded controllers, Fairchild FAN53880,
     NXP PCA9450, Qualcomm LABIBB, MP5496, and VBUS booster, and Silergy
     SY8827N"

* tag 'regulator-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (67 commits)
  regulator: add the sub node names for the MP5496 PMIC
  regulator: cros-ec-regulator: Fix double free of desc->name.
  platform/chrome: cros_ec: Fix host command for regulator control.
  regulator: pca9450: Convert to use module_i2c_driver
  regulator: fix memory leak on error path of regulator_register()
  regulator: Replace HTTP links with HTTPS ones
  regulator: convert QCOM SMD-RPM regulator document to YAML schema
  regulator: gpio: Honor regulator-boot-on property
  regulator: core: Add destroy_regulator()
  regulator: Correct kernel-doc inconsistency
  regulator: Add labibb regulator binding
  regulator: qcom: Add labibb driver
  regulator: Allow regulators to verify enabled during enable()
  regulator: cros-ec: Constify cros_ec_regulator_voltage_ops
  regulator: devres: Standardise on function documentation headers
  regulator: of_regulator: Add missing colon for rdev kerneldoc argument
  regulator: devres: Fix issues with kerneldoc headers
  regulator: fan53880: Add support for COMPILE_TEST
  regulator: fan53880: Add missing .owner field in regulator_desc
  dt-bindings: regulator: add pca9450 regulator yaml
  ...
This commit is contained in:
Linus Torvalds 2020-08-03 20:05:44 -07:00
commit bbb839901f
64 changed files with 3042 additions and 487 deletions

View File

@ -15,6 +15,8 @@ Required properties:
Optional properties:
- enable-gpios: platform gpio for control of BUCKA/BUCKB.
- Any optional property defined in regulator.txt
- regulator-initial-mode and regulator-allowed-modes may be specified using
mode values from dt-bindings/regulator/dlg,da9211-regulator.h
Example 1) DA9211
pmic: da9211@68 {
@ -30,6 +32,8 @@ Example 1) DA9211
regulator-min-microamp = <2000000>;
regulator-max-microamp = <5000000>;
enable-gpios = <&gpio 27 0>;
regulator-allowed-modes = <DA9211_BUCK_MODE_SYNC
DA9211_BUCK_MODE_AUTO>;
};
};
};

View File

@ -0,0 +1,51 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/google,cros-ec-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ChromeOS EC controlled voltage regulators
maintainers:
- Pi-Hsun Shih <pihsun@chromium.org>
description:
Any property defined as part of the core regulator binding, defined in
regulator.yaml, can also be used.
allOf:
- $ref: "regulator.yaml#"
properties:
compatible:
const: google,cros-ec-regulator
reg:
maxItems: 1
description: Identifier for the voltage regulator to ChromeOS EC.
required:
- compatible
- reg
examples:
- |
spi0 {
#address-cells = <1>;
#size-cells = <0>;
cros_ec: ec@0 {
compatible = "google,cros-ec-spi";
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
regulator@0 {
compatible = "google,cros-ec-regulator";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
reg = <0>;
};
};
};
...

View File

@ -37,8 +37,8 @@ Optional properties:
(Documentation/devicetree/bindings/regulator/regulator.txt)
Datasheet
- LP8720: http://www.ti.com/lit/ds/symlink/lp8720.pdf
- LP8725: http://www.ti.com/lit/ds/symlink/lp8725.pdf
- LP8720: https://www.ti.com/lit/ds/symlink/lp8720.pdf
- LP8725: https://www.ti.com/lit/ds/symlink/lp8725.pdf
Example 1) LP8720

View File

@ -16,6 +16,9 @@ LDO:
ldo_vemc3v3, ldo_vgp1, ldo_vgp2, ldo_vgp3, ldo_vgp4, ldo_vgp5, ldo_vgp6,
ldo_vibr
BUCK regulators can set regulator-initial-mode and regulator-allowed-modes to
values specified in dt-bindings/regulator/mediatek,mt6397-regulator.h
Example:
pmic {
compatible = "mediatek,mt6397";

View File

@ -0,0 +1,190 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/nxp,pca9450-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP PCA9450A/B/C Power Management Integrated Circuit regulators
maintainers:
- Robin Gong <yibin.gong@nxp.com>
description: |
Regulator nodes should be named to BUCK_<number> and LDO_<number>. The
definition for each of these nodes is defined using the standard
binding for regulators at
Documentation/devicetree/bindings/regulator/regulator.txt.
Datasheet is available at
https://www.nxp.com/docs/en/data-sheet/PCA9450DS.pdf
#The valid names for PCA9450 regulator nodes are:
#BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6,
#LDO1, LDO2, LDO3, LDO4, LDO5
#Note: Buck3 removed on PCA9450B and connect with Buck1 on PCA9450C.
properties:
compatible:
enum:
- nxp,pca9450a
- nxp,pca9450b
- nxp,pca9450c
reg:
maxItems: 1
interrupts:
maxItems: 1
regulators:
type: object
description: |
list of regulators provided by this controller
patternProperties:
"^LDO[1-5]$":
type: object
$ref: regulator.yaml#
description:
Properties for single LDO regulator.
properties:
regulator-name:
pattern: "^LDO[1-5]$"
description:
should be "LDO1", ..., "LDO5"
unevaluatedProperties: false
"^BUCK[1-6]$":
type: object
$ref: regulator.yaml#
description:
Properties for single BUCK regulator.
properties:
regulator-name:
pattern: "^BUCK[1-6]$"
description:
should be "BUCK1", ..., "BUCK6"
nxp,dvs-run-voltage:
$ref: "/schemas/types.yaml#/definitions/uint32"
minimum: 600000
maximum: 2187500
description:
PMIC default "RUN" state voltage in uV. Only Buck1~3 have such
dvs(dynamic voltage scaling) property.
nxp,dvs-standby-voltage:
$ref: "/schemas/types.yaml#/definitions/uint32"
minimum: 600000
maximum: 2187500
description:
PMIC default "STANDBY" state voltage in uV. Only Buck1~3 have such
dvs(dynamic voltage scaling) property.
unevaluatedProperties: false
additionalProperties: false
required:
- compatible
- reg
- interrupts
- regulators
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic: pmic@25 {
compatible = "nxp,pca9450b";
reg = <0x25>;
pinctrl-0 = <&pinctrl_pmic>;
interrupt-parent = <&gpio1>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
regulators {
buck1: BUCK1 {
regulator-name = "BUCK1";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <2187500>;
regulator-boot-on;
regulator-always-on;
regulator-ramp-delay = <3125>;
};
buck2: BUCK2 {
regulator-name = "BUCK2";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <2187500>;
regulator-boot-on;
regulator-always-on;
regulator-ramp-delay = <3125>;
nxp,dvs-run-voltage = <950000>;
nxp,dvs-standby-voltage = <850000>;
};
buck4: BUCK4 {
regulator-name = "BUCK4";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <3400000>;
regulator-boot-on;
regulator-always-on;
};
buck5: BUCK5 {
regulator-name = "BUCK5";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <3400000>;
regulator-boot-on;
regulator-always-on;
};
buck6: BUCK6 {
regulator-name = "BUCK6";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <3400000>;
regulator-boot-on;
regulator-always-on;
};
ldo1: LDO1 {
regulator-name = "LDO1";
regulator-min-microvolt = <1600000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
};
ldo2: LDO2 {
regulator-name = "LDO2";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1150000>;
regulator-boot-on;
regulator-always-on;
};
ldo3: LDO3 {
regulator-name = "LDO3";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
};
ldo4: LDO4 {
regulator-name = "LDO4";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
};
ldo5: LDO5 {
regulator-name = "LDO5";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
};
};
};
};

View File

@ -0,0 +1,85 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/onnn,fan53880.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Onsemi FAN53880 PMIC
maintainers:
- Christoph Fritz <chf.fritz@googlemail.com>
description: |
The FAN53880 is an I2C porgrammable power management IC (PMIC)
that contains a BUCK (step-down converter), four low dropouts (LDO)
and one BOOST (step-up converter) output. It is designed for mobile
power applications.
properties:
$nodename:
pattern: "pmic@[0-9a-f]{1,2}"
compatible:
enum:
- onnn,fan53880
reg:
maxItems: 1
VIN12-supply:
description: Input supply phandle(s) for LDO1 and LDO2
VIN3-supply:
description: Input supply phandle(s) for LDO3
VIN4-supply:
description: Input supply phandle(s) for LDO4
PVIN-supply:
description: Input supply phandle(s) for BUCK and BOOST
regulators:
type: object
$ref: regulator.yaml#
description: |
list of regulators provided by this controller, must be named
after their hardware counterparts LDO[1-4], BUCK and BOOST
patternProperties:
"^LDO[1-4]$":
type: object
$ref: regulator.yaml#
"^BUCK|BOOST$":
type: object
$ref: regulator.yaml#
additionalProperties: false
required:
- compatible
- reg
- regulators
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@35 {
compatible = "onnn,fan53880";
reg = <0x35>;
PVIN-supply = <&fixreg_example_vcc>;
regulators {
BUCK {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
};
};
};
};
...

View File

@ -1,320 +0,0 @@
QCOM SMD RPM REGULATOR
The Qualcomm RPM over SMD regulator is modelled as a subdevice of the RPM.
Because SMD is used as the communication transport mechanism, the RPM resides as
a subnode of the SMD. As such, the SMD-RPM regulator requires that the SMD and
RPM nodes be present.
Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt for
information pertaining to the SMD node.
Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt for
information regarding the RPM node.
== Regulator
Regulator nodes are identified by their compatible:
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,rpm-pm8841-regulators"
"qcom,rpm-pm8916-regulators"
"qcom,rpm-pm8941-regulators"
"qcom,rpm-pm8950-regulators"
"qcom,rpm-pm8994-regulators"
"qcom,rpm-pm8998-regulators"
"qcom,rpm-pma8084-regulators"
"qcom,rpm-pmi8994-regulators"
"qcom,rpm-pmi8998-regulators"
"qcom,rpm-pms405-regulators"
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_s5-supply:
- vdd_s6-supply:
- vdd_s7-supply:
- vdd_s8-supply:
Usage: optional (pm8841 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_l1_l2_l3-supply:
- vdd_l4_l5_l6-supply:
- vdd_l7-supply:
- vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18-supply:
Usage: optional (pm8916 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_s4-supply:
- vdd_s5-supply:
- vdd_s6-supply:
- vdd_l1_l19-supply:
- vdd_l2_l23-supply:
- vdd_l3-supply:
- vdd_l4_l5_l6_l7_l16-supply:
- vdd_l8_l11_l12_l17_l22-supply:
- vdd_l9_l10_l13_l14_l15_l18-supply:
- vdd_l20-supply:
- vdd_l21-supply:
Usage: optional (pm8950 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_l1_l3-supply:
- vdd_l2_lvs1_2_3-supply:
- vdd_l4_l11-supply:
- vdd_l5_l7-supply:
- vdd_l6_l12_l14_l15-supply:
- vdd_l8_l16_l18_l19-supply:
- vdd_l9_l10_l17_l22-supply:
- vdd_l13_l20_l23_l24-supply:
- vdd_l21-supply:
- vin_5vs-supply:
Usage: optional (pm8941 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_s5-supply:
- vdd_s6-supply:
- vdd_s7-supply:
- vdd_s8-supply:
- vdd_s9-supply:
- vdd_s10-supply:
- vdd_s11-supply:
- vdd_s12-supply:
- vdd_l1-supply:
- vdd_l2_l26_l28-supply:
- vdd_l3_l11-supply:
- vdd_l4_l27_l31-supply:
- vdd_l5_l7-supply:
- vdd_l6_l12_l32-supply:
- vdd_l5_l7-supply:
- vdd_l8_l16_l30-supply:
- vdd_l9_l10_l18_l22-supply:
- vdd_l9_l10_l18_l22-supply:
- vdd_l3_l11-supply:
- vdd_l6_l12_l32-supply:
- vdd_l13_l19_l23_l24-supply:
- vdd_l14_l15-supply:
- vdd_l14_l15-supply:
- vdd_l8_l16_l30-supply:
- vdd_l17_l29-supply:
- vdd_l9_l10_l18_l22-supply:
- vdd_l13_l19_l23_l24-supply:
- vdd_l20_l21-supply:
- vdd_l20_l21-supply:
- vdd_l9_l10_l18_l22-supply:
- vdd_l13_l19_l23_l24-supply:
- vdd_l13_l19_l23_l24-supply:
- vdd_l25-supply:
- vdd_l2_l26_l28-supply:
- vdd_l4_l27_l31-supply:
- vdd_l2_l26_l28-supply:
- vdd_l17_l29-supply:
- vdd_l8_l16_l30-supply:
- vdd_l4_l27_l31-supply:
- vdd_l6_l12_l32-supply:
- vdd_lvs1_2-supply:
Usage: optional (pm8994 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_bst_byp-supply:
Usage: optional (pmi8994 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_s5-supply:
- vdd_s6-supply:
- vdd_s7-supply:
- vdd_s8-supply:
- vdd_s9-supply:
- vdd_s10-supply:
- vdd_s11-supply:
- vdd_s12-supply:
- vdd_s13-supply:
- vdd_l1_l27-supply:
- vdd_l20_l24-supply:
- vdd_l26-supply:
- vdd_l2_l8_l17-supply:
- vdd_l3_l11-supply:
- vdd_l4_l5-supply:
- vdd_l6-supply:
- vdd_l7_l12_l14_l15-supply:
- vdd_l9-supply:
- vdd_l10_l23_l25-supply:
- vdd_l13_l19_l21-supply:
- vdd_l16_l28-supply:
- vdd_l18_l22-supply:
- vdd_lvs1_lvs2-supply:
Usage: optional (pmi8998 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_s5-supply:
- vdd_s6-supply:
- vdd_s7-supply:
- vdd_s8-supply:
- vdd_s9-supply:
- vdd_s10-supply:
- vdd_s11-supply:
- vdd_s12-supply:
- vdd_l1_l11-supply:
- vdd_l2_l3_l4_l27-supply:
- vdd_l5_l7-supply:
- vdd_l6_l12_l14_l15_l26-supply:
- vdd_l8-supply:
- vdd_l9_l10_l13_l20_l23_l24-supply:
- vdd_l16_l25-supply:
- vdd_l17-supply:
- vdd_l18-supply:
- vdd_l19-supply:
- vdd_l21-supply:
- vdd_l22-supply:
Usage: optional (pma8084 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_bob-supply:
Usage: optional (pmi8998 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_s5-supply:
- vdd_l1_l2-supply:
- vdd_l3_l8-supply:
- vdd_l4-supply:
- vdd_l5_l6-supply:
- vdd_l7-supply:
- vdd_l3_l8-supply:
- vdd_l9-supply:
- vdd_l10_l11_l12_l13-supply:
Usage: optional (pms405 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
The regulator node houses sub-nodes for each regulator within the device. Each
sub-node is identified using the node's name, with valid values listed for each
of the pmics below.
pm8841:
s1, s2, s3, s4, s5, s6, s7, s8
pm8916:
s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13,
l14, l15, l16, l17, l18
pm8941:
s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13,
l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2,
lvs3, 5vs1, 5vs2
pm8994:
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, 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, l29, l30, l31, l32, lvs1, lvs2
pm8998:
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, 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, lvs2
pma8084:
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, 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, lvs1, lvs2, lvs3, lvs4, 5vs1
pmi8994:
s1, s2, s3, boost-bypass
pmi8998:
bob
pms405:
s1, s2, s3, s4, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12,
l13
The content of each sub-node is defined by the standard binding for regulators -
see regulator.txt.
= EXAMPLE
smd {
compatible = "qcom,smd";
rpm {
interrupts = <0 168 1>;
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
rpm_requests {
compatible = "qcom,rpm-msm8974";
qcom,smd-channels = "rpm_requests";
pm8941-regulators {
compatible = "qcom,rpm-pm8941-regulators";
vdd_l13_l20_l23_l24-supply = <&pm8941_boost>;
pm8941_s3: s3 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
pm8941_boost: s4 {
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
pm8941_l20: l20 {
regulator-min-microvolt = <2950000>;
regulator-max-microvolt = <2950000>;
};
};
};
};
};

View File

@ -0,0 +1,108 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/qcom,smd-rpm-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: QCOM SMD RPM REGULATOR
description:
The Qualcomm RPM over SMD regulator is modelled as a subdevice of the RPM.
Because SMD is used as the communication transport mechanism, the RPM
resides as a subnode of the SMD. As such, the SMD-RPM regulator requires
that the SMD and RPM nodes be present.
Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt for
information pertaining to the SMD node.
Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml
for information regarding the RPM node.
The regulator node houses sub-nodes for each regulator within the device.
Each sub-node is identified using the node's name, with valid values listed
for each of the pmics below.
For mp5496, s2
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,
l12, l13, l14, l15, l16, l17, l18
For pm8941, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2,
lvs3, 5vs1, 5vs2
For pm8994, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, 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, l29, l30, l31, l32, lvs1, lvs2
For pm8998, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, 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, lvs2
For pma8084, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, 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, lvs1, lvs2, lvs3, lvs4, 5vs1
For pmi8994, s1, s2, s3, boost-bypass
For pmi8998, bob
For pms405, s1, s2, s3, s4, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
l12, l13
maintainers:
- Kathiravan T <kathirav@codeaurora.org>
properties:
compatible:
enum:
- qcom,rpm-mp5496-regulators
- qcom,rpm-pm8841-regulators
- qcom,rpm-pm8916-regulators
- qcom,rpm-pm8941-regulators
- qcom,rpm-pm8950-regulators
- qcom,rpm-pm8994-regulators
- qcom,rpm-pm8998-regulators
- qcom,rpm-pma8084-regulators
- qcom,rpm-pmi8994-regulators
- qcom,rpm-pmi8998-regulators
- qcom,rpm-pms405-regulators
patternProperties:
".*-supply$":
description: Input supply phandle(s) for this node
"^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$":
description: List of regulators and its properties
allOf:
- $ref: regulator.yaml#
additionalProperties: false
required:
- compatible
examples:
- |
pm8941-regulators {
compatible = "qcom,rpm-pm8941-regulators";
vdd_l13_l20_l23_l24-supply = <&pm8941_boost>;
pm8941_s3: s3 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
pm8941_boost: s4 {
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
pm8941_l20: l20 {
regulator-min-microvolt = <2950000>;
regulator-max-microvolt = <2950000>;
};
};
...

View File

@ -0,0 +1,41 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/qcom,usb-vbus-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: The Qualcomm PMIC VBUS output regulator driver
maintainers:
- Wesley Cheng <wcheng@codeaurora.org>
description: |
This regulator driver controls the VBUS output by the Qualcomm PMIC. This
regulator will be enabled in situations where the device is required to
provide power to the connected peripheral.
properties:
compatible:
enum:
- qcom,pm8150b-vbus-reg
reg:
maxItems: 1
description: VBUS output base address
required:
- compatible
additionalProperties: false
examples:
- |
pm8150b {
#address-cells = <1>;
#size-cells = <0>;
pm8150b_vbus: dcdc@1100 {
compatible = "qcom,pm8150b-vbus-reg";
reg = <0x1100>;
};
};
...

View File

@ -0,0 +1,70 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/qcom-labibb-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm's LAB(LCD AMOLED Boost)/IBB(Inverting Buck Boost) Regulator
maintainers:
- Sumit Semwal <sumit.semwal@linaro.org>
description:
LAB can be used as a positive boost power supply and IBB can be used as a
negative boost power supply for display panels. Currently implemented for
pmi8998.
properties:
compatible:
const: qcom,pmi8998-lab-ibb
lab:
type: object
properties:
interrupts:
maxItems: 1
description:
Short-circuit interrupt for lab.
required:
- interrupts
ibb:
type: object
properties:
interrupts:
maxItems: 1
description:
Short-circuit interrupt for lab.
required:
- interrupts
required:
- compatible
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
labibb {
compatible = "qcom,pmi8998-lab-ibb";
lab {
interrupts = <0x3 0x0 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "sc-err";
};
ibb {
interrupts = <0x3 0x2 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "sc-err";
};
};
...

View File

@ -0,0 +1,45 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/silergy,sy8827n.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: silergy sy8827n PMIC
maintainers:
- Jisheng Zhang <jszhang@kernel.org>
properties:
compatible:
enum:
- silergy,sy8827n
reg:
maxItems: 1
enable-gpios:
description: GPIO to enable/disable the regulator.
maxItems: 1
silergy,vsel-state-high:
type: boolean
description:
Indicates if the VSEL pin is set to high.
If this property is missing, assume the VSEL pin is set to low.
required:
- compatible
- reg
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
regulator@60 {
compatible = "silergy,sy8827n";
reg = <0x60>;
};
};
...

View File

@ -161,6 +161,11 @@
TRACE_SYMBOL(EC_CMD_ADC_READ), \
TRACE_SYMBOL(EC_CMD_ROLLBACK_INFO), \
TRACE_SYMBOL(EC_CMD_AP_RESET), \
TRACE_SYMBOL(EC_CMD_REGULATOR_GET_INFO), \
TRACE_SYMBOL(EC_CMD_REGULATOR_ENABLE), \
TRACE_SYMBOL(EC_CMD_REGULATOR_IS_ENABLED), \
TRACE_SYMBOL(EC_CMD_REGULATOR_SET_VOLTAGE), \
TRACE_SYMBOL(EC_CMD_REGULATOR_GET_VOLTAGE), \
TRACE_SYMBOL(EC_CMD_CR51_BASE), \
TRACE_SYMBOL(EC_CMD_CR51_LAST), \
TRACE_SYMBOL(EC_CMD_FP_PASSTHRU), \

View File

@ -238,6 +238,16 @@ config REGULATOR_CPCAP
Say y here for CPCAP regulator found on some Motorola phones
and tablets such as Droid 4.
config REGULATOR_CROS_EC
tristate "ChromeOS EC regulators"
depends on CROS_EC && OF
help
This driver supports voltage regulators that is connected to ChromeOS
EC and controlled through EC host commands.
This driver can also be built as a module. If so, the module
will be called cros-ec-regulator.
config REGULATOR_DA903X
tristate "Dialog Semiconductor DA9030/DA9034 regulators"
depends on PMIC_DA903X
@ -326,6 +336,16 @@ config REGULATOR_FAN53555
input voltage supply of 2.5V to 5.5V. The output voltage is
programmed through an I2C interface.
config REGULATOR_FAN53880
tristate "Fairchild FAN53880 Regulator"
depends on I2C && (OF || COMPILE_TEST)
select REGMAP_I2C
help
This driver supports Fairchild (ON Semiconductor) FAN53880
regulator. The regulator is a programmable power management IC
(PMIC), it is controlled by I2C and provides one BUCK, one BOOST
and four LDO outputs.
config REGULATOR_GPIO
tristate "GPIO regulator support"
depends on GPIOLIB || COMPILE_TEST
@ -730,6 +750,14 @@ config REGULATOR_PBIAS
This driver provides support for OMAP pbias modelled
regulators.
config REGULATOR_PCA9450
tristate "NXP PCA9450A/PCA9450B/PCA9450C regulator driver"
depends on I2C
select REGMAP_I2C
help
Say y here to support the NXP PCA9450A/PCA9450B/PCA9450C PMIC
regulator driver.
config REGULATOR_PCAP
tristate "Motorola PCAP2 regulator driver"
depends on EZX_PCAP
@ -826,6 +854,16 @@ config REGULATOR_QCOM_SPMI
Qualcomm SPMI PMICs as a module. The module will be named
"qcom_spmi-regulator".
config REGULATOR_QCOM_USB_VBUS
tristate "Qualcomm USB Vbus regulator driver"
depends on SPMI || COMPILE_TEST
help
If you say yes to this option, support will be included for the
regulator used to enable the VBUS output.
Say M here if you want to include support for enabling the VBUS output
as a module. The module will be named "qcom_usb_vbus_regulator".
config REGULATOR_RC5T583
tristate "RICOH RC5T583 Power regulators"
depends on MFD_RC5T583
@ -989,6 +1027,13 @@ config REGULATOR_SY8824X
help
This driver supports SY8824C single output regulator.
config REGULATOR_SY8827N
tristate "Silergy SY8827N regulator"
depends on I2C && (OF || COMPILE_TEST)
select REGMAP_I2C
help
This driver supports SY8827N single output regulator.
config REGULATOR_TPS51632
tristate "TI TPS51632 Power Regulator"
depends on I2C
@ -1178,5 +1223,15 @@ config REGULATOR_WM8994
This driver provides support for the voltage regulators on the
WM8994 CODEC.
config REGULATOR_QCOM_LABIBB
tristate "QCOM LAB/IBB regulator support"
depends on SPMI || COMPILE_TEST
help
This driver supports Qualcomm's LAB/IBB regulators present on the
Qualcomm's PMIC chip pmi8998. QCOM LAB and IBB are SPMI
based PMIC implementations. LAB can be used as positive
boost regulator and IBB can be used as a negative boost regulator
for LCD display panel.
endif

View File

@ -13,6 +13,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_88PG86X) += 88pg86x.o
obj-$(CONFIG_REGULATOR_88PM800) += 88pm800-regulator.o
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_CROS_EC) += cros-ec-regulator.o
obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
@ -41,6 +42,7 @@ obj-$(CONFIG_REGULATOR_DA9211) += da9211-regulator.o
obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
obj-$(CONFIG_REGULATOR_FAN53880) += fan53880.o
obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o
obj-$(CONFIG_REGULATOR_HI6421V530) += hi6421v530-regulator.o
@ -88,11 +90,14 @@ obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_USB_VBUS) += qcom_usb_vbus-regulator.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
obj-$(CONFIG_REGULATOR_PCA9450) += pca9450-regulator.o
obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o
obj-$(CONFIG_REGULATOR_PV88080) += pv88080-regulator.o
@ -120,6 +125,7 @@ obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o
obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
obj-$(CONFIG_REGULATOR_SY8824X) += sy8824x.o
obj-$(CONFIG_REGULATOR_SY8827N) += sy8827n.o
obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o

View File

@ -59,6 +59,7 @@ struct ab8500_shared_mode {
* @voltage_bank: bank to control regulator voltage
* @voltage_reg: register to control regulator voltage
* @voltage_mask: mask to control regulator voltage
* @expand_register:
*/
struct ab8500_regulator_info {
struct device *dev;
@ -79,12 +80,6 @@ struct ab8500_regulator_info {
u8 voltage_bank;
u8 voltage_reg;
u8 voltage_mask;
struct {
u8 voltage_limit;
u8 voltage_bank;
u8 voltage_reg;
u8 voltage_mask;
} expand_register;
};
/* voltage tables for the vauxn/vintcore supplies */

View File

@ -139,7 +139,7 @@ static struct regulator_ops anatop_rops = {
.map_voltage = regulator_map_voltage_linear,
};
static struct regulator_ops anatop_core_rops = {
static const struct regulator_ops anatop_core_rops = {
.enable = anatop_regmap_enable,
.disable = anatop_regmap_disable,
.is_enabled = anatop_regmap_is_enabled,

View File

@ -105,6 +105,7 @@ static int regulator_balance_voltage(struct regulator_dev *rdev,
static struct regulator *create_regulator(struct regulator_dev *rdev,
struct device *dev,
const char *supply_name);
static void destroy_regulator(struct regulator *regulator);
static void _regulator_put(struct regulator *regulator);
const char *rdev_get_name(struct regulator_dev *rdev)
@ -2034,20 +2035,9 @@ struct regulator *regulator_get_optional(struct device *dev, const char *id)
}
EXPORT_SYMBOL_GPL(regulator_get_optional);
/* regulator_list_mutex lock held by regulator_put() */
static void _regulator_put(struct regulator *regulator)
static void destroy_regulator(struct regulator *regulator)
{
struct regulator_dev *rdev;
if (IS_ERR_OR_NULL(regulator))
return;
lockdep_assert_held_once(&regulator_list_mutex);
/* Docs say you must disable before calling regulator_put() */
WARN_ON(regulator->enable_count);
rdev = regulator->rdev;
struct regulator_dev *rdev = regulator->rdev;
debugfs_remove_recursive(regulator->debugfs);
@ -2068,6 +2058,24 @@ static void _regulator_put(struct regulator *regulator)
kfree_const(regulator->supply_name);
kfree(regulator);
}
/* regulator_list_mutex lock held by regulator_put() */
static void _regulator_put(struct regulator *regulator)
{
struct regulator_dev *rdev;
if (IS_ERR_OR_NULL(regulator))
return;
lockdep_assert_held_once(&regulator_list_mutex);
/* Docs say you must disable before calling regulator_put() */
WARN_ON(regulator->enable_count);
rdev = regulator->rdev;
destroy_regulator(regulator);
module_put(rdev->owner);
put_device(&rdev->dev);
@ -2347,6 +2355,37 @@ static void _regulator_enable_delay(unsigned int delay)
udelay(us);
}
/**
* _regulator_check_status_enabled
*
* A helper function to check if the regulator status can be interpreted
* as 'regulator is enabled'.
* @rdev: the regulator device to check
*
* Return:
* * 1 - if status shows regulator is in enabled state
* * 0 - if not enabled state
* * Error Value - as received from ops->get_status()
*/
static inline int _regulator_check_status_enabled(struct regulator_dev *rdev)
{
int ret = rdev->desc->ops->get_status(rdev);
if (ret < 0) {
rdev_info(rdev, "get_status returned error: %d\n", ret);
return ret;
}
switch (ret) {
case REGULATOR_STATUS_OFF:
case REGULATOR_STATUS_ERROR:
case REGULATOR_STATUS_UNDEFINED:
return 0;
default:
return 1;
}
}
static int _regulator_do_enable(struct regulator_dev *rdev)
{
int ret, delay;
@ -2407,7 +2446,37 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
* together. */
trace_regulator_enable_delay(rdev_get_name(rdev));
_regulator_enable_delay(delay);
/* If poll_enabled_time is set, poll upto the delay calculated
* above, delaying poll_enabled_time uS to check if the regulator
* actually got enabled.
* If the regulator isn't enabled after enable_delay has
* expired, return -ETIMEDOUT.
*/
if (rdev->desc->poll_enabled_time) {
unsigned int time_remaining = delay;
while (time_remaining > 0) {
_regulator_enable_delay(rdev->desc->poll_enabled_time);
if (rdev->desc->ops->get_status) {
ret = _regulator_check_status_enabled(rdev);
if (ret < 0)
return ret;
else if (ret)
break;
} else if (rdev->desc->ops->is_enabled(rdev))
break;
time_remaining -= rdev->desc->poll_enabled_time;
}
if (time_remaining <= 0) {
rdev_err(rdev, "Enabled check timed out\n");
return -ETIMEDOUT;
}
} else {
_regulator_enable_delay(delay);
}
trace_regulator_enable_complete(rdev_get_name(rdev));
@ -5023,7 +5092,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
struct regulator_dev *rdev;
bool dangling_cfg_gpiod = false;
bool dangling_of_gpiod = false;
bool reg_device_fail = false;
struct device *dev;
int ret, i;
@ -5152,10 +5220,12 @@ regulator_register(const struct regulator_desc *regulator_desc,
}
/* register with sysfs */
device_initialize(&rdev->dev);
rdev->dev.class = &regulator_class;
rdev->dev.parent = dev;
dev_set_name(&rdev->dev, "regulator.%lu",
(unsigned long) atomic_inc_return(&regulator_no));
dev_set_drvdata(&rdev->dev, rdev);
/* set regulator constraints */
if (init_data)
@ -5206,12 +5276,9 @@ regulator_register(const struct regulator_desc *regulator_desc,
!rdev->desc->fixed_uV)
rdev->is_switch = true;
dev_set_drvdata(&rdev->dev, rdev);
ret = device_register(&rdev->dev);
if (ret != 0) {
reg_device_fail = true;
ret = device_add(&rdev->dev);
if (ret != 0)
goto unset_supplies;
}
rdev_init_debugfs(rdev);
@ -5233,17 +5300,15 @@ regulator_register(const struct regulator_desc *regulator_desc,
mutex_unlock(&regulator_list_mutex);
wash:
kfree(rdev->coupling_desc.coupled_rdevs);
kfree(rdev->constraints);
mutex_lock(&regulator_list_mutex);
regulator_ena_gpio_free(rdev);
mutex_unlock(&regulator_list_mutex);
put_device(&rdev->dev);
rdev = NULL;
clean:
if (dangling_of_gpiod)
gpiod_put(config->ena_gpiod);
if (reg_device_fail)
put_device(&rdev->dev);
else
kfree(rdev);
kfree(rdev);
kfree(config);
rinse:
if (dangling_cfg_gpiod)

View File

@ -89,7 +89,7 @@
*/
#define CPCAP_REG_OFF_MODE_SEC BIT(15)
/**
/*
* SoC specific configuration for CPCAP regulator. There are at least three
* different SoCs each with their own parameters: omap3, omap4 and tegra2.
*
@ -169,7 +169,7 @@ enum cpcap_regulator_id {
static int cpcap_regulator_enable(struct regulator_dev *rdev)
{
struct cpcap_regulator *regulator = rdev_get_drvdata(rdev);
int error, ignore;
int error;
error = regulator_enable_regmap(rdev);
if (error)
@ -180,7 +180,7 @@ static int cpcap_regulator_enable(struct regulator_dev *rdev)
regulator->assign_mask,
regulator->assign_mask);
if (error)
ignore = regulator_disable_regmap(rdev);
regulator_disable_regmap(rdev);
}
return error;
@ -193,7 +193,7 @@ static int cpcap_regulator_enable(struct regulator_dev *rdev)
static int cpcap_regulator_disable(struct regulator_dev *rdev)
{
struct cpcap_regulator *regulator = rdev_get_drvdata(rdev);
int error, ignore;
int error;
if (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC) {
error = regmap_update_bits(rdev->regmap, regulator->assign_reg,
@ -204,9 +204,9 @@ static int cpcap_regulator_disable(struct regulator_dev *rdev)
error = regulator_disable_regmap(rdev);
if (error && (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC)) {
ignore = regmap_update_bits(rdev->regmap, regulator->assign_reg,
regulator->assign_mask,
regulator->assign_mask);
regmap_update_bits(rdev->regmap, regulator->assign_reg,
regulator->assign_mask,
regulator->assign_mask);
}
return error;
@ -256,7 +256,7 @@ static int cpcap_regulator_set_mode(struct regulator_dev *rdev,
CPCAP_BIT_AUDIO_LOW_PWR, value);
}
static struct regulator_ops cpcap_regulator_ops = {
static const struct regulator_ops cpcap_regulator_ops = {
.enable = cpcap_regulator_enable,
.disable = cpcap_regulator_disable,
.is_enabled = regulator_is_enabled_regmap,
@ -325,7 +325,7 @@ static const unsigned int vvib_val_tbl[] = { 1300000, 1800000, 2000000,
static const unsigned int vusb_val_tbl[] = { 0, 3300000, };
static const unsigned int vaudio_val_tbl[] = { 0, 2775000, };
/**
/*
* SoC specific configuration for omap4. The data below is comes from Motorola
* Linux kernel tree. It's basically the values of cpcap_regltr_data,
* cpcap_regulator_mode_values and cpcap_regulator_off_mode_values, see

View File

@ -0,0 +1,252 @@
// SPDX-License-Identifier: GPL-2.0-only
//
// Copyright 2020 Google LLC.
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
struct cros_ec_regulator_data {
struct regulator_desc desc;
struct regulator_dev *dev;
struct cros_ec_device *ec_dev;
u32 index;
u16 *voltages_mV;
u16 num_voltages;
};
static int cros_ec_cmd(struct cros_ec_device *ec, u32 version, u32 command,
void *outdata, u32 outsize, void *indata, u32 insize)
{
struct cros_ec_command *msg;
int ret;
msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL);
if (!msg)
return -ENOMEM;
msg->version = version;
msg->command = command;
msg->outsize = outsize;
msg->insize = insize;
if (outdata && outsize > 0)
memcpy(msg->data, outdata, outsize);
ret = cros_ec_cmd_xfer_status(ec, msg);
if (ret < 0)
goto cleanup;
if (insize)
memcpy(indata, msg->data, insize);
cleanup:
kfree(msg);
return ret;
}
static int cros_ec_regulator_enable(struct regulator_dev *dev)
{
struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
struct ec_params_regulator_enable cmd = {
.index = data->index,
.enable = 1,
};
return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,
sizeof(cmd), NULL, 0);
}
static int cros_ec_regulator_disable(struct regulator_dev *dev)
{
struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
struct ec_params_regulator_enable cmd = {
.index = data->index,
.enable = 0,
};
return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,
sizeof(cmd), NULL, 0);
}
static int cros_ec_regulator_is_enabled(struct regulator_dev *dev)
{
struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
struct ec_params_regulator_is_enabled cmd = {
.index = data->index,
};
struct ec_response_regulator_is_enabled resp;
int ret;
ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_IS_ENABLED, &cmd,
sizeof(cmd), &resp, sizeof(resp));
if (ret < 0)
return ret;
return resp.enabled;
}
static int cros_ec_regulator_list_voltage(struct regulator_dev *dev,
unsigned int selector)
{
struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
if (selector >= data->num_voltages)
return -EINVAL;
return data->voltages_mV[selector] * 1000;
}
static int cros_ec_regulator_get_voltage(struct regulator_dev *dev)
{
struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
struct ec_params_regulator_get_voltage cmd = {
.index = data->index,
};
struct ec_response_regulator_get_voltage resp;
int ret;
ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_GET_VOLTAGE, &cmd,
sizeof(cmd), &resp, sizeof(resp));
if (ret < 0)
return ret;
return resp.voltage_mv * 1000;
}
static int cros_ec_regulator_set_voltage(struct regulator_dev *dev, int min_uV,
int max_uV, unsigned int *selector)
{
struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
int min_mV = DIV_ROUND_UP(min_uV, 1000);
int max_mV = max_uV / 1000;
struct ec_params_regulator_set_voltage cmd = {
.index = data->index,
.min_mv = min_mV,
.max_mv = max_mV,
};
/*
* This can happen when the given range [min_uV, max_uV] doesn't
* contain any voltage that can be represented exactly in mV.
*/
if (min_mV > max_mV)
return -EINVAL;
return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_SET_VOLTAGE, &cmd,
sizeof(cmd), NULL, 0);
}
static const struct regulator_ops cros_ec_regulator_voltage_ops = {
.enable = cros_ec_regulator_enable,
.disable = cros_ec_regulator_disable,
.is_enabled = cros_ec_regulator_is_enabled,
.list_voltage = cros_ec_regulator_list_voltage,
.get_voltage = cros_ec_regulator_get_voltage,
.set_voltage = cros_ec_regulator_set_voltage,
};
static int cros_ec_regulator_init_info(struct device *dev,
struct cros_ec_regulator_data *data)
{
struct ec_params_regulator_get_info cmd = {
.index = data->index,
};
struct ec_response_regulator_get_info resp;
int ret;
ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_GET_INFO, &cmd,
sizeof(cmd), &resp, sizeof(resp));
if (ret < 0)
return ret;
data->num_voltages =
min_t(u16, ARRAY_SIZE(resp.voltages_mv), resp.num_voltages);
data->voltages_mV =
devm_kmemdup(dev, resp.voltages_mv,
sizeof(u16) * data->num_voltages, GFP_KERNEL);
data->desc.n_voltages = data->num_voltages;
/* Make sure the returned name is always a valid string */
resp.name[ARRAY_SIZE(resp.name) - 1] = '\0';
data->desc.name = devm_kstrdup(dev, resp.name, GFP_KERNEL);
if (!data->desc.name)
return -ENOMEM;
return 0;
}
static int cros_ec_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct cros_ec_regulator_data *drvdata;
struct regulator_init_data *init_data;
struct regulator_config cfg = {};
struct regulator_desc *desc;
int ret;
drvdata = devm_kzalloc(
&pdev->dev, sizeof(struct cros_ec_regulator_data), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->ec_dev = dev_get_drvdata(dev->parent);
desc = &drvdata->desc;
init_data = of_get_regulator_init_data(dev, np, desc);
if (!init_data)
return -EINVAL;
ret = of_property_read_u32(np, "reg", &drvdata->index);
if (ret < 0)
return ret;
desc->owner = THIS_MODULE;
desc->type = REGULATOR_VOLTAGE;
desc->ops = &cros_ec_regulator_voltage_ops;
ret = cros_ec_regulator_init_info(dev, drvdata);
if (ret < 0)
return ret;
cfg.dev = &pdev->dev;
cfg.init_data = init_data;
cfg.driver_data = drvdata;
cfg.of_node = np;
drvdata->dev = devm_regulator_register(dev, &drvdata->desc, &cfg);
if (IS_ERR(drvdata->dev)) {
dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
return PTR_ERR(drvdata->dev);
}
platform_set_drvdata(pdev, drvdata);
return 0;
}
static const struct of_device_id regulator_cros_ec_of_match[] = {
{ .compatible = "google,cros-ec-regulator", },
{}
};
MODULE_DEVICE_TABLE(of, regulator_cros_ec_of_match);
static struct platform_driver cros_ec_regulator_driver = {
.probe = cros_ec_regulator_probe,
.driver = {
.name = "cros-ec-regulator",
.of_match_table = regulator_cros_ec_of_match,
},
};
module_platform_driver(cros_ec_regulator_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ChromeOS EC controlled regulator");
MODULE_AUTHOR("Pi-Hsun Shih <pihsun@chromium.org>");

View File

@ -17,6 +17,7 @@
#include <linux/gpio/consumer.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/da9211.h>
#include <dt-bindings/regulator/dlg,da9211-regulator.h>
#include "da9211-regulator.h"
/* DEVICE IDs */
@ -24,10 +25,6 @@
#define DA9213_DEVICE_ID 0x23
#define DA9215_DEVICE_ID 0x24
#define DA9211_BUCK_MODE_SLEEP 1
#define DA9211_BUCK_MODE_SYNC 2
#define DA9211_BUCK_MODE_AUTO 3
/* DA9211 REGULATOR IDs */
#define DA9211_ID_BUCKA 0
#define DA9211_ID_BUCKB 1
@ -89,6 +86,20 @@ static const int da9215_current_limits[] = {
5600000, 5800000, 6000000, 6200000, 6400000, 6600000, 6800000, 7000000
};
static unsigned int da9211_map_buck_mode(unsigned int mode)
{
switch (mode) {
case DA9211_BUCK_MODE_SLEEP:
return REGULATOR_MODE_STANDBY;
case DA9211_BUCK_MODE_SYNC:
return REGULATOR_MODE_FAST;
case DA9211_BUCK_MODE_AUTO:
return REGULATOR_MODE_NORMAL;
default:
return REGULATOR_MODE_INVALID;
}
}
static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev)
{
int id = rdev_get_id(rdev);
@ -236,6 +247,7 @@ static const struct regulator_ops da9211_buck_ops = {
.vsel_reg = DA9211_REG_VBUCKA_A + DA9211_ID_##_id * 2,\
.vsel_mask = DA9211_VBUCK_MASK,\
.owner = THIS_MODULE,\
.of_map_mode = da9211_map_buck_mode,\
}
static struct regulator_desc da9211_regulators[] = {
@ -245,8 +257,14 @@ static struct regulator_desc da9211_regulators[] = {
#ifdef CONFIG_OF
static struct of_regulator_match da9211_matches[] = {
[DA9211_ID_BUCKA] = { .name = "BUCKA" },
[DA9211_ID_BUCKB] = { .name = "BUCKB" },
[DA9211_ID_BUCKA] = {
.name = "BUCKA",
.desc = &da9211_regulators[DA9211_ID_BUCKA],
},
[DA9211_ID_BUCKB] = {
.name = "BUCKB",
.desc = &da9211_regulators[DA9211_ID_BUCKB],
},
};
static struct da9211_pdata *da9211_parse_regulators_dt(

View File

@ -110,13 +110,6 @@ static int ux500_regulator_status_show(struct seq_file *s, void *p)
}
DEFINE_SHOW_ATTRIBUTE(ux500_regulator_status);
int __attribute__((weak)) dbx500_regulator_testcase(
struct dbx500_regulator_info *regulator_info,
int num_regulators)
{
return 0;
}
int
ux500_regulator_debug_init(struct platform_device *pdev,
struct dbx500_regulator_info *regulator_info,
@ -152,7 +145,6 @@ ux500_regulator_debug_init(struct platform_device *pdev,
if (!rdebug.state_after_suspend)
goto exit_free;
dbx500_regulator_testcase(regulator_info, num_regulators);
return 0;
exit_free:

View File

@ -41,8 +41,8 @@ static struct regulator *_devm_regulator_get(struct device *dev, const char *id,
/**
* devm_regulator_get - Resource managed regulator_get()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
* @dev: device to supply
* @id: supply name or regulator ID.
*
* Managed regulator_get(). Regulators returned from this function are
* automatically regulator_put() on driver detach. See regulator_get() for more
@ -56,8 +56,8 @@ EXPORT_SYMBOL_GPL(devm_regulator_get);
/**
* devm_regulator_get_exclusive - Resource managed regulator_get_exclusive()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
* @dev: device to supply
* @id: supply name or regulator ID.
*
* Managed regulator_get_exclusive(). Regulators returned from this function
* are automatically regulator_put() on driver detach. See regulator_get() for
@ -72,8 +72,8 @@ EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);
/**
* devm_regulator_get_optional - Resource managed regulator_get_optional()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
* @dev: device to supply
* @id: supply name or regulator ID.
*
* Managed regulator_get_optional(). Regulators returned from this
* function are automatically regulator_put() on driver detach. See
@ -130,9 +130,9 @@ static void devm_regulator_bulk_release(struct device *dev, void *res)
/**
* devm_regulator_bulk_get - managed get multiple regulator consumers
*
* @dev: Device to supply
* @num_consumers: Number of consumers to register
* @consumers: Configuration of consumers; clients are stored here.
* @dev: device to supply
* @num_consumers: number of consumers to register
* @consumers: configuration of consumers; clients are stored here.
*
* @return 0 on success, an errno on failure.
*
@ -173,8 +173,9 @@ static void devm_rdev_release(struct device *dev, void *res)
/**
* devm_regulator_register - Resource managed regulator_register()
* @dev: device to supply
* @regulator_desc: regulator to register
* @config: runtime configuration for regulator
* @config: runtime configuration for regulator
*
* Called by regulator drivers to register a regulator. Returns a
* valid pointer to struct regulator_dev on success or an ERR_PTR() on
@ -216,7 +217,8 @@ static int devm_rdev_match(struct device *dev, void *res, void *data)
/**
* devm_regulator_unregister - Resource managed regulator_unregister()
* @regulator: regulator to free
* @dev: device to supply
* @rdev: regulator to free
*
* Unregister a regulator registered with devm_regulator_register().
* Normally this function will not need to be called and the resource
@ -257,10 +259,10 @@ static void devm_regulator_destroy_supply_alias(struct device *dev, void *res)
* devm_regulator_register_supply_alias - Resource managed
* regulator_register_supply_alias()
*
* @dev: device that will be given as the regulator "consumer"
* @id: Supply name or regulator ID
* @dev: device to supply
* @id: supply name or regulator ID
* @alias_dev: device that should be used to lookup the supply
* @alias_id: Supply name or regulator ID that should be used to lookup the
* @alias_id: supply name or regulator ID that should be used to lookup the
* supply
*
* The supply alias will automatically be unregistered when the source
@ -298,8 +300,8 @@ EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias);
* devm_regulator_unregister_supply_alias - Resource managed
* regulator_unregister_supply_alias()
*
* @dev: device that will be given as the regulator "consumer"
* @id: Supply name or regulator ID
* @dev: device to supply
* @id: supply name or regulator ID
*
* Unregister an alias registered with
* devm_regulator_register_supply_alias(). Normally this function
@ -325,12 +327,12 @@ EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias);
* devm_regulator_bulk_register_supply_alias - Managed register
* multiple aliases
*
* @dev: device that will be given as the regulator "consumer"
* @id: List of supply names or regulator IDs
* @dev: device to supply
* @id: list of supply names or regulator IDs
* @alias_dev: device that should be used to lookup the supply
* @alias_id: List of supply names or regulator IDs that should be used to
* lookup the supply
* @num_id: Number of aliases to register
* @alias_id: list of supply names or regulator IDs that should be used to
* lookup the supply
* @num_id: number of aliases to register
*
* @return 0 on success, an errno on failure.
*
@ -375,9 +377,9 @@ EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias);
* devm_regulator_bulk_unregister_supply_alias - Managed unregister
* multiple aliases
*
* @dev: device that will be given as the regulator "consumer"
* @id: List of supply names or regulator IDs
* @num_id: Number of aliases to unregister
* @dev: device to supply
* @id: list of supply names or regulator IDs
* @num_id: number of aliases to unregister
*
* Unregister aliases registered with
* devm_regulator_bulk_register_supply_alias(). Normally this function
@ -421,7 +423,7 @@ static void devm_regulator_destroy_notifier(struct device *dev, void *res)
* regulator_register_notifier
*
* @regulator: regulator source
* @nb: notifier block
* @nb: notifier block
*
* The notifier will be registers under the consumer device and be
* automatically be unregistered when the source device is unbound.
@ -458,7 +460,7 @@ EXPORT_SYMBOL_GPL(devm_regulator_register_notifier);
* regulator_unregister_notifier()
*
* @regulator: regulator source
* @nb: notifier block
* @nb: notifier block
*
* Unregister a notifier registered with devm_regulator_register_notifier().
* Normally this function will not need to be called and the resource

View File

@ -0,0 +1,184 @@
// SPDX-License-Identifier: GPL-2.0+
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
enum fan53880_regulator_ids {
FAN53880_LDO1,
FAN53880_LDO2,
FAN53880_LDO3,
FAN53880_LDO4,
FAN53880_BUCK,
FAN53880_BOOST,
};
enum fan53880_registers {
FAN53880_PRODUCT_ID = 0x00,
FAN53880_SILICON_REV,
FAN53880_BUCKVOUT,
FAN53880_BOOSTVOUT,
FAN53880_LDO1VOUT,
FAN53880_LDO2VOUT,
FAN53880_LDO3VOUT,
FAN53880_LDO4VOUT,
FAN53880_IOUT,
FAN53880_ENABLE,
FAN53880_ENABLE_BOOST,
};
#define FAN53880_ID 0x01
static const struct regulator_ops fan53880_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
#define FAN53880_LDO(_num, _supply, _default) \
[FAN53880_LDO ## _num] = { \
.name = "LDO"#_num, \
.of_match = of_match_ptr("LDO"#_num), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.linear_ranges = (struct linear_range[]) { \
REGULATOR_LINEAR_RANGE(_default, 0x0, 0x0, 0), \
REGULATOR_LINEAR_RANGE(800000, 0xf, 0x73, 25000), \
}, \
.n_linear_ranges = 2, \
.vsel_reg = FAN53880_LDO ## _num ## VOUT, \
.vsel_mask = 0x7f, \
.enable_reg = FAN53880_ENABLE, \
.enable_mask = BIT(_num - 1), \
.enable_time = 150, \
.supply_name = _supply, \
.ops = &fan53880_ops, \
}
static const struct regulator_desc fan53880_regulators[] = {
FAN53880_LDO(1, "VIN12", 2800000),
FAN53880_LDO(2, "VIN12", 2800000),
FAN53880_LDO(3, "VIN3", 1800000),
FAN53880_LDO(4, "VIN4", 1800000),
[FAN53880_BUCK] = {
.name = "BUCK",
.of_match = of_match_ptr("BUCK"),
.regulators_node = of_match_ptr("regulators"),
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(1100000, 0x0, 0x0, 0),
REGULATOR_LINEAR_RANGE(600000, 0x1f, 0xf7, 12500),
},
.n_linear_ranges = 2,
.vsel_reg = FAN53880_BUCKVOUT,
.vsel_mask = 0x7f,
.enable_reg = FAN53880_ENABLE,
.enable_mask = 0x10,
.enable_time = 480,
.supply_name = "PVIN",
.ops = &fan53880_ops,
},
[FAN53880_BOOST] = {
.name = "BOOST",
.of_match = of_match_ptr("BOOST"),
.regulators_node = of_match_ptr("regulators"),
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(5000000, 0x0, 0x0, 0),
REGULATOR_LINEAR_RANGE(3000000, 0x4, 0x70, 25000),
},
.n_linear_ranges = 2,
.vsel_reg = FAN53880_BOOSTVOUT,
.vsel_mask = 0x7f,
.enable_reg = FAN53880_ENABLE_BOOST,
.enable_mask = 0xff,
.enable_time = 580,
.supply_name = "PVIN",
.ops = &fan53880_ops,
},
};
static const struct regmap_config fan53880_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = FAN53880_ENABLE_BOOST,
};
static int fan53880_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct regulator_config config = { };
struct regulator_dev *rdev;
struct regmap *regmap;
int i, ret;
unsigned int data;
regmap = devm_regmap_init_i2c(i2c, &fan53880_regmap);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
return ret;
}
ret = regmap_read(regmap, FAN53880_PRODUCT_ID, &data);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to read PRODUCT_ID: %d\n", ret);
return ret;
}
if (data != FAN53880_ID) {
dev_err(&i2c->dev, "Unsupported device id: 0x%x.\n", data);
return -ENODEV;
}
config.dev = &i2c->dev;
config.init_data = NULL;
for (i = 0; i < ARRAY_SIZE(fan53880_regulators); i++) {
rdev = devm_regulator_register(&i2c->dev,
&fan53880_regulators[i],
&config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&i2c->dev, "Failed to register %s: %d\n",
fan53880_regulators[i].name, ret);
return ret;
}
}
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id fan53880_dt_ids[] = {
{ .compatible = "onnn,fan53880", },
{}
};
MODULE_DEVICE_TABLE(of, fan53880_dt_ids);
#endif
static const struct i2c_device_id fan53880_i2c_id[] = {
{ "fan53880", },
{}
};
MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id);
static struct i2c_driver fan53880_regulator_driver = {
.driver = {
.name = "fan53880",
.of_match_table = of_match_ptr(fan53880_dt_ids),
},
.probe = fan53880_i2c_probe,
.id_table = fan53880_i2c_id,
};
module_i2c_driver(fan53880_regulator_driver);
MODULE_DESCRIPTION("FAN53880 PMIC voltage regulator driver");
MODULE_AUTHOR("Christoph Fritz <chf.fritz@googlemail.com>");
MODULE_LICENSE("GPL");

View File

@ -210,7 +210,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
/*
* The signal will be inverted by the GPIO core if flagged so in the
* decriptor.
* descriptor.
*/
if (config->enabled_at_boot)
gflags = GPIOD_OUT_HIGH;

View File

@ -148,6 +148,13 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np,
config->supply_name = config->init_data->constraints.name;
if (config->init_data->constraints.boot_on)
config->enabled_at_boot = true;
/*
* Do not use: undocumented device tree property.
* This is kept around solely for device tree ABI stability.
*/
if (of_property_read_bool(np, "enable-at-boot"))
config->enabled_at_boot = true;
@ -311,7 +318,7 @@ static int gpio_regulator_probe(struct platform_device *pdev)
/*
* The signal will be inverted by the GPIO core if flagged so in the
* decriptor.
* descriptor.
*/
if (config->enabled_at_boot)
gflags = GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE;

View File

@ -5,7 +5,7 @@
// Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
// http://www.hisilicon.com
// Copyright (c) <2013-2014> Linaro Ltd.
// http://www.linaro.org
// https://www.linaro.org
//
// Author: Guodong Xu <guodong.xu@linaro.org>

View File

@ -5,7 +5,7 @@
// Copyright (c) <2017> HiSilicon Technologies Co., Ltd.
// http://www.hisilicon.com
// Copyright (c) <2017> Linaro Ltd.
// http://www.linaro.org
// https://www.linaro.org
//
// Author: Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com>
// Guodong Xu <guodong.xu@linaro.org>

View File

@ -1,7 +1,7 @@
/*
* Regulator driver for LP873X PMIC
*
* Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2 as

View File

@ -2,7 +2,7 @@
/*
* Regulator driver for LP87565 PMIC
*
* Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <linux/module.h>
@ -11,8 +11,8 @@
#include <linux/mfd/lp87565.h>
#define LP87565_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, _er, _em, \
_delay, _lr, _cr) \
#define LP87565_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, \
_er, _em, _ev, _delay, _lr, _cr) \
[_id] = { \
.desc = { \
.name = _name, \
@ -28,6 +28,7 @@
.vsel_mask = _vm, \
.enable_reg = _er, \
.enable_mask = _em, \
.enable_val = _ev, \
.ramp_delay = _delay, \
.linear_ranges = _lr, \
.n_linear_ranges = ARRAY_SIZE(_lr), \
@ -121,38 +122,54 @@ static const struct lp87565_regulator regulators[] = {
LP87565_REGULATOR("BUCK0", LP87565_BUCK_0, "buck0", lp87565_buck_ops,
256, LP87565_REG_BUCK0_VOUT, LP87565_BUCK_VSET,
LP87565_REG_BUCK0_CTRL_1,
LP87565_BUCK_CTRL_1_EN |
LP87565_BUCK_CTRL_1_EN_PIN_CTRL,
LP87565_BUCK_CTRL_1_EN, 3230,
buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2),
LP87565_REGULATOR("BUCK1", LP87565_BUCK_1, "buck1", lp87565_buck_ops,
256, LP87565_REG_BUCK1_VOUT, LP87565_BUCK_VSET,
LP87565_REG_BUCK1_CTRL_1,
LP87565_BUCK_CTRL_1_EN |
LP87565_BUCK_CTRL_1_EN_PIN_CTRL,
LP87565_BUCK_CTRL_1_EN, 3230,
buck0_1_2_3_ranges, LP87565_REG_BUCK1_CTRL_2),
LP87565_REGULATOR("BUCK2", LP87565_BUCK_2, "buck2", lp87565_buck_ops,
256, LP87565_REG_BUCK2_VOUT, LP87565_BUCK_VSET,
LP87565_REG_BUCK2_CTRL_1,
LP87565_BUCK_CTRL_1_EN |
LP87565_BUCK_CTRL_1_EN_PIN_CTRL,
LP87565_BUCK_CTRL_1_EN, 3230,
buck0_1_2_3_ranges, LP87565_REG_BUCK2_CTRL_2),
LP87565_REGULATOR("BUCK3", LP87565_BUCK_3, "buck3", lp87565_buck_ops,
256, LP87565_REG_BUCK3_VOUT, LP87565_BUCK_VSET,
LP87565_REG_BUCK3_CTRL_1,
LP87565_BUCK_CTRL_1_EN |
LP87565_BUCK_CTRL_1_EN_PIN_CTRL,
LP87565_BUCK_CTRL_1_EN, 3230,
buck0_1_2_3_ranges, LP87565_REG_BUCK3_CTRL_2),
LP87565_REGULATOR("BUCK10", LP87565_BUCK_10, "buck10", lp87565_buck_ops,
256, LP87565_REG_BUCK0_VOUT, LP87565_BUCK_VSET,
LP87565_REG_BUCK0_CTRL_1,
LP87565_BUCK_CTRL_1_EN |
LP87565_BUCK_CTRL_1_EN_PIN_CTRL |
LP87565_BUCK_CTRL_1_FPWM_MP_0_2,
LP87565_BUCK_CTRL_1_EN |
LP87565_BUCK_CTRL_1_FPWM_MP_0_2, 3230,
buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2),
LP87565_REGULATOR("BUCK23", LP87565_BUCK_23, "buck23", lp87565_buck_ops,
256, LP87565_REG_BUCK2_VOUT, LP87565_BUCK_VSET,
LP87565_REG_BUCK2_CTRL_1,
LP87565_BUCK_CTRL_1_EN |
LP87565_BUCK_CTRL_1_EN_PIN_CTRL,
LP87565_BUCK_CTRL_1_EN, 3230,
buck0_1_2_3_ranges, LP87565_REG_BUCK2_CTRL_2),
LP87565_REGULATOR("BUCK3210", LP87565_BUCK_3210, "buck3210",
lp87565_buck_ops, 256, LP87565_REG_BUCK0_VOUT,
LP87565_BUCK_VSET, LP87565_REG_BUCK0_CTRL_1,
LP87565_BUCK_CTRL_1_EN |
LP87565_BUCK_CTRL_1_EN_PIN_CTRL |
LP87565_BUCK_CTRL_1_FPWM_MP_0_2,
LP87565_BUCK_CTRL_1_EN |
LP87565_BUCK_CTRL_1_FPWM_MP_0_2, 3230,
buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2),
};

View File

@ -221,7 +221,7 @@ static const struct regulator_ops ltc3676_fixed_regulator_ops = {
#define LTC3676_FIXED_REG(_id, _name, _en_reg, _en_bit) \
LTC3676_REG(_id, _name, fixed, LTC3676_ ## _en_reg, _en_bit, 0, 0)
static struct regulator_desc ltc3676_regulators[LTC3676_NUM_REGULATORS] = {
static const struct regulator_desc ltc3676_regulators[LTC3676_NUM_REGULATORS] = {
LTC3676_LINEAR_REG(SW1, sw1, BUCK1, DVB1A),
LTC3676_LINEAR_REG(SW2, sw2, BUCK2, DVB2A),
LTC3676_LINEAR_REG(SW3, sw3, BUCK3, DVB3A),

View File

@ -155,7 +155,7 @@ static const struct regulator_desc max77836_supported_regulators[] = {
[MAX77836_LDO2] = MAX77836_LDO_REG(2),
};
/**
/*
* Registers for regulators of max77836 use different I2C slave addresses so
* different regmaps must be used for them.
*

View File

@ -109,7 +109,7 @@ struct max8907_regulator {
static const struct regulator_ops max8907_mbatt_ops = {
};
static struct regulator_ops max8907_ldo_ops = {
static const struct regulator_ops max8907_ldo_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@ -128,7 +128,7 @@ static const struct regulator_ops max8907_fixed_ops = {
.list_voltage = regulator_list_voltage_linear,
};
static struct regulator_ops max8907_out5v_ops = {
static const struct regulator_ops max8907_out5v_ops = {
.list_voltage = regulator_list_voltage_linear,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -145,7 +145,7 @@ static const struct regulator_ops max8907_bbat_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
static struct regulator_desc max8907_regulators[] = {
static const struct regulator_desc max8907_regulators[] = {
REG_MBATT(),
REG_LDO(SD1, "in-v1", MAX8907_REG_SDCTL1, 650000, 2225000, 25000),
REG_LDO(SD2, "in-v2", MAX8907_REG_SDCTL2, 637500, 1425000, 12500),

View File

@ -732,7 +732,7 @@ static int max8997_reg_disable_suspend(struct regulator_dev *rdev)
return max8997_update_reg(i2c, reg, ~pattern, mask);
}
static struct regulator_ops max8997_ldo_ops = {
static const struct regulator_ops max8997_ldo_ops = {
.list_voltage = max8997_list_voltage,
.is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable,
@ -742,7 +742,7 @@ static struct regulator_ops max8997_ldo_ops = {
.set_suspend_disable = max8997_reg_disable_suspend,
};
static struct regulator_ops max8997_buck_ops = {
static const struct regulator_ops max8997_buck_ops = {
.list_voltage = max8997_list_voltage,
.is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable,
@ -753,7 +753,7 @@ static struct regulator_ops max8997_buck_ops = {
.set_suspend_disable = max8997_reg_disable_suspend,
};
static struct regulator_ops max8997_fixedvolt_ops = {
static const struct regulator_ops max8997_fixedvolt_ops = {
.list_voltage = max8997_list_voltage,
.is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable,
@ -761,7 +761,7 @@ static struct regulator_ops max8997_fixedvolt_ops = {
.set_suspend_disable = max8997_reg_disable_suspend,
};
static struct regulator_ops max8997_safeout_ops = {
static const struct regulator_ops max8997_safeout_ops = {
.list_voltage = regulator_list_voltage_table,
.is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable,
@ -771,7 +771,7 @@ static struct regulator_ops max8997_safeout_ops = {
.set_suspend_disable = max8997_reg_disable_suspend,
};
static struct regulator_ops max8997_fixedstate_ops = {
static const struct regulator_ops max8997_fixedstate_ops = {
.list_voltage = max8997_list_voltage_charger_cv,
.get_voltage_sel = max8997_get_voltage_sel,
.set_voltage = max8997_set_voltage_charger_cv,
@ -805,7 +805,7 @@ static int max8997_get_current_limit(struct regulator_dev *rdev)
return max8997_list_voltage(rdev, sel);
}
static struct regulator_ops max8997_charger_ops = {
static const struct regulator_ops max8997_charger_ops = {
.is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable,
.disable = max8997_reg_disable,
@ -813,7 +813,7 @@ static struct regulator_ops max8997_charger_ops = {
.set_current_limit = max8997_set_current_limit,
};
static struct regulator_ops max8997_charger_fixedstate_ops = {
static const struct regulator_ops max8997_charger_fixedstate_ops = {
.get_current_limit = max8997_get_current_limit,
.set_current_limit = max8997_set_current_limit,
};

View File

@ -415,7 +415,7 @@ static int max8998_set_current_limit(struct regulator_dev *rdev,
sel, rdev->desc->csel_mask);
}
int max8998_get_current_limit(struct regulator_dev *rdev)
static int max8998_get_current_limit(struct regulator_dev *rdev)
{
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
struct i2c_client *i2c = max8998->iodev->i2c;

View File

@ -206,8 +206,7 @@ static const struct regmap_config mp886x_regmap_config = {
.val_bits = 8,
};
static int mp886x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int mp886x_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct device_node *np = dev->of_node;
@ -280,7 +279,7 @@ static struct i2c_driver mp886x_regulator_driver = {
.name = "mp886x-regulator",
.of_match_table = of_match_ptr(mp886x_dt_ids),
},
.probe = mp886x_i2c_probe,
.probe_new = mp886x_i2c_probe,
.id_table = mp886x_id,
};
module_i2c_driver(mp886x_regulator_driver);

View File

@ -13,9 +13,7 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/mt6397-regulator.h>
#include <linux/regulator/of_regulator.h>
#define MT6397_BUCK_MODE_AUTO 0
#define MT6397_BUCK_MODE_FORCE_PWM 1
#include <dt-bindings/regulator/mediatek,mt6397-regulator.h>
/*
* MT6397 regulators' information
@ -55,6 +53,7 @@ struct mt6397_regulator_info {
.vsel_mask = vosel_mask, \
.enable_reg = enreg, \
.enable_mask = BIT(0), \
.of_map_mode = mt6397_map_mode, \
}, \
.qi = BIT(13), \
.vselon_reg = voselon, \
@ -146,6 +145,18 @@ static const unsigned int ldo_volt_table7[] = {
1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000,
};
static unsigned int mt6397_map_mode(unsigned int mode)
{
switch (mode) {
case MT6397_BUCK_MODE_AUTO:
return REGULATOR_MODE_NORMAL;
case MT6397_BUCK_MODE_FORCE_PWM:
return REGULATOR_MODE_FAST;
default:
return REGULATOR_MODE_INVALID;
}
}
static int mt6397_regulator_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{

View File

@ -532,7 +532,7 @@ static bool of_coupling_find_node(struct device_node *src,
/**
* of_check_coupling_data - Parse rdev's coupling properties and check data
* consistency
* @rdev - pointer to regulator_dev whose data is checked
* @rdev: pointer to regulator_dev whose data is checked
*
* Function checks if all the following conditions are met:
* - rdev's max_spread is greater than 0

View File

@ -1,7 +1,7 @@
/*
* pbias-regulator.c
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/
* Author: Balaji T K <balajitk@ti.com>
*
* This program is free software; you can redistribute it and/or

View File

@ -0,0 +1,833 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2020 NXP.
* NXP PCA9450 pmic driver
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/pca9450.h>
struct pc9450_dvs_config {
unsigned int run_reg; /* dvs0 */
unsigned int run_mask;
unsigned int standby_reg; /* dvs1 */
unsigned int standby_mask;
};
struct pca9450_regulator_desc {
struct regulator_desc desc;
const struct pc9450_dvs_config dvs;
};
struct pca9450 {
struct device *dev;
struct regmap *regmap;
enum pca9450_chip_type type;
unsigned int rcnt;
int irq;
};
static const struct regmap_range pca9450_status_range = {
.range_min = PCA9450_REG_INT1,
.range_max = PCA9450_REG_PWRON_STAT,
};
static const struct regmap_access_table pca9450_volatile_regs = {
.yes_ranges = &pca9450_status_range,
.n_yes_ranges = 1,
};
static const struct regmap_config pca9450_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.volatile_table = &pca9450_volatile_regs,
.max_register = PCA9450_MAX_REGISTER - 1,
.cache_type = REGCACHE_RBTREE,
};
/*
* BUCK1/2/3
* BUCK1RAM[1:0] BUCK1 DVS ramp rate setting
* 00: 25mV/1usec
* 01: 25mV/2usec
* 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 struct regulator_ops pca9450_dvs_buck_regulator_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 = pca9450_dvs_set_ramp_delay,
};
static struct regulator_ops pca9450_buck_regulator_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 struct regulator_ops pca9450_ldo_regulator_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,
};
/*
* BUCK1/2/3
* 0.60 to 2.1875V (12.5mV step)
*/
static const struct linear_range pca9450_dvs_buck_volts[] = {
REGULATOR_LINEAR_RANGE(600000, 0x00, 0x7F, 12500),
};
/*
* BUCK4/5/6
* 0.6V to 3.4V (25mV step)
*/
static const struct linear_range pca9450_buck_volts[] = {
REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000),
REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0),
};
/*
* LDO1
* 1.6 to 3.3V ()
*/
static const struct linear_range pca9450_ldo1_volts[] = {
REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000),
};
/*
* LDO2
* 0.8 to 1.15V (50mV step)
*/
static const struct linear_range pca9450_ldo2_volts[] = {
REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000),
};
/*
* LDO3/4
* 0.8 to 3.3V (100mV step)
*/
static const struct linear_range pca9450_ldo34_volts[] = {
REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000),
REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0),
};
/*
* LDO5
* 1.8 to 3.3V (100mV step)
*/
static const struct linear_range pca9450_ldo5_volts[] = {
REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
};
static int buck_set_dvs(const struct regulator_desc *desc,
struct device_node *np, struct regmap *regmap,
char *prop, unsigned int reg, unsigned int mask)
{
int ret, i;
uint32_t uv;
ret = of_property_read_u32(np, prop, &uv);
if (ret == -EINVAL)
return 0;
else if (ret)
return ret;
for (i = 0; i < desc->n_voltages; i++) {
ret = regulator_desc_list_voltage_linear_range(desc, i);
if (ret < 0)
continue;
if (ret == uv) {
i <<= ffs(desc->vsel_mask) - 1;
ret = regmap_update_bits(regmap, reg, mask, i);
break;
}
}
return ret;
}
static int pca9450_set_dvs_levels(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *cfg)
{
struct pca9450_regulator_desc *data = container_of(desc,
struct pca9450_regulator_desc, desc);
const struct pc9450_dvs_config *dvs = &data->dvs;
unsigned int reg, mask;
char *prop;
int i, ret = 0;
for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) {
switch (i) {
case PCA9450_DVS_LEVEL_RUN:
prop = "nxp,dvs-run-voltage";
reg = dvs->run_reg;
mask = dvs->run_mask;
break;
case PCA9450_DVS_LEVEL_STANDBY:
prop = "nxp,dvs-standby-voltage";
reg = dvs->standby_reg;
mask = dvs->standby_mask;
break;
default:
return -EINVAL;
}
ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask);
if (ret)
break;
}
return ret;
}
static const struct pca9450_regulator_desc pca9450a_regulators[] = {
{
.desc = {
.name = "buck1",
.of_match = of_match_ptr("BUCK1"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK1,
.ops = &pca9450_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
.linear_ranges = pca9450_dvs_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
.vsel_mask = BUCK1OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK1CTRL,
.enable_mask = BUCK1_ENMODE_MASK,
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
.run_mask = BUCK1OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
.standby_mask = BUCK1OUT_DVS1_MASK,
},
},
{
.desc = {
.name = "buck2",
.of_match = of_match_ptr("BUCK2"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK2,
.ops = &pca9450_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
.linear_ranges = pca9450_dvs_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
.vsel_mask = BUCK2OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK2CTRL,
.enable_mask = BUCK1_ENMODE_MASK,
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
.run_mask = BUCK2OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
.standby_mask = BUCK2OUT_DVS1_MASK,
},
},
{
.desc = {
.name = "buck3",
.of_match = of_match_ptr("BUCK3"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK3,
.ops = &pca9450_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK3_VOLTAGE_NUM,
.linear_ranges = pca9450_dvs_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
.vsel_reg = PCA9450_REG_BUCK3OUT_DVS0,
.vsel_mask = BUCK3OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK3CTRL,
.enable_mask = BUCK3_ENMODE_MASK,
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK3OUT_DVS0,
.run_mask = BUCK3OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK3OUT_DVS1,
.standby_mask = BUCK3OUT_DVS1_MASK,
},
},
{
.desc = {
.name = "buck4",
.of_match = of_match_ptr("BUCK4"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK4,
.ops = &pca9450_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
.linear_ranges = pca9450_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
.vsel_reg = PCA9450_REG_BUCK4OUT,
.vsel_mask = BUCK4OUT_MASK,
.enable_reg = PCA9450_REG_BUCK4CTRL,
.enable_mask = BUCK4_ENMODE_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "buck5",
.of_match = of_match_ptr("BUCK5"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK5,
.ops = &pca9450_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
.linear_ranges = pca9450_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
.vsel_reg = PCA9450_REG_BUCK5OUT,
.vsel_mask = BUCK5OUT_MASK,
.enable_reg = PCA9450_REG_BUCK5CTRL,
.enable_mask = BUCK5_ENMODE_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "buck6",
.of_match = of_match_ptr("BUCK6"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK6,
.ops = &pca9450_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
.linear_ranges = pca9450_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
.vsel_reg = PCA9450_REG_BUCK6OUT,
.vsel_mask = BUCK6OUT_MASK,
.enable_reg = PCA9450_REG_BUCK6CTRL,
.enable_mask = BUCK6_ENMODE_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo1",
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO1,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo1_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
.vsel_reg = PCA9450_REG_LDO1CTRL,
.vsel_mask = LDO1OUT_MASK,
.enable_reg = PCA9450_REG_LDO1CTRL,
.enable_mask = LDO1_EN_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo2",
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO2,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo2_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
.vsel_reg = PCA9450_REG_LDO2CTRL,
.vsel_mask = LDO2OUT_MASK,
.enable_reg = PCA9450_REG_LDO2CTRL,
.enable_mask = LDO2_EN_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo3",
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO3,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
.vsel_reg = PCA9450_REG_LDO3CTRL,
.vsel_mask = LDO3OUT_MASK,
.enable_reg = PCA9450_REG_LDO3CTRL,
.enable_mask = LDO3_EN_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo4",
.of_match = of_match_ptr("LDO4"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO4,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
.vsel_reg = PCA9450_REG_LDO4CTRL,
.vsel_mask = LDO4OUT_MASK,
.enable_reg = PCA9450_REG_LDO4CTRL,
.enable_mask = LDO4_EN_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo5",
.of_match = of_match_ptr("LDO5"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO5,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo5_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
.vsel_reg = PCA9450_REG_LDO5CTRL_H,
.vsel_mask = LDO5HOUT_MASK,
.enable_reg = PCA9450_REG_LDO5CTRL_H,
.enable_mask = LDO5H_EN_MASK,
.owner = THIS_MODULE,
},
},
};
/*
* Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase
* on PCA9450C as no Buck3.
*/
static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
{
.desc = {
.name = "buck1",
.of_match = of_match_ptr("BUCK1"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK1,
.ops = &pca9450_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
.linear_ranges = pca9450_dvs_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
.vsel_mask = BUCK1OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK1CTRL,
.enable_mask = BUCK1_ENMODE_MASK,
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
.run_mask = BUCK1OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
.standby_mask = BUCK1OUT_DVS1_MASK,
},
},
{
.desc = {
.name = "buck2",
.of_match = of_match_ptr("BUCK2"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK2,
.ops = &pca9450_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
.linear_ranges = pca9450_dvs_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
.vsel_mask = BUCK2OUT_DVS0_MASK,
.enable_reg = PCA9450_REG_BUCK2CTRL,
.enable_mask = BUCK1_ENMODE_MASK,
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
.run_mask = BUCK2OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
.standby_mask = BUCK2OUT_DVS1_MASK,
},
},
{
.desc = {
.name = "buck4",
.of_match = of_match_ptr("BUCK4"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK4,
.ops = &pca9450_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
.linear_ranges = pca9450_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
.vsel_reg = PCA9450_REG_BUCK4OUT,
.vsel_mask = BUCK4OUT_MASK,
.enable_reg = PCA9450_REG_BUCK4CTRL,
.enable_mask = BUCK4_ENMODE_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "buck5",
.of_match = of_match_ptr("BUCK5"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK5,
.ops = &pca9450_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
.linear_ranges = pca9450_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
.vsel_reg = PCA9450_REG_BUCK5OUT,
.vsel_mask = BUCK5OUT_MASK,
.enable_reg = PCA9450_REG_BUCK5CTRL,
.enable_mask = BUCK5_ENMODE_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "buck6",
.of_match = of_match_ptr("BUCK6"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_BUCK6,
.ops = &pca9450_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
.linear_ranges = pca9450_buck_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
.vsel_reg = PCA9450_REG_BUCK6OUT,
.vsel_mask = BUCK6OUT_MASK,
.enable_reg = PCA9450_REG_BUCK6CTRL,
.enable_mask = BUCK6_ENMODE_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo1",
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO1,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo1_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
.vsel_reg = PCA9450_REG_LDO1CTRL,
.vsel_mask = LDO1OUT_MASK,
.enable_reg = PCA9450_REG_LDO1CTRL,
.enable_mask = LDO1_EN_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo2",
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO2,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo2_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
.vsel_reg = PCA9450_REG_LDO2CTRL,
.vsel_mask = LDO2OUT_MASK,
.enable_reg = PCA9450_REG_LDO2CTRL,
.enable_mask = LDO2_EN_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo3",
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO3,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
.vsel_reg = PCA9450_REG_LDO3CTRL,
.vsel_mask = LDO3OUT_MASK,
.enable_reg = PCA9450_REG_LDO3CTRL,
.enable_mask = LDO3_EN_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo4",
.of_match = of_match_ptr("LDO4"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO4,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo34_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
.vsel_reg = PCA9450_REG_LDO4CTRL,
.vsel_mask = LDO4OUT_MASK,
.enable_reg = PCA9450_REG_LDO4CTRL,
.enable_mask = LDO4_EN_MASK,
.owner = THIS_MODULE,
},
},
{
.desc = {
.name = "ldo5",
.of_match = of_match_ptr("LDO5"),
.regulators_node = of_match_ptr("regulators"),
.id = PCA9450_LDO5,
.ops = &pca9450_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
.linear_ranges = pca9450_ldo5_volts,
.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
.vsel_reg = PCA9450_REG_LDO5CTRL_H,
.vsel_mask = LDO5HOUT_MASK,
.enable_reg = PCA9450_REG_LDO5CTRL_H,
.enable_mask = LDO5H_EN_MASK,
.owner = THIS_MODULE,
},
},
};
static irqreturn_t pca9450_irq_handler(int irq, void *data)
{
struct pca9450 *pca9450 = data;
struct regmap *regmap = pca9450->regmap;
unsigned int status;
int ret;
ret = regmap_read(regmap, PCA9450_REG_INT1, &status);
if (ret < 0) {
dev_err(pca9450->dev,
"Failed to read INT1(%d)\n", ret);
return IRQ_NONE;
}
if (status & IRQ_PWRON)
dev_warn(pca9450->dev, "PWRON interrupt.\n");
if (status & IRQ_WDOGB)
dev_warn(pca9450->dev, "WDOGB interrupt.\n");
if (status & IRQ_VR_FLT1)
dev_warn(pca9450->dev, "VRFLT1 interrupt.\n");
if (status & IRQ_VR_FLT2)
dev_warn(pca9450->dev, "VRFLT2 interrupt.\n");
if (status & IRQ_LOWVSYS)
dev_warn(pca9450->dev, "LOWVSYS interrupt.\n");
if (status & IRQ_THERM_105)
dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n");
if (status & IRQ_THERM_125)
dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n");
return IRQ_HANDLED;
}
static int pca9450_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
enum pca9450_chip_type type = (unsigned int)(uintptr_t)
of_device_get_match_data(&i2c->dev);
const struct pca9450_regulator_desc *regulator_desc;
struct regulator_config config = { };
struct pca9450 *pca9450;
unsigned int device_id, i;
int ret;
if (!i2c->irq) {
dev_err(&i2c->dev, "No IRQ configured?\n");
return -EINVAL;
}
pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL);
if (!pca9450)
return -ENOMEM;
switch (type) {
case PCA9450_TYPE_PCA9450A:
regulator_desc = pca9450a_regulators;
pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators);
break;
case PCA9450_TYPE_PCA9450BC:
regulator_desc = pca9450bc_regulators;
pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
break;
default:
dev_err(&i2c->dev, "Unknown device type");
return -EINVAL;
}
pca9450->irq = i2c->irq;
pca9450->type = type;
pca9450->dev = &i2c->dev;
dev_set_drvdata(&i2c->dev, pca9450);
pca9450->regmap = devm_regmap_init_i2c(i2c,
&pca9450_regmap_config);
if (IS_ERR(pca9450->regmap)) {
dev_err(&i2c->dev, "regmap initialization failed\n");
return PTR_ERR(pca9450->regmap);
}
ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);
if (ret) {
dev_err(&i2c->dev, "Read device id error\n");
return ret;
}
/* Check your board and dts for match the right pmic */
if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) {
dev_err(&i2c->dev, "Device id(%x) mismatched\n",
device_id >> 4);
return -EINVAL;
}
for (i = 0; i < pca9450->rcnt; i++) {
const struct regulator_desc *desc;
struct regulator_dev *rdev;
const struct pca9450_regulator_desc *r;
r = &regulator_desc[i];
desc = &r->desc;
config.regmap = pca9450->regmap;
config.dev = pca9450->dev;
rdev = devm_regulator_register(pca9450->dev, desc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(pca9450->dev,
"Failed to register regulator(%s): %d\n",
desc->name, ret);
return ret;
}
}
ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL,
pca9450_irq_handler,
(IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
"pca9450-irq", pca9450);
if (ret != 0) {
dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
pca9450->irq);
return ret;
}
/* Unmask all interrupt except PWRON/WDOG/RSVD */
ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,
IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |
IRQ_THERM_105 | IRQ_THERM_125,
IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);
if (ret) {
dev_err(&i2c->dev, "Unmask irq error\n");
return ret;
}
dev_info(&i2c->dev, "%s probed.\n",
type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
return 0;
}
static const struct of_device_id pca9450_of_match[] = {
{
.compatible = "nxp,pca9450a",
.data = (void *)PCA9450_TYPE_PCA9450A,
},
{
.compatible = "nxp,pca9450b",
.data = (void *)PCA9450_TYPE_PCA9450BC,
},
{
.compatible = "nxp,pca9450c",
.data = (void *)PCA9450_TYPE_PCA9450BC,
},
{ }
};
MODULE_DEVICE_TABLE(of, pca9450_of_match);
static struct i2c_driver pca9450_i2c_driver = {
.driver = {
.name = "nxp-pca9450",
.of_match_table = pca9450_of_match,
},
.probe = pca9450_i2c_probe,
};
module_i2c_driver(pca9450_i2c_driver);
MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
MODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver");
MODULE_LICENSE("GPL");

View File

@ -128,7 +128,7 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
bool reg_has_ramp_delay;
unsigned int ramp_bits;
unsigned int ramp_bits = 0;
int ret;
switch (pfuze100->chip_id) {
@ -149,8 +149,11 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
}
if (reg_has_ramp_delay) {
ramp_delay = 12500 / ramp_delay;
ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3);
if (ramp_delay > 0) {
ramp_delay = 12500 / ramp_delay;
ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3);
}
ret = regmap_update_bits(pfuze100->regmap,
rdev->desc->vsel_reg + 4,
0xc0, ramp_bits << 6);

View File

@ -48,7 +48,7 @@ struct pwm_voltages {
unsigned int dutycycle;
};
/**
/*
* Voltage table call-backs
*/
static void pwm_regulator_init_state(struct regulator_dev *rdev)

View File

@ -0,0 +1,175 @@
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2020, The Linux Foundation. All rights reserved.
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#define REG_PERPH_TYPE 0x04
#define QCOM_LAB_TYPE 0x24
#define QCOM_IBB_TYPE 0x20
#define PMI8998_LAB_REG_BASE 0xde00
#define PMI8998_IBB_REG_BASE 0xdc00
#define REG_LABIBB_STATUS1 0x08
#define REG_LABIBB_ENABLE_CTL 0x46
#define LABIBB_STATUS1_VREG_OK_BIT BIT(7)
#define LABIBB_CONTROL_ENABLE BIT(7)
#define LAB_ENABLE_CTL_MASK BIT(7)
#define IBB_ENABLE_CTL_MASK (BIT(7) | BIT(6))
#define LABIBB_OFF_ON_DELAY 1000
#define LAB_ENABLE_TIME (LABIBB_OFF_ON_DELAY * 2)
#define IBB_ENABLE_TIME (LABIBB_OFF_ON_DELAY * 10)
#define LABIBB_POLL_ENABLED_TIME 1000
struct labibb_regulator {
struct regulator_desc desc;
struct device *dev;
struct regmap *regmap;
struct regulator_dev *rdev;
u16 base;
u8 type;
};
struct labibb_regulator_data {
const char *name;
u8 type;
u16 base;
struct regulator_desc *desc;
};
static struct regulator_ops qcom_labibb_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_desc pmi8998_lab_desc = {
.enable_mask = LAB_ENABLE_CTL_MASK,
.enable_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_ENABLE_CTL),
.enable_val = LABIBB_CONTROL_ENABLE,
.enable_time = LAB_ENABLE_TIME,
.poll_enabled_time = LABIBB_POLL_ENABLED_TIME,
.off_on_delay = LABIBB_OFF_ON_DELAY,
.owner = THIS_MODULE,
.type = REGULATOR_VOLTAGE,
.ops = &qcom_labibb_ops,
};
static struct regulator_desc pmi8998_ibb_desc = {
.enable_mask = IBB_ENABLE_CTL_MASK,
.enable_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_ENABLE_CTL),
.enable_val = LABIBB_CONTROL_ENABLE,
.enable_time = IBB_ENABLE_TIME,
.poll_enabled_time = LABIBB_POLL_ENABLED_TIME,
.off_on_delay = LABIBB_OFF_ON_DELAY,
.owner = THIS_MODULE,
.type = REGULATOR_VOLTAGE,
.ops = &qcom_labibb_ops,
};
static const struct labibb_regulator_data pmi8998_labibb_data[] = {
{"lab", QCOM_LAB_TYPE, PMI8998_LAB_REG_BASE, &pmi8998_lab_desc},
{"ibb", QCOM_IBB_TYPE, PMI8998_IBB_REG_BASE, &pmi8998_ibb_desc},
{ },
};
static const struct of_device_id qcom_labibb_match[] = {
{ .compatible = "qcom,pmi8998-lab-ibb", .data = &pmi8998_labibb_data},
{ },
};
MODULE_DEVICE_TABLE(of, qcom_labibb_match);
static int qcom_labibb_regulator_probe(struct platform_device *pdev)
{
struct labibb_regulator *vreg;
struct device *dev = &pdev->dev;
struct regulator_config cfg = {};
const struct of_device_id *match;
const struct labibb_regulator_data *reg_data;
struct regmap *reg_regmap;
unsigned int type;
int ret;
reg_regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!reg_regmap) {
dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
return -ENODEV;
}
match = of_match_device(qcom_labibb_match, &pdev->dev);
if (!match)
return -ENODEV;
for (reg_data = match->data; reg_data->name; reg_data++) {
/* Validate if the type of regulator is indeed
* what's mentioned in DT.
*/
ret = regmap_read(reg_regmap, reg_data->base + REG_PERPH_TYPE,
&type);
if (ret < 0) {
dev_err(dev,
"Peripheral type read failed ret=%d\n",
ret);
return -EINVAL;
}
if (WARN_ON((type != QCOM_LAB_TYPE) && (type != QCOM_IBB_TYPE)) ||
WARN_ON(type != reg_data->type))
return -EINVAL;
vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg),
GFP_KERNEL);
if (!vreg)
return -ENOMEM;
vreg->regmap = reg_regmap;
vreg->dev = dev;
vreg->base = reg_data->base;
vreg->type = reg_data->type;
memcpy(&vreg->desc, reg_data->desc, sizeof(vreg->desc));
vreg->desc.of_match = reg_data->name;
vreg->desc.name = reg_data->name;
cfg.dev = vreg->dev;
cfg.driver_data = vreg;
cfg.regmap = vreg->regmap;
vreg->rdev = devm_regulator_register(vreg->dev, &vreg->desc,
&cfg);
if (IS_ERR(vreg->rdev)) {
dev_err(dev, "qcom_labibb: error registering %s : %d\n",
reg_data->name, ret);
return PTR_ERR(vreg->rdev);
}
}
return 0;
}
static struct platform_driver qcom_labibb_regulator_driver = {
.driver = {
.name = "qcom-lab-ibb-regulator",
.of_match_table = qcom_labibb_match,
},
.probe = qcom_labibb_regulator_probe,
};
module_platform_driver(qcom_labibb_regulator_driver);
MODULE_DESCRIPTION("Qualcomm labibb driver");
MODULE_AUTHOR("Nisha Kumari <nishakumari@codeaurora.org>");
MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>");
MODULE_LICENSE("GPL v2");

View File

@ -22,9 +22,9 @@
/**
* enum rpmh_regulator_type - supported RPMh accelerator types
* %VRM: RPMh VRM accelerator which supports voting on enable, voltage,
* @VRM: RPMh VRM accelerator which supports voting on enable, voltage,
* and mode of LDO, SMPS, and BOB type PMIC regulators.
* %XOB: RPMh XOB accelerator which supports voting on the enable state
* @XOB: RPMh XOB accelerator which supports voting on the enable state
* of PMIC regulators.
*/
enum rpmh_regulator_type {
@ -399,13 +399,13 @@ static const struct regulator_ops rpmh_regulator_xob_ops = {
/**
* rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator
* vreg: Pointer to the individual rpmh-regulator resource
* dev: Pointer to the top level rpmh-regulator PMIC device
* node: Pointer to the individual rpmh-regulator resource
* @vreg: Pointer to the individual rpmh-regulator resource
* @dev: Pointer to the top level rpmh-regulator PMIC device
* @node: Pointer to the individual rpmh-regulator resource
* device node
* pmic_id: String used to identify the top level rpmh-regulator
* @pmic_id: String used to identify the top level rpmh-regulator
* PMIC device on the board
* pmic_rpmh_data: Pointer to a null-terminated array of rpmh-regulator
* @pmic_rpmh_data: Pointer to a null-terminated array of rpmh-regulator
* resources defined for the top level PMIC device
*
* Return: 0 on success, errno on failure

View File

@ -407,7 +407,7 @@ static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA)
return ret;
}
static struct regulator_ops uV_ops = {
static const struct regulator_ops uV_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = rpm_reg_set_uV_sel,
@ -420,7 +420,7 @@ static struct regulator_ops uV_ops = {
.set_load = rpm_reg_set_load,
};
static struct regulator_ops mV_ops = {
static const struct regulator_ops mV_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = rpm_reg_set_mV_sel,
@ -433,7 +433,7 @@ static struct regulator_ops mV_ops = {
.set_load = rpm_reg_set_load,
};
static struct regulator_ops switch_ops = {
static const struct regulator_ops switch_ops = {
.enable = rpm_reg_switch_enable,
.disable = rpm_reg_switch_disable,
.is_enabled = rpm_reg_is_enabled,

View File

@ -198,6 +198,15 @@ static const struct regulator_ops rpm_bob_ops = {
.set_voltage = rpm_reg_set_voltage,
};
static const struct regulator_ops rpm_mp5496_ops = {
.enable = rpm_reg_enable,
.disable = rpm_reg_disable,
.is_enabled = rpm_reg_is_enabled,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage = rpm_reg_set_voltage,
};
static const struct regulator_desc pma8084_hfsmps = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500),
@ -474,15 +483,6 @@ static const struct regulator_desc pmi8994_bby = {
.ops = &rpm_bob_ops,
};
static const struct regulator_desc pmi8994_boost = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(4000000, 0, 30, 50000),
},
.n_linear_ranges = 1,
.n_voltages = 31,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8998_ftsmps = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
@ -595,6 +595,24 @@ static const struct regulator_desc pms405_pldo600 = {
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc mp5496_smpa2 = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(725000, 0, 27, 12500),
},
.n_linear_ranges = 1,
.n_voltages = 28,
.ops = &rpm_mp5496_ops,
};
static const struct regulator_desc mp5496_ldoa2 = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(1800000, 0, 60, 25000),
},
.n_linear_ranges = 1,
.n_voltages = 61,
.ops = &rpm_mp5496_ops,
};
struct rpm_regulator_data {
const char *name;
u32 type;
@ -603,6 +621,12 @@ struct rpm_regulator_data {
const char *supply;
};
static const struct rpm_regulator_data rpm_mp5496_regulators[] = {
{ "s2", QCOM_SMD_RPM_SMPA, 2, &mp5496_smpa2, "s2" },
{ "l2", QCOM_SMD_RPM_LDOA, 2, &mp5496_ldoa2, "l2" },
{}
};
static const struct rpm_regulator_data rpm_pm8841_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPB, 1, &pm8x41_hfsmps, "vdd_s1" },
{ "s2", QCOM_SMD_RPM_SMPB, 2, &pm8841_ftsmps, "vdd_s2" },
@ -901,6 +925,7 @@ static const struct rpm_regulator_data rpm_pms405_regulators[] = {
};
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-pm8941-regulators", .data = &rpm_pm8941_regulators },

View File

@ -380,7 +380,7 @@ struct spmi_regulator_mapping {
enum spmi_regulator_logical_type logical_type;
u32 revision_min;
u32 revision_max;
struct regulator_ops *ops;
const struct regulator_ops *ops;
struct spmi_voltage_set_points *set_points;
int hpm_min_load;
};
@ -1261,7 +1261,7 @@ spmi_regulator_saw_set_voltage(struct regulator_dev *rdev, unsigned selector)
static struct regulator_ops spmi_saw_ops = {};
static struct regulator_ops spmi_smps_ops = {
static const struct regulator_ops spmi_smps_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1276,7 +1276,7 @@ static struct regulator_ops spmi_smps_ops = {
.set_pull_down = spmi_regulator_common_set_pull_down,
};
static struct regulator_ops spmi_ldo_ops = {
static const struct regulator_ops spmi_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1293,7 +1293,7 @@ static struct regulator_ops spmi_ldo_ops = {
.set_soft_start = spmi_regulator_common_set_soft_start,
};
static struct regulator_ops spmi_ln_ldo_ops = {
static const struct regulator_ops spmi_ln_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1305,7 +1305,7 @@ static struct regulator_ops spmi_ln_ldo_ops = {
.get_bypass = spmi_regulator_common_get_bypass,
};
static struct regulator_ops spmi_vs_ops = {
static const struct regulator_ops spmi_vs_ops = {
.enable = spmi_regulator_vs_enable,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1316,7 +1316,7 @@ static struct regulator_ops spmi_vs_ops = {
.get_mode = spmi_regulator_common_get_mode,
};
static struct regulator_ops spmi_boost_ops = {
static const struct regulator_ops spmi_boost_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1327,7 +1327,7 @@ static struct regulator_ops spmi_boost_ops = {
.set_input_current_limit = spmi_regulator_set_ilim,
};
static struct regulator_ops spmi_ftsmps_ops = {
static const struct regulator_ops spmi_ftsmps_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1342,7 +1342,7 @@ static struct regulator_ops spmi_ftsmps_ops = {
.set_pull_down = spmi_regulator_common_set_pull_down,
};
static struct regulator_ops spmi_ult_lo_smps_ops = {
static const struct regulator_ops spmi_ult_lo_smps_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1356,7 +1356,7 @@ static struct regulator_ops spmi_ult_lo_smps_ops = {
.set_pull_down = spmi_regulator_common_set_pull_down,
};
static struct regulator_ops spmi_ult_ho_smps_ops = {
static const struct regulator_ops spmi_ult_ho_smps_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1371,7 +1371,7 @@ static struct regulator_ops spmi_ult_ho_smps_ops = {
.set_pull_down = spmi_regulator_common_set_pull_down,
};
static struct regulator_ops spmi_ult_ldo_ops = {
static const struct regulator_ops spmi_ult_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1388,7 +1388,7 @@ static struct regulator_ops spmi_ult_ldo_ops = {
.set_soft_start = spmi_regulator_common_set_soft_start,
};
static struct regulator_ops spmi_ftsmps426_ops = {
static const struct regulator_ops spmi_ftsmps426_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -1403,7 +1403,7 @@ static struct regulator_ops spmi_ftsmps426_ops = {
.set_pull_down = spmi_regulator_common_set_pull_down,
};
static struct regulator_ops spmi_hfs430_ops = {
static const struct regulator_ops spmi_hfs430_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -0,0 +1,97 @@
// SPDX-License-Identifier: GPL-2.0-only
//
// Qualcomm PMIC VBUS output regulator driver
//
// Copyright (c) 2020, The Linux Foundation. All rights reserved.
#include <linux/module.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regmap.h>
#define CMD_OTG 0x40
#define OTG_EN BIT(0)
#define OTG_CFG 0x53
#define OTG_EN_SRC_CFG BIT(1)
static const struct regulator_ops qcom_usb_vbus_reg_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_desc qcom_usb_vbus_rdesc = {
.name = "usb_vbus",
.ops = &qcom_usb_vbus_reg_ops,
.owner = THIS_MODULE,
.type = REGULATOR_VOLTAGE,
};
static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct regulator_dev *rdev;
struct regmap *regmap;
struct regulator_config config = { };
struct regulator_init_data *init_data;
int ret;
u32 base;
ret = of_property_read_u32(dev->of_node, "reg", &base);
if (ret < 0) {
dev_err(dev, "no base address found\n");
return ret;
}
regmap = dev_get_regmap(dev->parent, NULL);
if (!regmap) {
dev_err(dev, "Failed to get regmap\n");
return -ENOENT;
}
init_data = of_get_regulator_init_data(dev, dev->of_node,
&qcom_usb_vbus_rdesc);
if (!init_data)
return -ENOMEM;
qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG;
qcom_usb_vbus_rdesc.enable_mask = OTG_EN;
config.dev = dev;
config.init_data = init_data;
config.regmap = regmap;
rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(dev, "not able to register vbus reg %d\n", ret);
return ret;
}
/* Disable HW logic for VBUS enable */
regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0);
return 0;
}
static const struct of_device_id qcom_usb_vbus_regulator_match[] = {
{ .compatible = "qcom,pm8150b-vbus-reg" },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match);
static struct platform_driver qcom_usb_vbus_regulator_driver = {
.driver = {
.name = "qcom-usb-vbus-regulator",
.of_match_table = qcom_usb_vbus_regulator_match,
},
.probe = qcom_usb_vbus_regulator_probe,
};
module_platform_driver(qcom_usb_vbus_regulator_driver);
MODULE_DESCRIPTION("Qualcomm USB vbus regulator driver");
MODULE_LICENSE("GPL v2");

View File

@ -15,7 +15,7 @@
#include <dt-bindings/mfd/st,stpmic1.h>
/**
* stpmic1 regulator description: this structure is used as driver data
* struct stpmic1 regulator description: this structure is used as driver data
* @desc: regulator framework description
* @mask_reset_reg: mask reset register address
* @mask_reset_mask: mask rank and mask reset register mask

185
drivers/regulator/sy8827n.c Normal file
View File

@ -0,0 +1,185 @@
// SPDX-License-Identifier: GPL-2.0
//
// SY8827N regulator driver
//
// Copyright (C) 2020 Synaptics Incorporated
//
// Author: Jisheng Zhang <jszhang@kernel.org>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#define SY8827N_VSEL0 0
#define SY8827N_BUCK_EN (1 << 7)
#define SY8827N_MODE (1 << 6)
#define SY8827N_VSEL1 1
#define SY8827N_CTRL 2
#define SY8827N_NVOLTAGES 64
#define SY8827N_VSELMIN 600000
#define SY8827N_VSELSTEP 12500
struct sy8827n_device_info {
struct device *dev;
struct regulator_desc desc;
struct regulator_init_data *regulator;
struct gpio_desc *en_gpio;
unsigned int vsel_reg;
};
static int sy8827n_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
struct sy8827n_device_info *di = rdev_get_drvdata(rdev);
switch (mode) {
case REGULATOR_MODE_FAST:
regmap_update_bits(rdev->regmap, di->vsel_reg,
SY8827N_MODE, SY8827N_MODE);
break;
case REGULATOR_MODE_NORMAL:
regmap_update_bits(rdev->regmap, di->vsel_reg,
SY8827N_MODE, 0);
break;
default:
return -EINVAL;
}
return 0;
}
static unsigned int sy8827n_get_mode(struct regulator_dev *rdev)
{
struct sy8827n_device_info *di = rdev_get_drvdata(rdev);
u32 val;
int ret = 0;
ret = regmap_read(rdev->regmap, di->vsel_reg, &val);
if (ret < 0)
return ret;
if (val & SY8827N_MODE)
return REGULATOR_MODE_FAST;
else
return REGULATOR_MODE_NORMAL;
}
static const struct regulator_ops sy8827n_regulator_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.map_voltage = regulator_map_voltage_linear,
.list_voltage = regulator_list_voltage_linear,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_mode = sy8827n_set_mode,
.get_mode = sy8827n_get_mode,
};
static int sy8827n_regulator_register(struct sy8827n_device_info *di,
struct regulator_config *config)
{
struct regulator_desc *rdesc = &di->desc;
struct regulator_dev *rdev;
rdesc->name = "sy8827n-reg";
rdesc->supply_name = "vin";
rdesc->ops = &sy8827n_regulator_ops;
rdesc->type = REGULATOR_VOLTAGE;
rdesc->n_voltages = SY8827N_NVOLTAGES;
rdesc->enable_reg = di->vsel_reg;
rdesc->enable_mask = SY8827N_BUCK_EN;
rdesc->min_uV = SY8827N_VSELMIN;
rdesc->uV_step = SY8827N_VSELSTEP;
rdesc->vsel_reg = di->vsel_reg;
rdesc->vsel_mask = rdesc->n_voltages - 1;
rdesc->owner = THIS_MODULE;
rdev = devm_regulator_register(di->dev, &di->desc, config);
return PTR_ERR_OR_ZERO(rdev);
}
static const struct regmap_config sy8827n_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static int sy8827n_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct device_node *np = dev->of_node;
struct sy8827n_device_info *di;
struct regulator_config config = { };
struct regmap *regmap;
int ret;
di = devm_kzalloc(dev, sizeof(struct sy8827n_device_info), GFP_KERNEL);
if (!di)
return -ENOMEM;
di->regulator = of_get_regulator_init_data(dev, np, &di->desc);
if (!di->regulator) {
dev_err(dev, "Platform data not found!\n");
return -EINVAL;
}
di->en_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
if (IS_ERR(di->en_gpio))
return PTR_ERR(di->en_gpio);
if (of_property_read_bool(np, "silergy,vsel-state-high"))
di->vsel_reg = SY8827N_VSEL1;
else
di->vsel_reg = SY8827N_VSEL0;
di->dev = dev;
regmap = devm_regmap_init_i2c(client, &sy8827n_regmap_config);
if (IS_ERR(regmap)) {
dev_err(dev, "Failed to allocate regmap!\n");
return PTR_ERR(regmap);
}
i2c_set_clientdata(client, di);
config.dev = di->dev;
config.init_data = di->regulator;
config.regmap = regmap;
config.driver_data = di;
config.of_node = np;
ret = sy8827n_regulator_register(di, &config);
if (ret < 0)
dev_err(dev, "Failed to register regulator!\n");
return ret;
}
static const struct of_device_id sy8827n_dt_ids[] = {
{
.compatible = "silergy,sy8827n",
},
{ }
};
MODULE_DEVICE_TABLE(of, sy8827n_dt_ids);
static const struct i2c_device_id sy8827n_id[] = {
{ "sy8827n", },
{ },
};
MODULE_DEVICE_TABLE(i2c, sy8827n_id);
static struct i2c_driver sy8827n_regulator_driver = {
.driver = {
.name = "sy8827n-regulator",
.of_match_table = of_match_ptr(sy8827n_dt_ids),
},
.probe_new = sy8827n_i2c_probe,
.id_table = sy8827n_id,
};
module_i2c_driver(sy8827n_regulator_driver);
MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>");
MODULE_DESCRIPTION("SY8827N regulator driver");
MODULE_LICENSE("GPL v2");

View File

@ -3,7 +3,7 @@
*
* Supports TPS65023 Regulator
*
* Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/
* Copyright (C) 2009 Texas Instrument Incorporated - https://www.ti.com/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as

View File

@ -3,7 +3,7 @@
*
* Regulator driver for TPS65073 PMIC
*
* Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/
* Copyright (C) 2009 Texas Instrument Incorporated - https://www.ti.com/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
*
* Author: Andrew F. Davis <afd@ti.com>
*

View File

@ -3,7 +3,7 @@
*
* Regulator driver for TPS65217 PMIC
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -124,7 +124,7 @@ static int tps65217_pmic_set_suspend_enable(struct regulator_dev *dev)
struct tps65217 *tps = rdev_get_drvdata(dev);
unsigned int rid = rdev_get_id(dev);
if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
if (rid > TPS65217_LDO_4)
return -EINVAL;
return tps65217_clear_bits(tps, dev->desc->bypass_reg,
@ -137,7 +137,7 @@ static int tps65217_pmic_set_suspend_disable(struct regulator_dev *dev)
struct tps65217 *tps = rdev_get_drvdata(dev);
unsigned int rid = rdev_get_id(dev);
if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
if (rid > TPS65217_LDO_4)
return -EINVAL;
if (!tps->strobes[rid])
@ -254,6 +254,9 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
/* Store default strobe info */
ret = tps65217_reg_read(tps, regulators[i].bypass_reg, &val);
if (ret)
return ret;
tps->strobes[i] = val & regulators[i].bypass_mask;
}

View File

@ -3,7 +3,7 @@
*
* Regulator driver for TPS65218 PMIC
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2 as
@ -128,7 +128,7 @@ static int tps65218_pmic_set_suspend_enable(struct regulator_dev *dev)
struct tps65218 *tps = rdev_get_drvdata(dev);
unsigned int rid = rdev_get_id(dev);
if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
if (rid > TPS65218_LDO_1)
return -EINVAL;
return tps65218_clear_bits(tps, dev->desc->bypass_reg,
@ -141,7 +141,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
struct tps65218 *tps = rdev_get_drvdata(dev);
unsigned int rid = rdev_get_id(dev);
if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
if (rid > TPS65218_LDO_1)
return -EINVAL;
/*

View File

@ -1,7 +1,7 @@
/*
* Regulator driver for TI TPS65912x PMICs
*
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
* Andrew F. Davis <afd@ti.com>
*
* This program is free software; you can redistribute it and/or

View File

@ -1216,11 +1216,11 @@ EXPORT_SYMBOL_GPL(wm8350_register_regulator);
/**
* wm8350_register_led - Register a WM8350 LED output
*
* @param wm8350 The WM8350 device to configure.
* @param lednum LED device index to create.
* @param dcdc The DCDC to use for the LED.
* @param isink The ISINK to use for the LED.
* @param pdata Configuration for the LED.
* @wm8350: The WM8350 device to configure.
* @lednum: LED device index to create.
* @dcdc: The DCDC to use for the LED.
* @isink: The ISINK to use for the LED.
* @pdata: Configuration for the LED.
*
* The WM8350 supports the use of an ISINK together with a DCDC to
* provide a power-efficient LED driver. This function registers the

View File

@ -234,9 +234,9 @@ static struct platform_driver wm8400_regulator_driver = {
* the regulator API. It is intended to be called from the
* platform_init() callback of the WM8400 MFD driver.
*
* @param dev The WM8400 device to operate on.
* @param reg The regulator to control.
* @param initdata Regulator initdata for the regulator.
* @dev: The WM8400 device to operate on.
* @reg: The regulator to control.
* @initdata: Regulator initdata for the regulator.
*/
int wm8400_register_regulator(struct device *dev, int reg,
struct regulator_init_data *initdata)

View File

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DT_BINDINGS_REGULATOR_DLG_DA9211_H
#define _DT_BINDINGS_REGULATOR_DLG_DA9211_H
/*
* These buck mode constants may be used to specify values in device tree
* properties (e.g. regulator-initial-mode, regulator-allowed-modes).
* A description of the following modes is in the manufacturers datasheet.
*/
#define DA9211_BUCK_MODE_SLEEP 1
#define DA9211_BUCK_MODE_SYNC 2
#define DA9211_BUCK_MODE_AUTO 3
#endif

View File

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DT_BINDINGS_REGULATOR_MEDIATEK_MT6397_H_
#define _DT_BINDINGS_REGULATOR_MEDIATEK_MT6397_H_
/*
* Buck mode constants which may be used in devicetree properties (eg.
* regulator-initial-mode, regulator-allowed-modes).
* See the manufacturer's datasheet for more information on these modes.
*/
#define MT6397_BUCK_MODE_AUTO 0
#define MT6397_BUCK_MODE_FORCE_PWM 1
#endif

View File

@ -5430,6 +5430,89 @@ struct ec_response_rollback_info {
/* Issue AP reset */
#define EC_CMD_AP_RESET 0x0125
/*****************************************************************************/
/* Voltage regulator controls */
/*
* Get basic info of voltage regulator for given index.
*
* Returns the regulator name and supported voltage list in mV.
*/
#define EC_CMD_REGULATOR_GET_INFO 0x012C
/* Maximum length of regulator name */
#define EC_REGULATOR_NAME_MAX_LEN 16
/* Maximum length of the supported voltage list. */
#define EC_REGULATOR_VOLTAGE_MAX_COUNT 16
struct ec_params_regulator_get_info {
uint32_t index;
} __ec_align4;
struct ec_response_regulator_get_info {
char name[EC_REGULATOR_NAME_MAX_LEN];
uint16_t num_voltages;
uint16_t voltages_mv[EC_REGULATOR_VOLTAGE_MAX_COUNT];
} __ec_align2;
/*
* Configure the regulator as enabled / disabled.
*/
#define EC_CMD_REGULATOR_ENABLE 0x012D
struct ec_params_regulator_enable {
uint32_t index;
uint8_t enable;
} __ec_align4;
/*
* Query if the regulator is enabled.
*
* Returns 1 if the regulator is enabled, 0 if not.
*/
#define EC_CMD_REGULATOR_IS_ENABLED 0x012E
struct ec_params_regulator_is_enabled {
uint32_t index;
} __ec_align4;
struct ec_response_regulator_is_enabled {
uint8_t enabled;
} __ec_align1;
/*
* Set voltage for the voltage regulator within the range specified.
*
* The driver should select the voltage in range closest to min_mv.
*
* Also note that this might be called before the regulator is enabled, and the
* setting should be in effect after the regulator is enabled.
*/
#define EC_CMD_REGULATOR_SET_VOLTAGE 0x012F
struct ec_params_regulator_set_voltage {
uint32_t index;
uint32_t min_mv;
uint32_t max_mv;
} __ec_align4;
/*
* Get the currently configured voltage for the voltage regulator.
*
* Note that this might be called before the regulator is enabled, and this
* should return the configured output voltage if the regulator is enabled.
*/
#define EC_CMD_REGULATOR_GET_VOLTAGE 0x0130
struct ec_params_regulator_get_voltage {
uint32_t index;
} __ec_align4;
struct ec_response_regulator_get_voltage {
uint32_t voltage_mv;
} __ec_align4;
/*****************************************************************************/
/* The command range 0x200-0x2FF is reserved for Rotor. */

View File

@ -32,10 +32,12 @@
#define __LINUX_REGULATOR_CONSUMER_H_
#include <linux/err.h>
#include <linux/suspend.h>
struct device;
struct notifier_block;
struct regmap;
struct regulator_dev;
/*
* Regulator operating modes.
@ -277,6 +279,14 @@ int regulator_unregister_notifier(struct regulator *regulator,
void devm_regulator_unregister_notifier(struct regulator *regulator,
struct notifier_block *nb);
/* regulator suspend */
int regulator_suspend_enable(struct regulator_dev *rdev,
suspend_state_t state);
int regulator_suspend_disable(struct regulator_dev *rdev,
suspend_state_t state);
int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV,
int max_uV, suspend_state_t state);
/* driver data - core doesn't touch */
void *regulator_get_drvdata(struct regulator *regulator);
void regulator_set_drvdata(struct regulator *regulator, void *data);

View File

@ -117,7 +117,7 @@ enum regulator_status {
* suspended.
* @set_suspend_mode: Set the operating mode for the regulator when the
* system is suspended.
*
* @resume: Resume operation of suspended regulator.
* @set_pull_down: Configure the regulator to pull down when the regulator
* is disabled.
*
@ -305,6 +305,9 @@ enum regulator_type {
* @enable_time: Time taken for initial enable of regulator (in uS).
* @off_on_delay: guard time (in uS), before re-enabling a regulator
*
* @poll_enabled_time: The polling interval (in uS) to use while checking that
* the regulator was actually enabled. Max upto enable_time.
*
* @of_map_mode: Maps a hardware mode defined in a DeviceTree to a standard mode
*/
struct regulator_desc {
@ -372,6 +375,8 @@ struct regulator_desc {
unsigned int off_on_delay;
unsigned int poll_enabled_time;
unsigned int (*of_map_mode)(unsigned int mode);
};

View File

@ -101,6 +101,7 @@ struct regulator_state {
* @system_load: Load that isn't captured by any consumer requests.
*
* @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.
* @valid_ops_mask: Operations which may be performed by consumers.
*

View File

@ -0,0 +1,219 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright 2020 NXP. */
#ifndef __LINUX_REG_PCA9450_H__
#define __LINUX_REG_PCA9450_H__
#include <linux/regmap.h>
enum pca9450_chip_type {
PCA9450_TYPE_PCA9450A = 0,
PCA9450_TYPE_PCA9450BC,
PCA9450_TYPE_AMOUNT,
};
enum {
PCA9450_BUCK1 = 0,
PCA9450_BUCK2,
PCA9450_BUCK3,
PCA9450_BUCK4,
PCA9450_BUCK5,
PCA9450_BUCK6,
PCA9450_LDO1,
PCA9450_LDO2,
PCA9450_LDO3,
PCA9450_LDO4,
PCA9450_LDO5,
PCA9450_REGULATOR_CNT,
};
enum {
PCA9450_DVS_LEVEL_RUN = 0,
PCA9450_DVS_LEVEL_STANDBY,
PCA9450_DVS_LEVEL_MAX,
};
#define PCA9450_BUCK1_VOLTAGE_NUM 0x80
#define PCA9450_BUCK2_VOLTAGE_NUM 0x80
#define PCA9450_BUCK3_VOLTAGE_NUM 0x80
#define PCA9450_BUCK4_VOLTAGE_NUM 0x80
#define PCA9450_BUCK5_VOLTAGE_NUM 0x80
#define PCA9450_BUCK6_VOLTAGE_NUM 0x80
#define PCA9450_LDO1_VOLTAGE_NUM 0x08
#define PCA9450_LDO2_VOLTAGE_NUM 0x08
#define PCA9450_LDO3_VOLTAGE_NUM 0x20
#define PCA9450_LDO4_VOLTAGE_NUM 0x20
#define PCA9450_LDO5_VOLTAGE_NUM 0x10
enum {
PCA9450_REG_DEV_ID = 0x00,
PCA9450_REG_INT1 = 0x01,
PCA9450_REG_INT1_MSK = 0x02,
PCA9450_REG_STATUS1 = 0x03,
PCA9450_REG_STATUS2 = 0x04,
PCA9450_REG_PWRON_STAT = 0x05,
PCA9450_REG_SWRST = 0x06,
PCA9450_REG_PWRCTRL = 0x07,
PCA9450_REG_RESET_CTRL = 0x08,
PCA9450_REG_CONFIG1 = 0x09,
PCA9450_REG_CONFIG2 = 0x0A,
PCA9450_REG_BUCK123_DVS = 0x0C,
PCA9450_REG_BUCK1OUT_LIMIT = 0x0D,
PCA9450_REG_BUCK2OUT_LIMIT = 0x0E,
PCA9450_REG_BUCK3OUT_LIMIT = 0x0F,
PCA9450_REG_BUCK1CTRL = 0x10,
PCA9450_REG_BUCK1OUT_DVS0 = 0x11,
PCA9450_REG_BUCK1OUT_DVS1 = 0x12,
PCA9450_REG_BUCK2CTRL = 0x13,
PCA9450_REG_BUCK2OUT_DVS0 = 0x14,
PCA9450_REG_BUCK2OUT_DVS1 = 0x15,
PCA9450_REG_BUCK3CTRL = 0x16,
PCA9450_REG_BUCK3OUT_DVS0 = 0x17,
PCA9450_REG_BUCK3OUT_DVS1 = 0x18,
PCA9450_REG_BUCK4CTRL = 0x19,
PCA9450_REG_BUCK4OUT = 0x1A,
PCA9450_REG_BUCK5CTRL = 0x1B,
PCA9450_REG_BUCK5OUT = 0x1C,
PCA9450_REG_BUCK6CTRL = 0x1D,
PCA9450_REG_BUCK6OUT = 0x1E,
PCA9450_REG_LDO_AD_CTRL = 0x20,
PCA9450_REG_LDO1CTRL = 0x21,
PCA9450_REG_LDO2CTRL = 0x22,
PCA9450_REG_LDO3CTRL = 0x23,
PCA9450_REG_LDO4CTRL = 0x24,
PCA9450_REG_LDO5CTRL_L = 0x25,
PCA9450_REG_LDO5CTRL_H = 0x26,
PCA9450_REG_LOADSW_CTRL = 0x2A,
PCA9450_REG_VRFLT1_STS = 0x2B,
PCA9450_REG_VRFLT2_STS = 0x2C,
PCA9450_REG_VRFLT1_MASK = 0x2D,
PCA9450_REG_VRFLT2_MASK = 0x2E,
PCA9450_MAX_REGISTER = 0x2F,
};
/* PCA9450 BUCK ENMODE bits */
#define BUCK_ENMODE_OFF 0x00
#define BUCK_ENMODE_ONREQ 0x01
#define BUCK_ENMODE_ONREQ_STBYREQ 0x02
#define BUCK_ENMODE_ON 0x03
/* PCA9450_REG_BUCK1_CTRL bits */
#define BUCK1_RAMP_MASK 0xC0
#define BUCK1_RAMP_25MV 0x0
#define BUCK1_RAMP_12P5MV 0x1
#define BUCK1_RAMP_6P25MV 0x2
#define BUCK1_RAMP_3P125MV 0x3
#define BUCK1_DVS_CTRL 0x10
#define BUCK1_AD 0x08
#define BUCK1_FPWM 0x04
#define BUCK1_ENMODE_MASK 0x03
/* PCA9450_REG_BUCK2_CTRL bits */
#define BUCK2_RAMP_MASK 0xC0
#define BUCK2_RAMP_25MV 0x0
#define BUCK2_RAMP_12P5MV 0x1
#define BUCK2_RAMP_6P25MV 0x2
#define BUCK2_RAMP_3P125MV 0x3
#define BUCK2_DVS_CTRL 0x10
#define BUCK2_AD 0x08
#define BUCK2_FPWM 0x04
#define BUCK2_ENMODE_MASK 0x03
/* PCA9450_REG_BUCK3_CTRL bits */
#define BUCK3_RAMP_MASK 0xC0
#define BUCK3_RAMP_25MV 0x0
#define BUCK3_RAMP_12P5MV 0x1
#define BUCK3_RAMP_6P25MV 0x2
#define BUCK3_RAMP_3P125MV 0x3
#define BUCK3_DVS_CTRL 0x10
#define BUCK3_AD 0x08
#define BUCK3_FPWM 0x04
#define BUCK3_ENMODE_MASK 0x03
/* PCA9450_REG_BUCK4_CTRL bits */
#define BUCK4_AD 0x08
#define BUCK4_FPWM 0x04
#define BUCK4_ENMODE_MASK 0x03
/* PCA9450_REG_BUCK5_CTRL bits */
#define BUCK5_AD 0x08
#define BUCK5_FPWM 0x04
#define BUCK5_ENMODE_MASK 0x03
/* PCA9450_REG_BUCK6_CTRL bits */
#define BUCK6_AD 0x08
#define BUCK6_FPWM 0x04
#define BUCK6_ENMODE_MASK 0x03
/* PCA9450_BUCK1OUT_DVS0 bits */
#define BUCK1OUT_DVS0_MASK 0x7F
#define BUCK1OUT_DVS0_DEFAULT 0x14
/* PCA9450_BUCK1OUT_DVS1 bits */
#define BUCK1OUT_DVS1_MASK 0x7F
#define BUCK1OUT_DVS1_DEFAULT 0x14
/* PCA9450_BUCK2OUT_DVS0 bits */
#define BUCK2OUT_DVS0_MASK 0x7F
#define BUCK2OUT_DVS0_DEFAULT 0x14
/* PCA9450_BUCK2OUT_DVS1 bits */
#define BUCK2OUT_DVS1_MASK 0x7F
#define BUCK2OUT_DVS1_DEFAULT 0x14
/* PCA9450_BUCK3OUT_DVS0 bits */
#define BUCK3OUT_DVS0_MASK 0x7F
#define BUCK3OUT_DVS0_DEFAULT 0x14
/* PCA9450_BUCK3OUT_DVS1 bits */
#define BUCK3OUT_DVS1_MASK 0x7F
#define BUCK3OUT_DVS1_DEFAULT 0x14
/* PCA9450_REG_BUCK4OUT bits */
#define BUCK4OUT_MASK 0x7F
#define BUCK4OUT_DEFAULT 0x6C
/* PCA9450_REG_BUCK5OUT bits */
#define BUCK5OUT_MASK 0x7F
#define BUCK5OUT_DEFAULT 0x30
/* PCA9450_REG_BUCK6OUT bits */
#define BUCK6OUT_MASK 0x7F
#define BUCK6OUT_DEFAULT 0x14
/* PCA9450_REG_LDO1_VOLT bits */
#define LDO1_EN_MASK 0xC0
#define LDO1OUT_MASK 0x07
/* PCA9450_REG_LDO2_VOLT bits */
#define LDO2_EN_MASK 0xC0
#define LDO2OUT_MASK 0x07
/* PCA9450_REG_LDO3_VOLT bits */
#define LDO3_EN_MASK 0xC0
#define LDO3OUT_MASK 0x0F
/* PCA9450_REG_LDO4_VOLT bits */
#define LDO4_EN_MASK 0xC0
#define LDO4OUT_MASK 0x0F
/* PCA9450_REG_LDO5_VOLT bits */
#define LDO5L_EN_MASK 0xC0
#define LDO5LOUT_MASK 0x0F
#define LDO5H_EN_MASK 0xC0
#define LDO5HOUT_MASK 0x0F
/* PCA9450_REG_IRQ bits */
#define IRQ_PWRON 0x80
#define IRQ_WDOGB 0x40
#define IRQ_RSVD 0x20
#define IRQ_VR_FLT1 0x10
#define IRQ_VR_FLT2 0x08
#define IRQ_LOWVSYS 0x04
#define IRQ_THERM_105 0x02
#define IRQ_THERM_125 0x01
#endif /* __LINUX_REG_PCA9450_H__ */