regulator: Updates for v5.6
Hardly anything going on in the core this time around with the regulator API and pretty quiet on the driver front: - An API for comparing regulators, useful for devices that need to check if supply voltages exactly match rather than just nominally match. - Conversion of several DT bindings to YAML format. - Conversion of I2C drivers to probe_new(). - New drivers for Monolithic MPQ7920 and MP8859, and Rohm BD71828. -----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAl4vH54THGJyb29uaWVA a2VybmVsLm9yZwAKCRAk1otyXVSH0J3sB/9vdpvQa2ei2jyEna4w0ynscV/6HFbF br6U3E7gDzeyNHCz11x8q8cJidD20t44ICitSJkVsjbiJenRbDmrwUpCccCTS/fH byhirQTr+j9+4I/F4U26dpUU3ApOdT2Lsgm3C/SSQHjXg9BuyfdQYXIZjGpPns5F hD/ujf4n+2rPACnWiZC37a781Uct42OHM+ewRCMNdi7pm8lZuEE5edZ+HE+ipT/e QE9ZTXuNvpKOT1LRenXGiv03y3SJHFqRynjWBI5PLTFTO3dg5gY+mEWusLoSufas F3fZtOw0Q1kI7R/SPteYDT5l/htnKJA2g2VHTgwvgObUFSdwM4Eq4efj =++OR -----END PGP SIGNATURE----- Merge tag 'regulator-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator Pull regulator updates from Mark Brown: "Hardly anything going on in the core this time around with the regulator API and pretty quiet on the driver front: - An API for comparing regulators, useful for devices that need to check if supply voltages exactly match rather than just nominally match. - Conversion of several DT bindings to YAML format. - Conversion of I2C drivers to probe_new(). - New drivers for Monolithic MPQ7920 and MP8859, and Rohm BD71828" * tag 'regulator-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (34 commits) dt-bindings: regulator: add document bindings for mpq7920 regulator: core: Fix exported symbols to the exported GPL version regulator: mpq7920: Fix incorrect defines regulator: vqmmc-ipq4019: Fix platform_no_drv_owner.cocci warnings regulator: vctrl-regulator: Avoid deadlock getting and setting the voltage regulator fix for "regulator: core: Add regulator_is_equal() helper" regulator: core: Add regulator_is_equal() helper regulator: mpq7920: Convert to use .probe_new regulator: mpq7920: Remove unneeded fields from struct mpq7920_regulator_info regulator: vqmmc-ipq4019: Trivial clean up regulator: vqmmc-ipq4019: Remove ipq4019_regulator_remove regulator: bindings: Drop document bindings for mpq7920 dt-bindings: Drop entry for Monolithic Power System, MPS regulator: bd718x7: Simplify the code by removing struct bd718xx_pmic_inits regulator: add IPQ4019 SDHCI VQMMC LDO driver regulator: Convert i2c drivers to use .probe_new regulator: mpq7920: Check the correct variable in mpq7920_regulator_register() regulator: mpq7920: Fix Woverflow warning on conversion regulator: mp8859: tidy up white space in probe regulator: mpq7920: add mpq7920 regulator driver ...
This commit is contained in:
commit
aae1464f46
22
Documentation/devicetree/bindings/regulator/mp8859.txt
Normal file
22
Documentation/devicetree/bindings/regulator/mp8859.txt
Normal file
@ -0,0 +1,22 @@
|
||||
Monolithic Power Systems MP8859 voltage regulator
|
||||
|
||||
Required properties:
|
||||
- compatible: "mps,mp8859";
|
||||
- reg: I2C slave address.
|
||||
|
||||
Optional subnode for regulator: "mp8859_dcdc", using common regulator
|
||||
bindings given in <Documentation/devicetree/bindings/regulator/regulator.txt>.
|
||||
|
||||
Example:
|
||||
|
||||
mp8859: regulator@66 {
|
||||
compatible = "mps,mp8859";
|
||||
reg = <0x66>;
|
||||
dc_12v: mp8859_dcdc {
|
||||
regulator-name = "dc_12v";
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
121
Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml
Normal file
121
Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml
Normal file
@ -0,0 +1,121 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/mps,mpq7920.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Monolithic Power System MPQ7920 PMIC
|
||||
|
||||
maintainers:
|
||||
- Saravanan Sekar <sravanhome@gmail.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "pmic@[0-9a-f]{1,2}"
|
||||
compatible:
|
||||
enum:
|
||||
- mps,mpq7920
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
description: |
|
||||
list of regulators provided by this controller, must be named
|
||||
after their hardware counterparts BUCK[1-4], one LDORTC, and LDO[2-5]
|
||||
|
||||
properties:
|
||||
mps,switch-freq:
|
||||
allOf:
|
||||
- $ref: "/schemas/types.yaml#/definitions/uint8"
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
default: 2
|
||||
description: |
|
||||
switching frequency must be one of following corresponding value
|
||||
1.1MHz, 1.65MHz, 2.2MHz, 2.75MHz
|
||||
|
||||
patternProperties:
|
||||
"^ldo[1-4]$":
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
|
||||
"^ldortc$":
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
|
||||
"^buck[1-4]$":
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
|
||||
properties:
|
||||
mps,buck-softstart:
|
||||
allOf:
|
||||
- $ref: "/schemas/types.yaml#/definitions/uint8"
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
description: |
|
||||
defines the soft start time of this buck, must be one of the following
|
||||
corresponding values 150us, 300us, 610us, 920us
|
||||
|
||||
mps,buck-phase-delay:
|
||||
allOf:
|
||||
- $ref: "/schemas/types.yaml#/definitions/uint8"
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
description: |
|
||||
defines the phase delay of this buck, must be one of the following
|
||||
corresponding values 0deg, 90deg, 180deg, 270deg
|
||||
|
||||
mps,buck-ovp-disable:
|
||||
type: boolean
|
||||
description: |
|
||||
disables over voltage protection of this buck
|
||||
|
||||
additionalProperties: false
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- regulators
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic@69 {
|
||||
compatible = "mps,mpq7920";
|
||||
reg = <0x69>;
|
||||
|
||||
regulators {
|
||||
mps,switch-freq = /bits/ 8 <1>;
|
||||
|
||||
buck1 {
|
||||
regulator-name = "buck1";
|
||||
regulator-min-microvolt = <400000>;
|
||||
regulator-max-microvolt = <3587500>;
|
||||
regulator-min-microamp = <460000>;
|
||||
regulator-max-microamp = <7600000>;
|
||||
regulator-boot-on;
|
||||
mps,buck-ovp-disable;
|
||||
mps,buck-phase-delay = /bits/ 8 <2>;
|
||||
mps,buck-softstart = /bits/ 8 <1>;
|
||||
};
|
||||
|
||||
ldo2 {
|
||||
regulator-name = "ldo2";
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <3587500>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -0,0 +1,107 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/rohm,bd71828-regulator.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ROHM BD71828 Power Management Integrated Circuit regulators
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
|
||||
description: |
|
||||
This module is part of the ROHM BD71828 MFD device. For more details
|
||||
see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
|
||||
|
||||
The regulator controller is represented as a sub-node of the PMIC node
|
||||
on the device tree.
|
||||
|
||||
Regulator nodes should be named to BUCK_<number> and LDO_<number>.
|
||||
The valid names for BD71828 regulator nodes are
|
||||
BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7
|
||||
LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7
|
||||
|
||||
patternProperties:
|
||||
"^LDO[1-7]$":
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
description:
|
||||
Properties for single LDO regulator.
|
||||
|
||||
properties:
|
||||
regulator-name:
|
||||
pattern: "^ldo[1-7]$"
|
||||
description:
|
||||
should be "ldo1", ..., "ldo7"
|
||||
|
||||
"^BUCK[1-7]$":
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
description:
|
||||
Properties for single BUCK regulator.
|
||||
|
||||
properties:
|
||||
regulator-name:
|
||||
pattern: "^buck[1-7]$"
|
||||
description:
|
||||
should be "buck1", ..., "buck7"
|
||||
|
||||
rohm,dvs-run-voltage:
|
||||
allOf:
|
||||
- $ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
- minimum: 0
|
||||
maximum: 3300000
|
||||
description:
|
||||
PMIC default "RUN" state voltage in uV. See below table for
|
||||
bucks which support this. 0 means disabled.
|
||||
|
||||
rohm,dvs-idle-voltage:
|
||||
allOf:
|
||||
- $ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
- minimum: 0
|
||||
maximum: 3300000
|
||||
description:
|
||||
PMIC default "IDLE" state voltage in uV. See below table for
|
||||
bucks which support this. 0 means disabled.
|
||||
|
||||
rohm,dvs-suspend-voltage:
|
||||
allOf:
|
||||
- $ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
- minimum: 0
|
||||
maximum: 3300000
|
||||
description:
|
||||
PMIC default "SUSPEND" state voltage in uV. See below table for
|
||||
bucks which support this. 0 means disabled.
|
||||
|
||||
rohm,dvs-lpsr-voltage:
|
||||
allOf:
|
||||
- $ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
- minimum: 0
|
||||
maximum: 3300000
|
||||
description:
|
||||
PMIC default "LPSR" state voltage in uV. See below table for
|
||||
bucks which support this. 0 means disabled.
|
||||
|
||||
# Supported default DVS states:
|
||||
# buck | run | idle | suspend | lpsr
|
||||
#--------------------------------------------------------------
|
||||
# 1, 2, 6, and 7 | supported | supported | supported (*)
|
||||
#--------------------------------------------------------------
|
||||
# 3, 4, and 5 | supported (**)
|
||||
#--------------------------------------------------------------
|
||||
#
|
||||
#(*) LPSR and SUSPEND states use same voltage but both states have own
|
||||
# enable /
|
||||
# disable settings. Voltage 0 can be specified for a state to make
|
||||
# regulator disabled on that state.
|
||||
#
|
||||
#(**) All states use same voltage but have own enable / disable
|
||||
# settings. Voltage 0 can be specified for a state to make
|
||||
# regulator disabled on that state.
|
||||
|
||||
required:
|
||||
- regulator-name
|
||||
additionalProperties: false
|
||||
additionalProperties: false
|
@ -1,18 +0,0 @@
|
||||
STM32 BOOSTER - Booster for ADC analog input switches
|
||||
|
||||
Some STM32 devices embed a 3.3V booster supplied by Vdda, that can be used
|
||||
to supply ADC analog input switches.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be one of:
|
||||
"st,stm32h7-booster"
|
||||
"st,stm32mp1-booster"
|
||||
- st,syscfg: Phandle to system configuration controller.
|
||||
- vdda-supply: Phandle to the vdda input analog voltage.
|
||||
|
||||
Example:
|
||||
booster: regulator-booster {
|
||||
compatible = "st,stm32mp1-booster";
|
||||
st,syscfg = <&syscfg>;
|
||||
vdda-supply = <&vdda>;
|
||||
};
|
@ -0,0 +1,46 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/st,stm32-booster.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STM32 booster for ADC analog input switches bindings
|
||||
|
||||
maintainers:
|
||||
- Fabrice Gasnier <fabrice.gasnier@st.com>
|
||||
|
||||
description: |
|
||||
Some STM32 devices embed a 3.3V booster supplied by Vdda, that can be used
|
||||
to supply ADC analog input switches.
|
||||
|
||||
allOf:
|
||||
- $ref: "regulator.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- st,stm32h7-booster
|
||||
- st,stm32mp1-booster
|
||||
|
||||
st,syscfg:
|
||||
allOf:
|
||||
- $ref: "/schemas/types.yaml#/definitions/phandle-array"
|
||||
description: phandle to system configuration controller.
|
||||
|
||||
vdda-supply:
|
||||
description: phandle to the vdda input analog voltage.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- st,syscfg
|
||||
- vdda-supply
|
||||
|
||||
examples:
|
||||
- |
|
||||
regulator-booster {
|
||||
compatible = "st,stm32mp1-booster";
|
||||
st,syscfg = <&syscfg>;
|
||||
vdda-supply = <&vdda>;
|
||||
};
|
||||
|
||||
...
|
@ -1,20 +0,0 @@
|
||||
STM32 VREFBUF - Voltage reference buffer
|
||||
|
||||
Some STM32 devices embed a voltage reference buffer which can be used as
|
||||
voltage reference for ADCs, DACs and also as voltage reference for external
|
||||
components through the dedicated VREF+ pin.
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "st,stm32-vrefbuf".
|
||||
- reg: Offset and length of VREFBUF register set.
|
||||
- clocks: Must contain an entry for peripheral clock.
|
||||
|
||||
Example:
|
||||
vrefbuf: regulator@58003c00 {
|
||||
compatible = "st,stm32-vrefbuf";
|
||||
reg = <0x58003C00 0x8>;
|
||||
clocks = <&rcc VREF_CK>;
|
||||
regulator-min-microvolt = <1500000>;
|
||||
regulator-max-microvolt = <2500000>;
|
||||
vdda-supply = <&vdda>;
|
||||
};
|
@ -0,0 +1,52 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/st,stm32-vrefbuf.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STM32 Voltage reference buffer bindings
|
||||
|
||||
description: |
|
||||
Some STM32 devices embed a voltage reference buffer which can be used as
|
||||
voltage reference for ADCs, DACs and also as voltage reference for external
|
||||
components through the dedicated VREF+ pin.
|
||||
|
||||
maintainers:
|
||||
- Fabrice Gasnier <fabrice.gasnier@st.com>
|
||||
|
||||
allOf:
|
||||
- $ref: "regulator.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-vrefbuf
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
vdda-supply:
|
||||
description: phandle to the vdda input analog voltage.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- vdda-supply
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
vrefbuf@50025000 {
|
||||
compatible = "st,stm32-vrefbuf";
|
||||
reg = <0x50025000 0x8>;
|
||||
regulator-min-microvolt = <1500000>;
|
||||
regulator-max-microvolt = <2500000>;
|
||||
clocks = <&rcc VREF>;
|
||||
vdda-supply = <&vdda>;
|
||||
};
|
||||
|
||||
...
|
||||
|
@ -1,43 +0,0 @@
|
||||
STM32MP1 PWR Regulators
|
||||
-----------------------
|
||||
|
||||
Available Regulators in STM32MP1 PWR block are:
|
||||
- reg11 for regulator 1V1
|
||||
- reg18 for regulator 1V8
|
||||
- usb33 for the swtich USB3V3
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "st,stm32mp1,pwr-reg"
|
||||
- list of child nodes that specify the regulator reg11, reg18 or usb33
|
||||
initialization data for defined regulators. The definition for each of
|
||||
these nodes is defined using the standard binding for regulators found at
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt.
|
||||
- vdd-supply: phandle to the parent supply/regulator node for vdd input
|
||||
- vdd_3v3_usbfs-supply: phandle to the parent supply/regulator node for usb33
|
||||
|
||||
Example:
|
||||
|
||||
pwr_regulators: pwr@50001000 {
|
||||
compatible = "st,stm32mp1,pwr-reg";
|
||||
reg = <0x50001000 0x10>;
|
||||
vdd-supply = <&vdd>;
|
||||
vdd_3v3_usbfs-supply = <&vdd_usb>;
|
||||
|
||||
reg11: reg11 {
|
||||
regulator-name = "reg11";
|
||||
regulator-min-microvolt = <1100000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
};
|
||||
|
||||
reg18: reg18 {
|
||||
regulator-name = "reg18";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
usb33: usb33 {
|
||||
regulator-name = "usb33";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
};
|
@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/st,stm32mp1-pwr-reg.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STM32MP1 PWR voltage regulators
|
||||
|
||||
maintainers:
|
||||
- Pascal Paillet <p.paillet@st.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32mp1,pwr-reg
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
vdd-supply:
|
||||
description: Input supply phandle(s) for vdd input
|
||||
|
||||
vdd_3v3_usbfs-supply:
|
||||
description: Input supply phandle(s) for vdd_3v3_usbfs input
|
||||
|
||||
patternProperties:
|
||||
"^(reg11|reg18|usb33)$":
|
||||
type: object
|
||||
|
||||
allOf:
|
||||
- $ref: "regulator.yaml#"
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
pwr@50001000 {
|
||||
compatible = "st,stm32mp1,pwr-reg";
|
||||
reg = <0x50001000 0x10>;
|
||||
vdd-supply = <&vdd>;
|
||||
vdd_3v3_usbfs-supply = <&vdd_usb>;
|
||||
|
||||
reg11 {
|
||||
regulator-name = "reg11";
|
||||
regulator-min-microvolt = <1100000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
};
|
||||
|
||||
reg18 {
|
||||
regulator-name = "reg18";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
usb33 {
|
||||
regulator-name = "usb33";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
...
|
@ -11174,6 +11174,13 @@ S: Maintained
|
||||
F: Documentation/driver-api/serial/moxa-smartio.rst
|
||||
F: drivers/tty/mxser.*
|
||||
|
||||
MONOLITHIC POWER SYSTEM PMIC DRIVER
|
||||
M: Saravanan Sekar <sravanhome@gmail.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/regulator/mpq7920.yaml
|
||||
F: drivers/regulator/mpq7920.c
|
||||
F: drivers/regulator/mpq7920.h
|
||||
|
||||
MR800 AVERMEDIA USB FM RADIO DRIVER
|
||||
M: Alexey Klimov <klimov.linux@gmail.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -194,6 +194,18 @@ config REGULATOR_BD70528
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called bd70528-regulator.
|
||||
|
||||
config REGULATOR_BD71828
|
||||
tristate "ROHM BD71828 Power Regulator"
|
||||
depends on MFD_ROHM_BD71828
|
||||
select REGULATOR_ROHM
|
||||
help
|
||||
This driver supports voltage regulators on ROHM BD71828 PMIC.
|
||||
This will enable support for the software controllable buck
|
||||
and LDO regulators.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called bd71828-regulator.
|
||||
|
||||
config REGULATOR_BD718XX
|
||||
tristate "ROHM BD71837 Power Regulator"
|
||||
depends on MFD_ROHM_BD718XX
|
||||
@ -600,6 +612,27 @@ config REGULATOR_MCP16502
|
||||
through the regulator interface. In addition it enables
|
||||
suspend-to-ram/standby transition.
|
||||
|
||||
config REGULATOR_MP8859
|
||||
tristate "MPS MP8859 regulator driver"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say y here to support the MP8859 voltage regulator. This driver
|
||||
supports basic operations (get/set voltage) through the regulator
|
||||
interface.
|
||||
Say M here if you want to include support for the regulator as a
|
||||
module. The module will be named "mp8859".
|
||||
|
||||
config REGULATOR_MPQ7920
|
||||
tristate "Monolithic MPQ7920 PMIC"
|
||||
depends on I2C && OF
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say y here to support the MPQ7920 PMIC. This will enable supports
|
||||
the software controllable 4 buck and 5 LDO regulators.
|
||||
This driver supports the control of different power rails of device
|
||||
through regulator interface.
|
||||
|
||||
config REGULATOR_MT6311
|
||||
tristate "MediaTek MT6311 PMIC"
|
||||
depends on I2C
|
||||
@ -1077,6 +1110,13 @@ config REGULATOR_VEXPRESS
|
||||
This driver provides support for voltage regulators available
|
||||
on the ARM Ltd's Versatile Express platform.
|
||||
|
||||
config REGULATOR_VQMMC_IPQ4019
|
||||
tristate "IPQ4019 VQMMC SD LDO regulator support"
|
||||
depends on ARCH_QCOM
|
||||
help
|
||||
This driver provides support for the VQMMC LDO I/0
|
||||
voltage regulator of the IPQ4019 SD/EMMC controller.
|
||||
|
||||
config REGULATOR_WM831X
|
||||
tristate "Wolfson Microelectronics WM831x PMIC regulators"
|
||||
depends on MFD_WM831X
|
||||
|
@ -28,6 +28,7 @@ obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
|
||||
@ -77,6 +78,8 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
|
||||
obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
|
||||
obj-$(CONFIG_REGULATOR_MP8859) += mp8859.o
|
||||
obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o
|
||||
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
|
||||
@ -132,6 +135,7 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_UNIPHIER) += uniphier-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_VQMMC_IPQ4019) += vqmmc-ipq4019-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
|
||||
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
|
||||
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
|
||||
|
807
drivers/regulator/bd71828-regulator.c
Normal file
807
drivers/regulator/bd71828-regulator.c
Normal file
@ -0,0 +1,807 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// Copyright (C) 2019 ROHM Semiconductors
|
||||
// bd71828-regulator.c ROHM BD71828GW-DS1 regulator driver
|
||||
//
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/rohm-bd71828.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
|
||||
struct reg_init {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int val;
|
||||
};
|
||||
struct bd71828_regulator_data {
|
||||
struct regulator_desc desc;
|
||||
const struct rohm_dvs_config dvs;
|
||||
const struct reg_init *reg_inits;
|
||||
int reg_init_amnt;
|
||||
};
|
||||
|
||||
static const struct reg_init buck1_inits[] = {
|
||||
/*
|
||||
* DVS Buck voltages can be changed by register values or via GPIO.
|
||||
* Use register accesses by default.
|
||||
*/
|
||||
{
|
||||
.reg = BD71828_REG_PS_CTRL_1,
|
||||
.mask = BD71828_MASK_DVS_BUCK1_CTRL,
|
||||
.val = BD71828_DVS_BUCK1_CTRL_I2C,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct reg_init buck2_inits[] = {
|
||||
{
|
||||
.reg = BD71828_REG_PS_CTRL_1,
|
||||
.mask = BD71828_MASK_DVS_BUCK2_CTRL,
|
||||
.val = BD71828_DVS_BUCK2_CTRL_I2C,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct reg_init buck6_inits[] = {
|
||||
{
|
||||
.reg = BD71828_REG_PS_CTRL_1,
|
||||
.mask = BD71828_MASK_DVS_BUCK6_CTRL,
|
||||
.val = BD71828_DVS_BUCK6_CTRL_I2C,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct reg_init buck7_inits[] = {
|
||||
{
|
||||
.reg = BD71828_REG_PS_CTRL_1,
|
||||
.mask = BD71828_MASK_DVS_BUCK7_CTRL,
|
||||
.val = BD71828_DVS_BUCK7_CTRL_I2C,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range bd71828_buck1267_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0x00, 0xef, 6250),
|
||||
REGULATOR_LINEAR_RANGE(2000000, 0xf0, 0xff, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range bd71828_buck3_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x0f, 50000),
|
||||
REGULATOR_LINEAR_RANGE(2000000, 0x10, 0x1f, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range bd71828_buck4_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0x00, 0x1f, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0x20, 0x3f, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range bd71828_buck5_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(2500000, 0x00, 0x0f, 50000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 0x10, 0x1f, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range bd71828_ldo_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0x00, 0x31, 50000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 0x32, 0x3f, 0),
|
||||
};
|
||||
|
||||
static int bd71828_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
switch (ramp_delay) {
|
||||
case 1 ... 2500:
|
||||
val = 0;
|
||||
break;
|
||||
case 2501 ... 5000:
|
||||
val = 1;
|
||||
break;
|
||||
case 5001 ... 10000:
|
||||
val = 2;
|
||||
break;
|
||||
case 10001 ... 20000:
|
||||
val = 3;
|
||||
break;
|
||||
default:
|
||||
val = 3;
|
||||
dev_err(&rdev->dev,
|
||||
"ramp_delay: %d not supported, setting 20mV/uS",
|
||||
ramp_delay);
|
||||
}
|
||||
|
||||
/*
|
||||
* On BD71828 the ramp delay level control reg is at offset +2 to
|
||||
* enable reg
|
||||
*/
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg + 2,
|
||||
BD71828_MASK_RAMP_DELAY,
|
||||
val << (ffs(BD71828_MASK_RAMP_DELAY) - 1));
|
||||
}
|
||||
|
||||
static int buck_set_hw_dvs_levels(struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regulator_config *cfg)
|
||||
{
|
||||
struct bd71828_regulator_data *data;
|
||||
|
||||
data = container_of(desc, struct bd71828_regulator_data, desc);
|
||||
|
||||
return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
|
||||
}
|
||||
|
||||
static int ldo6_parse_dt(struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regulator_config *cfg)
|
||||
{
|
||||
int ret, i;
|
||||
uint32_t uv = 0;
|
||||
unsigned int en;
|
||||
struct regmap *regmap = cfg->regmap;
|
||||
static const char * const props[] = { "rohm,dvs-run-voltage",
|
||||
"rohm,dvs-idle-voltage",
|
||||
"rohm,dvs-suspend-voltage",
|
||||
"rohm,dvs-lpsr-voltage" };
|
||||
unsigned int mask[] = { BD71828_MASK_RUN_EN, BD71828_MASK_IDLE_EN,
|
||||
BD71828_MASK_SUSP_EN, BD71828_MASK_LPSR_EN };
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(props); i++) {
|
||||
ret = of_property_read_u32(np, props[i], &uv);
|
||||
if (ret) {
|
||||
if (ret != -EINVAL)
|
||||
return ret;
|
||||
continue;
|
||||
}
|
||||
if (uv)
|
||||
en = 0xffffffff;
|
||||
else
|
||||
en = 0;
|
||||
|
||||
ret = regmap_update_bits(regmap, desc->enable_reg, mask[i], en);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct regulator_ops bd71828_buck_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd71828_dvs_buck_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.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,
|
||||
.set_ramp_delay = bd71828_set_ramp_delay,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd71828_ldo_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd71828_ldo6_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static const struct bd71828_regulator_data bd71828_rdata[] = {
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck1",
|
||||
.of_match = of_match_ptr("BUCK1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_BUCK1,
|
||||
.ops = &bd71828_dvs_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_buck1267_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
|
||||
.n_voltages = BD71828_BUCK1267_VOLTS,
|
||||
.enable_reg = BD71828_REG_BUCK1_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_BUCK1_VOLT,
|
||||
.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_BUCK1_VOLT,
|
||||
.run_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.idle_reg = BD71828_REG_BUCK1_IDLE_VOLT,
|
||||
.idle_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_reg = BD71828_REG_BUCK1_SUSP_VOLT,
|
||||
.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
/*
|
||||
* LPSR voltage is same as SUSPEND voltage. Allow
|
||||
* setting it so that regulator can be set enabled at
|
||||
* LPSR state
|
||||
*/
|
||||
.lpsr_reg = BD71828_REG_BUCK1_SUSP_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
},
|
||||
.reg_inits = buck1_inits,
|
||||
.reg_init_amnt = ARRAY_SIZE(buck1_inits),
|
||||
},
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck2",
|
||||
.of_match = of_match_ptr("BUCK2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_BUCK2,
|
||||
.ops = &bd71828_dvs_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_buck1267_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
|
||||
.n_voltages = BD71828_BUCK1267_VOLTS,
|
||||
.enable_reg = BD71828_REG_BUCK2_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_BUCK2_VOLT,
|
||||
.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_BUCK2_VOLT,
|
||||
.run_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.idle_reg = BD71828_REG_BUCK2_IDLE_VOLT,
|
||||
.idle_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_reg = BD71828_REG_BUCK2_SUSP_VOLT,
|
||||
.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
.lpsr_reg = BD71828_REG_BUCK2_SUSP_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
},
|
||||
.reg_inits = buck2_inits,
|
||||
.reg_init_amnt = ARRAY_SIZE(buck2_inits),
|
||||
},
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck3",
|
||||
.of_match = of_match_ptr("BUCK3"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_BUCK3,
|
||||
.ops = &bd71828_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_buck3_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_buck3_volts),
|
||||
.n_voltages = BD71828_BUCK3_VOLTS,
|
||||
.enable_reg = BD71828_REG_BUCK3_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_BUCK3_VOLT,
|
||||
.vsel_mask = BD71828_MASK_BUCK3_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
/*
|
||||
* BUCK3 only supports single voltage for all states.
|
||||
* voltage can be individually enabled for each state
|
||||
* though => allow setting all states to support
|
||||
* enabling power rail on different states.
|
||||
*/
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_BUCK3_VOLT,
|
||||
.idle_reg = BD71828_REG_BUCK3_VOLT,
|
||||
.suspend_reg = BD71828_REG_BUCK3_VOLT,
|
||||
.lpsr_reg = BD71828_REG_BUCK3_VOLT,
|
||||
.run_mask = BD71828_MASK_BUCK3_VOLT,
|
||||
.idle_mask = BD71828_MASK_BUCK3_VOLT,
|
||||
.suspend_mask = BD71828_MASK_BUCK3_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_BUCK3_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
},
|
||||
},
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck4",
|
||||
.of_match = of_match_ptr("BUCK4"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_BUCK4,
|
||||
.ops = &bd71828_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_buck4_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_buck4_volts),
|
||||
.n_voltages = BD71828_BUCK4_VOLTS,
|
||||
.enable_reg = BD71828_REG_BUCK4_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_BUCK4_VOLT,
|
||||
.vsel_mask = BD71828_MASK_BUCK4_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
/*
|
||||
* BUCK4 only supports single voltage for all states.
|
||||
* voltage can be individually enabled for each state
|
||||
* though => allow setting all states to support
|
||||
* enabling power rail on different states.
|
||||
*/
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_BUCK4_VOLT,
|
||||
.idle_reg = BD71828_REG_BUCK4_VOLT,
|
||||
.suspend_reg = BD71828_REG_BUCK4_VOLT,
|
||||
.lpsr_reg = BD71828_REG_BUCK4_VOLT,
|
||||
.run_mask = BD71828_MASK_BUCK4_VOLT,
|
||||
.idle_mask = BD71828_MASK_BUCK4_VOLT,
|
||||
.suspend_mask = BD71828_MASK_BUCK4_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_BUCK4_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
},
|
||||
},
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck5",
|
||||
.of_match = of_match_ptr("BUCK5"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_BUCK5,
|
||||
.ops = &bd71828_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_buck5_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_buck5_volts),
|
||||
.n_voltages = BD71828_BUCK5_VOLTS,
|
||||
.enable_reg = BD71828_REG_BUCK5_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_BUCK5_VOLT,
|
||||
.vsel_mask = BD71828_MASK_BUCK5_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
/*
|
||||
* BUCK5 only supports single voltage for all states.
|
||||
* voltage can be individually enabled for each state
|
||||
* though => allow setting all states to support
|
||||
* enabling power rail on different states.
|
||||
*/
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_BUCK5_VOLT,
|
||||
.idle_reg = BD71828_REG_BUCK5_VOLT,
|
||||
.suspend_reg = BD71828_REG_BUCK5_VOLT,
|
||||
.lpsr_reg = BD71828_REG_BUCK5_VOLT,
|
||||
.run_mask = BD71828_MASK_BUCK5_VOLT,
|
||||
.idle_mask = BD71828_MASK_BUCK5_VOLT,
|
||||
.suspend_mask = BD71828_MASK_BUCK5_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_BUCK5_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
},
|
||||
},
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck6",
|
||||
.of_match = of_match_ptr("BUCK6"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_BUCK6,
|
||||
.ops = &bd71828_dvs_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_buck1267_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
|
||||
.n_voltages = BD71828_BUCK1267_VOLTS,
|
||||
.enable_reg = BD71828_REG_BUCK6_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_BUCK6_VOLT,
|
||||
.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_BUCK6_VOLT,
|
||||
.run_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.idle_reg = BD71828_REG_BUCK6_IDLE_VOLT,
|
||||
.idle_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_reg = BD71828_REG_BUCK6_SUSP_VOLT,
|
||||
.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
.lpsr_reg = BD71828_REG_BUCK6_SUSP_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
},
|
||||
.reg_inits = buck6_inits,
|
||||
.reg_init_amnt = ARRAY_SIZE(buck6_inits),
|
||||
},
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck7",
|
||||
.of_match = of_match_ptr("BUCK7"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_BUCK7,
|
||||
.ops = &bd71828_dvs_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_buck1267_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
|
||||
.n_voltages = BD71828_BUCK1267_VOLTS,
|
||||
.enable_reg = BD71828_REG_BUCK7_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_BUCK7_VOLT,
|
||||
.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_BUCK7_VOLT,
|
||||
.run_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.idle_reg = BD71828_REG_BUCK7_IDLE_VOLT,
|
||||
.idle_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_reg = BD71828_REG_BUCK7_SUSP_VOLT,
|
||||
.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
.lpsr_reg = BD71828_REG_BUCK7_SUSP_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
|
||||
},
|
||||
.reg_inits = buck7_inits,
|
||||
.reg_init_amnt = ARRAY_SIZE(buck7_inits),
|
||||
},
|
||||
{
|
||||
.desc = {
|
||||
.name = "ldo1",
|
||||
.of_match = of_match_ptr("LDO1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_LDO1,
|
||||
.ops = &bd71828_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_ldo_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
|
||||
.n_voltages = BD71828_LDO_VOLTS,
|
||||
.enable_reg = BD71828_REG_LDO1_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_LDO1_VOLT,
|
||||
.vsel_mask = BD71828_MASK_LDO_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
/*
|
||||
* LDO1 only supports single voltage for all states.
|
||||
* voltage can be individually enabled for each state
|
||||
* though => allow setting all states to support
|
||||
* enabling power rail on different states.
|
||||
*/
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_LDO1_VOLT,
|
||||
.idle_reg = BD71828_REG_LDO1_VOLT,
|
||||
.suspend_reg = BD71828_REG_LDO1_VOLT,
|
||||
.lpsr_reg = BD71828_REG_LDO1_VOLT,
|
||||
.run_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_mask = BD71828_MASK_LDO_VOLT,
|
||||
.suspend_mask = BD71828_MASK_LDO_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
},
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "ldo2",
|
||||
.of_match = of_match_ptr("LDO2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_LDO2,
|
||||
.ops = &bd71828_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_ldo_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
|
||||
.n_voltages = BD71828_LDO_VOLTS,
|
||||
.enable_reg = BD71828_REG_LDO2_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_LDO2_VOLT,
|
||||
.vsel_mask = BD71828_MASK_LDO_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
/*
|
||||
* LDO2 only supports single voltage for all states.
|
||||
* voltage can be individually enabled for each state
|
||||
* though => allow setting all states to support
|
||||
* enabling power rail on different states.
|
||||
*/
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_LDO2_VOLT,
|
||||
.idle_reg = BD71828_REG_LDO2_VOLT,
|
||||
.suspend_reg = BD71828_REG_LDO2_VOLT,
|
||||
.lpsr_reg = BD71828_REG_LDO2_VOLT,
|
||||
.run_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_mask = BD71828_MASK_LDO_VOLT,
|
||||
.suspend_mask = BD71828_MASK_LDO_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
},
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "ldo3",
|
||||
.of_match = of_match_ptr("LDO3"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_LDO3,
|
||||
.ops = &bd71828_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_ldo_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
|
||||
.n_voltages = BD71828_LDO_VOLTS,
|
||||
.enable_reg = BD71828_REG_LDO3_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_LDO3_VOLT,
|
||||
.vsel_mask = BD71828_MASK_LDO_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
/*
|
||||
* LDO3 only supports single voltage for all states.
|
||||
* voltage can be individually enabled for each state
|
||||
* though => allow setting all states to support
|
||||
* enabling power rail on different states.
|
||||
*/
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_LDO3_VOLT,
|
||||
.idle_reg = BD71828_REG_LDO3_VOLT,
|
||||
.suspend_reg = BD71828_REG_LDO3_VOLT,
|
||||
.lpsr_reg = BD71828_REG_LDO3_VOLT,
|
||||
.run_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_mask = BD71828_MASK_LDO_VOLT,
|
||||
.suspend_mask = BD71828_MASK_LDO_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
},
|
||||
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "ldo4",
|
||||
.of_match = of_match_ptr("LDO4"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_LDO4,
|
||||
.ops = &bd71828_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_ldo_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
|
||||
.n_voltages = BD71828_LDO_VOLTS,
|
||||
.enable_reg = BD71828_REG_LDO4_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_LDO4_VOLT,
|
||||
.vsel_mask = BD71828_MASK_LDO_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
/*
|
||||
* LDO1 only supports single voltage for all states.
|
||||
* voltage can be individually enabled for each state
|
||||
* though => allow setting all states to support
|
||||
* enabling power rail on different states.
|
||||
*/
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_LDO4_VOLT,
|
||||
.idle_reg = BD71828_REG_LDO4_VOLT,
|
||||
.suspend_reg = BD71828_REG_LDO4_VOLT,
|
||||
.lpsr_reg = BD71828_REG_LDO4_VOLT,
|
||||
.run_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_mask = BD71828_MASK_LDO_VOLT,
|
||||
.suspend_mask = BD71828_MASK_LDO_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
},
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "ldo5",
|
||||
.of_match = of_match_ptr("LDO5"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_LDO5,
|
||||
.ops = &bd71828_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_ldo_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
|
||||
.n_voltages = BD71828_LDO_VOLTS,
|
||||
.enable_reg = BD71828_REG_LDO5_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_LDO5_VOLT,
|
||||
.vsel_mask = BD71828_MASK_LDO_VOLT,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
/*
|
||||
* LDO5 is special. It can choose vsel settings to be configured
|
||||
* from 2 different registers (by GPIO).
|
||||
*
|
||||
* This driver supports only configuration where
|
||||
* BD71828_REG_LDO5_VOLT_L is used.
|
||||
*/
|
||||
.dvs = {
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_LDO5_VOLT,
|
||||
.idle_reg = BD71828_REG_LDO5_VOLT,
|
||||
.suspend_reg = BD71828_REG_LDO5_VOLT,
|
||||
.lpsr_reg = BD71828_REG_LDO5_VOLT,
|
||||
.run_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_mask = BD71828_MASK_LDO_VOLT,
|
||||
.suspend_mask = BD71828_MASK_LDO_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
},
|
||||
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "ldo6",
|
||||
.of_match = of_match_ptr("LDO6"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_LDO6,
|
||||
.ops = &bd71828_ldo6_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.fixed_uV = BD71828_LDO_6_VOLTAGE,
|
||||
.n_voltages = 1,
|
||||
.enable_reg = BD71828_REG_LDO6_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.owner = THIS_MODULE,
|
||||
/*
|
||||
* LDO6 only supports enable/disable for all states.
|
||||
* Voltage for LDO6 is fixed.
|
||||
*/
|
||||
.of_parse_cb = ldo6_parse_dt,
|
||||
},
|
||||
}, {
|
||||
.desc = {
|
||||
/* SNVS LDO in data-sheet */
|
||||
.name = "ldo7",
|
||||
.of_match = of_match_ptr("LDO7"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD71828_LDO_SNVS,
|
||||
.ops = &bd71828_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd71828_ldo_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
|
||||
.n_voltages = BD71828_LDO_VOLTS,
|
||||
.enable_reg = BD71828_REG_LDO7_EN,
|
||||
.enable_mask = BD71828_MASK_RUN_EN,
|
||||
.vsel_reg = BD71828_REG_LDO7_VOLT,
|
||||
.vsel_mask = BD71828_MASK_LDO_VOLT,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||
},
|
||||
.dvs = {
|
||||
/*
|
||||
* LDO7 only supports single voltage for all states.
|
||||
* voltage can be individually enabled for each state
|
||||
* though => allow setting all states to support
|
||||
* enabling power rail on different states.
|
||||
*/
|
||||
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
|
||||
ROHM_DVS_LEVEL_SUSPEND |
|
||||
ROHM_DVS_LEVEL_LPSR,
|
||||
.run_reg = BD71828_REG_LDO7_VOLT,
|
||||
.idle_reg = BD71828_REG_LDO7_VOLT,
|
||||
.suspend_reg = BD71828_REG_LDO7_VOLT,
|
||||
.lpsr_reg = BD71828_REG_LDO7_VOLT,
|
||||
.run_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_mask = BD71828_MASK_LDO_VOLT,
|
||||
.suspend_mask = BD71828_MASK_LDO_VOLT,
|
||||
.lpsr_mask = BD71828_MASK_LDO_VOLT,
|
||||
.idle_on_mask = BD71828_MASK_IDLE_EN,
|
||||
.suspend_on_mask = BD71828_MASK_SUSP_EN,
|
||||
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
|
||||
},
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
static int bd71828_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rohm_regmap_dev *bd71828;
|
||||
int i, j, ret;
|
||||
struct regulator_config config = {
|
||||
.dev = pdev->dev.parent,
|
||||
};
|
||||
|
||||
bd71828 = dev_get_drvdata(pdev->dev.parent);
|
||||
if (!bd71828) {
|
||||
dev_err(&pdev->dev, "No MFD driver data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
config.regmap = bd71828->regmap;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bd71828_rdata); i++) {
|
||||
struct regulator_dev *rdev;
|
||||
const struct bd71828_regulator_data *rd;
|
||||
|
||||
rd = &bd71828_rdata[i];
|
||||
rdev = devm_regulator_register(&pdev->dev,
|
||||
&rd->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to register %s regulator\n",
|
||||
rd->desc.name);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
for (j = 0; j < rd->reg_init_amnt; j++) {
|
||||
ret = regmap_update_bits(bd71828->regmap,
|
||||
rd->reg_inits[j].reg,
|
||||
rd->reg_inits[j].mask,
|
||||
rd->reg_inits[j].val);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"regulator %s init failed\n",
|
||||
rd->desc.name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver bd71828_regulator = {
|
||||
.driver = {
|
||||
.name = "bd71828-pmic"
|
||||
},
|
||||
.probe = bd71828_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(bd71828_regulator);
|
||||
|
||||
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
|
||||
MODULE_DESCRIPTION("BD71828 voltage regulator driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:bd71828-pmic");
|
@ -1142,28 +1142,14 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
},
|
||||
};
|
||||
|
||||
struct bd718xx_pmic_inits {
|
||||
const struct bd718xx_regulator_data *r_datas;
|
||||
unsigned int r_amount;
|
||||
};
|
||||
|
||||
static int bd718xx_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct bd718xx *mfd;
|
||||
struct regulator_config config = { 0 };
|
||||
struct bd718xx_pmic_inits pmic_regulators[ROHM_CHIP_TYPE_AMOUNT] = {
|
||||
[ROHM_CHIP_TYPE_BD71837] = {
|
||||
.r_datas = bd71837_regulators,
|
||||
.r_amount = ARRAY_SIZE(bd71837_regulators),
|
||||
},
|
||||
[ROHM_CHIP_TYPE_BD71847] = {
|
||||
.r_datas = bd71847_regulators,
|
||||
.r_amount = ARRAY_SIZE(bd71847_regulators),
|
||||
},
|
||||
};
|
||||
|
||||
int i, j, err;
|
||||
bool use_snvs;
|
||||
const struct bd718xx_regulator_data *reg_data;
|
||||
unsigned int num_reg_data;
|
||||
|
||||
mfd = dev_get_drvdata(pdev->dev.parent);
|
||||
if (!mfd) {
|
||||
@ -1172,8 +1158,16 @@ static int bd718xx_probe(struct platform_device *pdev)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (mfd->chip.chip_type >= ROHM_CHIP_TYPE_AMOUNT ||
|
||||
!pmic_regulators[mfd->chip.chip_type].r_datas) {
|
||||
switch (mfd->chip.chip_type) {
|
||||
case ROHM_CHIP_TYPE_BD71837:
|
||||
reg_data = bd71837_regulators;
|
||||
num_reg_data = ARRAY_SIZE(bd71837_regulators);
|
||||
break;
|
||||
case ROHM_CHIP_TYPE_BD71847:
|
||||
reg_data = bd71847_regulators;
|
||||
num_reg_data = ARRAY_SIZE(bd71847_regulators);
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "Unsupported chip type\n");
|
||||
err = -EINVAL;
|
||||
goto err;
|
||||
@ -1215,13 +1209,13 @@ static int bd718xx_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pmic_regulators[mfd->chip.chip_type].r_amount; i++) {
|
||||
for (i = 0; i < num_reg_data; i++) {
|
||||
|
||||
const struct regulator_desc *desc;
|
||||
struct regulator_dev *rdev;
|
||||
const struct bd718xx_regulator_data *r;
|
||||
|
||||
r = &pmic_regulators[mfd->chip.chip_type].r_datas[i];
|
||||
r = ®_data[i];
|
||||
desc = &r->desc;
|
||||
|
||||
config.dev = pdev->dev.parent;
|
||||
|
@ -3470,6 +3470,7 @@ int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_voltage_rdev);
|
||||
|
||||
static int regulator_limit_voltage_step(struct regulator_dev *rdev,
|
||||
int *current_uV, int *min_uV)
|
||||
@ -4034,6 +4035,7 @@ int regulator_get_voltage_rdev(struct regulator_dev *rdev)
|
||||
return ret;
|
||||
return ret - rdev->constraints->uV_offset;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_get_voltage_rdev);
|
||||
|
||||
/**
|
||||
* regulator_get_voltage - get regulator output voltage
|
||||
|
@ -131,8 +131,7 @@ static const struct of_device_id da9210_dt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, da9210_dt_ids);
|
||||
|
||||
static int da9210_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int da9210_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct da9210 *chip;
|
||||
struct device *dev = &i2c->dev;
|
||||
@ -228,7 +227,7 @@ static struct i2c_driver da9210_regulator_driver = {
|
||||
.name = "da9210",
|
||||
.of_match_table = of_match_ptr(da9210_dt_ids),
|
||||
},
|
||||
.probe = da9210_i2c_probe,
|
||||
.probe_new = da9210_i2c_probe,
|
||||
.id_table = da9210_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -416,8 +416,7 @@ static int da9211_regulator_init(struct da9211 *chip)
|
||||
/*
|
||||
* I2C driver interface functions
|
||||
*/
|
||||
static int da9211_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int da9211_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct da9211 *chip;
|
||||
int error, ret;
|
||||
@ -526,7 +525,7 @@ static struct i2c_driver da9211_regulator_driver = {
|
||||
.name = "da9211",
|
||||
.of_match_table = of_match_ptr(da9211_dt_ids),
|
||||
},
|
||||
.probe = da9211_i2c_probe,
|
||||
.probe_new = da9211_i2c_probe,
|
||||
.id_table = da9211_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* regulator_is_enabled_regmap - standard is_enabled() for regmap users
|
||||
*
|
||||
@ -881,3 +883,15 @@ void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
|
||||
consumers[i].supply = supply_names[i];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_bulk_set_supply_names);
|
||||
|
||||
/**
|
||||
* regulator_is_equal - test whether two regulators are the same
|
||||
*
|
||||
* @reg1: first regulator to operate on
|
||||
* @reg2: second regulator to operate on
|
||||
*/
|
||||
bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
|
||||
{
|
||||
return reg1->rdev == reg2->rdev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_is_equal);
|
||||
|
@ -137,8 +137,7 @@ static const struct regmap_config isl9305_regmap = {
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static int isl9305_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int isl9305_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct regulator_config config = { };
|
||||
struct isl9305_pdata *pdata = i2c->dev.platform_data;
|
||||
@ -198,7 +197,7 @@ static struct i2c_driver isl9305_regulator_driver = {
|
||||
.name = "isl9305",
|
||||
.of_match_table = of_match_ptr(isl9305_dt_ids),
|
||||
},
|
||||
.probe = isl9305_i2c_probe,
|
||||
.probe_new = isl9305_i2c_probe,
|
||||
.id_table = isl9305_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -400,8 +400,7 @@ static int setup_regulators(struct lp3971 *lp3971,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp3971_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int lp3971_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct lp3971 *lp3971;
|
||||
struct lp3971_platform_data *pdata = dev_get_platdata(&i2c->dev);
|
||||
@ -449,7 +448,7 @@ static struct i2c_driver lp3971_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "LP3971",
|
||||
},
|
||||
.probe = lp3971_i2c_probe,
|
||||
.probe_new = lp3971_i2c_probe,
|
||||
.id_table = lp3971_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -301,8 +301,7 @@ static irqreturn_t ltc3676_isr(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int ltc3676_regulator_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int ltc3676_regulator_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct regulator_init_data *init_data = dev_get_platdata(dev);
|
||||
@ -380,7 +379,7 @@ static struct i2c_driver ltc3676_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = of_match_ptr(ltc3676_of_match),
|
||||
},
|
||||
.probe = ltc3676_regulator_probe,
|
||||
.probe_new = ltc3676_regulator_probe,
|
||||
.id_table = ltc3676_i2c_id,
|
||||
};
|
||||
module_i2c_driver(ltc3676_driver);
|
||||
|
156
drivers/regulator/mp8859.c
Normal file
156
drivers/regulator/mp8859.c
Normal file
@ -0,0 +1,156 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Copyright (c) 2019 five technologies GmbH
|
||||
// Author: Markus Reichl <m.reichl@fivetechno.de>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
|
||||
#define VOL_MIN_IDX 0x00
|
||||
#define VOL_MAX_IDX 0x7ff
|
||||
|
||||
/* Register definitions */
|
||||
#define MP8859_VOUT_L_REG 0 //3 lo Bits
|
||||
#define MP8859_VOUT_H_REG 1 //8 hi Bits
|
||||
#define MP8859_VOUT_GO_REG 2
|
||||
#define MP8859_IOUT_LIM_REG 3
|
||||
#define MP8859_CTL1_REG 4
|
||||
#define MP8859_CTL2_REG 5
|
||||
#define MP8859_RESERVED1_REG 6
|
||||
#define MP8859_RESERVED2_REG 7
|
||||
#define MP8859_RESERVED3_REG 8
|
||||
#define MP8859_STATUS_REG 9
|
||||
#define MP8859_INTERRUPT_REG 0x0A
|
||||
#define MP8859_MASK_REG 0x0B
|
||||
#define MP8859_ID1_REG 0x0C
|
||||
#define MP8859_MFR_ID_REG 0x27
|
||||
#define MP8859_DEV_ID_REG 0x28
|
||||
#define MP8859_IC_REV_REG 0x29
|
||||
|
||||
#define MP8859_MAX_REG 0x29
|
||||
|
||||
#define MP8859_GO_BIT 0x01
|
||||
|
||||
|
||||
static int mp8859_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_write(rdev->regmap, MP8859_VOUT_L_REG, sel & 0x7);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = regmap_write(rdev->regmap, MP8859_VOUT_H_REG, sel >> 3);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = regmap_update_bits(rdev->regmap, MP8859_VOUT_GO_REG,
|
||||
MP8859_GO_BIT, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mp8859_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int val_tmp;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, MP8859_VOUT_H_REG, &val_tmp);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
val = val_tmp << 3;
|
||||
|
||||
ret = regmap_read(rdev->regmap, MP8859_VOUT_L_REG, &val_tmp);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
val |= val_tmp & 0x07;
|
||||
return val;
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range mp8859_dcdc_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000),
|
||||
};
|
||||
|
||||
static const struct regmap_config mp8859_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = MP8859_MAX_REG,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct regulator_ops mp8859_ops = {
|
||||
.set_voltage_sel = mp8859_set_voltage_sel,
|
||||
.get_voltage_sel = mp8859_get_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
};
|
||||
|
||||
static const struct regulator_desc mp8859_regulators[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.name = "mp8859_dcdc",
|
||||
.of_match = of_match_ptr("mp8859_dcdc"),
|
||||
.n_voltages = VOL_MAX_IDX + 1,
|
||||
.linear_ranges = mp8859_dcdc_ranges,
|
||||
.n_linear_ranges = 1,
|
||||
.ops = &mp8859_ops,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int mp8859_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
int ret;
|
||||
struct regulator_config config = {.dev = &i2c->dev};
|
||||
struct regmap *regmap = devm_regmap_init_i2c(i2c, &mp8859_regmap);
|
||||
struct regulator_dev *rdev;
|
||||
|
||||
if (IS_ERR(regmap)) {
|
||||
ret = PTR_ERR(regmap);
|
||||
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
rdev = devm_regulator_register(&i2c->dev, &mp8859_regulators[0],
|
||||
&config);
|
||||
|
||||
if (IS_ERR(rdev)) {
|
||||
ret = PTR_ERR(rdev);
|
||||
dev_err(&i2c->dev, "failed to register %s: %d\n",
|
||||
mp8859_regulators[0].name, ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mp8859_dt_id[] = {
|
||||
{.compatible = "mps,mp8859"},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mp8859_dt_id);
|
||||
|
||||
static const struct i2c_device_id mp8859_i2c_id[] = {
|
||||
{ "mp8859", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mp8859_i2c_id);
|
||||
|
||||
static struct i2c_driver mp8859_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "mp8859",
|
||||
.of_match_table = of_match_ptr(mp8859_dt_id),
|
||||
},
|
||||
.probe_new = mp8859_i2c_probe,
|
||||
.id_table = mp8859_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(mp8859_regulator_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Monolithic Power Systems MP8859 voltage regulator driver");
|
||||
MODULE_AUTHOR("Markus Reichl <m.reichl@fivetechno.de>");
|
||||
MODULE_LICENSE("GPL v2");
|
330
drivers/regulator/mpq7920.c
Normal file
330
drivers/regulator/mpq7920.c
Normal file
@ -0,0 +1,330 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
//
|
||||
// mpq7920.c - regulator driver for mps mpq7920
|
||||
//
|
||||
// Copyright 2019 Monolithic Power Systems, Inc
|
||||
//
|
||||
// Author: Saravanan Sekar <sravanhome@gmail.com>
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "mpq7920.h"
|
||||
|
||||
#define MPQ7920_BUCK_VOLT_RANGE \
|
||||
((MPQ7920_VOLT_MAX - MPQ7920_BUCK_VOLT_MIN)/MPQ7920_VOLT_STEP + 1)
|
||||
#define MPQ7920_LDO_VOLT_RANGE \
|
||||
((MPQ7920_VOLT_MAX - MPQ7920_LDO_VOLT_MIN)/MPQ7920_VOLT_STEP + 1)
|
||||
|
||||
#define MPQ7920BUCK(_name, _id, _ilim) \
|
||||
[MPQ7920_BUCK ## _id] = { \
|
||||
.id = MPQ7920_BUCK ## _id, \
|
||||
.name = _name, \
|
||||
.of_match = _name, \
|
||||
.regulators_node = "regulators", \
|
||||
.of_parse_cb = mpq7920_parse_cb, \
|
||||
.ops = &mpq7920_buck_ops, \
|
||||
.min_uV = MPQ7920_BUCK_VOLT_MIN, \
|
||||
.uV_step = MPQ7920_VOLT_STEP, \
|
||||
.n_voltages = MPQ7920_BUCK_VOLT_RANGE, \
|
||||
.curr_table = _ilim, \
|
||||
.n_current_limits = ARRAY_SIZE(_ilim), \
|
||||
.csel_reg = MPQ7920_BUCK ##_id## _REG_C, \
|
||||
.csel_mask = MPQ7920_MASK_BUCK_ILIM, \
|
||||
.enable_reg = MPQ7920_REG_REGULATOR_EN, \
|
||||
.enable_mask = BIT(MPQ7920_REGULATOR_EN_OFFSET - \
|
||||
MPQ7920_BUCK ## _id), \
|
||||
.vsel_reg = MPQ7920_BUCK ##_id## _REG_A, \
|
||||
.vsel_mask = MPQ7920_MASK_VREF, \
|
||||
.active_discharge_on = MPQ7920_DISCHARGE_ON, \
|
||||
.active_discharge_reg = MPQ7920_BUCK ##_id## _REG_B, \
|
||||
.active_discharge_mask = MPQ7920_MASK_DISCHARGE, \
|
||||
.soft_start_reg = MPQ7920_BUCK ##_id## _REG_C, \
|
||||
.soft_start_mask = MPQ7920_MASK_SOFTSTART, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
#define MPQ7920LDO(_name, _id, _ops, _ilim, _ilim_sz, _creg, _cmask) \
|
||||
[MPQ7920_LDO ## _id] = { \
|
||||
.id = MPQ7920_LDO ## _id, \
|
||||
.name = _name, \
|
||||
.of_match = _name, \
|
||||
.regulators_node = "regulators", \
|
||||
.ops = _ops, \
|
||||
.min_uV = MPQ7920_LDO_VOLT_MIN, \
|
||||
.uV_step = MPQ7920_VOLT_STEP, \
|
||||
.n_voltages = MPQ7920_LDO_VOLT_RANGE, \
|
||||
.vsel_reg = MPQ7920_LDO ##_id## _REG_A, \
|
||||
.vsel_mask = MPQ7920_MASK_VREF, \
|
||||
.curr_table = _ilim, \
|
||||
.n_current_limits = _ilim_sz, \
|
||||
.csel_reg = _creg, \
|
||||
.csel_mask = _cmask, \
|
||||
.enable_reg = (_id == 1) ? 0 : MPQ7920_REG_REGULATOR_EN,\
|
||||
.enable_mask = BIT(MPQ7920_REGULATOR_EN_OFFSET - \
|
||||
MPQ7920_LDO ##_id + 1), \
|
||||
.active_discharge_on = MPQ7920_DISCHARGE_ON, \
|
||||
.active_discharge_mask = MPQ7920_MASK_DISCHARGE, \
|
||||
.active_discharge_reg = MPQ7920_LDO ##_id## _REG_B, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
enum mpq7920_regulators {
|
||||
MPQ7920_BUCK1,
|
||||
MPQ7920_BUCK2,
|
||||
MPQ7920_BUCK3,
|
||||
MPQ7920_BUCK4,
|
||||
MPQ7920_LDO1, /* LDORTC */
|
||||
MPQ7920_LDO2,
|
||||
MPQ7920_LDO3,
|
||||
MPQ7920_LDO4,
|
||||
MPQ7920_LDO5,
|
||||
MPQ7920_MAX_REGULATORS,
|
||||
};
|
||||
|
||||
struct mpq7920_regulator_info {
|
||||
struct regmap *regmap;
|
||||
struct regulator_desc *rdesc;
|
||||
};
|
||||
|
||||
static const struct regmap_config mpq7920_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0x25,
|
||||
};
|
||||
|
||||
/* Current limits array (in uA)
|
||||
* ILIM1 & ILIM3
|
||||
*/
|
||||
static const unsigned int mpq7920_I_limits1[] = {
|
||||
4600000, 6600000, 7600000, 9300000
|
||||
};
|
||||
|
||||
/* ILIM2 & ILIM4 */
|
||||
static const unsigned int mpq7920_I_limits2[] = {
|
||||
2700000, 3900000, 5100000, 6100000
|
||||
};
|
||||
|
||||
/* LDO4 & LDO5 */
|
||||
static const unsigned int mpq7920_I_limits3[] = {
|
||||
300000, 700000
|
||||
};
|
||||
|
||||
static int mpq7920_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay);
|
||||
static int mpq7920_parse_cb(struct device_node *np,
|
||||
const struct regulator_desc *rdesc,
|
||||
struct regulator_config *config);
|
||||
|
||||
/* RTCLDO not controllable, always ON */
|
||||
static const struct regulator_ops mpq7920_ldortc_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops mpq7920_ldo_wo_current_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops mpq7920_ldo_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops mpq7920_buck_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
.set_soft_start = regulator_set_soft_start_regmap,
|
||||
.set_ramp_delay = mpq7920_set_ramp_delay,
|
||||
};
|
||||
|
||||
static struct regulator_desc mpq7920_regulators_desc[MPQ7920_MAX_REGULATORS] = {
|
||||
MPQ7920BUCK("buck1", 1, mpq7920_I_limits1),
|
||||
MPQ7920BUCK("buck2", 2, mpq7920_I_limits2),
|
||||
MPQ7920BUCK("buck3", 3, mpq7920_I_limits1),
|
||||
MPQ7920BUCK("buck4", 4, mpq7920_I_limits2),
|
||||
MPQ7920LDO("ldortc", 1, &mpq7920_ldortc_ops, NULL, 0, 0, 0),
|
||||
MPQ7920LDO("ldo2", 2, &mpq7920_ldo_wo_current_ops, NULL, 0, 0, 0),
|
||||
MPQ7920LDO("ldo3", 3, &mpq7920_ldo_wo_current_ops, NULL, 0, 0, 0),
|
||||
MPQ7920LDO("ldo4", 4, &mpq7920_ldo_ops, mpq7920_I_limits3,
|
||||
ARRAY_SIZE(mpq7920_I_limits3), MPQ7920_LDO4_REG_B,
|
||||
MPQ7920_MASK_LDO_ILIM),
|
||||
MPQ7920LDO("ldo5", 5, &mpq7920_ldo_ops, mpq7920_I_limits3,
|
||||
ARRAY_SIZE(mpq7920_I_limits3), MPQ7920_LDO5_REG_B,
|
||||
MPQ7920_MASK_LDO_ILIM),
|
||||
};
|
||||
|
||||
/*
|
||||
* DVS ramp rate BUCK1 to BUCK4
|
||||
* 00-01: Reserved
|
||||
* 10: 8mV/us
|
||||
* 11: 4mV/us
|
||||
*/
|
||||
static int mpq7920_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
|
||||
{
|
||||
unsigned int ramp_val;
|
||||
|
||||
if (ramp_delay > 8000 || ramp_delay < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (ramp_delay <= 4000)
|
||||
ramp_val = 3;
|
||||
else
|
||||
ramp_val = 2;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, MPQ7920_REG_CTL0,
|
||||
MPQ7920_MASK_DVS_SLEWRATE, ramp_val << 6);
|
||||
}
|
||||
|
||||
static int mpq7920_parse_cb(struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regulator_config *config)
|
||||
{
|
||||
uint8_t val;
|
||||
int ret;
|
||||
struct mpq7920_regulator_info *info = config->driver_data;
|
||||
struct regulator_desc *rdesc = &info->rdesc[desc->id];
|
||||
|
||||
if (of_property_read_bool(np, "mps,buck-ovp-disable")) {
|
||||
regmap_update_bits(config->regmap,
|
||||
MPQ7920_BUCK1_REG_B + (rdesc->id * 4),
|
||||
MPQ7920_MASK_OVP, MPQ7920_OVP_DISABLE);
|
||||
}
|
||||
|
||||
ret = of_property_read_u8(np, "mps,buck-phase-delay", &val);
|
||||
if (!ret) {
|
||||
regmap_update_bits(config->regmap,
|
||||
MPQ7920_BUCK1_REG_C + (rdesc->id * 4),
|
||||
MPQ7920_MASK_BUCK_PHASE_DEALY,
|
||||
(val & 3) << 4);
|
||||
}
|
||||
|
||||
ret = of_property_read_u8(np, "mps,buck-softstart", &val);
|
||||
if (!ret)
|
||||
rdesc->soft_start_val_on = (val & 3) << 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mpq7920_parse_dt(struct device *dev,
|
||||
struct mpq7920_regulator_info *info)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *np = dev->of_node;
|
||||
uint8_t freq;
|
||||
|
||||
np = of_get_child_by_name(np, "regulators");
|
||||
if (!np) {
|
||||
dev_err(dev, "missing 'regulators' subnode in DT\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = of_property_read_u8(np, "mps,switch-freq", &freq);
|
||||
if (!ret) {
|
||||
regmap_update_bits(info->regmap, MPQ7920_REG_CTL0,
|
||||
MPQ7920_MASK_SWITCH_FREQ,
|
||||
(freq & 3) << 4);
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
static int mpq7920_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct mpq7920_regulator_info *info;
|
||||
struct regulator_config config = { NULL, };
|
||||
struct regulator_dev *rdev;
|
||||
struct regmap *regmap;
|
||||
int i;
|
||||
|
||||
info = devm_kzalloc(dev, sizeof(struct mpq7920_regulator_info),
|
||||
GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
info->rdesc = mpq7920_regulators_desc;
|
||||
regmap = devm_regmap_init_i2c(client, &mpq7920_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(dev, "Failed to allocate regmap!\n");
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, info);
|
||||
info->regmap = regmap;
|
||||
if (client->dev.of_node)
|
||||
mpq7920_parse_dt(&client->dev, info);
|
||||
|
||||
config.dev = dev;
|
||||
config.regmap = regmap;
|
||||
config.driver_data = info;
|
||||
|
||||
for (i = 0; i < MPQ7920_MAX_REGULATORS; i++) {
|
||||
rdev = devm_regulator_register(dev,
|
||||
&mpq7920_regulators_desc[i],
|
||||
&config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(dev, "Failed to register regulator!\n");
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mpq7920_of_match[] = {
|
||||
{ .compatible = "mps,mpq7920"},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mpq7920_of_match);
|
||||
|
||||
static const struct i2c_device_id mpq7920_id[] = {
|
||||
{ "mpq7920", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mpq7920_id);
|
||||
|
||||
static struct i2c_driver mpq7920_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "mpq7920",
|
||||
.of_match_table = of_match_ptr(mpq7920_of_match),
|
||||
},
|
||||
.probe_new = mpq7920_i2c_probe,
|
||||
.id_table = mpq7920_id,
|
||||
};
|
||||
module_i2c_driver(mpq7920_regulator_driver);
|
||||
|
||||
MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>");
|
||||
MODULE_DESCRIPTION("MPQ7920 PMIC regulator driver");
|
||||
MODULE_LICENSE("GPL");
|
69
drivers/regulator/mpq7920.h
Normal file
69
drivers/regulator/mpq7920.h
Normal file
@ -0,0 +1,69 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* mpq7920.h - Regulator definitions for mpq7920
|
||||
*
|
||||
* Copyright 2019 Monolithic Power Systems, Inc
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MPQ7920_H__
|
||||
#define __MPQ7920_H__
|
||||
|
||||
#define MPQ7920_REG_CTL0 0x00
|
||||
#define MPQ7920_REG_CTL1 0x01
|
||||
#define MPQ7920_REG_CTL2 0x02
|
||||
#define MPQ7920_BUCK1_REG_A 0x03
|
||||
#define MPQ7920_BUCK1_REG_B 0x04
|
||||
#define MPQ7920_BUCK1_REG_C 0x05
|
||||
#define MPQ7920_BUCK1_REG_D 0x06
|
||||
#define MPQ7920_BUCK2_REG_A 0x07
|
||||
#define MPQ7920_BUCK2_REG_B 0x08
|
||||
#define MPQ7920_BUCK2_REG_C 0x09
|
||||
#define MPQ7920_BUCK2_REG_D 0x0a
|
||||
#define MPQ7920_BUCK3_REG_A 0x0b
|
||||
#define MPQ7920_BUCK3_REG_B 0x0c
|
||||
#define MPQ7920_BUCK3_REG_C 0x0d
|
||||
#define MPQ7920_BUCK3_REG_D 0x0e
|
||||
#define MPQ7920_BUCK4_REG_A 0x0f
|
||||
#define MPQ7920_BUCK4_REG_B 0x10
|
||||
#define MPQ7920_BUCK4_REG_C 0x11
|
||||
#define MPQ7920_BUCK4_REG_D 0x12
|
||||
#define MPQ7920_LDO1_REG_A 0x13
|
||||
#define MPQ7920_LDO1_REG_B 0x0
|
||||
#define MPQ7920_LDO2_REG_A 0x14
|
||||
#define MPQ7920_LDO2_REG_B 0x15
|
||||
#define MPQ7920_LDO2_REG_C 0x16
|
||||
#define MPQ7920_LDO3_REG_A 0x17
|
||||
#define MPQ7920_LDO3_REG_B 0x18
|
||||
#define MPQ7920_LDO3_REG_C 0x19
|
||||
#define MPQ7920_LDO4_REG_A 0x1a
|
||||
#define MPQ7920_LDO4_REG_B 0x1b
|
||||
#define MPQ7920_LDO4_REG_C 0x1c
|
||||
#define MPQ7920_LDO5_REG_A 0x1d
|
||||
#define MPQ7920_LDO5_REG_B 0x1e
|
||||
#define MPQ7920_LDO5_REG_C 0x1f
|
||||
#define MPQ7920_REG_MODE 0x20
|
||||
#define MPQ7920_REG_REGULATOR_EN 0x22
|
||||
|
||||
#define MPQ7920_MASK_VREF 0x7f
|
||||
#define MPQ7920_MASK_BUCK_ILIM 0xc0
|
||||
#define MPQ7920_MASK_LDO_ILIM BIT(6)
|
||||
#define MPQ7920_MASK_DISCHARGE BIT(5)
|
||||
#define MPQ7920_MASK_MODE 0xc0
|
||||
#define MPQ7920_MASK_SOFTSTART 0x0c
|
||||
#define MPQ7920_MASK_SWITCH_FREQ 0x30
|
||||
#define MPQ7920_MASK_BUCK_PHASE_DEALY 0x30
|
||||
#define MPQ7920_MASK_DVS_SLEWRATE 0xc0
|
||||
#define MPQ7920_MASK_OVP 0x40
|
||||
#define MPQ7920_OVP_DISABLE ~(0x40)
|
||||
#define MPQ7920_DISCHARGE_ON BIT(5)
|
||||
|
||||
#define MPQ7920_REGULATOR_EN_OFFSET 7
|
||||
|
||||
/* values in mV */
|
||||
#define MPQ7920_BUCK_VOLT_MIN 400000
|
||||
#define MPQ7920_LDO_VOLT_MIN 650000
|
||||
#define MPQ7920_VOLT_MAX 3587500
|
||||
#define MPQ7920_VOLT_STEP 12500
|
||||
|
||||
#endif /* __MPQ7920_H__ */
|
@ -85,8 +85,7 @@ static const struct regulator_desc mt6311_regulators[] = {
|
||||
/*
|
||||
* I2C driver interface functions
|
||||
*/
|
||||
static int mt6311_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int mt6311_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
@ -154,7 +153,7 @@ static struct i2c_driver mt6311_regulator_driver = {
|
||||
.name = "mt6311",
|
||||
.of_match_table = of_match_ptr(mt6311_dt_ids),
|
||||
},
|
||||
.probe = mt6311_i2c_probe,
|
||||
.probe_new = mt6311_i2c_probe,
|
||||
.id_table = mt6311_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -279,8 +279,7 @@ error_i2c:
|
||||
/*
|
||||
* I2C driver interface functions
|
||||
*/
|
||||
static int pv88060_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int pv88060_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
|
||||
struct pv88060 *chip;
|
||||
@ -385,7 +384,7 @@ static struct i2c_driver pv88060_regulator_driver = {
|
||||
.name = "pv88060",
|
||||
.of_match_table = of_match_ptr(pv88060_dt_ids),
|
||||
},
|
||||
.probe = pv88060_i2c_probe,
|
||||
.probe_new = pv88060_i2c_probe,
|
||||
.id_table = pv88060_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -272,8 +272,7 @@ error_i2c:
|
||||
/*
|
||||
* I2C driver interface functions
|
||||
*/
|
||||
static int pv88090_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int pv88090_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
|
||||
struct pv88090 *chip;
|
||||
@ -406,7 +405,7 @@ static struct i2c_driver pv88090_regulator_driver = {
|
||||
.name = "pv88090",
|
||||
.of_match_table = of_match_ptr(pv88090_dt_ids),
|
||||
},
|
||||
.probe = pv88090_i2c_probe,
|
||||
.probe_new = pv88090_i2c_probe,
|
||||
.id_table = pv88090_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -1282,7 +1282,7 @@ static int rk808_regulator_dt_parse_pdata(struct device *dev,
|
||||
}
|
||||
|
||||
if (!pdata->dvs_gpio[i]) {
|
||||
dev_warn(dev, "there is no dvs%d gpio\n", i);
|
||||
dev_info(dev, "there is no dvs%d gpio\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -390,5 +390,5 @@ module_platform_driver(s2mpa01_pmic_driver);
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
|
||||
MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>");
|
||||
MODULE_DESCRIPTION("SAMSUNG S2MPA01 Regulator Driver");
|
||||
MODULE_DESCRIPTION("Samsung S2MPA01 Regulator Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -1265,5 +1265,5 @@ module_platform_driver(s2mps11_pmic_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
|
||||
MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver");
|
||||
MODULE_DESCRIPTION("Samsung S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -1015,5 +1015,5 @@ module_exit(s5m8767_pmic_exit);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
|
||||
MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver");
|
||||
MODULE_DESCRIPTION("Samsung S5M8767 Regulator Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -439,8 +439,7 @@ static void slg51000_clear_fault_log(struct slg51000 *chip)
|
||||
dev_dbg(chip->dev, "Fault log: FLT_POR\n");
|
||||
}
|
||||
|
||||
static int slg51000_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int slg51000_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct slg51000 *chip;
|
||||
@ -509,7 +508,7 @@ static struct i2c_driver slg51000_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "slg51000-regulator",
|
||||
},
|
||||
.probe = slg51000_i2c_probe,
|
||||
.probe_new = slg51000_i2c_probe,
|
||||
.id_table = slg51000_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -61,8 +61,7 @@ static const struct regulator_desc sy8106a_reg = {
|
||||
/*
|
||||
* I2C driver interface functions
|
||||
*/
|
||||
static int sy8106a_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int sy8106a_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct device *dev = &i2c->dev;
|
||||
struct regulator_dev *rdev;
|
||||
@ -141,7 +140,7 @@ static struct i2c_driver sy8106a_regulator_driver = {
|
||||
.name = "sy8106a",
|
||||
.of_match_table = of_match_ptr(sy8106a_i2c_of_match),
|
||||
},
|
||||
.probe = sy8106a_i2c_probe,
|
||||
.probe_new = sy8106a_i2c_probe,
|
||||
.id_table = sy8106a_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -112,8 +112,7 @@ static const struct regmap_config sy8824_regmap_config = {
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static int sy8824_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int sy8824_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
@ -222,7 +221,7 @@ static struct i2c_driver sy8824_regulator_driver = {
|
||||
.name = "sy8824-regulator",
|
||||
.of_match_table = of_match_ptr(sy8824_dt_ids),
|
||||
},
|
||||
.probe = sy8824_i2c_probe,
|
||||
.probe_new = sy8824_i2c_probe,
|
||||
.id_table = sy8824_id,
|
||||
};
|
||||
module_i2c_driver(sy8824_regulator_driver);
|
||||
|
@ -220,8 +220,7 @@ static const struct regmap_config tps65132_regmap_config = {
|
||||
.wr_table = &tps65132_no_reg_table,
|
||||
};
|
||||
|
||||
static int tps65132_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *client_id)
|
||||
static int tps65132_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct tps65132_regulator *tps;
|
||||
@ -272,7 +271,7 @@ static struct i2c_driver tps65132_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "tps65132",
|
||||
},
|
||||
.probe = tps65132_probe,
|
||||
.probe_new = tps65132_probe,
|
||||
.id_table = tps65132_id,
|
||||
};
|
||||
|
||||
|
@ -11,10 +11,13 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regulator/coupler.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
struct vctrl_voltage_range {
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
@ -79,7 +82,7 @@ static int vctrl_calc_output_voltage(struct vctrl_data *vctrl, int ctrl_uV)
|
||||
static int vctrl_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
int ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
|
||||
int ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
|
||||
|
||||
return vctrl_calc_output_voltage(vctrl, ctrl_uV);
|
||||
}
|
||||
@ -90,16 +93,16 @@ static int vctrl_set_voltage(struct regulator_dev *rdev,
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
struct regulator *ctrl_reg = vctrl->ctrl_reg;
|
||||
int orig_ctrl_uV = regulator_get_voltage(ctrl_reg);
|
||||
int orig_ctrl_uV = regulator_get_voltage_rdev(ctrl_reg->rdev);
|
||||
int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV);
|
||||
int ret;
|
||||
|
||||
if (req_min_uV >= uV || !vctrl->ovp_threshold)
|
||||
/* voltage rising or no OVP */
|
||||
return regulator_set_voltage(
|
||||
ctrl_reg,
|
||||
return regulator_set_voltage_rdev(ctrl_reg->rdev,
|
||||
vctrl_calc_ctrl_voltage(vctrl, req_min_uV),
|
||||
vctrl_calc_ctrl_voltage(vctrl, req_max_uV));
|
||||
vctrl_calc_ctrl_voltage(vctrl, req_max_uV),
|
||||
PM_SUSPEND_ON);
|
||||
|
||||
while (uV > req_min_uV) {
|
||||
int max_drop_uV = (uV * vctrl->ovp_threshold) / 100;
|
||||
@ -114,9 +117,10 @@ static int vctrl_set_voltage(struct regulator_dev *rdev,
|
||||
next_uV = max_t(int, req_min_uV, uV - max_drop_uV);
|
||||
next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV);
|
||||
|
||||
ret = regulator_set_voltage(ctrl_reg,
|
||||
ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
|
||||
next_ctrl_uV,
|
||||
next_ctrl_uV);
|
||||
next_ctrl_uV,
|
||||
PM_SUSPEND_ON);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@ -130,7 +134,8 @@ static int vctrl_set_voltage(struct regulator_dev *rdev,
|
||||
|
||||
err:
|
||||
/* Try to go back to original voltage */
|
||||
regulator_set_voltage(ctrl_reg, orig_ctrl_uV, orig_ctrl_uV);
|
||||
regulator_set_voltage_rdev(ctrl_reg->rdev, orig_ctrl_uV, orig_ctrl_uV,
|
||||
PM_SUSPEND_ON);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -155,9 +160,10 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
|
||||
|
||||
if (selector >= vctrl->sel || !vctrl->ovp_threshold) {
|
||||
/* voltage rising or no OVP */
|
||||
ret = regulator_set_voltage(ctrl_reg,
|
||||
ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
|
||||
vctrl->vtable[selector].ctrl,
|
||||
vctrl->vtable[selector].ctrl);
|
||||
vctrl->vtable[selector].ctrl,
|
||||
PM_SUSPEND_ON);
|
||||
if (!ret)
|
||||
vctrl->sel = selector;
|
||||
|
||||
@ -173,9 +179,10 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
|
||||
else
|
||||
next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel;
|
||||
|
||||
ret = regulator_set_voltage(ctrl_reg,
|
||||
ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
|
||||
vctrl->vtable[next_sel].ctrl,
|
||||
vctrl->vtable[next_sel].ctrl);
|
||||
vctrl->vtable[next_sel].ctrl,
|
||||
PM_SUSPEND_ON);
|
||||
if (ret) {
|
||||
dev_err(&rdev->dev,
|
||||
"failed to set control voltage to %duV\n",
|
||||
@ -195,9 +202,10 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
|
||||
err:
|
||||
if (vctrl->sel != orig_sel) {
|
||||
/* Try to go back to original voltage */
|
||||
if (!regulator_set_voltage(ctrl_reg,
|
||||
if (!regulator_set_voltage_rdev(ctrl_reg->rdev,
|
||||
vctrl->vtable[orig_sel].ctrl,
|
||||
vctrl->vtable[orig_sel].ctrl))
|
||||
vctrl->vtable[orig_sel].ctrl,
|
||||
PM_SUSPEND_ON))
|
||||
vctrl->sel = orig_sel;
|
||||
else
|
||||
dev_warn(&rdev->dev,
|
||||
@ -482,7 +490,7 @@ static int vctrl_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
|
||||
ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
|
||||
if (ctrl_uV < 0) {
|
||||
dev_err(&pdev->dev, "failed to get control voltage\n");
|
||||
return ctrl_uV;
|
||||
|
101
drivers/regulator/vqmmc-ipq4019-regulator.c
Normal file
101
drivers/regulator/vqmmc-ipq4019-regulator.c
Normal file
@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
//
|
||||
// Copyright (c) 2019 Mantas Pucka <mantas@8devices.com>
|
||||
// Copyright (c) 2019 Robert Marko <robert.marko@sartura.hr>
|
||||
//
|
||||
// Driver for IPQ4019 SD/MMC controller's I/O LDO voltage regulator
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
|
||||
static const unsigned int ipq4019_vmmc_voltages[] = {
|
||||
1500000, 1800000, 2500000, 3000000,
|
||||
};
|
||||
|
||||
static const struct regulator_ops ipq4019_regulator_voltage_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_desc vmmc_regulator = {
|
||||
.name = "vmmcq",
|
||||
.ops = &ipq4019_regulator_voltage_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.volt_table = ipq4019_vmmc_voltages,
|
||||
.n_voltages = ARRAY_SIZE(ipq4019_vmmc_voltages),
|
||||
.vsel_reg = 0,
|
||||
.vsel_mask = 0x3,
|
||||
};
|
||||
|
||||
static const struct regmap_config ipq4019_vmmcq_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
};
|
||||
|
||||
static int ipq4019_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct regulator_init_data *init_data;
|
||||
struct regulator_config cfg = {};
|
||||
struct regulator_dev *rdev;
|
||||
struct resource *res;
|
||||
struct regmap *rmap;
|
||||
void __iomem *base;
|
||||
|
||||
init_data = of_get_regulator_init_data(dev, dev->of_node,
|
||||
&vmmc_regulator);
|
||||
if (!init_data)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
rmap = devm_regmap_init_mmio(dev, base, &ipq4019_vmmcq_regmap_config);
|
||||
if (IS_ERR(rmap))
|
||||
return PTR_ERR(rmap);
|
||||
|
||||
cfg.dev = dev;
|
||||
cfg.init_data = init_data;
|
||||
cfg.of_node = dev->of_node;
|
||||
cfg.regmap = rmap;
|
||||
|
||||
rdev = devm_regulator_register(dev, &vmmc_regulator, &cfg);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(dev, "Failed to register regulator: %ld\n",
|
||||
PTR_ERR(rdev));
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
platform_set_drvdata(pdev, rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id regulator_ipq4019_of_match[] = {
|
||||
{ .compatible = "qcom,vqmmc-ipq4019-regulator", },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver ipq4019_regulator_driver = {
|
||||
.probe = ipq4019_regulator_probe,
|
||||
.driver = {
|
||||
.name = "vqmmc-ipq4019-regulator",
|
||||
.of_match_table = of_match_ptr(regulator_ipq4019_of_match),
|
||||
},
|
||||
};
|
||||
module_platform_driver(ipq4019_regulator_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mantas Pucka <mantas@8devices.com>");
|
||||
MODULE_DESCRIPTION("IPQ4019 VQMMC voltage regulator");
|
@ -287,6 +287,8 @@ void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
|
||||
const char *const *supply_names,
|
||||
unsigned int num_supplies);
|
||||
|
||||
bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2);
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
@ -593,6 +595,11 @@ regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool
|
||||
regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int regulator_set_voltage_triplet(struct regulator *regulator,
|
||||
|
Loading…
Reference in New Issue
Block a user