diff options
32 files changed, 1897 insertions, 485 deletions
diff --git a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt index 443564d7784f..69bf41949b01 100644 --- a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt @@ -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 diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml index d289c2f7455a..a650b457085d 100644 --- a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml @@ -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 diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt deleted file mode 100644 index dd25e73b5d79..000000000000 --- a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt +++ /dev/null @@ -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; - }; diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.yaml b/Documentation/devicetree/bindings/regulator/gpio-regulator.yaml new file mode 100644 index 000000000000..9d3b28417fb6 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.yaml @@ -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; + }; +... diff --git a/Documentation/devicetree/bindings/regulator/max8660.txt b/Documentation/devicetree/bindings/regulator/max8660.txt deleted file mode 100644 index 8ba994d8a142..000000000000 --- a/Documentation/devicetree/bindings/regulator/max8660.txt +++ /dev/null @@ -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>; - }; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/regulator/max8660.yaml b/Documentation/devicetree/bindings/regulator/max8660.yaml new file mode 100644 index 000000000000..9c038698f880 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/max8660.yaml @@ -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>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 0a3f087d5844..487ccd8370b3 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -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. diff --git a/Documentation/devicetree/bindings/regulator/regulator.yaml b/Documentation/devicetree/bindings/regulator/regulator.yaml new file mode 100644 index 000000000000..02c3043ce419 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/regulator.yaml @@ -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; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/regulator/slg51000.txt b/Documentation/devicetree/bindings/regulator/slg51000.txt new file mode 100644 index 000000000000..aa0733e49b90 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/slg51000.txt @@ -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>; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 57f496cff999..96b54b548ab0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4697,6 +4697,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 @@ -4712,6 +4713,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 diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 379424d72ae7..8ec6a4f5eb05 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.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)); diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800-regulator.c index 9fd379732d18..9fd379732d18 100644 --- a/drivers/regulator/88pm800.c +++ b/drivers/regulator/88pm800-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 8553bdf87c1d..0e7d425ba9b1 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -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,15 @@ 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_VREFBUF tristate "STMicroelectronics STM32 VREFBUF" depends on ARCH_STM32 || COMPILE_TEST diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 93f53840e8f1..c15b0b613766 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -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,7 @@ 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_VREFBUF) += stm32-vrefbuf.o obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index e4bc7b1e5ccd..1a3d7b720f5e 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -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"); diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index be0d46da51a1..ae1a5de3e57d 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -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"); diff --git a/drivers/regulator/bd70528-regulator.c b/drivers/regulator/bd70528-regulator.c index 30e3ed430a8a..0248a61f1006 100644 --- a/drivers/regulator/bd70528-regulator.c +++ b/drivers/regulator/bd70528-regulator.c @@ -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> diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index fde4264da6ff..8c22cfb76173 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -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> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index c894cf0d8a28..85f61e5dc312 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1645,9 +1645,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( diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c index d3284361e594..f80781d58a28 100644 --- a/drivers/regulator/cpcap-regulator.c +++ b/drivers/regulator/cpcap-regulator.c @@ -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 diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 6f9ce1a6e44d..02f816318fba 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -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, diff --git a/drivers/regulator/max77620-regulator.c b/drivers/regulator/max77620-regulator.c index 0db367b54ae7..2ae2d319321b 100644 --- a/drivers/regulator/max77620-regulator.c +++ b/drivers/regulator/max77620-regulator.c @@ -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); diff --git a/drivers/regulator/max77650-regulator.c b/drivers/regulator/max77650-regulator.c index 5c4f86c98510..e3b28fc68cdb 100644 --- a/drivers/regulator/max77650-regulator.c +++ b/drivers/regulator/max77650-regulator.c @@ -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, @@ -130,6 +111,7 @@ static int max77650_regulator_disable(struct regulator_dev *rdev) static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) { + struct max77650_regulator_desc *rdesc = rdev_get_drvdata(rdev); int rv = 0, curr, diff; bool ascending; @@ -137,15 +119,24 @@ static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, * 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); + if (!max77650_regulator_is_enabled(rdev)) { + if (rdesc == &max77651_SBB1_desc) + return regulator_set_voltage_sel_pickable_regmap(rdev, + sel); + else + 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 (rdesc == &max77651_SBB1_desc) + curr = regulator_get_voltage_sel_pickable_regmap(rdev); + else + curr = regulator_get_voltage_sel_regmap(rdev); + if (curr < 0) return curr; @@ -162,57 +153,18 @@ static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, * 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); + if (rdesc == &max77651_SBB1_desc) + rv = regulator_set_voltage_sel_pickable_regmap(rdev, + curr); else - MAX77650_REGULATOR_SBB1_SEL_INCR(curr); + rv = regulator_set_voltage_sel_regmap(rdev, curr); - rv = regulator_set_voltage_sel_regmap(rdev, curr); if (rv) return rv; if (curr == sel) break; - }; + } return 0; } @@ -241,14 +193,14 @@ static const struct regulator_ops max77650_regulator_SBB_ops = { .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 = max77650_regulator_set_voltage_sel, .get_current_limit = regulator_get_current_limit_regmap, .set_current_limit = regulator_set_current_limit_regmap, .set_active_discharge = regulator_set_active_discharge_regmap, @@ -345,9 +297,13 @@ 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_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, diff --git a/drivers/regulator/max77802-regulator.c b/drivers/regulator/max77802-regulator.c index ea7b50397300..7b8ec8c0bd15 100644 --- a/drivers/regulator/max77802-regulator.c +++ b/drivers/regulator/max77802-regulator.c @@ -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> diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index 2a123b87d9f2..ccd5da63cdf2 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -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; - - 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) { + /* 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); + + /* 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); diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 6dfc9e176360..00773a485fc1 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -903,13 +903,16 @@ 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) - return REGULATOR_MODE_NORMAL; + reg &= SPMI_COMMON_MODE_HPM_MASK | SPMI_COMMON_MODE_AUTO_MASK; - if (reg & SPMI_COMMON_MODE_AUTO_MASK) + switch (reg) { + case SPMI_COMMON_MODE_HPM_MASK: + return REGULATOR_MODE_NORMAL; + case SPMI_COMMON_MODE_AUTO_MASK: return REGULATOR_MODE_FAST; - - return REGULATOR_MODE_IDLE; + default: + return REGULATOR_MODE_IDLE; + } } static int @@ -917,12 +920,19 @@ 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); } @@ -1736,6 +1746,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 +1836,12 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev) } } + if (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; diff --git a/drivers/regulator/slg51000-regulator.c b/drivers/regulator/slg51000-regulator.c new file mode 100644 index 000000000000..04b732991d69 --- /dev/null +++ b/drivers/regulator/slg51000-regulator.c @@ -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"); + diff --git a/drivers/regulator/slg51000-regulator.h b/drivers/regulator/slg51000-regulator.h new file mode 100644 index 000000000000..20feb7f91942 --- /dev/null +++ b/drivers/regulator/slg51000-regulator.h @@ -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__ */ + diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index b422eef97b77..018dbbd96771 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -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; diff --git a/include/linux/mfd/da9063/pdata.h b/include/linux/mfd/da9063/pdata.h index 77c566ab96ab..085edbf7601b 100644 --- a/include/linux/mfd/da9063/pdata.h +++ b/include/linux/mfd/da9063/pdata.h @@ -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 */ diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h index 071cdf3e16cf..986986fe4e4e 100644 --- a/include/linux/mfd/wm831x/pdata.h +++ b/include/linux/mfd/wm831x/pdata.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 */ diff --git a/include/linux/regulator/max8952.h b/include/linux/regulator/max8952.h index ebd99d2e62ad..8712c091abf0 100644 --- a/include/linux/regulator/max8952.h +++ b/include/linux/regulator/max8952.h @@ -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 */ |