Commit c5589c43 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull regulator updates from Mark Brown:
 "Quite a quiet release for regulator, the diffstat is dominated by the
  I2C migration to probe_new() and the newly added MT6357 driver. We've
  just one framework addition and the rest is all new device support,
  fixes and cleanups.

  The framework addition is an API for requesting all regulators defined
  in DT, this isn't great practice but has reasonable applications when
  there is generic code handling devices on buses where the bus
  specification doesn't include power. The immediate application is MDIO
  but I believe there's others, it's another API that'll need an eye
  keeping on it for undesirable usage.

  Summary:

    - An API for requesting all regulators defined in DT

    - Conversion of lots of drivers to the I2C probe_new() API

    - Support for Mediatek MT6357, Qualcomm PM8550, PMR735a and Richtek
      RT6190"

* tag 'regulator-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (56 commits)
  regulator: core: Use different devices for resource allocation and DT lookup
  dt-bindings: Add missing 'unevaluatedProperties' to regulator nodes
  regulator: qcom-labibb: Fix missing of_node_put() in qcom_labibb_regulator_probe()
  regulator: add mt6357 regulator
  regulator: dt-bindings: Add binding schema for mt6357 regulators
  regulator: core: fix resource leak in regulator_register()
  regulator: core: fix module refcount leak in set_supply()
  regulator: core: fix use_count leakage when handling boot-on
  regulator: rk808: Use dev_err_probe
  regulator: rk808: reduce 'struct rk808' usage
  regulator: Drop obsolete dependencies on COMPILE_TEST
  regulator: pv88080-regulator: Convert to i2c's .probe_new()
  regulator: pfuze100-regulator: Convert to i2c's .probe_new()
  regulator: isl6271a-regulator: Convert to i2c's .probe_new()
  regulator: fan53555: Convert to i2c's .probe_new()
  regulator: act8865-regulator: Convert to i2c's .probe_new()
  regulator: qcom-rpmh: Add support for PM8550 regulators
  regulator: dt-bindings: qcom,rpmh: Add compatible for PM8550
  regulator: tps65023-regulator: Convert to i2c's .probe_new()
  regulator: tps62360-regulator: Convert to i2c's .probe_new()
  ...
parents b8cc9174 8f3cbcd6
......@@ -100,14 +100,12 @@ examples:
compatible = "maxim,max77650-regulator";
max77650_ldo: regulator-ldo {
regulator-compatible = "ldo";
regulator-name = "max77650-ldo";
regulator-min-microvolt = <1350000>;
regulator-max-microvolt = <2937500>;
};
max77650_sbb0: regulator-sbb0 {
regulator-compatible = "sbb0";
regulator-name = "max77650-sbb0";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1587500>;
......
......@@ -83,7 +83,6 @@ examples:
richtek,vinovp-microvolt = <14500000>;
otg_vbus_regulator: usb-otg-vbus-regulator {
regulator-compatible = "usb-otg-vbus";
regulator-name = "usb-otg-vbus";
regulator-min-microvolt = <4425000>;
regulator-max-microvolt = <5825000>;
......@@ -145,7 +144,6 @@ examples:
compatible = "mediatek,mt6360-regulator";
LDO_VIN3-supply = <&BUCK2>;
buck1 {
regulator-compatible = "BUCK1";
regulator-name = "mt6360,buck1";
regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1300000>;
......@@ -154,7 +152,6 @@ examples:
MT6360_OPMODE_ULP>;
};
BUCK2: buck2 {
regulator-compatible = "BUCK2";
regulator-name = "mt6360,buck2";
regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1300000>;
......@@ -163,7 +160,6 @@ examples:
MT6360_OPMODE_ULP>;
};
ldo6 {
regulator-compatible = "LDO6";
regulator-name = "mt6360,ldo6";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2100000>;
......@@ -171,7 +167,6 @@ examples:
MT6360_OPMODE_LP>;
};
ldo7 {
regulator-compatible = "LDO7";
regulator-name = "mt6360,ldo7";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2100000>;
......@@ -179,7 +174,6 @@ examples:
MT6360_OPMODE_LP>;
};
ldo1 {
regulator-compatible = "LDO1";
regulator-name = "mt6360,ldo1";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
......@@ -187,7 +181,6 @@ examples:
MT6360_OPMODE_LP>;
};
ldo2 {
regulator-compatible = "LDO2";
regulator-name = "mt6360,ldo2";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
......@@ -195,7 +188,6 @@ examples:
MT6360_OPMODE_LP>;
};
ldo3 {
regulator-compatible = "LDO3";
regulator-name = "mt6360,ldo3";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
......@@ -203,7 +195,6 @@ examples:
MT6360_OPMODE_LP>;
};
ldo5 {
regulator-compatible = "LDO5";
regulator-name = "mt6360,ldo5";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3600000>;
......
......@@ -26,6 +26,7 @@ properties:
type: object
description: OTG boost regulator.
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
required:
- compatible
......@@ -39,7 +40,6 @@ examples:
richtek,vinovp-microvolt = <14500000>;
otg_vbus_regulator: usb-otg-vbus-regulator {
regulator-compatible = "usb-otg-vbus";
regulator-name = "usb-otg-vbus";
regulator-min-microvolt = <4425000>;
regulator-max-microvolt = <5825000>;
......
......@@ -26,6 +26,7 @@ properties:
patternProperties:
"^regulator-(ldo|sbb[0-2])$":
$ref: "regulator.yaml#"
unevaluatedProperties: false
required:
- compatible
......
......@@ -26,6 +26,7 @@ properties:
patternProperties:
"regulator-.+":
$ref: "regulator.yaml#"
unevaluatedProperties: false
additionalProperties: false
......@@ -43,31 +44,26 @@ examples:
regulators {
regulator-V3 {
regulator-compatible= "V3(DCDC)";
regulator-min-microvolt = <725000>;
regulator-max-microvolt = <1800000>;
};
regulator-V4 {
regulator-compatible= "V4(DCDC)";
regulator-min-microvolt = <725000>;
regulator-max-microvolt = <1800000>;
};
regulator-V5 {
regulator-compatible= "V5(LDO)";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <2000000>;
};
regulator-V6 {
regulator-compatible= "V6(LDO)";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
};
regulator-V7 {
regulator-compatible= "V7(LDO)";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
};
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/mediatek,mt6357-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek MT6357 Regulators
maintainers:
- Chen Zhong <chen.zhong@mediatek.com>
- Fabien Parent <fabien.parent@linaro.org>
- Alexandre Mergnat <amergnat@baylibre.com>
description: |
The MT6357 PMIC provides 5 BUCK and 29 LDO.
Regulators and nodes are named according to the regulator type:
- buck-<name>
- ldo-<name>.
MT6357 regulators node should be sub node of the MT6397 MFD node.
patternProperties:
"^buck-v(core|modem|pa|proc|s1)$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for single BUCK regulator.
required:
- regulator-name
- regulator-min-microvolt
- regulator-max-microvolt
"^ldo-v(camio18|aud28|aux18|io18|io28|rf12|rf18|cn18|cn28|fe28)$":
type: object
$ref: fixed-regulator.yaml#
unevaluatedProperties: false
description:
Properties for single fixed LDO regulator.
required:
- regulator-name
- regulator-min-microvolt
- regulator-max-microvolt
"^ldo-v(efuse|ibr|ldo28|mch|cama|camd|cn33-bt|cn33-wifi)$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for single LDO regulator.
required:
- regulator-name
- regulator-min-microvolt
- regulator-max-microvolt
"^ldo-v(xo22|emc|mc|sim1|sim2|sram-others|sram-proc|dram|usb33)$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for single LDO regulator.
required:
- regulator-name
- regulator-min-microvolt
- regulator-max-microvolt
additionalProperties: false
examples:
- |
pmic {
regulators {
mt6357_vproc_reg: buck-vproc {
regulator-name = "vproc";
regulator-min-microvolt = <518750>;
regulator-max-microvolt = <1312500>;
regulator-ramp-delay = <6250>;
regulator-enable-ramp-delay = <220>;
regulator-always-on;
};
mt6357_vcore_reg: buck-vcore {
regulator-name = "vcore";
regulator-min-microvolt = <518750>;
regulator-max-microvolt = <1312500>;
regulator-ramp-delay = <6250>;
regulator-enable-ramp-delay = <220>;
regulator-always-on;
};
mt6357_vmodem_reg: buck-vmodem {
regulator-name = "vmodem";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1193750>;
regulator-ramp-delay = <6250>;
regulator-enable-ramp-delay = <220>;
};
mt6357_vs1_reg: buck-vs1 {
regulator-name = "vs1";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <2200000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <220>;
regulator-always-on;
};
mt6357_vpa_reg: buck-vpa {
regulator-name = "vpa";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <3650000>;
regulator-ramp-delay = <50000>;
regulator-enable-ramp-delay = <220>;
};
mt6357_vfe28_reg: ldo-vfe28 {
compatible = "regulator-fixed";
regulator-name = "vfe28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vxo22_reg: ldo-vxo22 {
regulator-name = "vxo22";
regulator-min-microvolt = <2200000>;
regulator-max-microvolt = <2400000>;
regulator-enable-ramp-delay = <110>;
};
mt6357_vrf18_reg: ldo-vrf18 {
compatible = "regulator-fixed";
regulator-name = "vrf18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <110>;
};
mt6357_vrf12_reg: ldo-vrf12 {
compatible = "regulator-fixed";
regulator-name = "vrf12";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-enable-ramp-delay = <110>;
};
mt6357_vefuse_reg: ldo-vefuse {
regulator-name = "vefuse";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vcn33_bt_reg: ldo-vcn33-bt {
regulator-name = "vcn33-bt";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3500000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vcn33_wifi_reg: ldo-vcn33-wifi {
regulator-name = "vcn33-wifi";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3500000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vcn28_reg: ldo-vcn28 {
compatible = "regulator-fixed";
regulator-name = "vcn28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vcn18_reg: ldo-vcn18 {
compatible = "regulator-fixed";
regulator-name = "vcn18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vcama_reg: ldo-vcama {
regulator-name = "vcama";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vcamd_reg: ldo-vcamd {
regulator-name = "vcamd";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vcamio_reg: ldo-vcamio18 {
compatible = "regulator-fixed";
regulator-name = "vcamio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vldo28_reg: ldo-vldo28 {
regulator-name = "vldo28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3000000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vsram_others_reg: ldo-vsram-others {
regulator-name = "vsram-others";
regulator-min-microvolt = <518750>;
regulator-max-microvolt = <1312500>;
regulator-ramp-delay = <6250>;
regulator-enable-ramp-delay = <110>;
regulator-always-on;
};
mt6357_vsram_proc_reg: ldo-vsram-proc {
regulator-name = "vsram-proc";
regulator-min-microvolt = <518750>;
regulator-max-microvolt = <1312500>;
regulator-ramp-delay = <6250>;
regulator-enable-ramp-delay = <110>;
regulator-always-on;
};
mt6357_vaux18_reg: ldo-vaux18 {
compatible = "regulator-fixed";
regulator-name = "vaux18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vaud28_reg: ldo-vaud28 {
compatible = "regulator-fixed";
regulator-name = "vaud28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vio28_reg: ldo-vio28 {
compatible = "regulator-fixed";
regulator-name = "vio28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vio18_reg: ldo-vio18 {
compatible = "regulator-fixed";
regulator-name = "vio18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <264>;
regulator-always-on;
};
mt6357_vdram_reg: ldo-vdram {
regulator-name = "vdram";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1200000>;
regulator-enable-ramp-delay = <3300>;
};
mt6357_vmc_reg: ldo-vmc {
regulator-name = "vmc";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <44>;
};
mt6357_vmch_reg: ldo-vmch {
regulator-name = "vmch";
regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <44>;
};
mt6357_vemc_reg: ldo-vemc {
regulator-name = "vemc";
regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <44>;
regulator-always-on;
};
mt6357_vsim1_reg: ldo-vsim1 {
regulator-name = "vsim1";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <3100000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vsim2_reg: ldo-vsim2 {
regulator-name = "vsim2";
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <3100000>;
regulator-enable-ramp-delay = <264>;
};
mt6357_vibr_reg: ldo-vibr {
regulator-name = "vibr";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <44>;
};
mt6357_vusb33_reg: ldo-vusb33 {
regulator-name = "vusb33";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3100000>;
regulator-enable-ramp-delay = <264>;
};
};
};
...
......@@ -27,9 +27,11 @@ properties:
patternProperties:
"^buck[12]$":
$ref: "regulator.yaml#"
unevaluatedProperties: false
"^ldo[123567]$":
$ref: "regulator.yaml#"
unevaluatedProperties: false
required:
- compatible
......@@ -44,7 +46,6 @@ examples:
compatible = "mediatek,mt6360-regulator";
LDO_VIN3-supply = <&BUCK2>;
buck1 {
regulator-compatible = "BUCK1";
regulator-name = "mt6360,buck1";
regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1300000>;
......@@ -53,7 +54,6 @@ examples:
MT6360_OPMODE_ULP>;
};
BUCK2: buck2 {
regulator-compatible = "BUCK2";
regulator-name = "mt6360,buck2";
regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1300000>;
......@@ -62,7 +62,6 @@ examples:
MT6360_OPMODE_ULP>;
};
ldo6 {
regulator-compatible = "LDO6";
regulator-name = "mt6360,ldo6";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2100000>;
......@@ -70,7 +69,6 @@ examples:
MT6360_OPMODE_LP>;
};
ldo7 {
regulator-compatible = "LDO7";
regulator-name = "mt6360,ldo7";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2100000>;
......@@ -78,15 +76,13 @@ examples:
MT6360_OPMODE_LP>;
};
ldo1 {
regulator-compatible = "LDO1";
regulator-name = "mt6360,ldo1";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
regulator-allowed-modes = <MT6360_OPMODE_NORMAL
MT6360_OPMODE_LP>;
};
ldo2 {
regulator-compatible = "LDO2";
ldo2 {
regulator-name = "mt6360,ldo2";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
......@@ -94,7 +90,6 @@ examples:
MT6360_OPMODE_LP>;
};
ldo3 {
regulator-compatible = "LDO3";
regulator-name = "mt6360,ldo3";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
......@@ -102,7 +97,6 @@ examples:
MT6360_OPMODE_LP>;
};
ldo5 {
regulator-compatible = "LDO5";
regulator-name = "mt6360,ldo5";
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3600000>;
......
......@@ -47,6 +47,7 @@ description: |
For PM8350, smps1 - smps12, ldo1 - ldo10
For PM8350C, smps1 - smps10, ldo1 - ldo13, bob
For PM8450, smps1 - smps6, ldo1 - ldo4
For PM8550, smps1 - smps6, ldo1 - ldo17, bob1 - bob2
For PM8998, smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
For PMI8998, bob
For PMR735A, smps1 - smps3, ldo1 - ldo7
......@@ -70,6 +71,9 @@ properties:
- qcom,pm8350-rpmh-regulators
- qcom,pm8350c-rpmh-regulators
- qcom,pm8450-rpmh-regulators
- qcom,pm8550-rpmh-regulators
- qcom,pm8550ve-rpmh-regulators
- qcom,pm8550vs-rpmh-regulators
- qcom,pm8998-rpmh-regulators
- qcom,pmg1110-rpmh-regulators
- qcom,pmi8998-rpmh-regulators
......@@ -83,7 +87,7 @@ properties:
RPMh resource name suffix used for the regulators found
on this PMIC.
$ref: /schemas/types.yaml#/definitions/string
enum: [a, b, c, d, e, f, h, k]
enum: [a, b, c, d, e, f, g, h, k]
qcom,always-wait-for-ack:
description: |
......@@ -107,7 +111,7 @@ properties:
regulator-allow-set-load: ["regulator-allowed-modes"]
patternProperties:
"^(smps|ldo|lvs)[0-9]+$":
"^(smps|ldo|lvs|bob)[0-9]+$":
type: object
$ref: "regulator.yaml#"
description: smps/ldo regulator nodes(s).
......@@ -299,6 +303,24 @@ allOf:
"^vdd-l[1-4]-supply$": true
"^vdd-s[1-6]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pm8550-rpmh-regulators
- qcom,pm8550ve-rpmh-regulators
- qcom,pm8550vs-rpmh-regulators
then:
properties:
vdd-l2-l13-l14-supply: true
vdd-l5-l16-supply: true
vdd-l6-l7-supply: true
vdd-l8-l9-supply: true
patternProperties:
"^vdd-l([1-4]|1[0-7])-supply$": true
"^vdd-s[1-6]-supply$": true
"^vdd-bob[1-2]-supply$": true
- if:
properties:
compatible:
......@@ -412,9 +434,8 @@ examples:
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
regulator-allowed-modes =
<RPMH_REGULATOR_MODE_LPM
RPMH_REGULATOR_MODE_HPM>;
regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
RPMH_REGULATOR_MODE_HPM>;
regulator-allow-set-load;
};
......@@ -431,9 +452,8 @@ examples:
bob {
regulator-min-microvolt = <3312000>;
regulator-max-microvolt = <3600000>;
regulator-allowed-modes =
<RPMH_REGULATOR_MODE_AUTO
RPMH_REGULATOR_MODE_HPM>;
regulator-allowed-modes = <RPMH_REGULATOR_MODE_AUTO
RPMH_REGULATOR_MODE_HPM>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
};
};
......
......@@ -71,6 +71,8 @@ description:
For pmi8998, bob
For pmr735a, s1, s2, s3, l1, l2, l3, l4, l5, l6, l7
For pms405, s1, s2, s3, s4, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
l12, l13
......@@ -98,6 +100,7 @@ properties:
- qcom,rpm-pma8084-regulators
- qcom,rpm-pmi8994-regulators
- qcom,rpm-pmi8998-regulators
- qcom,rpm-pmr735a-regulators
- qcom,rpm-pms405-regulators
patternProperties:
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/regulator-output.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Regulator output connector
maintainers:
- Zev Weiss <zev@bewilderbeest.net>
description: |
This describes a power output connector supplied by a regulator,
such as a power outlet on a power distribution unit (PDU). The
connector may be standalone or merely one channel or set of pins
within a ganged physical connector carrying multiple independent
power outputs.
properties:
compatible:
const: regulator-output
vout-supply:
description:
Phandle of the regulator supplying the output.
required:
- compatible
- vout-supply
additionalProperties: false
examples:
- |
output {
compatible = "regulator-output";
vout-supply = <&output_reg>;
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/richtek,rt6190.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Richtek RT6190 4-Switch BuckBoost controller
maintainers:
- ChiYuan Huang <cy_huang@richtek.com>
description: |
The RT6190 is 4-Switch BuckBoost controller designed for converting input
voltage to output voltage that can be equal to, higher or lower than input
voltage. It operates with wide input voltage range from 4.5V to 36V, and
the output voltage can be set from 3V to 36V by external FB pin. It's commonly
used for the application like as BuckBoost bus supply, docking station and USB
power delivery product.
Datasheet is available at
https://www.richtek.com/assets/product_file/RT6190/DS6190-02.pdf
allOf:
- $ref: regulator.yaml#
properties:
compatible:
enum:
- richtek,rt6190
reg:
maxItems: 1
enable-gpios:
maxItems: 1
wakeup-source: true
interrupts:
maxItems: 1
regulator-allowed-modes:
description: |
buck allowed operating mode
0: PSM mode (light load Power Saving Mode)
1: FCCM mode (Forced-CCM mode)
maxItems: 2
items:
enum: [0, 1]
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
regulator@2c {
compatible = "richtek,rt6190";
reg = <0x2c>;
wakeup-source;
interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;
enable-gpios = <&gpio26 1 GPIO_ACTIVE_HIGH>;
regulator-name = "richtek,rt6190-buckboost";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <32000000>;
regulator-min-microamp = <306000>;
regulator-max-microamp = <12114000>;
regulator-allowed-modes = <0 1>;
};
};
......@@ -417,6 +417,7 @@ PWM
REGULATOR
devm_regulator_bulk_register_supply_alias()
devm_regulator_bulk_get()
devm_regulator_bulk_get_const()
devm_regulator_bulk_get_enable()
devm_regulator_bulk_put()
devm_regulator_get()
......
......@@ -185,7 +185,8 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
cfg.init_data = &init_data;
cfg.ena_gpiod = int3472->regulator.gpio;
int3472->regulator.rdev = regulator_register(&int3472->regulator.rdesc,
int3472->regulator.rdev = regulator_register(int3472->dev,
&int3472->regulator.rdesc,
&cfg);
if (IS_ERR(int3472->regulator.rdev)) {
ret = PTR_ERR(int3472->regulator.rdev);
......
......@@ -377,7 +377,7 @@ config REGULATOR_FAN53555
config REGULATOR_FAN53880
tristate "Fairchild FAN53880 Regulator"
depends on I2C && (OF || COMPILE_TEST)
depends on I2C && OF
select REGMAP_I2C
help
This driver supports Fairchild (ON Semiconductor) FAN53880
......@@ -743,7 +743,7 @@ config REGULATOR_MP8859
config REGULATOR_MP886X
tristate "MPS MP8869 regulator driver"
depends on I2C && (OF || COMPILE_TEST)
depends on I2C && OF
select REGMAP_I2C
help
This driver supports the MP8869 voltage regulator.
......@@ -805,6 +805,15 @@ config REGULATOR_MT6332
This driver supports the control of different power rails of device
through regulator interface
config REGULATOR_MT6357
tristate "MediaTek MT6357 PMIC"
depends on MFD_MT6397
help
Say y here to select this option to enable the power regulator of
MediaTek MT6357 PMIC.
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6358
tristate "MediaTek MT6358 PMIC"
depends on MFD_MT6397
......@@ -1124,6 +1133,17 @@ config REGULATOR_RT6160
The wide output range is from 2025mV to 5200mV and can be used on most
common application scenario.
config REGULATOR_RT6190
tristate "Richtek RT6190 4-Switch BuckBoost controller"
depends on I2C
select REGMAP_I2C
help
The RT6190 is a 4-Switch BuckBoost controller designed for converting
input voltage to output voltage that can be equal to, higher or lower
than input voltage. It operates with wide input voltage range from
4.5V to 36V, and the output voltage can be set from 3V to 36V by
external FB pin.
config REGULATOR_RT6245
tristate "Richtek RT6245 voltage regulator"
depends on I2C
......@@ -1288,21 +1308,21 @@ config REGULATOR_SY7636A
config REGULATOR_SY8106A
tristate "Silergy SY8106A regulator"
depends on I2C && (OF || COMPILE_TEST)
depends on I2C && OF
select REGMAP_I2C
help
This driver supports SY8106A single output regulator.
config REGULATOR_SY8824X
tristate "Silergy SY8824C/SY8824E regulator"
depends on I2C && (OF || COMPILE_TEST)
depends on I2C && OF
select REGMAP_I2C
help
This driver supports SY8824C single output regulator.
config REGULATOR_SY8827N
tristate "Silergy SY8827N regulator"
depends on I2C && (OF || COMPILE_TEST)
depends on I2C && OF
select REGMAP_I2C
help
This driver supports SY8827N single output regulator.
......
......@@ -97,6 +97,7 @@ obj-$(CONFIG_REGULATOR_MT6315) += mt6315-regulator.o
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6331) += mt6331-regulator.o
obj-$(CONFIG_REGULATOR_MT6332) += mt6332-regulator.o
obj-$(CONFIG_REGULATOR_MT6357) += mt6357-regulator.o
obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
obj-$(CONFIG_REGULATOR_MT6359) += mt6359-regulator.o
obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o
......@@ -134,6 +135,7 @@ obj-$(CONFIG_REGULATOR_RT5120) += rt5120-regulator.o
obj-$(CONFIG_REGULATOR_RT5190A) += rt5190a-regulator.o
obj-$(CONFIG_REGULATOR_RT5759) += rt5759-regulator.o
obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o
obj-$(CONFIG_REGULATOR_RT6190) += rt6190-regulator.o
obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o
obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
obj-$(CONFIG_REGULATOR_RTQ2134) += rtq2134-regulator.o
......
......@@ -651,9 +651,9 @@ static int act8600_charger_probe(struct device *dev, struct regmap *regmap)
return PTR_ERR_OR_ZERO(charger);
}
static int act8865_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
static int act8865_pmic_probe(struct i2c_client *client)
{
const struct i2c_device_id *i2c_id = i2c_client_get_device_id(client);
const struct regulator_desc *regulators;
struct act8865_platform_data *pdata = NULL;
struct device *dev = &client->dev;
......@@ -790,7 +790,7 @@ static struct i2c_driver act8865_pmic_driver = {
.driver = {
.name = "act8865",
},
.probe = act8865_pmic_probe,
.probe_new = act8865_pmic_probe,
.id_table = act8865_ids,
};
......
......@@ -212,9 +212,9 @@ static const struct i2c_device_id ad5398_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ad5398_id);
static int ad5398_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int ad5398_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct regulator_init_data *init_data = dev_get_platdata(&client->dev);
struct regulator_config config = { };
struct ad5398_chip_info *chip;
......@@ -254,7 +254,7 @@ static int ad5398_probe(struct i2c_client *client,
}
static struct i2c_driver ad5398_driver = {
.probe = ad5398_probe,
.probe_new = ad5398_probe,
.driver = {
.name = "ad5398",
},
......
......@@ -34,7 +34,7 @@ struct arizona_micsupp {
struct regulator_dev *regulator;
struct regmap *regmap;
struct snd_soc_dapm_context **dapm;
unsigned int enable_reg;
const struct regulator_desc *desc;
struct device *dev;
struct regulator_consumer_supply supply;
......@@ -49,10 +49,11 @@ static void arizona_micsupp_check_cp(struct work_struct *work)
container_of(work, struct arizona_micsupp, check_cp_work);
struct snd_soc_dapm_context *dapm = *micsupp->dapm;
struct snd_soc_component *component;
const struct regulator_desc *desc = micsupp->desc;
unsigned int val;
int ret;
ret = regmap_read(micsupp->regmap, micsupp->enable_reg, &val);
ret = regmap_read(micsupp->regmap, desc->enable_reg, &val);
if (ret != 0) {
dev_err(micsupp->dev,
"Failed to read CP state: %d\n", ret);
......@@ -62,8 +63,8 @@ static void arizona_micsupp_check_cp(struct work_struct *work)
if (dapm) {
component = snd_soc_dapm_to_component(dapm);
if ((val & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) ==
ARIZONA_CPMIC_ENA)
if ((val & (desc->enable_mask | desc->bypass_mask)) ==
desc->enable_mask)
snd_soc_component_force_enable_pin(component,
"MICSUPP");
else
......@@ -209,7 +210,6 @@ static const struct regulator_desc madera_micsupp = {
.type = REGULATOR_VOLTAGE,
.n_voltages = 40,
.ops = &arizona_micsupp_ops,
.vsel_reg = MADERA_LDO2_CONTROL_1,
.vsel_mask = MADERA_LDO2_VSEL_MASK,
.enable_reg = MADERA_MIC_CHARGE_PUMP_1,
......@@ -262,9 +262,8 @@ static int arizona_micsupp_common_init(struct platform_device *pdev,
INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp);
micsupp->init_data.consumer_supplies = &micsupp->supply;
micsupp->supply.supply = "MICVDD";
micsupp->supply.dev_name = dev_name(micsupp->dev);
micsupp->enable_reg = desc->enable_reg;
micsupp->desc = desc;
config.dev = micsupp->dev;
config.driver_data = micsupp;
......@@ -285,8 +284,7 @@ static int arizona_micsupp_common_init(struct platform_device *pdev,
config.init_data = &micsupp->init_data;
/* Default to regulated mode */
regmap_update_bits(micsupp->regmap, micsupp->enable_reg,
ARIZONA_CPMIC_BYPASS, 0);
regmap_update_bits(micsupp->regmap, desc->enable_reg, desc->bypass_mask, 0);
micsupp->regulator = devm_regulator_register(&pdev->dev,
desc,
......@@ -320,6 +318,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
micsupp->dapm = &arizona->dapm;
micsupp->dev = arizona->dev;
micsupp->supply.supply = "MICVDD";
/*
* Since the chip usually supplies itself we provide some
* default init_data for it. This will be overridden with
......@@ -355,6 +355,8 @@ static int madera_micsupp_probe(struct platform_device *pdev)
micsupp->dev = madera->dev;
micsupp->init_data = arizona_micsupp_ext_default;
micsupp->supply.supply = "MICVDD";
return arizona_micsupp_common_init(pdev, micsupp, &madera_micsupp,
&madera->pdata.micvdd);
}
......
......@@ -602,12 +602,10 @@ static int bd7181x_probe(struct platform_device *pdev)
config.ena_gpiod = NULL;
rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
desc->name);
return PTR_ERR(rdev);
}
if (IS_ERR(rdev))
return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
"failed to register %s regulator\n",
desc->name);
}
return 0;
}
......
......@@ -750,23 +750,20 @@ static int bd71828_probe(struct platform_device *pdev)
rd = &bd71828_rdata[i];
rdev = devm_regulator_register(&pdev->dev,
&rd->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
rd->desc.name);
return PTR_ERR(rdev);
}
if (IS_ERR(rdev))
return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
"failed to register %s regulator\n",
rd->desc.name);
for (j = 0; j < rd->reg_init_amnt; j++) {
ret = regmap_update_bits(config.regmap,
rd->reg_inits[j].reg,
rd->reg_inits[j].mask,
rd->reg_inits[j].val);
if (ret) {
dev_err(&pdev->dev,
"regulator %s init failed\n",
rd->desc.name);
return ret;
}
if (ret)
return dev_err_probe(&pdev->dev, ret,
"regulator %s init failed\n",
rd->desc.name);
}
}
return 0;
......
......@@ -1576,8 +1576,6 @@ static int setup_feedback_loop(struct device *dev, struct device_node *np,
if (!of_node_name_eq(np, desc->of_match))
continue;
pr_info("Looking at node '%s'\n", desc->of_match);
/* The feedback loop connection does not make sense for LDOs */
if (desc->id >= BD718XX_LDO1)
return -EINVAL;
......@@ -1708,20 +1706,17 @@ static int bd718xx_probe(struct platform_device *pdev)
break;
default:
dev_err(&pdev->dev, "Unsupported chip type\n");
err = -EINVAL;
goto err;
return -EINVAL;
}
/* Register LOCK release */
err = regmap_update_bits(regmap, BD718XX_REG_REGLOCK,
(REGLOCK_PWRSEQ | REGLOCK_VREG), 0);
if (err) {
dev_err(&pdev->dev, "Failed to unlock PMIC (%d)\n", err);
goto err;
} else {
dev_dbg(&pdev->dev, "Unlocked lock register 0x%x\n",
BD718XX_REG_REGLOCK);
}
if (err)
return dev_err_probe(&pdev->dev, err, "Failed to unlock PMIC\n");
dev_dbg(&pdev->dev, "Unlocked lock register 0x%x\n",
BD718XX_REG_REGLOCK);
use_snvs = of_property_read_bool(pdev->dev.parent->of_node,
"rohm,reset-snvs-powered");
......@@ -1738,13 +1733,11 @@ static int bd718xx_probe(struct platform_device *pdev)
BD718XX_WDOG_POWEROFF_MASK |
BD718XX_KEY_L_POWEROFF_MASK,
BD718XX_POWOFF_TO_RDY);
if (err) {
dev_err(&pdev->dev, "Failed to change reset target\n");
goto err;
} else {
dev_dbg(&pdev->dev,
"Changed all resets from SVNS to READY\n");
}
if (err)
return dev_err_probe(&pdev->dev, err,
"Failed to change reset target\n");
dev_dbg(&pdev->dev, "Changed all resets from SVNS to READY\n");
}
config.dev = pdev->dev.parent;
......@@ -1780,13 +1773,10 @@ static int bd718xx_probe(struct platform_device *pdev)
desc->ops = swops[i];
rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
desc->name);
err = PTR_ERR(rdev);
goto err;
}
if (IS_ERR(rdev))
return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
"failed to register %s regulator\n",
desc->name);
/*
* Regulator register gets the regulator constraints and
......@@ -1809,28 +1799,23 @@ static int bd718xx_probe(struct platform_device *pdev)
!rdev->constraints->boot_on)) {
err = regmap_update_bits(regmap, r->init.reg,
r->init.mask, r->init.val);
if (err) {
dev_err(&pdev->dev,
if (err)
return dev_err_probe(&pdev->dev, err,
"Failed to take control for (%s)\n",
desc->name);
goto err;
}
}
for (j = 0; j < r->additional_init_amnt; j++) {
err = regmap_update_bits(regmap,
r->additional_inits[j].reg,
r->additional_inits[j].mask,
r->additional_inits[j].val);
if (err) {
dev_err(&pdev->dev,
if (err)
return dev_err_probe(&pdev->dev, err,
"Buck (%s) initialization failed\n",
desc->name);
goto err;
}
}
}
err:
return err;
}
......
......@@ -953,30 +953,28 @@ static int bd957x_probe(struct platform_device *pdev)
dev_fwnode(pdev->dev.parent),
"rohm,vout1-en", GPIOD_OUT_LOW,
"vout1-en");
if (!IS_ERR(en)) {
/* VOUT1_OPS gpio ctrl */
/*
* Regulator core prioritizes the ena_gpio over
* enable/disable/is_enabled callbacks so no need to
* clear them. We can still use same ops
*/
/* VOUT1_OPS gpio ctrl */
/*
* Regulator core prioritizes the ena_gpio over
* enable/disable/is_enabled callbacks so no need to clear them
* even if GPIO is used. So, we can still use same ops.
*
* In theory it is possible someone wants to set vout1-en LOW
* during OTP loading and set VOUT1 to be controlled by GPIO -
* but control the GPIO from some where else than this driver.
* For that to work we should unset the is_enabled callback
* here.
*
* I believe such case where rohm,vout1-en-low is set and
* vout1-en-gpios is not is likely to be a misconfiguration.
* So let's just err out for now.
*/
if (!IS_ERR(en))
config.ena_gpiod = en;
} else {
/*
* In theory it is possible someone wants to set
* vout1-en LOW during OTP loading and set VOUT1 to be
* controlled by GPIO - but control the GPIO from some
* where else than this driver. For that to work we
* should unset the is_enabled callback here.
*
* I believe such case where rohm,vout1-en-low is set
* and vout1-en-gpios is not is likely to be a
* misconfiguration. So let's just err out for now.
*/
dev_err(&pdev->dev,
"Failed to get VOUT1 control GPIO\n");
return PTR_ERR(en);
}
else
return dev_err_probe(&pdev->dev, PTR_ERR(en),
"Failed to get VOUT1 control GPIO\n");
}
/*
......@@ -1037,12 +1035,10 @@ static int bd957x_probe(struct platform_device *pdev)
r->rdev = devm_regulator_register(&pdev->dev, desc,
&config);
if (IS_ERR(r->rdev)) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
desc->name);
return PTR_ERR(r->rdev);
}
if (IS_ERR(r->rdev))
return dev_err_probe(&pdev->dev, PTR_ERR(r->rdev),
"failed to register %s regulator\n",
desc->name);
/*
* Clear the VOUT1 GPIO setting - rest of the regulators do not
* support GPIO control
......
......@@ -1596,7 +1596,13 @@ static int set_machine_constraints(struct regulator_dev *rdev)
if (rdev->supply_name && !rdev->supply)
return -EPROBE_DEFER;
if (rdev->supply) {
/* If supplying regulator has already been enabled,
* it's not intended to have use_count increment
* when rdev is only boot-on.
*/
if (rdev->supply &&
(rdev->constraints->always_on ||
!regulator_is_enabled(rdev->supply))) {
ret = regulator_enable(rdev->supply);
if (ret < 0) {
_regulator_put(rdev->supply);
......@@ -1640,6 +1646,7 @@ static int set_supply(struct regulator_dev *rdev,
rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
if (rdev->supply == NULL) {
module_put(supply_rdev->owner);
err = -ENOMEM;
return err;
}
......@@ -1813,7 +1820,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
if (regulator == NULL) {
kfree(supply_name);
kfree_const(supply_name);
return NULL;
}
......@@ -1943,6 +1950,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
node = of_get_regulator(dev, supply);
if (node) {
r = of_find_regulator_by_node(node);
of_node_put(node);
if (r)
return r;
......@@ -4778,22 +4786,8 @@ static int _notifier_call_chain(struct regulator_dev *rdev,
return blocking_notifier_call_chain(&rdev->notifier, event, data);
}
/**
* regulator_bulk_get - get multiple regulator consumers
*
* @dev: Device to supply
* @num_consumers: Number of consumers to register
* @consumers: Configuration of consumers; clients are stored here.
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to get several regulator
* consumers in one operation. If any of the regulators cannot be
* acquired then any regulators that were allocated will be freed
* before returning to the caller.
*/
int regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers)
int _regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers, enum regulator_get_type get_type)
{
int i;
int ret;
......@@ -4802,8 +4796,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
consumers[i].consumer = NULL;
for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = regulator_get(dev,
consumers[i].supply);
consumers[i].consumer = _regulator_get(dev,
consumers[i].supply, get_type);
if (IS_ERR(consumers[i].consumer)) {
ret = dev_err_probe(dev, PTR_ERR(consumers[i].consumer),
"Failed to get supply '%s'",
......@@ -4830,6 +4824,26 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
return ret;
}
/**
* regulator_bulk_get - get multiple regulator consumers
*
* @dev: Device to supply
* @num_consumers: Number of consumers to register
* @consumers: Configuration of consumers; clients are stored here.
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to get several regulator
* consumers in one operation. If any of the regulators cannot be
* acquired then any regulators that were allocated will be freed
* before returning to the caller.
*/
int regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers)
{
return _regulator_bulk_get(dev, num_consumers, consumers, NORMAL_GET);
}
EXPORT_SYMBOL_GPL(regulator_bulk_get);
static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
......@@ -5396,6 +5410,7 @@ static struct regulator_coupler generic_regulator_coupler = {
/**
* regulator_register - register regulator
* @dev: the device that drive the regulator
* @regulator_desc: regulator to register
* @cfg: runtime configuration for regulator
*
......@@ -5404,7 +5419,8 @@ static struct regulator_coupler generic_regulator_coupler = {
* or an ERR_PTR() on error.
*/
struct regulator_dev *
regulator_register(const struct regulator_desc *regulator_desc,
regulator_register(struct device *dev,
const struct regulator_desc *regulator_desc,
const struct regulator_config *cfg)
{
const struct regulator_init_data *init_data;
......@@ -5413,7 +5429,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
struct regulator_dev *rdev;
bool dangling_cfg_gpiod = false;
bool dangling_of_gpiod = false;
struct device *dev;
int ret, i;
bool resolved_early = false;
......@@ -5426,8 +5441,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
goto rinse;
}
dev = cfg->dev;
WARN_ON(!dev);
WARN_ON(!dev || !cfg->dev);
if (regulator_desc->name == NULL || regulator_desc->ops == NULL) {
ret = -EINVAL;
......@@ -5641,6 +5655,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
regulator_remove_coupling(rdev);
mutex_unlock(&regulator_list_mutex);
wash:
regulator_put(rdev->supply);
kfree(rdev->coupling_desc.coupled_rdevs);
mutex_lock(&regulator_list_mutex);
regulator_ena_gpio_free(rdev);
......
......@@ -1128,8 +1128,7 @@ static inline int da9121_of_get_id(struct device *dev)
return (uintptr_t)id->data;
}
static int da9121_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int da9121_i2c_probe(struct i2c_client *i2c)
{
struct da9121 *chip;
const int mask_all[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
......@@ -1197,7 +1196,7 @@ static struct i2c_driver da9121_regulator_driver = {
.name = "da9121",
.of_match_table = of_match_ptr(da9121_dt_ids),
},
.probe = da9121_i2c_probe,
.probe_new = da9121_i2c_probe,
.remove = da9121_i2c_remove,
.id_table = da9121_i2c_id,
};
......
......@@ -186,23 +186,9 @@ static void devm_regulator_bulk_release(struct device *dev, void *res)
regulator_bulk_free(devres->num_consumers, devres->consumers);
}
/**
* devm_regulator_bulk_get - managed get multiple regulator consumers
*
* @dev: device to supply
* @num_consumers: number of consumers to register
* @consumers: configuration of consumers; clients are stored here.
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to get several regulator
* consumers in one operation with management, the regulators will
* automatically be freed when the device is unbound. If any of the
* regulators cannot be acquired then any regulators that were
* allocated will be freed before returning to the caller.
*/
int devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers)
static int _devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers,
enum regulator_get_type get_type)
{
struct regulator_bulk_devres *devres;
int ret;
......@@ -212,7 +198,7 @@ int devm_regulator_bulk_get(struct device *dev, int num_consumers,
if (!devres)
return -ENOMEM;
ret = regulator_bulk_get(dev, num_consumers, consumers);
ret = _regulator_bulk_get(dev, num_consumers, consumers, get_type);
if (!ret) {
devres->consumers = consumers;
devres->num_consumers = num_consumers;
......@@ -223,8 +209,52 @@ int devm_regulator_bulk_get(struct device *dev, int num_consumers,
return ret;
}
/**
* devm_regulator_bulk_get - managed get multiple regulator consumers
*
* @dev: device to supply
* @num_consumers: number of consumers to register
* @consumers: configuration of consumers; clients are stored here.
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to get several regulator
* consumers in one operation with management, the regulators will
* automatically be freed when the device is unbound. If any of the
* regulators cannot be acquired then any regulators that were
* allocated will be freed before returning to the caller.
*/
int devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers)
{
return _devm_regulator_bulk_get(dev, num_consumers, consumers, NORMAL_GET);
}
EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
/**
* devm_regulator_bulk_get_exclusive - managed exclusive get of multiple
* regulator consumers
*
* @dev: device to supply
* @num_consumers: number of consumers to register
* @consumers: configuration of consumers; clients are stored here.
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to exclusively get several
* regulator consumers in one operation with management, the regulators
* will automatically be freed when the device is unbound. If any of
* the regulators cannot be acquired then any regulators that were
* allocated will be freed before returning to the caller.
*/
int devm_regulator_bulk_get_exclusive(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers)
{
return _devm_regulator_bulk_get(dev, num_consumers, consumers, EXCLUSIVE_GET);
}
EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_exclusive);
/**
* devm_regulator_bulk_get_const - devm_regulator_bulk_get() w/ const data
*
......@@ -385,7 +415,7 @@ struct regulator_dev *devm_regulator_register(struct device *dev,
if (!ptr)
return ERR_PTR(-ENOMEM);
rdev = regulator_register(regulator_desc, config);
rdev = regulator_register(dev, regulator_desc, config);
if (!IS_ERR(rdev)) {
*ptr = rdev;
devres_add(dev, ptr);
......
......@@ -549,9 +549,9 @@ static const struct of_device_id __maybe_unused fan53555_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, fan53555_dt_ids);
static int fan53555_regulator_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int fan53555_regulator_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device_node *np = client->dev.of_node;
struct fan53555_device_info *di;
struct fan53555_platform_data *pdata;
......@@ -665,7 +665,7 @@ static struct i2c_driver fan53555_regulator_driver = {
.name = "fan53555-regulator",
.of_match_table = of_match_ptr(fan53555_dt_ids),
},
.probe = fan53555_regulator_probe,
.probe_new = fan53555_regulator_probe,
.id_table = fan53555_id,
};
......
......@@ -42,8 +42,8 @@ static const struct regulator_ops fan53880_ops = {
#define FAN53880_LDO(_num, _supply, _default) \
[FAN53880_LDO ## _num] = { \
.name = "LDO"#_num, \
.of_match = of_match_ptr("LDO"#_num), \
.regulators_node = of_match_ptr("regulators"), \
.of_match = "LDO"#_num, \
.regulators_node = "regulators", \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.linear_ranges = (struct linear_range[]) { \
......@@ -68,8 +68,8 @@ static const struct regulator_desc fan53880_regulators[] = {
FAN53880_LDO(4, "VIN4", 1800000),
[FAN53880_BUCK] = {
.name = "BUCK",
.of_match = of_match_ptr("BUCK"),
.regulators_node = of_match_ptr("regulators"),
.of_match = "BUCK",
.regulators_node = "regulators",
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.linear_ranges = (struct linear_range[]) {
......@@ -88,8 +88,8 @@ static const struct regulator_desc fan53880_regulators[] = {
},
[FAN53880_BOOST] = {
.name = "BOOST",
.of_match = of_match_ptr("BOOST"),
.regulators_node = of_match_ptr("regulators"),
.of_match = "BOOST",
.regulators_node = "regulators",
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.linear_ranges = (struct linear_range[]) {
......@@ -157,13 +157,11 @@ static int fan53880_i2c_probe(struct i2c_client *i2c)
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id fan53880_dt_ids[] = {
{ .compatible = "onnn,fan53880", },
{}
};
MODULE_DEVICE_TABLE(of, fan53880_dt_ids);
#endif
static const struct i2c_device_id fan53880_i2c_id[] = {
{ "fan53880", },
......@@ -174,7 +172,7 @@ MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id);
static struct i2c_driver fan53880_regulator_driver = {
.driver = {
.name = "fan53880",
.of_match_table = of_match_ptr(fan53880_dt_ids),
.of_match_table = fan53880_dt_ids,
},
.probe_new = fan53880_i2c_probe,
.id_table = fan53880_i2c_id,
......
......@@ -122,4 +122,6 @@ enum regulator_get_type {
struct regulator *_regulator_get(struct device *dev, const char *id,
enum regulator_get_type get_type);
int _regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers, enum regulator_get_type get_type);
#endif
......@@ -97,9 +97,9 @@ static const struct regulator_desc isl_rd[] = {
},
};
static int isl6271a_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int isl6271a_probe(struct i2c_client *i2c)
{
const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct regulator_dev *rdev;
struct regulator_config config = { };
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
......@@ -148,7 +148,7 @@ static struct i2c_driver isl6271a_i2c_driver = {
.driver = {
.name = "isl6271a",
},
.probe = isl6271a_probe,
.probe_new = isl6271a_probe,
.id_table = isl6271a_id,
};
......
......@@ -495,8 +495,7 @@ static int setup_regulators(struct lp3972 *lp3972,
return 0;
}
static int lp3972_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int lp3972_i2c_probe(struct i2c_client *i2c)
{
struct lp3972 *lp3972;
struct lp3972_platform_data *pdata = dev_get_platdata(&i2c->dev);
......@@ -547,7 +546,7 @@ static struct i2c_driver lp3972_i2c_driver = {
.driver = {
.name = "lp3972",
},
.probe = lp3972_i2c_probe,
.probe_new = lp3972_i2c_probe,
.id_table = lp3972_i2c_id,
};
......
......@@ -879,8 +879,9 @@ static struct lp872x_platform_data
}
#endif
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
static int lp872x_probe(struct i2c_client *cl)
{
const struct i2c_device_id *id = i2c_client_get_device_id(cl);
struct lp872x *lp;
struct lp872x_platform_data *pdata;
int ret;
......@@ -946,7 +947,7 @@ static struct i2c_driver lp872x_driver = {
.name = "lp872x",
.of_match_table = of_match_ptr(lp872x_dt_ids),
},
.probe = lp872x_probe,
.probe_new = lp872x_probe,
.id_table = lp872x_ids,
};
......
......@@ -357,8 +357,7 @@ static const struct regmap_config lp8755_regmap = {
.max_register = LP8755_REG_MAX,
};
static int lp8755_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int lp8755_probe(struct i2c_client *client)
{
int ret, icnt;
struct lp8755_chip *pchip;
......@@ -442,7 +441,7 @@ static struct i2c_driver lp8755_i2c_driver = {
.driver = {
.name = LP8755_NAME,
},
.probe = lp8755_probe,
.probe_new = lp8755_probe,
.remove = lp8755_remove,
.id_table = lp8755_id,
};
......
......@@ -378,9 +378,9 @@ static irqreturn_t ltc3589_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
static int ltc3589_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int ltc3589_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device *dev = &client->dev;
struct regulator_desc *descs;
struct ltc3589 *ltc3589;
......@@ -476,7 +476,7 @@ static struct i2c_driver ltc3589_driver = {
.name = DRIVER_NAME,
.of_match_table = of_match_ptr(ltc3589_of_match),
},
.probe = ltc3589_probe,
.probe_new = ltc3589_probe,
.id_table = ltc3589_i2c_id,
};
module_i2c_driver(ltc3589_driver);
......
......@@ -207,8 +207,7 @@ static const struct of_device_id __maybe_unused max1586_of_match[] = {
};
MODULE_DEVICE_TABLE(of, max1586_of_match);
static int max1586_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
static int max1586_pmic_probe(struct i2c_client *client)
{
struct max1586_platform_data *pdata, pdata_of;
struct regulator_config config = { };
......@@ -290,7 +289,7 @@ static const struct i2c_device_id max1586_id[] = {
MODULE_DEVICE_TABLE(i2c, max1586_id);
static struct i2c_driver max1586_pmic_driver = {
.probe = max1586_pmic_probe,
.probe_new = max1586_pmic_probe,
.driver = {
.name = "max1586",
.of_match_table = of_match_ptr(max1586_of_match),
......
......@@ -145,8 +145,7 @@ static const struct regmap_config max8649_regmap_config = {
.val_bits = 8,
};
static int max8649_regulator_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int max8649_regulator_probe(struct i2c_client *client)
{
struct max8649_platform_data *pdata = dev_get_platdata(&client->dev);
struct max8649_regulator_info *info = NULL;
......@@ -247,7 +246,7 @@ static const struct i2c_device_id max8649_id[] = {
MODULE_DEVICE_TABLE(i2c, max8649_id);
static struct i2c_driver max8649_driver = {
.probe = max8649_regulator_probe,
.probe_new = max8649_regulator_probe,
.driver = {
.name = "max8649",
},
......
......@@ -367,9 +367,9 @@ static inline int max8660_pdata_from_dt(struct device *dev,
}
#endif
static int max8660_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
static int max8660_probe(struct i2c_client *client)
{
const struct i2c_device_id *i2c_id = i2c_client_get_device_id(client);
struct device *dev = &client->dev;
struct max8660_platform_data pdata_of, *pdata = dev_get_platdata(dev);
struct regulator_config config = { };
......@@ -503,7 +503,7 @@ static const struct i2c_device_id max8660_id[] = {
MODULE_DEVICE_TABLE(i2c, max8660_id);
static struct i2c_driver max8660_driver = {
.probe = max8660_probe,
.probe_new = max8660_probe,
.driver = {
.name = "max8660",
},
......
......@@ -171,8 +171,7 @@ static struct max8952_platform_data *max8952_parse_dt(struct device *dev)
}
#endif
static int max8952_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
static int max8952_pmic_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
struct max8952_platform_data *pdata = dev_get_platdata(&client->dev);
......@@ -314,7 +313,7 @@ static const struct i2c_device_id max8952_ids[] = {
MODULE_DEVICE_TABLE(i2c, max8952_ids);
static struct i2c_driver max8952_pmic_driver = {
.probe = max8952_pmic_probe,
.probe_new = max8952_pmic_probe,
.driver = {
.name = "max8952",
.of_match_table = of_match_ptr(max8952_dt_match),
......
......@@ -586,9 +586,9 @@ static const struct of_device_id of_max8973_match_tbl[] = {
};
MODULE_DEVICE_TABLE(of, of_max8973_match_tbl);
static int max8973_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int max8973_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct max8973_regulator_platform_data *pdata;
struct regulator_init_data *ridata;
struct regulator_config config = { };
......@@ -806,7 +806,7 @@ static struct i2c_driver max8973_i2c_driver = {
.name = "max8973",
.of_match_table = of_max8973_match_tbl,
},
.probe = max8973_probe,
.probe_new = max8973_probe,
.id_table = max8973_id,
};
......
......@@ -362,7 +362,7 @@ MODULE_DEVICE_TABLE(i2c, mp886x_id);
static struct i2c_driver mp886x_regulator_driver = {
.driver = {
.name = "mp886x-regulator",
.of_match_table = of_match_ptr(mp886x_dt_ids),
.of_match_table = mp886x_dt_ids,
},
.probe_new = mp886x_i2c_probe,
.id_table = mp886x_id,
......
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2022 MediaTek Inc.
// Copyright (c) 2022 BayLibre, SAS.
// Author: Chen Zhong <chen.zhong@mediatek.com>
// Author: Fabien Parent <fparent@baylibre.com>
// Author: Alexandre Mergnat <amergnat@baylibre.com>
//
// Based on mt6397-regulator.c
//
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6357/registers.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/mt6357-regulator.h>
#include <linux/regulator/of_regulator.h>
/*
* MT6357 regulators' information
*
* @desc: standard fields of regulator description.
* @da_vsel_reg: Monitor register for query buck's voltage.
* @da_vsel_mask: Mask for query buck's voltage.
*/
struct mt6357_regulator_info {
struct regulator_desc desc;
u32 da_vsel_reg;
u32 da_vsel_mask;
};
#define MT6357_BUCK(match, vreg, min, max, step, \
volt_ranges, vosel_reg, vosel_mask, _da_vsel_mask) \
[MT6357_ID_##vreg] = { \
.desc = { \
.name = #vreg, \
.of_match = of_match_ptr(match), \
.regulators_node = "regulators", \
.ops = &mt6357_volt_range_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6357_ID_##vreg, \
.owner = THIS_MODULE, \
.n_voltages = ((max) - (min)) / (step) + 1, \
.linear_ranges = volt_ranges, \
.n_linear_ranges = ARRAY_SIZE(volt_ranges), \
.vsel_reg = vosel_reg, \
.vsel_mask = vosel_mask, \
.enable_reg = MT6357_BUCK_##vreg##_CON0, \
.enable_mask = BIT(0), \
}, \
.da_vsel_reg = MT6357_BUCK_##vreg##_DBG0, \
.da_vsel_mask = vosel_mask, \
}
#define MT6357_LDO(match, vreg, ldo_volt_table, \
enreg, vosel, vosel_mask) \
[MT6357_ID_##vreg] = { \
.desc = { \
.name = #vreg, \
.of_match = of_match_ptr(match), \
.regulators_node = "regulators", \
.ops = &mt6357_volt_table_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6357_ID_##vreg, \
.owner = THIS_MODULE, \
.n_voltages = ARRAY_SIZE(ldo_volt_table), \
.volt_table = ldo_volt_table, \
.vsel_reg = vosel, \
.vsel_mask = vosel_mask, \
.enable_reg = enreg, \
.enable_mask = BIT(0), \
}, \
}
#define MT6357_LDO1(match, vreg, min, max, step, volt_ranges, \
enreg, vosel, vosel_mask) \
[MT6357_ID_##vreg] = { \
.desc = { \
.name = #vreg, \
.of_match = of_match_ptr(match), \
.regulators_node = "regulators", \
.ops = &mt6357_volt_range_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6357_ID_##vreg, \
.owner = THIS_MODULE, \
.n_voltages = ((max) - (min)) / (step) + 1, \
.linear_ranges = volt_ranges, \
.n_linear_ranges = ARRAY_SIZE(volt_ranges), \
.vsel_reg = vosel, \
.vsel_mask = vosel_mask, \
.enable_reg = enreg, \
.enable_mask = BIT(0), \
}, \
.da_vsel_reg = MT6357_LDO_##vreg##_DBG0, \
.da_vsel_mask = 0x7f00, \
}
#define MT6357_REG_FIXED(match, vreg, volt) \
[MT6357_ID_##vreg] = { \
.desc = { \
.name = #vreg, \
.of_match = of_match_ptr(match), \
.regulators_node = "regulators", \
.ops = &mt6357_volt_fixed_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6357_ID_##vreg, \
.owner = THIS_MODULE, \
.n_voltages = 1, \
.enable_reg = MT6357_LDO_##vreg##_CON0, \
.enable_mask = BIT(0), \
.min_uV = volt, \
}, \
}
/**
* mt6357_get_buck_voltage_sel - get_voltage_sel for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* da_vsel_reg and da_vsel_mask fields in the info structure and
* then use this as their get_voltage_vsel operation.
*/
static int mt6357_get_buck_voltage_sel(struct regulator_dev *rdev)
{
int ret, regval;
struct mt6357_regulator_info *info = rdev_get_drvdata(rdev);
ret = regmap_read(rdev->regmap, info->da_vsel_reg, &regval);
if (ret != 0) {
dev_err(&rdev->dev,
"Failed to get mt6357 Buck %s vsel reg: %d\n",
info->desc.name, ret);
return ret;
}
regval &= info->da_vsel_mask;
regval >>= ffs(info->da_vsel_mask) - 1;
return regval;
}
static const struct regulator_ops mt6357_volt_range_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = mt6357_get_buck_voltage_sel,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static const struct regulator_ops mt6357_volt_table_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_iterate,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static const struct regulator_ops mt6357_volt_fixed_ops = {
.list_voltage = regulator_list_voltage_linear,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static const int vxo22_voltages[] = {
2200000,
0,
2400000,
};
static const int vefuse_voltages[] = {
1200000,
1300000,
1500000,
0,
1800000,
0,
0,
0,
0,
2800000,
2900000,
3000000,
0,
3300000,
};
static const int vcn33_voltages[] = {
0,
3300000,
3400000,
3500000,
};
static const int vcama_voltages[] = {
0,
0,
0,
0,
0,
0,
0,
2500000,
0,
0,
2800000,
};
static const int vcamd_voltages[] = {
0,
0,
0,
0,
1000000,
1100000,
1200000,
1300000,
0,
1500000,
0,
0,
1800000,
};
static const int vldo28_voltages[] = {
0,
2800000,
0,
3000000,
};
static const int vdram_voltages[] = {
0,
1100000,
1200000,
};
static const int vsim_voltages[] = {
0,
0,
0,
1700000,
1800000,
0,
0,
0,
2700000,
0,
0,
3000000,
3100000,
};
static const int vibr_voltages[] = {
1200000,
1300000,
1500000,
0,
1800000,
2000000,
0,
0,
0,
2800000,
0,
3000000,
0,
3300000,
};
static const int vmc_voltages[] = {
0,
0,
0,
0,
1800000,
0,
0,
0,
0,
0,
2900000,
3000000,
0,
3300000,
};
static const int vmch_voltages[] = {
0,
0,
2900000,
3000000,
0,
3300000,
};
static const int vemc_voltages[] = {
0,
0,
2900000,
3000000,
0,
3300000,
};
static const int vusb_voltages[] = {
0,
0,
0,
3000000,
3100000,
};
static const struct linear_range buck_volt_range1[] = {
REGULATOR_LINEAR_RANGE(518750, 0, 0x7f, 6250),
};
static const struct linear_range buck_volt_range2[] = {
REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
};
static const struct linear_range buck_volt_range3[] = {
REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
};
static const struct linear_range buck_volt_range4[] = {
REGULATOR_LINEAR_RANGE(1200000, 0, 0x7f, 12500),
};
/* The array is indexed by id(MT6357_ID_XXX) */
static struct mt6357_regulator_info mt6357_regulators[] = {
/* Bucks */
MT6357_BUCK("buck-vcore", VCORE, 518750, 1312500, 6250,
buck_volt_range1, MT6357_BUCK_VCORE_ELR0, 0x7f, 0x7f),
MT6357_BUCK("buck-vproc", VPROC, 518750, 1312500, 6250,
buck_volt_range1, MT6357_BUCK_VPROC_ELR0, 0x7f, 0x7f),
MT6357_BUCK("buck-vmodem", VMODEM, 500000, 1293750, 6250,
buck_volt_range2, MT6357_BUCK_VMODEM_ELR0, 0x7f, 0x7f),
MT6357_BUCK("buck-vpa", VPA, 500000, 3650000, 50000,
buck_volt_range3, MT6357_BUCK_VPA_CON1, 0x3f, 0x3f),
MT6357_BUCK("buck-vs1", VS1, 1200000, 2787500, 12500,
buck_volt_range4, MT6357_BUCK_VS1_ELR0, 0x7f, 0x7f),
/* LDOs */
MT6357_LDO("ldo-vcama", VCAMA, vcama_voltages,
MT6357_LDO_VCAMA_CON0, MT6357_VCAMA_ANA_CON0, 0xf00),
MT6357_LDO("ldo-vcamd", VCAMD, vcamd_voltages,
MT6357_LDO_VCAMD_CON0, MT6357_VCAMD_ANA_CON0, 0xf00),
MT6357_LDO("ldo-vcn33-bt", VCN33_BT, vcn33_voltages,
MT6357_LDO_VCN33_CON0_0, MT6357_VCN33_ANA_CON0, 0x300),
MT6357_LDO("ldo-vcn33-wifi", VCN33_WIFI, vcn33_voltages,
MT6357_LDO_VCN33_CON0_1, MT6357_VCN33_ANA_CON0, 0x300),
MT6357_LDO("ldo-vdram", VDRAM, vdram_voltages,
MT6357_LDO_VDRAM_CON0, MT6357_VDRAM_ELR_2, 0x300),
MT6357_LDO("ldo-vefuse", VEFUSE, vefuse_voltages,
MT6357_LDO_VEFUSE_CON0, MT6357_VEFUSE_ANA_CON0, 0xf00),
MT6357_LDO("ldo-vemc", VEMC, vemc_voltages,
MT6357_LDO_VEMC_CON0, MT6357_VEMC_ANA_CON0, 0x700),
MT6357_LDO("ldo-vibr", VIBR, vibr_voltages,
MT6357_LDO_VIBR_CON0, MT6357_VIBR_ANA_CON0, 0xf00),
MT6357_LDO("ldo-vldo28", VLDO28, vldo28_voltages,
MT6357_LDO_VLDO28_CON0_0, MT6357_VLDO28_ANA_CON0, 0x300),
MT6357_LDO("ldo-vmc", VMC, vmc_voltages,
MT6357_LDO_VMC_CON0, MT6357_VMC_ANA_CON0, 0xf00),
MT6357_LDO("ldo-vmch", VMCH, vmch_voltages,
MT6357_LDO_VMCH_CON0, MT6357_VMCH_ANA_CON0, 0x700),
MT6357_LDO("ldo-vsim1", VSIM1, vsim_voltages,
MT6357_LDO_VSIM1_CON0, MT6357_VSIM1_ANA_CON0, 0xf00),
MT6357_LDO("ldo-vsim2", VSIM2, vsim_voltages,
MT6357_LDO_VSIM2_CON0, MT6357_VSIM2_ANA_CON0, 0xf00),
MT6357_LDO("ldo-vusb33", VUSB33, vusb_voltages,
MT6357_LDO_VUSB33_CON0_0, MT6357_VUSB33_ANA_CON0, 0x700),
MT6357_LDO("ldo-vxo22", VXO22, vxo22_voltages,
MT6357_LDO_VXO22_CON0, MT6357_VXO22_ANA_CON0, 0x300),
MT6357_LDO1("ldo-vsram-proc", VSRAM_PROC, 518750, 1312500, 6250,
buck_volt_range1, MT6357_LDO_VSRAM_PROC_CON0,
MT6357_LDO_VSRAM_CON0, 0x7f00),
MT6357_LDO1("ldo-vsram-others", VSRAM_OTHERS, 518750, 1312500, 6250,
buck_volt_range1, MT6357_LDO_VSRAM_OTHERS_CON0,
MT6357_LDO_VSRAM_CON1, 0x7f00),
MT6357_REG_FIXED("ldo-vaud28", VAUD28, 2800000),
MT6357_REG_FIXED("ldo-vaux18", VAUX18, 1800000),
MT6357_REG_FIXED("ldo-vcamio18", VCAMIO, 1800000),
MT6357_REG_FIXED("ldo-vcn18", VCN18, 1800000),
MT6357_REG_FIXED("ldo-vcn28", VCN28, 2800000),
MT6357_REG_FIXED("ldo-vfe28", VFE28, 2800000),
MT6357_REG_FIXED("ldo-vio18", VIO18, 1800000),
MT6357_REG_FIXED("ldo-vio28", VIO28, 2800000),
MT6357_REG_FIXED("ldo-vrf12", VRF12, 1200000),
MT6357_REG_FIXED("ldo-vrf18", VRF18, 1800000),
};
static int mt6357_regulator_probe(struct platform_device *pdev)
{
struct mt6397_chip *mt6357 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = {};
struct regulator_dev *rdev;
int i;
pdev->dev.of_node = pdev->dev.parent->of_node;
for (i = 0; i < MT6357_MAX_REGULATOR; i++) {
config.dev = &pdev->dev;
config.driver_data = &mt6357_regulators[i];
config.regmap = mt6357->regmap;
rdev = devm_regulator_register(&pdev->dev,
&mt6357_regulators[i].desc,
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register %s\n",
mt6357_regulators[i].desc.name);
return PTR_ERR(rdev);
}
}
return 0;
}
static const struct platform_device_id mt6357_platform_ids[] = {
{ "mt6357-regulator" },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(platform, mt6357_platform_ids);
static struct platform_driver mt6357_regulator_driver = {
.driver = {
.name = "mt6357-regulator",
},
.probe = mt6357_regulator_probe,
.id_table = mt6357_platform_ids,
};
module_platform_driver(mt6357_regulator_driver);
MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
MODULE_AUTHOR("Fabien Parent <fabien.parent@linaro.org>");
MODULE_AUTHOR("Alexandre Mergnat <amergnat@baylibre.com>");
MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6357 PMIC");
MODULE_LICENSE("GPL");
......@@ -505,7 +505,7 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
struct device_node *child;
struct regulator_init_data *init_data = NULL;
child = regulator_of_get_init_node(dev, desc);
child = regulator_of_get_init_node(config->dev, desc);
if (!child)
return NULL;
......@@ -701,3 +701,95 @@ struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev,
return c_rdev;
}
/*
* Check if name is a supply name according to the '*-supply' pattern
* return 0 if false
* return length of supply name without the -supply
*/
static int is_supply_name(const char *name)
{
int strs, i;
strs = strlen(name);
/* string need to be at minimum len(x-supply) */
if (strs < 8)
return 0;
for (i = strs - 6; i > 0; i--) {
/* find first '-' and check if right part is supply */
if (name[i] != '-')
continue;
if (strcmp(name + i + 1, "supply") != 0)
return 0;
return i;
}
return 0;
}
/*
* of_regulator_bulk_get_all - get multiple regulator consumers
*
* @dev: Device to supply
* @np: device node to search for consumers
* @consumers: Configuration of consumers; clients are stored here.
*
* @return number of regulators on success, an errno on failure.
*
* This helper function allows drivers to get several regulator
* consumers in one operation. If any of the regulators cannot be
* acquired then any regulators that were allocated will be freed
* before returning to the caller.
*/
int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
struct regulator_bulk_data **consumers)
{
int num_consumers = 0;
struct regulator *tmp;
struct property *prop;
int i, n = 0, ret;
char name[64];
*consumers = NULL;
/*
* first pass: get numbers of xxx-supply
* second pass: fill consumers
*/
restart:
for_each_property_of_node(np, prop) {
i = is_supply_name(prop->name);
if (i == 0)
continue;
if (!*consumers) {
num_consumers++;
continue;
} else {
memcpy(name, prop->name, i);
name[i] = '\0';
tmp = regulator_get(dev, name);
if (IS_ERR(tmp)) {
ret = -EINVAL;
goto error;
}
(*consumers)[n].consumer = tmp;
n++;
continue;
}
}
if (*consumers)
return num_consumers;
if (num_consumers == 0)
return 0;
*consumers = kmalloc_array(num_consumers,
sizeof(struct regulator_bulk_data),
GFP_KERNEL);
if (!*consumers)
return -ENOMEM;
goto restart;
error:
while (--n >= 0)
regulator_put(consumers[n]->consumer);
return ret;
}
EXPORT_SYMBOL_GPL(of_regulator_bulk_get_all);
......@@ -701,8 +701,7 @@ static irqreturn_t pca9450_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
static int pca9450_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int pca9450_i2c_probe(struct i2c_client *i2c)
{
enum pca9450_chip_type type = (unsigned int)(uintptr_t)
of_device_get_match_data(&i2c->dev);
......@@ -875,7 +874,7 @@ static struct i2c_driver pca9450_i2c_driver = {
.name = "nxp-pca9450",
.of_match_table = pca9450_of_match,
},
.probe = pca9450_i2c_probe,
.probe_new = pca9450_i2c_probe,
};
module_i2c_driver(pca9450_i2c_driver);
......
......@@ -683,9 +683,9 @@ static const struct regmap_config pfuze_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
static int pfuze100_regulator_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int pfuze100_regulator_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct pfuze_chip *pfuze_chip;
struct regulator_config config = { };
int i, ret;
......@@ -847,7 +847,7 @@ static struct i2c_driver pfuze_driver = {
.name = "pfuze100-regulator",
.of_match_table = pfuze_dt_ids,
},
.probe = pfuze100_regulator_probe,
.probe_new = pfuze100_regulator_probe,
};
module_i2c_driver(pfuze_driver);
......
......@@ -374,9 +374,9 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data)
/*
* I2C driver interface functions
*/
static int pv88080_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int pv88080_i2c_probe(struct i2c_client *i2c)
{
const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
struct pv88080 *chip;
const struct pv88080_compatible_regmap *regmap_config;
......@@ -559,7 +559,7 @@ static struct i2c_driver pv88080_regulator_driver = {
.name = "pv88080",
.of_match_table = of_match_ptr(pv88080_dt_ids),
},
.probe = pv88080_i2c_probe,
.probe_new = pv88080_i2c_probe,
.id_table = pv88080_i2c_id,
};
......
......@@ -822,6 +822,7 @@ static int qcom_labibb_regulator_probe(struct platform_device *pdev)
if (irq == 0)
irq = -EINVAL;
of_node_put(reg_node);
return dev_err_probe(vreg->dev, irq,
"Short-circuit irq not found.\n");
}
......
......@@ -731,6 +731,24 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps520 = {
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
};
static const struct rpmh_vreg_hw_data pmic5_ftsmps525_lv = {
.regulator_type = VRM,
.ops = &rpmh_regulator_vrm_ops,
.voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 267, 4000),
.n_voltages = 268,
.pmic_mode_map = pmic_mode_map_pmic5_smps,
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
};
static const struct rpmh_vreg_hw_data pmic5_ftsmps525_mv = {
.regulator_type = VRM,
.ops = &rpmh_regulator_vrm_ops,
.voltage_range = REGULATOR_LINEAR_RANGE(600000, 0, 267, 8000),
.n_voltages = 268,
.pmic_mode_map = pmic_mode_map_pmic5_smps,
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
};
static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
.regulator_type = VRM,
.ops = &rpmh_regulator_vrm_ops,
......@@ -987,6 +1005,57 @@ static const struct rpmh_vreg_init_data pm8450_vreg_data[] = {
{}
};
static const struct rpmh_vreg_init_data pm8550_vreg_data[] = {
RPMH_VREG("ldo1", "ldo%s1", &pmic5_pldo, "vdd-l1-l4-l10"),
RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo, "vdd-l2-l13-l14"),
RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"),
RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l1-l4-l10"),
RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l16"),
RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo_lv, "vdd-l6-l7"),
RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo_lv, "vdd-l6-l7"),
RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo_lv, "vdd-l8-l9"),
RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l8-l9"),
RPMH_VREG("ldo10", "ldo%s10", &pmic5_nldo, "vdd-l1-l4-l10"),
RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l11"),
RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo, "vdd-l12"),
RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l2-l13-l14"),
RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo, "vdd-l2-l13-l14"),
RPMH_VREG("ldo15", "ldo%s15", &pmic5_pldo, "vdd-l15"),
RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l5-l16"),
RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l17"),
RPMH_VREG("bob1", "bob%s1", &pmic5_bob, "vdd-bob1"),
RPMH_VREG("bob2", "bob%s2", &pmic5_bob, "vdd-bob2"),
{}
};
static const struct rpmh_vreg_init_data pm8550vs_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525_lv, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525_lv, "vdd-s2"),
RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525_lv, "vdd-s3"),
RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525_lv, "vdd-s4"),
RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525_lv, "vdd-s5"),
RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525_mv, "vdd-s6"),
RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1"),
RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2"),
RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"),
{}
};
static const struct rpmh_vreg_init_data pm8550ve_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525_lv, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525_lv, "vdd-s2"),
RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525_lv, "vdd-s3"),
RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525_lv, "vdd-s4"),
RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525_lv, "vdd-s5"),
RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525_lv, "vdd-s6"),
RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps525_lv, "vdd-s7"),
RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps525_lv, "vdd-s8"),
RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1"),
RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2"),
RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"),
{}
};
static const struct rpmh_vreg_init_data pm8009_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_hfsmps515, "vdd-s2"),
......@@ -1187,7 +1256,7 @@ static const struct rpmh_vreg_init_data pm7325_vreg_data[] = {
static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps520, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps520, "vdd-s2"),
RPMH_VREG("smps3", "smp%s3", &pmic5_hfsmps510, "vdd-s3"),
RPMH_VREG("smps3", "smp%s3", &pmic5_hfsmps515, "vdd-s3"),
RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l2"),
RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l1-l2"),
RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"),
......@@ -1314,6 +1383,18 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
.compatible = "qcom,pm8450-rpmh-regulators",
.data = pm8450_vreg_data,
},
{
.compatible = "qcom,pm8550-rpmh-regulators",
.data = pm8550_vreg_data,
},
{
.compatible = "qcom,pm8550ve-rpmh-regulators",
.data = pm8550ve_vreg_data,
},
{
.compatible = "qcom,pm8550vs-rpmh-regulators",
.data = pm8550vs_vreg_data,
},
{
.compatible = "qcom,pm8998-rpmh-regulators",
.data = pm8998_vreg_data,
......
......@@ -677,6 +677,24 @@ static const struct regulator_desc pm6125_ftsmps = {
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pmic5_ftsmps520 = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
},
.n_linear_ranges = 1,
.n_voltages = 264,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pmic5_hfsmps515 = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(320000, 0, 235, 16000),
},
.n_linear_ranges = 1,
.n_voltages = 236,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pms405_hfsmps3 = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
......@@ -1265,6 +1283,20 @@ static const struct rpm_regulator_data rpm_pmi8998_regulators[] = {
{}
};
static const struct rpm_regulator_data rpm_pmr735a_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPE, 1, &pmic5_ftsmps520, "vdd_s1"},
{ "s2", QCOM_SMD_RPM_SMPE, 2, &pmic5_ftsmps520, "vdd_s2"},
{ "s3", QCOM_SMD_RPM_SMPE, 3, &pmic5_hfsmps515, "vdd_s3"},
{ "l1", QCOM_SMD_RPM_LDOE, 1, &pm660_nldo660, "vdd_l1_l2"},
{ "l2", QCOM_SMD_RPM_LDOE, 2, &pm660_nldo660, "vdd_l1_l2"},
{ "l3", QCOM_SMD_RPM_LDOE, 3, &pm660_nldo660, "vdd_l3"},
{ "l4", QCOM_SMD_RPM_LDOE, 4, &pm660_ht_lvpldo, "vdd_l4"},
{ "l5", QCOM_SMD_RPM_LDOE, 5, &pm660_nldo660, "vdd_l5_l6"},
{ "l6", QCOM_SMD_RPM_LDOE, 6, &pm660_nldo660, "vdd_l5_l6"},
{ "l7", QCOM_SMD_RPM_LDOE, 7, &pm660_pldo660, "vdd_l7_bob"},
{}
};
static const struct rpm_regulator_data rpm_pms405_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pms405_hfsmps3, "vdd_s1" },
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pms405_hfsmps3, "vdd_s2" },
......@@ -1305,6 +1337,7 @@ static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators },
{ .compatible = "qcom,rpm-pmi8994-regulators", .data = &rpm_pmi8994_regulators },
{ .compatible = "qcom,rpm-pmi8998-regulators", .data = &rpm_pmi8998_regulators },
{ .compatible = "qcom,rpm-pmr735a-regulators", .data = &rpm_pmr735a_regulators },
{ .compatible = "qcom,rpm-pms405-regulators", .data = &rpm_pms405_regulators },
{}
};
......
......@@ -14,7 +14,6 @@
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
......@@ -1286,19 +1285,23 @@ static int rk808_regulator_dt_parse_pdata(struct device *dev,
static int rk808_regulator_probe(struct platform_device *pdev)
{
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
struct i2c_client *client = rk808->i2c;
struct regulator_config config = {};
struct regulator_dev *rk808_rdev;
struct rk808_regulator_data *pdata;
const struct regulator_desc *regulators;
struct regmap *regmap;
int ret, i, nregulators;
regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!regmap)
return -ENODEV;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
ret = rk808_regulator_dt_parse_pdata(&pdev->dev, &client->dev,
rk808->regmap, pdata);
ret = rk808_regulator_dt_parse_pdata(&pdev->dev, pdev->dev.parent,
regmap, pdata);
if (ret < 0)
return ret;
......@@ -1326,24 +1329,23 @@ static int rk808_regulator_probe(struct platform_device *pdev)
nregulators = RK818_NUM_REGULATORS;
break;
default:
dev_err(&client->dev, "unsupported RK8XX ID %lu\n",
dev_err(&pdev->dev, "unsupported RK8XX ID %lu\n",
rk808->variant);
return -EINVAL;
}
config.dev = &client->dev;
config.dev = &pdev->dev;
config.dev->of_node = pdev->dev.parent->of_node;
config.driver_data = pdata;
config.regmap = rk808->regmap;
config.regmap = regmap;
/* Instantiate the regulators */
for (i = 0; i < nregulators; i++) {
rk808_rdev = devm_regulator_register(&pdev->dev,
&regulators[i], &config);
if (IS_ERR(rk808_rdev)) {
dev_err(&client->dev,
"failed to register %d regulator\n", i);
return PTR_ERR(rk808_rdev);
}
if (IS_ERR(rk808_rdev))
return dev_err_probe(&pdev->dev, PTR_ERR(rk808_rdev),
"failed to register %d regulator\n", i);
}
return 0;
......
......@@ -282,8 +282,7 @@ static int attiny_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf)
/*
* I2C driver interface functions
*/
static int attiny_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int attiny_i2c_probe(struct i2c_client *i2c)
{
struct backlight_properties props = { };
struct regulator_config config = { };
......@@ -399,7 +398,7 @@ static struct i2c_driver attiny_regulator_driver = {
.name = "rpi_touchscreen_attiny",
.of_match_table = of_match_ptr(attiny_dt_ids),
},
.probe = attiny_i2c_probe,
.probe_new = attiny_i2c_probe,
.remove = attiny_i2c_remove,
};
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2022 Richtek Technology Corp.
*
* Author: ChiYuan Huang <cy_huang@richtek.com>
*
*/
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#define RT6190_REG_VID 0x00
#define RT6190_REG_OUTV 0x01
#define RT6190_REG_OUTC 0x03
#define RT6190_REG_SET1 0x0D
#define RT6190_REG_SET2 0x0E
#define RT6190_REG_SET4 0x10
#define RT6190_REG_RATIO 0x11
#define RT6190_REG_OUT_VOLT_L 0x12
#define RT6190_REG_TEMP_H 0x1B
#define RT6190_REG_STAT1 0x1C
#define RT6190_REG_ALERT1 0x1E
#define RT6190_REG_ALERT2 0x1F
#define RT6190_REG_MASK2 0x21
#define RT6190_REG_OCPEN 0x28
#define RT6190_REG_SET5 0x29
#define RT6190_REG_VBUSC_ADC 0x32
#define RT6190_REG_BUSC_VOLT_L 0x33
#define RT6190_REG_BUSC_VOLT_H 0x34
#define RT6190_REG_STAT3 0x37
#define RT6190_REG_ALERT3 0x38
#define RT6190_REG_MASK3 0x39
#define RT6190_ENPWM_MASK BIT(7)
#define RT6190_ENDCHG_MASK BIT(4)
#define RT6190_ALERT_OTPEVT BIT(6)
#define RT6190_ALERT_UVPEVT BIT(5)
#define RT6190_ALERT_OVPEVT BIT(4)
#define RT6190_ENGCP_MASK BIT(1)
#define RT6190_FCCM_MASK BIT(7)
#define RICHTEK_VID 0x82
#define RT6190_OUT_MIN_UV 3000000
#define RT6190_OUT_MAX_UV 32000000
#define RT6190_OUT_STEP_UV 20000
#define RT6190_OUT_N_VOLT (RT6190_OUT_MAX_UV / RT6190_OUT_STEP_UV + 1)
#define RT6190_OUTV_MINSEL 150
#define RT6190_OUT_MIN_UA 306000
#define RT6190_OUT_MAX_UA 12114000
#define RT6190_OUT_STEP_UA 24000
#define RT6190_OUTC_MINSEL 19
#define RT6190_EN_TIME_US 500
#define RT6190_PSM_MODE 0
#define RT6190_FCCM_MODE 1
struct rt6190_data {
struct device *dev;
struct regmap *regmap;
struct gpio_desc *enable_gpio;
unsigned int cached_alert_evt;
};
static int rt6190_out_set_voltage_sel(struct regulator_dev *rdev,
unsigned int selector)
{
struct regmap *regmap = rdev_get_regmap(rdev);
__le16 le_sel = cpu_to_le16(selector);
return regmap_raw_write(regmap, RT6190_REG_OUTV, &le_sel,
sizeof(le_sel));
}
static int rt6190_out_get_voltage_sel(struct regulator_dev *rdev)
{
struct regmap *regmap = rdev_get_regmap(rdev);
__le16 le_sel;
int ret;
ret = regmap_raw_read(regmap, RT6190_REG_OUTV, &le_sel, sizeof(le_sel));
return ret ?: le16_to_cpu(le_sel);
}
static int rt6190_out_enable(struct regulator_dev *rdev)
{
struct rt6190_data *data = rdev_get_drvdata(rdev);
struct regmap *regmap = rdev_get_regmap(rdev);
u8 out_cfg[4];
int ret;
pm_runtime_get_sync(data->dev);
/*
* From off to on, vout config will restore to IC default.
* Read vout configs before enable, and restore them after enable
*/
ret = regmap_raw_read(regmap, RT6190_REG_OUTV, out_cfg,
sizeof(out_cfg));
if (ret)
return ret;
ret = regulator_enable_regmap(rdev);
if (ret)
return ret;
ret = regmap_raw_write(regmap, RT6190_REG_OUTV, out_cfg,
sizeof(out_cfg));
if (ret)
return ret;
return regmap_update_bits(regmap, RT6190_REG_SET5, RT6190_ENGCP_MASK,
RT6190_ENGCP_MASK);
}
static int rt6190_out_disable(struct regulator_dev *rdev)
{
struct rt6190_data *data = rdev_get_drvdata(rdev);
struct regmap *regmap = rdev_get_regmap(rdev);
int ret;
ret = regmap_update_bits(regmap, RT6190_REG_SET5, RT6190_ENGCP_MASK, 0);
if (ret)
return ret;
ret = regulator_disable_regmap(rdev);
if (ret)
return ret;
/* cleared cached alert event */
data->cached_alert_evt = 0;
pm_runtime_put(data->dev);
return 0;
}
static int rt6190_out_set_current_limit(struct regulator_dev *rdev, int min_uA,
int max_uA)
{
struct regmap *regmap = rdev_get_regmap(rdev);
int csel, clim;
__le16 le_csel;
if (min_uA < RT6190_OUT_MIN_UA || max_uA > RT6190_OUT_MAX_UA)
return -EINVAL;
csel = DIV_ROUND_UP(min_uA - RT6190_OUT_MIN_UA, RT6190_OUT_STEP_UA);
clim = RT6190_OUT_MIN_UA + RT6190_OUT_STEP_UA * csel;
if (clim > max_uA)
return -EINVAL;
csel += RT6190_OUTC_MINSEL;
le_csel = cpu_to_le16(csel);
return regmap_raw_write(regmap, RT6190_REG_OUTC, &le_csel,
sizeof(le_csel));
}
static int rt6190_out_get_current_limit(struct regulator_dev *rdev)
{
struct regmap *regmap = rdev_get_regmap(rdev);
__le16 le_csel;
int csel, ret;
ret = regmap_raw_read(regmap, RT6190_REG_OUTC, &le_csel,
sizeof(le_csel));
if (ret)
return ret;
csel = le16_to_cpu(le_csel);
csel -= RT6190_OUTC_MINSEL;
return RT6190_OUT_MIN_UA + RT6190_OUT_STEP_UA * csel;
}
static int rt6190_out_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
struct regmap *regmap = rdev_get_regmap(rdev);
unsigned int val;
switch (mode) {
case REGULATOR_MODE_FAST:
val = RT6190_FCCM_MASK;
break;
case REGULATOR_MODE_NORMAL:
val = 0;
break;
default:
return -EINVAL;
}
return regmap_update_bits(regmap, RT6190_REG_SET1, RT6190_FCCM_MASK,
val);
}
static unsigned int rt6190_out_get_mode(struct regulator_dev *rdev)
{
struct regmap *regmap = rdev_get_regmap(rdev);
unsigned int config;
int ret;
ret = regmap_read(regmap, RT6190_REG_SET1, &config);
if (ret)
return REGULATOR_MODE_INVALID;
if (config & RT6190_FCCM_MASK)
return REGULATOR_MODE_FAST;
return REGULATOR_MODE_NORMAL;
}
static int rt6190_out_get_error_flags(struct regulator_dev *rdev,
unsigned int *flags)
{
struct rt6190_data *data = rdev_get_drvdata(rdev);
unsigned int state, rpt_flags = 0;
int ret;
ret = regmap_read(data->regmap, RT6190_REG_STAT1, &state);
if (ret)
return ret;
state |= data->cached_alert_evt;
if (state & RT6190_ALERT_OTPEVT)
rpt_flags |= REGULATOR_ERROR_OVER_TEMP;
if (state & RT6190_ALERT_UVPEVT)
rpt_flags |= REGULATOR_ERROR_UNDER_VOLTAGE;
if (state & RT6190_ALERT_OVPEVT)
rpt_flags |= REGULATOR_ERROR_REGULATION_OUT;
*flags = rpt_flags;
return 0;
}
static unsigned int rt6190_out_of_map_mode(unsigned int mode)
{
switch (mode) {
case RT6190_PSM_MODE:
return REGULATOR_MODE_NORMAL;
case RT6190_FCCM_MODE:
return REGULATOR_MODE_FAST;
default:
return REGULATOR_MODE_INVALID;
}
}
static const struct regulator_ops rt6190_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = rt6190_out_set_voltage_sel,
.get_voltage_sel = rt6190_out_get_voltage_sel,
.enable = rt6190_out_enable,
.disable = rt6190_out_disable,
.is_enabled = regulator_is_enabled_regmap,
.set_current_limit = rt6190_out_set_current_limit,
.get_current_limit = rt6190_out_get_current_limit,
.set_active_discharge = regulator_set_active_discharge_regmap,
.set_mode = rt6190_out_set_mode,
.get_mode = rt6190_out_get_mode,
.get_error_flags = rt6190_out_get_error_flags,
};
static const struct regulator_desc rt6190_regulator_desc = {
.name = "rt6190-regulator",
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.ops = &rt6190_regulator_ops,
.min_uV = RT6190_OUT_MIN_UV,
.uV_step = RT6190_OUT_STEP_UV,
.n_voltages = RT6190_OUT_N_VOLT,
.linear_min_sel = RT6190_OUTV_MINSEL,
.enable_reg = RT6190_REG_SET2,
.enable_mask = RT6190_ENPWM_MASK,
.active_discharge_reg = RT6190_REG_SET2,
.active_discharge_mask = RT6190_ENDCHG_MASK,
.active_discharge_on = RT6190_ENDCHG_MASK,
.of_map_mode = rt6190_out_of_map_mode,
};
static bool rt6190_is_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case RT6190_REG_OUT_VOLT_L ... RT6190_REG_ALERT2:
case RT6190_REG_BUSC_VOLT_L ... RT6190_REG_BUSC_VOLT_H:
case RT6190_REG_STAT3 ... RT6190_REG_ALERT3:
return true;
default:
return false;
}
}
static const struct regmap_config rt6190_regmap_config = {
.name = "rt6190",
.cache_type = REGCACHE_FLAT,
.reg_bits = 8,
.val_bits = 8,
.max_register = RT6190_REG_MASK3,
.num_reg_defaults_raw = RT6190_REG_MASK3 + 1,
.volatile_reg = rt6190_is_volatile_reg,
};
static irqreturn_t rt6190_irq_handler(int irq, void *devid)
{
struct regulator_dev *rdev = devid;
struct rt6190_data *data = rdev_get_drvdata(rdev);
unsigned int alert;
int ret;
ret = regmap_read(data->regmap, RT6190_REG_ALERT1, &alert);
if (ret)
return IRQ_NONE;
/* Write clear alert events */
ret = regmap_write(data->regmap, RT6190_REG_ALERT1, alert);
if (ret)
return IRQ_NONE;
data->cached_alert_evt |= alert;
if (alert & RT6190_ALERT_OTPEVT)
regulator_notifier_call_chain(rdev, REGULATOR_EVENT_OVER_TEMP, NULL);
if (alert & RT6190_ALERT_UVPEVT)
regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE, NULL);
if (alert & RT6190_ALERT_OVPEVT)
regulator_notifier_call_chain(rdev, REGULATOR_EVENT_REGULATION_OUT, NULL);
return IRQ_HANDLED;
}
static int rt6190_init_registers(struct regmap *regmap)
{
int ret;
/* Enable_ADC = 1 */
ret = regmap_write(regmap, RT6190_REG_SET4, 0x82);
if (ret)
return ret;
/* Config default VOUT ratio to be higher */
ret = regmap_write(regmap, RT6190_REG_RATIO, 0x20);
/* Mask unused alert */
ret = regmap_write(regmap, RT6190_REG_MASK2, 0);
if (ret)
return ret;
/* OCP config */
ret = regmap_write(regmap, RT6190_REG_OCPEN, 0);
if (ret)
return ret;
/* Enable VBUSC ADC */
return regmap_write(regmap, RT6190_REG_VBUSC_ADC, 0x02);
}
static int rt6190_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct rt6190_data *data;
struct gpio_desc *enable_gpio;
struct regmap *regmap;
struct regulator_dev *rdev;
struct regulator_config cfg = {};
unsigned int vid;
int ret;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
if (IS_ERR(enable_gpio))
return dev_err_probe(dev, PTR_ERR(enable_gpio), "Failed to get 'enable' gpio\n");
else if (enable_gpio)
usleep_range(RT6190_EN_TIME_US, RT6190_EN_TIME_US * 2);
regmap = devm_regmap_init_i2c(i2c, &rt6190_regmap_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n");
data->dev = dev;
data->enable_gpio = enable_gpio;
data->regmap = regmap;
i2c_set_clientdata(i2c, data);
ret = regmap_read(regmap, RT6190_REG_VID, &vid);
if (ret)
return dev_err_probe(dev, ret, "Failed to read VID\n");
if (vid != RICHTEK_VID)
return dev_err_probe(dev, -ENODEV, "Incorrect VID 0x%02x\n", vid);
ret = rt6190_init_registers(regmap);
if (ret)
return dev_err_probe(dev, ret, "Failed to init registers\n");
pm_runtime_set_active(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to set pm_runtime enable\n");
cfg.dev = dev;
cfg.of_node = dev->of_node;
cfg.driver_data = data;
cfg.init_data = of_get_regulator_init_data(dev, dev->of_node,
&rt6190_regulator_desc);
rdev = devm_regulator_register(dev, &rt6190_regulator_desc, &cfg);
if (IS_ERR(rdev))
return dev_err_probe(dev, PTR_ERR(rdev), "Failed to register regulator\n");
if (i2c->irq) {
ret = devm_request_threaded_irq(dev, i2c->irq, NULL,
rt6190_irq_handler,
IRQF_ONESHOT, dev_name(dev),
rdev);
if (ret)
return dev_err_probe(dev, ret, "Failed to register interrupt\n");
}
return 0;
}
static int rt6190_runtime_suspend(struct device *dev)
{
struct rt6190_data *data = dev_get_drvdata(dev);
struct regmap *regmap = data->regmap;
if (!data->enable_gpio)
return 0;
regcache_cache_only(regmap, true);
regcache_mark_dirty(regmap);
gpiod_set_value(data->enable_gpio, 0);
return 0;
}
static int rt6190_runtime_resume(struct device *dev)
{
struct rt6190_data *data = dev_get_drvdata(dev);
struct regmap *regmap = data->regmap;
if (!data->enable_gpio)
return 0;
gpiod_set_value(data->enable_gpio, 1);
usleep_range(RT6190_EN_TIME_US, RT6190_EN_TIME_US * 2);
regcache_cache_only(regmap, false);
return regcache_sync(regmap);
}
static const struct dev_pm_ops __maybe_unused rt6190_dev_pm = {
RUNTIME_PM_OPS(rt6190_runtime_suspend, rt6190_runtime_resume, NULL)
};
static const struct of_device_id rt6190_of_dev_table[] = {
{ .compatible = "richtek,rt6190" },
{}
};
MODULE_DEVICE_TABLE(of, rt6190_of_dev_table);
static struct i2c_driver rt6190_driver = {
.driver = {
.name = "rt6190",
.of_match_table = rt6190_of_dev_table,
.pm = pm_ptr(&rt6190_dev_pm),
},
.probe_new = rt6190_probe,
};
module_i2c_driver(rt6190_driver);
MODULE_DESCRIPTION("Richtek RT6190 regulator driver");
MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
MODULE_LICENSE("GPL");
......@@ -210,7 +210,7 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev)
pdev->dev.of_node,
&stm32_vrefbuf_regu);
rdev = regulator_register(&stm32_vrefbuf_regu, &config);
rdev = regulator_register(&pdev->dev, &stm32_vrefbuf_regu, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&pdev->dev, "register failed with error %d\n", ret);
......
......@@ -123,7 +123,7 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c)
return 0;
}
static const struct of_device_id __maybe_unused sy8106a_i2c_of_match[] = {
static const struct of_device_id sy8106a_i2c_of_match[] = {
{ .compatible = "silergy,sy8106a" },
{ },
};
......@@ -138,7 +138,7 @@ MODULE_DEVICE_TABLE(i2c, sy8106a_i2c_id);
static struct i2c_driver sy8106a_regulator_driver = {
.driver = {
.name = "sy8106a",
.of_match_table = of_match_ptr(sy8106a_i2c_of_match),
.of_match_table = sy8106a_i2c_of_match,
},
.probe_new = sy8106a_i2c_probe,
.id_table = sy8106a_i2c_id,
......
......@@ -233,7 +233,7 @@ MODULE_DEVICE_TABLE(i2c, sy8824_id);
static struct i2c_driver sy8824_regulator_driver = {
.driver = {
.name = "sy8824-regulator",
.of_match_table = of_match_ptr(sy8824_dt_ids),
.of_match_table = sy8824_dt_ids,
},
.probe_new = sy8824_i2c_probe,
.id_table = sy8824_id,
......
......@@ -170,7 +170,6 @@ static int sy8827n_i2c_probe(struct i2c_client *client)
return ret;
}
#ifdef CONFIG_OF
static const struct of_device_id sy8827n_dt_ids[] = {
{
.compatible = "silergy,sy8827n",
......@@ -178,7 +177,6 @@ static const struct of_device_id sy8827n_dt_ids[] = {
{ }
};
MODULE_DEVICE_TABLE(of, sy8827n_dt_ids);
#endif
static const struct i2c_device_id sy8827n_id[] = {
{ "sy8827n", },
......@@ -189,7 +187,7 @@ MODULE_DEVICE_TABLE(i2c, sy8827n_id);
static struct i2c_driver sy8827n_regulator_driver = {
.driver = {
.name = "sy8827n-regulator",
.of_match_table = of_match_ptr(sy8827n_dt_ids),
.of_match_table = sy8827n_dt_ids,
},
.probe_new = sy8827n_i2c_probe,
.id_table = sy8827n_id,
......
......@@ -247,8 +247,7 @@ static struct tps51632_regulator_platform_data *
}
#endif
static int tps51632_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int tps51632_probe(struct i2c_client *client)
{
struct tps51632_regulator_platform_data *pdata;
struct regulator_dev *rdev;
......@@ -354,7 +353,7 @@ static struct i2c_driver tps51632_i2c_driver = {
.name = "tps51632",
.of_match_table = of_match_ptr(tps51632_of_match),
},
.probe = tps51632_probe,
.probe_new = tps51632_probe,
.id_table = tps51632_id,
};
......
......@@ -322,9 +322,9 @@ static const struct of_device_id tps62360_of_match[] = {
MODULE_DEVICE_TABLE(of, tps62360_of_match);
#endif
static int tps62360_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int tps62360_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct regulator_config config = { };
struct tps62360_regulator_platform_data *pdata;
struct regulator_dev *rdev;
......@@ -497,7 +497,7 @@ static struct i2c_driver tps62360_i2c_driver = {
.name = "tps62360",
.of_match_table = of_match_ptr(tps62360_of_match),
},
.probe = tps62360_probe,
.probe_new = tps62360_probe,
.shutdown = tps62360_shutdown,
.id_table = tps62360_id,
};
......
......@@ -111,8 +111,7 @@ static const struct of_device_id tps6286x_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, tps6286x_dt_ids);
static int tps6286x_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int tps6286x_i2c_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct regulator_config config = {};
......@@ -150,7 +149,7 @@ static struct i2c_driver tps6286x_regulator_driver = {
.name = "tps6286x",
.of_match_table = of_match_ptr(tps6286x_dt_ids),
},
.probe = tps6286x_i2c_probe,
.probe_new = tps6286x_i2c_probe,
.id_table = tps6286x_i2c_id,
};
......
......@@ -257,9 +257,9 @@ static struct tps_driver_data tps65023_drv_data = {
.core_regulator = TPS65023_DCDC_1,
};
static int tps_65023_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int tps_65023_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct regulator_init_data *init_data = dev_get_platdata(&client->dev);
struct regulator_config config = { };
struct tps_pmic *tps;
......@@ -336,7 +336,7 @@ static struct i2c_driver tps_65023_i2c_driver = {
.name = "tps65023",
.of_match_table = of_match_ptr(tps65023_of_match),
},
.probe = tps_65023_probe,
.probe_new = tps_65023_probe,
.id_table = tps_65023_id,
};
......
......@@ -14,6 +14,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/userspace-consumer.h>
......@@ -24,6 +25,7 @@ struct userspace_consumer_data {
struct mutex lock;
bool enabled;
bool no_autoswitch;
int num_supplies;
struct regulator_bulk_data *supplies;
......@@ -96,19 +98,50 @@ static struct attribute *attributes[] = {
NULL,
};
static umode_t attr_visible(struct kobject *kobj, struct attribute *attr, int idx)
{
struct device *dev = kobj_to_dev(kobj);
struct userspace_consumer_data *data = dev_get_drvdata(dev);
/* If a name hasn't been set, don't bother with the attribute */
if (attr == &dev_attr_name.attr && !data->name)
return 0;
return attr->mode;
}
static const struct attribute_group attr_group = {
.attrs = attributes,
.is_visible = attr_visible,
};
static int regulator_userspace_consumer_probe(struct platform_device *pdev)
{
struct regulator_userspace_consumer_data tmpdata;
struct regulator_userspace_consumer_data *pdata;
struct userspace_consumer_data *drvdata;
int ret;
pdata = dev_get_platdata(&pdev->dev);
if (!pdata)
if (!pdata) {
if (!pdev->dev.of_node)
return -EINVAL;
pdata = &tmpdata;
memset(pdata, 0, sizeof(*pdata));
pdata->no_autoswitch = true;
pdata->num_supplies = 1;
pdata->supplies = devm_kzalloc(&pdev->dev, sizeof(*pdata->supplies), GFP_KERNEL);
if (!pdata->supplies)
return -ENOMEM;
pdata->supplies[0].supply = "vout";
}
if (pdata->num_supplies < 1) {
dev_err(&pdev->dev, "At least one supply required\n");
return -EINVAL;
}
drvdata = devm_kzalloc(&pdev->dev,
sizeof(struct userspace_consumer_data),
......@@ -119,21 +152,24 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev)
drvdata->name = pdata->name;
drvdata->num_supplies = pdata->num_supplies;
drvdata->supplies = pdata->supplies;
drvdata->no_autoswitch = pdata->no_autoswitch;
mutex_init(&drvdata->lock);
ret = devm_regulator_bulk_get(&pdev->dev, drvdata->num_supplies,
drvdata->supplies);
ret = devm_regulator_bulk_get_exclusive(&pdev->dev, drvdata->num_supplies,
drvdata->supplies);
if (ret) {
dev_err(&pdev->dev, "Failed to get supplies: %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, drvdata);
ret = sysfs_create_group(&pdev->dev.kobj, &attr_group);
if (ret != 0)
return ret;
if (pdata->init_on) {
if (pdata->init_on && !pdata->no_autoswitch) {
ret = regulator_bulk_enable(drvdata->num_supplies,
drvdata->supplies);
if (ret) {
......@@ -143,8 +179,12 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev)
}
}
drvdata->enabled = pdata->init_on;
platform_set_drvdata(pdev, drvdata);
ret = regulator_is_enabled(pdata->supplies[0].consumer);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get regulator status\n");
goto err_enable;
}
drvdata->enabled = !!ret;
return 0;
......@@ -160,17 +200,23 @@ static int regulator_userspace_consumer_remove(struct platform_device *pdev)
sysfs_remove_group(&pdev->dev.kobj, &attr_group);
if (data->enabled)
if (data->enabled && !data->no_autoswitch)
regulator_bulk_disable(data->num_supplies, data->supplies);
return 0;
}
static const struct of_device_id regulator_userspace_consumer_of_match[] = {
{ .compatible = "regulator-output", },
{},
};
static struct platform_driver regulator_userspace_consumer_driver = {
.probe = regulator_userspace_consumer_probe,
.remove = regulator_userspace_consumer_remove,
.driver = {
.name = "reg-userspace-consumer",
.of_match_table = regulator_userspace_consumer_of_match,
},
};
......
......@@ -244,9 +244,13 @@ int regulator_disable_deferred(struct regulator *regulator, int ms);
int __must_check regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers);
int __must_check of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
struct regulator_bulk_data **consumers);
int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers);
void devm_regulator_bulk_put(struct regulator_bulk_data *consumers);
int __must_check devm_regulator_bulk_get_exclusive(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers);
int __must_check devm_regulator_bulk_get_const(
struct device *dev, int num_consumers,
const struct regulator_bulk_data *in_consumers,
......@@ -479,6 +483,12 @@ static inline int devm_regulator_bulk_get(struct device *dev, int num_consumers,
return 0;
}
static inline int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
struct regulator_bulk_data **consumers)
{
return 0;
}
static inline int regulator_bulk_enable(int num_consumers,
struct regulator_bulk_data *consumers)
{
......
......@@ -687,7 +687,8 @@ static inline int regulator_err2notif(int err)
struct regulator_dev *
regulator_register(const struct regulator_desc *regulator_desc,
regulator_register(struct device *dev,
const struct regulator_desc *regulator_desc,
const struct regulator_config *config);
struct regulator_dev *
devm_regulator_register(struct device *dev,
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2022 MediaTek Inc.
*/
#ifndef __LINUX_REGULATOR_MT6357_H
#define __LINUX_REGULATOR_MT6357_H
enum {
/* Bucks */
MT6357_ID_VCORE,
MT6357_ID_VMODEM,
MT6357_ID_VPA,
MT6357_ID_VPROC,
MT6357_ID_VS1,
/* LDOs */
MT6357_ID_VAUX18,
MT6357_ID_VAUD28,
MT6357_ID_VCAMA,
MT6357_ID_VCAMD,
MT6357_ID_VCAMIO,
MT6357_ID_VCN18,
MT6357_ID_VCN28,
MT6357_ID_VCN33_BT,
MT6357_ID_VCN33_WIFI,
MT6357_ID_VDRAM,
MT6357_ID_VEFUSE,
MT6357_ID_VEMC,
MT6357_ID_VFE28,
MT6357_ID_VIBR,
MT6357_ID_VIO18,
MT6357_ID_VIO28,
MT6357_ID_VLDO28,
MT6357_ID_VMC,
MT6357_ID_VMCH,
MT6357_ID_VRF12,
MT6357_ID_VRF18,
MT6357_ID_VSIM1,
MT6357_ID_VSIM2,
MT6357_ID_VSRAM_OTHERS,
MT6357_ID_VSRAM_PROC,
MT6357_ID_VUSB33,
MT6357_ID_VXO22,
MT6357_ID_RG_MAX,
};
#define MT6357_MAX_REGULATOR MT6357_ID_RG_MAX
#endif /* __LINUX_REGULATOR_MT6357_H */
......@@ -21,6 +21,7 @@ struct regulator_userspace_consumer_data {
struct regulator_bulk_data *supplies;
bool init_on;
bool no_autoswitch;
};
#endif /* __REGULATOR_PLATFORM_CONSUMER_H_ */
......@@ -19,6 +19,7 @@ struct qcom_smd_rpm;
#define QCOM_SMD_RPM_CLK_BUF_A 0x616B6C63
#define QCOM_SMD_RPM_LDOA 0x616f646c
#define QCOM_SMD_RPM_LDOB 0x626F646C
#define QCOM_SMD_RPM_LDOE 0x656f646c
#define QCOM_SMD_RPM_RWCX 0x78637772
#define QCOM_SMD_RPM_RWMX 0x786d7772
#define QCOM_SMD_RPM_RWLC 0x636c7772
......@@ -32,6 +33,7 @@ struct qcom_smd_rpm;
#define QCOM_SMD_RPM_QUP_CLK 0x707571
#define QCOM_SMD_RPM_SMPA 0x61706d73
#define QCOM_SMD_RPM_SMPB 0x62706d73
#define QCOM_SMD_RPM_SMPE 0x65706d73
#define QCOM_SMD_RPM_SPDM 0x63707362
#define QCOM_SMD_RPM_VSA 0x00617376
#define QCOM_SMD_RPM_MMAXI_CLK 0x69786d6d
......
......@@ -107,17 +107,8 @@ static const unsigned int range2_vals[] = { RANGE2_MIN, RANGE2_MIN +
#define SMALLEST_VAL RANGE1_MIN
static struct linear_range testr[] = {
{
.min = RANGE1_MIN,
.min_sel = RANGE1_MIN_SEL,
.max_sel = RANGE1_MAX_SEL,
.step = RANGE1_STEP,
}, {
.min = RANGE2_MIN,
.min_sel = RANGE2_MIN_SEL,
.max_sel = RANGE2_MAX_SEL,
.step = RANGE2_STEP
},
LINEAR_RANGE(RANGE1_MIN, RANGE1_MIN_SEL, RANGE1_MAX_SEL, RANGE1_STEP),
LINEAR_RANGE(RANGE2_MIN, RANGE2_MIN_SEL, RANGE2_MAX_SEL, RANGE2_STEP),
};
static void range_test_get_value(struct kunit *test)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment