diff --git a/Documentation/devicetree/bindings/regulator/fcs,fan53555.yaml b/Documentation/devicetree/bindings/regulator/fcs,fan53555.yaml index 69bae90fc4b2..9a18891f721e 100644 --- a/Documentation/devicetree/bindings/regulator/fcs,fan53555.yaml +++ b/Documentation/devicetree/bindings/regulator/fcs,fan53555.yaml @@ -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 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 = ; }; }; ... diff --git a/Documentation/devicetree/bindings/regulator/lltc,ltc3589.yaml b/Documentation/devicetree/bindings/regulator/lltc,ltc3589.yaml new file mode 100644 index 000000000000..2c2755bb84eb --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/lltc,ltc3589.yaml @@ -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 + +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>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/ltc3589.txt b/Documentation/devicetree/bindings/regulator/ltc3589.txt deleted file mode 100644 index 801053036146..000000000000 --- a/Documentation/devicetree/bindings/regulator/ltc3589.txt +++ /dev/null @@ -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>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml index 894bdbca78a2..8ac77c1a9b9f 100644 --- a/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml @@ -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 { diff --git a/Documentation/devicetree/bindings/regulator/pbias-regulator.txt b/Documentation/devicetree/bindings/regulator/pbias-regulator.txt deleted file mode 100644 index acbcb452a69a..000000000000 --- a/Documentation/devicetree/bindings/regulator/pbias-regulator.txt +++ /dev/null @@ -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>; - }; diff --git a/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml index 40f9223d4c27..0bbf7c806fbc 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml @@ -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: diff --git a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml index fcefc722ee2a..024b34d0eb1a 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml @@ -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>; + }; + }; ... diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml index 022c1f197364..25b0865d4c04 100644 --- a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml +++ b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml @@ -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 { diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd71815-regulator.yaml b/Documentation/devicetree/bindings/regulator/rohm,bd71815-regulator.yaml index cc4ceb32e9d6..68b5e579e2d3 100644 --- a/Documentation/devicetree/bindings/regulator/rohm,bd71815-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/rohm,bd71815-regulator.yaml @@ -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 diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml b/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml index d898800d6bca..8cba397678a6 100644 --- a/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml @@ -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 diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.yaml b/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.yaml index 29b350a4f88a..efb38dd15145 100644 --- a/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.yaml @@ -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: # diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd71847-regulator.yaml b/Documentation/devicetree/bindings/regulator/rohm,bd71847-regulator.yaml index 7ba4ccf723d8..ef6f69be24ae 100644 --- a/Documentation/devicetree/bindings/regulator/rohm,bd71847-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/rohm,bd71847-regulator.yaml @@ -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: # diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd72720-regulator.yaml b/Documentation/devicetree/bindings/regulator/rohm,bd72720-regulator.yaml index 5518082129bd..76747bf2bbdd 100644 --- a/Documentation/devicetree/bindings/regulator/rohm,bd72720-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/rohm,bd72720-regulator.yaml @@ -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 diff --git a/Documentation/devicetree/bindings/regulator/rohm,pmic-states.yaml b/Documentation/devicetree/bindings/regulator/rohm,pmic-states.yaml new file mode 100644 index 000000000000..f09f021bdde4 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/rohm,pmic-states.yaml @@ -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 + +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 diff --git a/Documentation/devicetree/bindings/regulator/ti,pbias-omap.yaml b/Documentation/devicetree/bindings/regulator/ti,pbias-omap.yaml new file mode 100644 index 000000000000..4533f337963f --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/ti,pbias-omap.yaml @@ -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 + +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>; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/ti,tps51632.yaml b/Documentation/devicetree/bindings/regulator/ti,tps51632.yaml new file mode 100644 index 000000000000..130fa9796f57 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/ti,tps51632.yaml @@ -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 + +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; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/tps51632-regulator.txt b/Documentation/devicetree/bindings/regulator/tps51632-regulator.txt deleted file mode 100644 index 2f7e44a96414..000000000000 --- a/Documentation/devicetree/bindings/regulator/tps51632-regulator.txt +++ /dev/null @@ -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; - }; diff --git a/drivers/regulator/88pg86x.c b/drivers/regulator/88pg86x.c index e6598e74ec94..8c25a1db412f 100644 --- a/drivers/regulator/88pg86x.c +++ b/drivers/regulator/88pg86x.c @@ -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); diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index a54a549196fe..89789ac7a786 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -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 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 134eee274dbf..5a764cec8df8 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -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 diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 6b4a3a3d8385..3705c98b0713 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -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; diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index b2a6ddc6f56d..882b6e58e911 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -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); diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index eb2a666a45cb..0123ca8157a8 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c @@ -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); diff --git a/drivers/regulator/adp5055-regulator.c b/drivers/regulator/adp5055-regulator.c index 9ebd52b39235..194dcfe4f527 100644 --- a/drivers/regulator/adp5055-regulator.c +++ b/drivers/regulator/adp5055-regulator.c @@ -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); diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index da378bfdba40..85e2aaa1a06b 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c @@ -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); diff --git a/drivers/regulator/aw37503-regulator.c b/drivers/regulator/aw37503-regulator.c index a5ff6dfd29b5..ca5f2a14c28c 100644 --- a/drivers/regulator/aw37503-regulator.c +++ b/drivers/regulator/aw37503-regulator.c @@ -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); diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2e61606fc1d0..6a4008f387b5 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -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(®ulator_init_complete_work, - msecs_to_jiffies(30000)); + queue_delayed_work(system_freezable_wq, + ®ulator_init_complete_work, + msecs_to_jiffies(30000)); return 0; } diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c index 36a52f707602..f501cf8152c2 100644 --- a/drivers/regulator/da9121-regulator.c +++ b/drivers/regulator/da9121-regulator.c @@ -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); diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index 39ade0dba40f..9154e32bd745 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c @@ -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); diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index d4f14d7ea8cf..9cf713755636 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -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); diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index c282236959b1..6557d8cbe98d 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -21,6 +21,7 @@ #include #include #include +#include /* 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) { diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c index 6cb5656845f9..79ba705ec324 100644 --- a/drivers/regulator/fan53880.c +++ b/drivers/regulator/fan53880.c @@ -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); diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index 7883cd160727..868f2b823a10 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -138,7 +138,7 @@ static int isl6271a_probe(struct i2c_client *i2c) } static const struct i2c_device_id isl6271a_id[] = { - { .name = "isl6271a", }, + { .name = "isl6271a" }, { } }; diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c index 5a234f25e6bb..ec6bd6bb9721 100644 --- a/drivers/regulator/isl9305.c +++ b/drivers/regulator/isl9305.c @@ -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); diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index d4dab86fe385..6f830ae1bb61 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -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); diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c index 1b918fb72134..235c640ba57f 100644 --- a/drivers/regulator/lp3972.c +++ b/drivers/regulator/lp3972.c @@ -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); diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 942f37082cb1..5b2faddd8110 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -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); diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index 5509bee49bda..632320ba1800 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -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); diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index 3f70c2225dba..8bae5d8aeaf4 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -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)<c3589_info }, - { "ltc3589-1", (kernel_ulong_t)<c3589_12_info }, - { "ltc3589-2", (kernel_ulong_t)<c3589_12_info }, + { .name = "ltc3589", .driver_data = (kernel_ulong_t)<c3589_info }, + { .name = "ltc3589-1", .driver_data = (kernel_ulong_t)<c3589_12_info }, + { .name = "ltc3589-2", .driver_data = (kernel_ulong_t)<c3589_12_info }, { } }; MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id); diff --git a/drivers/regulator/ltc3676.c b/drivers/regulator/ltc3676.c index 768cdce0d4ec..307c6f7a155d 100644 --- a/drivers/regulator/ltc3676.c +++ b/drivers/regulator/ltc3676.c @@ -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); diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c index c9d8d5e31cbd..cd592c5de148 100644 --- a/drivers/regulator/max14577-regulator.c +++ b/drivers/regulator/max14577-regulator.c @@ -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); diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 4242fbb7b147..e5cbc09c2d39 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -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); diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c index fcdd2d0317a5..92594b2915f3 100644 --- a/drivers/regulator/max20086-regulator.c +++ b/drivers/regulator/max20086-regulator.c @@ -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); diff --git a/drivers/regulator/max20411-regulator.c b/drivers/regulator/max20411-regulator.c index 6c0ebb970e90..ac7a9aa014aa 100644 --- a/drivers/regulator/max20411-regulator.c +++ b/drivers/regulator/max20411-regulator.c @@ -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); diff --git a/drivers/regulator/max77503-regulator.c b/drivers/regulator/max77503-regulator.c index c7c94e868fc1..1cae846f96d0 100644 --- a/drivers/regulator/max77503-regulator.c +++ b/drivers/regulator/max77503-regulator.c @@ -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" }, { } }; diff --git a/drivers/regulator/max77675-regulator.c b/drivers/regulator/max77675-regulator.c index fad0844f364e..23b54b44f8b7 100644 --- a/drivers/regulator/max77675-regulator.c +++ b/drivers/regulator/max77675-regulator.c @@ -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); diff --git a/drivers/regulator/max77826-regulator.c b/drivers/regulator/max77826-regulator.c index 310bc8ee7af8..8b60a9fcab44 100644 --- a/drivers/regulator/max77826-regulator.c +++ b/drivers/regulator/max77826-regulator.c @@ -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); diff --git a/drivers/regulator/max77838-regulator.c b/drivers/regulator/max77838-regulator.c index 9faddbfd25fd..765756fdcf6e 100644 --- a/drivers/regulator/max77838-regulator.c +++ b/drivers/regulator/max77838-regulator.c @@ -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); diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c index 1216cc3a6f72..f1410f845653 100644 --- a/drivers/regulator/max77857-regulator.c +++ b/drivers/regulator/max77857-regulator.c @@ -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); diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index f57c588bcf28..2d17405242e7 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -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); diff --git a/drivers/regulator/max8893.c b/drivers/regulator/max8893.c index 5a90633d8536..7a0e44a16d49 100644 --- a/drivers/regulator/max8893.c +++ b/drivers/regulator/max8893.c @@ -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); diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index 1f94315bfb02..f8b91a5701f3 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -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); diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index f68caa07f546..95062032dc7e 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c @@ -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); diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index cc85fbe8b77c..90651f4d1828 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -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"); diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c index b34ae0bbba6f..07c67ad1ab7f 100644 --- a/drivers/regulator/mcp16502.c +++ b/drivers/regulator/mcp16502.c @@ -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); diff --git a/drivers/regulator/mp5416.c b/drivers/regulator/mp5416.c index e6794190cb68..2948635b1b9f 100644 --- a/drivers/regulator/mp5416.c +++ b/drivers/regulator/mp5416.c @@ -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); diff --git a/drivers/regulator/mp8859.c b/drivers/regulator/mp8859.c index ab105ffd6a2e..9a708e826d93 100644 --- a/drivers/regulator/mp8859.c +++ b/drivers/regulator/mp8859.c @@ -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); diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c index 9ad16b04c913..e0b62bc02a1e 100644 --- a/drivers/regulator/mp886x.c +++ b/drivers/regulator/mp886x.c @@ -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); diff --git a/drivers/regulator/mpq7920.c b/drivers/regulator/mpq7920.c index a670e09891e7..0cbc17deb1d1 100644 --- a/drivers/regulator/mpq7920.c +++ b/drivers/regulator/mpq7920.c @@ -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); diff --git a/drivers/regulator/mt6311-regulator.c b/drivers/regulator/mt6311-regulator.c index 2ebc1c0b5e6f..1d457d1fdf23 100644 --- a/drivers/regulator/mt6311-regulator.c +++ b/drivers/regulator/mt6311-regulator.c @@ -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); diff --git a/drivers/regulator/pf530x-regulator.c b/drivers/regulator/pf530x-regulator.c index f789c4b6a499..8ad1cbbd7a8c 100644 --- a/drivers/regulator/pf530x-regulator.c +++ b/drivers/regulator/pf530x-regulator.c @@ -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); diff --git a/drivers/regulator/pf8x00-regulator.c b/drivers/regulator/pf8x00-regulator.c index ea3611de42b4..c938b4632ef1 100644 --- a/drivers/regulator/pf8x00-regulator.c +++ b/drivers/regulator/pf8x00-regulator.c @@ -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); diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index 7d56c22b5e40..d3a0e2505524 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -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 = { diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c index ae1c4b9daaa1..375d9e759c47 100644 --- a/drivers/regulator/pv88060-regulator.c +++ b/drivers/regulator/pv88060-regulator.c @@ -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); diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c index 112eb1c73647..b96afbf11ff3 100644 --- a/drivers/regulator/pv88080-regulator.c +++ b/drivers/regulator/pv88080-regulator.c @@ -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); diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c index 3c48757bbbda..ca5eeb5dfe62 100644 --- a/drivers/regulator/pv88090-regulator.c +++ b/drivers/regulator/pv88090-regulator.c @@ -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); diff --git a/drivers/regulator/qcom-refgen-regulator.c b/drivers/regulator/qcom-refgen-regulator.c index 299ac3c8c3bc..cc72e5a43ba6 100644 --- a/drivers/regulator/qcom-refgen-regulator.c +++ b/drivers/regulator/qcom-refgen-regulator.c @@ -3,6 +3,7 @@ // Copyright (c) 2023, Linaro Limited #include +#include #include #include #include @@ -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); diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index 73856e3df337..25c14de3cd8b 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -4,6 +4,7 @@ #define pr_fmt(fmt) "%s: " fmt, __func__ +#include #include #include #include @@ -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; diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c index cd94ed67621f..9aea68876284 100644 --- a/drivers/regulator/qcom_usb_vbus-regulator.c +++ b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -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); diff --git a/drivers/regulator/rt6245-regulator.c b/drivers/regulator/rt6245-regulator.c index 1843ecec1922..5c0ee04e97ac 100644 --- a/drivers/regulator/rt6245-regulator.c +++ b/drivers/regulator/rt6245-regulator.c @@ -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; diff --git a/drivers/regulator/rtq2208-regulator.c b/drivers/regulator/rtq2208-regulator.c index 4fe111aa018f..b4eb5d3eb5bd 100644 --- a/drivers/regulator/rtq2208-regulator.c +++ b/drivers/regulator/rtq2208-regulator.c @@ -11,6 +11,7 @@ #include /* 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]; diff --git a/drivers/regulator/sc2730-regulator.c b/drivers/regulator/sc2730-regulator.c new file mode 100644 index 000000000000..166b19ed539b --- /dev/null +++ b/drivers/regulator/sc2730-regulator.c @@ -0,0 +1,375 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018-2021 Unisoc Inc. + */ + +#include +#include +#include +#include +#include +#include + +/* + * 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, ®ulators[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 "); +MODULE_DESCRIPTION("Spreadtrum SC2730 regulator driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/sgm3804-regulator.c b/drivers/regulator/sgm3804-regulator.c index c3406cfb73d0..a34c9418b275 100644 --- a/drivers/regulator/sgm3804-regulator.c +++ b/drivers/regulator/sgm3804-regulator.c @@ -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); diff --git a/drivers/regulator/slg51000-regulator.c b/drivers/regulator/slg51000-regulator.c index 3bbd4a29e6d3..d682764cdbf8 100644 --- a/drivers/regulator/slg51000-regulator.c +++ b/drivers/regulator/slg51000-regulator.c @@ -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); diff --git a/drivers/regulator/sy8106a-regulator.c b/drivers/regulator/sy8106a-regulator.c index d79a4cc25a0d..b2b835c60262 100644 --- a/drivers/regulator/sy8106a-regulator.c +++ b/drivers/regulator/sy8106a-regulator.c @@ -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); diff --git a/drivers/regulator/sy8824x.c b/drivers/regulator/sy8824x.c index 5bec84db25f1..3f07e7da90cb 100644 --- a/drivers/regulator/sy8824x.c +++ b/drivers/regulator/sy8824x.c @@ -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); diff --git a/drivers/regulator/sy8827n.c b/drivers/regulator/sy8827n.c index 0b811514782f..a1cac8cc3d96 100644 --- a/drivers/regulator/sy8827n.c +++ b/drivers/regulator/sy8827n.c @@ -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); diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index 3a384bf9d2c5..8459b49ec26e 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -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); diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index be6a6702cbfa..00f19082c1da 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -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); diff --git a/drivers/regulator/tps6286x-regulator.c b/drivers/regulator/tps6286x-regulator.c index e29aab06bf79..1ab53bee9f6e 100644 --- a/drivers/regulator/tps6286x-regulator.c +++ b/drivers/regulator/tps6286x-regulator.c @@ -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); diff --git a/drivers/regulator/tps6287x-regulator.c b/drivers/regulator/tps6287x-regulator.c index 9df104cb6bd2..e6403398facc 100644 --- a/drivers/regulator/tps6287x-regulator.c +++ b/drivers/regulator/tps6287x-regulator.c @@ -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); diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 3334b5b7d907..5a2fc57cddf6 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -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, }, { }, }; diff --git a/drivers/regulator/tps65132-regulator.c b/drivers/regulator/tps65132-regulator.c index 9c2f0dd42613..fecda3fd8ebc 100644 --- a/drivers/regulator/tps65132-regulator.c +++ b/drivers/regulator/tps65132-regulator.c @@ -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); diff --git a/drivers/regulator/tps65185.c b/drivers/regulator/tps65185.c index 786622d8d598..1f13e4156cab 100644 --- a/drivers/regulator/tps65185.c +++ b/drivers/regulator/tps65185.c @@ -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; diff --git a/drivers/regulator/tps6594-regulator.c b/drivers/regulator/tps6594-regulator.c index 645e83462c64..31a5218d5510 100644 --- a/drivers/regulator/tps6594-regulator.c +++ b/drivers/regulator/tps6594-regulator.c @@ -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); diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 43f220cea21c..b46e2cde5e9d 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -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); } diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 66928ca40b9a..f881af35ecfc 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -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); } diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index ca37da3dc2b1..f881c4c757ec 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -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]; } diff --git a/include/dt-bindings/regulator/fcs,fan53555-regulator.h b/include/dt-bindings/regulator/fcs,fan53555-regulator.h new file mode 100644 index 000000000000..ce3d6c63a0f1 --- /dev/null +++ b/include/dt-bindings/regulator/fcs,fan53555-regulator.h @@ -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 diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h index dd51a37fa37f..5957e15b568e 100644 --- a/include/linux/mfd/max14577-private.h +++ b/include/linux/mfd/max14577-private.h @@ -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 */ diff --git a/include/soc/qcom/rpmh.h b/include/soc/qcom/rpmh.h index bdbee1a97d36..14ecbf242b6b 100644 --- a/include/soc/qcom/rpmh.h +++ b/include/soc/qcom/rpmh.h @@ -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; } diff --git a/include/soc/qcom/tcs.h b/include/soc/qcom/tcs.h index cff67ce25488..45b8513be2f9 100644 --- a/include/soc/qcom/tcs.h +++ b/include/soc/qcom/tcs.h @@ -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;