Merge branch 'regulator-5.3' into regulator-next
This commit is contained in:
commit
65244e5b1f
46 changed files with 2552 additions and 675 deletions
|
@ -5,7 +5,8 @@ of analogue I/O.
|
|||
|
||||
This document lists regulator specific bindings, see the primary binding
|
||||
document:
|
||||
../mfd/arizona.txt
|
||||
For Wolfson Microelectronic Arizona codecs: ../mfd/arizona.txt
|
||||
For Cirrus Logic Madera codecs: ../mfd/madera.txt
|
||||
|
||||
Optional properties:
|
||||
- wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
|
||||
|
|
|
@ -12,10 +12,13 @@ maintainers:
|
|||
|
||||
description:
|
||||
Any property defined as part of the core regulator binding, defined in
|
||||
regulator.txt, can also be used. However a fixed voltage regulator is
|
||||
regulator.yaml, can also be used. However a fixed voltage regulator is
|
||||
expected to have the regulator-min-microvolt and regulator-max-microvolt
|
||||
to be the same.
|
||||
|
||||
allOf:
|
||||
- $ref: "regulator.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: regulator-fixed
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
GPIO controlled regulators
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be "regulator-gpio".
|
||||
- regulator-name : Defined in regulator.txt as optional, but required
|
||||
here.
|
||||
- gpios : Array of one or more GPIO pins used to select the
|
||||
regulator voltage/current listed in "states".
|
||||
- states : Selection of available voltages/currents provided by
|
||||
this regulator and matching GPIO configurations to
|
||||
achieve them. If there are no states in the "states"
|
||||
array, use a fixed regulator instead.
|
||||
|
||||
Optional properties:
|
||||
- enable-gpios : GPIO used to enable/disable the regulator.
|
||||
Warning, the GPIO phandle flags are ignored and the
|
||||
GPIO polarity is controlled solely by the presence
|
||||
of "enable-active-high" DT property. This is due to
|
||||
compatibility with old DTs.
|
||||
- enable-active-high : Polarity of "enable-gpio" GPIO is active HIGH.
|
||||
Default is active LOW.
|
||||
- gpios-states : On operating systems, that don't support reading back
|
||||
gpio values in output mode (most notably linux), this
|
||||
array provides the state of GPIO pins set when
|
||||
requesting them from the gpio controller. Systems,
|
||||
that are capable of preserving state when requesting
|
||||
the lines, are free to ignore this property.
|
||||
0: LOW, 1: HIGH. Default is LOW if nothing else
|
||||
is specified.
|
||||
- startup-delay-us : Startup time in microseconds.
|
||||
- regulator-type : Specifies what is being regulated, must be either
|
||||
"voltage" or "current", defaults to voltage.
|
||||
|
||||
Any property defined as part of the core regulator binding defined in
|
||||
regulator.txt can also be used.
|
||||
|
||||
Example:
|
||||
|
||||
mmciv: gpio-regulator {
|
||||
compatible = "regulator-gpio";
|
||||
|
||||
regulator-name = "mmci-gpio-supply";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <2600000>;
|
||||
regulator-boot-on;
|
||||
|
||||
enable-gpios = <&gpio0 23 0x4>;
|
||||
gpios = <&gpio0 24 0x4
|
||||
&gpio0 25 0x4>;
|
||||
states = <1800000 0x3
|
||||
2200000 0x2
|
||||
2600000 0x1
|
||||
2900000 0x0>;
|
||||
|
||||
startup-delay-us = <100000>;
|
||||
enable-active-high;
|
||||
};
|
118
Documentation/devicetree/bindings/regulator/gpio-regulator.yaml
Normal file
118
Documentation/devicetree/bindings/regulator/gpio-regulator.yaml
Normal file
|
@ -0,0 +1,118 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/gpio-regulator.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: GPIO controlled regulators
|
||||
|
||||
maintainers:
|
||||
- Liam Girdwood <lgirdwood@gmail.com>
|
||||
- Mark Brown <broonie@kernel.org>
|
||||
|
||||
description:
|
||||
Any property defined as part of the core regulator binding, defined in
|
||||
regulator.txt, can also be used.
|
||||
|
||||
allOf:
|
||||
- $ref: "regulator.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: regulator-gpio
|
||||
|
||||
regulator-name: true
|
||||
|
||||
enable-gpios:
|
||||
description: GPIO to use to enable/disable the regulator.
|
||||
Warning, the GPIO phandle flags are ignored and the GPIO polarity is
|
||||
controlled solely by the presence of "enable-active-high" DT property.
|
||||
This is due to compatibility with old DTs.
|
||||
maxItems: 1
|
||||
|
||||
gpios:
|
||||
description: Array of one or more GPIO pins used to select the regulator
|
||||
voltage/current listed in "states".
|
||||
minItems: 1
|
||||
maxItems: 8 # Should be enough...
|
||||
|
||||
gpios-states:
|
||||
description: |
|
||||
On operating systems, that don't support reading back gpio values in
|
||||
output mode (most notably linux), this array provides the state of GPIO
|
||||
pins set when requesting them from the gpio controller. Systems, that are
|
||||
capable of preserving state when requesting the lines, are free to ignore
|
||||
this property.
|
||||
0: LOW
|
||||
1: HIGH
|
||||
Default is LOW if nothing else is specified.
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
- maxItems: 8
|
||||
items:
|
||||
enum: [ 0, 1 ]
|
||||
default: 0
|
||||
|
||||
states:
|
||||
description: Selection of available voltages/currents provided by this
|
||||
regulator and matching GPIO configurations to achieve them. If there are
|
||||
no states in the "states" array, use a fixed regulator instead.
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/uint32-matrix
|
||||
- maxItems: 8
|
||||
items:
|
||||
items:
|
||||
- description: Voltage in microvolts
|
||||
- description: GPIO group state value
|
||||
|
||||
startup-delay-us:
|
||||
description: startup time in microseconds
|
||||
|
||||
enable-active-high:
|
||||
description: Polarity of "enable-gpio" GPIO is active HIGH. Default is
|
||||
active LOW.
|
||||
type: boolean
|
||||
|
||||
gpio-open-drain:
|
||||
description:
|
||||
GPIO is open drain type. If this property is missing then default
|
||||
assumption is false.
|
||||
type: boolean
|
||||
|
||||
regulator-type:
|
||||
description: Specifies what is being regulated.
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/string
|
||||
- enum:
|
||||
- voltage
|
||||
- current
|
||||
default: voltage
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- regulator-name
|
||||
- gpios
|
||||
- states
|
||||
|
||||
examples:
|
||||
- |
|
||||
gpio-regulator {
|
||||
compatible = "regulator-gpio";
|
||||
|
||||
regulator-name = "mmci-gpio-supply";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <2600000>;
|
||||
regulator-boot-on;
|
||||
|
||||
enable-gpios = <&gpio0 23 0x4>;
|
||||
gpios = <&gpio0 24 0x4
|
||||
&gpio0 25 0x4>;
|
||||
states = <1800000 0x3>,
|
||||
<2200000 0x2>,
|
||||
<2600000 0x1>,
|
||||
<2900000 0x0>;
|
||||
|
||||
startup-delay-us = <100000>;
|
||||
enable-active-high;
|
||||
};
|
||||
...
|
|
@ -1,47 +0,0 @@
|
|||
Maxim MAX8660 voltage regulator
|
||||
|
||||
Required properties:
|
||||
- compatible: must be one of "maxim,max8660", "maxim,max8661"
|
||||
- reg: I2C slave address, usually 0x34
|
||||
- any required generic properties defined in regulator.txt
|
||||
|
||||
Example:
|
||||
|
||||
i2c_master {
|
||||
max8660@34 {
|
||||
compatible = "maxim,max8660";
|
||||
reg = <0x34>;
|
||||
|
||||
regulators {
|
||||
regulator@0 {
|
||||
regulator-compatible= "V3(DCDC)";
|
||||
regulator-min-microvolt = <725000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
regulator@1 {
|
||||
regulator-compatible= "V4(DCDC)";
|
||||
regulator-min-microvolt = <725000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
regulator@2 {
|
||||
regulator-compatible= "V5(LDO)";
|
||||
regulator-min-microvolt = <1700000>;
|
||||
regulator-max-microvolt = <2000000>;
|
||||
};
|
||||
|
||||
regulator@3 {
|
||||
regulator-compatible= "V6(LDO)";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
regulator@4 {
|
||||
regulator-compatible= "V7(LDO)";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
77
Documentation/devicetree/bindings/regulator/max8660.yaml
Normal file
77
Documentation/devicetree/bindings/regulator/max8660.yaml
Normal file
|
@ -0,0 +1,77 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/max8660.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Maxim MAX8660 voltage regulator
|
||||
|
||||
maintainers:
|
||||
- Daniel Mack <zonque@gmail.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "pmic@[0-9a-f]{1,2}"
|
||||
compatible:
|
||||
enum:
|
||||
- maxim,max8660
|
||||
- maxim,max8661
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
|
||||
patternProperties:
|
||||
"regulator-.+":
|
||||
$ref: "regulator.yaml#"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic@34 {
|
||||
compatible = "maxim,max8660";
|
||||
reg = <0x34>;
|
||||
|
||||
regulators {
|
||||
regulator-V3 {
|
||||
regulator-compatible= "V3(DCDC)";
|
||||
regulator-min-microvolt = <725000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
regulator-V4 {
|
||||
regulator-compatible= "V4(DCDC)";
|
||||
regulator-min-microvolt = <725000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
regulator-V5 {
|
||||
regulator-compatible= "V5(LDO)";
|
||||
regulator-min-microvolt = <1700000>;
|
||||
regulator-max-microvolt = <2000000>;
|
||||
};
|
||||
|
||||
regulator-V6 {
|
||||
regulator-compatible= "V6(LDO)";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
regulator-V7 {
|
||||
regulator-compatible= "V7(LDO)";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -4,11 +4,13 @@ Qualcomm SPMI Regulators
|
|||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: must be one of:
|
||||
"qcom,pm8005-regulators"
|
||||
"qcom,pm8841-regulators"
|
||||
"qcom,pm8916-regulators"
|
||||
"qcom,pm8941-regulators"
|
||||
"qcom,pm8994-regulators"
|
||||
"qcom,pmi8994-regulators"
|
||||
"qcom,pms405-regulators"
|
||||
|
||||
- interrupts:
|
||||
Usage: optional
|
||||
|
@ -110,6 +112,23 @@ Qualcomm SPMI Regulators
|
|||
Definition: Reference to regulator supplying the input pin, as
|
||||
described in the data sheet.
|
||||
|
||||
- vdd_l1_l2-supply:
|
||||
- vdd_l3_l8-supply:
|
||||
- vdd_l4-supply:
|
||||
- vdd_l5_l6-supply:
|
||||
- vdd_l10_l11_l12_l13-supply:
|
||||
- vdd_l7-supply:
|
||||
- vdd_l9-supply:
|
||||
- vdd_s1-supply:
|
||||
- vdd_s2-supply:
|
||||
- vdd_s3-supply:
|
||||
- vdd_s4-supply:
|
||||
- vdd_s5-supply
|
||||
Usage: optional (pms405 only)
|
||||
Value type: <phandle>
|
||||
Definition: Reference to regulator supplying the input pin, as
|
||||
described in the data sheet.
|
||||
|
||||
- qcom,saw-reg:
|
||||
Usage: optional
|
||||
Value type: <phandle>
|
||||
|
@ -120,6 +139,9 @@ The regulator node houses sub-nodes for each regulator within the device. Each
|
|||
sub-node is identified using the node's name, with valid values listed for each
|
||||
of the PMICs below.
|
||||
|
||||
pm8005:
|
||||
s1, s2, s3, s4
|
||||
|
||||
pm8841:
|
||||
s1, s2, s3, s4, s5, s6, s7, s8
|
||||
|
||||
|
|
|
@ -1,139 +1 @@
|
|||
Voltage/Current Regulators
|
||||
|
||||
Optional properties:
|
||||
- regulator-name: A string used as a descriptive name for regulator outputs
|
||||
- regulator-min-microvolt: smallest voltage consumers may set
|
||||
- regulator-max-microvolt: largest voltage consumers may set
|
||||
- regulator-microvolt-offset: Offset applied to voltages to compensate for voltage drops
|
||||
- regulator-min-microamp: smallest current consumers may set
|
||||
- regulator-max-microamp: largest current consumers may set
|
||||
- regulator-input-current-limit-microamp: maximum input current regulator allows
|
||||
- regulator-always-on: boolean, regulator should never be disabled
|
||||
- regulator-boot-on: bootloader/firmware enabled regulator
|
||||
- regulator-allow-bypass: allow the regulator to go into bypass mode
|
||||
- regulator-allow-set-load: allow the regulator performance level to be configured
|
||||
- <name>-supply: phandle to the parent supply/regulator node
|
||||
- regulator-ramp-delay: ramp delay for regulator(in uV/us)
|
||||
For hardware which supports disabling ramp rate, it should be explicitly
|
||||
initialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay.
|
||||
- regulator-enable-ramp-delay: The time taken, in microseconds, for the supply
|
||||
rail to reach the target voltage, plus/minus whatever tolerance the board
|
||||
design requires. This property describes the total system ramp time
|
||||
required due to the combination of internal ramping of the regulator itself,
|
||||
and board design issues such as trace capacitance and load on the supply.
|
||||
- regulator-settling-time-us: Settling time, in microseconds, for voltage
|
||||
change if regulator have the constant time for any level voltage change.
|
||||
This is useful when regulator have exponential voltage change.
|
||||
- regulator-settling-time-up-us: Settling time, in microseconds, for voltage
|
||||
increase if the regulator needs a constant time to settle after voltage
|
||||
increases of any level. This is useful for regulators with exponential
|
||||
voltage changes.
|
||||
- regulator-settling-time-down-us: Settling time, in microseconds, for voltage
|
||||
decrease if the regulator needs a constant time to settle after voltage
|
||||
decreases of any level. This is useful for regulators with exponential
|
||||
voltage changes.
|
||||
- regulator-soft-start: Enable soft start so that voltage ramps slowly
|
||||
- regulator-state-standby sub-root node for Standby mode
|
||||
: equivalent with standby Linux sleep state, which provides energy savings
|
||||
with a relatively quick transition back time.
|
||||
- regulator-state-mem sub-root node for Suspend-to-RAM mode
|
||||
: suspend to memory, the device goes to sleep, but all data stored in memory,
|
||||
only some external interrupt can wake the device.
|
||||
- regulator-state-disk sub-root node for Suspend-to-DISK mode
|
||||
: suspend to disk, this state operates similarly to Suspend-to-RAM,
|
||||
but includes a final step of writing memory contents to disk.
|
||||
- regulator-state-[mem/disk/standby] node has following common properties:
|
||||
- regulator-on-in-suspend: regulator should be on in suspend state.
|
||||
- regulator-off-in-suspend: regulator should be off in suspend state.
|
||||
- regulator-suspend-min-microvolt: minimum voltage may be set in
|
||||
suspend state.
|
||||
- regulator-suspend-max-microvolt: maximum voltage may be set in
|
||||
suspend state.
|
||||
- regulator-suspend-microvolt: the default voltage which regulator
|
||||
would be set in suspend. This property is now deprecated, instead
|
||||
setting voltage for suspend mode via the API which regulator
|
||||
driver provides is recommended.
|
||||
- regulator-changeable-in-suspend: whether the default voltage and
|
||||
the regulator on/off in suspend can be changed in runtime.
|
||||
- regulator-mode: operating mode in the given suspend state.
|
||||
The set of possible operating modes depends on the capabilities of
|
||||
every hardware so the valid modes are documented on each regulator
|
||||
device tree binding document.
|
||||
- regulator-initial-mode: initial operating mode. The set of possible operating
|
||||
modes depends on the capabilities of every hardware so each device binding
|
||||
documentation explains which values the regulator supports.
|
||||
- regulator-allowed-modes: list of operating modes that software is allowed to
|
||||
configure for the regulator at run-time. Elements may be specified in any
|
||||
order. The set of possible operating modes depends on the capabilities of
|
||||
every hardware so each device binding document explains which values the
|
||||
regulator supports.
|
||||
- regulator-system-load: Load in uA present on regulator that is not captured by
|
||||
any consumer request.
|
||||
- regulator-pull-down: Enable pull down resistor when the regulator is disabled.
|
||||
- regulator-over-current-protection: Enable over current protection.
|
||||
- regulator-active-discharge: tristate, enable/disable active discharge of
|
||||
regulators. The values are:
|
||||
0: Disable active discharge.
|
||||
1: Enable active discharge.
|
||||
Absence of this property will leave configuration to default.
|
||||
- regulator-coupled-with: Regulators with which the regulator
|
||||
is coupled. The linkage is 2-way - all coupled regulators should be linked
|
||||
with each other. A regulator should not be coupled with its supplier.
|
||||
- regulator-coupled-max-spread: Array of maximum spread between voltages of
|
||||
coupled regulators in microvolts, each value in the array relates to the
|
||||
corresponding couple specified by the regulator-coupled-with property.
|
||||
- regulator-max-step-microvolt: Maximum difference between current and target
|
||||
voltages that can be changed safely in a single step.
|
||||
|
||||
Deprecated properties:
|
||||
- regulator-compatible: If a regulator chip contains multiple
|
||||
regulators, and if the chip's binding contains a child node that
|
||||
describes each regulator, then this property indicates which regulator
|
||||
this child node is intended to configure. If this property is missing,
|
||||
the node's name will be used instead.
|
||||
|
||||
Example:
|
||||
|
||||
xyzreg: regulator@0 {
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <2500000>;
|
||||
regulator-always-on;
|
||||
vin-supply = <&vin>;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
Regulator Consumers:
|
||||
Consumer nodes can reference one or more of its supplies/
|
||||
regulators using the below bindings.
|
||||
|
||||
- <name>-supply: phandle to the regulator node
|
||||
|
||||
These are the same bindings that a regulator in the above
|
||||
example used to reference its own supply, in which case
|
||||
its just seen as a special case of a regulator being a
|
||||
consumer itself.
|
||||
|
||||
Example of a consumer device node (mmc) referencing two
|
||||
regulators (twl_reg1 and twl_reg2),
|
||||
|
||||
twl_reg1: regulator@0 {
|
||||
...
|
||||
...
|
||||
...
|
||||
};
|
||||
|
||||
twl_reg2: regulator@1 {
|
||||
...
|
||||
...
|
||||
...
|
||||
};
|
||||
|
||||
mmc: mmc@0 {
|
||||
...
|
||||
...
|
||||
vmmc-supply = <&twl_reg1>;
|
||||
vmmcaux-supply = <&twl_reg2>;
|
||||
};
|
||||
This file has moved to regulator.yaml.
|
||||
|
|
200
Documentation/devicetree/bindings/regulator/regulator.yaml
Normal file
200
Documentation/devicetree/bindings/regulator/regulator.yaml
Normal file
|
@ -0,0 +1,200 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/regulator.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Voltage/Current Regulators
|
||||
|
||||
maintainers:
|
||||
- Liam Girdwood <lgirdwood@gmail.com>
|
||||
- Mark Brown <broonie@kernel.org>
|
||||
|
||||
properties:
|
||||
regulator-name:
|
||||
description: A string used as a descriptive name for regulator outputs
|
||||
$ref: "/schemas/types.yaml#/definitions/string"
|
||||
|
||||
regulator-min-microvolt:
|
||||
description: smallest voltage consumers may set
|
||||
|
||||
regulator-max-microvolt:
|
||||
description: largest voltage consumers may set
|
||||
|
||||
regulator-microvolt-offset:
|
||||
description: Offset applied to voltages to compensate for voltage drops
|
||||
|
||||
regulator-min-microamp:
|
||||
description: smallest current consumers may set
|
||||
|
||||
regulator-max-microamp:
|
||||
description: largest current consumers may set
|
||||
|
||||
regulator-input-current-limit-microamp:
|
||||
description: maximum input current regulator allows
|
||||
|
||||
regulator-always-on:
|
||||
description: boolean, regulator should never be disabled
|
||||
type: boolean
|
||||
|
||||
regulator-boot-on:
|
||||
description: bootloader/firmware enabled regulator
|
||||
type: boolean
|
||||
|
||||
regulator-allow-bypass:
|
||||
description: allow the regulator to go into bypass mode
|
||||
type: boolean
|
||||
|
||||
regulator-allow-set-load:
|
||||
description: allow the regulator performance level to be configured
|
||||
type: boolean
|
||||
|
||||
regulator-ramp-delay:
|
||||
description: ramp delay for regulator(in uV/us) For hardware which supports
|
||||
disabling ramp rate, it should be explicitly initialised to zero (regulator-ramp-delay
|
||||
= <0>) for disabling ramp delay.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
|
||||
regulator-enable-ramp-delay:
|
||||
description: The time taken, in microseconds, for the supply rail to
|
||||
reach the target voltage, plus/minus whatever tolerance the board
|
||||
design requires. This property describes the total system ramp time
|
||||
required due to the combination of internal ramping of the regulator
|
||||
itself, and board design issues such as trace capacitance and load
|
||||
on the supply.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
|
||||
regulator-settling-time-us:
|
||||
description: Settling time, in microseconds, for voltage change if regulator
|
||||
have the constant time for any level voltage change. This is useful
|
||||
when regulator have exponential voltage change.
|
||||
|
||||
regulator-settling-time-up-us:
|
||||
description: Settling time, in microseconds, for voltage increase if
|
||||
the regulator needs a constant time to settle after voltage increases
|
||||
of any level. This is useful for regulators with exponential voltage
|
||||
changes.
|
||||
|
||||
regulator-settling-time-down-us:
|
||||
description: Settling time, in microseconds, for voltage decrease if
|
||||
the regulator needs a constant time to settle after voltage decreases
|
||||
of any level. This is useful for regulators with exponential voltage
|
||||
changes.
|
||||
|
||||
regulator-soft-start:
|
||||
description: Enable soft start so that voltage ramps slowly
|
||||
type: boolean
|
||||
|
||||
regulator-initial-mode:
|
||||
description: initial operating mode. The set of possible operating modes
|
||||
depends on the capabilities of every hardware so each device binding
|
||||
documentation explains which values the regulator supports.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
|
||||
regulator-allowed-modes:
|
||||
description: list of operating modes that software is allowed to configure
|
||||
for the regulator at run-time. Elements may be specified in any order.
|
||||
The set of possible operating modes depends on the capabilities of
|
||||
every hardware so each device binding document explains which values
|
||||
the regulator supports.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32-array"
|
||||
|
||||
regulator-system-load:
|
||||
description: Load in uA present on regulator that is not captured by
|
||||
any consumer request.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
|
||||
regulator-pull-down:
|
||||
description: Enable pull down resistor when the regulator is disabled.
|
||||
type: boolean
|
||||
|
||||
regulator-over-current-protection:
|
||||
description: Enable over current protection.
|
||||
type: boolean
|
||||
|
||||
regulator-active-discharge:
|
||||
description: |
|
||||
tristate, enable/disable active discharge of regulators. The values are:
|
||||
0: Disable active discharge.
|
||||
1: Enable active discharge.
|
||||
Absence of this property will leave configuration to default.
|
||||
allOf:
|
||||
- $ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
- enum: [ 0, 1 ]
|
||||
|
||||
regulator-coupled-with:
|
||||
description: Regulators with which the regulator is coupled. The linkage
|
||||
is 2-way - all coupled regulators should be linked with each other.
|
||||
A regulator should not be coupled with its supplier.
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle-array"
|
||||
|
||||
regulator-coupled-max-spread:
|
||||
description: Array of maximum spread between voltages of coupled regulators
|
||||
in microvolts, each value in the array relates to the corresponding
|
||||
couple specified by the regulator-coupled-with property.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
|
||||
regulator-max-step-microvolt:
|
||||
description: Maximum difference between current and target voltages
|
||||
that can be changed safely in a single step.
|
||||
|
||||
patternProperties:
|
||||
".*-supply$":
|
||||
description: Input supply phandle(s) for this node
|
||||
|
||||
regulator-state-(standby|mem|disk):
|
||||
type: object
|
||||
description:
|
||||
sub-nodes for regulator state in Standby, Suspend-to-RAM, and
|
||||
Suspend-to-DISK modes. Equivalent with standby, mem, and disk Linux
|
||||
sleep states.
|
||||
|
||||
properties:
|
||||
regulator-on-in-suspend:
|
||||
description: regulator should be on in suspend state.
|
||||
type: boolean
|
||||
|
||||
regulator-off-in-suspend:
|
||||
description: regulator should be off in suspend state.
|
||||
type: boolean
|
||||
|
||||
regulator-suspend-min-microvolt:
|
||||
description: minimum voltage may be set in suspend state.
|
||||
|
||||
regulator-suspend-max-microvolt:
|
||||
description: maximum voltage may be set in suspend state.
|
||||
|
||||
regulator-suspend-microvolt:
|
||||
description: the default voltage which regulator would be set in
|
||||
suspend. This property is now deprecated, instead setting voltage
|
||||
for suspend mode via the API which regulator driver provides is
|
||||
recommended.
|
||||
|
||||
regulator-changeable-in-suspend:
|
||||
description: whether the default voltage and the regulator on/off
|
||||
in suspend can be changed in runtime.
|
||||
type: boolean
|
||||
|
||||
regulator-mode:
|
||||
description: operating mode in the given suspend state. The set
|
||||
of possible operating modes depends on the capabilities of every
|
||||
hardware so the valid modes are documented on each regulator device
|
||||
tree binding document.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
xyzreg: regulator@0 {
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <2500000>;
|
||||
regulator-always-on;
|
||||
vin-supply = <&vin>;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
88
Documentation/devicetree/bindings/regulator/slg51000.txt
Normal file
88
Documentation/devicetree/bindings/regulator/slg51000.txt
Normal file
|
@ -0,0 +1,88 @@
|
|||
* Dialog Semiconductor SLG51000 Voltage Regulator
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "dlg,slg51000" for SLG51000
|
||||
- reg : Specifies the I2C slave address.
|
||||
- xxx-supply: Input voltage supply regulator for ldo3 to ldo7.
|
||||
These entries are required if regulators are enabled for a device.
|
||||
An absence of these properties can cause the regulator registration to fail.
|
||||
If some of input supply is powered through battery or always-on supply then
|
||||
also it is required to have these parameters with proper node handle of always
|
||||
on power supply.
|
||||
vin3-supply: Input supply for ldo3
|
||||
vin4-supply: Input supply for ldo4
|
||||
vin5-supply: Input supply for ldo5
|
||||
vin6-supply: Input supply for ldo6
|
||||
vin7-supply: Input supply for ldo7
|
||||
|
||||
Optional properties:
|
||||
- interrupt-parent : Specifies the reference to the interrupt controller.
|
||||
- interrupts : IRQ line information.
|
||||
- dlg,cs-gpios : Specify a valid GPIO for chip select
|
||||
|
||||
Sub-nodes:
|
||||
- regulators : This node defines the settings for the regulators.
|
||||
The content of the sub-node is defined by the standard binding
|
||||
for regulators; see regulator.txt.
|
||||
|
||||
The SLG51000 regulators are bound using their names listed below:
|
||||
ldo1
|
||||
ldo2
|
||||
ldo3
|
||||
ldo4
|
||||
ldo5
|
||||
ldo6
|
||||
ldo7
|
||||
|
||||
Optional properties for regulators:
|
||||
- enable-gpios : Specify a valid GPIO for platform control of the regulator.
|
||||
|
||||
Example:
|
||||
pmic: slg51000@75 {
|
||||
compatible = "dlg,slg51000";
|
||||
reg = <0x75>;
|
||||
|
||||
regulators {
|
||||
ldo1 {
|
||||
regulator-name = "ldo1";
|
||||
regulator-min-microvolt = <2400000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
ldo2 {
|
||||
regulator-name = "ldo2";
|
||||
regulator-min-microvolt = <2400000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
ldo3 {
|
||||
regulator-name = "ldo3";
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <3750000>;
|
||||
};
|
||||
|
||||
ldo4 {
|
||||
regulator-name = "ldo4";
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <3750000>;
|
||||
};
|
||||
|
||||
ldo5 {
|
||||
regulator-name = "ldo5";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
};
|
||||
|
||||
ldo6 {
|
||||
regulator-name = "ldo6";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
};
|
||||
|
||||
ldo7 {
|
||||
regulator-name = "ldo7";
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <3750000>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
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>;
|
||||
};
|
|
@ -4707,6 +4707,7 @@ F: Documentation/devicetree/bindings/mfd/da90*.txt
|
|||
F: Documentation/devicetree/bindings/input/da90??-onkey.txt
|
||||
F: Documentation/devicetree/bindings/thermal/da90??-thermal.txt
|
||||
F: Documentation/devicetree/bindings/regulator/da92*.txt
|
||||
F: Documentation/devicetree/bindings/regulator/slg51000.txt
|
||||
F: Documentation/devicetree/bindings/watchdog/da90??-wdt.txt
|
||||
F: Documentation/devicetree/bindings/sound/da[79]*.txt
|
||||
F: drivers/gpio/gpio-da90??.c
|
||||
|
@ -4722,6 +4723,7 @@ F: drivers/power/supply/da9052-battery.c
|
|||
F: drivers/power/supply/da91??-*.c
|
||||
F: drivers/regulator/da903x.c
|
||||
F: drivers/regulator/da9???-regulator.[ch]
|
||||
F: drivers/regulator/slg51000-regulator.[ch]
|
||||
F: drivers/thermal/da90??-thermal.c
|
||||
F: drivers/rtc/rtc-da90??.c
|
||||
F: drivers/video/backlight/da90??_bl.c
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mmc/host.h>
|
||||
|
@ -398,7 +399,6 @@ static struct pca953x_platform_data crag6410_pca_data = {
|
|||
/* VDDARM is controlled by DVS1 connected to GPK(0) */
|
||||
static struct wm831x_buckv_pdata vddarm_pdata = {
|
||||
.dvs_control_src = 1,
|
||||
.dvs_gpio = S3C64XX_GPK(0),
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply vddarm_consumers[] = {
|
||||
|
@ -596,6 +596,24 @@ static struct wm831x_pdata crag_pmic_pdata = {
|
|||
.touch = &touch_pdata,
|
||||
};
|
||||
|
||||
/*
|
||||
* VDDARM is eventually ending up as a regulator hanging on the MFD cell device
|
||||
* "wm831x-buckv.1" spawn from drivers/mfd/wm831x-core.c.
|
||||
*
|
||||
* From the note on the platform data we can see that this is clearly DVS1
|
||||
* and assigned as dcdc1 resource to the MFD core which sets .id of the cell
|
||||
* spawning the DVS1 platform device to 1, then the cell platform device
|
||||
* name is calculated from 10*instance + id resulting in the device name
|
||||
* "wm831x-buckv.11"
|
||||
*/
|
||||
static struct gpiod_lookup_table crag_pmic_gpiod_table = {
|
||||
.dev_id = "wm831x-buckv.11",
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPIOK", 0, "dvs", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct i2c_board_info i2c_devs0[] = {
|
||||
{ I2C_BOARD_INFO("24c08", 0x50), },
|
||||
{ I2C_BOARD_INFO("tca6408", 0x20),
|
||||
|
@ -836,6 +854,7 @@ static void __init crag6410_machine_init(void)
|
|||
s3c_fb_set_platdata(&crag6410_lcd_pdata);
|
||||
dwc2_hsotg_set_platdata(&crag6410_hsotg_pdata);
|
||||
|
||||
gpiod_add_lookup_table(&crag_pmic_gpiod_table);
|
||||
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
|
||||
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
|
||||
|
||||
|
|
|
@ -27,6 +27,23 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pm8005_lsid1 {
|
||||
pm8005-regulators {
|
||||
compatible = "qcom,pm8005-regulators";
|
||||
|
||||
vdd_s1-supply = <&vph_pwr>;
|
||||
|
||||
pm8005_s1: s1 { /* VDD_GFX supply */
|
||||
regulator-min-microvolt = <524000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
|
||||
/* hack until we rig up the gpu consumer */
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&qusb2phy {
|
||||
status = "okay";
|
||||
|
||||
|
|
|
@ -4244,8 +4244,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_index);
|
|||
*
|
||||
* Returns:
|
||||
* On successful request the GPIO pin is configured in accordance with
|
||||
* provided @dflags. If the node does not have the requested GPIO
|
||||
* property, NULL is returned.
|
||||
* provided @dflags.
|
||||
*
|
||||
* In case of error an ERR_PTR() is returned.
|
||||
*/
|
||||
|
@ -4267,9 +4266,6 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
|
|||
index, &flags);
|
||||
|
||||
if (!desc || IS_ERR(desc)) {
|
||||
/* If it is not there, just return NULL */
|
||||
if (PTR_ERR(desc) == -ENOENT)
|
||||
return NULL;
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
|
@ -136,19 +136,20 @@ config REGULATOR_AB8500
|
|||
signal AB8500 PMIC
|
||||
|
||||
config REGULATOR_ARIZONA_LDO1
|
||||
tristate "Wolfson Arizona class devices LDO1"
|
||||
depends on MFD_ARIZONA
|
||||
tristate "Cirrus Madera and Wolfson Arizona class devices LDO1"
|
||||
depends on MFD_ARIZONA || MFD_MADERA
|
||||
depends on SND_SOC
|
||||
help
|
||||
Support for the LDO1 regulators found on Wolfson Arizona class
|
||||
devices.
|
||||
Support for the LDO1 regulators found on Cirrus Logic Madera codecs
|
||||
and Wolfson Microelectronic Arizona codecs.
|
||||
|
||||
config REGULATOR_ARIZONA_MICSUPP
|
||||
tristate "Wolfson Arizona class devices MICSUPP"
|
||||
depends on MFD_ARIZONA
|
||||
tristate "Cirrus Madera and Wolfson Arizona class devices MICSUPP"
|
||||
depends on MFD_ARIZONA || MFD_MADERA
|
||||
depends on SND_SOC
|
||||
help
|
||||
Support for the MICSUPP regulators found on Wolfson Arizona class
|
||||
Support for the MICSUPP regulators found on Cirrus Logic Madera codecs
|
||||
and Wolfson Microelectronic Arizona codecs
|
||||
devices.
|
||||
|
||||
config REGULATOR_AS3711
|
||||
|
@ -258,7 +259,7 @@ config REGULATOR_DA9062
|
|||
|
||||
config REGULATOR_DA9063
|
||||
tristate "Dialog Semiconductor DA9063 regulators"
|
||||
depends on MFD_DA9063
|
||||
depends on MFD_DA9063 && OF
|
||||
help
|
||||
Say y here to support the BUCKs and LDOs regulators found on
|
||||
DA9063 PMICs.
|
||||
|
@ -829,6 +830,26 @@ config REGULATOR_SKY81452
|
|||
This driver can also be built as a module. If so, the module
|
||||
will be called sky81452-regulator.
|
||||
|
||||
config REGULATOR_SLG51000
|
||||
tristate "Dialog Semiconductor SLG51000 regulators"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say y here to support for the Dialog Semiconductor SLG51000.
|
||||
The SLG51000 is seven compact and customizable low dropout
|
||||
regulators.
|
||||
|
||||
config REGULATOR_STM32_BOOSTER
|
||||
tristate "STMicroelectronics STM32 BOOSTER"
|
||||
depends on ARCH_STM32 || COMPILE_TEST
|
||||
help
|
||||
This driver supports internal booster (3V3) embedded in some
|
||||
STMicroelectronics STM32 chips. It can be used to supply ADC analog
|
||||
input switches when vdda supply is below 2.7V.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called stm32-booster.
|
||||
|
||||
config REGULATOR_STM32_VREFBUF
|
||||
tristate "STMicroelectronics STM32 VREFBUF"
|
||||
depends on ARCH_STM32 || COMPILE_TEST
|
||||
|
|
|
@ -11,7 +11,7 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
|
|||
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
|
||||
|
||||
obj-$(CONFIG_REGULATOR_88PG86X) += 88pg86x.o
|
||||
obj-$(CONFIG_REGULATOR_88PM800) += 88pm800.o
|
||||
obj-$(CONFIG_REGULATOR_88PM800) += 88pm800-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
|
||||
obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
|
||||
|
@ -104,6 +104,8 @@ obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
|
|||
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
|
||||
obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o
|
||||
obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
|
||||
obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
|
||||
obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
#include <linux/mfd/arizona/pdata.h>
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
|
||||
#include <linux/mfd/madera/core.h>
|
||||
#include <linux/mfd/madera/pdata.h>
|
||||
#include <linux/mfd/madera/registers.h>
|
||||
|
||||
struct arizona_ldo1 {
|
||||
struct regulator_dev *regulator;
|
||||
struct regmap *regmap;
|
||||
|
@ -158,6 +162,31 @@ static const struct regulator_init_data arizona_ldo1_wm5110 = {
|
|||
.num_consumer_supplies = 1,
|
||||
};
|
||||
|
||||
static const struct regulator_desc madera_ldo1 = {
|
||||
.name = "LDO1",
|
||||
.supply_name = "LDOVDD",
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.ops = &arizona_ldo1_ops,
|
||||
|
||||
.vsel_reg = MADERA_LDO1_CONTROL_1,
|
||||
.vsel_mask = MADERA_LDO1_VSEL_MASK,
|
||||
.min_uV = 900000,
|
||||
.uV_step = 25000,
|
||||
.n_voltages = 13,
|
||||
.enable_time = 3000,
|
||||
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct regulator_init_data madera_ldo1_default = {
|
||||
.constraints = {
|
||||
.min_uV = 1200000,
|
||||
.max_uV = 1200000,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
};
|
||||
|
||||
static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata,
|
||||
struct regulator_config *config,
|
||||
const struct regulator_desc *desc,
|
||||
|
@ -320,6 +349,32 @@ static int arizona_ldo1_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int madera_ldo1_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct madera *madera = dev_get_drvdata(pdev->dev.parent);
|
||||
struct arizona_ldo1 *ldo1;
|
||||
bool external_dcvdd;
|
||||
int ret;
|
||||
|
||||
ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL);
|
||||
if (!ldo1)
|
||||
return -ENOMEM;
|
||||
|
||||
ldo1->regmap = madera->regmap;
|
||||
|
||||
ldo1->init_data = madera_ldo1_default;
|
||||
|
||||
ret = arizona_ldo1_common_init(pdev, ldo1, &madera_ldo1,
|
||||
&madera->pdata.ldo1,
|
||||
&external_dcvdd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
madera->internal_dcvdd = !external_dcvdd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver arizona_ldo1_driver = {
|
||||
.probe = arizona_ldo1_probe,
|
||||
.remove = arizona_ldo1_remove,
|
||||
|
@ -328,10 +383,36 @@ static struct platform_driver arizona_ldo1_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
module_platform_driver(arizona_ldo1_driver);
|
||||
static struct platform_driver madera_ldo1_driver = {
|
||||
.probe = madera_ldo1_probe,
|
||||
.remove = arizona_ldo1_remove,
|
||||
.driver = {
|
||||
.name = "madera-ldo1",
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver * const madera_ldo1_drivers[] = {
|
||||
&arizona_ldo1_driver,
|
||||
&madera_ldo1_driver,
|
||||
};
|
||||
|
||||
static int __init arizona_ldo1_init(void)
|
||||
{
|
||||
return platform_register_drivers(madera_ldo1_drivers,
|
||||
ARRAY_SIZE(madera_ldo1_drivers));
|
||||
}
|
||||
module_init(arizona_ldo1_init);
|
||||
|
||||
static void __exit madera_ldo1_exit(void)
|
||||
{
|
||||
platform_unregister_drivers(madera_ldo1_drivers,
|
||||
ARRAY_SIZE(madera_ldo1_drivers));
|
||||
}
|
||||
module_exit(madera_ldo1_exit);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_DESCRIPTION("Arizona LDO1 driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:arizona-ldo1");
|
||||
MODULE_ALIAS("platform:madera-ldo1");
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <sound/soc.h>
|
||||
|
@ -25,6 +24,10 @@
|
|||
#include <linux/mfd/arizona/pdata.h>
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
|
||||
#include <linux/mfd/madera/core.h>
|
||||
#include <linux/mfd/madera/pdata.h>
|
||||
#include <linux/mfd/madera/registers.h>
|
||||
|
||||
#include <linux/regulator/arizona-micsupp.h>
|
||||
|
||||
struct arizona_micsupp {
|
||||
|
@ -200,6 +203,28 @@ static const struct regulator_init_data arizona_micsupp_ext_default = {
|
|||
.num_consumer_supplies = 1,
|
||||
};
|
||||
|
||||
static const struct regulator_desc madera_micsupp = {
|
||||
.name = "MICVDD",
|
||||
.supply_name = "CPVDD1",
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 40,
|
||||
.ops = &arizona_micsupp_ops,
|
||||
|
||||
.vsel_reg = MADERA_LDO2_CONTROL_1,
|
||||
.vsel_mask = MADERA_LDO2_VSEL_MASK,
|
||||
.enable_reg = MADERA_MIC_CHARGE_PUMP_1,
|
||||
.enable_mask = MADERA_CPMIC_ENA,
|
||||
.bypass_reg = MADERA_MIC_CHARGE_PUMP_1,
|
||||
.bypass_mask = MADERA_CPMIC_BYPASS,
|
||||
|
||||
.linear_ranges = arizona_micsupp_ext_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ext_ranges),
|
||||
|
||||
.enable_time = 3000,
|
||||
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int arizona_micsupp_of_get_pdata(struct arizona_micsupp_pdata *pdata,
|
||||
struct regulator_config *config,
|
||||
const struct regulator_desc *desc)
|
||||
|
@ -316,6 +341,24 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
|
|||
&arizona->pdata.micvdd);
|
||||
}
|
||||
|
||||
static int madera_micsupp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct madera *madera = dev_get_drvdata(pdev->dev.parent);
|
||||
struct arizona_micsupp *micsupp;
|
||||
|
||||
micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL);
|
||||
if (!micsupp)
|
||||
return -ENOMEM;
|
||||
|
||||
micsupp->regmap = madera->regmap;
|
||||
micsupp->dapm = &madera->dapm;
|
||||
micsupp->dev = madera->dev;
|
||||
micsupp->init_data = arizona_micsupp_ext_default;
|
||||
|
||||
return arizona_micsupp_common_init(pdev, micsupp, &madera_micsupp,
|
||||
&madera->pdata.micvdd);
|
||||
}
|
||||
|
||||
static struct platform_driver arizona_micsupp_driver = {
|
||||
.probe = arizona_micsupp_probe,
|
||||
.driver = {
|
||||
|
@ -323,10 +366,35 @@ static struct platform_driver arizona_micsupp_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
module_platform_driver(arizona_micsupp_driver);
|
||||
static struct platform_driver madera_micsupp_driver = {
|
||||
.probe = madera_micsupp_probe,
|
||||
.driver = {
|
||||
.name = "madera-micsupp",
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver * const arizona_micsupp_drivers[] = {
|
||||
&arizona_micsupp_driver,
|
||||
&madera_micsupp_driver,
|
||||
};
|
||||
|
||||
static int __init arizona_micsupp_init(void)
|
||||
{
|
||||
return platform_register_drivers(arizona_micsupp_drivers,
|
||||
ARRAY_SIZE(arizona_micsupp_drivers));
|
||||
}
|
||||
module_init(arizona_micsupp_init);
|
||||
|
||||
static void __exit arizona_micsupp_exit(void)
|
||||
{
|
||||
platform_unregister_drivers(arizona_micsupp_drivers,
|
||||
ARRAY_SIZE(arizona_micsupp_drivers));
|
||||
}
|
||||
module_exit(arizona_micsupp_exit);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_DESCRIPTION("Arizona microphone supply driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:arizona-micsupp");
|
||||
MODULE_ALIAS("platform:madera-micsupp");
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/rohm-bd70528.h>
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/rohm-bd718x7.h>
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* core.c -- Voltage/Current Regulator framework.
|
||||
*
|
||||
* Copyright 2007, 2008 Wolfson Microelectronics PLC.
|
||||
* Copyright 2008 SlimLogic Ltd.
|
||||
*
|
||||
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
|
||||
*/
|
||||
//
|
||||
// core.c -- Voltage/Current Regulator framework.
|
||||
//
|
||||
// Copyright 2007, 2008 Wolfson Microelectronics PLC.
|
||||
// Copyright 2008 SlimLogic Ltd.
|
||||
//
|
||||
// Author: Liam Girdwood <lrg@slimlogic.co.uk>
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -1645,9 +1644,9 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev)
|
|||
{
|
||||
if (rdev->constraints && rdev->constraints->enable_time)
|
||||
return rdev->constraints->enable_time;
|
||||
if (!rdev->desc->ops->enable_time)
|
||||
return rdev->desc->enable_time;
|
||||
return rdev->desc->ops->enable_time(rdev);
|
||||
if (rdev->desc->ops->enable_time)
|
||||
return rdev->desc->ops->enable_time(rdev);
|
||||
return rdev->desc->enable_time;
|
||||
}
|
||||
|
||||
static struct regulator_supply_alias *regulator_find_supply_alias(
|
||||
|
@ -3107,6 +3106,66 @@ static int _regulator_call_set_voltage_sel(struct regulator_dev *rdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int _regulator_set_voltage_sel_step(struct regulator_dev *rdev,
|
||||
int uV, int new_selector)
|
||||
{
|
||||
const struct regulator_ops *ops = rdev->desc->ops;
|
||||
int diff, old_sel, curr_sel, ret;
|
||||
|
||||
/* Stepping is only needed if the regulator is enabled. */
|
||||
if (!_regulator_is_enabled(rdev))
|
||||
goto final_set;
|
||||
|
||||
if (!ops->get_voltage_sel)
|
||||
return -EINVAL;
|
||||
|
||||
old_sel = ops->get_voltage_sel(rdev);
|
||||
if (old_sel < 0)
|
||||
return old_sel;
|
||||
|
||||
diff = new_selector - old_sel;
|
||||
if (diff == 0)
|
||||
return 0; /* No change needed. */
|
||||
|
||||
if (diff > 0) {
|
||||
/* Stepping up. */
|
||||
for (curr_sel = old_sel + rdev->desc->vsel_step;
|
||||
curr_sel < new_selector;
|
||||
curr_sel += rdev->desc->vsel_step) {
|
||||
/*
|
||||
* Call the callback directly instead of using
|
||||
* _regulator_call_set_voltage_sel() as we don't
|
||||
* want to notify anyone yet. Same in the branch
|
||||
* below.
|
||||
*/
|
||||
ret = ops->set_voltage_sel(rdev, curr_sel);
|
||||
if (ret)
|
||||
goto try_revert;
|
||||
}
|
||||
} else {
|
||||
/* Stepping down. */
|
||||
for (curr_sel = old_sel - rdev->desc->vsel_step;
|
||||
curr_sel > new_selector;
|
||||
curr_sel -= rdev->desc->vsel_step) {
|
||||
ret = ops->set_voltage_sel(rdev, curr_sel);
|
||||
if (ret)
|
||||
goto try_revert;
|
||||
}
|
||||
}
|
||||
|
||||
final_set:
|
||||
/* The final selector will trigger the notifiers. */
|
||||
return _regulator_call_set_voltage_sel(rdev, uV, new_selector);
|
||||
|
||||
try_revert:
|
||||
/*
|
||||
* At least try to return to the previous voltage if setting a new
|
||||
* one failed.
|
||||
*/
|
||||
(void)ops->set_voltage_sel(rdev, old_sel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _regulator_set_voltage_time(struct regulator_dev *rdev,
|
||||
int old_uV, int new_uV)
|
||||
{
|
||||
|
@ -3180,6 +3239,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
|
|||
selector = ret;
|
||||
if (old_selector == selector)
|
||||
ret = 0;
|
||||
else if (rdev->desc->vsel_step)
|
||||
ret = _regulator_set_voltage_sel_step(
|
||||
rdev, best_val, selector);
|
||||
else
|
||||
ret = _regulator_call_set_voltage_sel(
|
||||
rdev, best_val, selector);
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
#define CPCAP_REG_OFF_MODE_SEC BIT(15)
|
||||
|
||||
/**
|
||||
* SoC specific configuraion for CPCAP regulator. There are at least three
|
||||
* SoC specific configuration for CPCAP regulator. There are at least three
|
||||
* different SoCs each with their own parameters: omap3, omap4 and tegra2.
|
||||
*
|
||||
* The assign_reg and assign_mask seem to allow toggling between primary
|
||||
|
|
|
@ -493,12 +493,13 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
|
|||
.desc.ops = &da9062_ldo_ops,
|
||||
.desc.min_uV = (900) * 1000,
|
||||
.desc.uV_step = (50) * 1000,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1
|
||||
+ DA9062AA_VLDO_A_MIN_SEL,
|
||||
.desc.enable_reg = DA9062AA_LDO1_CONT,
|
||||
.desc.enable_mask = DA9062AA_LDO1_EN_MASK,
|
||||
.desc.vsel_reg = DA9062AA_VLDO1_A,
|
||||
.desc.vsel_mask = DA9062AA_VLDO1_A_MASK,
|
||||
.desc.linear_min_sel = 0,
|
||||
.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
|
||||
.sleep = REG_FIELD(DA9062AA_VLDO1_A,
|
||||
__builtin_ffs((int)DA9062AA_LDO1_SL_A_MASK) - 1,
|
||||
sizeof(unsigned int) * 8 -
|
||||
|
@ -525,12 +526,13 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
|
|||
.desc.ops = &da9062_ldo_ops,
|
||||
.desc.min_uV = (900) * 1000,
|
||||
.desc.uV_step = (50) * 1000,
|
||||
.desc.n_voltages = ((3600) - (600))/(50) + 1,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1
|
||||
+ DA9062AA_VLDO_A_MIN_SEL,
|
||||
.desc.enable_reg = DA9062AA_LDO2_CONT,
|
||||
.desc.enable_mask = DA9062AA_LDO2_EN_MASK,
|
||||
.desc.vsel_reg = DA9062AA_VLDO2_A,
|
||||
.desc.vsel_mask = DA9062AA_VLDO2_A_MASK,
|
||||
.desc.linear_min_sel = 0,
|
||||
.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
|
||||
.sleep = REG_FIELD(DA9062AA_VLDO2_A,
|
||||
__builtin_ffs((int)DA9062AA_LDO2_SL_A_MASK) - 1,
|
||||
sizeof(unsigned int) * 8 -
|
||||
|
@ -557,12 +559,13 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
|
|||
.desc.ops = &da9062_ldo_ops,
|
||||
.desc.min_uV = (900) * 1000,
|
||||
.desc.uV_step = (50) * 1000,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1
|
||||
+ DA9062AA_VLDO_A_MIN_SEL,
|
||||
.desc.enable_reg = DA9062AA_LDO3_CONT,
|
||||
.desc.enable_mask = DA9062AA_LDO3_EN_MASK,
|
||||
.desc.vsel_reg = DA9062AA_VLDO3_A,
|
||||
.desc.vsel_mask = DA9062AA_VLDO3_A_MASK,
|
||||
.desc.linear_min_sel = 0,
|
||||
.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
|
||||
.sleep = REG_FIELD(DA9062AA_VLDO3_A,
|
||||
__builtin_ffs((int)DA9062AA_LDO3_SL_A_MASK) - 1,
|
||||
sizeof(unsigned int) * 8 -
|
||||
|
@ -589,12 +592,13 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
|
|||
.desc.ops = &da9062_ldo_ops,
|
||||
.desc.min_uV = (900) * 1000,
|
||||
.desc.uV_step = (50) * 1000,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1
|
||||
+ DA9062AA_VLDO_A_MIN_SEL,
|
||||
.desc.enable_reg = DA9062AA_LDO4_CONT,
|
||||
.desc.enable_mask = DA9062AA_LDO4_EN_MASK,
|
||||
.desc.vsel_reg = DA9062AA_VLDO4_A,
|
||||
.desc.vsel_mask = DA9062AA_VLDO4_A_MASK,
|
||||
.desc.linear_min_sel = 0,
|
||||
.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
|
||||
.sleep = REG_FIELD(DA9062AA_VLDO4_A,
|
||||
__builtin_ffs((int)DA9062AA_LDO4_SL_A_MASK) - 1,
|
||||
sizeof(unsigned int) * 8 -
|
||||
|
@ -769,12 +773,13 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
|
|||
.desc.ops = &da9062_ldo_ops,
|
||||
.desc.min_uV = (900) * 1000,
|
||||
.desc.uV_step = (50) * 1000,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1
|
||||
+ DA9062AA_VLDO_A_MIN_SEL,
|
||||
.desc.enable_reg = DA9062AA_LDO1_CONT,
|
||||
.desc.enable_mask = DA9062AA_LDO1_EN_MASK,
|
||||
.desc.vsel_reg = DA9062AA_VLDO1_A,
|
||||
.desc.vsel_mask = DA9062AA_VLDO1_A_MASK,
|
||||
.desc.linear_min_sel = 0,
|
||||
.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
|
||||
.sleep = REG_FIELD(DA9062AA_VLDO1_A,
|
||||
__builtin_ffs((int)DA9062AA_LDO1_SL_A_MASK) - 1,
|
||||
sizeof(unsigned int) * 8 -
|
||||
|
@ -801,12 +806,13 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
|
|||
.desc.ops = &da9062_ldo_ops,
|
||||
.desc.min_uV = (900) * 1000,
|
||||
.desc.uV_step = (50) * 1000,
|
||||
.desc.n_voltages = ((3600) - (600))/(50) + 1,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1
|
||||
+ DA9062AA_VLDO_A_MIN_SEL,
|
||||
.desc.enable_reg = DA9062AA_LDO2_CONT,
|
||||
.desc.enable_mask = DA9062AA_LDO2_EN_MASK,
|
||||
.desc.vsel_reg = DA9062AA_VLDO2_A,
|
||||
.desc.vsel_mask = DA9062AA_VLDO2_A_MASK,
|
||||
.desc.linear_min_sel = 0,
|
||||
.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
|
||||
.sleep = REG_FIELD(DA9062AA_VLDO2_A,
|
||||
__builtin_ffs((int)DA9062AA_LDO2_SL_A_MASK) - 1,
|
||||
sizeof(unsigned int) * 8 -
|
||||
|
@ -833,12 +839,13 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
|
|||
.desc.ops = &da9062_ldo_ops,
|
||||
.desc.min_uV = (900) * 1000,
|
||||
.desc.uV_step = (50) * 1000,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1
|
||||
+ DA9062AA_VLDO_A_MIN_SEL,
|
||||
.desc.enable_reg = DA9062AA_LDO3_CONT,
|
||||
.desc.enable_mask = DA9062AA_LDO3_EN_MASK,
|
||||
.desc.vsel_reg = DA9062AA_VLDO3_A,
|
||||
.desc.vsel_mask = DA9062AA_VLDO3_A_MASK,
|
||||
.desc.linear_min_sel = 0,
|
||||
.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
|
||||
.sleep = REG_FIELD(DA9062AA_VLDO3_A,
|
||||
__builtin_ffs((int)DA9062AA_LDO3_SL_A_MASK) - 1,
|
||||
sizeof(unsigned int) * 8 -
|
||||
|
@ -865,12 +872,13 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
|
|||
.desc.ops = &da9062_ldo_ops,
|
||||
.desc.min_uV = (900) * 1000,
|
||||
.desc.uV_step = (50) * 1000,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1,
|
||||
.desc.n_voltages = ((3600) - (900))/(50) + 1
|
||||
+ DA9062AA_VLDO_A_MIN_SEL,
|
||||
.desc.enable_reg = DA9062AA_LDO4_CONT,
|
||||
.desc.enable_mask = DA9062AA_LDO4_EN_MASK,
|
||||
.desc.vsel_reg = DA9062AA_VLDO4_A,
|
||||
.desc.vsel_mask = DA9062AA_VLDO4_A_MASK,
|
||||
.desc.linear_min_sel = 0,
|
||||
.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
|
||||
.sleep = REG_FIELD(DA9062AA_VLDO4_A,
|
||||
__builtin_ffs((int)DA9062AA_LDO4_SL_A_MASK) - 1,
|
||||
sizeof(unsigned int) * 8 -
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/mfd/da9063/core.h>
|
||||
#include <linux/mfd/da9063/pdata.h>
|
||||
#include <linux/mfd/da9063/registers.h>
|
||||
|
||||
|
||||
|
@ -28,6 +27,49 @@
|
|||
REG_FIELD(_reg, __builtin_ffs((int)_mask) - 1, \
|
||||
sizeof(unsigned int) * 8 - __builtin_clz((_mask)) - 1)
|
||||
|
||||
/* DA9063 and DA9063L regulator IDs */
|
||||
enum {
|
||||
/* BUCKs */
|
||||
DA9063_ID_BCORE1,
|
||||
DA9063_ID_BCORE2,
|
||||
DA9063_ID_BPRO,
|
||||
DA9063_ID_BMEM,
|
||||
DA9063_ID_BIO,
|
||||
DA9063_ID_BPERI,
|
||||
|
||||
/* BCORE1 and BCORE2 in merged mode */
|
||||
DA9063_ID_BCORES_MERGED,
|
||||
/* BMEM and BIO in merged mode */
|
||||
DA9063_ID_BMEM_BIO_MERGED,
|
||||
/* When two BUCKs are merged, they cannot be reused separately */
|
||||
|
||||
/* LDOs on both DA9063 and DA9063L */
|
||||
DA9063_ID_LDO3,
|
||||
DA9063_ID_LDO7,
|
||||
DA9063_ID_LDO8,
|
||||
DA9063_ID_LDO9,
|
||||
DA9063_ID_LDO11,
|
||||
|
||||
/* DA9063-only LDOs */
|
||||
DA9063_ID_LDO1,
|
||||
DA9063_ID_LDO2,
|
||||
DA9063_ID_LDO4,
|
||||
DA9063_ID_LDO5,
|
||||
DA9063_ID_LDO6,
|
||||
DA9063_ID_LDO10,
|
||||
};
|
||||
|
||||
/* Old regulator platform data */
|
||||
struct da9063_regulator_data {
|
||||
int id;
|
||||
struct regulator_init_data *initdata;
|
||||
};
|
||||
|
||||
struct da9063_regulators_pdata {
|
||||
unsigned n_regulators;
|
||||
struct da9063_regulator_data *regulator_data;
|
||||
};
|
||||
|
||||
/* Regulator capabilities and registers description */
|
||||
struct da9063_regulator_info {
|
||||
struct regulator_desc desc;
|
||||
|
@ -592,7 +634,6 @@ static const struct regulator_init_data *da9063_get_regulator_initdata(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct of_regulator_match da9063_matches[] = {
|
||||
[DA9063_ID_BCORE1] = { .name = "bcore1" },
|
||||
[DA9063_ID_BCORE2] = { .name = "bcore2" },
|
||||
|
@ -670,20 +711,10 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt(
|
|||
*da9063_reg_matches = da9063_matches;
|
||||
return pdata;
|
||||
}
|
||||
#else
|
||||
static struct da9063_regulators_pdata *da9063_parse_regulators_dt(
|
||||
struct platform_device *pdev,
|
||||
struct of_regulator_match **da9063_reg_matches)
|
||||
{
|
||||
*da9063_reg_matches = NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int da9063_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct da9063_pdata *da9063_pdata = dev_get_platdata(da9063->dev);
|
||||
struct of_regulator_match *da9063_reg_matches = NULL;
|
||||
struct da9063_regulators_pdata *regl_pdata;
|
||||
const struct da9063_dev_model *model;
|
||||
|
@ -693,11 +724,7 @@ static int da9063_regulator_probe(struct platform_device *pdev)
|
|||
bool bcores_merged, bmem_bio_merged;
|
||||
int id, irq, n, n_regulators, ret, val;
|
||||
|
||||
regl_pdata = da9063_pdata ? da9063_pdata->regulators_pdata : NULL;
|
||||
|
||||
if (!regl_pdata)
|
||||
regl_pdata = da9063_parse_regulators_dt(pdev,
|
||||
&da9063_reg_matches);
|
||||
regl_pdata = da9063_parse_regulators_dt(pdev, &da9063_reg_matches);
|
||||
|
||||
if (IS_ERR(regl_pdata) || regl_pdata->n_regulators == 0) {
|
||||
dev_err(&pdev->dev,
|
||||
|
|
|
@ -289,6 +289,8 @@ static struct da9211_pdata *da9211_parse_regulators_dt(
|
|||
0,
|
||||
GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
|
||||
"da9211-enable");
|
||||
if (IS_ERR(pdata->gpiod_ren[n]))
|
||||
pdata->gpiod_ren[n] = NULL;
|
||||
n++;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* helpers.c -- Voltage/Current Regulator framework helper functions.
|
||||
*
|
||||
* Copyright 2007, 2008 Wolfson Microelectronics PLC.
|
||||
* Copyright 2008 SlimLogic Ltd.
|
||||
*/
|
||||
//
|
||||
// helpers.c -- Voltage/Current Regulator framework helper functions.
|
||||
//
|
||||
// Copyright 2007, 2008 Wolfson Microelectronics PLC.
|
||||
// Copyright 2008 SlimLogic Ltd.
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
|
|
|
@ -467,7 +467,7 @@ static int max77620_regulator_is_enabled(struct regulator_dev *rdev)
|
|||
{
|
||||
struct max77620_regulator *pmic = rdev_get_drvdata(rdev);
|
||||
int id = rdev_get_id(rdev);
|
||||
int ret = 1;
|
||||
int ret;
|
||||
|
||||
if (pmic->active_fps_src[id] != MAX77620_FPS_SRC_NONE)
|
||||
return 1;
|
||||
|
@ -758,6 +758,24 @@ static struct max77620_regulator_info max20024_regs_info[MAX77620_NUM_REGS] = {
|
|||
RAIL_LDO(LDO8, ldo8, "in-ldo7-8", N, 800000, 3950000, 50000),
|
||||
};
|
||||
|
||||
static struct max77620_regulator_info max77663_regs_info[MAX77620_NUM_REGS] = {
|
||||
RAIL_SD(SD0, sd0, "in-sd0", SD0, 600000, 3387500, 12500, 0xFF, NONE),
|
||||
RAIL_SD(SD1, sd1, "in-sd1", SD1, 800000, 1587500, 12500, 0xFF, NONE),
|
||||
RAIL_SD(SD2, sd2, "in-sd2", SDX, 600000, 3787500, 12500, 0xFF, NONE),
|
||||
RAIL_SD(SD3, sd3, "in-sd3", SDX, 600000, 3787500, 12500, 0xFF, NONE),
|
||||
RAIL_SD(SD4, sd4, "in-sd4", SDX, 600000, 3787500, 12500, 0xFF, NONE),
|
||||
|
||||
RAIL_LDO(LDO0, ldo0, "in-ldo0-1", N, 800000, 2375000, 25000),
|
||||
RAIL_LDO(LDO1, ldo1, "in-ldo0-1", N, 800000, 2375000, 25000),
|
||||
RAIL_LDO(LDO2, ldo2, "in-ldo2", P, 800000, 3950000, 50000),
|
||||
RAIL_LDO(LDO3, ldo3, "in-ldo3-5", P, 800000, 3950000, 50000),
|
||||
RAIL_LDO(LDO4, ldo4, "in-ldo4-6", P, 800000, 1587500, 12500),
|
||||
RAIL_LDO(LDO5, ldo5, "in-ldo3-5", P, 800000, 3950000, 50000),
|
||||
RAIL_LDO(LDO6, ldo6, "in-ldo4-6", P, 800000, 3950000, 50000),
|
||||
RAIL_LDO(LDO7, ldo7, "in-ldo7-8", N, 800000, 3950000, 50000),
|
||||
RAIL_LDO(LDO8, ldo8, "in-ldo7-8", N, 800000, 3950000, 50000),
|
||||
};
|
||||
|
||||
static int max77620_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct max77620_chip *max77620_chip = dev_get_drvdata(pdev->dev.parent);
|
||||
|
@ -782,9 +800,14 @@ static int max77620_regulator_probe(struct platform_device *pdev)
|
|||
case MAX77620:
|
||||
rinfo = max77620_regs_info;
|
||||
break;
|
||||
default:
|
||||
case MAX20024:
|
||||
rinfo = max20024_regs_info;
|
||||
break;
|
||||
case MAX77663:
|
||||
rinfo = max77663_regs_info;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
config.regmap = pmic->rmap;
|
||||
|
@ -878,6 +901,7 @@ static const struct dev_pm_ops max77620_regulator_pm_ops = {
|
|||
static const struct platform_device_id max77620_regulator_devtype[] = {
|
||||
{ .name = "max77620-pmic", },
|
||||
{ .name = "max20024-pmic", },
|
||||
{ .name = "max77663-pmic", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, max77620_regulator_devtype);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#define MAX77650_REGULATOR_V_LDO_MASK GENMASK(6, 0)
|
||||
#define MAX77650_REGULATOR_V_SBB_MASK GENMASK(5, 0)
|
||||
#define MAX77651_REGULATOR_V_SBB1_MASK GENMASK(5, 2)
|
||||
#define MAX77651_REGULATOR_V_SBB1_RANGE_MASK GENMASK(1, 0)
|
||||
|
||||
#define MAX77650_REGULATOR_AD_MASK BIT(3)
|
||||
#define MAX77650_REGULATOR_AD_DISABLED 0x00
|
||||
|
@ -41,43 +43,22 @@ struct max77650_regulator_desc {
|
|||
unsigned int regB;
|
||||
};
|
||||
|
||||
static const unsigned int max77651_sbb1_regulator_volt_table[] = {
|
||||
2400000, 3200000, 4000000, 4800000,
|
||||
2450000, 3250000, 4050000, 4850000,
|
||||
2500000, 3300000, 4100000, 4900000,
|
||||
2550000, 3350000, 4150000, 4950000,
|
||||
2600000, 3400000, 4200000, 5000000,
|
||||
2650000, 3450000, 4250000, 5050000,
|
||||
2700000, 3500000, 4300000, 5100000,
|
||||
2750000, 3550000, 4350000, 5150000,
|
||||
2800000, 3600000, 4400000, 5200000,
|
||||
2850000, 3650000, 4450000, 5250000,
|
||||
2900000, 3700000, 4500000, 0,
|
||||
2950000, 3750000, 4550000, 0,
|
||||
3000000, 3800000, 4600000, 0,
|
||||
3050000, 3850000, 4650000, 0,
|
||||
3100000, 3900000, 4700000, 0,
|
||||
3150000, 3950000, 4750000, 0,
|
||||
static struct max77650_regulator_desc max77651_SBB1_desc;
|
||||
|
||||
static const unsigned int max77651_sbb1_volt_range_sel[] = {
|
||||
0x0, 0x1, 0x2, 0x3
|
||||
};
|
||||
|
||||
#define MAX77651_REGULATOR_SBB1_SEL_DEC(_val) \
|
||||
(((_val & 0x3c) >> 2) | ((_val & 0x03) << 4))
|
||||
#define MAX77651_REGULATOR_SBB1_SEL_ENC(_val) \
|
||||
(((_val & 0x30) >> 4) | ((_val & 0x0f) << 2))
|
||||
|
||||
#define MAX77650_REGULATOR_SBB1_SEL_DECR(_val) \
|
||||
do { \
|
||||
_val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \
|
||||
_val--; \
|
||||
_val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \
|
||||
} while (0)
|
||||
|
||||
#define MAX77650_REGULATOR_SBB1_SEL_INCR(_val) \
|
||||
do { \
|
||||
_val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \
|
||||
_val++; \
|
||||
_val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \
|
||||
} while (0)
|
||||
static const struct regulator_linear_range max77651_sbb1_volt_ranges[] = {
|
||||
/* range index 0 */
|
||||
REGULATOR_LINEAR_RANGE(2400000, 0x00, 0x0f, 50000),
|
||||
/* range index 1 */
|
||||
REGULATOR_LINEAR_RANGE(3200000, 0x00, 0x0f, 50000),
|
||||
/* range index 2 */
|
||||
REGULATOR_LINEAR_RANGE(4000000, 0x00, 0x0f, 50000),
|
||||
/* range index 3 */
|
||||
REGULATOR_LINEAR_RANGE(4800000, 0x00, 0x09, 50000),
|
||||
};
|
||||
|
||||
static const unsigned int max77650_current_limit_table[] = {
|
||||
1000000, 866000, 707000, 500000,
|
||||
|
@ -127,96 +108,6 @@ static int max77650_regulator_disable(struct regulator_dev *rdev)
|
|||
MAX77650_REGULATOR_DISABLED);
|
||||
}
|
||||
|
||||
static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned int sel)
|
||||
{
|
||||
int rv = 0, curr, diff;
|
||||
bool ascending;
|
||||
|
||||
/*
|
||||
* If the regulator is disabled, we can program the desired
|
||||
* voltage right away.
|
||||
*/
|
||||
if (!max77650_regulator_is_enabled(rdev))
|
||||
return regulator_set_voltage_sel_regmap(rdev, sel);
|
||||
|
||||
/*
|
||||
* Otherwise we need to manually ramp the output voltage up/down
|
||||
* one step at a time.
|
||||
*/
|
||||
|
||||
curr = regulator_get_voltage_sel_regmap(rdev);
|
||||
if (curr < 0)
|
||||
return curr;
|
||||
|
||||
diff = curr - sel;
|
||||
if (diff == 0)
|
||||
return 0; /* Already there. */
|
||||
else if (diff > 0)
|
||||
ascending = false;
|
||||
else
|
||||
ascending = true;
|
||||
|
||||
/*
|
||||
* Make sure we'll get to the right voltage and break the loop even if
|
||||
* the selector equals 0.
|
||||
*/
|
||||
for (ascending ? curr++ : curr--;; ascending ? curr++ : curr--) {
|
||||
rv = regulator_set_voltage_sel_regmap(rdev, curr);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (curr == sel)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case: non-linear voltage table for max77651 SBB1 - software
|
||||
* must ensure the voltage is ramped in 50mV increments.
|
||||
*/
|
||||
static int max77651_regulator_sbb1_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned int sel)
|
||||
{
|
||||
int rv = 0, curr, vcurr, vdest, vdiff;
|
||||
|
||||
/*
|
||||
* If the regulator is disabled, we can program the desired
|
||||
* voltage right away.
|
||||
*/
|
||||
if (!max77650_regulator_is_enabled(rdev))
|
||||
return regulator_set_voltage_sel_regmap(rdev, sel);
|
||||
|
||||
curr = regulator_get_voltage_sel_regmap(rdev);
|
||||
if (curr < 0)
|
||||
return curr;
|
||||
|
||||
if (curr == sel)
|
||||
return 0; /* Already there. */
|
||||
|
||||
vcurr = max77651_sbb1_regulator_volt_table[curr];
|
||||
vdest = max77651_sbb1_regulator_volt_table[sel];
|
||||
vdiff = vcurr - vdest;
|
||||
|
||||
for (;;) {
|
||||
if (vdiff > 0)
|
||||
MAX77650_REGULATOR_SBB1_SEL_DECR(curr);
|
||||
else
|
||||
MAX77650_REGULATOR_SBB1_SEL_INCR(curr);
|
||||
|
||||
rv = regulator_set_voltage_sel_regmap(rdev, curr);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (curr == sel)
|
||||
break;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct regulator_ops max77650_regulator_LDO_ops = {
|
||||
.is_enabled = max77650_regulator_is_enabled,
|
||||
.enable = max77650_regulator_enable,
|
||||
|
@ -224,7 +115,7 @@ static const struct regulator_ops max77650_regulator_LDO_ops = {
|
|||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = max77650_regulator_set_voltage_sel,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
};
|
||||
|
||||
|
@ -235,20 +126,20 @@ static const struct regulator_ops max77650_regulator_SBB_ops = {
|
|||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = max77650_regulator_set_voltage_sel,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
};
|
||||
|
||||
/* Special case for max77651 SBB1 - non-linear voltage mapping. */
|
||||
/* Special case for max77651 SBB1 - pickable linear-range voltage mapping. */
|
||||
static const struct regulator_ops max77651_SBB1_regulator_ops = {
|
||||
.is_enabled = max77650_regulator_is_enabled,
|
||||
.enable = max77650_regulator_enable,
|
||||
.disable = max77650_regulator_disable,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = max77651_regulator_sbb1_set_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_pickable_linear_range,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
|
@ -265,6 +156,7 @@ static struct max77650_regulator_desc max77650_LDO_desc = {
|
|||
.min_uV = 1350000,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 128,
|
||||
.vsel_step = 1,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_LDO_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_LDO_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
|
@ -290,6 +182,7 @@ static struct max77650_regulator_desc max77650_SBB0_desc = {
|
|||
.min_uV = 800000,
|
||||
.uV_step = 25000,
|
||||
.n_voltages = 64,
|
||||
.vsel_step = 1,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB0_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
|
@ -319,6 +212,7 @@ static struct max77650_regulator_desc max77650_SBB1_desc = {
|
|||
.min_uV = 800000,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 64,
|
||||
.vsel_step = 1,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB1_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
|
@ -345,9 +239,14 @@ static struct max77650_regulator_desc max77651_SBB1_desc = {
|
|||
.supply_name = "in-sbb1",
|
||||
.id = MAX77650_REGULATOR_ID_SBB1,
|
||||
.ops = &max77651_SBB1_regulator_ops,
|
||||
.volt_table = max77651_sbb1_regulator_volt_table,
|
||||
.n_voltages = ARRAY_SIZE(max77651_sbb1_regulator_volt_table),
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.linear_range_selectors = max77651_sbb1_volt_range_sel,
|
||||
.linear_ranges = max77651_sbb1_volt_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(max77651_sbb1_volt_ranges),
|
||||
.n_voltages = 58,
|
||||
.vsel_step = 1,
|
||||
.vsel_range_mask = MAX77651_REGULATOR_V_SBB1_RANGE_MASK,
|
||||
.vsel_range_reg = MAX77650_REG_CNFG_SBB1_A,
|
||||
.vsel_mask = MAX77651_REGULATOR_V_SBB1_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB1_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
.active_discharge_on = MAX77650_REGULATOR_AD_ENABLED,
|
||||
|
@ -376,6 +275,7 @@ static struct max77650_regulator_desc max77650_SBB2_desc = {
|
|||
.min_uV = 800000,
|
||||
.uV_step = 50000,
|
||||
.n_voltages = 64,
|
||||
.vsel_step = 1,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB2_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
|
@ -405,6 +305,7 @@ static struct max77650_regulator_desc max77651_SBB2_desc = {
|
|||
.min_uV = 2400000,
|
||||
.uV_step = 50000,
|
||||
.n_voltages = 64,
|
||||
.vsel_step = 1,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB2_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
|
@ -496,3 +397,4 @@ module_platform_driver(max77650_regulator_driver);
|
|||
MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver");
|
||||
MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:max77650-regulator");
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
|
|
|
@ -13,11 +13,9 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/max8952.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -37,7 +35,8 @@ enum {
|
|||
struct max8952_data {
|
||||
struct i2c_client *client;
|
||||
struct max8952_platform_data *pdata;
|
||||
|
||||
struct gpio_desc *vid0_gpiod;
|
||||
struct gpio_desc *vid1_gpiod;
|
||||
bool vid0;
|
||||
bool vid1;
|
||||
};
|
||||
|
@ -87,16 +86,15 @@ static int max8952_set_voltage_sel(struct regulator_dev *rdev,
|
|||
{
|
||||
struct max8952_data *max8952 = rdev_get_drvdata(rdev);
|
||||
|
||||
if (!gpio_is_valid(max8952->pdata->gpio_vid0) ||
|
||||
!gpio_is_valid(max8952->pdata->gpio_vid1)) {
|
||||
if (!max8952->vid0_gpiod || !max8952->vid1_gpiod) {
|
||||
/* DVS not supported */
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
max8952->vid0 = selector & 0x1;
|
||||
max8952->vid1 = (selector >> 1) & 0x1;
|
||||
gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0);
|
||||
gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1);
|
||||
gpiod_set_value(max8952->vid0_gpiod, max8952->vid0);
|
||||
gpiod_set_value(max8952->vid1_gpiod, max8952->vid1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -134,9 +132,6 @@ static struct max8952_platform_data *max8952_parse_dt(struct device *dev)
|
|||
if (!pd)
|
||||
return NULL;
|
||||
|
||||
pd->gpio_vid0 = of_get_named_gpio(np, "max8952,vid-gpios", 0);
|
||||
pd->gpio_vid1 = of_get_named_gpio(np, "max8952,vid-gpios", 1);
|
||||
|
||||
if (of_property_read_u32(np, "max8952,default-mode", &pd->default_mode))
|
||||
dev_warn(dev, "Default mode not specified, assuming 0\n");
|
||||
|
||||
|
@ -179,7 +174,7 @@ static struct max8952_platform_data *max8952_parse_dt(struct device *dev)
|
|||
static int max8952_pmic_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *i2c_id)
|
||||
{
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
struct max8952_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
struct regulator_config config = { };
|
||||
struct max8952_data *max8952;
|
||||
|
@ -187,7 +182,7 @@ static int max8952_pmic_probe(struct i2c_client *client,
|
|||
struct gpio_desc *gpiod;
|
||||
enum gpiod_flags gflags;
|
||||
|
||||
int ret = 0, err = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (client->dev.of_node)
|
||||
pdata = max8952_parse_dt(&client->dev);
|
||||
|
@ -240,32 +235,31 @@ static int max8952_pmic_probe(struct i2c_client *client,
|
|||
max8952->vid0 = pdata->default_mode & 0x1;
|
||||
max8952->vid1 = (pdata->default_mode >> 1) & 0x1;
|
||||
|
||||
if (gpio_is_valid(pdata->gpio_vid0) &&
|
||||
gpio_is_valid(pdata->gpio_vid1)) {
|
||||
unsigned long gpio_flags;
|
||||
/* Fetch vid0 and vid1 GPIOs if available */
|
||||
gflags = max8952->vid0 ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
|
||||
max8952->vid0_gpiod = devm_gpiod_get_index_optional(&client->dev,
|
||||
"max8952,vid",
|
||||
0, gflags);
|
||||
if (IS_ERR(max8952->vid0_gpiod))
|
||||
return PTR_ERR(max8952->vid0_gpiod);
|
||||
gflags = max8952->vid1 ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
|
||||
max8952->vid1_gpiod = devm_gpiod_get_index_optional(&client->dev,
|
||||
"max8952,vid",
|
||||
1, gflags);
|
||||
if (IS_ERR(max8952->vid1_gpiod))
|
||||
return PTR_ERR(max8952->vid1_gpiod);
|
||||
|
||||
gpio_flags = max8952->vid0 ?
|
||||
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
|
||||
if (devm_gpio_request_one(&client->dev, pdata->gpio_vid0,
|
||||
gpio_flags, "MAX8952 VID0"))
|
||||
err = 1;
|
||||
|
||||
gpio_flags = max8952->vid1 ?
|
||||
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
|
||||
if (devm_gpio_request_one(&client->dev, pdata->gpio_vid1,
|
||||
gpio_flags, "MAX8952 VID1"))
|
||||
err = 2;
|
||||
} else
|
||||
err = 3;
|
||||
|
||||
if (err) {
|
||||
/* If either VID GPIO is missing just disable this */
|
||||
if (!max8952->vid0_gpiod || !max8952->vid1_gpiod) {
|
||||
dev_warn(&client->dev, "VID0/1 gpio invalid: "
|
||||
"DVS not available.\n");
|
||||
"DVS not available.\n");
|
||||
max8952->vid0 = 0;
|
||||
max8952->vid1 = 0;
|
||||
/* Mark invalid */
|
||||
pdata->gpio_vid0 = -1;
|
||||
pdata->gpio_vid1 = -1;
|
||||
/* Make sure if we have any descriptors they get set to low */
|
||||
if (max8952->vid0_gpiod)
|
||||
gpiod_set_value(max8952->vid0_gpiod, 0);
|
||||
if (max8952->vid1_gpiod)
|
||||
gpiod_set_value(max8952->vid1_gpiod, 0);
|
||||
|
||||
/* Disable Pulldown of EN only */
|
||||
max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x60);
|
||||
|
|
|
@ -96,6 +96,8 @@ enum spmi_regulator_logical_type {
|
|||
SPMI_REGULATOR_LOGICAL_TYPE_ULT_LO_SMPS,
|
||||
SPMI_REGULATOR_LOGICAL_TYPE_ULT_HO_SMPS,
|
||||
SPMI_REGULATOR_LOGICAL_TYPE_ULT_LDO,
|
||||
SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS426,
|
||||
SPMI_REGULATOR_LOGICAL_TYPE_HFS430,
|
||||
};
|
||||
|
||||
enum spmi_regulator_type {
|
||||
|
@ -142,11 +144,13 @@ enum spmi_regulator_subtype {
|
|||
SPMI_REGULATOR_SUBTYPE_5V_BOOST = 0x01,
|
||||
SPMI_REGULATOR_SUBTYPE_FTS_CTL = 0x08,
|
||||
SPMI_REGULATOR_SUBTYPE_FTS2p5_CTL = 0x09,
|
||||
SPMI_REGULATOR_SUBTYPE_FTS426_CTL = 0x0a,
|
||||
SPMI_REGULATOR_SUBTYPE_BB_2A = 0x01,
|
||||
SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL1 = 0x0d,
|
||||
SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL2 = 0x0e,
|
||||
SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL3 = 0x0f,
|
||||
SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL4 = 0x10,
|
||||
SPMI_REGULATOR_SUBTYPE_HFS430 = 0x0a,
|
||||
};
|
||||
|
||||
enum spmi_common_regulator_registers {
|
||||
|
@ -162,6 +166,18 @@ enum spmi_common_regulator_registers {
|
|||
SPMI_COMMON_REG_STEP_CTRL = 0x61,
|
||||
};
|
||||
|
||||
/*
|
||||
* Second common register layout used by newer devices starting with ftsmps426
|
||||
* Note that some of the registers from the first common layout remain
|
||||
* unchanged and their definition is not duplicated.
|
||||
*/
|
||||
enum spmi_ftsmps426_regulator_registers {
|
||||
SPMI_FTSMPS426_REG_VOLTAGE_LSB = 0x40,
|
||||
SPMI_FTSMPS426_REG_VOLTAGE_MSB = 0x41,
|
||||
SPMI_FTSMPS426_REG_VOLTAGE_ULS_LSB = 0x68,
|
||||
SPMI_FTSMPS426_REG_VOLTAGE_ULS_MSB = 0x69,
|
||||
};
|
||||
|
||||
enum spmi_vs_registers {
|
||||
SPMI_VS_REG_OCP = 0x4a,
|
||||
SPMI_VS_REG_SOFT_START = 0x4c,
|
||||
|
@ -221,6 +237,14 @@ enum spmi_common_control_register_index {
|
|||
#define SPMI_COMMON_MODE_FOLLOW_HW_EN0_MASK 0x01
|
||||
#define SPMI_COMMON_MODE_FOLLOW_ALL_MASK 0x1f
|
||||
|
||||
#define SPMI_FTSMPS426_MODE_BYPASS_MASK 3
|
||||
#define SPMI_FTSMPS426_MODE_RETENTION_MASK 4
|
||||
#define SPMI_FTSMPS426_MODE_LPM_MASK 5
|
||||
#define SPMI_FTSMPS426_MODE_AUTO_MASK 6
|
||||
#define SPMI_FTSMPS426_MODE_HPM_MASK 7
|
||||
|
||||
#define SPMI_FTSMPS426_MODE_MASK 0x07
|
||||
|
||||
/* Common regulator pull down control register layout */
|
||||
#define SPMI_COMMON_PULL_DOWN_ENABLE_MASK 0x80
|
||||
|
||||
|
@ -266,6 +290,25 @@ enum spmi_common_control_register_index {
|
|||
#define SPMI_FTSMPS_STEP_MARGIN_NUM 4
|
||||
#define SPMI_FTSMPS_STEP_MARGIN_DEN 5
|
||||
|
||||
#define SPMI_FTSMPS426_STEP_CTRL_DELAY_MASK 0x03
|
||||
#define SPMI_FTSMPS426_STEP_CTRL_DELAY_SHIFT 0
|
||||
|
||||
/* Clock rate in kHz of the FTSMPS426 regulator reference clock. */
|
||||
#define SPMI_FTSMPS426_CLOCK_RATE 4800
|
||||
|
||||
#define SPMI_HFS430_CLOCK_RATE 1600
|
||||
|
||||
/* Minimum voltage stepper delay for each step. */
|
||||
#define SPMI_FTSMPS426_STEP_DELAY 2
|
||||
|
||||
/*
|
||||
* The ratio SPMI_FTSMPS426_STEP_MARGIN_NUM/SPMI_FTSMPS426_STEP_MARGIN_DEN is
|
||||
* used to adjust the step rate in order to account for oscillator variance.
|
||||
*/
|
||||
#define SPMI_FTSMPS426_STEP_MARGIN_NUM 10
|
||||
#define SPMI_FTSMPS426_STEP_MARGIN_DEN 11
|
||||
|
||||
|
||||
/* VSET value to decide the range of ULT SMPS */
|
||||
#define ULT_SMPS_RANGE_SPLIT 0x60
|
||||
|
||||
|
@ -439,6 +482,10 @@ static struct spmi_voltage_range ftsmps2p5_ranges[] = {
|
|||
SPMI_VOLTAGE_RANGE(1, 160000, 1360000, 2200000, 2200000, 10000),
|
||||
};
|
||||
|
||||
static struct spmi_voltage_range ftsmps426_ranges[] = {
|
||||
SPMI_VOLTAGE_RANGE(0, 0, 320000, 1352000, 1352000, 4000),
|
||||
};
|
||||
|
||||
static struct spmi_voltage_range boost_ranges[] = {
|
||||
SPMI_VOLTAGE_RANGE(0, 4000000, 4000000, 5550000, 5550000, 50000),
|
||||
};
|
||||
|
@ -464,6 +511,10 @@ static struct spmi_voltage_range ult_pldo_ranges[] = {
|
|||
SPMI_VOLTAGE_RANGE(0, 1750000, 1750000, 3337500, 3337500, 12500),
|
||||
};
|
||||
|
||||
static struct spmi_voltage_range hfs430_ranges[] = {
|
||||
SPMI_VOLTAGE_RANGE(0, 320000, 320000, 2040000, 2040000, 8000),
|
||||
};
|
||||
|
||||
static DEFINE_SPMI_SET_POINTS(pldo);
|
||||
static DEFINE_SPMI_SET_POINTS(nldo1);
|
||||
static DEFINE_SPMI_SET_POINTS(nldo2);
|
||||
|
@ -472,12 +523,14 @@ static DEFINE_SPMI_SET_POINTS(ln_ldo);
|
|||
static DEFINE_SPMI_SET_POINTS(smps);
|
||||
static DEFINE_SPMI_SET_POINTS(ftsmps);
|
||||
static DEFINE_SPMI_SET_POINTS(ftsmps2p5);
|
||||
static DEFINE_SPMI_SET_POINTS(ftsmps426);
|
||||
static DEFINE_SPMI_SET_POINTS(boost);
|
||||
static DEFINE_SPMI_SET_POINTS(boost_byp);
|
||||
static DEFINE_SPMI_SET_POINTS(ult_lo_smps);
|
||||
static DEFINE_SPMI_SET_POINTS(ult_ho_smps);
|
||||
static DEFINE_SPMI_SET_POINTS(ult_nldo);
|
||||
static DEFINE_SPMI_SET_POINTS(ult_pldo);
|
||||
static DEFINE_SPMI_SET_POINTS(hfs430);
|
||||
|
||||
static inline int spmi_vreg_read(struct spmi_regulator *vreg, u16 addr, u8 *buf,
|
||||
int len)
|
||||
|
@ -739,18 +792,31 @@ spmi_regulator_common_set_voltage(struct regulator_dev *rdev, unsigned selector)
|
|||
return spmi_vreg_write(vreg, SPMI_COMMON_REG_VOLTAGE_RANGE, buf, 2);
|
||||
}
|
||||
|
||||
static int spmi_regulator_common_list_voltage(struct regulator_dev *rdev,
|
||||
unsigned selector);
|
||||
|
||||
static int spmi_regulator_ftsmps426_set_voltage(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
u8 buf[2];
|
||||
int mV;
|
||||
|
||||
mV = spmi_regulator_common_list_voltage(rdev, selector) / 1000;
|
||||
|
||||
buf[0] = mV & 0xff;
|
||||
buf[1] = mV >> 8;
|
||||
return spmi_vreg_write(vreg, SPMI_FTSMPS426_REG_VOLTAGE_LSB, buf, 2);
|
||||
}
|
||||
|
||||
static int spmi_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
unsigned int old_selector, unsigned int new_selector)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
const struct spmi_voltage_range *range;
|
||||
int diff_uV;
|
||||
|
||||
range = spmi_regulator_find_range(vreg);
|
||||
if (!range)
|
||||
return -EINVAL;
|
||||
|
||||
diff_uV = abs(new_selector - old_selector) * range->step_uV;
|
||||
diff_uV = abs(spmi_regulator_common_list_voltage(rdev, new_selector) -
|
||||
spmi_regulator_common_list_voltage(rdev, old_selector));
|
||||
|
||||
return DIV_ROUND_UP(diff_uV, vreg->slew_rate);
|
||||
}
|
||||
|
@ -770,6 +836,21 @@ static int spmi_regulator_common_get_voltage(struct regulator_dev *rdev)
|
|||
return spmi_hw_selector_to_sw(vreg, voltage_sel, range);
|
||||
}
|
||||
|
||||
static int spmi_regulator_ftsmps426_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
const struct spmi_voltage_range *range;
|
||||
u8 buf[2];
|
||||
int uV;
|
||||
|
||||
spmi_vreg_read(vreg, SPMI_FTSMPS426_REG_VOLTAGE_LSB, buf, 2);
|
||||
|
||||
uV = (((unsigned int)buf[1] << 8) | (unsigned int)buf[0]) * 1000;
|
||||
range = vreg->set_points->range;
|
||||
|
||||
return (uV - range->set_point_min_uV) / range->step_uV;
|
||||
}
|
||||
|
||||
static int spmi_regulator_single_map_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
|
@ -903,13 +984,33 @@ static unsigned int spmi_regulator_common_get_mode(struct regulator_dev *rdev)
|
|||
|
||||
spmi_vreg_read(vreg, SPMI_COMMON_REG_MODE, ®, 1);
|
||||
|
||||
if (reg & SPMI_COMMON_MODE_HPM_MASK)
|
||||
reg &= SPMI_COMMON_MODE_HPM_MASK | SPMI_COMMON_MODE_AUTO_MASK;
|
||||
|
||||
switch (reg) {
|
||||
case SPMI_COMMON_MODE_HPM_MASK:
|
||||
return REGULATOR_MODE_NORMAL;
|
||||
|
||||
if (reg & SPMI_COMMON_MODE_AUTO_MASK)
|
||||
case SPMI_COMMON_MODE_AUTO_MASK:
|
||||
return REGULATOR_MODE_FAST;
|
||||
default:
|
||||
return REGULATOR_MODE_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
return REGULATOR_MODE_IDLE;
|
||||
static unsigned int spmi_regulator_ftsmps426_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
u8 reg;
|
||||
|
||||
spmi_vreg_read(vreg, SPMI_COMMON_REG_MODE, ®, 1);
|
||||
|
||||
switch (reg) {
|
||||
case SPMI_FTSMPS426_MODE_HPM_MASK:
|
||||
return REGULATOR_MODE_NORMAL;
|
||||
case SPMI_FTSMPS426_MODE_AUTO_MASK:
|
||||
return REGULATOR_MODE_FAST;
|
||||
default:
|
||||
return REGULATOR_MODE_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -917,12 +1018,43 @@ spmi_regulator_common_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
|||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
u8 mask = SPMI_COMMON_MODE_HPM_MASK | SPMI_COMMON_MODE_AUTO_MASK;
|
||||
u8 val = 0;
|
||||
u8 val;
|
||||
|
||||
if (mode == REGULATOR_MODE_NORMAL)
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
val = SPMI_COMMON_MODE_HPM_MASK;
|
||||
else if (mode == REGULATOR_MODE_FAST)
|
||||
break;
|
||||
case REGULATOR_MODE_FAST:
|
||||
val = SPMI_COMMON_MODE_AUTO_MASK;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return spmi_vreg_update_bits(vreg, SPMI_COMMON_REG_MODE, val, mask);
|
||||
}
|
||||
|
||||
static int
|
||||
spmi_regulator_ftsmps426_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
u8 mask = SPMI_FTSMPS426_MODE_MASK;
|
||||
u8 val;
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
val = SPMI_FTSMPS426_MODE_HPM_MASK;
|
||||
break;
|
||||
case REGULATOR_MODE_FAST:
|
||||
val = SPMI_FTSMPS426_MODE_AUTO_MASK;
|
||||
break;
|
||||
case REGULATOR_MODE_IDLE:
|
||||
val = SPMI_FTSMPS426_MODE_LPM_MASK;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return spmi_vreg_update_bits(vreg, SPMI_COMMON_REG_MODE, val, mask);
|
||||
}
|
||||
|
@ -1256,12 +1388,41 @@ static struct regulator_ops spmi_ult_ldo_ops = {
|
|||
.set_soft_start = spmi_regulator_common_set_soft_start,
|
||||
};
|
||||
|
||||
static struct regulator_ops spmi_ftsmps426_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_voltage_sel = spmi_regulator_ftsmps426_set_voltage,
|
||||
.set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
||||
.get_voltage_sel = spmi_regulator_ftsmps426_get_voltage,
|
||||
.map_voltage = spmi_regulator_single_map_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_mode = spmi_regulator_ftsmps426_set_mode,
|
||||
.get_mode = spmi_regulator_ftsmps426_get_mode,
|
||||
.set_load = spmi_regulator_common_set_load,
|
||||
.set_pull_down = spmi_regulator_common_set_pull_down,
|
||||
};
|
||||
|
||||
static struct regulator_ops spmi_hfs430_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_voltage_sel = spmi_regulator_ftsmps426_set_voltage,
|
||||
.set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
||||
.get_voltage_sel = spmi_regulator_ftsmps426_get_voltage,
|
||||
.map_voltage = spmi_regulator_single_map_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_mode = spmi_regulator_ftsmps426_set_mode,
|
||||
.get_mode = spmi_regulator_ftsmps426_get_mode,
|
||||
};
|
||||
|
||||
/* Maximum possible digital major revision value */
|
||||
#define INF 0xFF
|
||||
|
||||
static const struct spmi_regulator_mapping supported_regulators[] = {
|
||||
/* type subtype dig_min dig_max ltype ops setpoints hpm_min */
|
||||
SPMI_VREG(BUCK, GP_CTL, 0, INF, SMPS, smps, smps, 100000),
|
||||
SPMI_VREG(BUCK, HFS430, 0, INF, HFS430, hfs430, hfs430, 10000),
|
||||
SPMI_VREG(LDO, N300, 0, INF, LDO, ldo, nldo1, 10000),
|
||||
SPMI_VREG(LDO, N600, 0, 0, LDO, ldo, nldo2, 10000),
|
||||
SPMI_VREG(LDO, N1200, 0, 0, LDO, ldo, nldo2, 10000),
|
||||
|
@ -1291,6 +1452,7 @@ static const struct spmi_regulator_mapping supported_regulators[] = {
|
|||
SPMI_VREG(BOOST, 5V_BOOST, 0, INF, BOOST, boost, boost, 0),
|
||||
SPMI_VREG(FTS, FTS_CTL, 0, INF, FTSMPS, ftsmps, ftsmps, 100000),
|
||||
SPMI_VREG(FTS, FTS2p5_CTL, 0, INF, FTSMPS, ftsmps, ftsmps2p5, 100000),
|
||||
SPMI_VREG(FTS, FTS426_CTL, 0, INF, FTSMPS426, ftsmps426, ftsmps426, 100000),
|
||||
SPMI_VREG(BOOST_BYP, BB_2A, 0, INF, BOOST_BYP, boost, boost_byp, 0),
|
||||
SPMI_VREG(ULT_BUCK, ULT_HF_CTL1, 0, INF, ULT_LO_SMPS, ult_lo_smps,
|
||||
ult_lo_smps, 100000),
|
||||
|
@ -1428,6 +1590,35 @@ static int spmi_regulator_init_slew_rate(struct spmi_regulator *vreg)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int spmi_regulator_init_slew_rate_ftsmps426(struct spmi_regulator *vreg,
|
||||
int clock_rate)
|
||||
{
|
||||
int ret;
|
||||
u8 reg = 0;
|
||||
int delay, slew_rate;
|
||||
const struct spmi_voltage_range *range = &vreg->set_points->range[0];
|
||||
|
||||
ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_STEP_CTRL, ®, 1);
|
||||
if (ret) {
|
||||
dev_err(vreg->dev, "spmi read failed, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
delay = reg & SPMI_FTSMPS426_STEP_CTRL_DELAY_MASK;
|
||||
delay >>= SPMI_FTSMPS426_STEP_CTRL_DELAY_SHIFT;
|
||||
|
||||
/* slew_rate has units of uV/us */
|
||||
slew_rate = clock_rate * range->step_uV;
|
||||
slew_rate /= 1000 * (SPMI_FTSMPS426_STEP_DELAY << delay);
|
||||
slew_rate *= SPMI_FTSMPS426_STEP_MARGIN_NUM;
|
||||
slew_rate /= SPMI_FTSMPS426_STEP_MARGIN_DEN;
|
||||
|
||||
/* Ensure that the slew rate is greater than 0 */
|
||||
vreg->slew_rate = max(slew_rate, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spmi_regulator_init_registers(struct spmi_regulator *vreg,
|
||||
const struct spmi_regulator_init_data *data)
|
||||
{
|
||||
|
@ -1567,6 +1758,19 @@ static int spmi_regulator_of_parse(struct device_node *node,
|
|||
ret = spmi_regulator_init_slew_rate(vreg);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS426:
|
||||
ret = spmi_regulator_init_slew_rate_ftsmps426(vreg,
|
||||
SPMI_FTSMPS426_CLOCK_RATE);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case SPMI_REGULATOR_LOGICAL_TYPE_HFS430:
|
||||
ret = spmi_regulator_init_slew_rate_ftsmps426(vreg,
|
||||
SPMI_HFS430_CLOCK_RATE);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1723,12 +1927,27 @@ static const struct spmi_regulator_data pmi8994_regulators[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
static const struct spmi_regulator_data pm8005_regulators[] = {
|
||||
{ "s1", 0x1400, "vdd_s1", },
|
||||
{ "s2", 0x1700, "vdd_s2", },
|
||||
{ "s3", 0x1a00, "vdd_s3", },
|
||||
{ "s4", 0x1d00, "vdd_s4", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct spmi_regulator_data pms405_regulators[] = {
|
||||
{ "s3", 0x1a00, "vdd_s3"},
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct of_device_id qcom_spmi_regulator_match[] = {
|
||||
{ .compatible = "qcom,pm8005-regulators", .data = &pm8005_regulators },
|
||||
{ .compatible = "qcom,pm8841-regulators", .data = &pm8841_regulators },
|
||||
{ .compatible = "qcom,pm8916-regulators", .data = &pm8916_regulators },
|
||||
{ .compatible = "qcom,pm8941-regulators", .data = &pm8941_regulators },
|
||||
{ .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators },
|
||||
{ .compatible = "qcom,pmi8994-regulators", .data = &pmi8994_regulators },
|
||||
{ .compatible = "qcom,pms405-regulators", .data = &pms405_regulators },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qcom_spmi_regulator_match);
|
||||
|
@ -1736,6 +1955,7 @@ MODULE_DEVICE_TABLE(of, qcom_spmi_regulator_match);
|
|||
static int qcom_spmi_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct spmi_regulator_data *reg;
|
||||
const struct spmi_voltage_range *range;
|
||||
const struct of_device_id *match;
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
|
@ -1825,6 +2045,12 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
if (vreg->set_points && vreg->set_points->count == 1) {
|
||||
/* since there is only one range */
|
||||
range = vreg->set_points->range;
|
||||
vreg->desc.uV_step = range->step_uV;
|
||||
}
|
||||
|
||||
config.dev = dev;
|
||||
config.driver_data = vreg;
|
||||
config.regmap = regmap;
|
||||
|
|
|
@ -34,7 +34,7 @@ struct s2mps11_info {
|
|||
enum sec_device_type dev_type;
|
||||
|
||||
/*
|
||||
* One bit for each S2MPS13/S2MPS14/S2MPU02 regulator whether
|
||||
* One bit for each S2MPS11/S2MPS13/S2MPS14/S2MPU02 regulator whether
|
||||
* the suspend mode was enabled.
|
||||
*/
|
||||
DECLARE_BITMAP(suspend_state, S2MPS_REGULATOR_MAX);
|
||||
|
@ -70,10 +70,11 @@ static int s2mps11_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
|
|||
unsigned int new_selector)
|
||||
{
|
||||
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
|
||||
int rdev_id = rdev_get_id(rdev);
|
||||
unsigned int ramp_delay = 0;
|
||||
int old_volt, new_volt;
|
||||
|
||||
switch (rdev_get_id(rdev)) {
|
||||
switch (rdev_id) {
|
||||
case S2MPS11_BUCK2:
|
||||
ramp_delay = s2mps11->ramp_delay2;
|
||||
break;
|
||||
|
@ -111,9 +112,10 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
|
|||
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
|
||||
unsigned int ramp_val, ramp_shift, ramp_reg = S2MPS11_REG_RAMP_BUCK;
|
||||
unsigned int ramp_enable = 1, enable_shift = 0;
|
||||
int rdev_id = rdev_get_id(rdev);
|
||||
int ret;
|
||||
|
||||
switch (rdev_get_id(rdev)) {
|
||||
switch (rdev_id) {
|
||||
case S2MPS11_BUCK1:
|
||||
if (ramp_delay > s2mps11->ramp_delay16)
|
||||
s2mps11->ramp_delay16 = ramp_delay;
|
||||
|
@ -203,9 +205,8 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
|
|||
goto ramp_disable;
|
||||
|
||||
/* Ramp delay can be enabled/disabled only for buck[2346] */
|
||||
if ((rdev_get_id(rdev) >= S2MPS11_BUCK2 &&
|
||||
rdev_get_id(rdev) <= S2MPS11_BUCK4) ||
|
||||
rdev_get_id(rdev) == S2MPS11_BUCK6) {
|
||||
if ((rdev_id >= S2MPS11_BUCK2 && rdev_id <= S2MPS11_BUCK4) ||
|
||||
rdev_id == S2MPS11_BUCK6) {
|
||||
ret = regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP,
|
||||
1 << enable_shift, 1 << enable_shift);
|
||||
if (ret) {
|
||||
|
@ -224,27 +225,133 @@ ramp_disable:
|
|||
1 << enable_shift, 0);
|
||||
}
|
||||
|
||||
static int s2mps11_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
|
||||
int rdev_id = rdev_get_id(rdev);
|
||||
unsigned int val;
|
||||
|
||||
switch (s2mps11->dev_type) {
|
||||
case S2MPS11X:
|
||||
if (test_bit(rdev_id, s2mps11->suspend_state))
|
||||
val = S2MPS14_ENABLE_SUSPEND;
|
||||
else
|
||||
val = rdev->desc->enable_mask;
|
||||
break;
|
||||
case S2MPS13X:
|
||||
case S2MPS14X:
|
||||
if (test_bit(rdev_id, s2mps11->suspend_state))
|
||||
val = S2MPS14_ENABLE_SUSPEND;
|
||||
else if (s2mps11->ext_control_gpiod[rdev_id])
|
||||
val = S2MPS14_ENABLE_EXT_CONTROL;
|
||||
else
|
||||
val = rdev->desc->enable_mask;
|
||||
break;
|
||||
case S2MPU02:
|
||||
if (test_bit(rdev_id, s2mps11->suspend_state))
|
||||
val = S2MPU02_ENABLE_SUSPEND;
|
||||
else
|
||||
val = rdev->desc->enable_mask;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
|
||||
rdev->desc->enable_mask, val);
|
||||
}
|
||||
|
||||
static int s2mps11_regulator_set_suspend_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
int ret;
|
||||
unsigned int val, state;
|
||||
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
|
||||
int rdev_id = rdev_get_id(rdev);
|
||||
|
||||
/* Below LDO should be always on or does not support suspend mode. */
|
||||
switch (s2mps11->dev_type) {
|
||||
case S2MPS11X:
|
||||
switch (rdev_id) {
|
||||
case S2MPS11_LDO2:
|
||||
case S2MPS11_LDO36:
|
||||
case S2MPS11_LDO37:
|
||||
case S2MPS11_LDO38:
|
||||
return 0;
|
||||
default:
|
||||
state = S2MPS14_ENABLE_SUSPEND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case S2MPS13X:
|
||||
case S2MPS14X:
|
||||
switch (rdev_id) {
|
||||
case S2MPS14_LDO3:
|
||||
return 0;
|
||||
default:
|
||||
state = S2MPS14_ENABLE_SUSPEND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case S2MPU02:
|
||||
switch (rdev_id) {
|
||||
case S2MPU02_LDO13:
|
||||
case S2MPU02_LDO14:
|
||||
case S2MPU02_LDO15:
|
||||
case S2MPU02_LDO17:
|
||||
case S2MPU02_BUCK7:
|
||||
state = S2MPU02_DISABLE_SUSPEND;
|
||||
break;
|
||||
default:
|
||||
state = S2MPU02_ENABLE_SUSPEND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
set_bit(rdev_id, s2mps11->suspend_state);
|
||||
/*
|
||||
* Don't enable suspend mode if regulator is already disabled because
|
||||
* this would effectively for a short time turn on the regulator after
|
||||
* resuming.
|
||||
* However we still want to toggle the suspend_state bit for regulator
|
||||
* in case if it got enabled before suspending the system.
|
||||
*/
|
||||
if (!(val & rdev->desc->enable_mask))
|
||||
return 0;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
|
||||
rdev->desc->enable_mask, state);
|
||||
}
|
||||
|
||||
static const struct regulator_ops s2mps11_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.enable = s2mps11_regulator_enable,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops s2mps11_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.enable = s2mps11_regulator_enable,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = s2mps11_regulator_set_voltage_time_sel,
|
||||
.set_ramp_delay = s2mps11_set_ramp_delay,
|
||||
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
|
||||
};
|
||||
|
||||
#define regulator_desc_s2mps11_ldo(num, step) { \
|
||||
|
@ -507,101 +614,16 @@ static const struct regulator_desc s2mps13_regulators[] = {
|
|||
regulator_desc_s2mps13_buck8_10(10, MIN_500_MV, STEP_6_25_MV, 0x10),
|
||||
};
|
||||
|
||||
static int s2mps14_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
|
||||
unsigned int val;
|
||||
|
||||
switch (s2mps11->dev_type) {
|
||||
case S2MPS13X:
|
||||
case S2MPS14X:
|
||||
if (test_bit(rdev_get_id(rdev), s2mps11->suspend_state))
|
||||
val = S2MPS14_ENABLE_SUSPEND;
|
||||
else if (s2mps11->ext_control_gpiod[rdev_get_id(rdev)])
|
||||
val = S2MPS14_ENABLE_EXT_CONTROL;
|
||||
else
|
||||
val = rdev->desc->enable_mask;
|
||||
break;
|
||||
case S2MPU02:
|
||||
if (test_bit(rdev_get_id(rdev), s2mps11->suspend_state))
|
||||
val = S2MPU02_ENABLE_SUSPEND;
|
||||
else
|
||||
val = rdev->desc->enable_mask;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
|
||||
rdev->desc->enable_mask, val);
|
||||
}
|
||||
|
||||
static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
int ret;
|
||||
unsigned int val, state;
|
||||
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
|
||||
int rdev_id = rdev_get_id(rdev);
|
||||
|
||||
/* Below LDO should be always on or does not support suspend mode. */
|
||||
switch (s2mps11->dev_type) {
|
||||
case S2MPS13X:
|
||||
case S2MPS14X:
|
||||
switch (rdev_id) {
|
||||
case S2MPS14_LDO3:
|
||||
return 0;
|
||||
default:
|
||||
state = S2MPS14_ENABLE_SUSPEND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case S2MPU02:
|
||||
switch (rdev_id) {
|
||||
case S2MPU02_LDO13:
|
||||
case S2MPU02_LDO14:
|
||||
case S2MPU02_LDO15:
|
||||
case S2MPU02_LDO17:
|
||||
case S2MPU02_BUCK7:
|
||||
state = S2MPU02_DISABLE_SUSPEND;
|
||||
break;
|
||||
default:
|
||||
state = S2MPU02_ENABLE_SUSPEND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
set_bit(rdev_get_id(rdev), s2mps11->suspend_state);
|
||||
/*
|
||||
* Don't enable suspend mode if regulator is already disabled because
|
||||
* this would effectively for a short time turn on the regulator after
|
||||
* resuming.
|
||||
* However we still want to toggle the suspend_state bit for regulator
|
||||
* in case if it got enabled before suspending the system.
|
||||
*/
|
||||
if (!(val & rdev->desc->enable_mask))
|
||||
return 0;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
|
||||
rdev->desc->enable_mask, state);
|
||||
}
|
||||
|
||||
static const struct regulator_ops s2mps14_reg_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = s2mps14_regulator_enable,
|
||||
.enable = s2mps11_regulator_enable,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
.set_suspend_disable = s2mps14_regulator_set_suspend_disable,
|
||||
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
|
||||
};
|
||||
|
||||
#define regulator_desc_s2mps14_ldo(num, min, step) { \
|
||||
|
@ -828,7 +850,9 @@ static void s2mps14_pmic_dt_parse_ext_control_gpio(struct platform_device *pdev,
|
|||
0,
|
||||
GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
|
||||
"s2mps11-regulator");
|
||||
if (IS_ERR(gpio[reg])) {
|
||||
if (PTR_ERR(gpio[reg]) == -ENOENT)
|
||||
gpio[reg] = NULL;
|
||||
else if (IS_ERR(gpio[reg])) {
|
||||
dev_err(&pdev->dev, "Failed to get control GPIO for %d/%s\n",
|
||||
reg, rdata[reg].name);
|
||||
gpio[reg] = NULL;
|
||||
|
@ -864,8 +888,9 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev,
|
|||
static int s2mpu02_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
|
||||
{
|
||||
unsigned int ramp_val, ramp_shift, ramp_reg;
|
||||
int rdev_id = rdev_get_id(rdev);
|
||||
|
||||
switch (rdev_get_id(rdev)) {
|
||||
switch (rdev_id) {
|
||||
case S2MPU02_BUCK1:
|
||||
ramp_shift = S2MPU02_BUCK1_RAMP_SHIFT;
|
||||
break;
|
||||
|
@ -893,24 +918,24 @@ static const struct regulator_ops s2mpu02_ldo_ops = {
|
|||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = s2mps14_regulator_enable,
|
||||
.enable = s2mps11_regulator_enable,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
.set_suspend_disable = s2mps14_regulator_set_suspend_disable,
|
||||
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops s2mpu02_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = s2mps14_regulator_enable,
|
||||
.enable = s2mps11_regulator_enable,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
.set_suspend_disable = s2mps14_regulator_set_suspend_disable,
|
||||
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
|
||||
.set_ramp_delay = s2mpu02_set_ramp_delay,
|
||||
};
|
||||
|
||||
|
|
|
@ -574,7 +574,9 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
|
|||
0,
|
||||
GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
|
||||
"s5m8767");
|
||||
if (IS_ERR(rdata->ext_control_gpiod))
|
||||
if (PTR_ERR(rdata->ext_control_gpiod) == -ENOENT)
|
||||
rdata->ext_control_gpiod = NULL;
|
||||
else if (IS_ERR(rdata->ext_control_gpiod))
|
||||
return PTR_ERR(rdata->ext_control_gpiod);
|
||||
|
||||
rdata->id = i;
|
||||
|
|
523
drivers/regulator/slg51000-regulator.c
Normal file
523
drivers/regulator/slg51000-regulator.c
Normal file
|
@ -0,0 +1,523 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
//
|
||||
// SLG51000 High PSRR, Multi-Output Regulators
|
||||
// Copyright (C) 2019 Dialog Semiconductor
|
||||
//
|
||||
// Author: Eric Jeong <eric.jeong.opensource@diasemi.com>
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include "slg51000-regulator.h"
|
||||
|
||||
#define SLG51000_SCTL_EVT 7
|
||||
#define SLG51000_MAX_EVT_REGISTER 8
|
||||
#define SLG51000_LDOHP_LV_MIN 1200000
|
||||
#define SLG51000_LDOHP_HV_MIN 2400000
|
||||
|
||||
enum slg51000_regulators {
|
||||
SLG51000_REGULATOR_LDO1 = 0,
|
||||
SLG51000_REGULATOR_LDO2,
|
||||
SLG51000_REGULATOR_LDO3,
|
||||
SLG51000_REGULATOR_LDO4,
|
||||
SLG51000_REGULATOR_LDO5,
|
||||
SLG51000_REGULATOR_LDO6,
|
||||
SLG51000_REGULATOR_LDO7,
|
||||
SLG51000_MAX_REGULATORS,
|
||||
};
|
||||
|
||||
struct slg51000 {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct regulator_desc *rdesc[SLG51000_MAX_REGULATORS];
|
||||
struct regulator_dev *rdev[SLG51000_MAX_REGULATORS];
|
||||
struct gpio_desc *cs_gpiod;
|
||||
int chip_irq;
|
||||
};
|
||||
|
||||
struct slg51000_evt_sta {
|
||||
unsigned int ereg;
|
||||
unsigned int sreg;
|
||||
};
|
||||
|
||||
static const struct slg51000_evt_sta es_reg[SLG51000_MAX_EVT_REGISTER] = {
|
||||
{SLG51000_LDO1_EVENT, SLG51000_LDO1_STATUS},
|
||||
{SLG51000_LDO2_EVENT, SLG51000_LDO2_STATUS},
|
||||
{SLG51000_LDO3_EVENT, SLG51000_LDO3_STATUS},
|
||||
{SLG51000_LDO4_EVENT, SLG51000_LDO4_STATUS},
|
||||
{SLG51000_LDO5_EVENT, SLG51000_LDO5_STATUS},
|
||||
{SLG51000_LDO6_EVENT, SLG51000_LDO6_STATUS},
|
||||
{SLG51000_LDO7_EVENT, SLG51000_LDO7_STATUS},
|
||||
{SLG51000_SYSCTL_EVENT, SLG51000_SYSCTL_STATUS},
|
||||
};
|
||||
|
||||
static const struct regmap_range slg51000_writeable_ranges[] = {
|
||||
regmap_reg_range(SLG51000_SYSCTL_MATRIX_CONF_A,
|
||||
SLG51000_SYSCTL_MATRIX_CONF_A),
|
||||
regmap_reg_range(SLG51000_LDO1_VSEL, SLG51000_LDO1_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO1_MINV, SLG51000_LDO1_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO1_IRQ_MASK, SLG51000_LDO1_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO2_VSEL, SLG51000_LDO2_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO2_MINV, SLG51000_LDO2_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO2_IRQ_MASK, SLG51000_LDO2_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO3_VSEL, SLG51000_LDO3_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO3_MINV, SLG51000_LDO3_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO3_IRQ_MASK, SLG51000_LDO3_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO4_VSEL, SLG51000_LDO4_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO4_MINV, SLG51000_LDO4_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO4_IRQ_MASK, SLG51000_LDO4_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO5_VSEL, SLG51000_LDO5_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO5_MINV, SLG51000_LDO5_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO5_IRQ_MASK, SLG51000_LDO5_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO6_VSEL, SLG51000_LDO6_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO6_MINV, SLG51000_LDO6_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO6_IRQ_MASK, SLG51000_LDO6_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO7_VSEL, SLG51000_LDO7_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO7_MINV, SLG51000_LDO7_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO7_IRQ_MASK, SLG51000_LDO7_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_OTP_IRQ_MASK, SLG51000_OTP_IRQ_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_range slg51000_readable_ranges[] = {
|
||||
regmap_reg_range(SLG51000_SYSCTL_PATN_ID_B0,
|
||||
SLG51000_SYSCTL_PATN_ID_B2),
|
||||
regmap_reg_range(SLG51000_SYSCTL_SYS_CONF_A,
|
||||
SLG51000_SYSCTL_SYS_CONF_A),
|
||||
regmap_reg_range(SLG51000_SYSCTL_SYS_CONF_D,
|
||||
SLG51000_SYSCTL_MATRIX_CONF_B),
|
||||
regmap_reg_range(SLG51000_SYSCTL_REFGEN_CONF_C,
|
||||
SLG51000_SYSCTL_UVLO_CONF_A),
|
||||
regmap_reg_range(SLG51000_SYSCTL_FAULT_LOG1, SLG51000_SYSCTL_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_IO_GPIO1_CONF, SLG51000_IO_GPIO_STATUS),
|
||||
regmap_reg_range(SLG51000_LUTARRAY_LUT_VAL_0,
|
||||
SLG51000_LUTARRAY_LUT_VAL_11),
|
||||
regmap_reg_range(SLG51000_MUXARRAY_INPUT_SEL_0,
|
||||
SLG51000_MUXARRAY_INPUT_SEL_63),
|
||||
regmap_reg_range(SLG51000_PWRSEQ_RESOURCE_EN_0,
|
||||
SLG51000_PWRSEQ_INPUT_SENSE_CONF_B),
|
||||
regmap_reg_range(SLG51000_LDO1_VSEL, SLG51000_LDO1_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO1_MINV, SLG51000_LDO1_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO1_MISC1, SLG51000_LDO1_VSEL_ACTUAL),
|
||||
regmap_reg_range(SLG51000_LDO1_EVENT, SLG51000_LDO1_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO2_VSEL, SLG51000_LDO2_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO2_MINV, SLG51000_LDO2_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO2_MISC1, SLG51000_LDO2_VSEL_ACTUAL),
|
||||
regmap_reg_range(SLG51000_LDO2_EVENT, SLG51000_LDO2_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO3_VSEL, SLG51000_LDO3_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO3_MINV, SLG51000_LDO3_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO3_CONF1, SLG51000_LDO3_VSEL_ACTUAL),
|
||||
regmap_reg_range(SLG51000_LDO3_EVENT, SLG51000_LDO3_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO4_VSEL, SLG51000_LDO4_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO4_MINV, SLG51000_LDO4_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO4_CONF1, SLG51000_LDO4_VSEL_ACTUAL),
|
||||
regmap_reg_range(SLG51000_LDO4_EVENT, SLG51000_LDO4_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO5_VSEL, SLG51000_LDO5_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO5_MINV, SLG51000_LDO5_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO5_TRIM2, SLG51000_LDO5_TRIM2),
|
||||
regmap_reg_range(SLG51000_LDO5_CONF1, SLG51000_LDO5_VSEL_ACTUAL),
|
||||
regmap_reg_range(SLG51000_LDO5_EVENT, SLG51000_LDO5_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO6_VSEL, SLG51000_LDO6_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO6_MINV, SLG51000_LDO6_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO6_TRIM2, SLG51000_LDO6_TRIM2),
|
||||
regmap_reg_range(SLG51000_LDO6_CONF1, SLG51000_LDO6_VSEL_ACTUAL),
|
||||
regmap_reg_range(SLG51000_LDO6_EVENT, SLG51000_LDO6_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_LDO7_VSEL, SLG51000_LDO7_VSEL),
|
||||
regmap_reg_range(SLG51000_LDO7_MINV, SLG51000_LDO7_MAXV),
|
||||
regmap_reg_range(SLG51000_LDO7_CONF1, SLG51000_LDO7_VSEL_ACTUAL),
|
||||
regmap_reg_range(SLG51000_LDO7_EVENT, SLG51000_LDO7_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_OTP_EVENT, SLG51000_OTP_EVENT),
|
||||
regmap_reg_range(SLG51000_OTP_IRQ_MASK, SLG51000_OTP_IRQ_MASK),
|
||||
regmap_reg_range(SLG51000_OTP_LOCK_OTP_PROG, SLG51000_OTP_LOCK_CTRL),
|
||||
regmap_reg_range(SLG51000_LOCK_GLOBAL_LOCK_CTRL1,
|
||||
SLG51000_LOCK_GLOBAL_LOCK_CTRL1),
|
||||
};
|
||||
|
||||
static const struct regmap_range slg51000_volatile_ranges[] = {
|
||||
regmap_reg_range(SLG51000_SYSCTL_FAULT_LOG1, SLG51000_SYSCTL_STATUS),
|
||||
regmap_reg_range(SLG51000_IO_GPIO_STATUS, SLG51000_IO_GPIO_STATUS),
|
||||
regmap_reg_range(SLG51000_LDO1_EVENT, SLG51000_LDO1_STATUS),
|
||||
regmap_reg_range(SLG51000_LDO2_EVENT, SLG51000_LDO2_STATUS),
|
||||
regmap_reg_range(SLG51000_LDO3_EVENT, SLG51000_LDO3_STATUS),
|
||||
regmap_reg_range(SLG51000_LDO4_EVENT, SLG51000_LDO4_STATUS),
|
||||
regmap_reg_range(SLG51000_LDO5_EVENT, SLG51000_LDO5_STATUS),
|
||||
regmap_reg_range(SLG51000_LDO6_EVENT, SLG51000_LDO6_STATUS),
|
||||
regmap_reg_range(SLG51000_LDO7_EVENT, SLG51000_LDO7_STATUS),
|
||||
regmap_reg_range(SLG51000_OTP_EVENT, SLG51000_OTP_EVENT),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table slg51000_writeable_table = {
|
||||
.yes_ranges = slg51000_writeable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(slg51000_writeable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table slg51000_readable_table = {
|
||||
.yes_ranges = slg51000_readable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(slg51000_readable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table slg51000_volatile_table = {
|
||||
.yes_ranges = slg51000_volatile_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(slg51000_volatile_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config slg51000_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
.max_register = 0x8000,
|
||||
.wr_table = &slg51000_writeable_table,
|
||||
.rd_table = &slg51000_readable_table,
|
||||
.volatile_table = &slg51000_volatile_table,
|
||||
};
|
||||
|
||||
static const struct regulator_ops slg51000_regl_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,
|
||||
};
|
||||
|
||||
static const struct regulator_ops slg51000_switch_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static int slg51000_of_parse_cb(struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regulator_config *config)
|
||||
{
|
||||
struct slg51000 *chip = config->driver_data;
|
||||
struct gpio_desc *ena_gpiod;
|
||||
enum gpiod_flags gflags = GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE;
|
||||
|
||||
ena_gpiod = devm_gpiod_get_from_of_node(chip->dev, np,
|
||||
"enable-gpios", 0,
|
||||
gflags, "gpio-en-ldo");
|
||||
if (ena_gpiod) {
|
||||
config->ena_gpiod = ena_gpiod;
|
||||
devm_gpiod_unhinge(chip->dev, config->ena_gpiod);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SLG51000_REGL_DESC(_id, _name, _s_name, _min, _step) \
|
||||
[SLG51000_REGULATOR_##_id] = { \
|
||||
.name = #_name, \
|
||||
.supply_name = _s_name, \
|
||||
.id = SLG51000_REGULATOR_##_id, \
|
||||
.of_match = of_match_ptr(#_name), \
|
||||
.of_parse_cb = slg51000_of_parse_cb, \
|
||||
.ops = &slg51000_regl_ops, \
|
||||
.regulators_node = of_match_ptr("regulators"), \
|
||||
.n_voltages = 256, \
|
||||
.min_uV = _min, \
|
||||
.uV_step = _step, \
|
||||
.linear_min_sel = 0, \
|
||||
.vsel_mask = SLG51000_VSEL_MASK, \
|
||||
.vsel_reg = SLG51000_##_id##_VSEL, \
|
||||
.enable_reg = SLG51000_SYSCTL_MATRIX_CONF_A, \
|
||||
.enable_mask = BIT(SLG51000_REGULATOR_##_id), \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
static struct regulator_desc regls_desc[SLG51000_MAX_REGULATORS] = {
|
||||
SLG51000_REGL_DESC(LDO1, ldo1, NULL, 2400000, 5000),
|
||||
SLG51000_REGL_DESC(LDO2, ldo2, NULL, 2400000, 5000),
|
||||
SLG51000_REGL_DESC(LDO3, ldo3, "vin3", 1200000, 10000),
|
||||
SLG51000_REGL_DESC(LDO4, ldo4, "vin4", 1200000, 10000),
|
||||
SLG51000_REGL_DESC(LDO5, ldo5, "vin5", 400000, 5000),
|
||||
SLG51000_REGL_DESC(LDO6, ldo6, "vin6", 400000, 5000),
|
||||
SLG51000_REGL_DESC(LDO7, ldo7, "vin7", 1200000, 10000),
|
||||
};
|
||||
|
||||
static int slg51000_regulator_init(struct slg51000 *chip)
|
||||
{
|
||||
struct regulator_config config = { };
|
||||
struct regulator_desc *rdesc;
|
||||
unsigned int reg, val;
|
||||
u8 vsel_range[2];
|
||||
int id, ret = 0;
|
||||
const unsigned int min_regs[SLG51000_MAX_REGULATORS] = {
|
||||
SLG51000_LDO1_MINV, SLG51000_LDO2_MINV, SLG51000_LDO3_MINV,
|
||||
SLG51000_LDO4_MINV, SLG51000_LDO5_MINV, SLG51000_LDO6_MINV,
|
||||
SLG51000_LDO7_MINV,
|
||||
};
|
||||
|
||||
for (id = 0; id < SLG51000_MAX_REGULATORS; id++) {
|
||||
chip->rdesc[id] = ®ls_desc[id];
|
||||
rdesc = chip->rdesc[id];
|
||||
config.regmap = chip->regmap;
|
||||
config.dev = chip->dev;
|
||||
config.driver_data = chip;
|
||||
|
||||
ret = regmap_bulk_read(chip->regmap, min_regs[id],
|
||||
vsel_range, 2);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev,
|
||||
"Failed to read the MIN register\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case SLG51000_REGULATOR_LDO1:
|
||||
case SLG51000_REGULATOR_LDO2:
|
||||
if (id == SLG51000_REGULATOR_LDO1)
|
||||
reg = SLG51000_LDO1_MISC1;
|
||||
else
|
||||
reg = SLG51000_LDO2_MISC1;
|
||||
|
||||
ret = regmap_read(chip->regmap, reg, &val);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev,
|
||||
"Failed to read voltage range of ldo%d\n",
|
||||
id + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rdesc->linear_min_sel = vsel_range[0];
|
||||
rdesc->n_voltages = vsel_range[1] + 1;
|
||||
if (val & SLG51000_SEL_VRANGE_MASK)
|
||||
rdesc->min_uV = SLG51000_LDOHP_HV_MIN
|
||||
+ (vsel_range[0]
|
||||
* rdesc->uV_step);
|
||||
else
|
||||
rdesc->min_uV = SLG51000_LDOHP_LV_MIN
|
||||
+ (vsel_range[0]
|
||||
* rdesc->uV_step);
|
||||
break;
|
||||
|
||||
case SLG51000_REGULATOR_LDO5:
|
||||
case SLG51000_REGULATOR_LDO6:
|
||||
if (id == SLG51000_REGULATOR_LDO5)
|
||||
reg = SLG51000_LDO5_TRIM2;
|
||||
else
|
||||
reg = SLG51000_LDO6_TRIM2;
|
||||
|
||||
ret = regmap_read(chip->regmap, reg, &val);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev,
|
||||
"Failed to read LDO mode register\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (val & SLG51000_SEL_BYP_MODE_MASK) {
|
||||
rdesc->ops = &slg51000_switch_ops;
|
||||
rdesc->n_voltages = 0;
|
||||
rdesc->min_uV = 0;
|
||||
rdesc->uV_step = 0;
|
||||
rdesc->linear_min_sel = 0;
|
||||
break;
|
||||
}
|
||||
/* Fall through - to the check below.*/
|
||||
|
||||
default:
|
||||
rdesc->linear_min_sel = vsel_range[0];
|
||||
rdesc->n_voltages = vsel_range[1] + 1;
|
||||
rdesc->min_uV = rdesc->min_uV
|
||||
+ (vsel_range[0] * rdesc->uV_step);
|
||||
break;
|
||||
}
|
||||
|
||||
chip->rdev[id] = devm_regulator_register(chip->dev, rdesc,
|
||||
&config);
|
||||
if (IS_ERR(chip->rdev[id])) {
|
||||
ret = PTR_ERR(chip->rdev[id]);
|
||||
dev_err(chip->dev,
|
||||
"Failed to register regulator(%s):%d\n",
|
||||
chip->rdesc[id]->name, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t slg51000_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct slg51000 *chip = data;
|
||||
struct regmap *regmap = chip->regmap;
|
||||
enum { R0 = 0, R1, R2, REG_MAX };
|
||||
u8 evt[SLG51000_MAX_EVT_REGISTER][REG_MAX];
|
||||
int ret, i, handled = IRQ_NONE;
|
||||
unsigned int evt_otp, mask_otp;
|
||||
|
||||
/* Read event[R0], status[R1] and mask[R2] register */
|
||||
for (i = 0; i < SLG51000_MAX_EVT_REGISTER; i++) {
|
||||
ret = regmap_bulk_read(regmap, es_reg[i].ereg, evt[i], REG_MAX);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev,
|
||||
"Failed to read event registers(%d)\n", ret);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_read(regmap, SLG51000_OTP_EVENT, &evt_otp);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev,
|
||||
"Failed to read otp event registers(%d)\n", ret);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
ret = regmap_read(regmap, SLG51000_OTP_IRQ_MASK, &mask_otp);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev,
|
||||
"Failed to read otp mask register(%d)\n", ret);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if ((evt_otp & SLG51000_EVT_CRC_MASK) &&
|
||||
!(mask_otp & SLG51000_IRQ_CRC_MASK)) {
|
||||
dev_info(chip->dev,
|
||||
"OTP has been read or OTP crc is not zero\n");
|
||||
handled = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
for (i = 0; i < SLG51000_MAX_REGULATORS; i++) {
|
||||
if (!(evt[i][R2] & SLG51000_IRQ_ILIM_FLAG_MASK) &&
|
||||
(evt[i][R0] & SLG51000_EVT_ILIM_FLAG_MASK)) {
|
||||
regulator_lock(chip->rdev[i]);
|
||||
regulator_notifier_call_chain(chip->rdev[i],
|
||||
REGULATOR_EVENT_OVER_CURRENT, NULL);
|
||||
regulator_unlock(chip->rdev[i]);
|
||||
|
||||
if (evt[i][R1] & SLG51000_STA_ILIM_FLAG_MASK)
|
||||
dev_warn(chip->dev,
|
||||
"Over-current limit(ldo%d)\n", i + 1);
|
||||
handled = IRQ_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(evt[SLG51000_SCTL_EVT][R2] & SLG51000_IRQ_HIGH_TEMP_WARN_MASK) &&
|
||||
(evt[SLG51000_SCTL_EVT][R0] & SLG51000_EVT_HIGH_TEMP_WARN_MASK)) {
|
||||
for (i = 0; i < SLG51000_MAX_REGULATORS; i++) {
|
||||
if (!(evt[i][R1] & SLG51000_STA_ILIM_FLAG_MASK) &&
|
||||
(evt[i][R1] & SLG51000_STA_VOUT_OK_FLAG_MASK)) {
|
||||
regulator_lock(chip->rdev[i]);
|
||||
regulator_notifier_call_chain(chip->rdev[i],
|
||||
REGULATOR_EVENT_OVER_TEMP, NULL);
|
||||
regulator_unlock(chip->rdev[i]);
|
||||
}
|
||||
}
|
||||
handled = IRQ_HANDLED;
|
||||
if (evt[SLG51000_SCTL_EVT][R1] &
|
||||
SLG51000_STA_HIGH_TEMP_WARN_MASK)
|
||||
dev_warn(chip->dev, "High temperature warning!\n");
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
static void slg51000_clear_fault_log(struct slg51000 *chip)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
int ret = 0;
|
||||
|
||||
ret = regmap_read(chip->regmap, SLG51000_SYSCTL_FAULT_LOG1, &val);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "Failed to read Fault log register\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (val & SLG51000_FLT_OVER_TEMP_MASK)
|
||||
dev_dbg(chip->dev, "Fault log: FLT_OVER_TEMP\n");
|
||||
if (val & SLG51000_FLT_POWER_SEQ_CRASH_REQ_MASK)
|
||||
dev_dbg(chip->dev, "Fault log: FLT_POWER_SEQ_CRASH_REQ\n");
|
||||
if (val & SLG51000_FLT_RST_MASK)
|
||||
dev_dbg(chip->dev, "Fault log: FLT_RST\n");
|
||||
if (val & SLG51000_FLT_POR_MASK)
|
||||
dev_dbg(chip->dev, "Fault log: FLT_POR\n");
|
||||
}
|
||||
|
||||
static int slg51000_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct slg51000 *chip;
|
||||
struct gpio_desc *cs_gpiod = NULL;
|
||||
int error, ret;
|
||||
|
||||
chip = devm_kzalloc(dev, sizeof(struct slg51000), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
cs_gpiod = devm_gpiod_get_from_of_node(dev, dev->of_node,
|
||||
"dlg,cs-gpios", 0,
|
||||
GPIOD_OUT_HIGH
|
||||
| GPIOD_FLAGS_BIT_NONEXCLUSIVE,
|
||||
"slg51000-cs");
|
||||
if (cs_gpiod) {
|
||||
dev_info(dev, "Found chip selector property\n");
|
||||
chip->cs_gpiod = cs_gpiod;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, chip);
|
||||
chip->chip_irq = client->irq;
|
||||
chip->dev = dev;
|
||||
chip->regmap = devm_regmap_init_i2c(client, &slg51000_regmap_config);
|
||||
if (IS_ERR(chip->regmap)) {
|
||||
error = PTR_ERR(chip->regmap);
|
||||
dev_err(dev, "Failed to allocate register map: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
||||
ret = slg51000_regulator_init(chip);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "Failed to init regulator(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
slg51000_clear_fault_log(chip);
|
||||
|
||||
if (chip->chip_irq) {
|
||||
ret = devm_request_threaded_irq(dev, chip->chip_irq, NULL,
|
||||
slg51000_irq_handler,
|
||||
(IRQF_TRIGGER_HIGH |
|
||||
IRQF_ONESHOT),
|
||||
"slg51000-irq", chip);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "Failed to request IRQ: %d\n",
|
||||
chip->chip_irq);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
dev_info(dev, "No IRQ configured\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id slg51000_i2c_id[] = {
|
||||
{"slg51000", 0},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, slg51000_i2c_id);
|
||||
|
||||
static struct i2c_driver slg51000_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "slg51000-regulator",
|
||||
},
|
||||
.probe = slg51000_i2c_probe,
|
||||
.id_table = slg51000_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(slg51000_regulator_driver);
|
||||
|
||||
MODULE_AUTHOR("Eric Jeong <eric.jeong.opensource@diasemi.com>");
|
||||
MODULE_DESCRIPTION("SLG51000 regulator driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
505
drivers/regulator/slg51000-regulator.h
Normal file
505
drivers/regulator/slg51000-regulator.h
Normal file
|
@ -0,0 +1,505 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* SLG51000 High PSRR, Multi-Output Regulators
|
||||
* Copyright (C) 2019 Dialog Semiconductor
|
||||
*
|
||||
* Author: Eric Jeong <eric.jeong.opensource@diasemi.com>
|
||||
*/
|
||||
|
||||
#ifndef __SLG51000_REGISTERS_H__
|
||||
#define __SLG51000_REGISTERS_H__
|
||||
|
||||
/* Registers */
|
||||
|
||||
#define SLG51000_SYSCTL_PATN_ID_B0 0x1105
|
||||
#define SLG51000_SYSCTL_PATN_ID_B1 0x1106
|
||||
#define SLG51000_SYSCTL_PATN_ID_B2 0x1107
|
||||
#define SLG51000_SYSCTL_SYS_CONF_A 0x1109
|
||||
#define SLG51000_SYSCTL_SYS_CONF_D 0x110c
|
||||
#define SLG51000_SYSCTL_MATRIX_CONF_A 0x110d
|
||||
#define SLG51000_SYSCTL_MATRIX_CONF_B 0x110e
|
||||
#define SLG51000_SYSCTL_REFGEN_CONF_C 0x1111
|
||||
#define SLG51000_SYSCTL_UVLO_CONF_A 0x1112
|
||||
#define SLG51000_SYSCTL_FAULT_LOG1 0x1115
|
||||
#define SLG51000_SYSCTL_EVENT 0x1116
|
||||
#define SLG51000_SYSCTL_STATUS 0x1117
|
||||
#define SLG51000_SYSCTL_IRQ_MASK 0x1118
|
||||
#define SLG51000_IO_GPIO1_CONF 0x1500
|
||||
#define SLG51000_IO_GPIO2_CONF 0x1501
|
||||
#define SLG51000_IO_GPIO3_CONF 0x1502
|
||||
#define SLG51000_IO_GPIO4_CONF 0x1503
|
||||
#define SLG51000_IO_GPIO5_CONF 0x1504
|
||||
#define SLG51000_IO_GPIO6_CONF 0x1505
|
||||
#define SLG51000_IO_GPIO_STATUS 0x1506
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_0 0x1600
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_1 0x1601
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_2 0x1602
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_3 0x1603
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_4 0x1604
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_5 0x1605
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_6 0x1606
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_7 0x1607
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_8 0x1608
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_9 0x1609
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_10 0x160a
|
||||
#define SLG51000_LUTARRAY_LUT_VAL_11 0x160b
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_0 0x1700
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_1 0x1701
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_2 0x1702
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_3 0x1703
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_4 0x1704
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_5 0x1705
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_6 0x1706
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_7 0x1707
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_8 0x1708
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_9 0x1709
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_10 0x170a
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_11 0x170b
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_12 0x170c
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_13 0x170d
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_14 0x170e
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_15 0x170f
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_16 0x1710
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_17 0x1711
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_18 0x1712
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_19 0x1713
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_20 0x1714
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_21 0x1715
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_22 0x1716
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_23 0x1717
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_24 0x1718
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_25 0x1719
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_26 0x171a
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_27 0x171b
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_28 0x171c
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_29 0x171d
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_30 0x171e
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_31 0x171f
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_32 0x1720
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_33 0x1721
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_34 0x1722
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_35 0x1723
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_36 0x1724
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_37 0x1725
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_38 0x1726
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_39 0x1727
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_40 0x1728
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_41 0x1729
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_42 0x172a
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_43 0x172b
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_44 0x172c
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_45 0x172d
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_46 0x172e
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_47 0x172f
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_48 0x1730
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_49 0x1731
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_50 0x1732
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_51 0x1733
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_52 0x1734
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_53 0x1735
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_54 0x1736
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_55 0x1737
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_56 0x1738
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_57 0x1739
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_58 0x173a
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_59 0x173b
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_60 0x173c
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_61 0x173d
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_62 0x173e
|
||||
#define SLG51000_MUXARRAY_INPUT_SEL_63 0x173f
|
||||
#define SLG51000_PWRSEQ_RESOURCE_EN_0 0x1900
|
||||
#define SLG51000_PWRSEQ_RESOURCE_EN_1 0x1901
|
||||
#define SLG51000_PWRSEQ_RESOURCE_EN_2 0x1902
|
||||
#define SLG51000_PWRSEQ_RESOURCE_EN_3 0x1903
|
||||
#define SLG51000_PWRSEQ_RESOURCE_EN_4 0x1904
|
||||
#define SLG51000_PWRSEQ_RESOURCE_EN_5 0x1905
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_UP0 0x1906
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_DOWN0 0x1907
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_UP1 0x1908
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_DOWN1 0x1909
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_UP2 0x190a
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_DOWN2 0x190b
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_UP3 0x190c
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_DOWN3 0x190d
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_UP4 0x190e
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_DOWN4 0x190f
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_UP5 0x1910
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MIN_DOWN5 0x1911
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MAX_CONF_A 0x1912
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MAX_CONF_B 0x1913
|
||||
#define SLG51000_PWRSEQ_SLOT_TIME_MAX_CONF_C 0x1914
|
||||
#define SLG51000_PWRSEQ_INPUT_SENSE_CONF_A 0x1915
|
||||
#define SLG51000_PWRSEQ_INPUT_SENSE_CONF_B 0x1916
|
||||
#define SLG51000_LDO1_VSEL 0x2000
|
||||
#define SLG51000_LDO1_MINV 0x2060
|
||||
#define SLG51000_LDO1_MAXV 0x2061
|
||||
#define SLG51000_LDO1_MISC1 0x2064
|
||||
#define SLG51000_LDO1_VSEL_ACTUAL 0x2065
|
||||
#define SLG51000_LDO1_EVENT 0x20c0
|
||||
#define SLG51000_LDO1_STATUS 0x20c1
|
||||
#define SLG51000_LDO1_IRQ_MASK 0x20c2
|
||||
#define SLG51000_LDO2_VSEL 0x2200
|
||||
#define SLG51000_LDO2_MINV 0x2260
|
||||
#define SLG51000_LDO2_MAXV 0x2261
|
||||
#define SLG51000_LDO2_MISC1 0x2264
|
||||
#define SLG51000_LDO2_VSEL_ACTUAL 0x2265
|
||||
#define SLG51000_LDO2_EVENT 0x22c0
|
||||
#define SLG51000_LDO2_STATUS 0x22c1
|
||||
#define SLG51000_LDO2_IRQ_MASK 0x22c2
|
||||
#define SLG51000_LDO3_VSEL 0x2300
|
||||
#define SLG51000_LDO3_MINV 0x2360
|
||||
#define SLG51000_LDO3_MAXV 0x2361
|
||||
#define SLG51000_LDO3_CONF1 0x2364
|
||||
#define SLG51000_LDO3_CONF2 0x2365
|
||||
#define SLG51000_LDO3_VSEL_ACTUAL 0x2366
|
||||
#define SLG51000_LDO3_EVENT 0x23c0
|
||||
#define SLG51000_LDO3_STATUS 0x23c1
|
||||
#define SLG51000_LDO3_IRQ_MASK 0x23c2
|
||||
#define SLG51000_LDO4_VSEL 0x2500
|
||||
#define SLG51000_LDO4_MINV 0x2560
|
||||
#define SLG51000_LDO4_MAXV 0x2561
|
||||
#define SLG51000_LDO4_CONF1 0x2564
|
||||
#define SLG51000_LDO4_CONF2 0x2565
|
||||
#define SLG51000_LDO4_VSEL_ACTUAL 0x2566
|
||||
#define SLG51000_LDO4_EVENT 0x25c0
|
||||
#define SLG51000_LDO4_STATUS 0x25c1
|
||||
#define SLG51000_LDO4_IRQ_MASK 0x25c2
|
||||
#define SLG51000_LDO5_VSEL 0x2700
|
||||
#define SLG51000_LDO5_MINV 0x2760
|
||||
#define SLG51000_LDO5_MAXV 0x2761
|
||||
#define SLG51000_LDO5_TRIM2 0x2763
|
||||
#define SLG51000_LDO5_CONF1 0x2765
|
||||
#define SLG51000_LDO5_CONF2 0x2766
|
||||
#define SLG51000_LDO5_VSEL_ACTUAL 0x2767
|
||||
#define SLG51000_LDO5_EVENT 0x27c0
|
||||
#define SLG51000_LDO5_STATUS 0x27c1
|
||||
#define SLG51000_LDO5_IRQ_MASK 0x27c2
|
||||
#define SLG51000_LDO6_VSEL 0x2900
|
||||
#define SLG51000_LDO6_MINV 0x2960
|
||||
#define SLG51000_LDO6_MAXV 0x2961
|
||||
#define SLG51000_LDO6_TRIM2 0x2963
|
||||
#define SLG51000_LDO6_CONF1 0x2965
|
||||
#define SLG51000_LDO6_CONF2 0x2966
|
||||
#define SLG51000_LDO6_VSEL_ACTUAL 0x2967
|
||||
#define SLG51000_LDO6_EVENT 0x29c0
|
||||
#define SLG51000_LDO6_STATUS 0x29c1
|
||||
#define SLG51000_LDO6_IRQ_MASK 0x29c2
|
||||
#define SLG51000_LDO7_VSEL 0x3100
|
||||
#define SLG51000_LDO7_MINV 0x3160
|
||||
#define SLG51000_LDO7_MAXV 0x3161
|
||||
#define SLG51000_LDO7_CONF1 0x3164
|
||||
#define SLG51000_LDO7_CONF2 0x3165
|
||||
#define SLG51000_LDO7_VSEL_ACTUAL 0x3166
|
||||
#define SLG51000_LDO7_EVENT 0x31c0
|
||||
#define SLG51000_LDO7_STATUS 0x31c1
|
||||
#define SLG51000_LDO7_IRQ_MASK 0x31c2
|
||||
#define SLG51000_OTP_EVENT 0x782b
|
||||
#define SLG51000_OTP_IRQ_MASK 0x782d
|
||||
#define SLG51000_OTP_LOCK_OTP_PROG 0x78fe
|
||||
#define SLG51000_OTP_LOCK_CTRL 0x78ff
|
||||
#define SLG51000_LOCK_GLOBAL_LOCK_CTRL1 0x8000
|
||||
|
||||
/* Register Bit Fields */
|
||||
|
||||
/* SLG51000_SYSCTL_PATTERN_ID_BYTE0 = 0x1105 */
|
||||
#define SLG51000_PATTERN_ID_BYTE0_SHIFT 0
|
||||
#define SLG51000_PATTERN_ID_BYTE0_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_SYSCTL_PATTERN_ID_BYTE1 = 0x1106 */
|
||||
#define SLG51000_PATTERN_ID_BYTE1_SHIFT 0
|
||||
#define SLG51000_PATTERN_ID_BYTE1_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_SYSCTL_PATTERN_ID_BYTE2 = 0x1107 */
|
||||
#define SLG51000_PATTERN_ID_BYTE2_SHIFT 0
|
||||
#define SLG51000_PATTERN_ID_BYTE2_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_SYSCTL_SYS_CONF_A = 0x1109 */
|
||||
#define SLG51000_I2C_ADDRESS_SHIFT 0
|
||||
#define SLG51000_I2C_ADDRESS_MASK (0x7f << 0)
|
||||
#define SLG51000_I2C_DISABLE_SHIFT 7
|
||||
#define SLG51000_I2C_DISABLE_MASK (0x01 << 7)
|
||||
|
||||
/* SLG51000_SYSCTL_SYS_CONF_D = 0x110c */
|
||||
#define SLG51000_CS_T_DEB_SHIFT 6
|
||||
#define SLG51000_CS_T_DEB_MASK (0x03 << 6)
|
||||
#define SLG51000_I2C_CLR_MODE_SHIFT 5
|
||||
#define SLG51000_I2C_CLR_MODE_MASK (0x01 << 5)
|
||||
|
||||
/* SLG51000_SYSCTL_MATRIX_CTRL_CONF_A = 0x110d */
|
||||
#define SLG51000_RESOURCE_CTRL_SHIFT 0
|
||||
#define SLG51000_RESOURCE_CTRL_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_SYSCTL_MATRIX_CTRL_CONF_B = 0x110e */
|
||||
#define SLG51000_MATRIX_EVENT_SENSE_SHIFT 0
|
||||
#define SLG51000_MATRIX_EVENT_SENSE_MASK (0x07 << 0)
|
||||
|
||||
/* SLG51000_SYSCTL_REFGEN_CONF_C = 0x1111 */
|
||||
#define SLG51000_REFGEN_SEL_TEMP_WARN_DEBOUNCE_SHIFT 2
|
||||
#define SLG51000_REFGEN_SEL_TEMP_WARN_DEBOUNCE_MASK (0x03 << 2)
|
||||
#define SLG51000_REFGEN_SEL_TEMP_WARN_THR_SHIFT 0
|
||||
#define SLG51000_REFGEN_SEL_TEMP_WARN_THR_MASK (0x03 << 0)
|
||||
|
||||
/* SLG51000_SYSCTL_UVLO_CONF_A = 0x1112 */
|
||||
#define SLG51000_VMON_UVLO_SEL_THR_SHIFT 0
|
||||
#define SLG51000_VMON_UVLO_SEL_THR_MASK (0x1f << 0)
|
||||
|
||||
/* SLG51000_SYSCTL_FAULT_LOG1 = 0x1115 */
|
||||
#define SLG51000_FLT_POR_SHIFT 5
|
||||
#define SLG51000_FLT_POR_MASK (0x01 << 5)
|
||||
#define SLG51000_FLT_RST_SHIFT 4
|
||||
#define SLG51000_FLT_RST_MASK (0x01 << 4)
|
||||
#define SLG51000_FLT_POWER_SEQ_CRASH_REQ_SHIFT 2
|
||||
#define SLG51000_FLT_POWER_SEQ_CRASH_REQ_MASK (0x01 << 2)
|
||||
#define SLG51000_FLT_OVER_TEMP_SHIFT 1
|
||||
#define SLG51000_FLT_OVER_TEMP_MASK (0x01 << 1)
|
||||
|
||||
/* SLG51000_SYSCTL_EVENT = 0x1116 */
|
||||
#define SLG51000_EVT_MATRIX_SHIFT 1
|
||||
#define SLG51000_EVT_MATRIX_MASK (0x01 << 1)
|
||||
#define SLG51000_EVT_HIGH_TEMP_WARN_SHIFT 0
|
||||
#define SLG51000_EVT_HIGH_TEMP_WARN_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_SYSCTL_STATUS = 0x1117 */
|
||||
#define SLG51000_STA_MATRIX_SHIFT 1
|
||||
#define SLG51000_STA_MATRIX_MASK (0x01 << 1)
|
||||
#define SLG51000_STA_HIGH_TEMP_WARN_SHIFT 0
|
||||
#define SLG51000_STA_HIGH_TEMP_WARN_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_SYSCTL_IRQ_MASK = 0x1118 */
|
||||
#define SLG51000_IRQ_MATRIX_SHIFT 1
|
||||
#define SLG51000_IRQ_MATRIX_MASK (0x01 << 1)
|
||||
#define SLG51000_IRQ_HIGH_TEMP_WARN_SHIFT 0
|
||||
#define SLG51000_IRQ_HIGH_TEMP_WARN_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_IO_GPIO1_CONF ~ SLG51000_IO_GPIO5_CONF =
|
||||
* 0x1500, 0x1501, 0x1502, 0x1503, 0x1504
|
||||
*/
|
||||
#define SLG51000_GPIO_DIR_SHIFT 7
|
||||
#define SLG51000_GPIO_DIR_MASK (0x01 << 7)
|
||||
#define SLG51000_GPIO_SENS_SHIFT 5
|
||||
#define SLG51000_GPIO_SENS_MASK (0x03 << 5)
|
||||
#define SLG51000_GPIO_INVERT_SHIFT 4
|
||||
#define SLG51000_GPIO_INVERT_MASK (0x01 << 4)
|
||||
#define SLG51000_GPIO_BYP_SHIFT 3
|
||||
#define SLG51000_GPIO_BYP_MASK (0x01 << 3)
|
||||
#define SLG51000_GPIO_T_DEB_SHIFT 1
|
||||
#define SLG51000_GPIO_T_DEB_MASK (0x03 << 1)
|
||||
#define SLG51000_GPIO_LEVEL_SHIFT 0
|
||||
#define SLG51000_GPIO_LEVEL_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_IO_GPIO6_CONF = 0x1505 */
|
||||
#define SLG51000_GPIO6_SENS_SHIFT 5
|
||||
#define SLG51000_GPIO6_SENS_MASK (0x03 << 5)
|
||||
#define SLG51000_GPIO6_INVERT_SHIFT 4
|
||||
#define SLG51000_GPIO6_INVERT_MASK (0x01 << 4)
|
||||
#define SLG51000_GPIO6_T_DEB_SHIFT 1
|
||||
#define SLG51000_GPIO6_T_DEB_MASK (0x03 << 1)
|
||||
#define SLG51000_GPIO6_LEVEL_SHIFT 0
|
||||
#define SLG51000_GPIO6_LEVEL_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_IO_GPIO_STATUS = 0x1506 */
|
||||
#define SLG51000_GPIO6_STATUS_SHIFT 5
|
||||
#define SLG51000_GPIO6_STATUS_MASK (0x01 << 5)
|
||||
#define SLG51000_GPIO5_STATUS_SHIFT 4
|
||||
#define SLG51000_GPIO5_STATUS_MASK (0x01 << 4)
|
||||
#define SLG51000_GPIO4_STATUS_SHIFT 3
|
||||
#define SLG51000_GPIO4_STATUS_MASK (0x01 << 3)
|
||||
#define SLG51000_GPIO3_STATUS_SHIFT 2
|
||||
#define SLG51000_GPIO3_STATUS_MASK (0x01 << 2)
|
||||
#define SLG51000_GPIO2_STATUS_SHIFT 1
|
||||
#define SLG51000_GPIO2_STATUS_MASK (0x01 << 1)
|
||||
#define SLG51000_GPIO1_STATUS_SHIFT 0
|
||||
#define SLG51000_GPIO1_STATUS_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_LUTARRAY_LUT_VAL_0 ~ SLG51000_LUTARRAY_LUT_VAL_11
|
||||
* 0x1600, 0x1601, 0x1602, 0x1603, 0x1604, 0x1605,
|
||||
* 0x1606, 0x1607, 0x1608, 0x1609, 0x160a, 0x160b
|
||||
*/
|
||||
#define SLG51000_LUT_VAL_SHIFT 0
|
||||
#define SLG51000_LUT_VAL_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_MUXARRAY_INPUT_SEL_0 ~ SLG51000_MUXARRAY_INPUT_SEL_63
|
||||
* 0x1700, 0x1701, 0x1702, 0x1703, 0x1704, 0x1705,
|
||||
* 0x1706, 0x1707, 0x1708, 0x1709, 0x170a, 0x170b,
|
||||
* 0x170c, 0x170d, 0x170e, 0x170f, 0x1710, 0x1711,
|
||||
* 0x1712, 0x1713, 0x1714, 0x1715, 0x1716, 0x1717,
|
||||
* 0x1718, 0x1719, 0x171a, 0x171b, 0x171c, 0x171d,
|
||||
* 0x171e, 0x171f, 0x1720, 0x1721, 0x1722, 0x1723,
|
||||
* 0x1724, 0x1725, 0x1726, 0x1727, 0x1728, 0x1729,
|
||||
* 0x173a, 0x173b, 0x173c, 0x173d, 0x173e, 0x173f,
|
||||
*/
|
||||
#define SLG51000_INPUT_SEL_SHIFT 0
|
||||
#define SLG51000_INPUT_SEL_MASK (0x3f << 0)
|
||||
|
||||
/* SLG51000_PWRSEQ_RESOURCE_EN_0 ~ SLG51000_PWRSEQ_RESOURCE_EN_5
|
||||
* 0x1900, 0x1901, 0x1902, 0x1903, 0x1904, 0x1905
|
||||
*/
|
||||
#define SLG51000_RESOURCE_EN_DOWN0_SHIFT 4
|
||||
#define SLG51000_RESOURCE_EN_DOWN0_MASK (0x07 << 4)
|
||||
#define SLG51000_RESOURCE_EN_UP0_SHIFT 0
|
||||
#define SLG51000_RESOURCE_EN_UP0_MASK (0x07 << 0)
|
||||
|
||||
/* SLG51000_PWRSEQ_SLOT_TIME_MIN_UP0 ~ SLG51000_PWRSEQ_SLOT_TIME_MIN_UP5
|
||||
* 0x1906, 0x1908, 0x190a, 0x190c, 0x190e, 0x1910
|
||||
*/
|
||||
#define SLG51000_SLOT_TIME_MIN_UP_SHIFT 0
|
||||
#define SLG51000_SLOT_TIME_MIN_UP_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_PWRSEQ_SLOT_TIME_MIN_DOWN0 ~ SLG51000_PWRSEQ_SLOT_TIME_MIN_DOWN5
|
||||
* 0x1907, 0x1909, 0x190b, 0x190d, 0x190f, 0x1911
|
||||
*/
|
||||
#define SLG51000_SLOT_TIME_MIN_DOWN_SHIFT 0
|
||||
#define SLG51000_SLOT_TIME_MIN_DOWN_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_PWRSEQ_SLOT_TIME_MAX_CONF_A ~ SLG51000_PWRSEQ_SLOT_TIME_MAX_CONF_C
|
||||
* 0x1912, 0x1913, 0x1914
|
||||
*/
|
||||
#define SLG51000_SLOT_TIME_MAX_DOWN1_SHIFT 6
|
||||
#define SLG51000_SLOT_TIME_MAX_DOWN1_MASK (0x03 << 6)
|
||||
#define SLG51000_SLOT_TIME_MAX_UP1_SHIFT 4
|
||||
#define SLG51000_SLOT_TIME_MAX_UP1_MASK (0x03 << 4)
|
||||
#define SLG51000_SLOT_TIME_MAX_DOWN0_SHIFT 2
|
||||
#define SLG51000_SLOT_TIME_MAX_DOWN0_MASK (0x03 << 2)
|
||||
#define SLG51000_SLOT_TIME_MAX_UP0_SHIFT 0
|
||||
#define SLG51000_SLOT_TIME_MAX_UP0_MASK (0x03 << 0)
|
||||
|
||||
/* SLG51000_PWRSEQ_INPUT_SENSE_CONF_A = 0x1915 */
|
||||
#define SLG51000_TRIG_UP_SENSE_SHIFT 6
|
||||
#define SLG51000_TRIG_UP_SENSE_MASK (0x01 << 6)
|
||||
#define SLG51000_UP_EN_SENSE5_SHIFT 5
|
||||
#define SLG51000_UP_EN_SENSE5_MASK (0x01 << 5)
|
||||
#define SLG51000_UP_EN_SENSE4_SHIFT 4
|
||||
#define SLG51000_UP_EN_SENSE4_MASK (0x01 << 4)
|
||||
#define SLG51000_UP_EN_SENSE3_SHIFT 3
|
||||
#define SLG51000_UP_EN_SENSE3_MASK (0x01 << 3)
|
||||
#define SLG51000_UP_EN_SENSE2_SHIFT 2
|
||||
#define SLG51000_UP_EN_SENSE2_MASK (0x01 << 2)
|
||||
#define SLG51000_UP_EN_SENSE1_SHIFT 1
|
||||
#define SLG51000_UP_EN_SENSE1_MASK (0x01 << 1)
|
||||
#define SLG51000_UP_EN_SENSE0_SHIFT 0
|
||||
#define SLG51000_UP_EN_SENSE0_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_PWRSEQ_INPUT_SENSE_CONF_B = 0x1916 */
|
||||
#define SLG51000_CRASH_DETECT_SENSE_SHIFT 7
|
||||
#define SLG51000_CRASH_DETECT_SENSE_MASK (0x01 << 7)
|
||||
#define SLG51000_TRIG_DOWN_SENSE_SHIFT 6
|
||||
#define SLG51000_TRIG_DOWN_SENSE_MASK (0x01 << 6)
|
||||
#define SLG51000_DOWN_EN_SENSE5_SHIFT 5
|
||||
#define SLG51000_DOWN_EN_SENSE5_MASK (0x01 << 5)
|
||||
#define SLG51000_DOWN_EN_SENSE4_SHIFT 4
|
||||
#define SLG51000_DOWN_EN_SENSE4_MASK (0x01 << 4)
|
||||
#define SLG51000_DOWN_EN_SENSE3_SHIFT 3
|
||||
#define SLG51000_DOWN_EN_SENSE3_MASK (0x01 << 3)
|
||||
#define SLG51000_DOWN_EN_SENSE2_SHIFT 2
|
||||
#define SLG51000_DOWN_EN_SENSE2_MASK (0x01 << 2)
|
||||
#define SLG51000_DOWN_EN_SENSE1_SHIFT 1
|
||||
#define SLG51000_DOWN_EN_SENSE1_MASK (0x01 << 1)
|
||||
#define SLG51000_DOWN_EN_SENSE0_SHIFT 0
|
||||
#define SLG51000_DOWN_EN_SENSE0_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_LDO1_VSEL ~ SLG51000_LDO7_VSEL =
|
||||
* 0x2000, 0x2200, 0x2300, 0x2500, 0x2700, 0x2900, 0x3100
|
||||
*/
|
||||
#define SLG51000_VSEL_SHIFT 0
|
||||
#define SLG51000_VSEL_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_LDO1_MINV ~ SLG51000_LDO7_MINV =
|
||||
* 0x2060, 0x2260, 0x2360, 0x2560, 0x2760, 0x2960, 0x3160
|
||||
*/
|
||||
#define SLG51000_MINV_SHIFT 0
|
||||
#define SLG51000_MINV_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_LDO1_MAXV ~ SLG51000_LDO7_MAXV =
|
||||
* 0x2061, 0x2261, 0x2361, 0x2561, 0x2761, 0x2961, 0x3161
|
||||
*/
|
||||
#define SLG51000_MAXV_SHIFT 0
|
||||
#define SLG51000_MAXV_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_LDO1_MISC1 = 0x2064, SLG51000_LDO2_MISC1 = 0x2264 */
|
||||
#define SLG51000_SEL_VRANGE_SHIFT 0
|
||||
#define SLG51000_SEL_VRANGE_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_LDO1_VSEL_ACTUAL ~ SLG51000_LDO7_VSEL_ACTUAL =
|
||||
* 0x2065, 0x2265, 0x2366, 0x2566, 0x2767, 0x2967, 0x3166
|
||||
*/
|
||||
#define SLG51000_VSEL_ACTUAL_SHIFT 0
|
||||
#define SLG51000_VSEL_ACTUAL_MASK (0xff << 0)
|
||||
|
||||
/* SLG51000_LDO1_EVENT ~ SLG51000_LDO7_EVENT =
|
||||
* 0x20c0, 0x22c0, 0x23c0, 0x25c0, 0x27c0, 0x29c0, 0x31c0
|
||||
*/
|
||||
#define SLG51000_EVT_ILIM_FLAG_SHIFT 0
|
||||
#define SLG51000_EVT_ILIM_FLAG_MASK (0x01 << 0)
|
||||
#define SLG51000_EVT_VOUT_OK_FLAG_SHIFT 1
|
||||
#define SLG51000_EVT_VOUT_OK_FLAG_MASK (0x01 << 1)
|
||||
|
||||
/* SLG51000_LDO1_STATUS ~ SLG51000_LDO7_STATUS =
|
||||
* 0x20c1, 0x22c1, 0x23c1, 0x25c1, 0x27c1, 0x29c1, 0x31c1
|
||||
*/
|
||||
#define SLG51000_STA_ILIM_FLAG_SHIFT 0
|
||||
#define SLG51000_STA_ILIM_FLAG_MASK (0x01 << 0)
|
||||
#define SLG51000_STA_VOUT_OK_FLAG_SHIFT 1
|
||||
#define SLG51000_STA_VOUT_OK_FLAG_MASK (0x01 << 1)
|
||||
|
||||
/* SLG51000_LDO1_IRQ_MASK ~ SLG51000_LDO7_IRQ_MASK =
|
||||
* 0x20c2, 0x22c2, 0x23c2, 0x25c2, 0x27c2, 0x29c2, 0x31c2
|
||||
*/
|
||||
#define SLG51000_IRQ_ILIM_FLAG_SHIFT 0
|
||||
#define SLG51000_IRQ_ILIM_FLAG_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_LDO3_CONF1 ~ SLG51000_LDO7_CONF1 =
|
||||
* 0x2364, 0x2564, 0x2765, 0x2965, 0x3164
|
||||
*/
|
||||
#define SLG51000_SEL_START_ILIM_SHIFT 0
|
||||
#define SLG51000_SEL_START_ILIM_MASK (0x7f << 0)
|
||||
|
||||
/* SLG51000_LDO3_CONF2 ~ SLG51000_LDO7_CONF2 =
|
||||
* 0x2365, 0x2565, 0x2766, 0x2966, 0x3165
|
||||
*/
|
||||
#define SLG51000_SEL_FUNC_ILIM_SHIFT 0
|
||||
#define SLG51000_SEL_FUNC_ILIM_MASK (0x7f << 0)
|
||||
|
||||
/* SLG51000_LDO5_TRIM2 = 0x2763, SLG51000_LDO6_TRIM2 = 0x2963 */
|
||||
#define SLG51000_SEL_BYP_SLEW_RATE_SHIFT 2
|
||||
#define SLG51000_SEL_BYP_SLEW_RATE_MASK (0x03 << 2)
|
||||
#define SLG51000_SEL_BYP_VGATE_SHIFT 1
|
||||
#define SLG51000_SEL_BYP_VGATE_MASK (0x01 << 1)
|
||||
#define SLG51000_SEL_BYP_MODE_SHIFT 0
|
||||
#define SLG51000_SEL_BYP_MODE_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_OTP_EVENT = 0x782b */
|
||||
#define SLG51000_EVT_CRC_SHIFT 0
|
||||
#define SLG51000_EVT_CRC_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_OTP_IRQ_MASK = 0x782d */
|
||||
#define SLG51000_IRQ_CRC_SHIFT 0
|
||||
#define SLG51000_IRQ_CRC_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_OTP_LOCK_OTP_PROG = 0x78fe */
|
||||
#define SLG51000_LOCK_OTP_PROG_SHIFT 0
|
||||
#define SLG51000_LOCK_OTP_PROG_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_OTP_LOCK_CTRL = 0x78ff */
|
||||
#define SLG51000_LOCK_DFT_SHIFT 1
|
||||
#define SLG51000_LOCK_DFT_MASK (0x01 << 1)
|
||||
#define SLG51000_LOCK_RWT_SHIFT 0
|
||||
#define SLG51000_LOCK_RWT_MASK (0x01 << 0)
|
||||
|
||||
/* SLG51000_LOCK_GLOBAL_LOCK_CTRL1 = 0x8000 */
|
||||
#define SLG51000_LDO7_LOCK_SHIFT 7
|
||||
#define SLG51000_LDO7_LOCK_MASK (0x01 << 7)
|
||||
#define SLG51000_LDO6_LOCK_SHIFT 6
|
||||
#define SLG51000_LDO6_LOCK_MASK (0x01 << 6)
|
||||
#define SLG51000_LDO5_LOCK_SHIFT 5
|
||||
#define SLG51000_LDO5_LOCK_MASK (0x01 << 5)
|
||||
#define SLG51000_LDO4_LOCK_SHIFT 4
|
||||
#define SLG51000_LDO4_LOCK_MASK (0x01 << 4)
|
||||
#define SLG51000_LDO3_LOCK_SHIFT 3
|
||||
#define SLG51000_LDO3_LOCK_MASK (0x01 << 3)
|
||||
#define SLG51000_LDO2_LOCK_SHIFT 2
|
||||
#define SLG51000_LDO2_LOCK_MASK (0x01 << 2)
|
||||
#define SLG51000_LDO1_LOCK_SHIFT 1
|
||||
#define SLG51000_LDO1_LOCK_MASK (0x01 << 1)
|
||||
|
||||
#endif /* __SLG51000_REGISTERS_H__ */
|
||||
|
132
drivers/regulator/stm32-booster.c
Normal file
132
drivers/regulator/stm32-booster.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) STMicroelectronics 2019
|
||||
// Author(s): Fabrice Gasnier <fabrice.gasnier@st.com>.
|
||||
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
|
||||
/* STM32H7 SYSCFG register */
|
||||
#define STM32H7_SYSCFG_PMCR 0x04
|
||||
#define STM32H7_SYSCFG_BOOSTE_MASK BIT(8)
|
||||
|
||||
/* STM32MP1 SYSCFG has set and clear registers */
|
||||
#define STM32MP1_SYSCFG_PMCSETR 0x04
|
||||
#define STM32MP1_SYSCFG_PMCCLRR 0x44
|
||||
#define STM32MP1_SYSCFG_EN_BOOSTER_MASK BIT(8)
|
||||
|
||||
static const struct regulator_ops stm32h7_booster_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_desc stm32h7_booster_desc = {
|
||||
.name = "booster",
|
||||
.supply_name = "vdda",
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.min_uV = 3300000,
|
||||
.fixed_uV = 3300000,
|
||||
.ramp_delay = 66000, /* up to 50us to stabilize */
|
||||
.ops = &stm32h7_booster_ops,
|
||||
.enable_reg = STM32H7_SYSCFG_PMCR,
|
||||
.enable_mask = STM32H7_SYSCFG_BOOSTE_MASK,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int stm32mp1_booster_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
return regmap_write(rdev->regmap, STM32MP1_SYSCFG_PMCSETR,
|
||||
STM32MP1_SYSCFG_EN_BOOSTER_MASK);
|
||||
}
|
||||
|
||||
static int stm32mp1_booster_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
return regmap_write(rdev->regmap, STM32MP1_SYSCFG_PMCCLRR,
|
||||
STM32MP1_SYSCFG_EN_BOOSTER_MASK);
|
||||
}
|
||||
|
||||
static const struct regulator_ops stm32mp1_booster_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.enable = stm32mp1_booster_enable,
|
||||
.disable = stm32mp1_booster_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_desc stm32mp1_booster_desc = {
|
||||
.name = "booster",
|
||||
.supply_name = "vdda",
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.min_uV = 3300000,
|
||||
.fixed_uV = 3300000,
|
||||
.ramp_delay = 66000,
|
||||
.ops = &stm32mp1_booster_ops,
|
||||
.enable_reg = STM32MP1_SYSCFG_PMCSETR,
|
||||
.enable_mask = STM32MP1_SYSCFG_EN_BOOSTER_MASK,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int stm32_booster_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct regulator_config config = { };
|
||||
const struct regulator_desc *desc;
|
||||
struct regulator_dev *rdev;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
desc = (const struct regulator_desc *)
|
||||
of_match_device(dev->driver->of_match_table, dev)->data;
|
||||
|
||||
config.regmap = regmap;
|
||||
config.dev = dev;
|
||||
config.of_node = np;
|
||||
config.init_data = of_get_regulator_init_data(dev, np, desc);
|
||||
|
||||
rdev = devm_regulator_register(dev, desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
ret = PTR_ERR(rdev);
|
||||
dev_err(dev, "register failed with error %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id stm32_booster_of_match[] = {
|
||||
{
|
||||
.compatible = "st,stm32h7-booster",
|
||||
.data = (void *)&stm32h7_booster_desc
|
||||
}, {
|
||||
.compatible = "st,stm32mp1-booster",
|
||||
.data = (void *)&stm32mp1_booster_desc
|
||||
}, {
|
||||
},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_booster_of_match);
|
||||
|
||||
static struct platform_driver stm32_booster_driver = {
|
||||
.probe = stm32_booster_probe,
|
||||
.driver = {
|
||||
.name = "stm32-booster",
|
||||
.of_match_table = of_match_ptr(stm32_booster_of_match),
|
||||
},
|
||||
};
|
||||
module_platform_driver(stm32_booster_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
|
||||
MODULE_DESCRIPTION("STMicroelectronics STM32 booster regulator driver");
|
||||
MODULE_ALIAS("platform:stm32-booster");
|
|
@ -371,11 +371,12 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data(
|
|||
"dcdc-ext-control-gpios", 0,
|
||||
gflags,
|
||||
"tps65090");
|
||||
if (IS_ERR(rpdata->gpiod))
|
||||
return ERR_CAST(rpdata->gpiod);
|
||||
if (!rpdata->gpiod)
|
||||
if (PTR_ERR(rpdata->gpiod) == -ENOENT) {
|
||||
dev_err(&pdev->dev,
|
||||
"could not find DCDC external control GPIO\n");
|
||||
rpdata->gpiod = NULL;
|
||||
} else if (IS_ERR(rpdata->gpiod))
|
||||
return ERR_CAST(rpdata->gpiod);
|
||||
}
|
||||
|
||||
if (of_property_read_u32(tps65090_matches[idx].of_node,
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/mfd/wm831x/core.h>
|
||||
|
@ -50,7 +50,7 @@ struct wm831x_dcdc {
|
|||
int base;
|
||||
struct wm831x *wm831x;
|
||||
struct regulator_dev *regulator;
|
||||
int dvs_gpio;
|
||||
struct gpio_desc *dvs_gpiod;
|
||||
int dvs_gpio_state;
|
||||
int on_vsel;
|
||||
int dvs_vsel;
|
||||
|
@ -217,7 +217,7 @@ static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state)
|
|||
return 0;
|
||||
|
||||
dcdc->dvs_gpio_state = state;
|
||||
gpio_set_value(dcdc->dvs_gpio, state);
|
||||
gpiod_set_value(dcdc->dvs_gpiod, state);
|
||||
|
||||
/* Should wait for DVS state change to be asserted if we have
|
||||
* a GPIO for it, for now assume the device is configured
|
||||
|
@ -237,10 +237,10 @@ static int wm831x_buckv_set_voltage_sel(struct regulator_dev *rdev,
|
|||
int ret;
|
||||
|
||||
/* If this value is already set then do a GPIO update if we can */
|
||||
if (dcdc->dvs_gpio && dcdc->on_vsel == vsel)
|
||||
if (dcdc->dvs_gpiod && dcdc->on_vsel == vsel)
|
||||
return wm831x_buckv_set_dvs(rdev, 0);
|
||||
|
||||
if (dcdc->dvs_gpio && dcdc->dvs_vsel == vsel)
|
||||
if (dcdc->dvs_gpiod && dcdc->dvs_vsel == vsel)
|
||||
return wm831x_buckv_set_dvs(rdev, 1);
|
||||
|
||||
/* Always set the ON status to the minimum voltage */
|
||||
|
@ -249,7 +249,7 @@ static int wm831x_buckv_set_voltage_sel(struct regulator_dev *rdev,
|
|||
return ret;
|
||||
dcdc->on_vsel = vsel;
|
||||
|
||||
if (!dcdc->dvs_gpio)
|
||||
if (!dcdc->dvs_gpiod)
|
||||
return ret;
|
||||
|
||||
/* Kick the voltage transition now */
|
||||
|
@ -296,7 +296,7 @@ static int wm831x_buckv_get_voltage_sel(struct regulator_dev *rdev)
|
|||
{
|
||||
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
|
||||
|
||||
if (dcdc->dvs_gpio && dcdc->dvs_gpio_state)
|
||||
if (dcdc->dvs_gpiod && dcdc->dvs_gpio_state)
|
||||
return dcdc->dvs_vsel;
|
||||
else
|
||||
return dcdc->on_vsel;
|
||||
|
@ -337,7 +337,7 @@ static void wm831x_buckv_dvs_init(struct platform_device *pdev,
|
|||
int ret;
|
||||
u16 ctrl;
|
||||
|
||||
if (!pdata || !pdata->dvs_gpio)
|
||||
if (!pdata)
|
||||
return;
|
||||
|
||||
/* gpiolib won't let us read the GPIO status so pick the higher
|
||||
|
@ -345,17 +345,14 @@ static void wm831x_buckv_dvs_init(struct platform_device *pdev,
|
|||
*/
|
||||
dcdc->dvs_gpio_state = pdata->dvs_init_state;
|
||||
|
||||
ret = devm_gpio_request_one(&pdev->dev, pdata->dvs_gpio,
|
||||
dcdc->dvs_gpio_state ? GPIOF_INIT_HIGH : 0,
|
||||
"DCDC DVS");
|
||||
if (ret < 0) {
|
||||
dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n",
|
||||
dcdc->name, ret);
|
||||
dcdc->dvs_gpiod = devm_gpiod_get(&pdev->dev, "dvs",
|
||||
dcdc->dvs_gpio_state ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW);
|
||||
if (IS_ERR(dcdc->dvs_gpiod)) {
|
||||
dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %ld\n",
|
||||
dcdc->name, PTR_ERR(dcdc->dvs_gpiod));
|
||||
return;
|
||||
}
|
||||
|
||||
dcdc->dvs_gpio = pdata->dvs_gpio;
|
||||
|
||||
switch (pdata->dvs_control_src) {
|
||||
case 1:
|
||||
ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT;
|
||||
|
|
|
@ -797,6 +797,9 @@
|
|||
#define DA9062AA_BUCK3_SL_A_SHIFT 7
|
||||
#define DA9062AA_BUCK3_SL_A_MASK BIT(7)
|
||||
|
||||
/* DA9062AA_VLDO[1-4]_A common */
|
||||
#define DA9062AA_VLDO_A_MIN_SEL 2
|
||||
|
||||
/* DA9062AA_VLDO1_A = 0x0A9 */
|
||||
#define DA9062AA_VLDO1_A_SHIFT 0
|
||||
#define DA9062AA_VLDO1_A_MASK 0x3f
|
||||
|
|
|
@ -11,55 +11,6 @@
|
|||
#ifndef __MFD_DA9063_PDATA_H__
|
||||
#define __MFD_DA9063_PDATA_H__
|
||||
|
||||
#include <linux/regulator/machine.h>
|
||||
|
||||
/*
|
||||
* Regulator configuration
|
||||
*/
|
||||
/* DA9063 and DA9063L regulator IDs */
|
||||
enum {
|
||||
/* BUCKs */
|
||||
DA9063_ID_BCORE1,
|
||||
DA9063_ID_BCORE2,
|
||||
DA9063_ID_BPRO,
|
||||
DA9063_ID_BMEM,
|
||||
DA9063_ID_BIO,
|
||||
DA9063_ID_BPERI,
|
||||
|
||||
/* BCORE1 and BCORE2 in merged mode */
|
||||
DA9063_ID_BCORES_MERGED,
|
||||
/* BMEM and BIO in merged mode */
|
||||
DA9063_ID_BMEM_BIO_MERGED,
|
||||
/* When two BUCKs are merged, they cannot be reused separately */
|
||||
|
||||
/* LDOs on both DA9063 and DA9063L */
|
||||
DA9063_ID_LDO3,
|
||||
DA9063_ID_LDO7,
|
||||
DA9063_ID_LDO8,
|
||||
DA9063_ID_LDO9,
|
||||
DA9063_ID_LDO11,
|
||||
|
||||
/* DA9063-only LDOs */
|
||||
DA9063_ID_LDO1,
|
||||
DA9063_ID_LDO2,
|
||||
DA9063_ID_LDO4,
|
||||
DA9063_ID_LDO5,
|
||||
DA9063_ID_LDO6,
|
||||
DA9063_ID_LDO10,
|
||||
};
|
||||
|
||||
/* Regulators platform data */
|
||||
struct da9063_regulator_data {
|
||||
int id;
|
||||
struct regulator_init_data *initdata;
|
||||
};
|
||||
|
||||
struct da9063_regulators_pdata {
|
||||
unsigned n_regulators;
|
||||
struct da9063_regulator_data *regulator_data;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* RGB LED configuration
|
||||
*/
|
||||
|
|
|
@ -190,4 +190,9 @@ enum s2mps11_regulators {
|
|||
#define S2MPS11_BUCK6_RAMP_EN_SHIFT 0
|
||||
#define S2MPS11_PMIC_EN_SHIFT 6
|
||||
|
||||
/*
|
||||
* Bits for "enable suspend" (On/Off controlled by PWREN)
|
||||
* are the same as in S2MPS14: S2MPS14_ENABLE_SUSPEND
|
||||
*/
|
||||
|
||||
#endif /* __LINUX_MFD_S2MPS11_H */
|
||||
|
|
|
@ -47,7 +47,6 @@ struct wm831x_battery_pdata {
|
|||
* I2C or SPI buses.
|
||||
*/
|
||||
struct wm831x_buckv_pdata {
|
||||
int dvs_gpio; /** CPU GPIO to use for DVS switching */
|
||||
int dvs_control_src; /** Hardware DVS source to use (1 or 2) */
|
||||
int dvs_init_state; /** DVS state to expect on startup */
|
||||
int dvs_state_gpio; /** CPU GPIO to use for monitoring status */
|
||||
|
|
|
@ -283,6 +283,11 @@ enum regulator_type {
|
|||
* @vsel_range_mask: Mask for register bitfield used for range selector
|
||||
* @vsel_reg: Register for selector when using regulator_regmap_X_voltage_
|
||||
* @vsel_mask: Mask for register bitfield used for selector
|
||||
* @vsel_step: Specify the resolution of selector stepping when setting
|
||||
* voltage. If 0, then no stepping is done (requested selector is
|
||||
* set directly), if >0 then the regulator API will ramp the
|
||||
* voltage up/down gradually each time increasing/decreasing the
|
||||
* selector by the specified step value.
|
||||
* @csel_reg: Register for current limit selector using regmap set_current_limit
|
||||
* @csel_mask: Mask for register bitfield used for current limit selector
|
||||
* @apply_reg: Register for initiate voltage change on the output when
|
||||
|
@ -357,6 +362,7 @@ struct regulator_desc {
|
|||
unsigned int vsel_range_mask;
|
||||
unsigned int vsel_reg;
|
||||
unsigned int vsel_mask;
|
||||
unsigned int vsel_step;
|
||||
unsigned int csel_reg;
|
||||
unsigned int csel_mask;
|
||||
unsigned int apply_reg;
|
||||
|
|
|
@ -105,9 +105,6 @@ enum {
|
|||
#define MAX8952_NUM_DVS_MODE 4
|
||||
|
||||
struct max8952_platform_data {
|
||||
int gpio_vid0;
|
||||
int gpio_vid1;
|
||||
|
||||
u32 default_mode;
|
||||
u32 dvs_mode[MAX8952_NUM_DVS_MODE]; /* MAX8952_DVS_MODEx_XXXXmV */
|
||||
|
||||
|
|
Loading…
Reference in a new issue