regulator: Updates for v6.2

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.
 
  - 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.
 
 There's a cross tree merge with the I2C tree in order to use the new
 i2c_client_get_device_id() helper in the conversions to probe_new().
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmOXIIcACgkQJNaLcl1U
 h9DW8Af/SkLjUIhuMYrln1QBKvJfMOzAIOo8LeCRCU6E8IxsDu/zccEva6dqr/M/
 DFkq5VBCH7cX7VIvaHLjED/VdM0n+JG35tzwv83TVuAohLW/qsRdO6RE9IRBJcUd
 7wUj2gjUBjjnCwbpI0hTygqQHvIxO0deQVYoQsxF8VwJTQ+ufpA3TJ3tmxqeWvbd
 N/qkLohCk9NoFgiMjzBxBonacaZEvHkjUtqRthHm/nx8Mdu9NhBb6ai6KIpN7EJD
 CaY+nUOx/cW8YJWBaZ32bcnvRgtanJGWn+p49/JmUCu0lIEOX2r7jds/kBo/hWWl
 akGDUTcmvZY0CfrJfbx+FJxcA1A7Jg==
 =Dmpg
 -----END PGP SIGNATURE-----

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()
  ...
This commit is contained in:
Linus Torvalds 2022-12-13 12:49:59 -08:00
commit c5589c436d
65 changed files with 1998 additions and 288 deletions

View File

@ -100,14 +100,12 @@ examples:
compatible = "maxim,max77650-regulator"; compatible = "maxim,max77650-regulator";
max77650_ldo: regulator-ldo { max77650_ldo: regulator-ldo {
regulator-compatible = "ldo";
regulator-name = "max77650-ldo"; regulator-name = "max77650-ldo";
regulator-min-microvolt = <1350000>; regulator-min-microvolt = <1350000>;
regulator-max-microvolt = <2937500>; regulator-max-microvolt = <2937500>;
}; };
max77650_sbb0: regulator-sbb0 { max77650_sbb0: regulator-sbb0 {
regulator-compatible = "sbb0";
regulator-name = "max77650-sbb0"; regulator-name = "max77650-sbb0";
regulator-min-microvolt = <800000>; regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1587500>; regulator-max-microvolt = <1587500>;

View File

@ -83,7 +83,6 @@ examples:
richtek,vinovp-microvolt = <14500000>; richtek,vinovp-microvolt = <14500000>;
otg_vbus_regulator: usb-otg-vbus-regulator { otg_vbus_regulator: usb-otg-vbus-regulator {
regulator-compatible = "usb-otg-vbus";
regulator-name = "usb-otg-vbus"; regulator-name = "usb-otg-vbus";
regulator-min-microvolt = <4425000>; regulator-min-microvolt = <4425000>;
regulator-max-microvolt = <5825000>; regulator-max-microvolt = <5825000>;
@ -145,7 +144,6 @@ examples:
compatible = "mediatek,mt6360-regulator"; compatible = "mediatek,mt6360-regulator";
LDO_VIN3-supply = <&BUCK2>; LDO_VIN3-supply = <&BUCK2>;
buck1 { buck1 {
regulator-compatible = "BUCK1";
regulator-name = "mt6360,buck1"; regulator-name = "mt6360,buck1";
regulator-min-microvolt = <300000>; regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1300000>; regulator-max-microvolt = <1300000>;
@ -154,7 +152,6 @@ examples:
MT6360_OPMODE_ULP>; MT6360_OPMODE_ULP>;
}; };
BUCK2: buck2 { BUCK2: buck2 {
regulator-compatible = "BUCK2";
regulator-name = "mt6360,buck2"; regulator-name = "mt6360,buck2";
regulator-min-microvolt = <300000>; regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1300000>; regulator-max-microvolt = <1300000>;
@ -163,7 +160,6 @@ examples:
MT6360_OPMODE_ULP>; MT6360_OPMODE_ULP>;
}; };
ldo6 { ldo6 {
regulator-compatible = "LDO6";
regulator-name = "mt6360,ldo6"; regulator-name = "mt6360,ldo6";
regulator-min-microvolt = <500000>; regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2100000>; regulator-max-microvolt = <2100000>;
@ -171,7 +167,6 @@ examples:
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo7 { ldo7 {
regulator-compatible = "LDO7";
regulator-name = "mt6360,ldo7"; regulator-name = "mt6360,ldo7";
regulator-min-microvolt = <500000>; regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2100000>; regulator-max-microvolt = <2100000>;
@ -179,7 +174,6 @@ examples:
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo1 { ldo1 {
regulator-compatible = "LDO1";
regulator-name = "mt6360,ldo1"; regulator-name = "mt6360,ldo1";
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>; regulator-max-microvolt = <3600000>;
@ -187,7 +181,6 @@ examples:
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo2 { ldo2 {
regulator-compatible = "LDO2";
regulator-name = "mt6360,ldo2"; regulator-name = "mt6360,ldo2";
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>; regulator-max-microvolt = <3600000>;
@ -195,7 +188,6 @@ examples:
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo3 { ldo3 {
regulator-compatible = "LDO3";
regulator-name = "mt6360,ldo3"; regulator-name = "mt6360,ldo3";
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>; regulator-max-microvolt = <3600000>;
@ -203,7 +195,6 @@ examples:
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo5 { ldo5 {
regulator-compatible = "LDO5";
regulator-name = "mt6360,ldo5"; regulator-name = "mt6360,ldo5";
regulator-min-microvolt = <2700000>; regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3600000>; regulator-max-microvolt = <3600000>;

View File

@ -26,6 +26,7 @@ properties:
type: object type: object
description: OTG boost regulator. description: OTG boost regulator.
$ref: /schemas/regulator/regulator.yaml# $ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
required: required:
- compatible - compatible
@ -39,7 +40,6 @@ examples:
richtek,vinovp-microvolt = <14500000>; richtek,vinovp-microvolt = <14500000>;
otg_vbus_regulator: usb-otg-vbus-regulator { otg_vbus_regulator: usb-otg-vbus-regulator {
regulator-compatible = "usb-otg-vbus";
regulator-name = "usb-otg-vbus"; regulator-name = "usb-otg-vbus";
regulator-min-microvolt = <4425000>; regulator-min-microvolt = <4425000>;
regulator-max-microvolt = <5825000>; regulator-max-microvolt = <5825000>;

View File

@ -26,6 +26,7 @@ properties:
patternProperties: patternProperties:
"^regulator-(ldo|sbb[0-2])$": "^regulator-(ldo|sbb[0-2])$":
$ref: "regulator.yaml#" $ref: "regulator.yaml#"
unevaluatedProperties: false
required: required:
- compatible - compatible

View File

@ -26,6 +26,7 @@ properties:
patternProperties: patternProperties:
"regulator-.+": "regulator-.+":
$ref: "regulator.yaml#" $ref: "regulator.yaml#"
unevaluatedProperties: false
additionalProperties: false additionalProperties: false
@ -43,31 +44,26 @@ examples:
regulators { regulators {
regulator-V3 { regulator-V3 {
regulator-compatible= "V3(DCDC)";
regulator-min-microvolt = <725000>; regulator-min-microvolt = <725000>;
regulator-max-microvolt = <1800000>; regulator-max-microvolt = <1800000>;
}; };
regulator-V4 { regulator-V4 {
regulator-compatible= "V4(DCDC)";
regulator-min-microvolt = <725000>; regulator-min-microvolt = <725000>;
regulator-max-microvolt = <1800000>; regulator-max-microvolt = <1800000>;
}; };
regulator-V5 { regulator-V5 {
regulator-compatible= "V5(LDO)";
regulator-min-microvolt = <1700000>; regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <2000000>; regulator-max-microvolt = <2000000>;
}; };
regulator-V6 { regulator-V6 {
regulator-compatible= "V6(LDO)";
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
}; };
regulator-V7 { regulator-V7 {
regulator-compatible= "V7(LDO)";
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
}; };

View File

@ -0,0 +1,294 @@
# 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>;
};
};
};
...

View File

@ -27,9 +27,11 @@ properties:
patternProperties: patternProperties:
"^buck[12]$": "^buck[12]$":
$ref: "regulator.yaml#" $ref: "regulator.yaml#"
unevaluatedProperties: false
"^ldo[123567]$": "^ldo[123567]$":
$ref: "regulator.yaml#" $ref: "regulator.yaml#"
unevaluatedProperties: false
required: required:
- compatible - compatible
@ -44,7 +46,6 @@ examples:
compatible = "mediatek,mt6360-regulator"; compatible = "mediatek,mt6360-regulator";
LDO_VIN3-supply = <&BUCK2>; LDO_VIN3-supply = <&BUCK2>;
buck1 { buck1 {
regulator-compatible = "BUCK1";
regulator-name = "mt6360,buck1"; regulator-name = "mt6360,buck1";
regulator-min-microvolt = <300000>; regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1300000>; regulator-max-microvolt = <1300000>;
@ -53,7 +54,6 @@ examples:
MT6360_OPMODE_ULP>; MT6360_OPMODE_ULP>;
}; };
BUCK2: buck2 { BUCK2: buck2 {
regulator-compatible = "BUCK2";
regulator-name = "mt6360,buck2"; regulator-name = "mt6360,buck2";
regulator-min-microvolt = <300000>; regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1300000>; regulator-max-microvolt = <1300000>;
@ -62,7 +62,6 @@ examples:
MT6360_OPMODE_ULP>; MT6360_OPMODE_ULP>;
}; };
ldo6 { ldo6 {
regulator-compatible = "LDO6";
regulator-name = "mt6360,ldo6"; regulator-name = "mt6360,ldo6";
regulator-min-microvolt = <500000>; regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2100000>; regulator-max-microvolt = <2100000>;
@ -70,7 +69,6 @@ examples:
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo7 { ldo7 {
regulator-compatible = "LDO7";
regulator-name = "mt6360,ldo7"; regulator-name = "mt6360,ldo7";
regulator-min-microvolt = <500000>; regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2100000>; regulator-max-microvolt = <2100000>;
@ -78,15 +76,13 @@ examples:
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo1 { ldo1 {
regulator-compatible = "LDO1";
regulator-name = "mt6360,ldo1"; regulator-name = "mt6360,ldo1";
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>; regulator-max-microvolt = <3600000>;
regulator-allowed-modes = <MT6360_OPMODE_NORMAL regulator-allowed-modes = <MT6360_OPMODE_NORMAL
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo2 { ldo2 {
regulator-compatible = "LDO2";
regulator-name = "mt6360,ldo2"; regulator-name = "mt6360,ldo2";
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>; regulator-max-microvolt = <3600000>;
@ -94,7 +90,6 @@ examples:
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo3 { ldo3 {
regulator-compatible = "LDO3";
regulator-name = "mt6360,ldo3"; regulator-name = "mt6360,ldo3";
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>; regulator-max-microvolt = <3600000>;
@ -102,7 +97,6 @@ examples:
MT6360_OPMODE_LP>; MT6360_OPMODE_LP>;
}; };
ldo5 { ldo5 {
regulator-compatible = "LDO5";
regulator-name = "mt6360,ldo5"; regulator-name = "mt6360,ldo5";
regulator-min-microvolt = <2700000>; regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3600000>; regulator-max-microvolt = <3600000>;

View File

@ -47,6 +47,7 @@ description: |
For PM8350, smps1 - smps12, ldo1 - ldo10 For PM8350, smps1 - smps12, ldo1 - ldo10
For PM8350C, smps1 - smps10, ldo1 - ldo13, bob For PM8350C, smps1 - smps10, ldo1 - ldo13, bob
For PM8450, smps1 - smps6, ldo1 - ldo4 For PM8450, smps1 - smps6, ldo1 - ldo4
For PM8550, smps1 - smps6, ldo1 - ldo17, bob1 - bob2
For PM8998, smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2 For PM8998, smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
For PMI8998, bob For PMI8998, bob
For PMR735A, smps1 - smps3, ldo1 - ldo7 For PMR735A, smps1 - smps3, ldo1 - ldo7
@ -70,6 +71,9 @@ properties:
- qcom,pm8350-rpmh-regulators - qcom,pm8350-rpmh-regulators
- qcom,pm8350c-rpmh-regulators - qcom,pm8350c-rpmh-regulators
- qcom,pm8450-rpmh-regulators - qcom,pm8450-rpmh-regulators
- qcom,pm8550-rpmh-regulators
- qcom,pm8550ve-rpmh-regulators
- qcom,pm8550vs-rpmh-regulators
- qcom,pm8998-rpmh-regulators - qcom,pm8998-rpmh-regulators
- qcom,pmg1110-rpmh-regulators - qcom,pmg1110-rpmh-regulators
- qcom,pmi8998-rpmh-regulators - qcom,pmi8998-rpmh-regulators
@ -83,7 +87,7 @@ properties:
RPMh resource name suffix used for the regulators found RPMh resource name suffix used for the regulators found
on this PMIC. on this PMIC.
$ref: /schemas/types.yaml#/definitions/string $ref: /schemas/types.yaml#/definitions/string
enum: [a, b, c, d, e, f, h, k] enum: [a, b, c, d, e, f, g, h, k]
qcom,always-wait-for-ack: qcom,always-wait-for-ack:
description: | description: |
@ -107,7 +111,7 @@ properties:
regulator-allow-set-load: ["regulator-allowed-modes"] regulator-allow-set-load: ["regulator-allowed-modes"]
patternProperties: patternProperties:
"^(smps|ldo|lvs)[0-9]+$": "^(smps|ldo|lvs|bob)[0-9]+$":
type: object type: object
$ref: "regulator.yaml#" $ref: "regulator.yaml#"
description: smps/ldo regulator nodes(s). description: smps/ldo regulator nodes(s).
@ -299,6 +303,24 @@ allOf:
"^vdd-l[1-4]-supply$": true "^vdd-l[1-4]-supply$": true
"^vdd-s[1-6]-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: - if:
properties: properties:
compatible: compatible:
@ -412,9 +434,8 @@ examples:
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>; regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
regulator-allowed-modes = regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
<RPMH_REGULATOR_MODE_LPM RPMH_REGULATOR_MODE_HPM>;
RPMH_REGULATOR_MODE_HPM>;
regulator-allow-set-load; regulator-allow-set-load;
}; };
@ -431,9 +452,8 @@ examples:
bob { bob {
regulator-min-microvolt = <3312000>; regulator-min-microvolt = <3312000>;
regulator-max-microvolt = <3600000>; regulator-max-microvolt = <3600000>;
regulator-allowed-modes = regulator-allowed-modes = <RPMH_REGULATOR_MODE_AUTO
<RPMH_REGULATOR_MODE_AUTO RPMH_REGULATOR_MODE_HPM>;
RPMH_REGULATOR_MODE_HPM>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
}; };
}; };

View File

@ -71,6 +71,8 @@ description:
For pmi8998, bob 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, For pms405, s1, s2, s3, s4, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
l12, l13 l12, l13
@ -98,6 +100,7 @@ properties:
- qcom,rpm-pma8084-regulators - qcom,rpm-pma8084-regulators
- qcom,rpm-pmi8994-regulators - qcom,rpm-pmi8994-regulators
- qcom,rpm-pmi8998-regulators - qcom,rpm-pmi8998-regulators
- qcom,rpm-pmr735a-regulators
- qcom,rpm-pms405-regulators - qcom,rpm-pms405-regulators
patternProperties: patternProperties:

View File

@ -0,0 +1,39 @@
# 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>;
};

View File

@ -0,0 +1,79 @@
# 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>;
};
};

View File

@ -417,6 +417,7 @@ PWM
REGULATOR REGULATOR
devm_regulator_bulk_register_supply_alias() devm_regulator_bulk_register_supply_alias()
devm_regulator_bulk_get() devm_regulator_bulk_get()
devm_regulator_bulk_get_const()
devm_regulator_bulk_get_enable() devm_regulator_bulk_get_enable()
devm_regulator_bulk_put() devm_regulator_bulk_put()
devm_regulator_get() devm_regulator_get()

View File

@ -185,7 +185,8 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
cfg.init_data = &init_data; cfg.init_data = &init_data;
cfg.ena_gpiod = int3472->regulator.gpio; 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); &cfg);
if (IS_ERR(int3472->regulator.rdev)) { if (IS_ERR(int3472->regulator.rdev)) {
ret = PTR_ERR(int3472->regulator.rdev); ret = PTR_ERR(int3472->regulator.rdev);

View File

@ -377,7 +377,7 @@ config REGULATOR_FAN53555
config REGULATOR_FAN53880 config REGULATOR_FAN53880
tristate "Fairchild FAN53880 Regulator" tristate "Fairchild FAN53880 Regulator"
depends on I2C && (OF || COMPILE_TEST) depends on I2C && OF
select REGMAP_I2C select REGMAP_I2C
help help
This driver supports Fairchild (ON Semiconductor) FAN53880 This driver supports Fairchild (ON Semiconductor) FAN53880
@ -743,7 +743,7 @@ config REGULATOR_MP8859
config REGULATOR_MP886X config REGULATOR_MP886X
tristate "MPS MP8869 regulator driver" tristate "MPS MP8869 regulator driver"
depends on I2C && (OF || COMPILE_TEST) depends on I2C && OF
select REGMAP_I2C select REGMAP_I2C
help help
This driver supports the MP8869 voltage regulator. 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 This driver supports the control of different power rails of device
through regulator interface 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 config REGULATOR_MT6358
tristate "MediaTek MT6358 PMIC" tristate "MediaTek MT6358 PMIC"
depends on MFD_MT6397 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 The wide output range is from 2025mV to 5200mV and can be used on most
common application scenario. 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 config REGULATOR_RT6245
tristate "Richtek RT6245 voltage regulator" tristate "Richtek RT6245 voltage regulator"
depends on I2C depends on I2C
@ -1288,21 +1308,21 @@ config REGULATOR_SY7636A
config REGULATOR_SY8106A config REGULATOR_SY8106A
tristate "Silergy SY8106A regulator" tristate "Silergy SY8106A regulator"
depends on I2C && (OF || COMPILE_TEST) depends on I2C && OF
select REGMAP_I2C select REGMAP_I2C
help help
This driver supports SY8106A single output regulator. This driver supports SY8106A single output regulator.
config REGULATOR_SY8824X config REGULATOR_SY8824X
tristate "Silergy SY8824C/SY8824E regulator" tristate "Silergy SY8824C/SY8824E regulator"
depends on I2C && (OF || COMPILE_TEST) depends on I2C && OF
select REGMAP_I2C select REGMAP_I2C
help help
This driver supports SY8824C single output regulator. This driver supports SY8824C single output regulator.
config REGULATOR_SY8827N config REGULATOR_SY8827N
tristate "Silergy SY8827N regulator" tristate "Silergy SY8827N regulator"
depends on I2C && (OF || COMPILE_TEST) depends on I2C && OF
select REGMAP_I2C select REGMAP_I2C
help help
This driver supports SY8827N single output regulator. This driver supports SY8827N single output regulator.

View File

@ -97,6 +97,7 @@ obj-$(CONFIG_REGULATOR_MT6315) += mt6315-regulator.o
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6331) += mt6331-regulator.o obj-$(CONFIG_REGULATOR_MT6331) += mt6331-regulator.o
obj-$(CONFIG_REGULATOR_MT6332) += mt6332-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_MT6358) += mt6358-regulator.o
obj-$(CONFIG_REGULATOR_MT6359) += mt6359-regulator.o obj-$(CONFIG_REGULATOR_MT6359) += mt6359-regulator.o
obj-$(CONFIG_REGULATOR_MT6360) += mt6360-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_RT5190A) += rt5190a-regulator.o
obj-$(CONFIG_REGULATOR_RT5759) += rt5759-regulator.o obj-$(CONFIG_REGULATOR_RT5759) += rt5759-regulator.o
obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o
obj-$(CONFIG_REGULATOR_RT6190) += rt6190-regulator.o
obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o
obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
obj-$(CONFIG_REGULATOR_RTQ2134) += rtq2134-regulator.o obj-$(CONFIG_REGULATOR_RTQ2134) += rtq2134-regulator.o

View File

@ -651,9 +651,9 @@ static int act8600_charger_probe(struct device *dev, struct regmap *regmap)
return PTR_ERR_OR_ZERO(charger); return PTR_ERR_OR_ZERO(charger);
} }
static int act8865_pmic_probe(struct i2c_client *client, static int act8865_pmic_probe(struct i2c_client *client)
const struct i2c_device_id *i2c_id)
{ {
const struct i2c_device_id *i2c_id = i2c_client_get_device_id(client);
const struct regulator_desc *regulators; const struct regulator_desc *regulators;
struct act8865_platform_data *pdata = NULL; struct act8865_platform_data *pdata = NULL;
struct device *dev = &client->dev; struct device *dev = &client->dev;
@ -790,7 +790,7 @@ static struct i2c_driver act8865_pmic_driver = {
.driver = { .driver = {
.name = "act8865", .name = "act8865",
}, },
.probe = act8865_pmic_probe, .probe_new = act8865_pmic_probe,
.id_table = act8865_ids, .id_table = act8865_ids,
}; };

View File

@ -212,9 +212,9 @@ static const struct i2c_device_id ad5398_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, ad5398_id); MODULE_DEVICE_TABLE(i2c, ad5398_id);
static int ad5398_probe(struct i2c_client *client, static int ad5398_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
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_init_data *init_data = dev_get_platdata(&client->dev);
struct regulator_config config = { }; struct regulator_config config = { };
struct ad5398_chip_info *chip; struct ad5398_chip_info *chip;
@ -254,7 +254,7 @@ static int ad5398_probe(struct i2c_client *client,
} }
static struct i2c_driver ad5398_driver = { static struct i2c_driver ad5398_driver = {
.probe = ad5398_probe, .probe_new = ad5398_probe,
.driver = { .driver = {
.name = "ad5398", .name = "ad5398",
}, },

View File

@ -34,7 +34,7 @@ struct arizona_micsupp {
struct regulator_dev *regulator; struct regulator_dev *regulator;
struct regmap *regmap; struct regmap *regmap;
struct snd_soc_dapm_context **dapm; struct snd_soc_dapm_context **dapm;
unsigned int enable_reg; const struct regulator_desc *desc;
struct device *dev; struct device *dev;
struct regulator_consumer_supply supply; 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); container_of(work, struct arizona_micsupp, check_cp_work);
struct snd_soc_dapm_context *dapm = *micsupp->dapm; struct snd_soc_dapm_context *dapm = *micsupp->dapm;
struct snd_soc_component *component; struct snd_soc_component *component;
const struct regulator_desc *desc = micsupp->desc;
unsigned int val; unsigned int val;
int ret; int ret;
ret = regmap_read(micsupp->regmap, micsupp->enable_reg, &val); ret = regmap_read(micsupp->regmap, desc->enable_reg, &val);
if (ret != 0) { if (ret != 0) {
dev_err(micsupp->dev, dev_err(micsupp->dev,
"Failed to read CP state: %d\n", ret); "Failed to read CP state: %d\n", ret);
@ -62,8 +63,8 @@ static void arizona_micsupp_check_cp(struct work_struct *work)
if (dapm) { if (dapm) {
component = snd_soc_dapm_to_component(dapm); component = snd_soc_dapm_to_component(dapm);
if ((val & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) == if ((val & (desc->enable_mask | desc->bypass_mask)) ==
ARIZONA_CPMIC_ENA) desc->enable_mask)
snd_soc_component_force_enable_pin(component, snd_soc_component_force_enable_pin(component,
"MICSUPP"); "MICSUPP");
else else
@ -209,7 +210,6 @@ static const struct regulator_desc madera_micsupp = {
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = 40, .n_voltages = 40,
.ops = &arizona_micsupp_ops, .ops = &arizona_micsupp_ops,
.vsel_reg = MADERA_LDO2_CONTROL_1, .vsel_reg = MADERA_LDO2_CONTROL_1,
.vsel_mask = MADERA_LDO2_VSEL_MASK, .vsel_mask = MADERA_LDO2_VSEL_MASK,
.enable_reg = MADERA_MIC_CHARGE_PUMP_1, .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); INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp);
micsupp->init_data.consumer_supplies = &micsupp->supply; micsupp->init_data.consumer_supplies = &micsupp->supply;
micsupp->supply.supply = "MICVDD";
micsupp->supply.dev_name = dev_name(micsupp->dev); micsupp->supply.dev_name = dev_name(micsupp->dev);
micsupp->enable_reg = desc->enable_reg; micsupp->desc = desc;
config.dev = micsupp->dev; config.dev = micsupp->dev;
config.driver_data = micsupp; config.driver_data = micsupp;
@ -285,8 +284,7 @@ static int arizona_micsupp_common_init(struct platform_device *pdev,
config.init_data = &micsupp->init_data; config.init_data = &micsupp->init_data;
/* Default to regulated mode */ /* Default to regulated mode */
regmap_update_bits(micsupp->regmap, micsupp->enable_reg, regmap_update_bits(micsupp->regmap, desc->enable_reg, desc->bypass_mask, 0);
ARIZONA_CPMIC_BYPASS, 0);
micsupp->regulator = devm_regulator_register(&pdev->dev, micsupp->regulator = devm_regulator_register(&pdev->dev,
desc, desc,
@ -320,6 +318,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
micsupp->dapm = &arizona->dapm; micsupp->dapm = &arizona->dapm;
micsupp->dev = arizona->dev; micsupp->dev = arizona->dev;
micsupp->supply.supply = "MICVDD";
/* /*
* Since the chip usually supplies itself we provide some * Since the chip usually supplies itself we provide some
* default init_data for it. This will be overridden with * 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->dev = madera->dev;
micsupp->init_data = arizona_micsupp_ext_default; micsupp->init_data = arizona_micsupp_ext_default;
micsupp->supply.supply = "MICVDD";
return arizona_micsupp_common_init(pdev, micsupp, &madera_micsupp, return arizona_micsupp_common_init(pdev, micsupp, &madera_micsupp,
&madera->pdata.micvdd); &madera->pdata.micvdd);
} }

View File

@ -602,12 +602,10 @@ static int bd7181x_probe(struct platform_device *pdev)
config.ena_gpiod = NULL; config.ena_gpiod = NULL;
rdev = devm_regulator_register(&pdev->dev, desc, &config); rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev)) { if (IS_ERR(rdev))
dev_err(&pdev->dev, return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
"failed to register %s regulator\n", "failed to register %s regulator\n",
desc->name); desc->name);
return PTR_ERR(rdev);
}
} }
return 0; return 0;
} }

View File

@ -750,23 +750,20 @@ static int bd71828_probe(struct platform_device *pdev)
rd = &bd71828_rdata[i]; rd = &bd71828_rdata[i];
rdev = devm_regulator_register(&pdev->dev, rdev = devm_regulator_register(&pdev->dev,
&rd->desc, &config); &rd->desc, &config);
if (IS_ERR(rdev)) { if (IS_ERR(rdev))
dev_err(&pdev->dev, return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
"failed to register %s regulator\n", "failed to register %s regulator\n",
rd->desc.name); rd->desc.name);
return PTR_ERR(rdev);
}
for (j = 0; j < rd->reg_init_amnt; j++) { for (j = 0; j < rd->reg_init_amnt; j++) {
ret = regmap_update_bits(config.regmap, ret = regmap_update_bits(config.regmap,
rd->reg_inits[j].reg, rd->reg_inits[j].reg,
rd->reg_inits[j].mask, rd->reg_inits[j].mask,
rd->reg_inits[j].val); rd->reg_inits[j].val);
if (ret) { if (ret)
dev_err(&pdev->dev, return dev_err_probe(&pdev->dev, ret,
"regulator %s init failed\n", "regulator %s init failed\n",
rd->desc.name); rd->desc.name);
return ret;
}
} }
} }
return 0; return 0;

View File

@ -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)) if (!of_node_name_eq(np, desc->of_match))
continue; continue;
pr_info("Looking at node '%s'\n", desc->of_match);
/* The feedback loop connection does not make sense for LDOs */ /* The feedback loop connection does not make sense for LDOs */
if (desc->id >= BD718XX_LDO1) if (desc->id >= BD718XX_LDO1)
return -EINVAL; return -EINVAL;
@ -1708,20 +1706,17 @@ static int bd718xx_probe(struct platform_device *pdev)
break; break;
default: default:
dev_err(&pdev->dev, "Unsupported chip type\n"); dev_err(&pdev->dev, "Unsupported chip type\n");
err = -EINVAL; return -EINVAL;
goto err;
} }
/* Register LOCK release */ /* Register LOCK release */
err = regmap_update_bits(regmap, BD718XX_REG_REGLOCK, err = regmap_update_bits(regmap, BD718XX_REG_REGLOCK,
(REGLOCK_PWRSEQ | REGLOCK_VREG), 0); (REGLOCK_PWRSEQ | REGLOCK_VREG), 0);
if (err) { if (err)
dev_err(&pdev->dev, "Failed to unlock PMIC (%d)\n", err); return dev_err_probe(&pdev->dev, err, "Failed to unlock PMIC\n");
goto err;
} else { dev_dbg(&pdev->dev, "Unlocked lock register 0x%x\n",
dev_dbg(&pdev->dev, "Unlocked lock register 0x%x\n", BD718XX_REG_REGLOCK);
BD718XX_REG_REGLOCK);
}
use_snvs = of_property_read_bool(pdev->dev.parent->of_node, use_snvs = of_property_read_bool(pdev->dev.parent->of_node,
"rohm,reset-snvs-powered"); "rohm,reset-snvs-powered");
@ -1738,13 +1733,11 @@ static int bd718xx_probe(struct platform_device *pdev)
BD718XX_WDOG_POWEROFF_MASK | BD718XX_WDOG_POWEROFF_MASK |
BD718XX_KEY_L_POWEROFF_MASK, BD718XX_KEY_L_POWEROFF_MASK,
BD718XX_POWOFF_TO_RDY); BD718XX_POWOFF_TO_RDY);
if (err) { if (err)
dev_err(&pdev->dev, "Failed to change reset target\n"); return dev_err_probe(&pdev->dev, err,
goto err; "Failed to change reset target\n");
} else {
dev_dbg(&pdev->dev, dev_dbg(&pdev->dev, "Changed all resets from SVNS to READY\n");
"Changed all resets from SVNS to READY\n");
}
} }
config.dev = pdev->dev.parent; config.dev = pdev->dev.parent;
@ -1780,13 +1773,10 @@ static int bd718xx_probe(struct platform_device *pdev)
desc->ops = swops[i]; desc->ops = swops[i];
rdev = devm_regulator_register(&pdev->dev, desc, &config); rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev)) { if (IS_ERR(rdev))
dev_err(&pdev->dev, return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
"failed to register %s regulator\n", "failed to register %s regulator\n",
desc->name); desc->name);
err = PTR_ERR(rdev);
goto err;
}
/* /*
* Regulator register gets the regulator constraints and * Regulator register gets the regulator constraints and
@ -1809,28 +1799,23 @@ static int bd718xx_probe(struct platform_device *pdev)
!rdev->constraints->boot_on)) { !rdev->constraints->boot_on)) {
err = regmap_update_bits(regmap, r->init.reg, err = regmap_update_bits(regmap, r->init.reg,
r->init.mask, r->init.val); r->init.mask, r->init.val);
if (err) { if (err)
dev_err(&pdev->dev, return dev_err_probe(&pdev->dev, err,
"Failed to take control for (%s)\n", "Failed to take control for (%s)\n",
desc->name); desc->name);
goto err;
}
} }
for (j = 0; j < r->additional_init_amnt; j++) { for (j = 0; j < r->additional_init_amnt; j++) {
err = regmap_update_bits(regmap, err = regmap_update_bits(regmap,
r->additional_inits[j].reg, r->additional_inits[j].reg,
r->additional_inits[j].mask, r->additional_inits[j].mask,
r->additional_inits[j].val); r->additional_inits[j].val);
if (err) { if (err)
dev_err(&pdev->dev, return dev_err_probe(&pdev->dev, err,
"Buck (%s) initialization failed\n", "Buck (%s) initialization failed\n",
desc->name); desc->name);
goto err;
}
} }
} }
err:
return err; return err;
} }

View File

@ -953,30 +953,28 @@ static int bd957x_probe(struct platform_device *pdev)
dev_fwnode(pdev->dev.parent), dev_fwnode(pdev->dev.parent),
"rohm,vout1-en", GPIOD_OUT_LOW, "rohm,vout1-en", GPIOD_OUT_LOW,
"vout1-en"); "vout1-en");
if (!IS_ERR(en)) {
/* VOUT1_OPS gpio ctrl */ /* VOUT1_OPS gpio ctrl */
/* /*
* Regulator core prioritizes the ena_gpio over * Regulator core prioritizes the ena_gpio over
* enable/disable/is_enabled callbacks so no need to * enable/disable/is_enabled callbacks so no need to clear them
* clear them. We can still use same ops * 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; config.ena_gpiod = en;
} else { else
/* return dev_err_probe(&pdev->dev, PTR_ERR(en),
* In theory it is possible someone wants to set "Failed to get VOUT1 control GPIO\n");
* 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);
}
} }
/* /*
@ -1037,12 +1035,10 @@ static int bd957x_probe(struct platform_device *pdev)
r->rdev = devm_regulator_register(&pdev->dev, desc, r->rdev = devm_regulator_register(&pdev->dev, desc,
&config); &config);
if (IS_ERR(r->rdev)) { if (IS_ERR(r->rdev))
dev_err(&pdev->dev, return dev_err_probe(&pdev->dev, PTR_ERR(r->rdev),
"failed to register %s regulator\n", "failed to register %s regulator\n",
desc->name); desc->name);
return PTR_ERR(r->rdev);
}
/* /*
* Clear the VOUT1 GPIO setting - rest of the regulators do not * Clear the VOUT1 GPIO setting - rest of the regulators do not
* support GPIO control * support GPIO control

View File

@ -1596,7 +1596,13 @@ static int set_machine_constraints(struct regulator_dev *rdev)
if (rdev->supply_name && !rdev->supply) if (rdev->supply_name && !rdev->supply)
return -EPROBE_DEFER; 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); ret = regulator_enable(rdev->supply);
if (ret < 0) { if (ret < 0) {
_regulator_put(rdev->supply); _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"); rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
if (rdev->supply == NULL) { if (rdev->supply == NULL) {
module_put(supply_rdev->owner);
err = -ENOMEM; err = -ENOMEM;
return err; return err;
} }
@ -1813,7 +1820,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
regulator = kzalloc(sizeof(*regulator), GFP_KERNEL); regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
if (regulator == NULL) { if (regulator == NULL) {
kfree(supply_name); kfree_const(supply_name);
return NULL; return NULL;
} }
@ -1943,6 +1950,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
node = of_get_regulator(dev, supply); node = of_get_regulator(dev, supply);
if (node) { if (node) {
r = of_find_regulator_by_node(node); r = of_find_regulator_by_node(node);
of_node_put(node);
if (r) if (r)
return 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); return blocking_notifier_call_chain(&rdev->notifier, event, data);
} }
/** int _regulator_bulk_get(struct device *dev, int num_consumers,
* regulator_bulk_get - get multiple regulator consumers struct regulator_bulk_data *consumers, enum regulator_get_type get_type)
*
* @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 i; int i;
int ret; int ret;
@ -4802,8 +4796,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
consumers[i].consumer = NULL; consumers[i].consumer = NULL;
for (i = 0; i < num_consumers; i++) { for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = regulator_get(dev, consumers[i].consumer = _regulator_get(dev,
consumers[i].supply); consumers[i].supply, get_type);
if (IS_ERR(consumers[i].consumer)) { if (IS_ERR(consumers[i].consumer)) {
ret = dev_err_probe(dev, PTR_ERR(consumers[i].consumer), ret = dev_err_probe(dev, PTR_ERR(consumers[i].consumer),
"Failed to get supply '%s'", "Failed to get supply '%s'",
@ -4830,6 +4824,26 @@ err:
return ret; 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); EXPORT_SYMBOL_GPL(regulator_bulk_get);
static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) 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 * regulator_register - register regulator
* @dev: the device that drive the regulator
* @regulator_desc: regulator to register * @regulator_desc: regulator to register
* @cfg: runtime configuration for regulator * @cfg: runtime configuration for regulator
* *
@ -5404,7 +5419,8 @@ static struct regulator_coupler generic_regulator_coupler = {
* or an ERR_PTR() on error. * or an ERR_PTR() on error.
*/ */
struct regulator_dev * 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_config *cfg)
{ {
const struct regulator_init_data *init_data; const struct regulator_init_data *init_data;
@ -5413,7 +5429,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
struct regulator_dev *rdev; struct regulator_dev *rdev;
bool dangling_cfg_gpiod = false; bool dangling_cfg_gpiod = false;
bool dangling_of_gpiod = false; bool dangling_of_gpiod = false;
struct device *dev;
int ret, i; int ret, i;
bool resolved_early = false; bool resolved_early = false;
@ -5426,8 +5441,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
goto rinse; goto rinse;
} }
dev = cfg->dev; WARN_ON(!dev || !cfg->dev);
WARN_ON(!dev);
if (regulator_desc->name == NULL || regulator_desc->ops == NULL) { if (regulator_desc->name == NULL || regulator_desc->ops == NULL) {
ret = -EINVAL; ret = -EINVAL;
@ -5641,6 +5655,7 @@ unset_supplies:
regulator_remove_coupling(rdev); regulator_remove_coupling(rdev);
mutex_unlock(&regulator_list_mutex); mutex_unlock(&regulator_list_mutex);
wash: wash:
regulator_put(rdev->supply);
kfree(rdev->coupling_desc.coupled_rdevs); kfree(rdev->coupling_desc.coupled_rdevs);
mutex_lock(&regulator_list_mutex); mutex_lock(&regulator_list_mutex);
regulator_ena_gpio_free(rdev); regulator_ena_gpio_free(rdev);

View File

@ -1128,8 +1128,7 @@ static inline int da9121_of_get_id(struct device *dev)
return (uintptr_t)id->data; return (uintptr_t)id->data;
} }
static int da9121_i2c_probe(struct i2c_client *i2c, static int da9121_i2c_probe(struct i2c_client *i2c)
const struct i2c_device_id *id)
{ {
struct da9121 *chip; struct da9121 *chip;
const int mask_all[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; const int mask_all[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
@ -1197,7 +1196,7 @@ static struct i2c_driver da9121_regulator_driver = {
.name = "da9121", .name = "da9121",
.of_match_table = of_match_ptr(da9121_dt_ids), .of_match_table = of_match_ptr(da9121_dt_ids),
}, },
.probe = da9121_i2c_probe, .probe_new = da9121_i2c_probe,
.remove = da9121_i2c_remove, .remove = da9121_i2c_remove,
.id_table = da9121_i2c_id, .id_table = da9121_i2c_id,
}; };

View File

@ -186,6 +186,30 @@ static void devm_regulator_bulk_release(struct device *dev, void *res)
regulator_bulk_free(devres->num_consumers, devres->consumers); regulator_bulk_free(devres->num_consumers, devres->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;
devres = devres_alloc(devm_regulator_bulk_release,
sizeof(*devres), GFP_KERNEL);
if (!devres)
return -ENOMEM;
ret = _regulator_bulk_get(dev, num_consumers, consumers, get_type);
if (!ret) {
devres->consumers = consumers;
devres->num_consumers = num_consumers;
devres_add(dev, devres);
} else {
devres_free(devres);
}
return ret;
}
/** /**
* devm_regulator_bulk_get - managed get multiple regulator consumers * devm_regulator_bulk_get - managed get multiple regulator consumers
* *
@ -204,27 +228,33 @@ static void devm_regulator_bulk_release(struct device *dev, void *res)
int devm_regulator_bulk_get(struct device *dev, int num_consumers, int devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers) struct regulator_bulk_data *consumers)
{ {
struct regulator_bulk_devres *devres; return _devm_regulator_bulk_get(dev, num_consumers, consumers, NORMAL_GET);
int ret;
devres = devres_alloc(devm_regulator_bulk_release,
sizeof(*devres), GFP_KERNEL);
if (!devres)
return -ENOMEM;
ret = regulator_bulk_get(dev, num_consumers, consumers);
if (!ret) {
devres->consumers = consumers;
devres->num_consumers = num_consumers;
devres_add(dev, devres);
} else {
devres_free(devres);
}
return ret;
} }
EXPORT_SYMBOL_GPL(devm_regulator_bulk_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 * 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) if (!ptr)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
rdev = regulator_register(regulator_desc, config); rdev = regulator_register(dev, regulator_desc, config);
if (!IS_ERR(rdev)) { if (!IS_ERR(rdev)) {
*ptr = rdev; *ptr = rdev;
devres_add(dev, ptr); devres_add(dev, ptr);

View File

@ -549,9 +549,9 @@ static const struct of_device_id __maybe_unused fan53555_dt_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, fan53555_dt_ids); MODULE_DEVICE_TABLE(of, fan53555_dt_ids);
static int fan53555_regulator_probe(struct i2c_client *client, static int fan53555_regulator_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device_node *np = client->dev.of_node; struct device_node *np = client->dev.of_node;
struct fan53555_device_info *di; struct fan53555_device_info *di;
struct fan53555_platform_data *pdata; struct fan53555_platform_data *pdata;
@ -665,7 +665,7 @@ static struct i2c_driver fan53555_regulator_driver = {
.name = "fan53555-regulator", .name = "fan53555-regulator",
.of_match_table = of_match_ptr(fan53555_dt_ids), .of_match_table = of_match_ptr(fan53555_dt_ids),
}, },
.probe = fan53555_regulator_probe, .probe_new = fan53555_regulator_probe,
.id_table = fan53555_id, .id_table = fan53555_id,
}; };

View File

@ -42,8 +42,8 @@ static const struct regulator_ops fan53880_ops = {
#define FAN53880_LDO(_num, _supply, _default) \ #define FAN53880_LDO(_num, _supply, _default) \
[FAN53880_LDO ## _num] = { \ [FAN53880_LDO ## _num] = { \
.name = "LDO"#_num, \ .name = "LDO"#_num, \
.of_match = of_match_ptr("LDO"#_num), \ .of_match = "LDO"#_num, \
.regulators_node = of_match_ptr("regulators"), \ .regulators_node = "regulators", \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
.linear_ranges = (struct linear_range[]) { \ .linear_ranges = (struct linear_range[]) { \
@ -68,8 +68,8 @@ static const struct regulator_desc fan53880_regulators[] = {
FAN53880_LDO(4, "VIN4", 1800000), FAN53880_LDO(4, "VIN4", 1800000),
[FAN53880_BUCK] = { [FAN53880_BUCK] = {
.name = "BUCK", .name = "BUCK",
.of_match = of_match_ptr("BUCK"), .of_match = "BUCK",
.regulators_node = of_match_ptr("regulators"), .regulators_node = "regulators",
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.linear_ranges = (struct linear_range[]) { .linear_ranges = (struct linear_range[]) {
@ -88,8 +88,8 @@ static const struct regulator_desc fan53880_regulators[] = {
}, },
[FAN53880_BOOST] = { [FAN53880_BOOST] = {
.name = "BOOST", .name = "BOOST",
.of_match = of_match_ptr("BOOST"), .of_match = "BOOST",
.regulators_node = of_match_ptr("regulators"), .regulators_node = "regulators",
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.linear_ranges = (struct linear_range[]) { .linear_ranges = (struct linear_range[]) {
@ -157,13 +157,11 @@ static int fan53880_i2c_probe(struct i2c_client *i2c)
return 0; return 0;
} }
#ifdef CONFIG_OF
static const struct of_device_id fan53880_dt_ids[] = { static const struct of_device_id fan53880_dt_ids[] = {
{ .compatible = "onnn,fan53880", }, { .compatible = "onnn,fan53880", },
{} {}
}; };
MODULE_DEVICE_TABLE(of, fan53880_dt_ids); MODULE_DEVICE_TABLE(of, fan53880_dt_ids);
#endif
static const struct i2c_device_id fan53880_i2c_id[] = { static const struct i2c_device_id fan53880_i2c_id[] = {
{ "fan53880", }, { "fan53880", },
@ -174,7 +172,7 @@ MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id);
static struct i2c_driver fan53880_regulator_driver = { static struct i2c_driver fan53880_regulator_driver = {
.driver = { .driver = {
.name = "fan53880", .name = "fan53880",
.of_match_table = of_match_ptr(fan53880_dt_ids), .of_match_table = fan53880_dt_ids,
}, },
.probe_new = fan53880_i2c_probe, .probe_new = fan53880_i2c_probe,
.id_table = fan53880_i2c_id, .id_table = fan53880_i2c_id,

View File

@ -122,4 +122,6 @@ enum regulator_get_type {
struct regulator *_regulator_get(struct device *dev, const char *id, struct regulator *_regulator_get(struct device *dev, const char *id,
enum regulator_get_type get_type); 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 #endif

View File

@ -97,9 +97,9 @@ static const struct regulator_desc isl_rd[] = {
}, },
}; };
static int isl6271a_probe(struct i2c_client *i2c, static int isl6271a_probe(struct i2c_client *i2c)
const struct i2c_device_id *id)
{ {
const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct regulator_dev *rdev; struct regulator_dev *rdev;
struct regulator_config config = { }; struct regulator_config config = { };
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
@ -148,7 +148,7 @@ static struct i2c_driver isl6271a_i2c_driver = {
.driver = { .driver = {
.name = "isl6271a", .name = "isl6271a",
}, },
.probe = isl6271a_probe, .probe_new = isl6271a_probe,
.id_table = isl6271a_id, .id_table = isl6271a_id,
}; };

View File

@ -495,8 +495,7 @@ static int setup_regulators(struct lp3972 *lp3972,
return 0; return 0;
} }
static int lp3972_i2c_probe(struct i2c_client *i2c, static int lp3972_i2c_probe(struct i2c_client *i2c)
const struct i2c_device_id *id)
{ {
struct lp3972 *lp3972; struct lp3972 *lp3972;
struct lp3972_platform_data *pdata = dev_get_platdata(&i2c->dev); struct lp3972_platform_data *pdata = dev_get_platdata(&i2c->dev);
@ -547,7 +546,7 @@ static struct i2c_driver lp3972_i2c_driver = {
.driver = { .driver = {
.name = "lp3972", .name = "lp3972",
}, },
.probe = lp3972_i2c_probe, .probe_new = lp3972_i2c_probe,
.id_table = lp3972_i2c_id, .id_table = lp3972_i2c_id,
}; };

View File

@ -879,8 +879,9 @@ static struct lp872x_platform_data
} }
#endif #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 *lp;
struct lp872x_platform_data *pdata; struct lp872x_platform_data *pdata;
int ret; int ret;
@ -946,7 +947,7 @@ static struct i2c_driver lp872x_driver = {
.name = "lp872x", .name = "lp872x",
.of_match_table = of_match_ptr(lp872x_dt_ids), .of_match_table = of_match_ptr(lp872x_dt_ids),
}, },
.probe = lp872x_probe, .probe_new = lp872x_probe,
.id_table = lp872x_ids, .id_table = lp872x_ids,
}; };

View File

@ -357,8 +357,7 @@ static const struct regmap_config lp8755_regmap = {
.max_register = LP8755_REG_MAX, .max_register = LP8755_REG_MAX,
}; };
static int lp8755_probe(struct i2c_client *client, static int lp8755_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
int ret, icnt; int ret, icnt;
struct lp8755_chip *pchip; struct lp8755_chip *pchip;
@ -442,7 +441,7 @@ static struct i2c_driver lp8755_i2c_driver = {
.driver = { .driver = {
.name = LP8755_NAME, .name = LP8755_NAME,
}, },
.probe = lp8755_probe, .probe_new = lp8755_probe,
.remove = lp8755_remove, .remove = lp8755_remove,
.id_table = lp8755_id, .id_table = lp8755_id,
}; };

View File

@ -378,9 +378,9 @@ static irqreturn_t ltc3589_isr(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int ltc3589_probe(struct i2c_client *client, static int ltc3589_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device *dev = &client->dev; struct device *dev = &client->dev;
struct regulator_desc *descs; struct regulator_desc *descs;
struct ltc3589 *ltc3589; struct ltc3589 *ltc3589;
@ -476,7 +476,7 @@ static struct i2c_driver ltc3589_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.of_match_table = of_match_ptr(ltc3589_of_match), .of_match_table = of_match_ptr(ltc3589_of_match),
}, },
.probe = ltc3589_probe, .probe_new = ltc3589_probe,
.id_table = ltc3589_i2c_id, .id_table = ltc3589_i2c_id,
}; };
module_i2c_driver(ltc3589_driver); module_i2c_driver(ltc3589_driver);

View File

@ -207,8 +207,7 @@ static const struct of_device_id __maybe_unused max1586_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, max1586_of_match); MODULE_DEVICE_TABLE(of, max1586_of_match);
static int max1586_pmic_probe(struct i2c_client *client, static int max1586_pmic_probe(struct i2c_client *client)
const struct i2c_device_id *i2c_id)
{ {
struct max1586_platform_data *pdata, pdata_of; struct max1586_platform_data *pdata, pdata_of;
struct regulator_config config = { }; struct regulator_config config = { };
@ -290,7 +289,7 @@ static const struct i2c_device_id max1586_id[] = {
MODULE_DEVICE_TABLE(i2c, max1586_id); MODULE_DEVICE_TABLE(i2c, max1586_id);
static struct i2c_driver max1586_pmic_driver = { static struct i2c_driver max1586_pmic_driver = {
.probe = max1586_pmic_probe, .probe_new = max1586_pmic_probe,
.driver = { .driver = {
.name = "max1586", .name = "max1586",
.of_match_table = of_match_ptr(max1586_of_match), .of_match_table = of_match_ptr(max1586_of_match),

View File

@ -145,8 +145,7 @@ static const struct regmap_config max8649_regmap_config = {
.val_bits = 8, .val_bits = 8,
}; };
static int max8649_regulator_probe(struct i2c_client *client, static int max8649_regulator_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
struct max8649_platform_data *pdata = dev_get_platdata(&client->dev); struct max8649_platform_data *pdata = dev_get_platdata(&client->dev);
struct max8649_regulator_info *info = NULL; struct max8649_regulator_info *info = NULL;
@ -247,7 +246,7 @@ static const struct i2c_device_id max8649_id[] = {
MODULE_DEVICE_TABLE(i2c, max8649_id); MODULE_DEVICE_TABLE(i2c, max8649_id);
static struct i2c_driver max8649_driver = { static struct i2c_driver max8649_driver = {
.probe = max8649_regulator_probe, .probe_new = max8649_regulator_probe,
.driver = { .driver = {
.name = "max8649", .name = "max8649",
}, },

View File

@ -367,9 +367,9 @@ static inline int max8660_pdata_from_dt(struct device *dev,
} }
#endif #endif
static int max8660_probe(struct i2c_client *client, static int max8660_probe(struct i2c_client *client)
const struct i2c_device_id *i2c_id)
{ {
const struct i2c_device_id *i2c_id = i2c_client_get_device_id(client);
struct device *dev = &client->dev; struct device *dev = &client->dev;
struct max8660_platform_data pdata_of, *pdata = dev_get_platdata(dev); struct max8660_platform_data pdata_of, *pdata = dev_get_platdata(dev);
struct regulator_config config = { }; struct regulator_config config = { };
@ -503,7 +503,7 @@ static const struct i2c_device_id max8660_id[] = {
MODULE_DEVICE_TABLE(i2c, max8660_id); MODULE_DEVICE_TABLE(i2c, max8660_id);
static struct i2c_driver max8660_driver = { static struct i2c_driver max8660_driver = {
.probe = max8660_probe, .probe_new = max8660_probe,
.driver = { .driver = {
.name = "max8660", .name = "max8660",
}, },

View File

@ -171,8 +171,7 @@ static struct max8952_platform_data *max8952_parse_dt(struct device *dev)
} }
#endif #endif
static int max8952_pmic_probe(struct i2c_client *client, static int max8952_pmic_probe(struct i2c_client *client)
const struct i2c_device_id *i2c_id)
{ {
struct i2c_adapter *adapter = client->adapter; struct i2c_adapter *adapter = client->adapter;
struct max8952_platform_data *pdata = dev_get_platdata(&client->dev); 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); MODULE_DEVICE_TABLE(i2c, max8952_ids);
static struct i2c_driver max8952_pmic_driver = { static struct i2c_driver max8952_pmic_driver = {
.probe = max8952_pmic_probe, .probe_new = max8952_pmic_probe,
.driver = { .driver = {
.name = "max8952", .name = "max8952",
.of_match_table = of_match_ptr(max8952_dt_match), .of_match_table = of_match_ptr(max8952_dt_match),

View File

@ -586,9 +586,9 @@ static const struct of_device_id of_max8973_match_tbl[] = {
}; };
MODULE_DEVICE_TABLE(of, of_max8973_match_tbl); MODULE_DEVICE_TABLE(of, of_max8973_match_tbl);
static int max8973_probe(struct i2c_client *client, static int max8973_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct max8973_regulator_platform_data *pdata; struct max8973_regulator_platform_data *pdata;
struct regulator_init_data *ridata; struct regulator_init_data *ridata;
struct regulator_config config = { }; struct regulator_config config = { };
@ -806,7 +806,7 @@ static struct i2c_driver max8973_i2c_driver = {
.name = "max8973", .name = "max8973",
.of_match_table = of_max8973_match_tbl, .of_match_table = of_max8973_match_tbl,
}, },
.probe = max8973_probe, .probe_new = max8973_probe,
.id_table = max8973_id, .id_table = max8973_id,
}; };

View File

@ -362,7 +362,7 @@ MODULE_DEVICE_TABLE(i2c, mp886x_id);
static struct i2c_driver mp886x_regulator_driver = { static struct i2c_driver mp886x_regulator_driver = {
.driver = { .driver = {
.name = "mp886x-regulator", .name = "mp886x-regulator",
.of_match_table = of_match_ptr(mp886x_dt_ids), .of_match_table = mp886x_dt_ids,
}, },
.probe_new = mp886x_i2c_probe, .probe_new = mp886x_i2c_probe,
.id_table = mp886x_id, .id_table = mp886x_id,

View File

@ -0,0 +1,453 @@
// 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");

View File

@ -505,7 +505,7 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
struct device_node *child; struct device_node *child;
struct regulator_init_data *init_data = NULL; 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) if (!child)
return NULL; return NULL;
@ -701,3 +701,95 @@ struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev,
return c_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);

View File

@ -701,8 +701,7 @@ static irqreturn_t pca9450_irq_handler(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int pca9450_i2c_probe(struct i2c_client *i2c, static int pca9450_i2c_probe(struct i2c_client *i2c)
const struct i2c_device_id *id)
{ {
enum pca9450_chip_type type = (unsigned int)(uintptr_t) enum pca9450_chip_type type = (unsigned int)(uintptr_t)
of_device_get_match_data(&i2c->dev); of_device_get_match_data(&i2c->dev);
@ -875,7 +874,7 @@ static struct i2c_driver pca9450_i2c_driver = {
.name = "nxp-pca9450", .name = "nxp-pca9450",
.of_match_table = pca9450_of_match, .of_match_table = pca9450_of_match,
}, },
.probe = pca9450_i2c_probe, .probe_new = pca9450_i2c_probe,
}; };
module_i2c_driver(pca9450_i2c_driver); module_i2c_driver(pca9450_i2c_driver);

View File

@ -683,9 +683,9 @@ static const struct regmap_config pfuze_regmap_config = {
.cache_type = REGCACHE_RBTREE, .cache_type = REGCACHE_RBTREE,
}; };
static int pfuze100_regulator_probe(struct i2c_client *client, static int pfuze100_regulator_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct pfuze_chip *pfuze_chip; struct pfuze_chip *pfuze_chip;
struct regulator_config config = { }; struct regulator_config config = { };
int i, ret; int i, ret;
@ -847,7 +847,7 @@ static struct i2c_driver pfuze_driver = {
.name = "pfuze100-regulator", .name = "pfuze100-regulator",
.of_match_table = pfuze_dt_ids, .of_match_table = pfuze_dt_ids,
}, },
.probe = pfuze100_regulator_probe, .probe_new = pfuze100_regulator_probe,
}; };
module_i2c_driver(pfuze_driver); module_i2c_driver(pfuze_driver);

View File

@ -374,9 +374,9 @@ error_i2c:
/* /*
* I2C driver interface functions * I2C driver interface functions
*/ */
static int pv88080_i2c_probe(struct i2c_client *i2c, static int pv88080_i2c_probe(struct i2c_client *i2c)
const struct i2c_device_id *id)
{ {
const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
struct pv88080 *chip; struct pv88080 *chip;
const struct pv88080_compatible_regmap *regmap_config; const struct pv88080_compatible_regmap *regmap_config;
@ -559,7 +559,7 @@ static struct i2c_driver pv88080_regulator_driver = {
.name = "pv88080", .name = "pv88080",
.of_match_table = of_match_ptr(pv88080_dt_ids), .of_match_table = of_match_ptr(pv88080_dt_ids),
}, },
.probe = pv88080_i2c_probe, .probe_new = pv88080_i2c_probe,
.id_table = pv88080_i2c_id, .id_table = pv88080_i2c_id,
}; };

View File

@ -822,6 +822,7 @@ static int qcom_labibb_regulator_probe(struct platform_device *pdev)
if (irq == 0) if (irq == 0)
irq = -EINVAL; irq = -EINVAL;
of_node_put(reg_node);
return dev_err_probe(vreg->dev, irq, return dev_err_probe(vreg->dev, irq,
"Short-circuit irq not found.\n"); "Short-circuit irq not found.\n");
} }

View File

@ -731,6 +731,24 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps520 = {
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode, .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 = { static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
.regulator_type = VRM, .regulator_type = VRM,
.ops = &rpmh_regulator_vrm_ops, .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[] = { static const struct rpmh_vreg_init_data pm8009_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"), RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_hfsmps515, "vdd-s2"), 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[] = { static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps520, "vdd-s1"), RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps520, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps520, "vdd-s2"), 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("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l2"),
RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l1-l2"), RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l1-l2"),
RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"), 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", .compatible = "qcom,pm8450-rpmh-regulators",
.data = pm8450_vreg_data, .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", .compatible = "qcom,pm8998-rpmh-regulators",
.data = pm8998_vreg_data, .data = pm8998_vreg_data,

View File

@ -677,6 +677,24 @@ static const struct regulator_desc pm6125_ftsmps = {
.ops = &rpm_smps_ldo_ops, .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 = { static const struct regulator_desc pms405_hfsmps3 = {
.linear_ranges = (struct linear_range[]) { .linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000), 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[] = { static const struct rpm_regulator_data rpm_pms405_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pms405_hfsmps3, "vdd_s1" }, { "s1", QCOM_SMD_RPM_SMPA, 1, &pms405_hfsmps3, "vdd_s1" },
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pms405_hfsmps3, "vdd_s2" }, { "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-pma8084-regulators", .data = &rpm_pma8084_regulators },
{ .compatible = "qcom,rpm-pmi8994-regulators", .data = &rpm_pmi8994_regulators }, { .compatible = "qcom,rpm-pmi8994-regulators", .data = &rpm_pmi8994_regulators },
{ .compatible = "qcom,rpm-pmi8998-regulators", .data = &rpm_pmi8998_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 }, { .compatible = "qcom,rpm-pms405-regulators", .data = &rpm_pms405_regulators },
{} {}
}; };

View File

@ -14,7 +14,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
@ -1286,19 +1285,23 @@ dt_parse_end:
static int rk808_regulator_probe(struct platform_device *pdev) static int rk808_regulator_probe(struct platform_device *pdev)
{ {
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
struct i2c_client *client = rk808->i2c;
struct regulator_config config = {}; struct regulator_config config = {};
struct regulator_dev *rk808_rdev; struct regulator_dev *rk808_rdev;
struct rk808_regulator_data *pdata; struct rk808_regulator_data *pdata;
const struct regulator_desc *regulators; const struct regulator_desc *regulators;
struct regmap *regmap;
int ret, i, nregulators; 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); pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) if (!pdata)
return -ENOMEM; return -ENOMEM;
ret = rk808_regulator_dt_parse_pdata(&pdev->dev, &client->dev, ret = rk808_regulator_dt_parse_pdata(&pdev->dev, pdev->dev.parent,
rk808->regmap, pdata); regmap, pdata);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -1326,24 +1329,23 @@ static int rk808_regulator_probe(struct platform_device *pdev)
nregulators = RK818_NUM_REGULATORS; nregulators = RK818_NUM_REGULATORS;
break; break;
default: default:
dev_err(&client->dev, "unsupported RK8XX ID %lu\n", dev_err(&pdev->dev, "unsupported RK8XX ID %lu\n",
rk808->variant); rk808->variant);
return -EINVAL; return -EINVAL;
} }
config.dev = &client->dev; config.dev = &pdev->dev;
config.dev->of_node = pdev->dev.parent->of_node;
config.driver_data = pdata; config.driver_data = pdata;
config.regmap = rk808->regmap; config.regmap = regmap;
/* Instantiate the regulators */ /* Instantiate the regulators */
for (i = 0; i < nregulators; i++) { for (i = 0; i < nregulators; i++) {
rk808_rdev = devm_regulator_register(&pdev->dev, rk808_rdev = devm_regulator_register(&pdev->dev,
&regulators[i], &config); &regulators[i], &config);
if (IS_ERR(rk808_rdev)) { if (IS_ERR(rk808_rdev))
dev_err(&client->dev, return dev_err_probe(&pdev->dev, PTR_ERR(rk808_rdev),
"failed to register %d regulator\n", i); "failed to register %d regulator\n", i);
return PTR_ERR(rk808_rdev);
}
} }
return 0; return 0;

View File

@ -282,8 +282,7 @@ static int attiny_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf)
/* /*
* I2C driver interface functions * I2C driver interface functions
*/ */
static int attiny_i2c_probe(struct i2c_client *i2c, static int attiny_i2c_probe(struct i2c_client *i2c)
const struct i2c_device_id *id)
{ {
struct backlight_properties props = { }; struct backlight_properties props = { };
struct regulator_config config = { }; struct regulator_config config = { };
@ -399,7 +398,7 @@ static struct i2c_driver attiny_regulator_driver = {
.name = "rpi_touchscreen_attiny", .name = "rpi_touchscreen_attiny",
.of_match_table = of_match_ptr(attiny_dt_ids), .of_match_table = of_match_ptr(attiny_dt_ids),
}, },
.probe = attiny_i2c_probe, .probe_new = attiny_i2c_probe,
.remove = attiny_i2c_remove, .remove = attiny_i2c_remove,
}; };

View File

@ -0,0 +1,495 @@
// 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");

View File

@ -210,7 +210,7 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev)
pdev->dev.of_node, pdev->dev.of_node,
&stm32_vrefbuf_regu); &stm32_vrefbuf_regu);
rdev = regulator_register(&stm32_vrefbuf_regu, &config); rdev = regulator_register(&pdev->dev, &stm32_vrefbuf_regu, &config);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev); ret = PTR_ERR(rdev);
dev_err(&pdev->dev, "register failed with error %d\n", ret); dev_err(&pdev->dev, "register failed with error %d\n", ret);

View File

@ -123,7 +123,7 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c)
return 0; 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" }, { .compatible = "silergy,sy8106a" },
{ }, { },
}; };
@ -138,7 +138,7 @@ MODULE_DEVICE_TABLE(i2c, sy8106a_i2c_id);
static struct i2c_driver sy8106a_regulator_driver = { static struct i2c_driver sy8106a_regulator_driver = {
.driver = { .driver = {
.name = "sy8106a", .name = "sy8106a",
.of_match_table = of_match_ptr(sy8106a_i2c_of_match), .of_match_table = sy8106a_i2c_of_match,
}, },
.probe_new = sy8106a_i2c_probe, .probe_new = sy8106a_i2c_probe,
.id_table = sy8106a_i2c_id, .id_table = sy8106a_i2c_id,

View File

@ -233,7 +233,7 @@ MODULE_DEVICE_TABLE(i2c, sy8824_id);
static struct i2c_driver sy8824_regulator_driver = { static struct i2c_driver sy8824_regulator_driver = {
.driver = { .driver = {
.name = "sy8824-regulator", .name = "sy8824-regulator",
.of_match_table = of_match_ptr(sy8824_dt_ids), .of_match_table = sy8824_dt_ids,
}, },
.probe_new = sy8824_i2c_probe, .probe_new = sy8824_i2c_probe,
.id_table = sy8824_id, .id_table = sy8824_id,

View File

@ -170,7 +170,6 @@ static int sy8827n_i2c_probe(struct i2c_client *client)
return ret; return ret;
} }
#ifdef CONFIG_OF
static const struct of_device_id sy8827n_dt_ids[] = { static const struct of_device_id sy8827n_dt_ids[] = {
{ {
.compatible = "silergy,sy8827n", .compatible = "silergy,sy8827n",
@ -178,7 +177,6 @@ static const struct of_device_id sy8827n_dt_ids[] = {
{ } { }
}; };
MODULE_DEVICE_TABLE(of, sy8827n_dt_ids); MODULE_DEVICE_TABLE(of, sy8827n_dt_ids);
#endif
static const struct i2c_device_id sy8827n_id[] = { static const struct i2c_device_id sy8827n_id[] = {
{ "sy8827n", }, { "sy8827n", },
@ -189,7 +187,7 @@ MODULE_DEVICE_TABLE(i2c, sy8827n_id);
static struct i2c_driver sy8827n_regulator_driver = { static struct i2c_driver sy8827n_regulator_driver = {
.driver = { .driver = {
.name = "sy8827n-regulator", .name = "sy8827n-regulator",
.of_match_table = of_match_ptr(sy8827n_dt_ids), .of_match_table = sy8827n_dt_ids,
}, },
.probe_new = sy8827n_i2c_probe, .probe_new = sy8827n_i2c_probe,
.id_table = sy8827n_id, .id_table = sy8827n_id,

View File

@ -247,8 +247,7 @@ static struct tps51632_regulator_platform_data *
} }
#endif #endif
static int tps51632_probe(struct i2c_client *client, static int tps51632_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
struct tps51632_regulator_platform_data *pdata; struct tps51632_regulator_platform_data *pdata;
struct regulator_dev *rdev; struct regulator_dev *rdev;
@ -354,7 +353,7 @@ static struct i2c_driver tps51632_i2c_driver = {
.name = "tps51632", .name = "tps51632",
.of_match_table = of_match_ptr(tps51632_of_match), .of_match_table = of_match_ptr(tps51632_of_match),
}, },
.probe = tps51632_probe, .probe_new = tps51632_probe,
.id_table = tps51632_id, .id_table = tps51632_id,
}; };

View File

@ -322,9 +322,9 @@ static const struct of_device_id tps62360_of_match[] = {
MODULE_DEVICE_TABLE(of, tps62360_of_match); MODULE_DEVICE_TABLE(of, tps62360_of_match);
#endif #endif
static int tps62360_probe(struct i2c_client *client, static int tps62360_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct regulator_config config = { }; struct regulator_config config = { };
struct tps62360_regulator_platform_data *pdata; struct tps62360_regulator_platform_data *pdata;
struct regulator_dev *rdev; struct regulator_dev *rdev;
@ -497,7 +497,7 @@ static struct i2c_driver tps62360_i2c_driver = {
.name = "tps62360", .name = "tps62360",
.of_match_table = of_match_ptr(tps62360_of_match), .of_match_table = of_match_ptr(tps62360_of_match),
}, },
.probe = tps62360_probe, .probe_new = tps62360_probe,
.shutdown = tps62360_shutdown, .shutdown = tps62360_shutdown,
.id_table = tps62360_id, .id_table = tps62360_id,
}; };

View File

@ -111,8 +111,7 @@ static const struct of_device_id tps6286x_dt_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, tps6286x_dt_ids); MODULE_DEVICE_TABLE(of, tps6286x_dt_ids);
static int tps6286x_i2c_probe(struct i2c_client *i2c, static int tps6286x_i2c_probe(struct i2c_client *i2c)
const struct i2c_device_id *id)
{ {
struct device *dev = &i2c->dev; struct device *dev = &i2c->dev;
struct regulator_config config = {}; struct regulator_config config = {};
@ -150,7 +149,7 @@ static struct i2c_driver tps6286x_regulator_driver = {
.name = "tps6286x", .name = "tps6286x",
.of_match_table = of_match_ptr(tps6286x_dt_ids), .of_match_table = of_match_ptr(tps6286x_dt_ids),
}, },
.probe = tps6286x_i2c_probe, .probe_new = tps6286x_i2c_probe,
.id_table = tps6286x_i2c_id, .id_table = tps6286x_i2c_id,
}; };

View File

@ -257,9 +257,9 @@ static struct tps_driver_data tps65023_drv_data = {
.core_regulator = TPS65023_DCDC_1, .core_regulator = TPS65023_DCDC_1,
}; };
static int tps_65023_probe(struct i2c_client *client, static int tps_65023_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
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_init_data *init_data = dev_get_platdata(&client->dev);
struct regulator_config config = { }; struct regulator_config config = { };
struct tps_pmic *tps; struct tps_pmic *tps;
@ -336,7 +336,7 @@ static struct i2c_driver tps_65023_i2c_driver = {
.name = "tps65023", .name = "tps65023",
.of_match_table = of_match_ptr(tps65023_of_match), .of_match_table = of_match_ptr(tps65023_of_match),
}, },
.probe = tps_65023_probe, .probe_new = tps_65023_probe,
.id_table = tps_65023_id, .id_table = tps_65023_id,
}; };

View File

@ -14,6 +14,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/regulator/userspace-consumer.h> #include <linux/regulator/userspace-consumer.h>
@ -24,6 +25,7 @@ struct userspace_consumer_data {
struct mutex lock; struct mutex lock;
bool enabled; bool enabled;
bool no_autoswitch;
int num_supplies; int num_supplies;
struct regulator_bulk_data *supplies; struct regulator_bulk_data *supplies;
@ -96,19 +98,50 @@ static struct attribute *attributes[] = {
NULL, 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 = { static const struct attribute_group attr_group = {
.attrs = attributes, .attrs = attributes,
.is_visible = attr_visible,
}; };
static int regulator_userspace_consumer_probe(struct platform_device *pdev) static int regulator_userspace_consumer_probe(struct platform_device *pdev)
{ {
struct regulator_userspace_consumer_data tmpdata;
struct regulator_userspace_consumer_data *pdata; struct regulator_userspace_consumer_data *pdata;
struct userspace_consumer_data *drvdata; struct userspace_consumer_data *drvdata;
int ret; int ret;
pdata = dev_get_platdata(&pdev->dev); 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; return -EINVAL;
}
drvdata = devm_kzalloc(&pdev->dev, drvdata = devm_kzalloc(&pdev->dev,
sizeof(struct userspace_consumer_data), sizeof(struct userspace_consumer_data),
@ -119,21 +152,24 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev)
drvdata->name = pdata->name; drvdata->name = pdata->name;
drvdata->num_supplies = pdata->num_supplies; drvdata->num_supplies = pdata->num_supplies;
drvdata->supplies = pdata->supplies; drvdata->supplies = pdata->supplies;
drvdata->no_autoswitch = pdata->no_autoswitch;
mutex_init(&drvdata->lock); mutex_init(&drvdata->lock);
ret = devm_regulator_bulk_get(&pdev->dev, drvdata->num_supplies, ret = devm_regulator_bulk_get_exclusive(&pdev->dev, drvdata->num_supplies,
drvdata->supplies); drvdata->supplies);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to get supplies: %d\n", ret); dev_err(&pdev->dev, "Failed to get supplies: %d\n", ret);
return ret; return ret;
} }
platform_set_drvdata(pdev, drvdata);
ret = sysfs_create_group(&pdev->dev.kobj, &attr_group); ret = sysfs_create_group(&pdev->dev.kobj, &attr_group);
if (ret != 0) if (ret != 0)
return ret; return ret;
if (pdata->init_on) { if (pdata->init_on && !pdata->no_autoswitch) {
ret = regulator_bulk_enable(drvdata->num_supplies, ret = regulator_bulk_enable(drvdata->num_supplies,
drvdata->supplies); drvdata->supplies);
if (ret) { if (ret) {
@ -143,8 +179,12 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev)
} }
} }
drvdata->enabled = pdata->init_on; ret = regulator_is_enabled(pdata->supplies[0].consumer);
platform_set_drvdata(pdev, drvdata); if (ret < 0) {
dev_err(&pdev->dev, "Failed to get regulator status\n");
goto err_enable;
}
drvdata->enabled = !!ret;
return 0; return 0;
@ -160,17 +200,23 @@ static int regulator_userspace_consumer_remove(struct platform_device *pdev)
sysfs_remove_group(&pdev->dev.kobj, &attr_group); 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); regulator_bulk_disable(data->num_supplies, data->supplies);
return 0; return 0;
} }
static const struct of_device_id regulator_userspace_consumer_of_match[] = {
{ .compatible = "regulator-output", },
{},
};
static struct platform_driver regulator_userspace_consumer_driver = { static struct platform_driver regulator_userspace_consumer_driver = {
.probe = regulator_userspace_consumer_probe, .probe = regulator_userspace_consumer_probe,
.remove = regulator_userspace_consumer_remove, .remove = regulator_userspace_consumer_remove,
.driver = { .driver = {
.name = "reg-userspace-consumer", .name = "reg-userspace-consumer",
.of_match_table = regulator_userspace_consumer_of_match,
}, },
}; };

View File

@ -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, int __must_check regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *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, int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers); struct regulator_bulk_data *consumers);
void devm_regulator_bulk_put(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( int __must_check devm_regulator_bulk_get_const(
struct device *dev, int num_consumers, struct device *dev, int num_consumers,
const struct regulator_bulk_data *in_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; 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, static inline int regulator_bulk_enable(int num_consumers,
struct regulator_bulk_data *consumers) struct regulator_bulk_data *consumers)
{ {

View File

@ -687,7 +687,8 @@ static inline int regulator_err2notif(int err)
struct regulator_dev * 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); const struct regulator_config *config);
struct regulator_dev * struct regulator_dev *
devm_regulator_register(struct device *dev, devm_regulator_register(struct device *dev,

View File

@ -0,0 +1,51 @@
/* 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 */

View File

@ -21,6 +21,7 @@ struct regulator_userspace_consumer_data {
struct regulator_bulk_data *supplies; struct regulator_bulk_data *supplies;
bool init_on; bool init_on;
bool no_autoswitch;
}; };
#endif /* __REGULATOR_PLATFORM_CONSUMER_H_ */ #endif /* __REGULATOR_PLATFORM_CONSUMER_H_ */

View File

@ -19,6 +19,7 @@ struct qcom_smd_rpm;
#define QCOM_SMD_RPM_CLK_BUF_A 0x616B6C63 #define QCOM_SMD_RPM_CLK_BUF_A 0x616B6C63
#define QCOM_SMD_RPM_LDOA 0x616f646c #define QCOM_SMD_RPM_LDOA 0x616f646c
#define QCOM_SMD_RPM_LDOB 0x626F646C #define QCOM_SMD_RPM_LDOB 0x626F646C
#define QCOM_SMD_RPM_LDOE 0x656f646c
#define QCOM_SMD_RPM_RWCX 0x78637772 #define QCOM_SMD_RPM_RWCX 0x78637772
#define QCOM_SMD_RPM_RWMX 0x786d7772 #define QCOM_SMD_RPM_RWMX 0x786d7772
#define QCOM_SMD_RPM_RWLC 0x636c7772 #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_QUP_CLK 0x707571
#define QCOM_SMD_RPM_SMPA 0x61706d73 #define QCOM_SMD_RPM_SMPA 0x61706d73
#define QCOM_SMD_RPM_SMPB 0x62706d73 #define QCOM_SMD_RPM_SMPB 0x62706d73
#define QCOM_SMD_RPM_SMPE 0x65706d73
#define QCOM_SMD_RPM_SPDM 0x63707362 #define QCOM_SMD_RPM_SPDM 0x63707362
#define QCOM_SMD_RPM_VSA 0x00617376 #define QCOM_SMD_RPM_VSA 0x00617376
#define QCOM_SMD_RPM_MMAXI_CLK 0x69786d6d #define QCOM_SMD_RPM_MMAXI_CLK 0x69786d6d

View File

@ -107,17 +107,8 @@ static const unsigned int range2_vals[] = { RANGE2_MIN, RANGE2_MIN +
#define SMALLEST_VAL RANGE1_MIN #define SMALLEST_VAL RANGE1_MIN
static struct linear_range testr[] = { static struct linear_range testr[] = {
{ LINEAR_RANGE(RANGE1_MIN, RANGE1_MIN_SEL, RANGE1_MAX_SEL, RANGE1_STEP),
.min = RANGE1_MIN, LINEAR_RANGE(RANGE2_MIN, RANGE2_MIN_SEL, RANGE2_MAX_SEL, RANGE2_STEP),
.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
},
}; };
static void range_test_get_value(struct kunit *test) static void range_test_get_value(struct kunit *test)