Commit 9b18d07b authored by Linus Torvalds's avatar Linus Torvalds

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

Pull regulator updates from Mark Brown:
 "This is mostly a drivers update including a couple of new drivers but
  we do have some fixes and improvements to the core as well.

   - Make sure we don't log spuriously about uncontrollable regulators.

   - Don't use delays when we should use sleeps for regulators with
     larger ramp times.

   - Support for MediaTek MT6358 and MT6366, Richtek RT5759 and Silicon
     Mitus SM5703"

* tag 'regulator-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (36 commits)
  regulator: scmi: Fix refcount leak in scmi_regulator_probe
  regulator: pfuze100: Fix refcount leak in pfuze_parse_regulators_dt
  regulator: qcom_smd: Fix up PM8950 regulator configuration
  regulator: core: Fix enable_count imbalance with EXCLUSIVE_GET
  regulator: core: Add error flags to sysfs attributes
  regulator: dt-bindings: qcom,rpmh: document vdd-l7-bob-supply on PMR735A
  regulator: dt-bindings: qcom,rpmh: document supplies per variant
  regulator: dt-bindings: qcom,rpmh: update maintainers
  regulator: mt6315: Enforce regulator-compatible, not name
  regulator: pca9450: Enable DVS control via PMIC_STBY_REQ
  regulator: pca9450: Make warm reset on WDOG_B assertion
  regulator: Add property for WDOG_B warm reset
  regulator: pca9450: Make I2C Level Translator configurable
  regulator: Add property for I2C level shifter
  regulator: sm5703: Correct reference to the common regulator schema
  regulator: sm5703-regulator: Add regulators support for SM5703 MFD
  dt-bindings: regulator: Add bindings for Silicon Mitus SM5703 regulators
  regulator: richtek,rt4801: parse GPIOs per regulator
  regulator: dt-bindings: richtek,rt4801: use existing ena_gpiod feature
  regulator: core: Sleep (not delay) in set_voltage()
  ...
parents 5d23bb5f a5b8e4a5
...@@ -370,3 +370,84 @@ Description: ...@@ -370,3 +370,84 @@ Description:
'unknown' means software cannot determine the state, or 'unknown' means software cannot determine the state, or
the reported state is invalid. the reported state is invalid.
What: /sys/class/regulator/.../under_voltage
Date: April 2022
KernelVersion: 5.18
Contact: Zev Weiss <zev@bewilderbeest.net>
Description:
Some regulator directories will contain a field called
under_voltage. This indicates if the device reports an
under-voltage fault (1) or not (0).
What: /sys/class/regulator/.../over_current
Date: April 2022
KernelVersion: 5.18
Contact: Zev Weiss <zev@bewilderbeest.net>
Description:
Some regulator directories will contain a field called
over_current. This indicates if the device reports an
over-current fault (1) or not (0).
What: /sys/class/regulator/.../regulation_out
Date: April 2022
KernelVersion: 5.18
Contact: Zev Weiss <zev@bewilderbeest.net>
Description:
Some regulator directories will contain a field called
regulation_out. This indicates if the device reports an
out-of-regulation fault (1) or not (0).
What: /sys/class/regulator/.../fail
Date: April 2022
KernelVersion: 5.18
Contact: Zev Weiss <zev@bewilderbeest.net>
Description:
Some regulator directories will contain a field called
fail. This indicates if the device reports an output failure
(1) or not (0).
What: /sys/class/regulator/.../over_temp
Date: April 2022
KernelVersion: 5.18
Contact: Zev Weiss <zev@bewilderbeest.net>
Description:
Some regulator directories will contain a field called
over_temp. This indicates if the device reports an
over-temperature fault (1) or not (0).
What: /sys/class/regulator/.../under_voltage_warn
Date: April 2022
KernelVersion: 5.18
Contact: Zev Weiss <zev@bewilderbeest.net>
Description:
Some regulator directories will contain a field called
under_voltage_warn. This indicates if the device reports an
under-voltage warning (1) or not (0).
What: /sys/class/regulator/.../over_current_warn
Date: April 2022
KernelVersion: 5.18
Contact: Zev Weiss <zev@bewilderbeest.net>
Description:
Some regulator directories will contain a field called
over_current_warn. This indicates if the device reports an
over-current warning (1) or not (0).
What: /sys/class/regulator/.../over_voltage_warn
Date: April 2022
KernelVersion: 5.18
Contact: Zev Weiss <zev@bewilderbeest.net>
Description:
Some regulator directories will contain a field called
over_voltage_warn. This indicates if the device reports an
over-voltage warning (1) or not (0).
What: /sys/class/regulator/.../over_temp_warn
Date: April 2022
KernelVersion: 5.18
Contact: Zev Weiss <zev@bewilderbeest.net>
Description:
Some regulator directories will contain a field called
over_temp_warn. This indicates if the device reports an
over-temperature warning (1) or not (0).
...@@ -31,7 +31,7 @@ properties: ...@@ -31,7 +31,7 @@ properties:
$ref: "regulator.yaml#" $ref: "regulator.yaml#"
properties: properties:
regulator-name: regulator-compatible:
pattern: "^vbuck[1-4]$" pattern: "^vbuck[1-4]$"
additionalProperties: false additionalProperties: false
......
...@@ -8,14 +8,14 @@ Documentation/devicetree/bindings/regulator/regulator.txt. ...@@ -8,14 +8,14 @@ Documentation/devicetree/bindings/regulator/regulator.txt.
The valid names for regulators are:: The valid names for regulators are::
BUCK: BUCK:
buck_vdram1, buck_vcore, buck_vpa, buck_vproc11, buck_vproc12, buck_vgpu, buck_vdram1, buck_vcore, buck_vcore_sshub, buck_vpa, buck_vproc11,
buck_vs2, buck_vmodem, buck_vs1 buck_vproc12, buck_vgpu, buck_vs2, buck_vmodem, buck_vs1
LDO: LDO:
ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio, ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio,
ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others, ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others,
ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28, ldo_vsram_others_sshub, ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18,
ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18, ldo_vmch, ldo_vbif28, ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12,
ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28, ldo_vrf18, ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
ldo_vsim2 ldo_vsim2
Example: Example:
...@@ -354,5 +354,17 @@ Example: ...@@ -354,5 +354,17 @@ Example:
regulator-max-microvolt = <3100000>; regulator-max-microvolt = <3100000>;
regulator-enable-ramp-delay = <540>; regulator-enable-ramp-delay = <540>;
}; };
mt6358_vcore_sshub_reg: buck_vcore_sshub {
regulator-name = "vcore_sshub";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1293750>;
};
mt6358_vsram_others_sshub_reg: ldo_vsram_others_sshub {
regulator-name = "vsram_others_sshub";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1293750>;
};
}; };
}; };
...@@ -92,6 +92,17 @@ properties: ...@@ -92,6 +92,17 @@ properties:
LDO5CTRL_L or LDO5CTRL_H register. Use this if the SD_VSEL signal is LDO5CTRL_L or LDO5CTRL_H register. Use this if the SD_VSEL signal is
connected to a host GPIO. connected to a host GPIO.
nxp,i2c-lt-enable:
type: boolean
description:
Indicates that the I2C Level Translator is used.
nxp,wdog_b-warm-reset:
type: boolean
description:
When WDOG_B signal is asserted a warm reset will be done instead of cold
reset.
required: required:
- compatible - compatible
- reg - reg
......
...@@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# ...@@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. RPMh Regulators title: Qualcomm Technologies, Inc. RPMh Regulators
maintainers: maintainers:
- David Collins <collinsd@codeaurora.org> - Bjorn Andersson <bjorn.andersson@linaro.org>
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
description: | description: |
rpmh-regulator devices support PMIC regulator management via the Voltage rpmh-regulator devices support PMIC regulator management via the Voltage
...@@ -78,7 +79,7 @@ properties: ...@@ -78,7 +79,7 @@ properties:
RPMh resource name suffix used for the regulators found RPMh resource name suffix used for the regulators found
on this PMIC. on this PMIC.
$ref: /schemas/types.yaml#/definitions/string $ref: /schemas/types.yaml#/definitions/string
enum: [a, b, c, d, e, f] enum: [a, b, c, d, e, f, h, k]
qcom,always-wait-for-ack: qcom,always-wait-for-ack:
description: | description: |
...@@ -94,35 +95,264 @@ properties: ...@@ -94,35 +95,264 @@ properties:
vdd-rgb-supply: vdd-rgb-supply:
description: Input supply phandle of rgb. description: Input supply phandle of rgb.
vin-lvs-1-2-supply:
description: Input supply phandle of one or more regulators.
vdd-bob-supply:
description: BOB regulator parent supply phandle.
bob: bob:
type: object type: object
$ref: "regulator.yaml#" $ref: "regulator.yaml#"
description: BOB regulator node. description: BOB regulator node.
patternProperties: patternProperties:
"^vdd-s([0-9]+)-supply$":
description: Input supply phandle(s) of one or more regulators.
"^vdd-(l[0-9]+[-]){1,5}supply$":
description: Input supply phandle(s) of one or more regulators.
"^(smps|ldo|lvs)[0-9]+$": "^(smps|ldo|lvs)[0-9]+$":
type: object type: object
$ref: "regulator.yaml#" $ref: "regulator.yaml#"
description: smps/ldo regulator nodes(s). description: smps/ldo regulator nodes(s).
additionalProperties: false
required: required:
- compatible - compatible
- qcom,pmic-id - qcom,pmic-id
allOf:
- if:
properties:
compatible:
enum:
- qcom,pm6150-rpmh-regulators
then:
properties:
vdd-l2-l3-supply: true
vdd-l4-l7-l8-supply: true
vdd-l5-l16-l17-l18-l19-supply: true
vdd-l10-l14-l15-supply: true
vdd-l11-l12-l13-supply: true
patternProperties:
"^vdd-l[169]-supply$": true
"^vdd-s[1-5]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm6150l-rpmh-regulators
then:
properties:
vdd-bob-supply:
description: BOB regulator parent supply phandle.
vdd-l1-l8-supply: true
vdd-l2-l3-supply: true
vdd-l4-l5-l6-supply: true
vdd-l7-l11-supply: true
vdd-l9-l10-supply: true
patternProperties:
"^vdd-s[1-8]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm7325-rpmh-regulators
then:
properties:
vdd-l1-l4-l12-l15-supply: true
vdd-l2-l7-supply: true
vdd-l6-l9-l10-supply: true
vdd-l11-l17-l18-l19-supply: true
vdd-l13-supply: true
vdd-l14-l16-supply: true
patternProperties:
"^vdd-l[358]-supply$": true
"^vdd-s[1-8]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm8005-rpmh-regulators
then:
patternProperties:
"^vdd-s[1-4]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm8009-rpmh-regulators
- qcom,pm8009-1-rpmh-regulators
then:
properties:
vdd-l5-l6-supply: true
patternProperties:
"^vdd-l[1-47]-supply$": true
"^vdd-s[1-2]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm8150-rpmh-regulators
- qcom,pmm8155au-rpmh-regulators
then:
properties:
vdd-l1-l8-l11-supply: true
vdd-l2-l10-supply: true
vdd-l3-l4-l5-l18-supply: true
vdd-l6-l9-supply: true
vdd-l7-l12-l14-l15-supply: true
vdd-l13-l16-l17-supply: true
patternProperties:
"^vdd-s([1-9]|10)-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm8150l-rpmh-regulators
then:
properties:
vdd-bob-supply:
description: BOB regulator parent supply phandle.
vdd-l1-l8-supply: true
vdd-l2-l3-supply: true
vdd-l4-l5-l6-supply: true
vdd-l7-l11-supply: true
vdd-l9-l10-supply: true
patternProperties:
"^vdd-s[1-8]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm8350-rpmh-regulators
then:
properties:
vdd-l1-l4-supply: true
vdd-l2-l7-supply: true
vdd-l3-l5-supply: true
vdd-l6-l9-l10-supply: true
vdd-l8-supply: true
patternProperties:
"^vdd-s([1-9]|1[0-2])-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm8350c-rpmh-regulators
then:
properties:
vdd-bob-supply:
description: BOB regulator parent supply phandle.
vdd-l1-l12-supply: true
vdd-l2-l8-supply: true
vdd-l3-l4-l5-l7-l13-supply: true
vdd-l6-l9-l11-supply: true
vdd-l10-supply: true
patternProperties:
"^vdd-s([1-9]|10)-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm8450-rpmh-regulators
then:
patternProperties:
"^vdd-l[1-4]-supply$": true
"^vdd-s[1-6]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm8998-rpmh-regulators
then:
properties:
vdd-l1-l27-supply: true
vdd-l2-l8-l17-supply: true
vdd-l3-l11-supply: true
vdd-l4-l5-supply: true
vdd-l6-supply: true
vdd-l7-l12-l14-l15-supply: true
vdd-l9-supply: true
vdd-l10-l23-l25-supply: true
vdd-l13-l19-l21-supply: true
vdd-l16-l28-supply: true
vdd-l18-l22-supply: true
vdd-l20-l24-supply: true
vdd-l26-supply: true
vin-lvs-1-2-supply: true
patternProperties:
"^vdd-s([1-9]|1[0-3])-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pmg1110-rpmh-regulators
then:
properties:
vdd-s1-supply: true
- if:
properties:
compatible:
enum:
- qcom,pmi8998-rpmh-regulators
then:
properties:
vdd-bob-supply:
description: BOB regulator parent supply phandle.
- if:
properties:
compatible:
enum:
- qcom,pmr735a-rpmh-regulators
then:
properties:
vdd-l1-l2-supply: true
vdd-l3-supply: true
vdd-l4-supply: true
vdd-l5-l6-supply: true
vdd-l7-bob-supply: true
patternProperties:
"^vdd-s[1-3]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pmx55-rpmh-regulators
then:
properties:
vdd-l1-l2-supply: true
vdd-l3-l9-supply: true
vdd-l4-l12-supply: true
vdd-l5-l6-supply: true
vdd-l7-l8-supply: true
vdd-l10-l11-l13-supply: true
patternProperties:
"^vdd-l1[4-6]-supply$": true
"^vdd-s[1-7]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pmx65-rpmh-regulators
then:
properties:
vdd-l2-l18-supply: true
vdd-l5-l6-l16-supply: true
vdd-l8-l9-supply: true
vdd-l11-l13-supply: true
patternProperties:
"^vdd-l[1347]-supply$": true
"^vdd-l1[0245789]-supply$": true
"^vdd-l2[01]-supply$": true
"^vdd-s[1-8]-supply$": true
unevaluatedProperties: false
examples: examples:
- | - |
#include <dt-bindings/regulator/qcom,rpmh-regulator.h> #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
......
...@@ -17,9 +17,6 @@ description: | ...@@ -17,9 +17,6 @@ description: |
Datasheet is available at Datasheet is available at
https://www.richtek.com/assets/product_file/RT4801H/DS4801H-00.pdf https://www.richtek.com/assets/product_file/RT4801H/DS4801H-00.pdf
#The valid names for RT4801 regulator nodes are:
#DSVP, DSVN
properties: properties:
compatible: compatible:
enum: enum:
...@@ -33,10 +30,13 @@ properties: ...@@ -33,10 +30,13 @@ properties:
The first one is ENP to enable DSVP, and second one is ENM to enable DSVN. The first one is ENP to enable DSVP, and second one is ENM to enable DSVN.
Number of GPIO in the array list could be 1 or 2. Number of GPIO in the array list could be 1 or 2.
If only one gpio is specified, only one gpio used to control ENP/ENM. If only one gpio is specified, only one gpio used to control ENP/ENM.
Else both are spefied, DSVP/DSVN could be controlled individually. Else if both are specified, DSVP/DSVN could be controlled individually.
Othersie, this property not specified. treat both as always-on regulator. If this property not specified, treat both as always-on regulators.
Property is deprecated. Use enable-gpios in each regulator.
minItems: 1 minItems: 1
maxItems: 2 maxItems: 2
deprecated: true
patternProperties: patternProperties:
"^DSV(P|N)$": "^DSV(P|N)$":
...@@ -45,6 +45,14 @@ patternProperties: ...@@ -45,6 +45,14 @@ patternProperties:
description: description:
Properties for single display bias regulator. Properties for single display bias regulator.
properties:
enable-gpios:
description:
GPIO to use to enable DSVP/DSVN regulator. One GPIO can be configured
for controlling both regulators. If this property not specified for
any regulator, treat both as always-on regulators.
maxItems: 1
required: required:
- compatible - compatible
- reg - reg
...@@ -60,19 +68,20 @@ examples: ...@@ -60,19 +68,20 @@ examples:
rt4801@73 { rt4801@73 {
compatible = "richtek,rt4801"; compatible = "richtek,rt4801";
reg = <0x73>; reg = <0x73>;
enable-gpios = <&gpio26 2 0>, <&gpio26 3 0>;
dsvp: DSVP { dsvp: DSVP {
regulator-name = "rt4801,dsvp"; regulator-name = "rt4801,dsvp";
regulator-min-microvolt = <4000000>; regulator-min-microvolt = <4000000>;
regulator-max-microvolt = <6000000>; regulator-max-microvolt = <6000000>;
regulator-boot-on; regulator-boot-on;
enable-gpios = <&gpio26 2 0>;
}; };
dsvn: DSVN { dsvn: DSVN {
regulator-name = "rt4801,dsvn"; regulator-name = "rt4801,dsvn";
regulator-min-microvolt = <4000000>; regulator-min-microvolt = <4000000>;
regulator-max-microvolt = <6000000>; regulator-max-microvolt = <6000000>;
regulator-boot-on; regulator-boot-on;
enable-gpios = <&gpio26 3 0>;
}; };
}; };
......
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/richtek,rt5759-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Richtek RT5759 High Performance DCDC Converter
maintainers:
- ChiYuan Huang <cy_huang@richtek.com>
description: |
The RT5759 is a high-performance, synchronous step-down DC-DC converter that
can deliver up to 9A output current from 3V to 6.5V input supply, The output
voltage can be programmable with I2C controlled 7-Bit VID.
Datasheet is available at
https://www.richtek.com/assets/product_file/RT5759/DS5759-00.pdf
properties:
compatible:
enum:
- richtek,rt5759
- richtek,rt5759a
reg:
maxItems: 1
regulator-allowed-modes:
description: |
buck allowed operating mode
0: auto mode (PSKIP: pulse skipping)
1: force pwm mode
items:
enum: [0, 1]
richtek,watchdog-enable:
description: enable the external watchdog reset pin listening
type: boolean
allOf:
- $ref: regulator.yaml#
- if:
properties:
compatible:
contains:
const: richtek,rt5759
then:
properties:
richtek,watchdog-enable: false
required:
- compatible
- reg
unevaluatedProperties: false
examples:
# example 1 for RT5759
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
regulator@62 {
compatible = "richtek,rt5759";
reg = <0x62>;
regulator-name = "rt5759-buck";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1500000>;
regulator-boot-on;
};
};
# example 2 for RT5759A
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
regulator@62 {
compatible = "richtek,rt5759a";
reg = <0x62>;
regulator-name = "rt5759a-buck";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1725000>;
regulator-boot-on;
richtek,watchdog-enable;
};
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/siliconmitus,sm5703-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Silicon Mitus SM5703 multi function device regulators
maintainers:
- Markuss Broks <markuss.broks@gmail.com>
description: |
SM5703 regulators node should be a sub node of the SM5703 MFD node. See SM5703 MFD
bindings at Documentation/devicetree/bindings/mfd/siliconmitus,sm5703.yaml
Regulator nodes should be named as USBLDO_<number>, BUCK, VBUS, LDO_<number>.
The definition for each of these nodes is defined using the standard
binding for regulators at Documentation/devicetree/bindings/regulator/regulator.txt.
properties:
buck:
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for the BUCK regulator.
vbus:
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for the VBUS regulator.
patternProperties:
"^ldo[1-3]$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for single LDO regulator.
"^usbldo[1-2]$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for a single USBLDO regulator.
additionalProperties: false
...@@ -14,9 +14,6 @@ description: | ...@@ -14,9 +14,6 @@ description: |
maintainers: maintainers:
- Kunihiko Hayashi <hayashi.kunihiko@socionext.com> - Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
allOf:
- $ref: "regulator.yaml#"
# USB3 Controller # USB3 Controller
properties: properties:
...@@ -36,27 +33,51 @@ properties: ...@@ -36,27 +33,51 @@ properties:
minItems: 1 minItems: 1
maxItems: 2 maxItems: 2
clock-names: clock-names: true
oneOf:
- items: # for Pro4, Pro5
- const: gio
- const: link
- items: # for others
- const: link
resets: resets:
minItems: 1 minItems: 1
maxItems: 2 maxItems: 2
reset-names: reset-names: true
oneOf:
- items: # for Pro4, Pro5
- const: gio
- const: link
- items:
- const: link
additionalProperties: false allOf:
- $ref: "regulator.yaml#"
- if:
properties:
compatible:
contains:
enum:
- socionext,uniphier-pro4-usb3-regulator
- socionext,uniphier-pro5-usb3-regulator
then:
properties:
clocks:
minItems: 2
maxItems: 2
clock-names:
items:
- const: gio
- const: link
resets:
minItems: 2
maxItems: 2
reset-names:
items:
- const: gio
- const: link
else:
properties:
clocks:
maxItems: 1
clock-names:
const: link
resets:
maxItems: 1
reset-names:
const: link
unevaluatedProperties: false
required: required:
- compatible - compatible
......
...@@ -1057,6 +1057,16 @@ config REGULATOR_RT5190A ...@@ -1057,6 +1057,16 @@ config REGULATOR_RT5190A
buck converters, 1 LDO, mute AC OFF depop function, with the general buck converters, 1 LDO, mute AC OFF depop function, with the general
I2C control interface. I2C control interface.
config REGULATOR_RT5759
tristate "Richtek RT5759 Regulator"
depends on I2C
select REGMAP_I2C
help
This adds support for voltage regulator in Richtek RT5759.
The RT5759 is a high-performance, synchronous step-down DC-DC
converter that can deliver up to 9A output current from 3V to 6.5V
input supply.
config REGULATOR_RT6160 config REGULATOR_RT6160
tristate "Richtek RT6160 BuckBoost voltage regulator" tristate "Richtek RT6160 BuckBoost voltage regulator"
depends on I2C depends on I2C
...@@ -1157,6 +1167,13 @@ config REGULATOR_SLG51000 ...@@ -1157,6 +1167,13 @@ config REGULATOR_SLG51000
The SLG51000 is seven compact and customizable low dropout The SLG51000 is seven compact and customizable low dropout
regulators. regulators.
config REGULATOR_SM5703
tristate "Silicon Mitus SM5703 regulators"
depends on MFD_SM5703
help
This driver provides support for voltage regulators of SM5703
multi-function device.
config REGULATOR_STM32_BOOSTER config REGULATOR_STM32_BOOSTER
tristate "STMicroelectronics STM32 BOOSTER" tristate "STMicroelectronics STM32 BOOSTER"
depends on ARCH_STM32 || COMPILE_TEST depends on ARCH_STM32 || COMPILE_TEST
......
...@@ -127,6 +127,7 @@ obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o ...@@ -127,6 +127,7 @@ obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o
obj-$(CONFIG_REGULATOR_RT4831) += rt4831-regulator.o obj-$(CONFIG_REGULATOR_RT4831) += rt4831-regulator.o
obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
obj-$(CONFIG_REGULATOR_RT5190A) += rt5190a-regulator.o obj-$(CONFIG_REGULATOR_RT5190A) += rt5190a-regulator.o
obj-$(CONFIG_REGULATOR_RT5759) += rt5759-regulator.o
obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o
obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o
obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
...@@ -138,6 +139,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o ...@@ -138,6 +139,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o
obj-$(CONFIG_REGULATOR_SM5703) += sm5703-regulator.o
obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o
obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
......
...@@ -83,6 +83,7 @@ struct regulator_supply_alias { ...@@ -83,6 +83,7 @@ struct regulator_supply_alias {
static int _regulator_is_enabled(struct regulator_dev *rdev); static int _regulator_is_enabled(struct regulator_dev *rdev);
static int _regulator_disable(struct regulator *regulator); static int _regulator_disable(struct regulator *regulator);
static int _regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags);
static int _regulator_get_current_limit(struct regulator_dev *rdev); static int _regulator_get_current_limit(struct regulator_dev *rdev);
static unsigned int _regulator_get_mode(struct regulator_dev *rdev); static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
static int _notifier_call_chain(struct regulator_dev *rdev, static int _notifier_call_chain(struct regulator_dev *rdev,
...@@ -911,6 +912,30 @@ static ssize_t bypass_show(struct device *dev, ...@@ -911,6 +912,30 @@ static ssize_t bypass_show(struct device *dev,
} }
static DEVICE_ATTR_RO(bypass); static DEVICE_ATTR_RO(bypass);
#define REGULATOR_ERROR_ATTR(name, bit) \
static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
int ret; \
unsigned int flags; \
struct regulator_dev *rdev = dev_get_drvdata(dev); \
ret = _regulator_get_error_flags(rdev, &flags); \
if (ret) \
return ret; \
return sysfs_emit(buf, "%d\n", !!(flags & (bit))); \
} \
static DEVICE_ATTR_RO(name)
REGULATOR_ERROR_ATTR(under_voltage, REGULATOR_ERROR_UNDER_VOLTAGE);
REGULATOR_ERROR_ATTR(over_current, REGULATOR_ERROR_OVER_CURRENT);
REGULATOR_ERROR_ATTR(regulation_out, REGULATOR_ERROR_REGULATION_OUT);
REGULATOR_ERROR_ATTR(fail, REGULATOR_ERROR_FAIL);
REGULATOR_ERROR_ATTR(over_temp, REGULATOR_ERROR_OVER_TEMP);
REGULATOR_ERROR_ATTR(under_voltage_warn, REGULATOR_ERROR_UNDER_VOLTAGE_WARN);
REGULATOR_ERROR_ATTR(over_current_warn, REGULATOR_ERROR_OVER_CURRENT_WARN);
REGULATOR_ERROR_ATTR(over_voltage_warn, REGULATOR_ERROR_OVER_VOLTAGE_WARN);
REGULATOR_ERROR_ATTR(over_temp_warn, REGULATOR_ERROR_OVER_TEMP_WARN);
/* Calculate the new optimum regulator operating mode based on the new total /* Calculate the new optimum regulator operating mode based on the new total
* consumer load. All locks held by caller * consumer load. All locks held by caller
*/ */
...@@ -1522,6 +1547,24 @@ static int set_machine_constraints(struct regulator_dev *rdev) ...@@ -1522,6 +1547,24 @@ static int set_machine_constraints(struct regulator_dev *rdev)
} }
} }
/*
* If there is no mechanism for controlling the regulator then
* flag it as always_on so we don't end up duplicating checks
* for this so much. Note that we could control the state of
* a supply to control the output on a regulator that has no
* direct control.
*/
if (!rdev->ena_pin && !ops->enable) {
if (rdev->supply_name && !rdev->supply)
return -EPROBE_DEFER;
if (rdev->supply)
rdev->constraints->always_on =
rdev->supply->rdev->constraints->always_on;
else
rdev->constraints->always_on = true;
}
/* If the constraints say the regulator should be on at this point /* If the constraints say the regulator should be on at this point
* and we have control then make sure it is enabled. * and we have control then make sure it is enabled.
*/ */
...@@ -2133,10 +2176,13 @@ struct regulator *_regulator_get(struct device *dev, const char *id, ...@@ -2133,10 +2176,13 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
rdev->exclusive = 1; rdev->exclusive = 1;
ret = _regulator_is_enabled(rdev); ret = _regulator_is_enabled(rdev);
if (ret > 0) if (ret > 0) {
rdev->use_count = 1; rdev->use_count = 1;
else regulator->enable_count = 1;
} else {
rdev->use_count = 0; rdev->use_count = 0;
regulator->enable_count = 0;
}
} }
link = device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS); link = device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS);
...@@ -2511,17 +2557,17 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) ...@@ -2511,17 +2557,17 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
} }
/** /**
* _regulator_enable_delay - a delay helper function * _regulator_delay_helper - a delay helper function
* @delay: time to delay in microseconds * @delay: time to delay in microseconds
* *
* Delay for the requested amount of time as per the guidelines in: * Delay for the requested amount of time as per the guidelines in:
* *
* Documentation/timers/timers-howto.rst * Documentation/timers/timers-howto.rst
* *
* The assumption here is that regulators will never be enabled in * The assumption here is that these regulator operations will never used in
* atomic context and therefore sleeping functions can be used. * atomic context and therefore sleeping functions can be used.
*/ */
static void _regulator_enable_delay(unsigned int delay) static void _regulator_delay_helper(unsigned int delay)
{ {
unsigned int ms = delay / 1000; unsigned int ms = delay / 1000;
unsigned int us = delay % 1000; unsigned int us = delay % 1000;
...@@ -2603,7 +2649,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) ...@@ -2603,7 +2649,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
s64 remaining = ktime_us_delta(end, ktime_get()); s64 remaining = ktime_us_delta(end, ktime_get());
if (remaining > 0) if (remaining > 0)
_regulator_enable_delay(remaining); _regulator_delay_helper(remaining);
} }
if (rdev->ena_pin) { if (rdev->ena_pin) {
...@@ -2630,14 +2676,14 @@ static int _regulator_do_enable(struct regulator_dev *rdev) ...@@ -2630,14 +2676,14 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
/* If poll_enabled_time is set, poll upto the delay calculated /* If poll_enabled_time is set, poll upto the delay calculated
* above, delaying poll_enabled_time uS to check if the regulator * above, delaying poll_enabled_time uS to check if the regulator
* actually got enabled. * actually got enabled.
* If the regulator isn't enabled after enable_delay has * If the regulator isn't enabled after our delay helper has expired,
* expired, return -ETIMEDOUT. * return -ETIMEDOUT.
*/ */
if (rdev->desc->poll_enabled_time) { if (rdev->desc->poll_enabled_time) {
unsigned int time_remaining = delay; unsigned int time_remaining = delay;
while (time_remaining > 0) { while (time_remaining > 0) {
_regulator_enable_delay(rdev->desc->poll_enabled_time); _regulator_delay_helper(rdev->desc->poll_enabled_time);
if (rdev->desc->ops->get_status) { if (rdev->desc->ops->get_status) {
ret = _regulator_check_status_enabled(rdev); ret = _regulator_check_status_enabled(rdev);
...@@ -2656,7 +2702,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) ...@@ -2656,7 +2702,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
} else { } else {
_regulator_enable_delay(delay); _regulator_delay_helper(delay);
} }
trace_regulator_enable_complete(rdev_get_name(rdev)); trace_regulator_enable_complete(rdev_get_name(rdev));
...@@ -3548,12 +3594,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ...@@ -3548,12 +3594,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
} }
/* Insert any necessary delays */ /* Insert any necessary delays */
if (delay >= 1000) { _regulator_delay_helper(delay);
mdelay(delay / 1000);
udelay(delay % 1000);
} else if (delay) {
udelay(delay);
}
if (best_val >= 0) { if (best_val >= 0) {
unsigned long data = best_val; unsigned long data = best_val;
...@@ -4971,6 +5012,15 @@ static struct attribute *regulator_dev_attrs[] = { ...@@ -4971,6 +5012,15 @@ static struct attribute *regulator_dev_attrs[] = {
&dev_attr_max_microvolts.attr, &dev_attr_max_microvolts.attr,
&dev_attr_min_microamps.attr, &dev_attr_min_microamps.attr,
&dev_attr_max_microamps.attr, &dev_attr_max_microamps.attr,
&dev_attr_under_voltage.attr,
&dev_attr_over_current.attr,
&dev_attr_regulation_out.attr,
&dev_attr_fail.attr,
&dev_attr_over_temp.attr,
&dev_attr_under_voltage_warn.attr,
&dev_attr_over_current_warn.attr,
&dev_attr_over_voltage_warn.attr,
&dev_attr_over_temp_warn.attr,
&dev_attr_suspend_standby_state.attr, &dev_attr_suspend_standby_state.attr,
&dev_attr_suspend_mem_state.attr, &dev_attr_suspend_mem_state.attr,
&dev_attr_suspend_disk_state.attr, &dev_attr_suspend_disk_state.attr,
...@@ -5026,6 +5076,17 @@ static umode_t regulator_attr_is_visible(struct kobject *kobj, ...@@ -5026,6 +5076,17 @@ static umode_t regulator_attr_is_visible(struct kobject *kobj,
if (attr == &dev_attr_bypass.attr) if (attr == &dev_attr_bypass.attr)
return ops->get_bypass ? mode : 0; return ops->get_bypass ? mode : 0;
if (attr == &dev_attr_under_voltage.attr ||
attr == &dev_attr_over_current.attr ||
attr == &dev_attr_regulation_out.attr ||
attr == &dev_attr_fail.attr ||
attr == &dev_attr_over_temp.attr ||
attr == &dev_attr_under_voltage_warn.attr ||
attr == &dev_attr_over_current_warn.attr ||
attr == &dev_attr_over_voltage_warn.attr ||
attr == &dev_attr_over_temp_warn.attr)
return ops->get_error_flags ? mode : 0;
/* constraints need specific supporting methods */ /* constraints need specific supporting methods */
if (attr == &dev_attr_min_microvolts.attr || if (attr == &dev_attr_min_microvolts.attr ||
attr == &dev_attr_max_microvolts.attr) attr == &dev_attr_max_microvolts.attr)
......
...@@ -1030,6 +1030,8 @@ static int da9121_assign_chip_model(struct i2c_client *i2c, ...@@ -1030,6 +1030,8 @@ static int da9121_assign_chip_model(struct i2c_client *i2c,
chip->variant_id = DA9121_TYPE_DA9142; chip->variant_id = DA9121_TYPE_DA9142;
regmap = &da9121_2ch_regmap_config; regmap = &da9121_2ch_regmap_config;
break; break;
default:
return -EINVAL;
} }
/* Set these up for of_regulator_match call which may want .of_map_modes */ /* Set these up for of_regulator_match call which may want .of_map_modes */
......
...@@ -236,11 +236,8 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) ...@@ -236,11 +236,8 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
drvdata->desc.supply_name = devm_kstrdup(&pdev->dev, drvdata->desc.supply_name = devm_kstrdup(&pdev->dev,
config->input_supply, config->input_supply,
GFP_KERNEL); GFP_KERNEL);
if (!drvdata->desc.supply_name) { if (!drvdata->desc.supply_name)
dev_err(&pdev->dev,
"Failed to allocate input supply\n");
return -ENOMEM; return -ENOMEM;
}
} }
if (config->microvolts) if (config->microvolts)
......
This diff is collapsed.
...@@ -174,6 +174,14 @@ static int buck_set_dvs(const struct regulator_desc *desc, ...@@ -174,6 +174,14 @@ static int buck_set_dvs(const struct regulator_desc *desc,
} }
} }
if (ret == 0) {
struct pca9450_regulator_desc *regulator = container_of(desc,
struct pca9450_regulator_desc, desc);
/* Enable DVS control through PMIC_STBY_REQ for this BUCK */
ret = regmap_update_bits(regmap, regulator->desc.enable_reg,
BUCK1_DVS_CTRL, BUCK1_DVS_CTRL);
}
return ret; return ret;
} }
...@@ -702,6 +710,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c, ...@@ -702,6 +710,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,
struct regulator_config config = { }; struct regulator_config config = { };
struct pca9450 *pca9450; struct pca9450 *pca9450;
unsigned int device_id, i; unsigned int device_id, i;
unsigned int reset_ctrl;
int ret; int ret;
if (!i2c->irq) { if (!i2c->irq) {
...@@ -802,14 +811,30 @@ static int pca9450_i2c_probe(struct i2c_client *i2c, ...@@ -802,14 +811,30 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,
return ret; return ret;
} }
if (of_property_read_bool(i2c->dev.of_node, "nxp,wdog_b-warm-reset"))
reset_ctrl = WDOG_B_CFG_WARM;
else
reset_ctrl = WDOG_B_CFG_COLD_LDO12;
/* Set reset behavior on assertion of WDOG_B signal */ /* Set reset behavior on assertion of WDOG_B signal */
ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL, ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
WDOG_B_CFG_MASK, WDOG_B_CFG_COLD_LDO12); WDOG_B_CFG_MASK, reset_ctrl);
if (ret) { if (ret) {
dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n"); dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");
return ret; return ret;
} }
if (of_property_read_bool(i2c->dev.of_node, "nxp,i2c-lt-enable")) {
/* Enable I2C Level Translator */
ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_CONFIG2,
I2C_LT_MASK, I2C_LT_ON_STANDBY_RUN);
if (ret) {
dev_err(&i2c->dev,
"Failed to enable I2C level translator\n");
return ret;
}
}
/* /*
* The driver uses the LDO5CTRL_H register to control the LDO5 regulator. * The driver uses the LDO5CTRL_H register to control the LDO5 regulator.
* This is only valid if the SD_VSEL input of the PMIC is high. Let's * This is only valid if the SD_VSEL input of the PMIC is high. Let's
......
...@@ -521,6 +521,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) ...@@ -521,6 +521,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
parent = of_get_child_by_name(np, "regulators"); parent = of_get_child_by_name(np, "regulators");
if (!parent) { if (!parent) {
dev_err(dev, "regulators node not found\n"); dev_err(dev, "regulators node not found\n");
of_node_put(np);
return -EINVAL; return -EINVAL;
} }
...@@ -550,6 +551,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) ...@@ -550,6 +551,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
} }
of_node_put(parent); of_node_put(parent);
of_node_put(np);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Error parsing regulator init data: %d\n", dev_err(dev, "Error parsing regulator init data: %d\n",
ret); ret);
......
...@@ -944,32 +944,31 @@ static const struct rpm_regulator_data rpm_pm8950_regulators[] = { ...@@ -944,32 +944,31 @@ static const struct rpm_regulator_data rpm_pm8950_regulators[] = {
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pm8950_hfsmps, "vdd_s2" }, { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8950_hfsmps, "vdd_s2" },
{ "s3", QCOM_SMD_RPM_SMPA, 3, &pm8950_hfsmps, "vdd_s3" }, { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8950_hfsmps, "vdd_s3" },
{ "s4", QCOM_SMD_RPM_SMPA, 4, &pm8950_hfsmps, "vdd_s4" }, { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8950_hfsmps, "vdd_s4" },
{ "s5", QCOM_SMD_RPM_SMPA, 5, &pm8950_ftsmps2p5, "vdd_s5" }, /* S5 is managed via SPMI. */
{ "s6", QCOM_SMD_RPM_SMPA, 6, &pm8950_hfsmps, "vdd_s6" }, { "s6", QCOM_SMD_RPM_SMPA, 6, &pm8950_hfsmps, "vdd_s6" },
{ "l1", QCOM_SMD_RPM_LDOA, 1, &pm8950_ult_nldo, "vdd_l1_l19" }, { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8950_ult_nldo, "vdd_l1_l19" },
{ "l2", QCOM_SMD_RPM_LDOA, 2, &pm8950_ult_nldo, "vdd_l2_l23" }, { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8950_ult_nldo, "vdd_l2_l23" },
{ "l3", QCOM_SMD_RPM_LDOA, 3, &pm8950_ult_nldo, "vdd_l3" }, { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8950_ult_nldo, "vdd_l3" },
{ "l4", QCOM_SMD_RPM_LDOA, 4, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" }, /* L4 seems not to exist. */
{ "l5", QCOM_SMD_RPM_LDOA, 5, &pm8950_pldo_lv, "vdd_l4_l5_l6_l7_l16" }, { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8950_pldo_lv, "vdd_l5_l6_l7_l16" },
{ "l6", QCOM_SMD_RPM_LDOA, 6, &pm8950_pldo_lv, "vdd_l4_l5_l6_l7_l16" }, { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8950_pldo_lv, "vdd_l5_l6_l7_l16" },
{ "l7", QCOM_SMD_RPM_LDOA, 7, &pm8950_pldo_lv, "vdd_l4_l5_l6_l7_l16" }, { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8950_pldo_lv, "vdd_l5_l6_l7_l16" },
{ "l8", QCOM_SMD_RPM_LDOA, 8, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" }, { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
{ "l9", QCOM_SMD_RPM_LDOA, 9, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" }, { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
{ "l10", QCOM_SMD_RPM_LDOA, 10, &pm8950_ult_nldo, "vdd_l9_l10_l13_l14_l15_l18"}, { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8950_ult_nldo, "vdd_l9_l10_l13_l14_l15_l18"},
{ "l11", QCOM_SMD_RPM_LDOA, 11, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22"}, { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
{ "l12", QCOM_SMD_RPM_LDOA, 12, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22"}, { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
{ "l13", QCOM_SMD_RPM_LDOA, 13, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"}, { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
{ "l14", QCOM_SMD_RPM_LDOA, 14, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"}, { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
{ "l15", QCOM_SMD_RPM_LDOA, 15, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"}, { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
{ "l16", QCOM_SMD_RPM_LDOA, 16, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16"}, { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8950_ult_pldo, "vdd_l5_l6_l7_l16" },
{ "l17", QCOM_SMD_RPM_LDOA, 17, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22"}, { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
{ "l18", QCOM_SMD_RPM_LDOA, 18, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"}, /* L18 seems not to exist. */
{ "l19", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l1_l19"}, { "l19", QCOM_SMD_RPM_LDOA, 19, &pm8950_pldo, "vdd_l1_l19" },
{ "l20", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l20"}, /* L20 & L21 seem not to exist. */
{ "l21", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l21"}, { "l22", QCOM_SMD_RPM_LDOA, 22, &pm8950_pldo, "vdd_l8_l11_l12_l17_l22" },
{ "l22", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l8_l11_l12_l17_l22"}, { "l23", QCOM_SMD_RPM_LDOA, 23, &pm8950_pldo, "vdd_l2_l23" },
{ "l23", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l2_l23"},
{} {}
}; };
......
...@@ -364,7 +364,6 @@ static int attiny_i2c_probe(struct i2c_client *i2c, ...@@ -364,7 +364,6 @@ static int attiny_i2c_probe(struct i2c_client *i2c,
state->gc.parent = &i2c->dev; state->gc.parent = &i2c->dev;
state->gc.label = i2c->name; state->gc.label = i2c->name;
state->gc.owner = THIS_MODULE; state->gc.owner = THIS_MODULE;
state->gc.of_node = i2c->dev.of_node;
state->gc.base = -1; state->gc.base = -1;
state->gc.ngpio = NUM_GPIO; state->gc.ngpio = NUM_GPIO;
......
...@@ -29,11 +29,33 @@ ...@@ -29,11 +29,33 @@
struct rt4801_priv { struct rt4801_priv {
struct device *dev; struct device *dev;
struct gpio_descs *enable_gpios; struct gpio_desc *enable_gpios[DSV_OUT_MAX];
unsigned int enable_flag; unsigned int enable_flag;
unsigned int volt_sel[DSV_OUT_MAX]; unsigned int volt_sel[DSV_OUT_MAX];
}; };
static int rt4801_of_parse_cb(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *config)
{
struct rt4801_priv *priv = config->driver_data;
int id = desc->id;
if (priv->enable_gpios[id]) {
dev_warn(priv->dev, "duplicated enable-gpios property\n");
return 0;
}
priv->enable_gpios[id] = devm_fwnode_gpiod_get_index(priv->dev,
of_fwnode_handle(np),
"enable", 0,
GPIOD_OUT_HIGH,
"rt4801");
if (IS_ERR(priv->enable_gpios[id]))
priv->enable_gpios[id] = NULL;
return 0;
}
static int rt4801_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) static int rt4801_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector)
{ {
struct rt4801_priv *priv = rdev_get_drvdata(rdev); struct rt4801_priv *priv = rdev_get_drvdata(rdev);
...@@ -63,15 +85,14 @@ static int rt4801_get_voltage_sel(struct regulator_dev *rdev) ...@@ -63,15 +85,14 @@ static int rt4801_get_voltage_sel(struct regulator_dev *rdev)
static int rt4801_enable(struct regulator_dev *rdev) static int rt4801_enable(struct regulator_dev *rdev)
{ {
struct rt4801_priv *priv = rdev_get_drvdata(rdev); struct rt4801_priv *priv = rdev_get_drvdata(rdev);
struct gpio_descs *gpios = priv->enable_gpios;
int id = rdev_get_id(rdev), ret; int id = rdev_get_id(rdev), ret;
if (!gpios || gpios->ndescs <= id) { if (!priv->enable_gpios[id]) {
dev_warn(&rdev->dev, "no dedicated gpio can control\n"); dev_warn(&rdev->dev, "no dedicated gpio can control\n");
goto bypass_gpio; goto bypass_gpio;
} }
gpiod_set_value(gpios->desc[id], 1); gpiod_set_value(priv->enable_gpios[id], 1);
bypass_gpio: bypass_gpio:
ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, priv->volt_sel[id]); ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, priv->volt_sel[id]);
...@@ -85,15 +106,14 @@ static int rt4801_enable(struct regulator_dev *rdev) ...@@ -85,15 +106,14 @@ static int rt4801_enable(struct regulator_dev *rdev)
static int rt4801_disable(struct regulator_dev *rdev) static int rt4801_disable(struct regulator_dev *rdev)
{ {
struct rt4801_priv *priv = rdev_get_drvdata(rdev); struct rt4801_priv *priv = rdev_get_drvdata(rdev);
struct gpio_descs *gpios = priv->enable_gpios;
int id = rdev_get_id(rdev); int id = rdev_get_id(rdev);
if (!gpios || gpios->ndescs <= id) { if (!priv->enable_gpios[id]) {
dev_warn(&rdev->dev, "no dedicated gpio can control\n"); dev_warn(&rdev->dev, "no dedicated gpio can control\n");
goto bypass_gpio; goto bypass_gpio;
} }
gpiod_set_value(gpios->desc[id], 0); gpiod_set_value(priv->enable_gpios[id], 0);
bypass_gpio: bypass_gpio:
priv->enable_flag &= ~BIT(id); priv->enable_flag &= ~BIT(id);
...@@ -122,6 +142,7 @@ static const struct regulator_desc rt4801_regulator_descs[] = { ...@@ -122,6 +142,7 @@ static const struct regulator_desc rt4801_regulator_descs[] = {
.name = "DSVP", .name = "DSVP",
.ops = &rt4801_regulator_ops, .ops = &rt4801_regulator_ops,
.of_match = of_match_ptr("DSVP"), .of_match = of_match_ptr("DSVP"),
.of_parse_cb = rt4801_of_parse_cb,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.id = DSV_OUT_POS, .id = DSV_OUT_POS,
.min_uV = MIN_UV, .min_uV = MIN_UV,
...@@ -135,6 +156,7 @@ static const struct regulator_desc rt4801_regulator_descs[] = { ...@@ -135,6 +156,7 @@ static const struct regulator_desc rt4801_regulator_descs[] = {
.name = "DSVN", .name = "DSVN",
.ops = &rt4801_regulator_ops, .ops = &rt4801_regulator_ops,
.of_match = of_match_ptr("DSVN"), .of_match = of_match_ptr("DSVN"),
.of_parse_cb = rt4801_of_parse_cb,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.id = DSV_OUT_NEG, .id = DSV_OUT_NEG,
.min_uV = MIN_UV, .min_uV = MIN_UV,
...@@ -172,10 +194,15 @@ static int rt4801_probe(struct i2c_client *i2c) ...@@ -172,10 +194,15 @@ static int rt4801_probe(struct i2c_client *i2c)
return PTR_ERR(regmap); return PTR_ERR(regmap);
} }
priv->enable_gpios = devm_gpiod_get_array_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH); for (i = 0; i < DSV_OUT_MAX; i++) {
if (IS_ERR(priv->enable_gpios)) { priv->enable_gpios[i] = devm_gpiod_get_index_optional(&i2c->dev,
dev_err(&i2c->dev, "Failed to get gpios\n"); "enable",
return PTR_ERR(priv->enable_gpios); i,
GPIOD_OUT_HIGH);
if (IS_ERR(priv->enable_gpios[i])) {
dev_err(&i2c->dev, "Failed to get gpios\n");
return PTR_ERR(priv->enable_gpios[i]);
}
} }
for (i = 0; i < DSV_OUT_MAX; i++) { for (i = 0; i < DSV_OUT_MAX; i++) {
......
// SPDX-License-Identifier: GPL-2.0+
#include <linux/bits.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#define RT5759_REG_VENDORINFO 0x00
#define RT5759_REG_FREQ 0x01
#define RT5759_REG_VSEL 0x02
#define RT5759_REG_DCDCCTRL 0x03
#define RT5759_REG_STATUS 0x04
#define RT5759_REG_DCDCSET 0x05
#define RT5759A_REG_WDTEN 0x42
#define RT5759_TSTEP_MASK GENMASK(3, 2)
#define RT5759_VSEL_MASK GENMASK(6, 0)
#define RT5759_DISCHARGE_MASK BIT(3)
#define RT5759_FPWM_MASK BIT(2)
#define RT5759_ENABLE_MASK BIT(1)
#define RT5759_OT_MASK BIT(1)
#define RT5759_UV_MASK BIT(0)
#define RT5957_OCLVL_MASK GENMASK(7, 6)
#define RT5759_OCLVL_SHIFT 6
#define RT5957_OTLVL_MASK GENMASK(5, 4)
#define RT5759_OTLVL_SHIFT 4
#define RT5759A_WDTEN_MASK BIT(1)
#define RT5759_MANUFACTURER_ID 0x82
/* vsel range 0x00 ~ 0x5A */
#define RT5759_NUM_VOLTS 91
#define RT5759_MIN_UV 600000
#define RT5759_STEP_UV 10000
#define RT5759A_STEP_UV 12500
#define RT5759_MINSS_TIMEUS 1500
#define RT5759_PSKIP_MODE 0
#define RT5759_FPWM_MODE 1
enum {
CHIP_TYPE_RT5759 = 0,
CHIP_TYPE_RT5759A,
CHIP_TYPE_MAX
};
struct rt5759_priv {
struct device *dev;
struct regmap *regmap;
struct regulator_desc desc;
unsigned long chip_type;
};
static int rt5759_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
struct regmap *regmap = rdev_get_regmap(rdev);
unsigned int mode_val;
switch (mode) {
case REGULATOR_MODE_NORMAL:
mode_val = 0;
break;
case REGULATOR_MODE_FAST:
mode_val = RT5759_FPWM_MASK;
break;
default:
return -EINVAL;
}
return regmap_update_bits(regmap, RT5759_REG_STATUS, RT5759_FPWM_MASK,
mode_val);
}
static unsigned int rt5759_get_mode(struct regulator_dev *rdev)
{
struct regmap *regmap = rdev_get_regmap(rdev);
unsigned int regval;
int ret;
ret = regmap_read(regmap, RT5759_REG_DCDCCTRL, &regval);
if (ret)
return REGULATOR_MODE_INVALID;
if (regval & RT5759_FPWM_MASK)
return REGULATOR_MODE_FAST;
return REGULATOR_MODE_NORMAL;
}
static int rt5759_get_error_flags(struct regulator_dev *rdev,
unsigned int *flags)
{
struct regmap *regmap = rdev_get_regmap(rdev);
unsigned int status, events = 0;
int ret;
ret = regmap_read(regmap, RT5759_REG_STATUS, &status);
if (ret)
return ret;
if (status & RT5759_OT_MASK)
events |= REGULATOR_ERROR_OVER_TEMP;
if (status & RT5759_UV_MASK)
events |= REGULATOR_ERROR_UNDER_VOLTAGE;
*flags = events;
return 0;
}
static int rt5759_set_ocp(struct regulator_dev *rdev, int lim_uA, int severity,
bool enable)
{
struct regmap *regmap = rdev_get_regmap(rdev);
int ocp_lvl[] = { 9800000, 10800000, 11800000 };
unsigned int ocp_regval;
int i;
/* Only support over current protection parameter */
if (severity != REGULATOR_SEVERITY_PROT)
return 0;
if (enable) {
/* Default ocp level is 10.8A */
if (lim_uA == 0)
lim_uA = 10800000;
for (i = 0; i < ARRAY_SIZE(ocp_lvl); i++) {
if (lim_uA <= ocp_lvl[i])
break;
}
if (i == ARRAY_SIZE(ocp_lvl))
i = ARRAY_SIZE(ocp_lvl) - 1;
ocp_regval = i + 1;
} else
ocp_regval = 0;
return regmap_update_bits(regmap, RT5759_REG_DCDCSET, RT5957_OCLVL_MASK,
ocp_regval << RT5759_OCLVL_SHIFT);
}
static int rt5759_set_otp(struct regulator_dev *rdev, int lim, int severity,
bool enable)
{
struct regmap *regmap = rdev_get_regmap(rdev);
int otp_lvl[] = { 140, 150, 170 };
unsigned int otp_regval;
int i;
/* Only support over temperature protection parameter */
if (severity != REGULATOR_SEVERITY_PROT)
return 0;
if (enable) {
/* Default otp level is 150'c */
if (lim == 0)
lim = 150;
for (i = 0; i < ARRAY_SIZE(otp_lvl); i++) {
if (lim <= otp_lvl[i])
break;
}
if (i == ARRAY_SIZE(otp_lvl))
i = ARRAY_SIZE(otp_lvl) - 1;
otp_regval = i + 1;
} else
otp_regval = 0;
return regmap_update_bits(regmap, RT5759_REG_DCDCSET, RT5957_OTLVL_MASK,
otp_regval << RT5759_OTLVL_SHIFT);
}
static const struct regulator_ops rt5759_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
.set_mode = rt5759_set_mode,
.get_mode = rt5759_get_mode,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.get_error_flags = rt5759_get_error_flags,
.set_over_current_protection = rt5759_set_ocp,
.set_thermal_protection = rt5759_set_otp,
};
static unsigned int rt5759_of_map_mode(unsigned int mode)
{
switch (mode) {
case RT5759_FPWM_MODE:
return REGULATOR_MODE_FAST;
case RT5759_PSKIP_MODE:
return REGULATOR_MODE_NORMAL;
default:
return REGULATOR_MODE_INVALID;
}
}
static const unsigned int rt5759_ramp_table[] = { 20000, 15000, 10000, 5000 };
static int rt5759_regulator_register(struct rt5759_priv *priv)
{
struct device_node *np = priv->dev->of_node;
struct regulator_desc *reg_desc = &priv->desc;
struct regulator_config reg_cfg;
struct regulator_dev *rdev;
int ret;
reg_desc->name = "rt5759-buck";
reg_desc->type = REGULATOR_VOLTAGE;
reg_desc->owner = THIS_MODULE;
reg_desc->ops = &rt5759_regulator_ops;
reg_desc->n_voltages = RT5759_NUM_VOLTS;
reg_desc->min_uV = RT5759_MIN_UV;
reg_desc->uV_step = RT5759_STEP_UV;
reg_desc->vsel_reg = RT5759_REG_VSEL;
reg_desc->vsel_mask = RT5759_VSEL_MASK;
reg_desc->enable_reg = RT5759_REG_DCDCCTRL;
reg_desc->enable_mask = RT5759_ENABLE_MASK;
reg_desc->active_discharge_reg = RT5759_REG_DCDCCTRL;
reg_desc->active_discharge_mask = RT5759_DISCHARGE_MASK;
reg_desc->active_discharge_on = RT5759_DISCHARGE_MASK;
reg_desc->ramp_reg = RT5759_REG_FREQ;
reg_desc->ramp_mask = RT5759_TSTEP_MASK;
reg_desc->ramp_delay_table = rt5759_ramp_table;
reg_desc->n_ramp_values = ARRAY_SIZE(rt5759_ramp_table);
reg_desc->enable_time = RT5759_MINSS_TIMEUS;
reg_desc->of_map_mode = rt5759_of_map_mode;
/*
* RT5759 step uV = 10000
* RT5759A step uV = 12500
*/
if (priv->chip_type == CHIP_TYPE_RT5759A)
reg_desc->uV_step = RT5759A_STEP_UV;
reg_cfg.dev = priv->dev;
reg_cfg.of_node = np;
reg_cfg.init_data = of_get_regulator_init_data(priv->dev, np, reg_desc);
reg_cfg.regmap = priv->regmap;
rdev = devm_regulator_register(priv->dev, reg_desc, &reg_cfg);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(priv->dev, "Failed to register regulator (%d)\n", ret);
return ret;
}
return 0;
}
static int rt5759_init_device_property(struct rt5759_priv *priv)
{
unsigned int val = 0;
/*
* Only RT5759A support external watchdog input
*/
if (priv->chip_type != CHIP_TYPE_RT5759A)
return 0;
if (device_property_read_bool(priv->dev, "richtek,watchdog-enable"))
val = RT5759A_WDTEN_MASK;
return regmap_update_bits(priv->regmap, RT5759A_REG_WDTEN,
RT5759A_WDTEN_MASK, val);
}
static int rt5759_manufacturer_check(struct rt5759_priv *priv)
{
unsigned int vendor;
int ret;
ret = regmap_read(priv->regmap, RT5759_REG_VENDORINFO, &vendor);
if (ret)
return ret;
if (vendor != RT5759_MANUFACTURER_ID) {
dev_err(priv->dev, "vendor info not correct (%d)\n", vendor);
return -EINVAL;
}
return 0;
}
static bool rt5759_is_accessible_reg(struct device *dev, unsigned int reg)
{
struct rt5759_priv *priv = dev_get_drvdata(dev);
if (reg <= RT5759_REG_DCDCSET)
return true;
if (priv->chip_type == CHIP_TYPE_RT5759A && reg == RT5759A_REG_WDTEN)
return true;
return false;
}
static const struct regmap_config rt5759_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = RT5759A_REG_WDTEN,
.readable_reg = rt5759_is_accessible_reg,
.writeable_reg = rt5759_is_accessible_reg,
};
static int rt5759_probe(struct i2c_client *i2c)
{
struct rt5759_priv *priv;
int ret;
priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->dev = &i2c->dev;
priv->chip_type = (unsigned long)of_device_get_match_data(&i2c->dev);
i2c_set_clientdata(i2c, priv);
priv->regmap = devm_regmap_init_i2c(i2c, &rt5759_regmap_config);
if (IS_ERR(priv->regmap)) {
ret = PTR_ERR(priv->regmap);
dev_err(&i2c->dev, "Failed to allocate regmap (%d)\n", ret);
return ret;
}
ret = rt5759_manufacturer_check(priv);
if (ret) {
dev_err(&i2c->dev, "Failed to check device (%d)\n", ret);
return ret;
}
ret = rt5759_init_device_property(priv);
if (ret) {
dev_err(&i2c->dev, "Failed to init device (%d)\n", ret);
return ret;
}
return rt5759_regulator_register(priv);
}
static const struct of_device_id __maybe_unused rt5759_device_table[] = {
{ .compatible = "richtek,rt5759", .data = (void *)CHIP_TYPE_RT5759 },
{ .compatible = "richtek,rt5759a", .data = (void *)CHIP_TYPE_RT5759A },
{}
};
MODULE_DEVICE_TABLE(of, rt5759_device_table);
static struct i2c_driver rt5759_driver = {
.driver = {
.name = "rt5759",
.of_match_table = of_match_ptr(rt5759_device_table),
},
.probe_new = rt5759_probe,
};
module_i2c_driver(rt5759_driver);
MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
MODULE_DESCRIPTION("Richtek RT5759 Regulator Driver");
MODULE_LICENSE("GPL v2");
...@@ -352,7 +352,7 @@ static int scmi_regulator_probe(struct scmi_device *sdev) ...@@ -352,7 +352,7 @@ static int scmi_regulator_probe(struct scmi_device *sdev)
return ret; return ret;
} }
} }
of_node_put(np);
/* /*
* Register a regulator for each valid regulator-DT-entry that we * Register a regulator for each valid regulator-DT-entry that we
* can successfully reach via SCMI and has a valid associated voltage * can successfully reach via SCMI and has a valid associated voltage
......
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/mfd/sm5703.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
enum sm5703_regulators {
SM5703_BUCK,
SM5703_LDO1,
SM5703_LDO2,
SM5703_LDO3,
SM5703_USBLDO1,
SM5703_USBLDO2,
SM5703_VBUS,
SM5703_MAX_REGULATORS,
};
static const int sm5703_ldo_voltagemap[] = {
1500000, 1800000, 2600000, 2800000, 3000000, 3300000,
};
static const int sm5703_buck_voltagemap[] = {
1000000, 1000000, 1000000, 1000000,
1000000, 1000000, 1000000, 1000000,
1000000, 1000000, 1000000, 1100000,
1200000, 1300000, 1400000, 1500000,
1600000, 1700000, 1800000, 1900000,
2000000, 2100000, 2200000, 2300000,
2400000, 2500000, 2600000, 2700000,
2800000, 2900000, 3000000, 3000000,
};
#define SM5703USBLDO(_name, _id) \
[SM5703_USBLDO ## _id] = { \
.name = _name, \
.of_match = _name, \
.regulators_node = "regulators", \
.type = REGULATOR_VOLTAGE, \
.id = SM5703_USBLDO ## _id, \
.ops = &sm5703_regulator_ops_fixed, \
.fixed_uV = SM5703_USBLDO_MICROVOLT, \
.enable_reg = SM5703_REG_USBLDO12, \
.enable_mask = SM5703_REG_EN_USBLDO ##_id, \
.owner = THIS_MODULE, \
}
#define SM5703VBUS(_name) \
[SM5703_VBUS] = { \
.name = _name, \
.of_match = _name, \
.regulators_node = "regulators", \
.type = REGULATOR_VOLTAGE, \
.id = SM5703_VBUS, \
.ops = &sm5703_regulator_ops_fixed, \
.fixed_uV = SM5703_VBUS_MICROVOLT, \
.enable_reg = SM5703_REG_CNTL, \
.enable_mask = SM5703_OPERATION_MODE_MASK, \
.enable_val = SM5703_OPERATION_MODE_USB_OTG_MODE, \
.disable_val = SM5703_OPERATION_MODE_CHARGING_ON, \
.owner = THIS_MODULE, \
}
#define SM5703BUCK(_name) \
[SM5703_BUCK] = { \
.name = _name, \
.of_match = _name, \
.regulators_node = "regulators", \
.type = REGULATOR_VOLTAGE, \
.id = SM5703_BUCK, \
.ops = &sm5703_regulator_ops, \
.n_voltages = ARRAY_SIZE(sm5703_buck_voltagemap), \
.volt_table = sm5703_buck_voltagemap, \
.vsel_reg = SM5703_REG_BUCK, \
.vsel_mask = SM5703_BUCK_VOLT_MASK, \
.enable_reg = SM5703_REG_BUCK, \
.enable_mask = SM5703_REG_EN_BUCK, \
.owner = THIS_MODULE, \
}
#define SM5703LDO(_name, _id) \
[SM5703_LDO ## _id] = { \
.name = _name, \
.of_match = _name, \
.regulators_node = "regulators", \
.type = REGULATOR_VOLTAGE, \
.id = SM5703_LDO ## _id, \
.ops = &sm5703_regulator_ops, \
.n_voltages = ARRAY_SIZE(sm5703_ldo_voltagemap), \
.volt_table = sm5703_ldo_voltagemap, \
.vsel_reg = SM5703_REG_LDO ##_id, \
.vsel_mask = SM5703_LDO_VOLT_MASK, \
.enable_reg = SM5703_REG_LDO ##_id, \
.enable_mask = SM5703_LDO_EN, \
.owner = THIS_MODULE, \
}
static const struct regulator_ops sm5703_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_table,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static const struct regulator_ops sm5703_regulator_ops_fixed = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_desc sm5703_regulators_desc[SM5703_MAX_REGULATORS] = {
SM5703BUCK("buck"),
SM5703LDO("ldo1", 1),
SM5703LDO("ldo2", 2),
SM5703LDO("ldo3", 3),
SM5703USBLDO("usbldo1", 1),
SM5703USBLDO("usbldo2", 2),
SM5703VBUS("vbus"),
};
static int sm5703_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct regulator_config config = { NULL, };
struct regulator_dev *rdev;
struct sm5703_dev *sm5703 = dev_get_drvdata(pdev->dev.parent);
int i;
config.dev = dev->parent;
config.regmap = sm5703->regmap;
for (i = 0; i < SM5703_MAX_REGULATORS; i++) {
rdev = devm_regulator_register(dev,
&sm5703_regulators_desc[i],
&config);
if (IS_ERR(rdev))
return dev_err_probe(dev, PTR_ERR(rdev),
"Failed to register a regulator\n");
}
return 0;
}
static const struct platform_device_id sm5703_regulator_id[] = {
{ "sm5703-regulator", 0 },
{}
};
MODULE_DEVICE_TABLE(platform, sm5703_regulator_id);
static struct platform_driver sm5703_regulator_driver = {
.driver = {
.name = "sm5703-regulator",
},
.probe = sm5703_regulator_probe,
.id_table = sm5703_regulator_id,
};
module_platform_driver(sm5703_regulator_driver);
MODULE_DESCRIPTION("Silicon Mitus SM5703 LDO/Buck/USB regulator driver");
MODULE_AUTHOR("Markuss Broks <markuss.broks@gmail.com>");
MODULE_LICENSE("GPL");
...@@ -44,11 +44,9 @@ static int stm32_vrefbuf_enable(struct regulator_dev *rdev) ...@@ -44,11 +44,9 @@ static int stm32_vrefbuf_enable(struct regulator_dev *rdev)
u32 val; u32 val;
int ret; int ret;
ret = pm_runtime_get_sync(priv->dev); ret = pm_runtime_resume_and_get(priv->dev);
if (ret < 0) { if (ret < 0)
pm_runtime_put_noidle(priv->dev);
return ret; return ret;
}
val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
val = (val & ~STM32_HIZ) | STM32_ENVR; val = (val & ~STM32_HIZ) | STM32_ENVR;
...@@ -81,11 +79,9 @@ static int stm32_vrefbuf_disable(struct regulator_dev *rdev) ...@@ -81,11 +79,9 @@ static int stm32_vrefbuf_disable(struct regulator_dev *rdev)
u32 val; u32 val;
int ret; int ret;
ret = pm_runtime_get_sync(priv->dev); ret = pm_runtime_resume_and_get(priv->dev);
if (ret < 0) { if (ret < 0)
pm_runtime_put_noidle(priv->dev);
return ret; return ret;
}
val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
val &= ~STM32_ENVR; val &= ~STM32_ENVR;
...@@ -102,11 +98,9 @@ static int stm32_vrefbuf_is_enabled(struct regulator_dev *rdev) ...@@ -102,11 +98,9 @@ static int stm32_vrefbuf_is_enabled(struct regulator_dev *rdev)
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev); struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
int ret; int ret;
ret = pm_runtime_get_sync(priv->dev); ret = pm_runtime_resume_and_get(priv->dev);
if (ret < 0) { if (ret < 0)
pm_runtime_put_noidle(priv->dev);
return ret; return ret;
}
ret = readl_relaxed(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR; ret = readl_relaxed(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR;
...@@ -123,11 +117,9 @@ static int stm32_vrefbuf_set_voltage_sel(struct regulator_dev *rdev, ...@@ -123,11 +117,9 @@ static int stm32_vrefbuf_set_voltage_sel(struct regulator_dev *rdev,
u32 val; u32 val;
int ret; int ret;
ret = pm_runtime_get_sync(priv->dev); ret = pm_runtime_resume_and_get(priv->dev);
if (ret < 0) { if (ret < 0)
pm_runtime_put_noidle(priv->dev);
return ret; return ret;
}
val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
val = (val & ~STM32_VRS) | FIELD_PREP(STM32_VRS, sel); val = (val & ~STM32_VRS) | FIELD_PREP(STM32_VRS, sel);
...@@ -145,11 +137,9 @@ static int stm32_vrefbuf_get_voltage_sel(struct regulator_dev *rdev) ...@@ -145,11 +137,9 @@ static int stm32_vrefbuf_get_voltage_sel(struct regulator_dev *rdev)
u32 val; u32 val;
int ret; int ret;
ret = pm_runtime_get_sync(priv->dev); ret = pm_runtime_resume_and_get(priv->dev);
if (ret < 0) { if (ret < 0)
pm_runtime_put_noidle(priv->dev);
return ret; return ret;
}
val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
ret = FIELD_GET(STM32_VRS, val); ret = FIELD_GET(STM32_VRS, val);
......
...@@ -48,9 +48,54 @@ enum { ...@@ -48,9 +48,54 @@ enum {
MT6358_ID_VLDO28, MT6358_ID_VLDO28,
MT6358_ID_VAUD28, MT6358_ID_VAUD28,
MT6358_ID_VSIM2, MT6358_ID_VSIM2,
MT6358_ID_VCORE_SSHUB,
MT6358_ID_VSRAM_OTHERS_SSHUB,
MT6358_ID_RG_MAX, MT6358_ID_RG_MAX,
}; };
enum {
MT6366_ID_VDRAM1 = 0,
MT6366_ID_VCORE,
MT6366_ID_VPA,
MT6366_ID_VPROC11,
MT6366_ID_VPROC12,
MT6366_ID_VGPU,
MT6366_ID_VS2,
MT6366_ID_VMODEM,
MT6366_ID_VS1,
MT6366_ID_VDRAM2,
MT6366_ID_VSIM1,
MT6366_ID_VIBR,
MT6366_ID_VRF12,
MT6366_ID_VIO18,
MT6366_ID_VUSB,
MT6366_ID_VCN18,
MT6366_ID_VFE28,
MT6366_ID_VSRAM_PROC11,
MT6366_ID_VCN28,
MT6366_ID_VSRAM_OTHERS,
MT6366_ID_VSRAM_GPU,
MT6366_ID_VXO22,
MT6366_ID_VEFUSE,
MT6366_ID_VAUX18,
MT6366_ID_VMCH,
MT6366_ID_VBIF28,
MT6366_ID_VSRAM_PROC12,
MT6366_ID_VEMC,
MT6366_ID_VIO28,
MT6366_ID_VA12,
MT6366_ID_VRF18,
MT6366_ID_VCN33_BT,
MT6366_ID_VCN33_WIFI,
MT6366_ID_VMC,
MT6366_ID_VAUD28,
MT6366_ID_VSIM2,
MT6366_ID_VCORE_SSHUB,
MT6366_ID_VSRAM_OTHERS_SSHUB,
MT6366_ID_RG_MAX,
};
#define MT6358_MAX_REGULATOR MT6358_ID_RG_MAX #define MT6358_MAX_REGULATOR MT6358_ID_RG_MAX
#define MT6366_MAX_REGULATOR MT6366_ID_RG_MAX
#endif /* __LINUX_REGULATOR_MT6358_H */ #endif /* __LINUX_REGULATOR_MT6358_H */
...@@ -226,4 +226,11 @@ enum { ...@@ -226,4 +226,11 @@ enum {
#define WDOG_B_CFG_COLD_LDO12 0x80 #define WDOG_B_CFG_COLD_LDO12 0x80
#define WDOG_B_CFG_COLD 0xC0 #define WDOG_B_CFG_COLD 0xC0
/* PCA9450_REG_CONFIG2 bits */
#define I2C_LT_MASK 0x03
#define I2C_LT_FORCE_DISABLE 0x00
#define I2C_LT_ON_STANDBY_RUN 0x01
#define I2C_LT_ON_RUN 0x02
#define I2C_LT_FORCE_ENABLE 0x03
#endif /* __LINUX_REG_PCA9450_H__ */ #endif /* __LINUX_REG_PCA9450_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment