regulator: Updates for v7.3

This is a relatively quiet release for the regulator API, we've had no
 major core work and not really that much driver work either.  There's a
 bunch of activity, including several new devices, but nothing hugely
 remarkable here.
 
  - Reworking of the mode handling in the max14577 driver to fix issues
    with collisions with enables.
  - Support for onsemi FAN53555BUC23X, Qualcomm IPQ9650, PM4125 VBUS and
    PM8150B and Unisoc SC2730.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmqDPDUACgkQJNaLcl1U
 h9CvoAf/Y8owPCZFX9vMl/HUGvw+Bvj/fNXDUAar0rLjseD5hq6LUQi8l7YZJy+3
 Voun5Ehakiti6VfJvA08+guG1orI/BqeT6W/lx6h1DXzvifoU8N3itKsyMk1lvug
 JtYi16gwbMa3RSdWI0W3ftAMIq6GeTNyLnPfqSM8XWJ2McZVABpg3ndOegaU922y
 aSBODYyI7weoWD+p+JI5P9O/vncGoO9tDRdwHBeZXi1HuR7HcOe9aGDSeQn/1dvC
 /dLDRNKpSPV/jscvxAa3MyCIAbubQipRcfEIGZTYXDabr8NE2odgKwWaZRkVyts2
 +mfkEBqz1z5Tsx+AfplwxnXk+3i3vw==
 =0fgh
 -----END PGP SIGNATURE-----

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

Pull regulator updates from Mark Brown:
 "This is a relatively quiet release for the regulator API, we've had no
  major core work and not really that much driver work either. There's a
  bunch of activity, including several new devices, but nothing hugely
  remarkable here.

   - Reworking of the mode handling in the max14577 driver to fix issues
     with collisions with enables

   - Support for onsemi FAN53555BUC23X, Qualcomm IPQ9650, PM4125 VBUS
     and PM8150B and Unisoc SC2730"

* tag 'regulator-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (36 commits)
  regulator: fan53555: Add support for FAN53555BUC23X type
  regulator: qcom-rpmh: Fix coding style issues
  regulator: qcom-rpmh: readback voltage/bypass/mode set during bootup
  regulator: qcom-rpmh: Fix PMIC5 BOB bypass mode handling
  soc: qcom: rpmh: Add support to read back resource settings
  regulator: dt-bindings: ti,pbias-omap: Convert to DT schema
  regulator: ab8500: Remove stale expand_register kernel-doc entry
  regulator: dt-bindings: Correct white-space style
  regulator: pfuze100: add set_suspend_disable for LDO ops
  regulator: core: use system_freezable_wq for init complete work
  regulator: rt6245: Restore state on enable failure
  regulator: tps65185: handle gpiod_get_value_cansleep() error returns
  regulator: fan53555: Add support for mode operations on Silergy devices
  regulator: dt-bindings: Add fan53555 allowed modes
  regulator: wm831x-isink: remove conditional return with no effect
  regulator: dt-bindings: Convert ltc3589.txt to yaml format
  regulator: dt-bindings: tps51632: Convert to DT schema
  regulator: mcp16502: Convert to dev_err_probe() in mcp16502_probe()
  regulator: adp5055: Fix error code in adp5055_of_parse_cb()
  regulator: qcom_usb_vbus: add support for qcom,pm4125-vbus-reg
  ...
This commit is contained in:
Linus Torvalds 2026-08-19 09:36:58 -07:00
commit b3438e5ca7
92 changed files with 1621 additions and 463 deletions

View File

@ -48,6 +48,12 @@ properties:
VSEL0 register. When this pin is HIGH, VOUT is set by the VSEL1 register.
maxItems: 1
regulator-initial-mode:
enum:
[ 1, 2 ]
description:
Defined in include/dt-bindings/regulator/fcs,fan53555-regulator.h
required:
- compatible
- reg
@ -56,6 +62,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/regulator/fcs,fan53555-regulator.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
@ -68,6 +75,7 @@ examples:
regulator-max-microvolt = <1800000>;
vin-supply = <&parent_reg>;
fcs,suspend-voltage-selector = <1>;
regulator-initial-mode = <FAN53555_REGULATOR_MODE_FORCE_PWM>;
};
};
...

View File

@ -0,0 +1,149 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/lltc,ltc3589.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Linear Technology LTC3589 PMIC
maintainers:
- Frank Li <Frank.li@kernel.org>
description:
Linear Technology LTC3589, LTC3589-1 and LTC3589-2 are PMICs
containing three buck regulators, one boost regulator and four
LDO regulators.
properties:
compatible:
enum:
- lltc,ltc3589
- lltc,ltc3589-1
- lltc,ltc3589-2
reg:
maxItems: 1
interrupts:
maxItems: 1
regulators:
type: object
additionalProperties: false
patternProperties:
"^(sw1|sw2|sw3|bb-out|ldo1|ldo2)$":
type: object
unevaluatedProperties: false
$ref: regulator.yaml#
properties:
lltc,fb-voltage-divider:
description:
Feedback voltage divider resistor values (R1, R2) in ohms.
Regulators sw1, sw2, sw3, and ldo2 can regulate the feedback
reference from 0.3625 V to 0.75 V in 12.5 mV steps. The output
voltage thus ranges between 0.3625 * (1 + R1/R2) V and
0.75 * (1 + R1/R2) V. Regulators bb-out and ldo1 have a fixed
0.8 V reference and thus output 0.8 * (1 + R1/R2) V. The ldo3
regulator is fixed to 1.8 V on LTC3589 and to 2.8 V on
LTC3589-1,2. The ldo4 regulator can output between 1.8 V and
3.3 V on LTC3589 and between 1.2 V and 3.2 V on LTC3589-1,2 in
four steps. The ldo1 standby regulator can not be disabled and
thus should have the regulator-always-on property set.
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
- description: R1 in ohms
- description: R2 in ohms.
required:
- lltc,fb-voltage-divider
"^(ldo3|ldo4)$":
type: object
unevaluatedProperties: false
$ref: regulator.yaml#
required:
- compatible
- reg
- regulators
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@34 {
compatible = "lltc,ltc3589-1";
reg = <0x34>;
regulators {
sw1 {
regulator-min-microvolt = <591930>;
regulator-max-microvolt = <1224671>;
lltc,fb-voltage-divider = <100000 158000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
sw2 {
regulator-min-microvolt = <704123>;
regulator-max-microvolt = <1456803>;
lltc,fb-voltage-divider = <180000 191000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
sw3 {
regulator-min-microvolt = <1341250>;
regulator-max-microvolt = <2775000>;
lltc,fb-voltage-divider = <270000 100000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
bb-out {
regulator-min-microvolt = <3387341>;
regulator-max-microvolt = <3387341>;
lltc,fb-voltage-divider = <511000 158000>;
regulator-boot-on;
regulator-always-on;
};
ldo1 {
regulator-min-microvolt = <1306329>;
regulator-max-microvolt = <1306329>;
lltc,fb-voltage-divider = <100000 158000>;
regulator-boot-on;
regulator-always-on;
};
ldo2 {
regulator-min-microvolt = <704123>;
regulator-max-microvolt = <1456806>;
lltc,fb-voltage-divider = <180000 191000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
ldo3 {
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-boot-on;
};
ldo4 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3200000>;
};
};
};
};

View File

@ -1,99 +0,0 @@
Linear Technology LTC3589, LTC3589-1, and LTC3589-2 8-output regulators
Required properties:
- compatible: "lltc,ltc3589", "lltc,ltc3589-1" or "lltc,ltc3589-2"
- reg: I2C slave address
Required child node:
- regulators: Contains eight regulator child nodes sw1, sw2, sw3, bb-out,
ldo1, ldo2, ldo3, and ldo4, specifying the initialization data as
documented in Documentation/devicetree/bindings/regulator/regulator.txt.
Each regulator is defined using the standard binding for regulators. The
nodes for sw1, sw2, sw3, bb-out, ldo1, and ldo2 additionally need to specify
the resistor values of their external feedback voltage dividers:
Required properties (not on ldo3, ldo4):
- lltc,fb-voltage-divider: An array of two integers containing the resistor
values R1 and R2 of the feedback voltage divider in ohms.
Regulators sw1, sw2, sw3, and ldo2 can regulate the feedback reference from
0.3625 V to 0.75 V in 12.5 mV steps. The output voltage thus ranges between
0.3625 * (1 + R1/R2) V and 0.75 * (1 + R1/R2) V. Regulators bb-out and ldo1
have a fixed 0.8 V reference and thus output 0.8 * (1 + R1/R2) V. The ldo3
regulator is fixed to 1.8 V on LTC3589 and to 2.8 V on LTC3589-1,2. The ldo4
regulator can output between 1.8 V and 3.3 V on LTC3589 and between 1.2 V
and 3.2 V on LTC3589-1,2 in four steps. The ldo1 standby regulator can not
be disabled and thus should have the regulator-always-on property set.
Example:
ltc3589: pmic@34 {
compatible = "lltc,ltc3589-1";
reg = <0x34>;
regulators {
sw1_reg: sw1 {
regulator-min-microvolt = <591930>;
regulator-max-microvolt = <1224671>;
lltc,fb-voltage-divider = <100000 158000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
sw2_reg: sw2 {
regulator-min-microvolt = <704123>;
regulator-max-microvolt = <1456803>;
lltc,fb-voltage-divider = <180000 191000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
sw3_reg: sw3 {
regulator-min-microvolt = <1341250>;
regulator-max-microvolt = <2775000>;
lltc,fb-voltage-divider = <270000 100000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
bb_out_reg: bb-out {
regulator-min-microvolt = <3387341>;
regulator-max-microvolt = <3387341>;
lltc,fb-voltage-divider = <511000 158000>;
regulator-boot-on;
regulator-always-on;
};
ldo1_reg: ldo1 {
regulator-min-microvolt = <1306329>;
regulator-max-microvolt = <1306329>;
lltc,fb-voltage-divider = <100000 158000>;
regulator-boot-on;
regulator-always-on;
};
ldo2_reg: ldo2 {
regulator-min-microvolt = <704123>;
regulator-max-microvolt = <1456806>;
lltc,fb-voltage-divider = <180000 191000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
ldo3_reg: ldo3 {
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-boot-on;
};
ldo4_reg: ldo4 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3200000>;
};
};
};

View File

@ -134,42 +134,42 @@ examples:
regulator-always-on;
regulator-boot-on;
regulator-max-microvolt = <1800000>;
regulator-min-microvolt = <400000>;
regulator-min-microvolt = <400000>;
};
reg_buck2: buck2 {
regulator-always-on;
regulator-boot-on;
regulator-max-microvolt = <1800000>;
regulator-min-microvolt = <400000>;
regulator-min-microvolt = <400000>;
};
reg_buck3: buck3 {
regulator-always-on;
regulator-boot-on;
regulator-max-microvolt = <1800000>;
regulator-min-microvolt = <400000>;
regulator-min-microvolt = <400000>;
};
reg_buck4: buck4 {
regulator-always-on;
regulator-boot-on;
regulator-max-microvolt = <1800000>;
regulator-min-microvolt = <400000>;
regulator-min-microvolt = <400000>;
};
reg_buck5: buck5 {
regulator-always-on;
regulator-boot-on;
regulator-max-microvolt = <1800000>;
regulator-min-microvolt = <400000>;
regulator-min-microvolt = <400000>;
};
reg_buck6: buck6 {
regulator-always-on;
regulator-boot-on;
regulator-max-microvolt = <1800000>;
regulator-min-microvolt = <400000>;
regulator-min-microvolt = <400000>;
};
reg_buck7: buck7 {

View File

@ -1,32 +0,0 @@
PBIAS internal regulator for SD card dual voltage i/o pads on OMAP SoCs.
Required properties:
- compatible:
- should be "ti,pbias-dra7" for DRA7
- should be "ti,pbias-omap2" for OMAP2
- should be "ti,pbias-omap3" for OMAP3
- should be "ti,pbias-omap4" for OMAP4
- should be "ti,pbias-omap5" for OMAP5
- "ti,pbias-omap" is deprecated
- reg: pbias register offset from syscon base and size of pbias register.
- syscon : phandle of the system control module
- regulator-name : should be
pbias_mmc_omap2430 for OMAP2430, OMAP3 SoCs
pbias_sim_omap3 for OMAP3 SoCs
pbias_mmc_omap4 for OMAP4 SoCs
pbias_mmc_omap5 for OMAP5 and DRA7 SoC
Optional properties:
- Any optional property defined in bindings/regulator/regulator.txt
Example:
pbias_regulator: pbias_regulator {
compatible = "ti,pbias-omap";
reg = <0 0x4>;
syscon = <&omap5_padconf_global>;
pbias_mmc_reg: pbias_mmc_omap5 {
regulator-name = "pbias_mmc_omap5";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
};

View File

@ -13,9 +13,6 @@ description:
The REFGEN (reference voltage generator) regulator provides reference
voltage for on-chip IPs (like PHYs) on some Qualcomm SoCs.
allOf:
- $ref: regulator.yaml#
properties:
compatible:
oneOf:
@ -39,16 +36,44 @@ properties:
- const: qcom,sm8250-refgen-regulator
- enum:
- qcom,ipq9650-refgen-regulator
- qcom,sdm845-refgen-regulator
- qcom,sm8250-refgen-regulator
reg:
maxItems: 1
clocks:
items:
- description: Core reference clock
- description: AHB interface clock
clock-names:
items:
- const: core
- const: hclk
required:
- compatible
- reg
allOf:
- $ref: regulator.yaml#
- if:
properties:
compatible:
contains:
const: qcom,ipq9650-refgen-regulator
then:
required:
- clocks
- clock-names
else:
properties:
clocks: false
clock-names: false
unevaluatedProperties: false
examples:

View File

@ -14,17 +14,21 @@ description: |
regulator will be enabled in situations where the device is required to
provide power to the connected peripheral.
allOf:
- $ref: regulator.yaml#
The pm8150b variant uses an OTG current-limit selector, supporting limits
of 500 mA, 1000 mA, 1500 mA, 2000 mA, 2500 mA and 3000 mA.
The pm4125 variant uses a different register layout with a 2-bit VBOOST
voltage selector supporting output voltages of 4.25 V, 4.5 V, 4.75 V
and 5.0 V.
properties:
compatible:
oneOf:
- enum:
- qcom,pm8150b-vbus-reg
- qcom,pm4125-vbus-reg
- items:
- enum:
- qcom,pm4125-vbus-reg
- qcom,pm6150-vbus-reg
- qcom,pm7250b-vbus-reg
- qcom,pmi632-vbus-reg
@ -34,11 +38,35 @@ properties:
maxItems: 1
description: VBUS output base address
allOf:
- $ref: regulator.yaml#
- if:
properties:
compatible:
contains:
enum:
- qcom,pm8150b-vbus-reg
- qcom,pm6150-vbus-reg
- qcom,pm7250b-vbus-reg
- qcom,pmi632-vbus-reg
then:
required:
- regulator-min-microamp
- regulator-max-microamp
- if:
properties:
compatible:
contains:
const: qcom,pm4125-vbus-reg
then:
required:
- regulator-min-microvolt
- regulator-max-microvolt
required:
- compatible
- reg
- regulator-min-microamp
- regulator-max-microamp
unevaluatedProperties: false
@ -55,4 +83,16 @@ examples:
regulator-max-microamp = <3000000>;
};
};
- |
pmic {
#address-cells = <1>;
#size-cells = <0>;
usb-vbus-regulator@1100 {
compatible = "qcom,pm4125-vbus-reg";
reg = <0x1100>;
regulator-min-microvolt = <4250000>;
regulator-max-microvolt = <5000000>;
};
};
...

View File

@ -42,11 +42,14 @@ properties:
richtek,mtp-sel-high:
type: boolean
deprecated: true
description:
vout register selection based on this boolean value.
false - Using DVS0 register setting to adjust vout
true - Using DVS1 register setting to adjust vout
The property is now deprecated. Will be identified by RG HW register.
regulators:
type: object
additionalProperties: false
@ -100,7 +103,6 @@ examples:
compatible = "richtek,rtq2208";
reg = <0x10>;
interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;
richtek,mtp-sel-high;
regulators {
buck-a {

View File

@ -38,7 +38,9 @@ patternProperties:
type: object
description:
Properties for single LDO/BUCK regulator.
$ref: regulator.yaml#
allOf:
- $ref: regulator.yaml#
- $ref: rohm,pmic-states.yaml#
properties:
regulator-name:
@ -51,15 +53,6 @@ patternProperties:
description:
GPIO used to control ldo4 state (when ldo4 is controlled by GPIO).
rohm,dvs-run-voltage:
description:
PMIC "RUN" state voltage in uV when PMIC HW states are used. See
comments below for bucks/LDOs which support this. 0 means
regulator should be disabled at RUN state.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-snvs-voltage:
description:
Whether to keep regulator enabled at "SNVS" state or not.
@ -71,21 +64,15 @@ patternProperties:
minimum: 0
maximum: 3300000
rohm,dvs-run-voltage:
minimum: 0
maximum: 3300000
rohm,dvs-suspend-voltage:
description:
PMIC "SUSPEND" state voltage in uV when PMIC HW states are used. See
comments below for bucks/LDOs which support this. 0 means
regulator should be disabled at SUSPEND state.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-lpsr-voltage:
description:
PMIC "LPSR" state voltage in uV when PMIC HW states are used. See
comments below for bucks/LDOs which support this. 0 means
regulator should be disabled at LPSR state.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000

View File

@ -40,7 +40,9 @@ patternProperties:
type: object
description:
Properties for single BUCK regulator.
$ref: regulator.yaml#
allOf:
- $ref: regulator.yaml#
- $ref: rohm,pmic-states.yaml#
properties:
regulator-name:
@ -49,34 +51,18 @@ patternProperties:
should be "buck1", ..., "buck7"
rohm,dvs-run-voltage:
description:
PMIC default "RUN" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-idle-voltage:
description:
PMIC default "IDLE" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-suspend-voltage:
description:
PMIC default "SUSPEND" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-lpsr-voltage:
description:
PMIC default "LPSR" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000

View File

@ -44,7 +44,9 @@ patternProperties:
"^BUCK[1-8]$":
type: object
$ref: regulator.yaml#
allOf:
- $ref: regulator.yaml#
- $ref: rohm,pmic-states.yaml#
description:
Properties for single BUCK regulator.
@ -55,28 +57,16 @@ patternProperties:
should be "buck1", ..., "buck8"
rohm,dvs-run-voltage:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 1300000
description:
PMIC default "RUN" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-idle-voltage:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 1300000
description:
PMIC default "IDLE" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-suspend-voltage:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 1300000
description:
PMIC default "SUSPEND" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
# Supported default DVS states:
#

View File

@ -43,7 +43,9 @@ patternProperties:
"^BUCK[1-6]$":
type: object
$ref: regulator.yaml#
allOf:
- $ref: regulator.yaml#
- $ref: rohm,pmic-states.yaml#
description:
Properties for single BUCK regulator.
@ -54,28 +56,16 @@ patternProperties:
should be "buck1", ..., "buck6"
rohm,dvs-run-voltage:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 1300000
description:
PMIC default "RUN" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-idle-voltage:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 1300000
description:
PMIC default "IDLE" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-suspend-voltage:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 1300000
description:
PMIC default "SUSPEND" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
# Supported default DVS states:
#

View File

@ -26,41 +26,27 @@ patternProperties:
type: object
description:
Properties for single LDO regulator.
$ref: regulator.yaml#
allOf:
- $ref: regulator.yaml#
- $ref: rohm,pmic-states.yaml#
properties:
regulator-name:
pattern: "^ldo([1-9]|1[0-1])$"
rohm,dvs-run-voltage:
description:
PMIC default "RUN" state voltage in uV. See below table for
LDOs which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-idle-voltage:
description:
PMIC default "IDLE" state voltage in uV. See below table for
LDOs which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-suspend-voltage:
description:
PMIC default "SUSPEND" state voltage in uV. See below table for
LDOs which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-lpsr-voltage:
description:
PMIC default "deep-idle" state voltage in uV. See below table for
LDOs which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
@ -82,7 +68,9 @@ patternProperties:
type: object
description:
Properties for single BUCK regulator.
$ref: regulator.yaml#
allOf:
- $ref: regulator.yaml#
- $ref: rohm,pmic-states.yaml#
properties:
regulator-name:
@ -97,34 +85,18 @@ patternProperties:
maximum: 300000
rohm,dvs-run-voltage:
description:
PMIC default "RUN" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-idle-voltage:
description:
PMIC default "IDLE" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-suspend-voltage:
description:
PMIC default "SUSPEND" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000
rohm,dvs-lpsr-voltage:
description:
PMIC default "deep-idle" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3300000

View File

@ -0,0 +1,57 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/rohm,pmic-states.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ROHM PMICs' hardware state machine descriptions
maintainers:
- Matti Vaittinen <mazziesaccount@gmail.com>
description:
Many of the ROHM PMICs have internal state-machine designed to provide
correct voltages for different SOC states. In many cases the states and
transitions are SOC specific, but ones described here can be found from a
few of the different ROHM PMICs.
properties:
rohm,dvs-run-voltage:
description:
PMIC "RUN" state voltage in uV when PMIC HW states are used. 0 means the
regulator should be disabled at RUN state. Some regulators do not support
setting HW state specific voltage but do support enable/disable control.
For them any positive value means the regulator should be enabled without
touching the voltage.
$ref: /schemas/types.yaml#/definitions/uint32
rohm,dvs-suspend-voltage:
description:
PMIC "SUSPEND" state voltage in uV when PMIC HW states are used. 0 means
the regulator should be disabled at SUSPEND state. Some regulators do not
support setting HW state specific voltage but do support enable/disable
control. For them any positive value means the regulator should be
enabled without touching the voltage.
$ref: /schemas/types.yaml#/definitions/uint32
rohm,dvs-idle-voltage:
description:
PMIC "IDLE" state voltage in uV. 0 means the regulator should be disabled
at IDLE state. Some regulators do not support setting HW state specific
voltage but do support enable/disable control. For them any positive
value means the regulator should be enabled without touching the voltage.
$ref: /schemas/types.yaml#/definitions/uint32
rohm,dvs-lpsr-voltage:
description:
PMIC "LPSR" state voltage in uV when PMIC HW states are used. 0 means the
regulator should be disabled at LPSR state. Some regulators do not
support setting HW state specific voltage but do support enable/disable
control. For them any positive value means the regulator should be
enabled without touching the voltage. Some PMICs' documentation may refer
to this state as a "deep-idle state".
$ref: /schemas/types.yaml#/definitions/uint32
# The schema is expected to be reference by PMIC schemas, which may introduce
# other properties that must be allowed.
additionalProperties: true

View File

@ -0,0 +1,137 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/ti,pbias-omap.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments PBIAS internal regulator
maintainers:
- Tony Lindgren <tony@atomide.com>
properties:
compatible:
items:
- enum:
- ti,pbias-dra7
- ti,pbias-omap2
- ti,pbias-omap3
- ti,pbias-omap4
- ti,pbias-omap5
- const: ti,pbias-omap
reg:
maxItems: 1
syscon:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle of the system control module
pbias_mmc_omap2430:
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
required:
- regulator-name
pbias_sim_omap3:
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
required:
- regulator-name
pbias_mmc_omap4:
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
required:
- regulator-name
pbias_mmc_omap5:
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
required:
- regulator-name
required:
- compatible
- reg
- syscon
allOf:
- if:
properties:
compatible:
contains:
const: ti,pbias-omap2
then:
required:
- pbias_mmc_omap2430
properties:
pbias_sim_omap3: false
pbias_mmc_omap4: false
pbias_mmc_omap5: false
- if:
properties:
compatible:
contains:
const: ti,pbias-omap3
then:
anyOf:
- required:
- pbias_mmc_omap2430
- required:
- pbias_sim_omap3
properties:
pbias_mmc_omap4: false
pbias_mmc_omap5: false
- if:
properties:
compatible:
contains:
const: ti,pbias-omap4
then:
required:
- pbias_mmc_omap4
properties:
pbias_mmc_omap2430: false
pbias_sim_omap3: false
pbias_mmc_omap5: false
- if:
properties:
compatible:
contains:
enum:
- ti,pbias-omap5
- ti,pbias-dra7
then:
required:
- pbias_mmc_omap5
properties:
pbias_mmc_omap2430: false
pbias_sim_omap3: false
pbias_mmc_omap4: false
additionalProperties: false
examples:
- |
pbias_regulator@0 {
compatible = "ti,pbias-omap5", "ti,pbias-omap";
reg = <0 0x4>;
syscon = <&omap5_padconf_global>;
pbias_mmc_omap5 {
regulator-name = "pbias_mmc_omap5";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
};
};

View File

@ -0,0 +1,55 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/ti,tps51632.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments TPS51632 Voltage regulators
maintainers:
- Laxman Dewangan <ldewangan@nvidia.com>
allOf:
- $ref: regulator.yaml#
properties:
compatible:
const: ti,tps51632
reg:
maxItems: 1
ti,enable-pwm-dvfs:
description: Enable the DVFS voltage control through the PWM interface.
type: boolean
ti,dvfs-step-20mV:
description:
The 20mV step voltage when PWM DVFS enabled. Missing this will set 10mV
step voltage in PWM DVFS mode. In normal mode, the voltage step is 10mV
as per datasheet.
type: boolean
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
tps51632@43 {
compatible = "ti,tps51632";
reg = <0x43>;
regulator-name = "tps51632-vout";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1500000>;
regulator-boot-on;
ti,enable-pwm-dvfs;
ti,dvfs-step-20mV;
};
};

View File

@ -1,27 +0,0 @@
TPS51632 Voltage regulators
Required properties:
- compatible: Must be "ti,tps51632"
- reg: I2C slave address
Optional properties:
- ti,enable-pwm-dvfs: Enable the DVFS voltage control through the PWM interface.
- ti,dvfs-step-20mV: The 20mV step voltage when PWM DVFS enabled. Missing this
will set 10mV step voltage in PWM DVFS mode. In normal mode, the voltage
step is 10mV as per datasheet.
Any property defined as part of the core regulator binding, defined in
regulator.txt, can also be used.
Example:
tps51632 {
compatible = "ti,tps51632";
reg = <0x43>;
regulator-name = "tps51632-vout";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1500000>;
regulator-boot-on;
ti,enable-pwm-dvfs;
ti,dvfs-step-20mV;
};

View File

@ -92,8 +92,8 @@ static const struct of_device_id __maybe_unused pg86x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pg86x_dt_ids);
static const struct i2c_device_id pg86x_i2c_id[] = {
{ "88pg867", },
{ "88pg868", },
{ .name = "88pg867" },
{ .name = "88pg868" },
{ }
};
MODULE_DEVICE_TABLE(i2c, pg86x_i2c_id);

View File

@ -1477,6 +1477,13 @@ config REGULATOR_S5M8767
via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and
supports DVS mode with 8bits of output voltage control.
config REGULATOR_SC2730
tristate "Spreadtrum SC2730 power regulator driver"
depends on MFD_SC27XX_PMIC || COMPILE_TEST
help
This driver provides support for the voltage regulators on the
SC2730 PMIC.
config REGULATOR_SC2731
tristate "Spreadtrum SC2731 power regulator driver"
depends on MFD_SC27XX_PMIC || COMPILE_TEST

View File

@ -170,6 +170,7 @@ obj-$(CONFIG_REGULATOR_S2DOS05) += s2dos05-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_REGULATOR_SC2730) += sc2730-regulator.o
obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
obj-$(CONFIG_REGULATOR_SGM3804) += sgm3804-regulator.o
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o

View File

@ -173,7 +173,6 @@ 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;

View File

@ -780,7 +780,7 @@ static const struct i2c_device_id act8865_ids[] = {
{ .name = "act8600", .driver_data = ACT8600 },
{ .name = "act8846", .driver_data = ACT8846 },
{ .name = "act8865", .driver_data = ACT8865 },
{ },
{ }
};
MODULE_DEVICE_TABLE(i2c, act8865_ids);

View File

@ -207,8 +207,8 @@ struct ad5398_current_data_format {
static const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000};
static const struct i2c_device_id ad5398_id[] = {
{ "ad5398", (kernel_ulong_t)&df_10_4_120 },
{ "ad5821", (kernel_ulong_t)&df_10_4_120 },
{ .name = "ad5398", .driver_data = (kernel_ulong_t)&df_10_4_120 },
{ .name = "ad5821", .driver_data = (kernel_ulong_t)&df_10_4_120 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad5398_id);

View File

@ -224,7 +224,7 @@ static int adp5055_of_parse_cb(struct device_node *np,
adp5055->dvs_limit_upper[id] = pval;
if (adp5055->dvs_limit_upper[id] > 192000 || adp5055->dvs_limit_upper[id] < 12000)
return dev_err_probe(config->dev, adp5055->dvs_limit_upper[id],
return dev_err_probe(config->dev, -EINVAL,
"Out of range - dvs-limit-upper-microvolt value.");
ret = of_property_read_u32(np, "adi,dvs-limit-lower-microvolt", &pval);
@ -403,8 +403,8 @@ static const struct of_device_id adp5055_of_match[] = {
MODULE_DEVICE_TABLE(of, adp5055_of_match);
static const struct i2c_device_id adp5055_ids[] = {
{ .name = "adp5055"},
{ },
{ .name = "adp5055" },
{ }
};
MODULE_DEVICE_TABLE(i2c, adp5055_ids);

View File

@ -600,7 +600,6 @@ static int as3722_get_regulator_dt_data(struct platform_device *pdev,
ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches,
ARRAY_SIZE(as3722_regulator_matches));
of_node_put(np);
if (ret < 0) {
dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n",
ret);

View File

@ -212,8 +212,8 @@ static int aw37503_probe(struct i2c_client *client)
}
static const struct i2c_device_id aw37503_id[] = {
{.name = "aw37503",},
{},
{ .name = "aw37503" },
{ }
};
MODULE_DEVICE_TABLE(i2c, aw37503_id);

View File

@ -27,6 +27,7 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#define CREATE_TRACE_POINTS
#include <trace/events/regulator.h>
@ -6899,8 +6900,9 @@ static int __init regulator_init_complete(void)
* we'd only do this on systems that need it, and a kernel
* command line option might be useful.
*/
schedule_delayed_work(&regulator_init_complete_work,
msecs_to_jiffies(30000));
queue_delayed_work(system_freezable_wq,
&regulator_init_complete_work,
msecs_to_jiffies(30000));
return 0;
}

View File

@ -1195,16 +1195,16 @@ static void da9121_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id da9121_i2c_id[] = {
{"da9121", DA9121_SUBTYPE_DA9121},
{"da9130", DA9121_SUBTYPE_DA9130},
{"da9217", DA9121_SUBTYPE_DA9217},
{"da9122", DA9121_SUBTYPE_DA9122},
{"da9131", DA9121_SUBTYPE_DA9131},
{"da9220", DA9121_SUBTYPE_DA9220},
{"da9132", DA9121_SUBTYPE_DA9132},
{"da9141", DA9121_SUBTYPE_DA9141},
{"da9142", DA9121_SUBTYPE_DA9142},
{},
{ .name = "da9121", .driver_data = DA9121_SUBTYPE_DA9121 },
{ .name = "da9130", .driver_data = DA9121_SUBTYPE_DA9130 },
{ .name = "da9217", .driver_data = DA9121_SUBTYPE_DA9217 },
{ .name = "da9122", .driver_data = DA9121_SUBTYPE_DA9122 },
{ .name = "da9131", .driver_data = DA9121_SUBTYPE_DA9131 },
{ .name = "da9220", .driver_data = DA9121_SUBTYPE_DA9220 },
{ .name = "da9132", .driver_data = DA9121_SUBTYPE_DA9132 },
{ .name = "da9141", .driver_data = DA9121_SUBTYPE_DA9141 },
{ .name = "da9142", .driver_data = DA9121_SUBTYPE_DA9142 },
{ }
};
MODULE_DEVICE_TABLE(i2c, da9121_i2c_id);

View File

@ -202,8 +202,8 @@ static int da9210_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id da9210_i2c_id[] = {
{ "da9210" },
{}
{ .name = "da9210" },
{ }
};
MODULE_DEVICE_TABLE(i2c, da9210_i2c_id);

View File

@ -522,15 +522,15 @@ static int da9211_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id da9211_i2c_id[] = {
{"da9211", DA9211},
{"da9212", DA9212},
{"da9213", DA9213},
{"da9223", DA9223},
{"da9214", DA9214},
{"da9224", DA9224},
{"da9215", DA9215},
{"da9225", DA9225},
{},
{ .name = "da9211", .driver_data = DA9211 },
{ .name = "da9212", .driver_data = DA9212 },
{ .name = "da9213", .driver_data = DA9213 },
{ .name = "da9223", .driver_data = DA9223 },
{ .name = "da9214", .driver_data = DA9214 },
{ .name = "da9224", .driver_data = DA9224 },
{ .name = "da9215", .driver_data = DA9215 },
{ .name = "da9225", .driver_data = DA9225 },
{ }
};
MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);

View File

@ -21,6 +21,7 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
#include <dt-bindings/regulator/fcs,fan53555-regulator.h>
/* Voltage setting */
#define FAN53555_VSEL0 0x00
@ -113,6 +114,7 @@ enum {
enum {
FAN53555_CHIP_REV_00 = 0x3,
FAN53555_CHIP_REV_13 = 0xf,
FAN53555_CHIP_REV_23 = 0xc,
};
enum {
@ -305,6 +307,11 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
di->vsel_step = 10000;
di->enable_time = 400;
break;
case FAN53555_CHIP_REV_23:
di->vsel_min = 600000;
di->vsel_step = 12500;
di->enable_time = 400;
break;
default:
dev_err(di->dev,
"Chip ID %d with rev %d not supported!\n",
@ -389,6 +396,18 @@ static int rk8602_voltages_setup_rockchip(struct fan53555_device_info *di)
return 0;
}
static inline unsigned int fan53555_map_mode(unsigned int mode)
{
switch (mode) {
case FAN53555_REGULATOR_MODE_FORCE_PWM:
return REGULATOR_MODE_FAST;
case FAN53555_REGULATOR_MODE_AUTO:
return REGULATOR_MODE_NORMAL;
default:
return REGULATOR_MODE_INVALID;
}
}
static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
{
/* Init voltage range and step */
@ -586,6 +605,17 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
return ret;
}
static void fan53555_device_mode_map_setup(struct fan53555_device_info *di)
{
switch (di->vendor) {
case FAN53555_VENDOR_SILERGY:
di->desc.of_map_mode = fan53555_map_mode;
break;
default:
break;
}
}
static int fan53555_regulator_register(struct fan53555_device_info *di,
struct regulator_config *config)
{
@ -686,6 +716,10 @@ static int fan53555_regulator_probe(struct i2c_client *client)
if (!di)
return -ENOMEM;
di->vendor = (uintptr_t)i2c_get_match_data(client);
fan53555_device_mode_map_setup(di);
pdata = dev_get_platdata(&client->dev);
if (!pdata)
pdata = fan53555_parse_dt(&client->dev, np, &di->desc);
@ -695,7 +729,6 @@ static int fan53555_regulator_probe(struct i2c_client *client)
"Platform data not found!\n");
di->regulator = pdata->regulator;
di->vendor = (uintptr_t)i2c_get_match_data(client);
if (!dev_fwnode(&client->dev)) {
/* if no ramp constraint set, get the pdata ramp_delay */
if (!di->regulator->constraints.ramp_delay) {

View File

@ -164,8 +164,8 @@ static const struct of_device_id fan53880_dt_ids[] = {
MODULE_DEVICE_TABLE(of, fan53880_dt_ids);
static const struct i2c_device_id fan53880_i2c_id[] = {
{ "fan53880", },
{}
{ .name = "fan53880" },
{ }
};
MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id);

View File

@ -138,7 +138,7 @@ static int isl6271a_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id isl6271a_id[] = {
{ .name = "isl6271a", },
{ .name = "isl6271a" },
{ }
};

View File

@ -186,8 +186,8 @@ MODULE_DEVICE_TABLE(of, isl9305_dt_ids);
#endif
static const struct i2c_device_id isl9305_i2c_id[] = {
{ "isl9305", },
{ "isl9305h", },
{ .name = "isl9305" },
{ .name = "isl9305h" },
{ }
};
MODULE_DEVICE_TABLE(i2c, isl9305_i2c_id);

View File

@ -439,7 +439,7 @@ static int lp3971_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id lp3971_i2c_id[] = {
{ "lp3971" },
{ .name = "lp3971" },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);

View File

@ -537,7 +537,7 @@ static int lp3972_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id lp3972_i2c_id[] = {
{ "lp3972" },
{ .name = "lp3972" },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp3972_i2c_id);

View File

@ -935,8 +935,8 @@ static const struct of_device_id lp872x_dt_ids[] __maybe_unused = {
MODULE_DEVICE_TABLE(of, lp872x_dt_ids);
static const struct i2c_device_id lp872x_ids[] = {
{"lp8720", LP8720},
{"lp8725", LP8725},
{ .name = "lp8720", .driver_data = LP8720 },
{ .name = "lp8725", .driver_data = LP8725 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp872x_ids);

View File

@ -430,8 +430,8 @@ static void lp8755_remove(struct i2c_client *client)
}
static const struct i2c_device_id lp8755_id[] = {
{ LP8755_NAME },
{}
{ .name = LP8755_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp8755_id);

View File

@ -445,9 +445,9 @@ static const struct ltc3589_info ltc3589_12_info = {
};
static const struct i2c_device_id ltc3589_i2c_id[] = {
{ "ltc3589", (kernel_ulong_t)&ltc3589_info },
{ "ltc3589-1", (kernel_ulong_t)&ltc3589_12_info },
{ "ltc3589-2", (kernel_ulong_t)&ltc3589_12_info },
{ .name = "ltc3589", .driver_data = (kernel_ulong_t)&ltc3589_info },
{ .name = "ltc3589-1", .driver_data = (kernel_ulong_t)&ltc3589_12_info },
{ .name = "ltc3589-2", .driver_data = (kernel_ulong_t)&ltc3589_12_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id);

View File

@ -357,7 +357,7 @@ static int ltc3676_regulator_probe(struct i2c_client *client)
}
static const struct i2c_device_id ltc3676_i2c_id[] = {
{ "ltc3676" },
{ .name = "ltc3676" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc3676_i2c_id);

View File

@ -123,15 +123,88 @@ static const struct regulator_desc max14577_supported_regulators[] = {
[MAX14577_CHARGER] = MAX14577_CHARGER_REG,
};
struct max77836_ldo {
struct max14577 *max14577;
unsigned int mode;
};
static int max77836_ldo_enable(struct regulator_dev *rdev)
{
struct max77836_ldo *ldo = rdev_get_drvdata(rdev);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77836_CNFG1_LDO_PWRMD_MASK, ldo->mode);
}
static int max77836_ldo_disable(struct regulator_dev *rdev)
{
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77836_CNFG1_LDO_PWRMD_MASK,
MAX77836_CNFG1_LDO_PWRMD_OFF);
}
static unsigned int max77836_ldo_get_mode(struct regulator_dev *rdev)
{
struct max77836_ldo *ldo = rdev_get_drvdata(rdev);
switch (ldo->mode) {
case MAX77836_CNFG1_LDO_PWRMD_LPM:
return REGULATOR_MODE_IDLE;
case MAX77836_CNFG1_LDO_PWRMD_NORMAL:
return REGULATOR_MODE_NORMAL;
default:
return REGULATOR_MODE_INVALID;
}
}
static int max77836_ldo_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
struct max77836_ldo *ldo = rdev_get_drvdata(rdev);
unsigned int val;
switch (mode) {
case REGULATOR_MODE_NORMAL:
val = MAX77836_CNFG1_LDO_PWRMD_NORMAL;
break;
case REGULATOR_MODE_IDLE:
val = MAX77836_CNFG1_LDO_PWRMD_LPM;
break;
default:
return -EINVAL;
}
ldo->mode = val;
/* Only touch hardware if the regulator is already on */
if (regulator_is_enabled_regmap(rdev))
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77836_CNFG1_LDO_PWRMD_MASK, val);
return 0;
}
static unsigned int max77836_ldo_of_map_mode(unsigned int mode)
{
switch (mode) {
case REGULATOR_MODE_NORMAL:
case REGULATOR_MODE_IDLE:
return mode;
default:
return REGULATOR_MODE_INVALID;
}
}
static const struct regulator_ops max77836_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.enable = max77836_ldo_enable,
.disable = max77836_ldo_disable,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
/* TODO: add .set_suspend_mode */
.get_mode = max77836_ldo_get_mode,
.set_mode = max77836_ldo_set_mode,
};
#define MAX77836_LDO_REG(num) { \
@ -147,6 +220,7 @@ static const struct regulator_ops max77836_ldo_ops = {
.uV_step = MAX77836_REGULATOR_LDO_VOLTAGE_STEP, \
.enable_reg = MAX77836_LDO_REG_CNFG1_LDO ## num, \
.enable_mask = MAX77836_CNFG1_LDO_PWRMD_MASK, \
.of_map_mode = max77836_ldo_of_map_mode, \
.vsel_reg = MAX77836_LDO_REG_CNFG1_LDO ## num, \
.vsel_mask = MAX77836_CNFG1_LDO_TV_MASK, \
}
@ -205,7 +279,6 @@ static int max14577_regulator_probe(struct platform_device *pdev)
}
config.dev = max14577->dev;
config.driver_data = max14577;
for (i = 0; i < supported_regulators_size; i++) {
struct regulator_dev *regulator;
@ -217,6 +290,28 @@ static int max14577_regulator_probe(struct platform_device *pdev)
config.init_data = pdata->regulators[i].initdata;
config.of_node = pdata->regulators[i].of_node;
}
/*
* LDOs need per-regulator driver data to store their mode.
* The charger and safeout share the core MFD struct.
*/
if (dev_type == MAXIM_DEVICE_TYPE_MAX77836 &&
(supported_regulators[i].id == MAX77836_LDO1 ||
supported_regulators[i].id == MAX77836_LDO2)) {
struct max77836_ldo *ldo;
ldo = devm_kzalloc(&pdev->dev, sizeof(*ldo),
GFP_KERNEL);
if (!ldo)
return -ENOMEM;
ldo->max14577 = max14577;
ldo->mode = MAX77836_CNFG1_LDO_PWRMD_NORMAL;
config.driver_data = ldo;
} else {
config.driver_data = max14577;
}
config.regmap = max14577_get_regmap(max14577,
supported_regulators[i].id);

View File

@ -276,7 +276,7 @@ static int max1586_pmic_probe(struct i2c_client *client)
}
static const struct i2c_device_id max1586_id[] = {
{ "max1586" },
{ .name = "max1586" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max1586_id);

View File

@ -301,10 +301,10 @@ static const struct max20086_chip_info max20089_chip_info = {
};
static const struct i2c_device_id max20086_i2c_id[] = {
{ "max20086", (kernel_ulong_t)&max20086_chip_info },
{ "max20087", (kernel_ulong_t)&max20087_chip_info },
{ "max20088", (kernel_ulong_t)&max20088_chip_info },
{ "max20089", (kernel_ulong_t)&max20089_chip_info },
{ .name = "max20086", .driver_data = (kernel_ulong_t)&max20086_chip_info },
{ .name = "max20087", .driver_data = (kernel_ulong_t)&max20087_chip_info },
{ .name = "max20088", .driver_data = (kernel_ulong_t)&max20088_chip_info },
{ .name = "max20089", .driver_data = (kernel_ulong_t)&max20089_chip_info },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, max20086_i2c_id);

View File

@ -145,7 +145,7 @@ static const struct of_device_id of_max20411_match_tbl[] = {
MODULE_DEVICE_TABLE(of, of_max20411_match_tbl);
static const struct i2c_device_id max20411_id[] = {
{ "max20411" },
{ .name = "max20411" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max20411_id);

View File

@ -107,7 +107,7 @@ static const struct of_device_id of_max77503_match_tbl[] = {
MODULE_DEVICE_TABLE(of, of_max77503_match_tbl);
static const struct i2c_device_id max77503_regulator_id[] = {
{"max77503"},
{ .name = "max77503" },
{ }
};

View File

@ -1028,7 +1028,7 @@ static int max77675_regulator_probe(struct i2c_client *client)
}
static const struct i2c_device_id max77675_i2c_id[] = {
{ "max77675", 0 },
{ .name = "max77675" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max77675_i2c_id);

View File

@ -278,7 +278,7 @@ static const struct of_device_id __maybe_unused max77826_of_match[] = {
MODULE_DEVICE_TABLE(of, max77826_of_match);
static const struct i2c_device_id max77826_id[] = {
{ "max77826-regulator" },
{ .name = "max77826-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, max77826_id);

View File

@ -200,7 +200,7 @@ static const struct of_device_id __maybe_unused max77838_of_match[] = {
MODULE_DEVICE_TABLE(of, max77838_of_match);
static const struct i2c_device_id max77838_id[] = {
{ "max77838-regulator" },
{ .name = "max77838-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, max77838_id);

View File

@ -428,10 +428,10 @@ static int max77857_probe(struct i2c_client *client)
}
static const struct i2c_device_id max77857_id[] = {
{ "max77831", ID_MAX77831 },
{ "max77857", ID_MAX77857 },
{ "max77859", ID_MAX77859 },
{ "max77859a", ID_MAX77859A },
{ .name = "max77831", .driver_data = ID_MAX77831 },
{ .name = "max77857", .driver_data = ID_MAX77857 },
{ .name = "max77859", .driver_data = ID_MAX77859 },
{ .name = "max77859a", .driver_data = ID_MAX77859A },
{ }
};
MODULE_DEVICE_TABLE(i2c, max77857_id);

View File

@ -240,7 +240,7 @@ static int max8649_regulator_probe(struct i2c_client *client)
}
static const struct i2c_device_id max8649_id[] = {
{ "max8649" },
{ .name = "max8649" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8649_id);

View File

@ -162,7 +162,7 @@ MODULE_DEVICE_TABLE(of, max8893_dt_match);
#endif
static const struct i2c_device_id max8893_ids[] = {
{ "max8893" },
{ .name = "max8893" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8893_ids);

View File

@ -307,7 +307,7 @@ static int max8952_pmic_probe(struct i2c_client *client)
}
static const struct i2c_device_id max8952_ids[] = {
{ "max8952" },
{ .name = "max8952" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8952_ids);

View File

@ -780,9 +780,9 @@ static int max8973_probe(struct i2c_client *client)
}
static const struct i2c_device_id max8973_id[] = {
{.name = "max8973", .driver_data = MAX8973},
{.name = "max77621", .driver_data = MAX77621},
{},
{ .name = "max8973", .driver_data = MAX8973 },
{ .name = "max77621", .driver_data = MAX77621 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8973_id);

View File

@ -582,7 +582,6 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
}
pdata->num_regulators = rdata - pdata->regulators;
of_node_put(reg_np);
of_node_put(regulators_np);
pdata->buck_voltage_lock = of_property_read_bool(pmic_np, "max8998,pmic-buck-voltage-lock");

View File

@ -508,7 +508,7 @@ static int mcp16502_probe(struct i2c_client *client)
struct device *dev;
struct mcp16502 *mcp;
struct regmap *rmap;
int i, ret;
int i;
dev = &client->dev;
config.dev = dev;
@ -518,30 +518,23 @@ static int mcp16502_probe(struct i2c_client *client)
return -ENOMEM;
rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config);
if (IS_ERR(rmap)) {
ret = PTR_ERR(rmap);
dev_err(dev, "regmap init failed: %d\n", ret);
return ret;
}
if (IS_ERR(rmap))
return dev_err_probe(dev, PTR_ERR(rmap), "regmap init failed\n");
i2c_set_clientdata(client, mcp);
config.regmap = rmap;
config.driver_data = mcp;
mcp->lpm = devm_gpiod_get_optional(dev, "lpm", GPIOD_OUT_LOW);
if (IS_ERR(mcp->lpm)) {
dev_err(dev, "failed to get lpm pin: %ld\n", PTR_ERR(mcp->lpm));
return PTR_ERR(mcp->lpm);
}
if (IS_ERR(mcp->lpm))
return dev_err_probe(dev, PTR_ERR(mcp->lpm), "failed to get lpm pin\n");
for (i = 0; i < NUM_REGULATORS; i++) {
rdev = devm_regulator_register(dev, &mcp16502_desc[i], &config);
if (IS_ERR(rdev)) {
dev_err(dev,
"failed to register %s regulator %ld\n",
mcp16502_desc[i].name, PTR_ERR(rdev));
return PTR_ERR(rdev);
}
if (IS_ERR(rdev))
return dev_err_probe(dev, PTR_ERR(rdev),
"failed to register %s regulator\n",
mcp16502_desc[i].name);
}
mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
@ -578,7 +571,7 @@ static const struct dev_pm_ops mcp16502_pm_ops = {
};
#endif
static const struct i2c_device_id mcp16502_i2c_id[] = {
{ "mcp16502" },
{ .name = "mcp16502" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);

View File

@ -228,9 +228,9 @@ static const struct of_device_id mp5416_of_match[] = {
MODULE_DEVICE_TABLE(of, mp5416_of_match);
static const struct i2c_device_id mp5416_id[] = {
{ "mp5416", (kernel_ulong_t)&mp5416_regulators_desc },
{ "mp5496", (kernel_ulong_t)&mp5496_regulators_desc },
{}
{ .name = "mp5416", .driver_data = (kernel_ulong_t)&mp5416_regulators_desc },
{ .name = "mp5496", .driver_data = (kernel_ulong_t)&mp5496_regulators_desc },
{ }
};
MODULE_DEVICE_TABLE(i2c, mp5416_id);

View File

@ -386,8 +386,8 @@ static const struct of_device_id mp8859_dt_id[] __maybe_unused = {
MODULE_DEVICE_TABLE(of, mp8859_dt_id);
static const struct i2c_device_id mp8859_i2c_id[] = {
{ "mp8859", },
{ },
{ .name = "mp8859" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mp8859_i2c_id);

View File

@ -348,9 +348,9 @@ static const struct of_device_id mp886x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, mp886x_dt_ids);
static const struct i2c_device_id mp886x_id[] = {
{ "mp8867", (kernel_ulong_t)&mp8867_ci },
{ "mp8869", (kernel_ulong_t)&mp8869_ci },
{ },
{ .name = "mp8867", .driver_data = (kernel_ulong_t)&mp8867_ci },
{ .name = "mp8869", .driver_data = (kernel_ulong_t)&mp8869_ci },
{ }
};
MODULE_DEVICE_TABLE(i2c, mp886x_id);

View File

@ -309,8 +309,8 @@ static const struct of_device_id mpq7920_of_match[] = {
MODULE_DEVICE_TABLE(of, mpq7920_of_match);
static const struct i2c_device_id mpq7920_id[] = {
{ "mpq7920", },
{ },
{ .name = "mpq7920" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mpq7920_id);

View File

@ -133,8 +133,8 @@ static int mt6311_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id mt6311_i2c_id[] = {
{ "mt6311" },
{}
{ .name = "mt6311" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mt6311_i2c_id);

View File

@ -353,10 +353,10 @@ static const struct of_device_id pf530x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pf530x_dt_ids);
static const struct i2c_device_id pf530x_i2c_id[] = {
{ "pf5300", 0 },
{ "pf5301", 0 },
{ "pf5302", 0 },
{},
{ .name = "pf5300" },
{ .name = "pf5301" },
{ .name = "pf5302" },
{ }
};
MODULE_DEVICE_TABLE(i2c, pf530x_i2c_id);

View File

@ -596,10 +596,10 @@ static const struct of_device_id pf8x00_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pf8x00_dt_ids);
static const struct i2c_device_id pf8x00_i2c_id[] = {
{ "pf8100" },
{ "pf8121a" },
{ "pf8200" },
{}
{ .name = "pf8100" },
{ .name = "pf8121a" },
{ .name = "pf8200" },
{ }
};
MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id);

View File

@ -158,6 +158,25 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
return ret;
}
static int pfuze100_ldo_set_suspend_disable(struct regulator_dev *rdev)
{
struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
struct pfuze_regulator *desc = &pfuze100->regulator_descs[id];
/*
* Set the standby bit so the LDO output is turned off when the PMIC
* receives a STANDBY event, using the per-regulator stby_reg/stby_mask
* that describe the standby control for each LDO.
*
* The stby_mask only covers the VGENxSTBY bit. The VGENxLPWR stays at
* its reset value of 0, so the LDO is switched off rather than put
* into low-power mode.
*/
return regmap_update_bits(pfuze100->regmap, desc->stby_reg,
desc->stby_mask, desc->stby_mask);
}
static const struct regulator_ops pfuze100_ldo_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -165,6 +184,7 @@ static const struct regulator_ops pfuze100_ldo_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_suspend_disable = pfuze100_ldo_set_suspend_disable,
};
static const struct regulator_ops pfuze100_fixed_regulator_ops = {

View File

@ -360,8 +360,8 @@ static int pv88060_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id pv88060_i2c_id[] = {
{ "pv88060" },
{}
{ .name = "pv88060" },
{ }
};
MODULE_DEVICE_TABLE(i2c, pv88060_i2c_id);

View File

@ -522,10 +522,10 @@ static const struct of_device_id pv88080_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pv88080_dt_ids);
static const struct i2c_device_id pv88080_i2c_id[] = {
{ "pv88080", (kernel_ulong_t)&pv88080_aa_regs },
{ "pv88080-aa", (kernel_ulong_t)&pv88080_aa_regs },
{ "pv88080-ba", (kernel_ulong_t)&pv88080_ba_regs },
{}
{ .name = "pv88080", .driver_data = (kernel_ulong_t)&pv88080_aa_regs },
{ .name = "pv88080-aa", .driver_data = (kernel_ulong_t)&pv88080_aa_regs },
{ .name = "pv88080-ba", .driver_data = (kernel_ulong_t)&pv88080_ba_regs },
{ }
};
MODULE_DEVICE_TABLE(i2c, pv88080_i2c_id);

View File

@ -381,8 +381,8 @@ static int pv88090_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id pv88090_i2c_id[] = {
{ "pv88090" },
{}
{ .name = "pv88090" },
{ }
};
MODULE_DEVICE_TABLE(i2c, pv88090_i2c_id);

View File

@ -3,6 +3,7 @@
// Copyright (c) 2023, Linaro Limited
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@ -16,6 +17,9 @@
#define REFGEN_BIAS_EN_ENABLE 0x7
#define REFGEN_BIAS_EN_DISABLE 0x6
#define REFGEN_REG_REFGEN_STATUS 0xc
#define REFGEN_STATUS_OUT_MASK BIT(3)
#define REFGEN_REG_BG_CTRL 0x14
#define REFGEN_BG_CTRL_MASK GENMASK(2, 1)
#define REFGEN_BG_CTRL_ENABLE 0x3
@ -25,6 +29,17 @@
#define REFGEN_PWRDWN_CTRL5_MASK BIT(0)
#define REFGEN_PWRDWN_CTRL5_ENABLE 0x1
struct qcom_refgen_regulator_data {
const struct regulator_desc *rdesc;
bool has_clocks;
};
struct qcom_refgen_drvdata {
struct clk_bulk_data *clks;
int num_clks;
bool is_enabled;
};
static int qcom_sdm845_refgen_enable(struct regulator_dev *rdev)
{
regmap_update_bits(rdev->regmap, REFGEN_REG_BG_CTRL, REFGEN_BG_CTRL_MASK,
@ -62,11 +77,67 @@ static int qcom_sdm845_refgen_is_enabled(struct regulator_dev *rdev)
return 1;
}
static int qcom_ipq9650_refgen_enable(struct regulator_dev *rdev)
{
struct qcom_refgen_drvdata *drvdata = rdev_get_drvdata(rdev);
int ret;
ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
if (ret)
return ret;
drvdata->is_enabled = true;
return 0;
}
static int qcom_ipq9650_refgen_disable(struct regulator_dev *rdev)
{
struct qcom_refgen_drvdata *drvdata = rdev_get_drvdata(rdev);
clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
drvdata->is_enabled = false;
return 0;
}
static int qcom_ipq9650_refgen_is_enabled(struct regulator_dev *rdev)
{
struct qcom_refgen_drvdata *drvdata = rdev_get_drvdata(rdev);
return drvdata->is_enabled;
}
static int qcom_ipq9650_refgen_get_status(struct regulator_dev *rdev)
{
u32 val;
regmap_read(rdev->regmap, REFGEN_REG_REFGEN_STATUS, &val);
if (FIELD_GET(REFGEN_STATUS_OUT_MASK, val))
return REGULATOR_STATUS_ON;
return REGULATOR_STATUS_OFF;
}
static const struct regulator_desc ipq9650_refgen_desc = {
.enable_time = 5,
.name = "refgen",
.owner = THIS_MODULE,
.type = REGULATOR_CURRENT,
.ops = &(const struct regulator_ops) {
.enable = qcom_ipq9650_refgen_enable,
.disable = qcom_ipq9650_refgen_disable,
.is_enabled = qcom_ipq9650_refgen_is_enabled,
.get_status = qcom_ipq9650_refgen_get_status,
},
};
static const struct regulator_desc sdm845_refgen_desc = {
.enable_time = 5,
.name = "refgen",
.owner = THIS_MODULE,
.type = REGULATOR_VOLTAGE,
.type = REGULATOR_CURRENT,
.ops = &(const struct regulator_ops) {
.enable = qcom_sdm845_refgen_enable,
.disable = qcom_sdm845_refgen_disable,
@ -82,7 +153,7 @@ static const struct regulator_desc sm8250_refgen_desc = {
.enable_time = 5,
.name = "refgen",
.owner = THIS_MODULE,
.type = REGULATOR_VOLTAGE,
.type = REGULATOR_CURRENT,
.ops = &(const struct regulator_ops) {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -90,6 +161,19 @@ static const struct regulator_desc sm8250_refgen_desc = {
},
};
static const struct qcom_refgen_regulator_data ipq9650_data = {
.rdesc = &ipq9650_refgen_desc,
.has_clocks = true,
};
static const struct qcom_refgen_regulator_data sdm845_data = {
.rdesc = &sdm845_refgen_desc,
};
static const struct qcom_refgen_regulator_data sm8250_data = {
.rdesc = &sm8250_refgen_desc,
};
static const struct regmap_config qcom_refgen_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@ -98,6 +182,8 @@ static const struct regmap_config qcom_refgen_regmap_config = {
static int qcom_refgen_probe(struct platform_device *pdev)
{
const struct qcom_refgen_regulator_data *data;
struct qcom_refgen_drvdata *drvdata = NULL;
struct regulator_init_data *init_data;
struct regulator_config config = {};
const struct regulator_desc *rdesc;
@ -106,10 +192,23 @@ static int qcom_refgen_probe(struct platform_device *pdev)
struct regmap *regmap;
void __iomem *base;
rdesc = of_device_get_match_data(dev);
if (!rdesc)
data = of_device_get_match_data(dev);
if (!data)
return -ENODATA;
if (data->has_clocks) {
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->num_clks = devm_clk_bulk_get_all(dev, &drvdata->clks);
if (drvdata->num_clks < 0)
return dev_err_probe(dev, drvdata->num_clks,
"failed to get clocks\n");
}
rdesc = data->rdesc;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
@ -126,6 +225,7 @@ static int qcom_refgen_probe(struct platform_device *pdev)
config.init_data = init_data;
config.of_node = dev->of_node;
config.regmap = regmap;
config.driver_data = drvdata;
rdev = devm_regulator_register(dev, rdesc, &config);
if (IS_ERR(rdev))
@ -135,8 +235,9 @@ static int qcom_refgen_probe(struct platform_device *pdev)
}
static const struct of_device_id qcom_refgen_match_table[] = {
{ .compatible = "qcom,sdm845-refgen-regulator", .data = &sdm845_refgen_desc },
{ .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_refgen_desc },
{ .compatible = "qcom,ipq9650-refgen-regulator", .data = &ipq9650_data },
{ .compatible = "qcom,sdm845-refgen-regulator", .data = &sdm845_data },
{ .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_data },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_refgen_match_table);

View File

@ -4,6 +4,7 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/bits.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
@ -61,8 +62,13 @@ static const struct resource_name_formats vreg_rsc_name_lookup[NUM_REGULATOR_TYP
};
#define RPMH_REGULATOR_REG_VRM_VOLTAGE 0x0
#define RPMH_REGULATOR_VOLTAGE_MASK GENMASK(12, 0)
#define RPMH_REGULATOR_REG_ENABLE 0x4
#define RPMH_REGULATOR_ENABLE_MASK BIT(0)
#define RPMH_REGULATOR_REG_VRM_MODE 0x8
#define RPMH_REGULATOR_MODE_MASK GENMASK(2, 0)
#define PMIC4_LDO_MODE_RETENTION 4
#define PMIC4_LDO_MODE_LPM 5
@ -104,13 +110,14 @@ static const struct resource_name_formats vreg_rsc_name_lookup[NUM_REGULATOR_TYP
* regulator
* @ops: Pointer to regulator ops callback structure
* @voltage_ranges: The possible ranges of voltages supported by this
* PMIC regulator type
* PMIC regulator type
* @n_linear_ranges: Number of entries in voltage_ranges
* @n_voltages: The number of unique voltage set points defined
* by voltage_ranges
* @hpm_min_load_uA: Minimum load current in microamps that requires
* high power mode (HPM) operation. This is used
* for LDO hardware type regulators only.
* @pmic_bypass_mode: The PMIC bypass mode value.
* @pmic_mode_map: Array indexed by regulator framework mode
* containing PMIC hardware modes. Must be large
* enough to index all framework modes supported
@ -125,6 +132,7 @@ struct rpmh_vreg_hw_data {
int n_linear_ranges;
int n_voltages;
int hpm_min_load_uA;
int pmic_bypass_mode;
const int *pmic_mode_map;
unsigned int (*of_map_mode)(unsigned int mode);
};
@ -246,9 +254,34 @@ static int rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
selector > vreg->voltage_selector);
}
static int _rpmh_regulator_vrm_get_voltage(struct regulator_dev *rdev, int *uV)
{
struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
struct tcs_cmd cmd = {
.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
};
int ret;
ret = rpmh_read(vreg->dev, &cmd);
if (!ret)
*uV = (cmd.data & RPMH_REGULATOR_VOLTAGE_MASK) * 1000;
else
dev_err(vreg->dev, "failed to read VOLTAGE ret = %d\n", ret);
return ret;
}
static int rpmh_regulator_vrm_get_voltage_sel(struct regulator_dev *rdev)
{
struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
int ret, uV = 0;
if (vreg->voltage_selector < 0) {
ret = _rpmh_regulator_vrm_get_voltage(rdev, &uV);
if (!ret && uV != 0)
vreg->voltage_selector = regulator_map_voltage_linear_range(rdev,
uV, INT_MAX);
}
return vreg->voltage_selector;
}
@ -311,7 +344,7 @@ static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
return pmic_mode;
if (bypassed)
cmd.data = PMIC4_BOB_MODE_PASS;
cmd.data = vreg->hw_data->pmic_bypass_mode;
else
cmd.data = pmic_mode;
@ -334,6 +367,22 @@ static int rpmh_regulator_vrm_set_mode(struct regulator_dev *rdev,
return ret;
}
static int rpmh_regulator_vrm_get_pmic_mode(struct rpmh_vreg *vreg, int *pmic_mode)
{
struct tcs_cmd cmd = {
.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
};
int ret;
ret = rpmh_read(vreg->dev, &cmd);
if (!ret)
*pmic_mode = cmd.data & RPMH_REGULATOR_MODE_MASK;
else
return -EINVAL;
return 0;
}
static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
{
struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
@ -538,6 +587,73 @@ static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
return 0;
}
static int rpmh_regulator_determine_initial_mode(struct rpmh_vreg *vreg)
{
struct tcs_cmd cmd = {
.addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
};
int ret, pmic_mode, mode;
int sts;
ret = rpmh_read(vreg->dev, &cmd);
if (ret) {
dev_err(vreg->dev, "failed to read ENABLE status ret = %d\n", ret);
return ret;
}
sts = cmd.data & RPMH_REGULATOR_ENABLE_MASK;
if (!sts)
return 0;
if (vreg->hw_data->regulator_type == XOB)
return 0;
ret = rpmh_regulator_vrm_get_pmic_mode(vreg, &pmic_mode);
if (ret < 0) {
vreg->mode = REGULATOR_MODE_INVALID;
dev_err(vreg->dev, "failed to read pmic_mode ret = %d\n", ret);
return ret;
}
/*
* NOTE: Since BOB4 BYPASS_MODE value = 0 we cannot confirm if that BOB
* regulator has been sent into bypass mode by bootloader or if bootloader
* just has not requested for any mode voting. Due this limitation, we
* must check if the read pmic_mode value is non-zero before comparing it
* to bypass mode value. This also is needed to avoid setting BYPASS status
* for LDOs which dont support bypass mode, and have the pmic_bypass_mode
* uninitialized value as zero in the vreg hw data. For such cases assume
* lowest mode, if pmic_mode is zero, to allow for mode voting.
*/
if (!pmic_mode) {
for (mode = REGULATOR_MODE_STANDBY; mode > REGULATOR_MODE_INVALID; mode >>= 1) {
if (vreg->hw_data->pmic_mode_map[mode] >= 0) {
vreg->mode = mode;
break;
}
}
return 0;
}
if (vreg->hw_data->pmic_bypass_mode == pmic_mode) {
vreg->bypassed = true;
return 0;
}
for (mode = REGULATOR_MODE_STANDBY; mode > REGULATOR_MODE_INVALID; mode >>= 1) {
if (pmic_mode == vreg->hw_data->pmic_mode_map[mode]) {
vreg->mode = mode;
break;
}
}
return 0;
}
static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
[REGULATOR_MODE_INVALID] = -EINVAL,
[REGULATOR_MODE_STANDBY] = PMIC4_LDO_MODE_RETENTION,
@ -767,6 +883,7 @@ static const struct rpmh_vreg_hw_data pmic4_bob = {
},
.n_linear_ranges = 1,
.n_voltages = 84,
.pmic_bypass_mode = PMIC4_BOB_MODE_PASS,
.pmic_mode_map = pmic_mode_map_pmic4_bob,
.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
};
@ -975,6 +1092,7 @@ static const struct rpmh_vreg_hw_data pmic5_bob = {
},
.n_linear_ranges = 1,
.n_voltages = 32,
.pmic_bypass_mode = PMIC5_BOB_MODE_PASS,
.pmic_mode_map = pmic_mode_map_pmic5_bob,
.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
};
@ -1839,6 +1957,12 @@ static int rpmh_regulator_probe(struct platform_device *pdev)
vreg_data);
if (ret < 0)
return ret;
ret = rpmh_regulator_determine_initial_mode(vreg);
if (ret < 0)
dev_err(dev, "failed to read initial mode for %s\n",
vreg->rdesc.name);
}
return 0;

View File

@ -20,10 +20,35 @@
#define OTG_CFG 0x53
#define OTG_EN_SRC_CFG BIT(1)
#define PM4125_VBOOST_EN 0x50
#define PM4125_VBOOST_SEL 0x52
#define PM4125_VBOOST_CFG_MASK GENMASK(1, 0)
#define PM4125_VBOOST_CFG 0x56
#define PM4125_VBOOST_EN_SRC_CFG BIT(0)
struct qcom_usb_vbus_reg_data {
u16 cmd_otg;
u16 otg_cfg;
u8 otg_en_src_cfg;
u16 csel_reg;
u8 csel_mask;
const unsigned int *curr_table;
unsigned int n_current_limits;
u16 vsel_reg;
u8 vsel_mask;
const unsigned int *volt_table;
unsigned int n_voltages;
const struct regulator_ops *ops;
};
static const unsigned int curr_table[] = {
500000, 1000000, 1500000, 2000000, 2500000, 3000000,
};
static const unsigned int pm4125_vboost_table[] = {
4250000, 4500000, 4750000, 5000000,
};
static const struct regulator_ops qcom_usb_vbus_reg_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -32,19 +57,43 @@ static const struct regulator_ops qcom_usb_vbus_reg_ops = {
.set_current_limit = regulator_set_current_limit_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 const struct qcom_usb_vbus_reg_data pm8150b_data = {
.cmd_otg = CMD_OTG,
.otg_cfg = OTG_CFG,
.otg_en_src_cfg = OTG_EN_SRC_CFG,
.csel_reg = OTG_CURRENT_LIMIT_CFG,
.csel_mask = OTG_CURRENT_LIMIT_MASK,
.curr_table = curr_table,
.n_current_limits = ARRAY_SIZE(curr_table),
.ops = &qcom_usb_vbus_reg_ops,
};
static const struct regulator_ops qcom_usb_vbus_pm4125_reg_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_table,
};
static const struct qcom_usb_vbus_reg_data pm4125_data = {
.cmd_otg = PM4125_VBOOST_EN,
.otg_cfg = PM4125_VBOOST_CFG,
.otg_en_src_cfg = PM4125_VBOOST_EN_SRC_CFG,
.vsel_reg = PM4125_VBOOST_SEL,
.vsel_mask = PM4125_VBOOST_CFG_MASK,
.volt_table = pm4125_vboost_table,
.n_voltages = ARRAY_SIZE(pm4125_vboost_table),
.ops = &qcom_usb_vbus_pm4125_reg_ops,
};
static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct qcom_usb_vbus_reg_data *data;
struct regulator_dev *rdev;
struct regulator_desc *rdesc;
struct regmap *regmap;
struct regulator_config config = { };
struct regulator_init_data *init_data;
@ -57,27 +106,51 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
return ret;
}
data = of_device_get_match_data(dev);
if (!data)
return -EINVAL;
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);
rdesc = devm_kzalloc(dev, sizeof(*rdesc), GFP_KERNEL);
if (!rdesc)
return -ENOMEM;
rdesc->name = "usb_vbus";
rdesc->ops = data->ops;
rdesc->owner = THIS_MODULE;
rdesc->type = REGULATOR_VOLTAGE;
rdesc->enable_reg = base + data->cmd_otg;
rdesc->enable_mask = OTG_EN;
if (data->curr_table) {
rdesc->curr_table = data->curr_table;
rdesc->n_current_limits = data->n_current_limits;
rdesc->csel_reg = base + data->csel_reg;
rdesc->csel_mask = data->csel_mask;
}
if (data->volt_table) {
rdesc->volt_table = data->volt_table;
rdesc->n_voltages = data->n_voltages;
rdesc->vsel_reg = base + data->vsel_reg;
rdesc->vsel_mask = data->vsel_mask;
}
init_data = of_get_regulator_init_data(dev, dev->of_node, rdesc);
if (!init_data)
return -ENOMEM;
qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG;
qcom_usb_vbus_rdesc.enable_mask = OTG_EN;
qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG;
qcom_usb_vbus_rdesc.csel_mask = OTG_CURRENT_LIMIT_MASK;
config.dev = dev;
config.init_data = init_data;
config.of_node = dev->of_node;
config.regmap = regmap;
rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config);
rdev = devm_regulator_register(dev, rdesc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(dev, "not able to register vbus reg %d\n", ret);
@ -85,13 +158,14 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
}
/* Disable HW logic for VBUS enable */
regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0);
regmap_update_bits(regmap, base + data->otg_cfg, data->otg_en_src_cfg, 0);
return 0;
}
static const struct of_device_id qcom_usb_vbus_regulator_match[] = {
{ .compatible = "qcom,pm8150b-vbus-reg" },
{ .compatible = "qcom,pm8150b-vbus-reg", .data = &pm8150b_data },
{ .compatible = "qcom,pm4125-vbus-reg", .data = &pm4125_data },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match);

View File

@ -49,8 +49,11 @@ static int rt6245_enable(struct regulator_dev *rdev)
regcache_cache_only(regmap, false);
ret = regcache_sync(regmap);
if (ret)
if (ret) {
regcache_cache_only(regmap, true);
gpiod_direction_output(priv->enable_gpio, 0);
return ret;
}
priv->enable_state = true;
return 0;

View File

@ -11,6 +11,7 @@
#include <linux/regulator/of_regulator.h>
/* Register */
#define RTQ2208_REG_FSOUTB_CNTL 0x11
#define RTQ2208_REG_GLOBAL_INT1 0x12
#define RTQ2208_REG_FLT_RECORDBUCK_CB 0x18
#define RTQ2208_REG_GLOBAL_INT1_MASK 0x1D
@ -33,6 +34,7 @@
#define RTQ2208_REG_HIDDEN1 0xFF
/* Mask */
#define RTQ2208_MTP_SEL_RO_MASK BIT(7)
#define RTQ2208_BUCK_NR_MTP_SEL_MASK GENMASK(7, 0)
#define RTQ2208_BUCK_EN_NR_MTP_SEL0_MASK BIT(0)
#define RTQ2208_BUCK_EN_NR_MTP_SEL1_MASK BIT(1)
@ -464,10 +466,13 @@ static int rtq2208_parse_regulator_dt_data(int n_regulator, const unsigned int *
struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX], struct device *dev,
unsigned int ldo1_fixed, unsigned int ldo2_fixed)
{
struct regmap *regmap = dev_get_regmap(dev, NULL);
int mtp_sel, i, idx;
/* get mtp_sel0 or mtp_sel1 */
mtp_sel = device_property_read_bool(dev, "richtek,mtp-sel-high");
mtp_sel = regmap_test_bits(regmap, RTQ2208_REG_FSOUTB_CNTL, RTQ2208_MTP_SEL_RO_MASK);
if (mtp_sel < 0)
return dev_err_probe(dev, mtp_sel, "Failed to init mtp_sel state\n");
for (i = 0; i < n_regulator; i++) {
idx = regulator_idx_table[i];

View File

@ -0,0 +1,375 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018-2021 Unisoc Inc.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
/*
* SC2730 regulator base address
*/
#define SC2730_REGULATOR_BASE 0x1800
/*
* SC2730 regulator lock register
*/
#define SC2730_WR_UNLOCK_VALUE 0x6e7f
#define SC2730_PWR_WR_PROT (SC2730_REGULATOR_BASE + 0x3d0)
/*
* SC2730 enable register
*/
#define SC2730_POWER_PD_SW (SC2730_REGULATOR_BASE + 0x01c)
#define SC2730_LDO_VDDRF18_PD (SC2730_REGULATOR_BASE + 0x10c)
#define SC2730_LDO_VDDCAMIO_PD (SC2730_REGULATOR_BASE + 0x118)
#define SC2730_LDO_VDDWCN_PD (SC2730_REGULATOR_BASE + 0x11c)
#define SC2730_LDO_VDDCAMD1_PD (SC2730_REGULATOR_BASE + 0x128)
#define SC2730_LDO_VDDCAMD0_PD (SC2730_REGULATOR_BASE + 0x134)
#define SC2730_LDO_VDDRF1V25_PD (SC2730_REGULATOR_BASE + 0x140)
#define SC2730_LDO_AVDD12_PD (SC2730_REGULATOR_BASE + 0x14c)
#define SC2730_LDO_VDDCAMA0_PD (SC2730_REGULATOR_BASE + 0x158)
#define SC2730_LDO_VDDCAMA1_PD (SC2730_REGULATOR_BASE + 0x164)
#define SC2730_LDO_VDDCAMMOT_PD (SC2730_REGULATOR_BASE + 0x170)
#define SC2730_LDO_VDDSIM2_PD (SC2730_REGULATOR_BASE + 0x194)
#define SC2730_LDO_VDDEMMCCORE_PD (SC2730_REGULATOR_BASE + 0x1a0)
#define SC2730_LDO_VDDSDCORE_PD (SC2730_REGULATOR_BASE + 0x1ac)
#define SC2730_LDO_VDDSDIO_PD (SC2730_REGULATOR_BASE + 0x1b8)
#define SC2730_LDO_VDDWIFIPA_PD (SC2730_REGULATOR_BASE + 0x1d0)
#define SC2730_LDO_VDDUSB33_PD (SC2730_REGULATOR_BASE + 0x1e8)
#define SC2730_LDO_VDDLDO0_PD (SC2730_REGULATOR_BASE + 0x1f4)
#define SC2730_LDO_VDDLDO1_PD (SC2730_REGULATOR_BASE + 0x200)
#define SC2730_LDO_VDDLDO2_PD (SC2730_REGULATOR_BASE + 0x20c)
#define SC2730_LDO_VDDKPLED_PD (SC2730_REGULATOR_BASE + 0x38c)
/*
* SC2730 enable mask
*/
#define SC2730_DCDC_CPU_PD_MASK BIT(4)
#define SC2730_DCDC_GPU_PD_MASK BIT(3)
#define SC2730_DCDC_CORE_PD_MASK BIT(5)
#define SC2730_DCDC_MODEM_PD_MASK BIT(11)
#define SC2730_DCDC_MEM_PD_MASK BIT(6)
#define SC2730_DCDC_MEMQ_PD_MASK BIT(12)
#define SC2730_DCDC_GEN0_PD_MASK BIT(8)
#define SC2730_DCDC_GEN1_PD_MASK BIT(7)
#define SC2730_DCDC_SRAM_PD_MASK BIT(13)
#define SC2730_LDO_AVDD18_PD_MASK BIT(2)
#define SC2730_LDO_VDDRF18_PD_MASK BIT(0)
#define SC2730_LDO_VDDCAMIO_PD_MASK BIT(0)
#define SC2730_LDO_VDDWCN_PD_MASK BIT(0)
#define SC2730_LDO_VDDCAMD1_PD_MASK BIT(0)
#define SC2730_LDO_VDDCAMD0_PD_MASK BIT(0)
#define SC2730_LDO_VDDRF1V25_PD_MASK BIT(0)
#define SC2730_LDO_AVDD12_PD_MASK BIT(0)
#define SC2730_LDO_VDDCAMA0_PD_MASK BIT(0)
#define SC2730_LDO_VDDCAMA1_PD_MASK BIT(0)
#define SC2730_LDO_VDDCAMMOT_PD_MASK BIT(0)
#define SC2730_LDO_VDDSIM2_PD_MASK BIT(0)
#define SC2730_LDO_VDDEMMCCORE_PD_MASK BIT(0)
#define SC2730_LDO_VDDSDCORE_PD_MASK BIT(0)
#define SC2730_LDO_VDDSDIO_PD_MASK BIT(0)
#define SC2730_LDO_VDD28_PD_MASK BIT(1)
#define SC2730_LDO_VDDWIFIPA_PD_MASK BIT(0)
#define SC2730_LDO_VDD18_DCXO_PD_MASK BIT(10)
#define SC2730_LDO_VDDUSB33_PD_MASK BIT(0)
#define SC2730_LDO_VDDLDO0_PD_MASK BIT(0)
#define SC2730_LDO_VDDLDO1_PD_MASK BIT(0)
#define SC2730_LDO_VDDLDO2_PD_MASK BIT(0)
#define SC2730_LDO_VDDKPLED_PD_MASK BIT(15)
/*
* SC2730 vsel register
*/
#define SC2730_DCDC_CPU_VOL (SC2730_REGULATOR_BASE + 0x44)
#define SC2730_DCDC_GPU_VOL (SC2730_REGULATOR_BASE + 0x54)
#define SC2730_DCDC_CORE_VOL (SC2730_REGULATOR_BASE + 0x64)
#define SC2730_DCDC_MODEM_VOL (SC2730_REGULATOR_BASE + 0x74)
#define SC2730_DCDC_MEM_VOL (SC2730_REGULATOR_BASE + 0x84)
#define SC2730_DCDC_MEMQ_VOL (SC2730_REGULATOR_BASE + 0x94)
#define SC2730_DCDC_GEN0_VOL (SC2730_REGULATOR_BASE + 0xa4)
#define SC2730_DCDC_GEN1_VOL (SC2730_REGULATOR_BASE + 0xb4)
#define SC2730_DCDC_SRAM_VOL (SC2730_REGULATOR_BASE + 0xdc)
#define SC2730_LDO_AVDD18_VOL (SC2730_REGULATOR_BASE + 0x104)
#define SC2730_LDO_VDDRF18_VOL (SC2730_REGULATOR_BASE + 0x110)
#define SC2730_LDO_VDDCAMIO_VOL (SC2730_REGULATOR_BASE + 0x28)
#define SC2730_LDO_VDDWCN_VOL (SC2730_REGULATOR_BASE + 0x120)
#define SC2730_LDO_VDDCAMD1_VOL (SC2730_REGULATOR_BASE + 0x12c)
#define SC2730_LDO_VDDCAMD0_VOL (SC2730_REGULATOR_BASE + 0x138)
#define SC2730_LDO_VDDRF1V25_VOL (SC2730_REGULATOR_BASE + 0x144)
#define SC2730_LDO_AVDD12_VOL (SC2730_REGULATOR_BASE + 0x150)
#define SC2730_LDO_VDDCAMA0_VOL (SC2730_REGULATOR_BASE + 0x15c)
#define SC2730_LDO_VDDCAMA1_VOL (SC2730_REGULATOR_BASE + 0x168)
#define SC2730_LDO_VDDCAMMOT_VOL (SC2730_REGULATOR_BASE + 0x174)
#define SC2730_LDO_VDDSIM2_VOL (SC2730_REGULATOR_BASE + 0x198)
#define SC2730_LDO_VDDEMMCCORE_VOL (SC2730_REGULATOR_BASE + 0x1a4)
#define SC2730_LDO_VDDSDCORE_VOL (SC2730_REGULATOR_BASE + 0x1b0)
#define SC2730_LDO_VDDSDIO_VOL (SC2730_REGULATOR_BASE + 0x1bc)
#define SC2730_LDO_VDD28_VOL (SC2730_REGULATOR_BASE + 0x1c8)
#define SC2730_LDO_VDDWIFIPA_VOL (SC2730_REGULATOR_BASE + 0x1d4)
#define SC2730_LDO_VDD18_DCXO_VOL (SC2730_REGULATOR_BASE + 0x1e0)
#define SC2730_LDO_VDDUSB33_VOL (SC2730_REGULATOR_BASE + 0x1ec)
#define SC2730_LDO_VDDLDO0_VOL (SC2730_REGULATOR_BASE + 0x1f8)
#define SC2730_LDO_VDDLDO1_VOL (SC2730_REGULATOR_BASE + 0x204)
#define SC2730_LDO_VDDLDO2_VOL (SC2730_REGULATOR_BASE + 0x210)
#define SC2730_LDO_VDDKPLED_VOL (SC2730_REGULATOR_BASE + 0x38c)
/*
* SC2730 vsel register mask
*/
#define SC2730_DCDC_CPU_VOL_MASK GENMASK(8, 0)
#define SC2730_DCDC_GPU_VOL_MASK GENMASK(8, 0)
#define SC2730_DCDC_CORE_VOL_MASK GENMASK(8, 0)
#define SC2730_DCDC_MODEM_VOL_MASK GENMASK(8, 0)
#define SC2730_DCDC_MEM_VOL_MASK GENMASK(7, 0)
#define SC2730_DCDC_MEMQ_VOL_MASK GENMASK(8, 0)
#define SC2730_DCDC_GEN0_VOL_MASK GENMASK(7, 0)
#define SC2730_DCDC_GEN1_VOL_MASK GENMASK(7, 0)
#define SC2730_DCDC_SRAM_VOL_MASK GENMASK(8, 0)
#define SC2730_LDO_AVDD18_VOL_MASK GENMASK(5, 0)
#define SC2730_LDO_VDDRF18_VOL_MASK GENMASK(5, 0)
#define SC2730_LDO_VDDCAMIO_VOL_MASK GENMASK(5, 0)
#define SC2730_LDO_VDDWCN_VOL_MASK GENMASK(5, 0)
#define SC2730_LDO_VDDCAMD1_VOL_MASK GENMASK(4, 0)
#define SC2730_LDO_VDDCAMD0_VOL_MASK GENMASK(4, 0)
#define SC2730_LDO_VDDRF1V25_VOL_MASK GENMASK(4, 0)
#define SC2730_LDO_AVDD12_VOL_MASK GENMASK(4, 0)
#define SC2730_LDO_VDDCAMA0_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDCAMA1_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDCAMMOT_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDSIM2_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDEMMCCORE_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDSDCORE_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDSDIO_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDD28_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDWIFIPA_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDD18_DCXO_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDUSB33_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDLDO0_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDLDO1_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDLDO2_VOL_MASK GENMASK(7, 0)
#define SC2730_LDO_VDDKPLED_VOL_MASK GENMASK(14, 7)
enum sc2730_regulator_id {
SC2730_DCDC_CPU,
SC2730_DCDC_GPU,
SC2730_DCDC_CORE,
SC2730_DCDC_MODEM,
SC2730_DCDC_MEM,
SC2730_DCDC_MEMQ,
SC2730_DCDC_GEN0,
SC2730_DCDC_GEN1,
SC2730_DCDC_SRAM,
SC2730_LDO_AVDD18,
SC2730_LDO_VDDRF18,
SC2730_LDO_VDDCAMIO,
SC2730_LDO_VDDWCN,
SC2730_LDO_VDDCAMD1,
SC2730_LDO_VDDCAMD0,
SC2730_LDO_VDDRF1V25,
SC2730_LDO_AVDD12,
SC2730_LDO_VDDCAMA0,
SC2730_LDO_VDDCAMA1,
SC2730_LDO_VDDCAMMOT,
SC2730_LDO_VDDSIM2,
SC2730_LDO_VDDEMMCCORE,
SC2730_LDO_VDDSDCORE,
SC2730_LDO_VDDSDIO,
SC2730_LDO_VDD28,
SC2730_LDO_VDDWIFIPA,
SC2730_LDO_VDD18_DCXO,
SC2730_LDO_VDDUSB33,
SC2730_LDO_VDDLDO0,
SC2730_LDO_VDDLDO1,
SC2730_LDO_VDDLDO2,
SC2730_LDO_VDDKPLED,
};
static const struct regulator_ops sc2730_regu_linear_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
#define SC2730_REGU_LINEAR(_id, of_name, en_reg, en_mask, vreg, vmask, \
vstep, vmin, vmax) { \
.name = #_id, \
.of_match = of_name, \
.regulators_node = "regulators", \
.ops = &sc2730_regu_linear_ops, \
.type = REGULATOR_VOLTAGE, \
.id = SC2730_##_id, \
.owner = THIS_MODULE, \
.min_uV = vmin, \
.n_voltages = ((vmax) - (vmin)) / (vstep) + 1, \
.uV_step = vstep, \
.enable_is_inverted = true, \
.enable_val = 0, \
.enable_reg = en_reg, \
.enable_mask = en_mask, \
.vsel_reg = vreg, \
.vsel_mask = vmask, \
.linear_min_sel = 0, \
}
static const struct regulator_desc regulators[] = {
SC2730_REGU_LINEAR(DCDC_CPU, "dcdc-cpu", SC2730_POWER_PD_SW,
SC2730_DCDC_CPU_PD_MASK, SC2730_DCDC_CPU_VOL,
SC2730_DCDC_CPU_VOL_MASK, 3125, 0, 1596875),
SC2730_REGU_LINEAR(DCDC_GPU, "dcdc-gpu", SC2730_POWER_PD_SW,
SC2730_DCDC_GPU_PD_MASK, SC2730_DCDC_GPU_VOL,
SC2730_DCDC_GPU_VOL_MASK, 3125, 0, 1596875),
SC2730_REGU_LINEAR(DCDC_CORE, "dcdc-core", SC2730_POWER_PD_SW,
SC2730_DCDC_CORE_PD_MASK, SC2730_DCDC_CORE_VOL,
SC2730_DCDC_CORE_VOL_MASK, 3125, 0, 1596875),
SC2730_REGU_LINEAR(DCDC_MODEM, "dcdc-modem", SC2730_POWER_PD_SW,
SC2730_DCDC_MODEM_PD_MASK, SC2730_DCDC_MODEM_VOL,
SC2730_DCDC_MODEM_VOL_MASK, 3125, 0, 1596875),
SC2730_REGU_LINEAR(DCDC_MEM, "dcdc-mem", SC2730_POWER_PD_SW,
SC2730_DCDC_MEM_PD_MASK, SC2730_DCDC_MEM_VOL,
SC2730_DCDC_MEM_VOL_MASK, 6250, 0, 1593750),
SC2730_REGU_LINEAR(DCDC_MEMQ, "dcdc-memq", SC2730_POWER_PD_SW,
SC2730_DCDC_MEMQ_PD_MASK, SC2730_DCDC_MEMQ_VOL,
SC2730_DCDC_MEMQ_VOL_MASK, 3125, 0, 1596875),
SC2730_REGU_LINEAR(DCDC_GEN0, "dcdc-gen0", SC2730_POWER_PD_SW,
SC2730_DCDC_GEN0_PD_MASK, SC2730_DCDC_GEN0_VOL,
SC2730_DCDC_GEN0_VOL_MASK, 9375, 20000, 2410625),
SC2730_REGU_LINEAR(DCDC_GEN1, "dcdc-gen1", SC2730_POWER_PD_SW,
SC2730_DCDC_GEN1_PD_MASK, SC2730_DCDC_GEN1_VOL,
SC2730_DCDC_GEN1_VOL_MASK, 6250, 50000, 1643750),
SC2730_REGU_LINEAR(DCDC_SRAM, "dcdc-sram", SC2730_POWER_PD_SW,
SC2730_DCDC_SRAM_PD_MASK, SC2730_DCDC_SRAM_VOL,
SC2730_DCDC_SRAM_VOL_MASK, 3125, 0, 1596875),
SC2730_REGU_LINEAR(LDO_AVDD18, "ldo-avdd18", SC2730_POWER_PD_SW,
SC2730_LDO_AVDD18_PD_MASK, SC2730_LDO_AVDD18_VOL,
SC2730_LDO_AVDD18_VOL_MASK, 10000, 1175000, 1805000),
SC2730_REGU_LINEAR(LDO_VDDRF18, "ldo-vddrf18", SC2730_LDO_VDDRF18_PD,
SC2730_LDO_VDDRF18_PD_MASK, SC2730_LDO_VDDRF18_VOL,
SC2730_LDO_VDDRF18_VOL_MASK, 10000, 1175000, 1805000),
SC2730_REGU_LINEAR(LDO_VDDCAMIO, "ldo-vddcamio", SC2730_LDO_VDDCAMIO_PD,
SC2730_LDO_VDDCAMIO_PD_MASK, SC2730_LDO_VDDCAMIO_VOL,
SC2730_LDO_VDDCAMIO_VOL_MASK, 10000, 1200000, 1830000),
SC2730_REGU_LINEAR(LDO_VDDWCN, "ldo-vddwcn", SC2730_LDO_VDDWCN_PD,
SC2730_LDO_VDDWCN_PD_MASK, SC2730_LDO_VDDWCN_VOL,
SC2730_LDO_VDDWCN_VOL_MASK, 15000, 900000, 1845000),
SC2730_REGU_LINEAR(LDO_VDDCAMD1, "ldo-vddcamd1", SC2730_LDO_VDDCAMD1_PD,
SC2730_LDO_VDDCAMD1_PD_MASK, SC2730_LDO_VDDCAMD1_VOL,
SC2730_LDO_VDDCAMD1_VOL_MASK, 15000, 900000, 1365000),
SC2730_REGU_LINEAR(LDO_VDDCAMD0, "ldo-vddcamd0", SC2730_LDO_VDDCAMD0_PD,
SC2730_LDO_VDDCAMD0_PD_MASK, SC2730_LDO_VDDCAMD0_VOL,
SC2730_LDO_VDDCAMD0_VOL_MASK, 15000, 900000, 1365000),
SC2730_REGU_LINEAR(LDO_VDDRF1V25, "ldo-vddrf1v25", SC2730_LDO_VDDRF1V25_PD,
SC2730_LDO_VDDRF1V25_PD_MASK, SC2730_LDO_VDDRF1V25_VOL,
SC2730_LDO_VDDRF1V25_VOL_MASK, 15000, 900000, 1365000),
SC2730_REGU_LINEAR(LDO_AVDD12, "ldo-avdd12", SC2730_LDO_AVDD12_PD,
SC2730_LDO_AVDD12_PD_MASK, SC2730_LDO_AVDD12_VOL,
SC2730_LDO_AVDD12_VOL_MASK, 15000, 900000, 1365000),
SC2730_REGU_LINEAR(LDO_VDDCAMA0, "ldo-vddcama0", SC2730_LDO_VDDCAMA0_PD,
SC2730_LDO_VDDCAMA0_PD_MASK, SC2730_LDO_VDDCAMA0_VOL,
SC2730_LDO_VDDCAMA0_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDCAMA1, "ldo-vddcama1", SC2730_LDO_VDDCAMA1_PD,
SC2730_LDO_VDDCAMA1_PD_MASK, SC2730_LDO_VDDCAMA1_VOL,
SC2730_LDO_VDDCAMA1_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDCAMMOT, "ldo-vddcammot", SC2730_LDO_VDDCAMMOT_PD,
SC2730_LDO_VDDCAMMOT_PD_MASK, SC2730_LDO_VDDCAMMOT_VOL,
SC2730_LDO_VDDCAMMOT_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDSIM2, "ldo-vddsim2", SC2730_LDO_VDDSIM2_PD,
SC2730_LDO_VDDSIM2_PD_MASK, SC2730_LDO_VDDSIM2_VOL,
SC2730_LDO_VDDSIM2_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDEMMCCORE, "ldo-vddemmccore", SC2730_LDO_VDDEMMCCORE_PD,
SC2730_LDO_VDDEMMCCORE_PD_MASK, SC2730_LDO_VDDEMMCCORE_VOL,
SC2730_LDO_VDDEMMCCORE_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDSDCORE, "ldo-vddsdcore", SC2730_LDO_VDDSDCORE_PD,
SC2730_LDO_VDDSDCORE_PD_MASK, SC2730_LDO_VDDSDCORE_VOL,
SC2730_LDO_VDDSDCORE_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDSDIO, "ldo-vddsdio", SC2730_LDO_VDDSDIO_PD,
SC2730_LDO_VDDSDIO_PD_MASK, SC2730_LDO_VDDSDIO_VOL,
SC2730_LDO_VDDSDIO_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDD28, "ldo-vdd28", SC2730_POWER_PD_SW,
SC2730_LDO_VDD28_PD_MASK, SC2730_LDO_VDD28_VOL,
SC2730_LDO_VDD28_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDWIFIPA, "ldo-vddwifipa", SC2730_LDO_VDDWIFIPA_PD,
SC2730_LDO_VDDWIFIPA_PD_MASK, SC2730_LDO_VDDWIFIPA_VOL,
SC2730_LDO_VDDWIFIPA_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDD18_DCXO, "ldo-vdd18-dcxo", SC2730_POWER_PD_SW,
SC2730_LDO_VDD18_DCXO_PD_MASK, SC2730_LDO_VDD18_DCXO_VOL,
SC2730_LDO_VDD18_DCXO_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDUSB33, "ldo-vddusb33", SC2730_LDO_VDDUSB33_PD,
SC2730_LDO_VDDUSB33_PD_MASK, SC2730_LDO_VDDUSB33_VOL,
SC2730_LDO_VDDUSB33_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDLDO0, "ldo-vddldo0", SC2730_LDO_VDDLDO0_PD,
SC2730_LDO_VDDLDO0_PD_MASK, SC2730_LDO_VDDLDO0_VOL,
SC2730_LDO_VDDLDO0_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDLDO1, "ldo-vddldo1", SC2730_LDO_VDDLDO1_PD,
SC2730_LDO_VDDLDO1_PD_MASK, SC2730_LDO_VDDLDO1_VOL,
SC2730_LDO_VDDLDO1_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDLDO2, "ldo-vddldo2", SC2730_LDO_VDDLDO2_PD,
SC2730_LDO_VDDLDO2_PD_MASK, SC2730_LDO_VDDLDO2_VOL,
SC2730_LDO_VDDLDO2_VOL_MASK, 10000, 1200000, 3750000),
SC2730_REGU_LINEAR(LDO_VDDKPLED, "ldo-vddkpled", SC2730_LDO_VDDKPLED_PD,
SC2730_LDO_VDDKPLED_PD_MASK, SC2730_LDO_VDDKPLED_VOL,
SC2730_LDO_VDDKPLED_VOL_MASK, 10000, 1200000, 3750000),
};
static int sc2730_regulator_unlock(struct regmap *regmap)
{
return regmap_write(regmap, SC2730_PWR_WR_PROT, SC2730_WR_UNLOCK_VALUE);
}
static int sc2730_regulator_probe(struct platform_device *pdev)
{
int i, ret;
struct regmap *regmap;
struct regulator_config config = { };
struct regulator_dev *rdev;
regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!regmap)
return dev_err_probe(&pdev->dev, -ENODEV, "failed to get regmap\n");
ret = sc2730_regulator_unlock(regmap);
if (ret)
return dev_err_probe(&pdev->dev, ret, "failed to release regulator lock\n");
config.dev = pdev->dev.parent;
config.regmap = regmap;
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
rdev = devm_regulator_register(&pdev->dev, &regulators[i], &config);
if (IS_ERR(rdev)) {
return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
"failed to register regulator %s\n",
regulators[i].name);
}
}
return 0;
}
static const struct platform_device_id sc2730_regulator_id_table[] = {
{ .name = "sc2730-regulator" },
{ }
};
MODULE_DEVICE_TABLE(platform, sc2730_regulator_id_table);
static struct platform_driver sc2730_regulator_driver = {
.driver = {
.name = "sc2730-regulator",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
.probe = sc2730_regulator_probe,
.id_table = sc2730_regulator_id_table,
};
module_platform_driver(sc2730_regulator_driver);
MODULE_AUTHOR("Zhongfa Wang <zhongfa.wang@unisoc.com>");
MODULE_DESCRIPTION("Spreadtrum SC2730 regulator driver");
MODULE_LICENSE("GPL");

View File

@ -285,7 +285,7 @@ static int sgm3804_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id sgm3804_id[] = {
{ "sgm3804" },
{ .name = "sgm3804" },
{ }
};
MODULE_DEVICE_TABLE(i2c, sgm3804_id);

View File

@ -497,8 +497,8 @@ static int slg51000_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id slg51000_i2c_id[] = {
{ "slg51000" },
{}
{ .name = "slg51000" },
{ }
};
MODULE_DEVICE_TABLE(i2c, slg51000_i2c_id);

View File

@ -130,7 +130,7 @@ static const struct of_device_id sy8106a_i2c_of_match[] = {
MODULE_DEVICE_TABLE(of, sy8106a_i2c_of_match);
static const struct i2c_device_id sy8106a_i2c_id[] = {
{ "sy8106a" },
{ .name = "sy8106a" },
{ }
};
MODULE_DEVICE_TABLE(i2c, sy8106a_i2c_id);

View File

@ -213,10 +213,10 @@ static const struct of_device_id sy8824_dt_ids[] = {
MODULE_DEVICE_TABLE(of, sy8824_dt_ids);
static const struct i2c_device_id sy8824_id[] = {
{ "sy8824c", (kernel_ulong_t)&sy8824c_cfg },
{ "sy8824e", (kernel_ulong_t)&sy8824e_cfg },
{ "sy20276", (kernel_ulong_t)&sy20276_cfg },
{ "sy20278", (kernel_ulong_t)&sy20278_cfg },
{ .name = "sy8824c", .driver_data = (kernel_ulong_t)&sy8824c_cfg },
{ .name = "sy8824e", .driver_data = (kernel_ulong_t)&sy8824e_cfg },
{ .name = "sy20276", .driver_data = (kernel_ulong_t)&sy20276_cfg },
{ .name = "sy20278", .driver_data = (kernel_ulong_t)&sy20278_cfg },
{ }
};
MODULE_DEVICE_TABLE(i2c, sy8824_id);

View File

@ -180,8 +180,8 @@ static const struct of_device_id sy8827n_dt_ids[] = {
MODULE_DEVICE_TABLE(of, sy8827n_dt_ids);
static const struct i2c_device_id sy8827n_id[] = {
{ "sy8827n", },
{ },
{ .name = "sy8827n" },
{ }
};
MODULE_DEVICE_TABLE(i2c, sy8827n_id);

View File

@ -331,8 +331,8 @@ static int tps51632_probe(struct i2c_client *client)
}
static const struct i2c_device_id tps51632_id[] = {
{.name = "tps51632",},
{},
{ .name = "tps51632" },
{ }
};
MODULE_DEVICE_TABLE(i2c, tps51632_id);

View File

@ -476,11 +476,11 @@ static void tps62360_shutdown(struct i2c_client *client)
}
static const struct i2c_device_id tps62360_id[] = {
{.name = "tps62360", .driver_data = TPS62360},
{.name = "tps62361", .driver_data = TPS62361},
{.name = "tps62362", .driver_data = TPS62362},
{.name = "tps62363", .driver_data = TPS62363},
{},
{ .name = "tps62360", .driver_data = TPS62360 },
{ .name = "tps62361", .driver_data = TPS62361 },
{ .name = "tps62362", .driver_data = TPS62362 },
{ .name = "tps62363", .driver_data = TPS62363 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tps62360_id);

View File

@ -145,11 +145,11 @@ static int tps6286x_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id tps6286x_i2c_id[] = {
{ "tps62864" },
{ "tps62866" },
{ "tps62868" },
{ "tps62869" },
{}
{ .name = "tps62864" },
{ .name = "tps62866" },
{ .name = "tps62868" },
{ .name = "tps62869" },
{ }
};
MODULE_DEVICE_TABLE(i2c, tps6286x_i2c_id);

View File

@ -228,11 +228,11 @@ static const struct of_device_id tps6287x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, tps6287x_dt_ids);
static const struct i2c_device_id tps6287x_i2c_id[] = {
{ "tps62870" },
{ "tps62871" },
{ "tps62872" },
{ "tps62873" },
{}
{ .name = "tps62870" },
{ .name = "tps62871" },
{ .name = "tps62872" },
{ .name = "tps62873" },
{ }
};
MODULE_DEVICE_TABLE(i2c, tps6287x_i2c_id);

View File

@ -319,13 +319,13 @@ MODULE_DEVICE_TABLE(of, tps65023_of_match);
static const struct i2c_device_id tps_65023_id[] = {
{
.name = "tps65023",
.driver_data = (kernel_ulong_t)&tps65023_drv_data
.driver_data = (kernel_ulong_t)&tps65023_drv_data,
}, {
.name = "tps65021",
.driver_data = (kernel_ulong_t)&tps65021_drv_data
.driver_data = (kernel_ulong_t)&tps65021_drv_data,
}, {
.name = "tps65020",
.driver_data = (kernel_ulong_t)&tps65020_drv_data
.driver_data = (kernel_ulong_t)&tps65020_drv_data,
},
{ },
};

View File

@ -262,8 +262,8 @@ static int tps65132_probe(struct i2c_client *client)
}
static const struct i2c_device_id tps65132_id[] = {
{.name = "tps65132",},
{},
{ .name = "tps65132" },
{ }
};
MODULE_DEVICE_TABLE(i2c, tps65132_id);

View File

@ -183,7 +183,10 @@ static int tps65185_vposneg_enable(struct regulator_dev *rdev)
wait_for_completion_timeout(&data->pgood_completion,
msecs_to_jiffies(PGOOD_TIMEOUT_MSECS));
dev_dbg(data->dev, "turned on");
if (gpiod_get_value_cansleep(data->pgood_gpio) != 1)
ret = gpiod_get_value_cansleep(data->pgood_gpio);
if (ret < 0)
return ret;
if (!ret)
return -ETIMEDOUT;
return 0;

View File

@ -669,13 +669,20 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
* buck_configured to avoid creating bucks for every buck in multiphase
*/
for (multi = 0; multi < desc->num_multi_phase_regs; multi++) {
struct device_node *np_parent;
multi_regs = &desc->multi_phase_regs[multi];
np = of_find_node_by_name(tps->dev->of_node, multi_regs->supply_name);
npname = of_node_full_name(np);
np_pmic_parent = of_get_parent(of_get_parent(np));
if (of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name))
if (!np)
continue;
if (strcmp(npname, multi_regs->supply_name) == 0) {
npname = of_node_full_name(np);
np_parent = of_get_parent(np);
np_pmic_parent = of_get_parent(np_parent);
if (np_pmic_parent &&
!of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name) &&
strcmp(npname, multi_regs->supply_name) == 0) {
switch (multi) {
case MULTI_BUCK12:
buck_multi[0] = true;
@ -706,6 +713,10 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
break;
}
}
of_node_put(np_pmic_parent);
of_node_put(np_parent);
of_node_put(np);
}
reg_irq_nb = desc->num_irq_types * (desc->num_buck_regs + desc->num_ldo_regs);

View File

@ -62,11 +62,7 @@ static int wm831x_isink_disable(struct regulator_dev *rdev)
if (ret < 0)
return ret;
ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ENA, 0);
if (ret < 0)
return ret;
return ret;
return wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ENA, 0);
}

View File

@ -443,6 +443,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
int i;
unsigned long irq_status;
const struct tcs_request *req;
u32 reg;
irq_status = readl_relaxed(drv->tcs_base + drv->regs[RSC_DRV_IRQ_STATUS]);
@ -453,6 +454,11 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
trace_rpmh_tx_done(drv, i, req);
if (req->is_read) {
reg = drv->regs[RSC_DRV_CMD_RESP_DATA];
req->cmds[0].data = read_tcs_reg(drv, reg, i);
}
/* Clear AMC trigger & enable modes and
* disable interrupt for this TCS
*/
@ -493,13 +499,15 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
const struct tcs_request *msg)
{
u32 msgid;
u32 cmd_msgid = CMD_MSGID_LEN | CMD_MSGID_WRITE;
u32 cmd_msgid = CMD_MSGID_LEN;
u32 cmd_enable = 0;
struct tcs_cmd *cmd;
int i, j;
/* Convert all commands to RR when the request has wait_for_compl set */
cmd_msgid |= msg->wait_for_compl ? CMD_MSGID_RESP_REQ : 0;
if (!msg->is_read)
cmd_msgid |= CMD_MSGID_WRITE;
for (i = 0, j = cmd_id; i < msg->num_cmds; i++, j++) {
cmd = &msg->cmds[i];
@ -513,7 +521,8 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid);
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr);
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data);
if (!msg->is_read)
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data);
trace_rpmh_send_msg(drv, tcs_id, msg->state, j, msgid, cmd);
}

View File

@ -175,6 +175,9 @@ static int __rpmh_write(const struct device *dev, enum rpmh_state state,
struct cache_req *req;
int i;
if (rpm_msg->msg.is_read)
goto send_data;
/* Cache the request in our store and link the payload */
for (i = 0; i < rpm_msg->msg.num_cmds; i++) {
req = cache_rpm_request(ctrlr, state, &rpm_msg->msg.cmds[i]);
@ -182,6 +185,7 @@ static int __rpmh_write(const struct device *dev, enum rpmh_state state,
return PTR_ERR(req);
}
send_data:
if (state == RPMH_ACTIVE_ONLY_STATE) {
ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg->msg);
} else {
@ -194,7 +198,7 @@ static int __rpmh_write(const struct device *dev, enum rpmh_state state,
}
static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n)
const struct tcs_cmd *cmd, u32 n, bool is_read)
{
if (!cmd || !n || n > MAX_RPMH_PAYLOAD)
return -EINVAL;
@ -204,10 +208,45 @@ static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
req->msg.state = state;
req->msg.cmds = req->cmd;
req->msg.num_cmds = n;
req->msg.is_read = is_read;
return 0;
}
/**
* rpmh_read: Read a resource value
*
* @dev: The device making the request
* @cmd: The payload having address of resource to read
*
* Reads the value for the resource address given in tcs_cmd->addr
* and returns the tcs_cmd->data filled with same.
*
* Context: May sleep. Do not call from atomic contexts.
*
* Return: 0 on success, negative errno on failure
*/
int rpmh_read(const struct device *dev, struct tcs_cmd *cmd)
{
DECLARE_COMPLETION_ONSTACK(compl);
DEFINE_RPMH_MSG_ONSTACK(dev, RPMH_ACTIVE_ONLY_STATE, &compl, rpm_msg);
int ret;
ret = __fill_rpmh_msg(&rpm_msg, RPMH_ACTIVE_ONLY_STATE, cmd, 1, true);
if (ret)
return ret;
ret = __rpmh_write(dev, RPMH_ACTIVE_ONLY_STATE, &rpm_msg);
if (ret)
return ret;
ret = wait_for_completion_timeout(&compl, RPMH_TIMEOUT_MS);
cmd[0].data = rpm_msg.cmd[0].data;
return (ret > 0) ? 0 : -ETIMEDOUT;
}
EXPORT_SYMBOL_GPL(rpmh_read);
/**
* rpmh_write_async: Write a set of RPMH commands
*
@ -230,7 +269,7 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state,
return -ENOMEM;
rpm_msg->needs_free = true;
ret = __fill_rpmh_msg(rpm_msg, state, cmd, n);
ret = __fill_rpmh_msg(rpm_msg, state, cmd, n, false);
if (ret) {
kfree(rpm_msg);
return ret;
@ -257,7 +296,7 @@ int rpmh_write(const struct device *dev, enum rpmh_state state,
DEFINE_RPMH_MSG_ONSTACK(dev, state, &compl, rpm_msg);
int ret;
ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n);
ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n, false);
if (ret)
return ret;
@ -352,7 +391,7 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
rpm_msgs = req->rpm_msgs;
for (i = 0; i < count; i++) {
__fill_rpmh_msg(rpm_msgs + i, state, cmd, n[i]);
__fill_rpmh_msg(rpm_msgs + i, state, cmd, n[i], false);
cmd += n[i];
}

View File

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (c) 2026 Arturia - All rights reserved.
*
* Device Tree binding constants for the FAN53555 PMIC regulator
*/
#ifndef _DT_BINDINGS_REGULATOR_FAN53555_H
#define _DT_BINDINGS_REGULATOR_FAN53555_H
/*
* Constants to specify regulator modes in device tree for SYR82X regulators
* FAN53555_REGULATOR_MODE_FORCE_PWM: Force fixed PWM mode
* FAN53555_REGULATOR_MODE_AUTO: Allow auto-PFM mode during light load
*/
#define FAN53555_REGULATOR_MODE_FORCE_PWM 1
#define FAN53555_REGULATOR_MODE_AUTO 2
#endif

View File

@ -350,6 +350,9 @@ enum max77836_pmic_reg {
#define MAX77836_CNFG1_LDO_PWRMD_SHIFT 6
#define MAX77836_CNFG1_LDO_TV_SHIFT 0
#define MAX77836_CNFG1_LDO_PWRMD_MASK (0x3 << MAX77836_CNFG1_LDO_PWRMD_SHIFT)
#define MAX77836_CNFG1_LDO_PWRMD_OFF (0x0 << MAX77836_CNFG1_LDO_PWRMD_SHIFT)
#define MAX77836_CNFG1_LDO_PWRMD_LPM (0x1 << MAX77836_CNFG1_LDO_PWRMD_SHIFT)
#define MAX77836_CNFG1_LDO_PWRMD_NORMAL (0x3 << MAX77836_CNFG1_LDO_PWRMD_SHIFT)
#define MAX77836_CNFG1_LDO_TV_MASK (0x3f << MAX77836_CNFG1_LDO_TV_SHIFT)
/* LDO1/LDO2 CONFIG2 register */

View File

@ -11,6 +11,8 @@
#if IS_ENABLED(CONFIG_QCOM_RPMH)
int rpmh_read(const struct device *dev, struct tcs_cmd *cmd);
int rpmh_write(const struct device *dev, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n);
@ -24,6 +26,9 @@ void rpmh_invalidate(const struct device *dev);
#else
static inline int rpmh_read(const struct device *dev, struct tcs_cmd *cmd)
{ return -ENODEV; }
static inline int rpmh_write(const struct device *dev, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n)
{ return -ENODEV; }

View File

@ -51,6 +51,7 @@ struct tcs_cmd {
* struct tcs_request: A set of tcs_cmds sent together in a TCS
*
* @state: state for the request.
* @is_read: set for read only requests
* @wait_for_compl: wait until we get a response from the h/w accelerator
* (same as setting cmd->wait for all commands in the request)
* @num_cmds: the number of @cmds in this request
@ -58,6 +59,7 @@ struct tcs_cmd {
*/
struct tcs_request {
enum rpmh_state state;
bool is_read;
u32 wait_for_compl;
u32 num_cmds;
struct tcs_cmd *cmds;