mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-12 09:56:47 -05:00
Merge tag 'regulator-v6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown:
"There's a bunch of new drivers here, plus a lot of hardening for the
supply resolution code which allow us to support systems where we have
two PMICs each of which has regulators supplied by the other. This did
work a long time ago but got broken as part of improved integration
with the device model, it's fairly rare so nobody noticed.
- Improvements for supply handling from André Draszik to allow
systems with two PMICs with supply/consumer relationships in both
directions to instantiate.
- New drivers for Maxim MAX776750, Realtek RT8902, Samsung S2MPG11,
Texas Instuments TPS65185.
This have also pulls in some MFD updates which are build dependencies
for the Samsung S2MPG11 support"
* tag 'regulator-v6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (42 commits)
regulator: s2mps11: more descriptive gpio consumer name
regulator: s2mps11: add S2MPG11 regulator
regulator: s2mps11: refactor S2MPG10 regulator macros for S2MPG11 reuse
regulator: s2mps11: refactor S2MPG10 ::set_voltage_time() for S2MPG11 reuse
regulator: s2mps11: add S2MPG10 regulator
regulator: s2mps11: refactor handling of external rail control
regulator: s2mps11: update node parsing (allow -supply properties)
regulator: s2mps11: place constants on right side of comparison tests
regulator: s2mps11: use dev_err_probe() where appropriate
regulator: s2mps11: drop two needless variable initialisations
regulator: add REGULATOR_LINEAR_VRANGE macro
regulator: dt-bindings: add s2mpg11-pmic regulators
regulator: dt-bindings: add s2mpg10-pmic regulators
dt-bindings: firmware: google,gs101-acpm-ipc: convert regulators to lowercase
mfd: sec: Add support for S2MPG11 PMIC via ACPM
mfd: sec: s2mpg10: Reorder regulators for better probe performance
dt-bindings: mfd: Add samsung,s2mpg11-pmic
dt-bindings: mfd: samsung,s2mpg10-pmic: Link to its regulators
dt-bindings: mfd: samsung,s2mps11: Split s2mpg10-pmic into separate file
mfd: sec: Drop now unused struct sec_pmic_dev::irq_data
...
This commit is contained in:
@@ -75,7 +75,7 @@ examples:
|
||||
interrupts-extended = <&gpa0 6 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
regulators {
|
||||
LDO1 {
|
||||
ldo1m {
|
||||
regulator-name = "vdd_ldo1";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
@@ -84,7 +84,7 @@ examples:
|
||||
|
||||
// ...
|
||||
|
||||
BUCK1 {
|
||||
buck8m {
|
||||
regulator-name = "vdd_mif";
|
||||
regulator-min-microvolt = <450000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
|
||||
120
Documentation/devicetree/bindings/mfd/samsung,s2mpg10-pmic.yaml
Normal file
120
Documentation/devicetree/bindings/mfd/samsung,s2mpg10-pmic.yaml
Normal file
@@ -0,0 +1,120 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/samsung,s2mpg10-pmic.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S2MPG10 Power Management IC
|
||||
|
||||
maintainers:
|
||||
- André Draszik <andre.draszik@linaro.org>
|
||||
|
||||
description: |
|
||||
This is part of the device tree bindings for the S2MPG10 Power Management IC
|
||||
(PMIC).
|
||||
|
||||
The Samsung S2MPG10 is a Power Management IC for mobile applications with buck
|
||||
converters, various LDOs, power meters, RTC, clock outputs, and additional
|
||||
GPIO interfaces and is typically complemented by S2MPG10 PMIC in a main/sub
|
||||
configuration as the main PMIC.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: samsung,s2mpg10-pmic
|
||||
|
||||
clocks:
|
||||
$ref: /schemas/clock/samsung,s2mps11.yaml
|
||||
description:
|
||||
Child node describing clock provider.
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
$ref: /schemas/regulator/samsung,s2mpg10-regulator.yaml
|
||||
description:
|
||||
List of child nodes that specify the regulators.
|
||||
|
||||
system-power-controller: true
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
patternProperties:
|
||||
"^vinb([1-9]|10)m-supply$":
|
||||
description:
|
||||
Phandle to the power supply for each buck rail of this PMIC. There is a
|
||||
1:1 mapping of supply to rail, e.g. vinb1m-supply supplies buck1m.
|
||||
|
||||
"^vinl([1-9]|1[0-5])m-supply$":
|
||||
description: |
|
||||
Phandle to the power supply for one or multiple LDO rails of this PMIC.
|
||||
The mapping of supply to rail(s) is as follows:
|
||||
vinl1m - ldo13m
|
||||
vinl2m - ldo15m
|
||||
vinl3m - ldo1m, ldo5m, ldo7m
|
||||
vinl4m - ldo3m, ldo8m
|
||||
vinl5m - ldo16m
|
||||
vinl6m - ldo17m
|
||||
vinl7m - ldo6m, ldo11m, ldo24m, ldo28m
|
||||
vinl8m - ldo12m
|
||||
vinl9m - ldo2m, ldo4m
|
||||
vinl10m - ldo9m, ldo14m, ldo18m, 19m, ldo20m, ldo25m
|
||||
vinl11m - ldo23m, ldo31m
|
||||
vinl12m - ldo29m
|
||||
vinl13m - ldo30m
|
||||
vinl14m - ldo21m
|
||||
vinl15m - ldo10m, ldo22m, ldo26m, ldo27m
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- interrupts
|
||||
- regulators
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/regulator/samsung,s2mpg10-regulator.h>
|
||||
|
||||
pmic {
|
||||
compatible = "samsung,s2mpg10-pmic";
|
||||
interrupts-extended = <&gpa0 6 IRQ_TYPE_LEVEL_LOW>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pmic_int>;
|
||||
system-power-controller;
|
||||
wakeup-source;
|
||||
|
||||
vinl3m-supply = <&buck8m>;
|
||||
|
||||
clocks {
|
||||
compatible = "samsung,s2mpg10-clk";
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "rtc32k_ap", "peri32k1", "peri32k2";
|
||||
};
|
||||
|
||||
regulators {
|
||||
buck8m {
|
||||
regulator-name = "vdd_mif";
|
||||
regulator-min-microvolt = <450000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-ramp-delay = <6250>;
|
||||
};
|
||||
|
||||
ldo1m {
|
||||
regulator-name = "vdd_ldo1";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
};
|
||||
|
||||
ldo20m {
|
||||
regulator-name = "vdd_dmics";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-always-on;
|
||||
samsung,ext-control = <S2MPG10_EXTCTRL_LDO20M_EN2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,88 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/samsung,s2mpg11-pmic.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S2MPG11 Power Management IC
|
||||
|
||||
maintainers:
|
||||
- André Draszik <andre.draszik@linaro.org>
|
||||
|
||||
description: |
|
||||
This is part of the device tree bindings for the S2MPG11 Power Management IC
|
||||
(PMIC).
|
||||
|
||||
The Samsung S2MPG11 is a Power Management IC for mobile applications with buck
|
||||
converters, various LDOs, power meters, NTC thermistor inputs, and additional
|
||||
GPIO interfaces and typically complements an S2MPG10 PMIC in a main/sub
|
||||
configuration as the sub-PMIC.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: samsung,s2mpg11-pmic
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
$ref: /schemas/regulator/samsung,s2mpg11-regulator.yaml
|
||||
description:
|
||||
List of child nodes that specify the regulators.
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
patternProperties:
|
||||
"^vinb(([1-9]|10)s|[abd])-supply$":
|
||||
description:
|
||||
Phandle to the power supply for each buck rail of this PMIC. There is a
|
||||
1:1 mapping of numbered supply to rail, e.g. vinb1s-supply supplies
|
||||
buck1s. The remaining mapping is as follows
|
||||
vinba - bucka
|
||||
vinbb - buck boost
|
||||
vinbd - buckd
|
||||
|
||||
"^vinl[1-6]s-supply$":
|
||||
description: |
|
||||
Phandle to the power supply for one or multiple LDO rails of this PMIC.
|
||||
The mapping of supply to rail(s) is as follows
|
||||
vinl1s - ldo1s, ldo2s
|
||||
vinl2s - ldo8s, ldo9s
|
||||
vinl3s - ldo3s, ldo5s, ldo7s, ldo15s
|
||||
vinl4s - ldo10s, ldo11s, ldo12s, ldo14s
|
||||
vinl5s - ldo4s, ldo6s
|
||||
vinl6s - ldo13s
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- interrupts
|
||||
- regulators
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/regulator/samsung,s2mpg10-regulator.h>
|
||||
|
||||
pmic {
|
||||
compatible = "samsung,s2mpg11-pmic";
|
||||
interrupts-extended = <&gpa0 7 IRQ_TYPE_LEVEL_LOW>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pmic_int>;
|
||||
wakeup-source;
|
||||
|
||||
vinl1s-supply = <&buck8m>;
|
||||
vinl2s-supply = <&buck6s>;
|
||||
|
||||
regulators {
|
||||
buckd {
|
||||
regulator-name = "vcc_ufs";
|
||||
regulator-ramp-delay = <6250>;
|
||||
enable-gpios = <&gpp0 1 GPIO_ACTIVE_HIGH>;
|
||||
samsung,ext-control = <S2MPG11_EXTCTRL_UFS_EN>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -20,7 +20,6 @@ description: |
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- samsung,s2mpg10-pmic
|
||||
- samsung,s2mps11-pmic
|
||||
- samsung,s2mps13-pmic
|
||||
- samsung,s2mps14-pmic
|
||||
@@ -59,42 +58,16 @@ properties:
|
||||
reset (setting buck voltages to default values).
|
||||
type: boolean
|
||||
|
||||
system-power-controller: true
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- regulators
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,s2mpg10-pmic
|
||||
then:
|
||||
properties:
|
||||
reg: false
|
||||
samsung,s2mps11-acokb-ground: false
|
||||
samsung,s2mps11-wrstbi-ground: false
|
||||
|
||||
# oneOf is required, because dtschema's fixups.py doesn't handle this
|
||||
# nesting here. Its special treatment to allow either interrupt property
|
||||
# when only one is specified in the binding works at the top level only.
|
||||
oneOf:
|
||||
- required: [interrupts]
|
||||
- required: [interrupts-extended]
|
||||
|
||||
else:
|
||||
properties:
|
||||
system-power-controller: false
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
||||
184
Documentation/devicetree/bindings/regulator/adi,max77675.yaml
Normal file
184
Documentation/devicetree/bindings/regulator/adi,max77675.yaml
Normal file
@@ -0,0 +1,184 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/adi,max77675.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Maxim MAX77675 PMIC Regulator
|
||||
|
||||
maintainers:
|
||||
- Joan Na <joan.na@analog.com>
|
||||
|
||||
description:
|
||||
The MAX77675 is a Power Management IC providing four switching buck
|
||||
regulators (SBB0–SBB3) accessible via I2C. It supports configuration
|
||||
of output voltages and enable controls for each regulator.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/input/input.yaml
|
||||
- $ref: /schemas/pinctrl/pincfg-node.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: adi,max77675
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reset-time-sec:
|
||||
description: Manual reset time in seconds
|
||||
enum: [4, 8, 12, 16]
|
||||
default: 4
|
||||
|
||||
bias-disable:
|
||||
type: boolean
|
||||
description: Disable internal pull-up for EN pin
|
||||
|
||||
input-debounce:
|
||||
description: Debounce time for the enable pin, in microseconds
|
||||
items:
|
||||
- enum: [100, 30000]
|
||||
default: 100
|
||||
|
||||
adi,en-mode:
|
||||
description: |
|
||||
Enable mode configuration.
|
||||
The debounce time set by 'input-debounce' applies to
|
||||
both push-button and slide-switch modes.
|
||||
"push-button" - A long press triggers power-on or power-down
|
||||
"slide-switch" - Low : powers on, High : powers down
|
||||
"logic" - Low : powers on, High : powers down (no debounce time)
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [push-button, slide-switch, logic]
|
||||
default: slide-switch
|
||||
|
||||
adi,voltage-change-latency-us:
|
||||
description:
|
||||
Specifies the delay (in microseconds) between an output voltage change
|
||||
request and the start of the SBB voltage ramp.
|
||||
enum: [10, 100]
|
||||
default: 100
|
||||
|
||||
adi,drv-sbb-strength:
|
||||
description: |
|
||||
SIMO Buck-Boost Drive Strength Trim.
|
||||
Controls the drive strength of the SIMO regulator's power MOSFETs.
|
||||
This setting affects switching speed, impacting power efficiency and EMI.
|
||||
"max" – Maximum drive strength (~0.6 ns transition time)
|
||||
"high" – High drive strength (~1.2 ns transition time)
|
||||
"low" – Low drive strength (~1.8 ns transition time)
|
||||
"min" – Minimum drive strength (~8 ns transition time)
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [max, high, low, min]
|
||||
default: max
|
||||
|
||||
adi,dvs-slew-rate-mv-per-us:
|
||||
description:
|
||||
Dynamic rising slew rate for output voltage transitions, in mV/μs.
|
||||
This setting is only used when 'adi,fixed-slew-rate' is not present.
|
||||
enum: [5, 10]
|
||||
default: 5
|
||||
|
||||
adi,bias-low-power-request:
|
||||
type: boolean
|
||||
description: Request low-power bias mode
|
||||
|
||||
adi,simo-ldo-always-on:
|
||||
type: boolean
|
||||
description: Set internal LDO to always supply 1.8V
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
description: Regulator child nodes
|
||||
patternProperties:
|
||||
"^sbb[0-3]$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
properties:
|
||||
adi,fps-slot:
|
||||
description: |
|
||||
FPS (Flexible Power Sequencer) slot selection.
|
||||
The Flexible Power Sequencer allows resources to power up under
|
||||
hardware or software control. Additionally, each resource can
|
||||
power up independently or among a group of other regulators with
|
||||
adjustable power-up and power-down slots.
|
||||
"slot0" - Assign to FPS Slot 0
|
||||
"slot1" - Assign to FPS Slot 1
|
||||
"slot2" - Assign to FPS Slot 2
|
||||
"slot3" - Assign to FPS Slot 3
|
||||
"default" - Use the default FPS slot value stored in register
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [slot0, slot1, slot2, slot3, default]
|
||||
default: default
|
||||
|
||||
adi,fixed-slew-rate:
|
||||
type: boolean
|
||||
description:
|
||||
When this property is present, the device uses a constant 2 mV/μs
|
||||
slew rate and ignores any dynamic slew rate configuration.
|
||||
When absent, the device uses the dynamic slew rate specified
|
||||
by 'adi,dvs-slew-rate-mv-per-us'
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- regulators
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
max77675: pmic@44 {
|
||||
compatible = "adi,max77675";
|
||||
reg = <0x44>;
|
||||
|
||||
reset-time-sec = <4>;
|
||||
input-debounce = <100>;
|
||||
|
||||
adi,en-mode = "slide-switch";
|
||||
adi,voltage-change-latency-us = <100>;
|
||||
adi,drv-sbb-strength = "max";
|
||||
adi,dvs-slew-rate-mv-per-us = <5>;
|
||||
|
||||
regulators {
|
||||
sbb0: sbb0 {
|
||||
regulator-name = "sbb0";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <5500000>;
|
||||
adi,fps-slot = "default";
|
||||
adi,fixed-slew-rate;
|
||||
};
|
||||
|
||||
sbb1: sbb1 {
|
||||
regulator-name = "sbb1";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <5500000>;
|
||||
adi,fps-slot = "default";
|
||||
adi,fixed-slew-rate;
|
||||
};
|
||||
|
||||
sbb2: sbb2 {
|
||||
regulator-name = "sbb2";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <5500000>;
|
||||
adi,fps-slot = "default";
|
||||
adi,fixed-slew-rate;
|
||||
};
|
||||
|
||||
sbb3: sbb3 {
|
||||
regulator-name = "sbb3";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <5500000>;
|
||||
adi,fps-slot = "default";
|
||||
adi,fixed-slew-rate;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -40,13 +40,13 @@ patternProperties:
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^ldo-v(dig18|emc33|ibr|mc|mch|mipi|rtc|sim1|sim2|sram|usb10)$":
|
||||
"^ldo-v(dig18|emc33|ibr|io28|mc|mch|mipi|rtc|sim1|sim2|sram|usb10)$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
|
||||
properties:
|
||||
regulator-name:
|
||||
pattern: "^v(dig18|emc33|ibr|mc|mch|mipi|rtc|sim1|sim2|sram|usb)$"
|
||||
pattern: "^v(dig18|emc33|ibr|io28|mc|mch|mipi|rtc|sim1|sim2|sram|usb)$"
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -24,6 +24,11 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
|
||||
@@ -274,6 +274,7 @@ patternProperties:
|
||||
suspend. This property is now deprecated, instead setting voltage
|
||||
for suspend mode via the API which regulator driver provides is
|
||||
recommended.
|
||||
deprecated: true
|
||||
|
||||
regulator-changeable-in-suspend:
|
||||
description: whether the default voltage and the regulator on/off
|
||||
|
||||
@@ -15,6 +15,10 @@ description: |
|
||||
supply of 2.5V to 5.5V. It can provide up to 3.5A continuous current
|
||||
capability at over 80% high efficiency.
|
||||
|
||||
The RT8092 is similar type buck converter. Compared to RT5739, it can offer
|
||||
up to 4A output current and more output voltage range to meet the application
|
||||
on most mobile products.
|
||||
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
|
||||
@@ -23,6 +27,7 @@ properties:
|
||||
enum:
|
||||
- richtek,rt5733
|
||||
- richtek,rt5739
|
||||
- richtek,rt8092
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/samsung,s2mpg10-regulator.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S2MPG10 Power Management IC regulators
|
||||
|
||||
maintainers:
|
||||
- André Draszik <andre.draszik@linaro.org>
|
||||
|
||||
description: |
|
||||
This is part of the device tree bindings for the S2MG10 Power Management IC
|
||||
(PMIC).
|
||||
|
||||
The S2MPG10 PMIC provides 10 buck and 31 LDO regulators.
|
||||
|
||||
See also Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml for
|
||||
additional information and example.
|
||||
|
||||
properties:
|
||||
# 1 LDO with possible (but limited) external control
|
||||
ldo20m:
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for a single LDO regulator.
|
||||
|
||||
allOf:
|
||||
- $ref: "#/$defs/s2mpg10-ext-control"
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay: false
|
||||
|
||||
samsung,ext-control:
|
||||
minimum: 11
|
||||
|
||||
patternProperties:
|
||||
# 10 bucks
|
||||
"^buck([1-9]|10)m$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for a single buck regulator.
|
||||
|
||||
allOf:
|
||||
- $ref: "#/$defs/s2mpg10-ext-control"
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay:
|
||||
enum: [6250, 12500, 25000]
|
||||
default: 6250
|
||||
|
||||
samsung,ext-control:
|
||||
maximum: 10
|
||||
|
||||
# 12 standard LDOs
|
||||
"^ldo(2[1-9]?|3[0-1])m$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for single LDO regulator.
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay: false
|
||||
|
||||
# 12 LDOs with possible external control
|
||||
"^ldo([3-689]|1[046-9])m$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for a single LDO regulator.
|
||||
|
||||
allOf:
|
||||
- $ref: "#/$defs/s2mpg10-ext-control"
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay: false
|
||||
|
||||
samsung,ext-control:
|
||||
maximum: 10
|
||||
|
||||
# 6 LDOs with ramp support, 5 out of those with possible external control
|
||||
"^ldo(1[1235]?|7)m$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for a single LDO regulator.
|
||||
|
||||
allOf:
|
||||
- $ref: "#/$defs/s2mpg10-ext-control"
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay:
|
||||
enum: [6250, 12500]
|
||||
default: 6250
|
||||
|
||||
samsung,ext-control:
|
||||
maximum: 10
|
||||
|
||||
$defs:
|
||||
s2mpg10-ext-control:
|
||||
properties:
|
||||
samsung,ext-control:
|
||||
description: |
|
||||
These rails can be controlled via one of several possible external
|
||||
(hardware) signals. If so, this property configures the signal the PMIC
|
||||
should monitor. For S2MPG10 rails where external control is possible other
|
||||
than ldo20m, the following values generally corresponding to the
|
||||
respective on-chip pin are valid:
|
||||
- 0 # S2MPG10_EXTCTRL_PWREN - PWREN pin
|
||||
- 1 # S2MPG10_EXTCTRL_PWREN_MIF - PWREN_MIF pin
|
||||
- 2 # S2MPG10_EXTCTRL_AP_ACTIVE_N - ~AP_ACTIVE_N pin
|
||||
- 3 # S2MPG10_EXTCTRL_CPUCL1_EN - CPUCL1_EN pin
|
||||
- 4 # S2MPG10_EXTCTRL_CPUCL1_EN2 - CPUCL1_EN & PWREN pins
|
||||
- 5 # S2MPG10_EXTCTRL_CPUCL2_EN - CPUCL2_EN pin
|
||||
- 6 # S2MPG10_EXTCTRL_CPUCL2_EN2 - CPUCL2_E2 & PWREN pins
|
||||
- 7 # S2MPG10_EXTCTRL_TPU_EN - TPU_EN pin
|
||||
- 8 # S2MPG10_EXTCTRL_TPU_EN2 - TPU_EN & ~AP_ACTIVE_N pins
|
||||
- 9 # S2MPG10_EXTCTRL_TCXO_ON - TCXO_ON pin
|
||||
- 10 # S2MPG10_EXTCTRL_TCXO_ON2 - TCXO_ON & ~AP_ACTIVE_N pins
|
||||
|
||||
For S2MPG10 ldo20m, the following values are valid
|
||||
- 11 # S2MPG10_EXTCTRL_LDO20M_EN2 - VLDO20M_EN & LDO20M_SFR
|
||||
- 12 # S2MPG10_EXTCTRL_LDO20M_EN - VLDO20M_EN pin
|
||||
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 12
|
||||
|
||||
enable-gpios:
|
||||
description:
|
||||
For rails where external control is done via a GPIO, this optional
|
||||
property describes the GPIO line used.
|
||||
|
||||
dependentRequired:
|
||||
enable-gpios: [ "samsung,ext-control" ]
|
||||
|
||||
allOf:
|
||||
# Bucks 8, 9, and LDO 1 can not be controlled externally - above definition
|
||||
# allows it and we deny it here. This approach reduces repetition.
|
||||
- if:
|
||||
anyOf:
|
||||
- required: [buck8m]
|
||||
- required: [buck9m]
|
||||
- required: [ldo1m]
|
||||
then:
|
||||
patternProperties:
|
||||
"^(buck[8-9]|ldo1)m$":
|
||||
properties:
|
||||
samsung,ext-control: false
|
||||
|
||||
additionalProperties: false
|
||||
@@ -0,0 +1,136 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/samsung,s2mpg11-regulator.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S2MPG11 Power Management IC regulators
|
||||
|
||||
maintainers:
|
||||
- André Draszik <andre.draszik@linaro.org>
|
||||
|
||||
description: |
|
||||
This is part of the device tree bindings for the S2MG11 Power Management IC
|
||||
(PMIC).
|
||||
|
||||
The S2MPG11 PMIC provides 12 buck, 1 buck-boost, and 15 LDO regulators.
|
||||
|
||||
See also Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml for
|
||||
additional information and example.
|
||||
|
||||
properties:
|
||||
buckboost:
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for the buck-boost regulator.
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay: false
|
||||
|
||||
patternProperties:
|
||||
# 12 bucks
|
||||
"^buck(([1-9]|10)s|[ad])$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for a single buck regulator.
|
||||
|
||||
allOf:
|
||||
- $ref: "#/$defs/s2mpg11-ext-control"
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay:
|
||||
enum: [6250, 12500, 25000]
|
||||
default: 6250
|
||||
|
||||
# 11 standard LDOs
|
||||
"^ldo([3-79]|1[01245])s$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for a single LDO regulator.
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay: false
|
||||
|
||||
# 2 LDOs with possible external control
|
||||
"^ldo(8|13)s$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for single LDO regulator.
|
||||
|
||||
allOf:
|
||||
- $ref: "#/$defs/s2mpg11-ext-control"
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay: false
|
||||
|
||||
# 2 LDOs with ramp support and possible external control
|
||||
"^ldo[12]s$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for a single LDO regulator.
|
||||
|
||||
allOf:
|
||||
- $ref: "#/$defs/s2mpg11-ext-control"
|
||||
|
||||
properties:
|
||||
regulator-ramp-delay:
|
||||
enum: [6250, 12500]
|
||||
default: 6250
|
||||
|
||||
$defs:
|
||||
s2mpg11-ext-control:
|
||||
properties:
|
||||
samsung,ext-control:
|
||||
description: |
|
||||
These rails can be controlled via one of several possible external
|
||||
(hardware) signals. If so, this property configures the signal the PMIC
|
||||
should monitor. The following values generally corresponding to the
|
||||
respective on-chip pin are valid:
|
||||
- 0 # S2MPG11_EXTCTRL_PWREN - PWREN pin
|
||||
- 1 # S2MPG11_EXTCTRL_PWREN_MIF - PWREN_MIF pin
|
||||
- 2 # S2MPG11_EXTCTRL_AP_ACTIVE_N - ~AP_ACTIVE_N pin
|
||||
- 3 # S2MPG11_EXTCTRL_G3D_EN - G3D_EN pin
|
||||
- 4 # S2MPG11_EXTCTRL_G3D_EN2 - G3D_EN & ~AP_ACTIVE_N pins
|
||||
- 5 # S2MPG11_EXTCTRL_AOC_VDD - AOC_VDD pin
|
||||
- 6 # S2MPG11_EXTCTRL_AOC_RET - AOC_RET pin
|
||||
- 7 # S2MPG11_EXTCTRL_UFS_EN - UFS_EN pin
|
||||
- 8 # S2MPG11_EXTCTRL_LDO13S_EN - VLDO13S_EN pin
|
||||
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 8
|
||||
|
||||
enable-gpios:
|
||||
description:
|
||||
For rails where external control is done via a GPIO, this optional
|
||||
property describes the GPIO line used.
|
||||
|
||||
dependentRequired:
|
||||
enable-gpios: [ "samsung,ext-control" ]
|
||||
|
||||
allOf:
|
||||
# Bucks 4, 6, 7 and 10 can not be controlled externally - above definition
|
||||
# allows it and we deny it here. This approach reduces repetition.
|
||||
- if:
|
||||
anyOf:
|
||||
- required: [buck4s]
|
||||
- required: [buck6s]
|
||||
- required: [buck7s]
|
||||
- required: [buck10s]
|
||||
then:
|
||||
patternProperties:
|
||||
"^buck([467]|10)s$":
|
||||
properties:
|
||||
samsung,ext-control: false
|
||||
|
||||
additionalProperties: false
|
||||
96
Documentation/devicetree/bindings/regulator/ti,tps65185.yaml
Normal file
96
Documentation/devicetree/bindings/regulator/ti,tps65185.yaml
Normal file
@@ -0,0 +1,96 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/ti,tps65185.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI TPS65185 Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Andreas Kemnade <andreas@kemnade.info>
|
||||
|
||||
description:
|
||||
TPS65185 is a Power Management IC to provide Power for EPDs with one 3.3V
|
||||
switch, 2 symmetric LDOs behind 2 DC/DC converters, and one unsymmetric
|
||||
regulator for a compensation voltage.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,tps65185
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
enable-gpios:
|
||||
description:
|
||||
PWRUP pin
|
||||
maxItems: 1
|
||||
|
||||
pwr-good-gpios:
|
||||
maxItems: 1
|
||||
|
||||
vcom-ctrl-gpios:
|
||||
maxItems: 1
|
||||
|
||||
wakeup-gpios:
|
||||
maxItems: 1
|
||||
|
||||
vin-supply: true
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
patternProperties:
|
||||
"^(vcom|vposneg|v3p3)$":
|
||||
unevaluatedProperties: false
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- pwr-good-gpios
|
||||
- vin-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic@18 {
|
||||
compatible = "ti,tps65185";
|
||||
reg = <0x18>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_tps65185_gpio>;
|
||||
pwr-good-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>;
|
||||
vcom-ctrl-gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>;
|
||||
enable-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
|
||||
wakeup-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&epdc_pmic_supply>;
|
||||
interrupts-extended = <&gpio2 0 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
regulators {
|
||||
vcom {
|
||||
regulator-name = "vcom";
|
||||
};
|
||||
|
||||
vposneg {
|
||||
regulator-name = "vposneg";
|
||||
regulator-min-microvolt = <15000000>;
|
||||
regulator-max-microvolt = <15000000>;
|
||||
};
|
||||
|
||||
v3p3 {
|
||||
regulator-name = "v3p3";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -23308,6 +23308,7 @@ F: drivers/mfd/sec*.[ch]
|
||||
F: drivers/regulator/s2*.c
|
||||
F: drivers/regulator/s5m*.c
|
||||
F: drivers/rtc/rtc-s5m.c
|
||||
F: include/dt-bindings/regulator/samsung,s2m*.h
|
||||
F: include/linux/mfd/samsung/
|
||||
|
||||
SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/mfd/samsung/core.h>
|
||||
#include <linux/mfd/samsung/rtc.h>
|
||||
#include <linux/mfd/samsung/s2mpg10.h>
|
||||
#include <linux/mfd/samsung/s2mpg11.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
@@ -216,6 +217,155 @@ static const struct regmap_config s2mpg10_regmap_config_meter = {
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_common_registers[] = {
|
||||
regmap_reg_range(0x00, 0x02), /* CHIP_ID_S, INT, INT_MASK */
|
||||
regmap_reg_range(0x0a, 0x0c), /* Speedy control */
|
||||
regmap_reg_range(0x1a, 0x27), /* Debug */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_common_ro_registers[] = {
|
||||
regmap_reg_range(0x00, 0x01), /* CHIP_ID_S, INT */
|
||||
regmap_reg_range(0x25, 0x27), /* Debug */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_common_nonvolatile_registers[] = {
|
||||
regmap_reg_range(0x00, 0x00), /* CHIP_ID_S */
|
||||
regmap_reg_range(0x02, 0x02), /* INT_MASK */
|
||||
regmap_reg_range(0x0a, 0x0c), /* Speedy control */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_common_precious_registers[] = {
|
||||
regmap_reg_range(0x01, 0x01), /* INT */
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_common_wr_table = {
|
||||
.yes_ranges = s2mpg11_common_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg11_common_registers),
|
||||
.no_ranges = s2mpg11_common_ro_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg11_common_ro_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_common_rd_table = {
|
||||
.yes_ranges = s2mpg11_common_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg11_common_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_common_volatile_table = {
|
||||
.no_ranges = s2mpg11_common_nonvolatile_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg11_common_nonvolatile_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_common_precious_table = {
|
||||
.yes_ranges = s2mpg11_common_precious_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg11_common_precious_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpg11_regmap_config_common = {
|
||||
.name = "common",
|
||||
.reg_bits = ACPM_ADDR_BITS,
|
||||
.val_bits = 8,
|
||||
.max_register = S2MPG11_COMMON_SPD_DEBUG4,
|
||||
.wr_table = &s2mpg11_common_wr_table,
|
||||
.rd_table = &s2mpg11_common_rd_table,
|
||||
.volatile_table = &s2mpg11_common_volatile_table,
|
||||
.precious_table = &s2mpg11_common_precious_table,
|
||||
.num_reg_defaults_raw = S2MPG11_COMMON_SPD_DEBUG4 + 1,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_pmic_registers[] = {
|
||||
regmap_reg_range(0x00, 0x5a), /* All PMIC registers */
|
||||
regmap_reg_range(0x5c, 0xb7), /* All PMIC registers */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_pmic_ro_registers[] = {
|
||||
regmap_reg_range(0x00, 0x05), /* INTx */
|
||||
regmap_reg_range(0x0c, 0x0d), /* STATUS OFFSRC */
|
||||
regmap_reg_range(0x98, 0x98), /* GPIO input */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_pmic_nonvolatile_registers[] = {
|
||||
regmap_reg_range(0x06, 0x0b), /* INTxM */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_pmic_precious_registers[] = {
|
||||
regmap_reg_range(0x00, 0x05), /* INTx */
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_pmic_wr_table = {
|
||||
.yes_ranges = s2mpg11_pmic_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg11_pmic_registers),
|
||||
.no_ranges = s2mpg11_pmic_ro_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg11_pmic_ro_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_pmic_rd_table = {
|
||||
.yes_ranges = s2mpg11_pmic_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg11_pmic_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_pmic_volatile_table = {
|
||||
.no_ranges = s2mpg11_pmic_nonvolatile_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg11_pmic_nonvolatile_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_pmic_precious_table = {
|
||||
.yes_ranges = s2mpg11_pmic_precious_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg11_pmic_precious_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpg11_regmap_config_pmic = {
|
||||
.name = "pmic",
|
||||
.reg_bits = ACPM_ADDR_BITS,
|
||||
.val_bits = 8,
|
||||
.max_register = S2MPG11_PMIC_LDO_SENSE2,
|
||||
.wr_table = &s2mpg11_pmic_wr_table,
|
||||
.rd_table = &s2mpg11_pmic_rd_table,
|
||||
.volatile_table = &s2mpg11_pmic_volatile_table,
|
||||
.precious_table = &s2mpg11_pmic_precious_table,
|
||||
.num_reg_defaults_raw = S2MPG11_PMIC_LDO_SENSE2 + 1,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_meter_registers[] = {
|
||||
regmap_reg_range(0x00, 0x3e), /* Meter config */
|
||||
regmap_reg_range(0x40, 0x8a), /* Meter data */
|
||||
regmap_reg_range(0x8d, 0x9c), /* Meter data */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg11_meter_ro_registers[] = {
|
||||
regmap_reg_range(0x40, 0x9c), /* Meter data */
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_meter_wr_table = {
|
||||
.yes_ranges = s2mpg11_meter_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg11_meter_registers),
|
||||
.no_ranges = s2mpg11_meter_ro_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg11_meter_ro_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_meter_rd_table = {
|
||||
.yes_ranges = s2mpg11_meter_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg11_meter_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg11_meter_volatile_table = {
|
||||
.yes_ranges = s2mpg11_meter_ro_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg11_meter_ro_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpg11_regmap_config_meter = {
|
||||
.name = "meter",
|
||||
.reg_bits = ACPM_ADDR_BITS,
|
||||
.val_bits = 8,
|
||||
.max_register = S2MPG11_METER_LPF_DATA_NTC7_2,
|
||||
.wr_table = &s2mpg11_meter_wr_table,
|
||||
.rd_table = &s2mpg11_meter_rd_table,
|
||||
.volatile_table = &s2mpg11_meter_volatile_table,
|
||||
.num_reg_defaults_raw = S2MPG11_METER_LPF_DATA_NTC7_2 + 1,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
struct sec_pmic_acpm_shared_bus_context {
|
||||
const struct acpm_handle *acpm;
|
||||
unsigned int acpm_chan_id;
|
||||
@@ -364,10 +514,12 @@ static int sec_pmic_acpm_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(regmap_pmic))
|
||||
return PTR_ERR(regmap_pmic);
|
||||
|
||||
regmap = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_RTC,
|
||||
pdata->regmap_cfg_rtc, true);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
if (pdata->regmap_cfg_rtc) {
|
||||
regmap = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_RTC,
|
||||
pdata->regmap_cfg_rtc, true);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
regmap = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_METER,
|
||||
pdata->regmap_cfg_meter, true);
|
||||
@@ -399,8 +551,18 @@ static const struct sec_pmic_acpm_platform_data s2mpg10_data = {
|
||||
.regmap_cfg_meter = &s2mpg10_regmap_config_meter,
|
||||
};
|
||||
|
||||
static const struct sec_pmic_acpm_platform_data s2mpg11_data = {
|
||||
.device_type = S2MPG11,
|
||||
.acpm_chan_id = 2,
|
||||
.speedy_channel = 1,
|
||||
.regmap_cfg_common = &s2mpg11_regmap_config_common,
|
||||
.regmap_cfg_pmic = &s2mpg11_regmap_config_pmic,
|
||||
.regmap_cfg_meter = &s2mpg11_regmap_config_meter,
|
||||
};
|
||||
|
||||
static const struct of_device_id sec_pmic_acpm_of_match[] = {
|
||||
{ .compatible = "samsung,s2mpg10-pmic", .data = &s2mpg10_data, },
|
||||
{ .compatible = "samsung,s2mpg11-pmic", .data = &s2mpg11_data, },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sec_pmic_acpm_of_match);
|
||||
@@ -408,6 +570,7 @@ MODULE_DEVICE_TABLE(of, sec_pmic_acpm_of_match);
|
||||
static struct platform_driver sec_pmic_acpm_driver = {
|
||||
.driver = {
|
||||
.name = "sec-pmic-acpm",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.pm = pm_sleep_ptr(&sec_pmic_pm_ops),
|
||||
.of_match_table = sec_pmic_acpm_of_match,
|
||||
},
|
||||
|
||||
@@ -23,9 +23,13 @@
|
||||
#include <linux/regmap.h>
|
||||
#include "sec-core.h"
|
||||
|
||||
static const struct resource s5m8767_rtc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(S5M8767_IRQ_RTCA1, "alarm"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s5m8767_devs[] = {
|
||||
MFD_CELL_NAME("s5m8767-pmic"),
|
||||
MFD_CELL_NAME("s5m-rtc"),
|
||||
MFD_CELL_RES("s5m-rtc", s5m8767_rtc_resources),
|
||||
MFD_CELL_OF("s5m8767-clk", NULL, NULL, 0, 0, "samsung,s5m8767-clk"),
|
||||
};
|
||||
|
||||
@@ -33,50 +37,72 @@ static const struct mfd_cell s2dos05_devs[] = {
|
||||
MFD_CELL_NAME("s2dos05-regulator"),
|
||||
};
|
||||
|
||||
static const struct resource s2mpg10_rtc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(S2MPG10_IRQ_RTCA0, "alarm"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpg10_devs[] = {
|
||||
MFD_CELL_NAME("s2mpg10-meter"),
|
||||
MFD_CELL_NAME("s2mpg10-regulator"),
|
||||
MFD_CELL_NAME("s2mpg10-rtc"),
|
||||
MFD_CELL_RES("s2mpg10-rtc", s2mpg10_rtc_resources),
|
||||
MFD_CELL_OF("s2mpg10-clk", NULL, NULL, 0, 0, "samsung,s2mpg10-clk"),
|
||||
MFD_CELL_OF("s2mpg10-gpio", NULL, NULL, 0, 0, "samsung,s2mpg10-gpio"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpg11_devs[] = {
|
||||
MFD_CELL_NAME("s2mpg11-meter"),
|
||||
MFD_CELL_NAME("s2mpg11-regulator"),
|
||||
MFD_CELL_OF("s2mpg11-gpio", NULL, NULL, 0, 0, "samsung,s2mpg11-gpio"),
|
||||
};
|
||||
|
||||
static const struct resource s2mps11_rtc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(S2MPS11_IRQ_RTCA0, "alarm"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps11_devs[] = {
|
||||
MFD_CELL_NAME("s2mps11-regulator"),
|
||||
MFD_CELL_NAME("s2mps14-rtc"),
|
||||
MFD_CELL_RES("s2mps14-rtc", s2mps11_rtc_resources),
|
||||
MFD_CELL_OF("s2mps11-clk", NULL, NULL, 0, 0, "samsung,s2mps11-clk"),
|
||||
};
|
||||
|
||||
static const struct resource s2mps14_rtc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(S2MPS14_IRQ_RTCA0, "alarm"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps13_devs[] = {
|
||||
MFD_CELL_NAME("s2mps13-regulator"),
|
||||
MFD_CELL_NAME("s2mps13-rtc"),
|
||||
MFD_CELL_RES("s2mps13-rtc", s2mps14_rtc_resources),
|
||||
MFD_CELL_OF("s2mps13-clk", NULL, NULL, 0, 0, "samsung,s2mps13-clk"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps14_devs[] = {
|
||||
MFD_CELL_NAME("s2mps14-regulator"),
|
||||
MFD_CELL_NAME("s2mps14-rtc"),
|
||||
MFD_CELL_RES("s2mps14-rtc", s2mps14_rtc_resources),
|
||||
MFD_CELL_OF("s2mps14-clk", NULL, NULL, 0, 0, "samsung,s2mps14-clk"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps15_devs[] = {
|
||||
MFD_CELL_NAME("s2mps15-regulator"),
|
||||
MFD_CELL_NAME("s2mps15-rtc"),
|
||||
MFD_CELL_RES("s2mps15-rtc", s2mps14_rtc_resources),
|
||||
MFD_CELL_OF("s2mps13-clk", NULL, NULL, 0, 0, "samsung,s2mps13-clk"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpa01_devs[] = {
|
||||
MFD_CELL_NAME("s2mpa01-pmic"),
|
||||
MFD_CELL_NAME("s2mps14-rtc"),
|
||||
MFD_CELL_RES("s2mps14-rtc", s2mps14_rtc_resources),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpu02_devs[] = {
|
||||
MFD_CELL_NAME("s2mpu02-regulator"),
|
||||
};
|
||||
|
||||
static const struct resource s2mpu05_rtc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(S2MPU05_IRQ_RTCA0, "alarm"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpu05_devs[] = {
|
||||
MFD_CELL_NAME("s2mpu05-regulator"),
|
||||
MFD_CELL_NAME("s2mps15-rtc"),
|
||||
MFD_CELL_RES("s2mps15-rtc", s2mpu05_rtc_resources),
|
||||
};
|
||||
|
||||
static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
|
||||
@@ -84,8 +110,13 @@ static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
|
||||
unsigned int val;
|
||||
|
||||
/* For s2mpg1x, the revision is in a different regmap */
|
||||
if (sec_pmic->device_type == S2MPG10)
|
||||
switch (sec_pmic->device_type) {
|
||||
case S2MPG10:
|
||||
case S2MPG11:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* For each device type, the REG_ID is always the first register */
|
||||
if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
|
||||
@@ -143,6 +174,7 @@ sec_pmic_parse_dt_pdata(struct device *dev)
|
||||
int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq,
|
||||
struct regmap *regmap, struct i2c_client *client)
|
||||
{
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
struct sec_platform_data *pdata;
|
||||
const struct mfd_cell *sec_devs;
|
||||
struct sec_pmic_dev *sec_pmic;
|
||||
@@ -167,9 +199,9 @@ int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq,
|
||||
|
||||
sec_pmic->pdata = pdata;
|
||||
|
||||
ret = sec_irq_init(sec_pmic);
|
||||
if (ret)
|
||||
return ret;
|
||||
irq_data = sec_irq_init(sec_pmic);
|
||||
if (IS_ERR(irq_data))
|
||||
return PTR_ERR(irq_data);
|
||||
|
||||
pm_runtime_set_active(sec_pmic->dev);
|
||||
|
||||
@@ -190,6 +222,10 @@ int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq,
|
||||
sec_devs = s2mpg10_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mpg10_devs);
|
||||
break;
|
||||
case S2MPG11:
|
||||
sec_devs = s2mpg11_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mpg11_devs);
|
||||
break;
|
||||
case S2MPS11X:
|
||||
sec_devs = s2mps11_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mps11_devs);
|
||||
@@ -220,7 +256,7 @@ int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq,
|
||||
sec_pmic->device_type);
|
||||
}
|
||||
ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs,
|
||||
NULL, 0, NULL);
|
||||
NULL, 0, regmap_irq_get_domain(irq_data));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -18,6 +18,6 @@ int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq,
|
||||
struct regmap *regmap, struct i2c_client *client);
|
||||
void sec_pmic_shutdown(struct device *dev);
|
||||
|
||||
int sec_irq_init(struct sec_pmic_dev *sec_pmic);
|
||||
struct regmap_irq_chip_data *sec_irq_init(struct sec_pmic_dev *sec_pmic);
|
||||
|
||||
#endif /* __SEC_CORE_INT_H */
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/mfd/samsung/core.h>
|
||||
#include <linux/mfd/samsung/irq.h>
|
||||
#include <linux/mfd/samsung/s2mpg10.h>
|
||||
#include <linux/mfd/samsung/s2mpg11.h>
|
||||
#include <linux/mfd/samsung/s2mps11.h>
|
||||
#include <linux/mfd/samsung/s2mps14.h>
|
||||
#include <linux/mfd/samsung/s2mpu02.h>
|
||||
@@ -79,6 +80,64 @@ static const struct regmap_irq s2mpg10_pmic_irqs[] = {
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWR_WARN_CH7, 5, S2MPG10_IRQ_PWR_WARN_CH7_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq s2mpg11_irqs[] = {
|
||||
REGMAP_IRQ_REG(S2MPG11_COMMON_IRQ_PMIC, 0, S2MPG11_COMMON_INT_SRC_PMIC),
|
||||
/* No documentation or other reference for remaining bits */
|
||||
REGMAP_IRQ_REG(S2MPG11_COMMON_IRQ_UNUSED, 0, GENMASK(7, 1)),
|
||||
};
|
||||
|
||||
static const struct regmap_irq s2mpg11_pmic_irqs[] = {
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWRONF, 0, S2MPG11_IRQ_PWRONF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWRONR, 0, S2MPG11_IRQ_PWRONR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PIF_TIMEOUT_MIF, 0, S2MPG11_IRQ_PIF_TIMEOUT_MIF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PIF_TIMEOUTS, 0, S2MPG11_IRQ_PIF_TIMEOUTS_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_WTSR, 0, S2MPG11_IRQ_WTSR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_SPD_ABNORMAL_STOP, 0, S2MPG11_IRQ_SPD_ABNORMAL_STOP_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_SPD_PARITY_ERR, 0, S2MPG11_IRQ_SPD_PARITY_ERR_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_140C, 1, S2MPG11_IRQ_INT140C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_120C, 1, S2MPG11_IRQ_INT120C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_TSD, 1, S2MPG11_IRQ_TSD_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_WRST, 1, S2MPG11_IRQ_WRST_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_NTC_CYCLE_DONE, 1, S2MPG11_IRQ_NTC_CYCLE_DONE_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PMETER_OVERF, 1, S2MPG11_IRQ_PMETER_OVERF_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B1S, 2, S2MPG11_IRQ_OCP_B1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B2S, 2, S2MPG11_IRQ_OCP_B2S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B3S, 2, S2MPG11_IRQ_OCP_B3S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B4S, 2, S2MPG11_IRQ_OCP_B4S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B5S, 2, S2MPG11_IRQ_OCP_B5S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B6S, 2, S2MPG11_IRQ_OCP_B6S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B7S, 2, S2MPG11_IRQ_OCP_B7S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B8S, 2, S2MPG11_IRQ_OCP_B8S_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B9S, 3, S2MPG11_IRQ_OCP_B9S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_B10S, 3, S2MPG11_IRQ_OCP_B10S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_BDS, 3, S2MPG11_IRQ_OCP_BDS_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_BAS, 3, S2MPG11_IRQ_OCP_BAS_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_OCP_BBS, 3, S2MPG11_IRQ_OCP_BBS_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_WLWP_ACC, 3, S2MPG11_IRQ_WLWP_ACC_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_SPD_SRP_PKT_RST, 3, S2MPG11_IRQ_SPD_SRP_PKT_RST_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWR_WARN_CH0, 4, S2MPG11_IRQ_PWR_WARN_CH0_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWR_WARN_CH1, 4, S2MPG11_IRQ_PWR_WARN_CH1_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWR_WARN_CH2, 4, S2MPG11_IRQ_PWR_WARN_CH2_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWR_WARN_CH3, 4, S2MPG11_IRQ_PWR_WARN_CH3_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWR_WARN_CH4, 4, S2MPG11_IRQ_PWR_WARN_CH4_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWR_WARN_CH5, 4, S2MPG11_IRQ_PWR_WARN_CH5_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWR_WARN_CH6, 4, S2MPG11_IRQ_PWR_WARN_CH6_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_PWR_WARN_CH7, 4, S2MPG11_IRQ_PWR_WARN_CH7_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_NTC_WARN_CH0, 5, S2MPG11_IRQ_NTC_WARN_CH0_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_NTC_WARN_CH1, 5, S2MPG11_IRQ_NTC_WARN_CH1_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_NTC_WARN_CH2, 5, S2MPG11_IRQ_NTC_WARN_CH2_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_NTC_WARN_CH3, 5, S2MPG11_IRQ_NTC_WARN_CH3_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_NTC_WARN_CH4, 5, S2MPG11_IRQ_NTC_WARN_CH4_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_NTC_WARN_CH5, 5, S2MPG11_IRQ_NTC_WARN_CH5_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_NTC_WARN_CH6, 5, S2MPG11_IRQ_NTC_WARN_CH6_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG11_IRQ_NTC_WARN_CH7, 5, S2MPG11_IRQ_NTC_WARN_CH7_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq s2mps11_irqs[] = {
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_PWRONF, 0, S2MPS11_IRQ_PWRONF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_PWRONR, 0, S2MPS11_IRQ_PWRONR_MASK),
|
||||
@@ -186,7 +245,7 @@ static const struct regmap_irq s5m8767_irqs[] = {
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_WTSR, 2, S5M8767_IRQ_WTSR_MASK),
|
||||
};
|
||||
|
||||
/* All S2MPG10 interrupt sources are read-only and don't require clearing */
|
||||
/* All S2MPG1x interrupt sources are read-only and don't require clearing */
|
||||
static const struct regmap_irq_chip s2mpg10_irq_chip = {
|
||||
.name = "s2mpg10",
|
||||
.status_base = S2MPG10_COMMON_INT,
|
||||
@@ -205,6 +264,25 @@ static const struct regmap_irq_chip s2mpg10_irq_chip_pmic = {
|
||||
.num_irqs = ARRAY_SIZE(s2mpg10_pmic_irqs),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip s2mpg11_irq_chip = {
|
||||
.name = "s2mpg11",
|
||||
.status_base = S2MPG11_COMMON_INT,
|
||||
.mask_base = S2MPG11_COMMON_INT_MASK,
|
||||
.num_regs = 1,
|
||||
.irqs = s2mpg11_irqs,
|
||||
.num_irqs = ARRAY_SIZE(s2mpg11_irqs),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip s2mpg11_irq_chip_pmic = {
|
||||
.name = "s2mpg11-pmic",
|
||||
.domain_suffix = "pmic",
|
||||
.status_base = S2MPG11_PMIC_INT1,
|
||||
.mask_base = S2MPG11_PMIC_INT1M,
|
||||
.num_regs = 6,
|
||||
.irqs = s2mpg11_pmic_irqs,
|
||||
.num_irqs = ARRAY_SIZE(s2mpg11_pmic_irqs),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip s2mps11_irq_chip = {
|
||||
.name = "s2mps11",
|
||||
.irqs = s2mps11_irqs,
|
||||
@@ -268,26 +346,28 @@ static const struct regmap_irq_chip s5m8767_irq_chip = {
|
||||
.ack_base = S5M8767_REG_INT1,
|
||||
};
|
||||
|
||||
static int s2mpg1x_add_chained_irq_chip(struct device *dev, struct regmap *regmap, int pirq,
|
||||
struct regmap_irq_chip_data *parent,
|
||||
const struct regmap_irq_chip *chip,
|
||||
struct regmap_irq_chip_data **data)
|
||||
static struct regmap_irq_chip_data *
|
||||
s2mpg1x_add_chained_pmic(struct sec_pmic_dev *sec_pmic, int pirq,
|
||||
struct regmap_irq_chip_data *parent, const struct regmap_irq_chip *chip)
|
||||
{
|
||||
struct device *dev = sec_pmic->dev;
|
||||
struct regmap_irq_chip_data *data;
|
||||
int irq, ret;
|
||||
|
||||
irq = regmap_irq_get_virq(parent, pirq);
|
||||
if (irq < 0)
|
||||
return dev_err_probe(dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n", pirq,
|
||||
chip->name);
|
||||
return dev_err_ptr_probe(dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n",
|
||||
pirq, chip->name);
|
||||
|
||||
ret = devm_regmap_add_irq_chip(dev, regmap, irq, IRQF_ONESHOT | IRQF_SHARED, 0, chip, data);
|
||||
ret = devm_regmap_add_irq_chip(dev, sec_pmic->regmap_pmic, irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED, 0, chip, &data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name);
|
||||
return dev_err_ptr_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name);
|
||||
|
||||
return 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
static int sec_irq_init_s2mpg1x(struct sec_pmic_dev *sec_pmic)
|
||||
static struct regmap_irq_chip_data *sec_irq_init_s2mpg1x(struct sec_pmic_dev *sec_pmic)
|
||||
{
|
||||
const struct regmap_irq_chip *irq_chip, *chained_irq_chip;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
@@ -301,28 +381,33 @@ static int sec_irq_init_s2mpg1x(struct sec_pmic_dev *sec_pmic)
|
||||
chained_irq_chip = &s2mpg10_irq_chip_pmic;
|
||||
chained_pirq = S2MPG10_COMMON_IRQ_PMIC;
|
||||
break;
|
||||
case S2MPG11:
|
||||
irq_chip = &s2mpg11_irq_chip;
|
||||
chained_irq_chip = &s2mpg11_irq_chip_pmic;
|
||||
chained_pirq = S2MPG11_COMMON_IRQ_PMIC;
|
||||
break;
|
||||
default:
|
||||
return dev_err_probe(sec_pmic->dev, -EINVAL, "Unsupported device type %d\n",
|
||||
sec_pmic->device_type);
|
||||
return dev_err_ptr_probe(sec_pmic->dev, -EINVAL, "Unsupported device type %d\n",
|
||||
sec_pmic->device_type);
|
||||
}
|
||||
|
||||
regmap_common = dev_get_regmap(sec_pmic->dev, "common");
|
||||
if (!regmap_common)
|
||||
return dev_err_probe(sec_pmic->dev, -EINVAL, "No 'common' regmap %d\n",
|
||||
sec_pmic->device_type);
|
||||
return dev_err_ptr_probe(sec_pmic->dev, -EINVAL, "No 'common' regmap %d\n",
|
||||
sec_pmic->device_type);
|
||||
|
||||
ret = devm_regmap_add_irq_chip(sec_pmic->dev, regmap_common, sec_pmic->irq, IRQF_ONESHOT, 0,
|
||||
irq_chip, &irq_data);
|
||||
if (ret)
|
||||
return dev_err_probe(sec_pmic->dev, ret, "Failed to add %s IRQ chip\n",
|
||||
irq_chip->name);
|
||||
return dev_err_ptr_probe(sec_pmic->dev, ret, "Failed to add %s IRQ chip\n",
|
||||
irq_chip->name);
|
||||
|
||||
return s2mpg1x_add_chained_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic, chained_pirq,
|
||||
irq_data, chained_irq_chip, &sec_pmic->irq_data);
|
||||
return s2mpg1x_add_chained_pmic(sec_pmic, chained_pirq, irq_data, chained_irq_chip);
|
||||
}
|
||||
|
||||
int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
struct regmap_irq_chip_data *sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
{
|
||||
struct regmap_irq_chip_data *sec_irq_chip_data;
|
||||
const struct regmap_irq_chip *sec_irq_chip;
|
||||
int ret;
|
||||
|
||||
@@ -331,11 +416,12 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
sec_irq_chip = &s5m8767_irq_chip;
|
||||
break;
|
||||
case S2DOS05:
|
||||
return 0;
|
||||
return NULL;
|
||||
case S2MPA01:
|
||||
sec_irq_chip = &s2mps14_irq_chip;
|
||||
break;
|
||||
case S2MPG10:
|
||||
case S2MPG11:
|
||||
return sec_irq_init_s2mpg1x(sec_pmic);
|
||||
case S2MPS11X:
|
||||
sec_irq_chip = &s2mps11_irq_chip;
|
||||
@@ -356,30 +442,22 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
sec_irq_chip = &s2mpu05_irq_chip;
|
||||
break;
|
||||
default:
|
||||
return dev_err_probe(sec_pmic->dev, -EINVAL,
|
||||
"Unsupported device type %d\n",
|
||||
sec_pmic->device_type);
|
||||
return dev_err_ptr_probe(sec_pmic->dev, -EINVAL, "Unsupported device type %d\n",
|
||||
sec_pmic->device_type);
|
||||
}
|
||||
|
||||
if (!sec_pmic->irq) {
|
||||
dev_warn(sec_pmic->dev,
|
||||
"No interrupt specified, no interrupts\n");
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic,
|
||||
sec_pmic->irq, IRQF_ONESHOT,
|
||||
0, sec_irq_chip, &sec_pmic->irq_data);
|
||||
0, sec_irq_chip, &sec_irq_chip_data);
|
||||
if (ret)
|
||||
return dev_err_probe(sec_pmic->dev, ret,
|
||||
"Failed to add %s IRQ chip\n",
|
||||
sec_irq_chip->name);
|
||||
return dev_err_ptr_probe(sec_pmic->dev, ret, "Failed to add %s IRQ chip\n",
|
||||
sec_irq_chip->name);
|
||||
|
||||
/*
|
||||
* The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
|
||||
* so the interrupt number must be consistent.
|
||||
*/
|
||||
BUILD_BUG_ON(((enum s2mps14_irq)S2MPS11_IRQ_RTCA0) != S2MPS14_IRQ_RTCA0);
|
||||
|
||||
return 0;
|
||||
return sec_irq_chip_data;
|
||||
}
|
||||
|
||||
@@ -659,6 +659,15 @@ config REGULATOR_MAX77650
|
||||
Semiconductor. This device has a SIMO with three independent
|
||||
power rails and an LDO.
|
||||
|
||||
config REGULATOR_MAX77675
|
||||
tristate "Maxim MAX77675 regulator driver"
|
||||
depends on I2C && OF
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver controls the Maxim MAX77675 power regulator via I2C.
|
||||
It supports four programmable buck-boost outputs.
|
||||
Say Y here to enable the regulator driver
|
||||
|
||||
config REGULATOR_MAX77857
|
||||
tristate "ADI MAX77857/MAX77831 regulator support"
|
||||
depends on I2C
|
||||
@@ -1394,6 +1403,15 @@ config REGULATOR_RT6245
|
||||
It can support up to 14A output current and adjustable output voltage
|
||||
from 0.4375V to 1.3875V, per step 12.5mV.
|
||||
|
||||
config REGULATOR_RT8092
|
||||
tristate "Richtek RT8092 voltage regulator"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
The RT8092 is a peak-current mode PWM step-down DC/DC converter with
|
||||
I2C control interface. It is capable of delivering 4A continuing
|
||||
current over a wide input range from 2.5V to 5.5V.
|
||||
|
||||
config REGULATOR_RTQ2134
|
||||
tristate "Richtek RTQ2134 SubPMIC Regulator"
|
||||
depends on I2C
|
||||
@@ -1690,6 +1708,17 @@ config REGULATOR_TPS65132
|
||||
This driver supports TPS65132 single inductor - dual output
|
||||
power supply specifically designed for display panels.
|
||||
|
||||
config REGULATOR_TPS65185
|
||||
tristate "TI TPS65185 EPD regulator"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports the TPS65185 voltage regulator chip
|
||||
which is used to provide power to Electronic Paper Displays
|
||||
so it is found in E-Book readers.
|
||||
If HWWON is enabled, it also provides temperature measurement.
|
||||
|
||||
|
||||
config REGULATOR_TPS65217
|
||||
tristate "TI TPS65217 Power regulators"
|
||||
depends on MFD_TPS65217
|
||||
|
||||
@@ -79,6 +79,7 @@ obj-$(CONFIG_REGULATOR_MAX77503) += max77503-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MAX77541) += max77541-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MAX77675) += max77675-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8893) += max8893.o
|
||||
@@ -161,6 +162,7 @@ obj-$(CONFIG_REGULATOR_RT5759) += rt5759-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RT6190) += rt6190-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RT8092) += rt8092.o
|
||||
obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RTQ2134) += rtq2134-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RTQ6752) += rtq6752-regulator.o
|
||||
@@ -192,6 +194,7 @@ obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65086) += tps65086-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65185) += tps65185.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65219) += tps65219-regulator.o
|
||||
|
||||
@@ -44,6 +44,8 @@ static LIST_HEAD(regulator_supply_alias_list);
|
||||
static LIST_HEAD(regulator_coupler_list);
|
||||
static bool has_full_constraints;
|
||||
|
||||
static const struct bus_type regulator_bus;
|
||||
|
||||
static struct dentry *debugfs_root;
|
||||
|
||||
/*
|
||||
@@ -96,6 +98,7 @@ struct regulator_event_work {
|
||||
unsigned long event;
|
||||
};
|
||||
|
||||
static int _regulator_enable(struct regulator *regulator);
|
||||
static int _regulator_is_enabled(struct regulator_dev *rdev);
|
||||
static int _regulator_disable(struct regulator *regulator);
|
||||
static int _regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags);
|
||||
@@ -1183,7 +1186,7 @@ static void print_constraints_debug(struct regulator_dev *rdev)
|
||||
count += scnprintf(buf + count, len - count, "standby ");
|
||||
|
||||
if (constraints->pw_budget_mW)
|
||||
count += scnprintf(buf + count, len - count, "%d mW budget",
|
||||
count += scnprintf(buf + count, len - count, "%d mW budget ",
|
||||
constraints->pw_budget_mW);
|
||||
|
||||
if (!count)
|
||||
@@ -1430,6 +1433,7 @@ static int handle_notify_limits(struct regulator_dev *rdev,
|
||||
/**
|
||||
* set_machine_constraints - sets regulator constraints
|
||||
* @rdev: regulator source
|
||||
* @is_locked: whether or not this is called with locks held already
|
||||
*
|
||||
* Allows platform initialisation code to define and constrain
|
||||
* regulator circuits e.g. valid voltage/current ranges, etc. NOTE:
|
||||
@@ -1439,11 +1443,39 @@ static int handle_notify_limits(struct regulator_dev *rdev,
|
||||
*
|
||||
* Return: 0 on success or a negative error number on failure.
|
||||
*/
|
||||
static int set_machine_constraints(struct regulator_dev *rdev)
|
||||
static int set_machine_constraints(struct regulator_dev *rdev,
|
||||
bool is_locked)
|
||||
{
|
||||
int ret = 0;
|
||||
const struct regulator_ops *ops = rdev->desc->ops;
|
||||
|
||||
/*
|
||||
* If there is no mechanism for controlling the regulator then
|
||||
* flag it as always_on so we don't end up duplicating checks
|
||||
* for this so much. Note that we could control the state of
|
||||
* a supply to control the output on a regulator that has no
|
||||
* direct control.
|
||||
*/
|
||||
if (!rdev->ena_pin && !ops->enable) {
|
||||
if (rdev->supply_name && !rdev->supply)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (rdev->supply)
|
||||
rdev->constraints->always_on =
|
||||
rdev->supply->rdev->constraints->always_on;
|
||||
else
|
||||
rdev->constraints->always_on = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we want to enable this regulator, make sure that we know the
|
||||
* supplying regulator.
|
||||
*/
|
||||
if (rdev->constraints->always_on || rdev->constraints->boot_on) {
|
||||
if (rdev->supply_name && !rdev->supply)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
ret = machine_constraints_voltage(rdev, rdev->constraints);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
@@ -1609,44 +1641,24 @@ static int set_machine_constraints(struct regulator_dev *rdev)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no mechanism for controlling the regulator then
|
||||
* flag it as always_on so we don't end up duplicating checks
|
||||
* for this so much. Note that we could control the state of
|
||||
* a supply to control the output on a regulator that has no
|
||||
* direct control.
|
||||
*/
|
||||
if (!rdev->ena_pin && !ops->enable) {
|
||||
if (rdev->supply_name && !rdev->supply)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (rdev->supply)
|
||||
rdev->constraints->always_on =
|
||||
rdev->supply->rdev->constraints->always_on;
|
||||
else
|
||||
rdev->constraints->always_on = true;
|
||||
}
|
||||
|
||||
/* If the constraints say the regulator should be on at this point
|
||||
* and we have control then make sure it is enabled.
|
||||
*/
|
||||
if (rdev->constraints->always_on || rdev->constraints->boot_on) {
|
||||
bool supply_enabled = false;
|
||||
|
||||
/* If we want to enable this regulator, make sure that we know
|
||||
* the supplying regulator.
|
||||
*/
|
||||
if (rdev->supply_name && !rdev->supply)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
/* If supplying regulator has already been enabled,
|
||||
/* We have ensured a potential supply has been resolved above.
|
||||
*
|
||||
* If supplying regulator has already been enabled,
|
||||
* it's not intended to have use_count increment
|
||||
* when rdev is only boot-on.
|
||||
*/
|
||||
if (rdev->supply &&
|
||||
(rdev->constraints->always_on ||
|
||||
!regulator_is_enabled(rdev->supply))) {
|
||||
ret = regulator_enable(rdev->supply);
|
||||
ret = (is_locked
|
||||
? _regulator_enable(rdev->supply)
|
||||
: regulator_enable(rdev->supply));
|
||||
if (ret < 0) {
|
||||
_regulator_put(rdev->supply);
|
||||
rdev->supply = NULL;
|
||||
@@ -1774,6 +1786,15 @@ static int register_regulator_event_forwarding(struct regulator_dev *rdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unregister_regulator_event_forwarding(struct regulator_dev *rdev)
|
||||
{
|
||||
if (!rdev->supply_fwd_nb.notifier_call)
|
||||
return;
|
||||
|
||||
regulator_unregister_notifier(rdev->supply, &rdev->supply_fwd_nb);
|
||||
rdev->supply_fwd_nb.notifier_call = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_supply - set regulator supply regulator
|
||||
* @rdev: regulator (locked)
|
||||
@@ -2162,6 +2183,8 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
|
||||
struct regulator_dev *r;
|
||||
struct device *dev = rdev->dev.parent;
|
||||
struct ww_acquire_ctx ww_ctx;
|
||||
struct regulator *supply;
|
||||
bool do_final_setup;
|
||||
int ret = 0;
|
||||
|
||||
/* No supply to resolve? */
|
||||
@@ -2169,7 +2192,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
|
||||
return 0;
|
||||
|
||||
/* Supply already resolved? (fast-path without locking contention) */
|
||||
if (rdev->supply)
|
||||
if (rdev->supply && !rdev->constraints_pending)
|
||||
return 0;
|
||||
|
||||
/* first do a dt based lookup on the node described in the virtual
|
||||
@@ -2250,49 +2273,115 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
|
||||
|
||||
/* Supply just resolved by a concurrent task? */
|
||||
if (rdev->supply) {
|
||||
/* Constraints might still be pending due to concurrency. */
|
||||
bool done = !rdev->constraints_pending;
|
||||
|
||||
supply = rdev->supply;
|
||||
|
||||
regulator_unlock_two(rdev, r, &ww_ctx);
|
||||
put_device(&r->dev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = set_supply(rdev, r);
|
||||
if (ret < 0) {
|
||||
regulator_unlock_two(rdev, r, &ww_ctx);
|
||||
put_device(&r->dev);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Supply resolved by concurrent task, and constraints set as
|
||||
* well (or not required): fast path.
|
||||
*/
|
||||
if (done)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Automatically register for event forwarding from the new supply.
|
||||
* This creates the downstream propagation link for events like
|
||||
* under-voltage.
|
||||
*/
|
||||
ret = register_regulator_event_forwarding(rdev);
|
||||
if (ret < 0)
|
||||
rdev_warn(rdev, "Failed to register event forwarding: %pe\n",
|
||||
ERR_PTR(ret));
|
||||
|
||||
regulator_unlock_two(rdev, r, &ww_ctx);
|
||||
|
||||
/* rdev->supply was created in set_supply() */
|
||||
link_and_create_debugfs(rdev->supply, r, &rdev->dev);
|
||||
|
||||
/*
|
||||
* In set_machine_constraints() we may have turned this regulator on
|
||||
* but we couldn't propagate to the supply if it hadn't been resolved
|
||||
* yet. Do it now.
|
||||
*/
|
||||
if (rdev->use_count) {
|
||||
ret = regulator_enable(rdev->supply);
|
||||
do_final_setup = false;
|
||||
} else {
|
||||
ret = set_supply(rdev, r);
|
||||
if (ret < 0) {
|
||||
_regulator_put(rdev->supply);
|
||||
rdev->supply = NULL;
|
||||
regulator_unlock_two(rdev, r, &ww_ctx);
|
||||
put_device(&r->dev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
supply = rdev->supply;
|
||||
|
||||
/*
|
||||
* Automatically register for event forwarding from the new
|
||||
* supply. This creates the downstream propagation link for
|
||||
* events like under-voltage.
|
||||
*/
|
||||
ret = register_regulator_event_forwarding(rdev);
|
||||
if (ret < 0) {
|
||||
rdev_warn(rdev,
|
||||
"Failed to register event forwarding: %pe\n",
|
||||
ERR_PTR(ret));
|
||||
|
||||
goto unset_supply;
|
||||
}
|
||||
|
||||
regulator_unlock_two(rdev, r, &ww_ctx);
|
||||
|
||||
do_final_setup = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we have the supply, we can retry setting the machine
|
||||
* constraints, if necessary.
|
||||
*/
|
||||
regulator_lock_dependent(rdev, &ww_ctx);
|
||||
if (rdev->constraints_pending) {
|
||||
if (!rdev->supply) {
|
||||
/*
|
||||
* Supply could have been released by another task that
|
||||
* failed to set the constraints or event forwarding.
|
||||
*/
|
||||
regulator_unlock_dependent(rdev, &ww_ctx);
|
||||
ret = -EPROBE_DEFER;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = set_machine_constraints(rdev, true);
|
||||
if (ret < 0) {
|
||||
regulator_unlock_dependent(rdev, &ww_ctx);
|
||||
|
||||
rdev_warn(rdev,
|
||||
"Failed to set machine constraints: %pe\n",
|
||||
ERR_PTR(ret));
|
||||
|
||||
regulator_lock_two(rdev, r, &ww_ctx);
|
||||
|
||||
if (supply != rdev->supply) {
|
||||
/*
|
||||
* Supply could have been released by another
|
||||
* task that got here before us. If it did, it
|
||||
* will have released 'supply' (i.e. the
|
||||
* previous rdev->supply) and we shouldn't do
|
||||
* that again via unset_supply.
|
||||
*/
|
||||
regulator_unlock_two(rdev, r, &ww_ctx);
|
||||
goto out;
|
||||
}
|
||||
|
||||
unregister_regulator_event_forwarding(rdev);
|
||||
rdev->constraints_pending = true;
|
||||
goto unset_supply;
|
||||
}
|
||||
rdev->constraints_pending = false;
|
||||
}
|
||||
regulator_unlock_dependent(rdev, &ww_ctx);
|
||||
|
||||
if (!do_final_setup)
|
||||
goto out;
|
||||
|
||||
/* rdev->supply was created in set_supply() */
|
||||
link_and_create_debugfs(rdev->supply, rdev->supply->rdev, &rdev->dev);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
unset_supply:
|
||||
lockdep_assert_held_once(&rdev->mutex.base);
|
||||
lockdep_assert_held_once(&r->mutex.base);
|
||||
rdev->supply = NULL;
|
||||
regulator_unlock_two(rdev, supply->rdev, &ww_ctx);
|
||||
|
||||
regulator_put(supply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* common pre-checks for regulator requests */
|
||||
@@ -5692,16 +5781,6 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
|
||||
&rdev->bypass_count);
|
||||
}
|
||||
|
||||
static int regulator_register_resolve_supply(struct device *dev, void *data)
|
||||
{
|
||||
struct regulator_dev *rdev = dev_to_rdev(dev);
|
||||
|
||||
if (regulator_resolve_supply(rdev))
|
||||
rdev_dbg(rdev, "unable to resolve supply\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int regulator_coupler_register(struct regulator_coupler *coupler)
|
||||
{
|
||||
mutex_lock(®ulator_list_mutex);
|
||||
@@ -5920,10 +5999,10 @@ regulator_register(struct device *dev,
|
||||
struct regulator_config *config = NULL;
|
||||
static atomic_t regulator_no = ATOMIC_INIT(-1);
|
||||
struct regulator_dev *rdev;
|
||||
bool tried_supply_resolve = false;
|
||||
bool dangling_cfg_gpiod = false;
|
||||
bool dangling_of_gpiod = false;
|
||||
int ret, i;
|
||||
bool resolved_early = false;
|
||||
|
||||
if (cfg == NULL)
|
||||
return ERR_PTR(-EINVAL);
|
||||
@@ -6061,17 +6140,6 @@ regulator_register(struct device *dev,
|
||||
goto wash;
|
||||
}
|
||||
|
||||
if ((rdev->supply_name && !rdev->supply) &&
|
||||
(rdev->constraints->always_on ||
|
||||
rdev->constraints->boot_on)) {
|
||||
ret = regulator_resolve_supply(rdev);
|
||||
if (ret)
|
||||
rdev_dbg(rdev, "unable to resolve supply early: %pe\n",
|
||||
ERR_PTR(ret));
|
||||
|
||||
resolved_early = true;
|
||||
}
|
||||
|
||||
if (config->ena_gpiod) {
|
||||
ret = regulator_ena_gpio_request(rdev, config);
|
||||
if (ret != 0) {
|
||||
@@ -6084,10 +6152,11 @@ regulator_register(struct device *dev,
|
||||
dangling_of_gpiod = false;
|
||||
}
|
||||
|
||||
ret = set_machine_constraints(rdev);
|
||||
if (ret == -EPROBE_DEFER && !resolved_early) {
|
||||
/* Regulator might be in bypass mode and so needs its supply
|
||||
* to set the constraints
|
||||
ret = set_machine_constraints(rdev, false);
|
||||
if (ret == -EPROBE_DEFER) {
|
||||
/* Regulator might be in bypass mode or an always-on or boot-on
|
||||
* regulator and so needs its supply to set the constraints or
|
||||
* for enable.
|
||||
*/
|
||||
/* FIXME: this currently triggers a chicken-and-egg problem
|
||||
* when creating -SUPPLY symlink in sysfs to a regulator
|
||||
@@ -6097,13 +6166,17 @@ regulator_register(struct device *dev,
|
||||
rdev->supply_name);
|
||||
ret = regulator_resolve_supply(rdev);
|
||||
if (!ret)
|
||||
ret = set_machine_constraints(rdev);
|
||||
ret = set_machine_constraints(rdev, false);
|
||||
else
|
||||
rdev_dbg(rdev, "unable to resolve supply early: %pe\n",
|
||||
ERR_PTR(ret));
|
||||
tried_supply_resolve = true;
|
||||
}
|
||||
if (ret < 0) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
goto wash;
|
||||
rdev->constraints_pending = true;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto wash;
|
||||
|
||||
ret = regulator_init_coupling(rdev);
|
||||
if (ret < 0)
|
||||
@@ -6132,6 +6205,37 @@ regulator_register(struct device *dev,
|
||||
if (ret != 0)
|
||||
goto unset_supplies;
|
||||
|
||||
if (!tried_supply_resolve) {
|
||||
/*
|
||||
* As an optimisation, try to resolve our supply (if any) now to
|
||||
* avoid adding the bus device. Errors are not fatal at this
|
||||
* stage, we'll simply try again later.
|
||||
*/
|
||||
ret = regulator_resolve_supply(rdev);
|
||||
if (ret)
|
||||
rdev_dbg(rdev,
|
||||
"unable to resolve supply (ignoring): %pe\n",
|
||||
ERR_PTR(ret));
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have a supply but couldn't resolve it yet, register a device
|
||||
* with our bus, so that the bus probe gets called whenever any new
|
||||
* driver binds, allowing us to retry matching supplies and which then
|
||||
* triggers (re)probe of consumers if successful.
|
||||
*/
|
||||
if (rdev->supply_name && !rdev->supply) {
|
||||
device_initialize(&rdev->bdev);
|
||||
rdev->bdev.bus = ®ulator_bus;
|
||||
rdev->bdev.parent = &rdev->dev;
|
||||
device_set_pm_not_required(&rdev->dev);
|
||||
dev_set_name(&rdev->bdev, "%s.bdev", dev_name(&rdev->dev));
|
||||
|
||||
ret = device_add(&rdev->bdev);
|
||||
if (ret)
|
||||
goto del_cdev_and_bdev;
|
||||
}
|
||||
|
||||
rdev_init_debugfs(rdev);
|
||||
|
||||
/* try to resolve regulators coupling since a new one was registered */
|
||||
@@ -6139,12 +6243,13 @@ regulator_register(struct device *dev,
|
||||
regulator_resolve_coupling(rdev);
|
||||
mutex_unlock(®ulator_list_mutex);
|
||||
|
||||
/* try to resolve regulators supply since a new one was registered */
|
||||
class_for_each_device(®ulator_class, NULL, NULL,
|
||||
regulator_register_resolve_supply);
|
||||
kfree(config);
|
||||
return rdev;
|
||||
|
||||
del_cdev_and_bdev:
|
||||
if (rdev->bdev.bus == ®ulator_bus)
|
||||
put_device(&rdev->bdev);
|
||||
device_del(&rdev->dev);
|
||||
unset_supplies:
|
||||
mutex_lock(®ulator_list_mutex);
|
||||
unset_regulator_supplies(rdev);
|
||||
@@ -6197,6 +6302,9 @@ void regulator_unregister(struct regulator_dev *rdev)
|
||||
unset_regulator_supplies(rdev);
|
||||
list_del(&rdev->list);
|
||||
regulator_ena_gpio_free(rdev);
|
||||
if (rdev->bdev.bus == ®ulator_bus)
|
||||
/* only if the device was added in the first place */
|
||||
device_unregister(&rdev->bdev);
|
||||
device_unregister(&rdev->dev);
|
||||
|
||||
mutex_unlock(®ulator_list_mutex);
|
||||
@@ -6277,6 +6385,45 @@ const struct class regulator_class = {
|
||||
.pm = ®ulator_pm_ops,
|
||||
#endif
|
||||
};
|
||||
|
||||
#define bdev_to_rdev(__bdev) container_of_const(__bdev, struct regulator_dev, bdev)
|
||||
|
||||
static int regulator_bus_match(struct device *bdev,
|
||||
const struct device_driver *drv)
|
||||
{
|
||||
/* Match always succeeds, we only have one driver */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int regulator_bus_probe(struct device *bdev)
|
||||
{
|
||||
struct regulator_dev *rdev = bdev_to_rdev(bdev);
|
||||
int ret;
|
||||
|
||||
ret = regulator_resolve_supply(rdev);
|
||||
if (ret)
|
||||
rdev_dbg(rdev,
|
||||
"unable to resolve supply or constraints '%s': %pe\n",
|
||||
rdev->supply_name, ERR_PTR(ret));
|
||||
else
|
||||
rdev_dbg(rdev, "resolved supply '%s'\n", rdev->supply_name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct bus_type regulator_bus = {
|
||||
.name = "regulator",
|
||||
.match = regulator_bus_match,
|
||||
.probe = regulator_bus_probe,
|
||||
};
|
||||
|
||||
static struct device_driver regulator_bus_driver = {
|
||||
.name = "regulator-bus-drv",
|
||||
.bus = ®ulator_bus,
|
||||
.suppress_bind_attrs = true,
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
};
|
||||
|
||||
/**
|
||||
* regulator_has_full_constraints - the system has fully specified constraints
|
||||
*
|
||||
@@ -6610,7 +6757,17 @@ static int __init regulator_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bus_register(®ulator_bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = class_register(®ulator_class);
|
||||
if (ret)
|
||||
goto err_class;
|
||||
|
||||
ret = driver_register(®ulator_bus_driver);
|
||||
if (ret)
|
||||
goto err_driver;
|
||||
|
||||
debugfs_root = debugfs_create_dir("regulator", NULL);
|
||||
if (IS_ERR(debugfs_root))
|
||||
@@ -6627,6 +6784,12 @@ static int __init regulator_init(void)
|
||||
|
||||
regulator_coupler_register(&generic_regulator_coupler);
|
||||
|
||||
return 0;
|
||||
|
||||
err_driver:
|
||||
class_unregister(®ulator_class);
|
||||
err_class:
|
||||
bus_unregister(®ulator_bus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -6687,16 +6850,6 @@ __setup("regulator_ignore_unused", regulator_ignore_unused_setup);
|
||||
|
||||
static void regulator_init_complete_work_function(struct work_struct *work)
|
||||
{
|
||||
/*
|
||||
* Regulators may had failed to resolve their input supplies
|
||||
* when were registered, either because the input supply was
|
||||
* not registered yet or because its parent device was not
|
||||
* bound yet. So attempt to resolve the input supplies for
|
||||
* pending regulators before trying to disable unused ones.
|
||||
*/
|
||||
class_for_each_device(®ulator_class, NULL, NULL,
|
||||
regulator_register_resolve_supply);
|
||||
|
||||
/*
|
||||
* For debugging purposes, it may be useful to prevent unused
|
||||
* regulators from being disabled.
|
||||
|
||||
@@ -56,7 +56,7 @@ static int dummy_regulator_probe(struct faux_device *fdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct faux_device_ops dummy_regulator_driver = {
|
||||
static struct faux_device_ops dummy_regulator_driver = {
|
||||
.probe = dummy_regulator_probe,
|
||||
};
|
||||
|
||||
|
||||
1056
drivers/regulator/max77675-regulator.c
Normal file
1056
drivers/regulator/max77675-regulator.c
Normal file
File diff suppressed because it is too large
Load Diff
313
drivers/regulator/rt8092.c
Normal file
313
drivers/regulator/rt8092.c
Normal file
@@ -0,0 +1,313 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
//
|
||||
// Copyright (c) 2025 Richtek Technology Corp.
|
||||
//
|
||||
// Author: ChiYuan Huang <cy_huang@richtek.com>
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
|
||||
#define RT8092_REG_MNTRPT 0x00
|
||||
#define RT8092_REG_VOUTH 0x10
|
||||
#define RT8092_REG_VOUTL 0x11
|
||||
#define RT8092_REG_PWMMODE 0x14
|
||||
#define RT8092_REG_EVENT 0x18
|
||||
#define RT8092_REG_VBANKH 0x1C
|
||||
#define RT8092_REG_VBANKL 0x1D
|
||||
#define RT8092_REG_VBOUND 0x1E
|
||||
|
||||
#define RT8092_TSDEVT_MASK BIT(7)
|
||||
#define RT8092_PGEVT_MASK BIT(0)
|
||||
#define RT8092_VSEL_MASK GENMASK(6, 0)
|
||||
#define RT8092_VOUTEN_MASK BIT(7)
|
||||
#define RT8092_FPWML_MASK BIT(7)
|
||||
#define RT8092_FPWMH_MASK BIT(6)
|
||||
#define RT8092_OCPEVT_MASK BIT(7)
|
||||
#define RT8092_SCPEVT_MASK BIT(4)
|
||||
#define RT8092_VINUVEVT_MASK BIT(1)
|
||||
#define RT8092_VBANK_MASK GENMASK(1, 0)
|
||||
|
||||
#define RT8092_MODE_AUTO 0
|
||||
#define RT8092_MODE_FPWM 1
|
||||
#define RT8092_VOUT_BASEUV 303125
|
||||
#define RT8092_VOUT_STEPUV 3125
|
||||
#define RT8092_VOUT_MINSEL 15
|
||||
#define RT8092_NUM_VOLTS 128
|
||||
#define RT8092_INITSS_US 400
|
||||
|
||||
static int rt8092_get_vbank_index(struct regmap *regmap, bool vsel_high, unsigned int *vbank_idx)
|
||||
{
|
||||
unsigned int vbank_reg = vsel_high ? RT8092_REG_VBANKH : RT8092_REG_VBANKL;
|
||||
unsigned int index;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, vbank_reg, &index);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*vbank_idx = FIELD_GET(RT8092_VBANK_MASK, index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt8092_set_operating_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
const struct regulator_desc *desc = rdev->desc;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
unsigned int mode_mask, mode_val;
|
||||
|
||||
mode_mask = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_FPWMH_MASK : RT8092_FPWML_MASK;
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_FAST:
|
||||
mode_val = mode_mask;
|
||||
break;
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
mode_val = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return regmap_update_bits(regmap, RT8092_REG_PWMMODE, mode_mask, mode_val);
|
||||
}
|
||||
|
||||
static unsigned int rt8092_get_operating_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
const struct regulator_desc *desc = rdev->desc;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
unsigned int mode_mask, mode_val;
|
||||
int ret;
|
||||
|
||||
mode_mask = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_FPWMH_MASK : RT8092_FPWML_MASK;
|
||||
|
||||
ret = regmap_read(regmap, RT8092_REG_PWMMODE, &mode_val);
|
||||
if (ret)
|
||||
return REGULATOR_MODE_INVALID;
|
||||
|
||||
return mode_val & mode_mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static int rt8092_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
|
||||
{
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
unsigned int mntrpt, evtrpt, events = 0;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, RT8092_REG_MNTRPT, &mntrpt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(regmap, RT8092_REG_EVENT, &evtrpt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(mntrpt & RT8092_PGEVT_MASK) || evtrpt & RT8092_VINUVEVT_MASK)
|
||||
events |= REGULATOR_ERROR_UNDER_VOLTAGE;
|
||||
|
||||
if (mntrpt & RT8092_TSDEVT_MASK)
|
||||
events |= REGULATOR_ERROR_OVER_TEMP;
|
||||
|
||||
if (evtrpt & RT8092_OCPEVT_MASK)
|
||||
events |= REGULATOR_ERROR_OVER_CURRENT;
|
||||
|
||||
if (evtrpt & RT8092_SCPEVT_MASK)
|
||||
events |= REGULATOR_ERROR_FAIL;
|
||||
|
||||
*flags = events;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int rt8092_set_suspend_voltage(struct regulator_dev *rdev, int uV)
|
||||
{
|
||||
const struct regulator_desc *desc = rdev->desc;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
unsigned int vsel_reg, vsel_val, vbank_idx;
|
||||
bool vsel_high;
|
||||
int ret;
|
||||
|
||||
vsel_reg = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_REG_VOUTL : RT8092_REG_VOUTH;
|
||||
vsel_high = desc->vsel_reg == RT8092_REG_VOUTH;
|
||||
|
||||
ret = rt8092_get_vbank_index(regmap, vsel_high, &vbank_idx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* VOUT = (BASEUV + STEPUV * VSEL) * 2^vbank_idx */
|
||||
uV >>= vbank_idx;
|
||||
if (uV < RT8092_VOUT_BASEUV)
|
||||
return -EINVAL;
|
||||
|
||||
vsel_val = (uV - RT8092_VOUT_BASEUV) / RT8092_VOUT_STEPUV;
|
||||
if (vsel_val < RT8092_VOUT_MINSEL || vsel_val >= RT8092_NUM_VOLTS)
|
||||
return -EINVAL;
|
||||
|
||||
return regmap_update_bits(regmap, vsel_reg, RT8092_VSEL_MASK, vsel_val);
|
||||
}
|
||||
|
||||
static int rt8092_set_suspend_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
const struct regulator_desc *desc = rdev->desc;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
unsigned int enable_reg;
|
||||
|
||||
enable_reg = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_REG_VOUTL : RT8092_REG_VOUTH;
|
||||
return regmap_set_bits(regmap, enable_reg, RT8092_VOUTEN_MASK);
|
||||
}
|
||||
|
||||
static int rt8092_set_suspend_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
const struct regulator_desc *desc = rdev->desc;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
unsigned int enable_reg;
|
||||
|
||||
enable_reg = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_REG_VOUTL : RT8092_REG_VOUTH;
|
||||
return regmap_clear_bits(regmap, enable_reg, RT8092_VOUTEN_MASK);
|
||||
}
|
||||
|
||||
static int rt8092_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
const struct regulator_desc *desc = rdev->desc;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
unsigned int mode_mask, mode_val;
|
||||
|
||||
mode_mask = desc->vsel_reg == RT8092_REG_VOUTH ? RT8092_FPWML_MASK : RT8092_FPWMH_MASK;
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_FAST:
|
||||
mode_val = mode_mask;
|
||||
break;
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
mode_val = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return regmap_update_bits(regmap, RT8092_REG_PWMMODE, mode_mask, mode_val);
|
||||
}
|
||||
|
||||
static const struct regulator_ops rt8092_regulator_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_mode = rt8092_set_operating_mode,
|
||||
.get_mode = rt8092_get_operating_mode,
|
||||
.get_error_flags = rt8092_get_error_flags,
|
||||
.set_suspend_voltage = rt8092_set_suspend_voltage,
|
||||
.set_suspend_enable = rt8092_set_suspend_enable,
|
||||
.set_suspend_disable = rt8092_set_suspend_disable,
|
||||
.set_suspend_mode = rt8092_set_suspend_mode,
|
||||
};
|
||||
|
||||
static unsigned int rt8092_of_map_mode(unsigned int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case RT8092_MODE_AUTO:
|
||||
return REGULATOR_MODE_NORMAL;
|
||||
case RT8092_MODE_FPWM:
|
||||
return REGULATOR_MODE_FAST;
|
||||
default:
|
||||
return REGULATOR_MODE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config rt8092_regmap_cfg = {
|
||||
.name = "rt8092",
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RT8092_REG_VBOUND,
|
||||
};
|
||||
|
||||
static int rt8092_probe(struct i2c_client *i2c)
|
||||
{
|
||||
unsigned int vbank_idx, min_uV, step_uV;
|
||||
struct regulator_config cfg = {};
|
||||
struct device *dev = &i2c->dev;
|
||||
struct regulator_desc *desc;
|
||||
struct regulator_dev *rdev;
|
||||
struct gpio_desc *enable;
|
||||
struct regmap *regmap;
|
||||
bool vsel_high;
|
||||
int ret;
|
||||
|
||||
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
|
||||
if (!desc)
|
||||
return -ENOMEM;
|
||||
|
||||
enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(enable))
|
||||
return dev_err_probe(dev, PTR_ERR(enable), "Failed get 'enable' gpio\n");
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &rt8092_regmap_cfg);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n");
|
||||
|
||||
vsel_high = device_property_read_bool(dev, "richtek,vsel-active-high");
|
||||
|
||||
ret = rt8092_get_vbank_index(regmap, vsel_high, &vbank_idx);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to get VOUT bank index\n");
|
||||
|
||||
/*
|
||||
* step VOUT = STEP_UV * 2^vbank_idx
|
||||
* min VOUT = (BASEUV + STEPUV * VMIN_SEL) * 2^vbank_idx
|
||||
*/
|
||||
step_uV = RT8092_VOUT_STEPUV << vbank_idx;
|
||||
min_uV = (RT8092_VOUT_BASEUV + RT8092_VOUT_STEPUV * RT8092_VOUT_MINSEL) << vbank_idx;
|
||||
|
||||
desc->name = "rt8092";
|
||||
desc->owner = THIS_MODULE;
|
||||
desc->type = REGULATOR_VOLTAGE;
|
||||
desc->ops = &rt8092_regulator_ops;
|
||||
desc->n_voltages = RT8092_NUM_VOLTS;
|
||||
desc->min_uV = min_uV;
|
||||
desc->uV_step = step_uV;
|
||||
desc->linear_min_sel = RT8092_VOUT_MINSEL;
|
||||
desc->enable_reg = desc->vsel_reg = vsel_high ? RT8092_REG_VOUTH : RT8092_REG_VOUTL;
|
||||
desc->vsel_mask = RT8092_VSEL_MASK;
|
||||
desc->enable_mask = RT8092_VOUTEN_MASK;
|
||||
desc->enable_time = RT8092_INITSS_US;
|
||||
desc->of_map_mode = rt8092_of_map_mode;
|
||||
|
||||
cfg.dev = dev;
|
||||
cfg.of_node = dev_of_node(dev);
|
||||
cfg.init_data = of_get_regulator_init_data(dev, dev_of_node(dev), desc);
|
||||
|
||||
rdev = devm_regulator_register(dev, desc, &cfg);
|
||||
if (IS_ERR(rdev))
|
||||
return dev_err_probe(dev, PTR_ERR(rdev), "Failed to register regulator\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id rt8092_device_tables[] = {
|
||||
{ .compatible = "richtek,rt8092" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rt8092_device_tables);
|
||||
|
||||
static struct i2c_driver rt8092_driver = {
|
||||
.driver = {
|
||||
.name = "rt8092",
|
||||
.of_match_table = rt8092_device_tables,
|
||||
},
|
||||
.probe = rt8092_probe,
|
||||
};
|
||||
module_i2c_driver(rt8092_driver);
|
||||
|
||||
MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
|
||||
MODULE_DESCRIPTION("Richtek RT8092 Regulator Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
File diff suppressed because it is too large
Load Diff
454
drivers/regulator/tps65185.c
Normal file
454
drivers/regulator/tps65185.c
Normal file
@@ -0,0 +1,454 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// Copyright (C) 2025 Andreas Kemnade
|
||||
|
||||
/* Datasheet: https://www.ti.com/lit/gpn/tps65185 */
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define TPS65185_REG_TMST_VALUE 0
|
||||
#define TPS65185_REG_ENABLE 1
|
||||
#define TPS65185_REG_VADJ 2
|
||||
#define TPS65185_REG_VCOM1 3
|
||||
#define TPS65185_REG_VCOM2 4
|
||||
#define TPS65185_REG_INT_EN1 5
|
||||
#define TPS65185_REG_INT_EN2 6
|
||||
#define TPS65185_REG_INT1 7
|
||||
#define TPS65185_REG_INT2 8
|
||||
#define TPS65185_REG_TMST1 0xd
|
||||
#define TPS65185_REG_TMST2 0xe
|
||||
#define TPS65185_REG_PG 0xf
|
||||
#define TPS65185_REG_REVID 0x10
|
||||
|
||||
#define TPS65185_READ_THERM BIT(7)
|
||||
#define TPS65185_CONV_END BIT(5)
|
||||
|
||||
#define TPS65185_ENABLE_ACTIVE BIT(7)
|
||||
#define TPS65185_ENABLE_STANDBY BIT(6)
|
||||
|
||||
#define PGOOD_TIMEOUT_MSECS 200
|
||||
|
||||
struct tps65185_data {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct gpio_desc *pgood_gpio;
|
||||
struct gpio_desc *pwrup_gpio;
|
||||
struct gpio_desc *vcom_ctrl_gpio;
|
||||
struct gpio_desc *wakeup_gpio;
|
||||
struct completion pgood_completion;
|
||||
int pgood_irq;
|
||||
struct completion tmst_completion;
|
||||
};
|
||||
|
||||
static const struct hwmon_channel_info *tps65185_info[] = {
|
||||
HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
|
||||
HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
|
||||
NULL
|
||||
};
|
||||
|
||||
static int tps65185_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
|
||||
u32 attr, int channel, long *temp)
|
||||
{
|
||||
struct tps65185_data *data = dev_get_drvdata(dev);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
reinit_completion(&data->tmst_completion);
|
||||
/* start acquisition */
|
||||
regmap_update_bits(data->regmap, TPS65185_REG_TMST1,
|
||||
TPS65185_READ_THERM, TPS65185_READ_THERM);
|
||||
wait_for_completion_timeout(&data->tmst_completion,
|
||||
msecs_to_jiffies(PGOOD_TIMEOUT_MSECS));
|
||||
ret = regmap_read(data->regmap, TPS65185_REG_TMST1, &val);
|
||||
if (!(val & TPS65185_CONV_END))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
ret = regmap_read(data->regmap, TPS65185_REG_TMST_VALUE, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*temp = (s8)val * 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static umode_t tps65185_hwmon_is_visible(const void *data,
|
||||
enum hwmon_sensor_types type,
|
||||
u32 attr, int channel)
|
||||
{
|
||||
return 0444;
|
||||
}
|
||||
|
||||
static const struct hwmon_ops tps65185_hwmon_ops = {
|
||||
.is_visible = tps65185_hwmon_is_visible,
|
||||
.read = tps65185_hwmon_read,
|
||||
};
|
||||
|
||||
static const struct hwmon_chip_info tps65185_chip_info = {
|
||||
.ops = &tps65185_hwmon_ops,
|
||||
.info = tps65185_info,
|
||||
};
|
||||
|
||||
static bool tps65185_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case TPS65185_REG_TMST_VALUE:
|
||||
case TPS65185_REG_ENABLE:
|
||||
case TPS65185_REG_VCOM2:
|
||||
case TPS65185_REG_INT1:
|
||||
case TPS65185_REG_INT2:
|
||||
case TPS65185_REG_TMST1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0x10,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.volatile_reg = tps65185_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regulator_ops tps65185_v3p3ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static int tps65185_check_powergood(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps65185_data *data = rdev_get_drvdata(rdev);
|
||||
|
||||
return gpiod_get_value_cansleep(data->pgood_gpio);
|
||||
}
|
||||
|
||||
static int tps65185_vposneg_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regulator_get_voltage_sel_regmap(rdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* highest value is lowest voltage */
|
||||
return 6 - ret;
|
||||
}
|
||||
|
||||
static int tps65185_vposneg_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector)
|
||||
{
|
||||
return regulator_set_voltage_sel_regmap(rdev, 6 - selector);
|
||||
}
|
||||
|
||||
static irqreturn_t pgood_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct tps65185_data *data = dev_id;
|
||||
|
||||
complete(&data->pgood_completion);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int tps65185_vposneg_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps65185_data *data = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
reinit_completion(&data->pgood_completion);
|
||||
if (data->pwrup_gpio)
|
||||
ret = gpiod_set_value_cansleep(data->pwrup_gpio, 1);
|
||||
else
|
||||
ret = regmap_update_bits(data->regmap, TPS65185_REG_ENABLE,
|
||||
TPS65185_ENABLE_ACTIVE,
|
||||
TPS65185_ENABLE_ACTIVE);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_dbg(data->dev, "turning on...");
|
||||
wait_for_completion_timeout(&data->pgood_completion,
|
||||
msecs_to_jiffies(PGOOD_TIMEOUT_MSECS));
|
||||
dev_dbg(data->dev, "turned on");
|
||||
if (gpiod_get_value_cansleep(data->pgood_gpio) != 1)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65185_vposneg_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps65185_data *data = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
if (data->pwrup_gpio)
|
||||
ret = gpiod_set_value_cansleep(data->pwrup_gpio, 0);
|
||||
else
|
||||
ret = regmap_update_bits(data->regmap, TPS65185_REG_ENABLE,
|
||||
TPS65185_ENABLE_STANDBY,
|
||||
TPS65185_ENABLE_STANDBY);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tps65185_vcom_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector)
|
||||
{
|
||||
struct tps65185_data *data = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(data->regmap, TPS65185_REG_VCOM2, BIT(0), selector >> 8);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return regmap_write(data->regmap, TPS65185_REG_VCOM1, selector & 0xFF);
|
||||
}
|
||||
|
||||
static int tps65185_vcom_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps65185_data *data = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
unsigned int sel, sel2;
|
||||
|
||||
ret = regmap_read(data->regmap, TPS65185_REG_VCOM1, &sel);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(data->regmap, TPS65185_REG_VCOM2, &sel2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (sel2 & BIT(0))
|
||||
sel |= 0x100;
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
static const struct regulator_ops tps65185_vcom_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.set_voltage_sel = tps65185_vcom_set_voltage_sel,
|
||||
.get_voltage_sel = tps65185_vcom_get_voltage_sel,
|
||||
};
|
||||
|
||||
static const struct regulator_ops tps65185_vposneg_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.enable = tps65185_vposneg_enable,
|
||||
.disable = tps65185_vposneg_disable,
|
||||
.is_enabled = tps65185_check_powergood,
|
||||
.set_voltage_sel = tps65185_vposneg_set_voltage_sel,
|
||||
.get_voltage_sel = tps65185_vposneg_get_voltage_sel,
|
||||
};
|
||||
|
||||
static const struct regulator_desc regulators[] = {
|
||||
{
|
||||
.name = "v3p3",
|
||||
.of_match = of_match_ptr("v3p3"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = 0,
|
||||
.ops = &tps65185_v3p3ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = TPS65185_REG_ENABLE,
|
||||
.enable_mask = BIT(5),
|
||||
.n_voltages = 1,
|
||||
.min_uV = 3300000,
|
||||
},
|
||||
{
|
||||
.name = "vposneg",
|
||||
.of_match = of_match_ptr("vposneg"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = 1,
|
||||
.ops = &tps65185_vposneg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.n_voltages = 4,
|
||||
.vsel_reg = TPS65185_REG_VADJ,
|
||||
.vsel_mask = 0x7,
|
||||
.min_uV = 14250000,
|
||||
.uV_step = 250000,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct regulator_desc vcom_regulator_desc = {
|
||||
.name = "vcom",
|
||||
.of_match = of_match_ptr("vcom"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.supply_name = "vposneg",
|
||||
.id = 2,
|
||||
.ops = &tps65185_vcom_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.n_voltages = 511,
|
||||
.min_uV = 0,
|
||||
.uV_step = 10000,
|
||||
};
|
||||
|
||||
static irqreturn_t tps65185_irq_thread(int irq, void *dev_id)
|
||||
{
|
||||
struct tps65185_data *data = dev_id;
|
||||
unsigned int int_status_1, int_status_2;
|
||||
int ret;
|
||||
|
||||
/* read both status to have irq cleared */
|
||||
ret = regmap_read(data->regmap, TPS65185_REG_INT1, &int_status_1);
|
||||
if (ret)
|
||||
return IRQ_NONE;
|
||||
|
||||
ret = regmap_read(data->regmap, TPS65185_REG_INT2, &int_status_2);
|
||||
if (ret)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (int_status_2 & BIT(0))
|
||||
complete(&data->tmst_completion);
|
||||
|
||||
dev_dbg(data->dev, "irq status %02x %02x\n", int_status_1, int_status_2);
|
||||
|
||||
if (int_status_1 || int_status_2)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static int tps65185_probe(struct i2c_client *client)
|
||||
{
|
||||
struct tps65185_data *data;
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
|
||||
data->regmap = devm_regmap_init_i2c(client, ®map_config);
|
||||
if (IS_ERR(data->regmap))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(data->regmap),
|
||||
"failed to allocate regmap!\n");
|
||||
|
||||
data->pgood_gpio = devm_gpiod_get(&client->dev, "pwr-good", GPIOD_IN);
|
||||
if (IS_ERR(data->pgood_gpio))
|
||||
return dev_err_probe(&client->dev,
|
||||
PTR_ERR(data->pgood_gpio),
|
||||
"failed to get power good gpio\n");
|
||||
|
||||
data->pgood_irq = gpiod_to_irq(data->pgood_gpio);
|
||||
if (data->pgood_irq < 0)
|
||||
return data->pgood_irq;
|
||||
|
||||
data->pwrup_gpio = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(data->pwrup_gpio))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(data->pwrup_gpio),
|
||||
"failed to get pwrup gpio\n");
|
||||
|
||||
data->wakeup_gpio = devm_gpiod_get_optional(&client->dev, "wakeup", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(data->wakeup_gpio))
|
||||
return dev_err_probe(&client->dev,
|
||||
PTR_ERR(data->wakeup_gpio),
|
||||
"failed to get wakeup gpio\n");
|
||||
|
||||
data->vcom_ctrl_gpio = devm_gpiod_get_optional(&client->dev, "vcom-ctrl", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(data->vcom_ctrl_gpio))
|
||||
return dev_err_probe(&client->dev,
|
||||
PTR_ERR(data->vcom_ctrl_gpio),
|
||||
"failed to get vcm ctrl gpio\n");
|
||||
|
||||
ret = devm_regulator_get_enable(&client->dev, "vin");
|
||||
if (ret)
|
||||
return dev_err_probe(&client->dev, ret,
|
||||
"failed to get vin regulator\n");
|
||||
|
||||
data->dev = &client->dev;
|
||||
i2c_set_clientdata(client, data);
|
||||
|
||||
init_completion(&data->pgood_completion);
|
||||
init_completion(&data->tmst_completion);
|
||||
|
||||
ret = devm_request_threaded_irq(&client->dev, data->pgood_irq, NULL,
|
||||
pgood_handler,
|
||||
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
||||
"PGOOD", data);
|
||||
if (ret)
|
||||
return dev_err_probe(&client->dev, ret,
|
||||
"failed to request power good irq\n");
|
||||
|
||||
if (client->irq) {
|
||||
ret = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, tps65185_irq_thread,
|
||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
"tps65185", data);
|
||||
if (ret)
|
||||
return dev_err_probe(&client->dev, ret,
|
||||
"failed to request irq\n");
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(data->regmap, TPS65185_REG_INT_EN2, BIT(0), BIT(0));
|
||||
if (ret)
|
||||
return dev_err_probe(&client->dev, ret,
|
||||
"failed to enable temp irq\n");
|
||||
|
||||
config.driver_data = data;
|
||||
config.dev = &client->dev;
|
||||
config.regmap = data->regmap;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
|
||||
rdev = devm_regulator_register(&client->dev, ®ulators[i],
|
||||
&config);
|
||||
if (IS_ERR(rdev))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(rdev),
|
||||
"failed to register %s regulator\n",
|
||||
regulators[i].name);
|
||||
}
|
||||
|
||||
config.ena_gpiod = data->vcom_ctrl_gpio;
|
||||
rdev = devm_regulator_register(&client->dev, &vcom_regulator_desc, &config);
|
||||
if (IS_ERR(rdev))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(rdev),
|
||||
"failed to register vcom regulator\n");
|
||||
|
||||
if (IS_REACHABLE(CONFIG_HWMON)) {
|
||||
struct device *hwmon_dev;
|
||||
|
||||
hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, "tps65185", data,
|
||||
&tps65185_chip_info, NULL);
|
||||
if (IS_ERR(hwmon_dev))
|
||||
dev_notice(&client->dev, "failed to register hwmon\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id tps65185_dt_ids[] = {
|
||||
{
|
||||
.compatible = "ti,tps65185",
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tps65185_dt_ids);
|
||||
|
||||
static struct i2c_driver tps65185_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "tps65185",
|
||||
.of_match_table = tps65185_dt_ids,
|
||||
},
|
||||
.probe = tps65185_probe,
|
||||
};
|
||||
|
||||
module_i2c_driver(tps65185_i2c_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_DESCRIPTION("TPS65185 regulator driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/samsung/core.h>
|
||||
#include <linux/mfd/samsung/irq.h>
|
||||
#include <linux/mfd/samsung/rtc.h>
|
||||
#include <linux/mfd/samsung/s2mps14.h>
|
||||
|
||||
@@ -683,22 +682,18 @@ static int s5m_rtc_probe(struct platform_device *pdev)
|
||||
case S2MPS15X:
|
||||
regmap_cfg = &s2mps14_rtc_regmap_config;
|
||||
info->regs = &s2mps15_rtc_regs;
|
||||
alarm_irq = S2MPS14_IRQ_RTCA0;
|
||||
break;
|
||||
case S2MPS14X:
|
||||
regmap_cfg = &s2mps14_rtc_regmap_config;
|
||||
info->regs = &s2mps14_rtc_regs;
|
||||
alarm_irq = S2MPS14_IRQ_RTCA0;
|
||||
break;
|
||||
case S2MPS13X:
|
||||
regmap_cfg = &s2mps14_rtc_regmap_config;
|
||||
info->regs = &s2mps13_rtc_regs;
|
||||
alarm_irq = S2MPS14_IRQ_RTCA0;
|
||||
break;
|
||||
case S5M8767X:
|
||||
regmap_cfg = &s5m_rtc_regmap_config;
|
||||
info->regs = &s5m_rtc_regs;
|
||||
alarm_irq = S5M8767_IRQ_RTCA1;
|
||||
break;
|
||||
default:
|
||||
return dev_err_probe(&pdev->dev, -ENODEV,
|
||||
@@ -719,7 +714,6 @@ static int s5m_rtc_probe(struct platform_device *pdev)
|
||||
"Failed to allocate regmap\n");
|
||||
} else if (device_type == S2MPG10) {
|
||||
info->regs = &s2mpg10_rtc_regs;
|
||||
alarm_irq = S2MPG10_IRQ_RTCA0;
|
||||
} else {
|
||||
return dev_err_probe(&pdev->dev, -ENODEV,
|
||||
"Unsupported device type %d\n",
|
||||
@@ -730,13 +724,14 @@ static int s5m_rtc_probe(struct platform_device *pdev)
|
||||
info->s5m87xx = s5m87xx;
|
||||
info->device_type = device_type;
|
||||
|
||||
if (s5m87xx->irq_data) {
|
||||
info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq);
|
||||
if (info->irq <= 0)
|
||||
return dev_err_probe(&pdev->dev, -EINVAL,
|
||||
"Failed to get virtual IRQ %d\n",
|
||||
alarm_irq);
|
||||
}
|
||||
alarm_irq = platform_get_irq_byname_optional(pdev, "alarm");
|
||||
if (alarm_irq > 0)
|
||||
info->irq = alarm_irq;
|
||||
else if (alarm_irq == -ENXIO)
|
||||
info->irq = 0;
|
||||
else
|
||||
return dev_err_probe(&pdev->dev, alarm_irq ? : -EINVAL,
|
||||
"IRQ 'alarm' not found\n");
|
||||
|
||||
platform_set_drvdata(pdev, info);
|
||||
|
||||
|
||||
53
include/dt-bindings/regulator/samsung,s2mpg10-regulator.h
Normal file
53
include/dt-bindings/regulator/samsung,s2mpg10-regulator.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright 2021 Google LLC
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*
|
||||
* Device Tree binding constants for the Samsung S2MPG1x PMIC regulators
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_REGULATOR_SAMSUNG_S2MPG10_H
|
||||
#define _DT_BINDINGS_REGULATOR_SAMSUNG_S2MPG10_H
|
||||
|
||||
/*
|
||||
* Several regulators may be controlled via external signals instead of via
|
||||
* software. These constants describe the possible signals for such regulators
|
||||
* and generally correspond to the respecitve on-chip pins.
|
||||
*
|
||||
* S2MPG10 regulators supporting these are:
|
||||
* - buck1m .. buck7m buck10m
|
||||
* - ldo3m .. ldo19m
|
||||
*
|
||||
* ldo20m supports external control, but using a different set of control
|
||||
* signals.
|
||||
*
|
||||
* S2MPG11 regulators supporting these are:
|
||||
* - buck1s .. buck3s buck5s buck8s buck9s bucka buckd
|
||||
* - ldo1s ldo2s ldo8s ldo13s
|
||||
*/
|
||||
#define S2MPG10_EXTCTRL_PWREN 0 /* PWREN pin */
|
||||
#define S2MPG10_EXTCTRL_PWREN_MIF 1 /* PWREN_MIF pin */
|
||||
#define S2MPG10_EXTCTRL_AP_ACTIVE_N 2 /* ~AP_ACTIVE_N pin */
|
||||
#define S2MPG10_EXTCTRL_CPUCL1_EN 3 /* CPUCL1_EN pin */
|
||||
#define S2MPG10_EXTCTRL_CPUCL1_EN2 4 /* CPUCL1_EN & PWREN pins */
|
||||
#define S2MPG10_EXTCTRL_CPUCL2_EN 5 /* CPUCL2_EN pin */
|
||||
#define S2MPG10_EXTCTRL_CPUCL2_EN2 6 /* CPUCL2_E2 & PWREN pins */
|
||||
#define S2MPG10_EXTCTRL_TPU_EN 7 /* TPU_EN pin */
|
||||
#define S2MPG10_EXTCTRL_TPU_EN2 8 /* TPU_EN & ~AP_ACTIVE_N pins */
|
||||
#define S2MPG10_EXTCTRL_TCXO_ON 9 /* TCXO_ON pin */
|
||||
#define S2MPG10_EXTCTRL_TCXO_ON2 10 /* TCXO_ON & ~AP_ACTIVE_N pins */
|
||||
|
||||
#define S2MPG10_EXTCTRL_LDO20M_EN2 11 /* VLDO20M_EN & LDO20M_SFR */
|
||||
#define S2MPG10_EXTCTRL_LDO20M_EN 12 /* VLDO20M_EN pin */
|
||||
|
||||
#define S2MPG11_EXTCTRL_PWREN 0 /* PWREN pin */
|
||||
#define S2MPG11_EXTCTRL_PWREN_MIF 1 /* PWREN_MIF pin */
|
||||
#define S2MPG11_EXTCTRL_AP_ACTIVE_N 2 /* ~AP_ACTIVE_N pin */
|
||||
#define S2MPG11_EXTCTRL_G3D_EN 3 /* G3D_EN pin */
|
||||
#define S2MPG11_EXTCTRL_G3D_EN2 4 /* G3D_EN & ~AP_ACTIVE_N pins */
|
||||
#define S2MPG11_EXTCTRL_AOC_VDD 5 /* AOC_VDD pin */
|
||||
#define S2MPG11_EXTCTRL_AOC_RET 6 /* AOC_RET pin */
|
||||
#define S2MPG11_EXTCTRL_UFS_EN 7 /* UFS_EN pin */
|
||||
#define S2MPG11_EXTCTRL_LDO13S_EN 8 /* VLDO13S_EN pin */
|
||||
|
||||
#endif /* _DT_BINDINGS_REGULATOR_SAMSUNG_S2MPG10_H */
|
||||
@@ -40,6 +40,7 @@ enum sec_device_type {
|
||||
S2DOS05,
|
||||
S2MPA01,
|
||||
S2MPG10,
|
||||
S2MPG11,
|
||||
S2MPS11X,
|
||||
S2MPS13X,
|
||||
S2MPS14X,
|
||||
@@ -69,7 +70,6 @@ struct sec_pmic_dev {
|
||||
|
||||
int device_type;
|
||||
int irq;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
};
|
||||
|
||||
struct sec_platform_data {
|
||||
|
||||
@@ -166,6 +166,111 @@ enum s2mpg10_irq {
|
||||
S2MPG10_IRQ_NR,
|
||||
};
|
||||
|
||||
enum s2mpg11_common_irq {
|
||||
/* Top-level (common) block */
|
||||
S2MPG11_COMMON_IRQ_PMIC,
|
||||
S2MPG11_COMMON_IRQ_UNUSED,
|
||||
};
|
||||
|
||||
enum s2mpg11_irq {
|
||||
/* PMIC */
|
||||
S2MPG11_IRQ_PWRONF,
|
||||
S2MPG11_IRQ_PWRONR,
|
||||
S2MPG11_IRQ_PIF_TIMEOUT_MIF,
|
||||
S2MPG11_IRQ_PIF_TIMEOUTS,
|
||||
S2MPG11_IRQ_WTSR,
|
||||
S2MPG11_IRQ_SPD_ABNORMAL_STOP,
|
||||
S2MPG11_IRQ_SPD_PARITY_ERR,
|
||||
#define S2MPG11_IRQ_PWRONF_MASK BIT(0)
|
||||
#define S2MPG11_IRQ_PWRONR_MASK BIT(1)
|
||||
#define S2MPG11_IRQ_PIF_TIMEOUT_MIF_MASK BIT(3)
|
||||
#define S2MPG11_IRQ_PIF_TIMEOUTS_MASK BIT(4)
|
||||
#define S2MPG11_IRQ_WTSR_MASK BIT(5)
|
||||
#define S2MPG11_IRQ_SPD_ABNORMAL_STOP_MASK BIT(6)
|
||||
#define S2MPG11_IRQ_SPD_PARITY_ERR_MASK BIT(7)
|
||||
|
||||
S2MPG11_IRQ_140C,
|
||||
S2MPG11_IRQ_120C,
|
||||
S2MPG11_IRQ_TSD,
|
||||
S2MPG11_IRQ_WRST,
|
||||
S2MPG11_IRQ_NTC_CYCLE_DONE,
|
||||
S2MPG11_IRQ_PMETER_OVERF,
|
||||
#define S2MPG11_IRQ_INT140C_MASK BIT(0)
|
||||
#define S2MPG11_IRQ_INT120C_MASK BIT(1)
|
||||
#define S2MPG11_IRQ_TSD_MASK BIT(2)
|
||||
#define S2MPG11_IRQ_WRST_MASK BIT(5)
|
||||
#define S2MPG11_IRQ_NTC_CYCLE_DONE_MASK BIT(6)
|
||||
#define S2MPG11_IRQ_PMETER_OVERF_MASK BIT(7)
|
||||
|
||||
S2MPG11_IRQ_OCP_B1S,
|
||||
S2MPG11_IRQ_OCP_B2S,
|
||||
S2MPG11_IRQ_OCP_B3S,
|
||||
S2MPG11_IRQ_OCP_B4S,
|
||||
S2MPG11_IRQ_OCP_B5S,
|
||||
S2MPG11_IRQ_OCP_B6S,
|
||||
S2MPG11_IRQ_OCP_B7S,
|
||||
S2MPG11_IRQ_OCP_B8S,
|
||||
#define S2MPG11_IRQ_OCP_B1S_MASK BIT(0)
|
||||
#define S2MPG11_IRQ_OCP_B2S_MASK BIT(1)
|
||||
#define S2MPG11_IRQ_OCP_B3S_MASK BIT(2)
|
||||
#define S2MPG11_IRQ_OCP_B4S_MASK BIT(3)
|
||||
#define S2MPG11_IRQ_OCP_B5S_MASK BIT(4)
|
||||
#define S2MPG11_IRQ_OCP_B6S_MASK BIT(5)
|
||||
#define S2MPG11_IRQ_OCP_B7S_MASK BIT(6)
|
||||
#define S2MPG11_IRQ_OCP_B8S_MASK BIT(7)
|
||||
|
||||
S2MPG11_IRQ_OCP_B9S,
|
||||
S2MPG11_IRQ_OCP_B10S,
|
||||
S2MPG11_IRQ_OCP_BDS,
|
||||
S2MPG11_IRQ_OCP_BAS,
|
||||
S2MPG11_IRQ_OCP_BBS,
|
||||
S2MPG11_IRQ_WLWP_ACC,
|
||||
S2MPG11_IRQ_SPD_SRP_PKT_RST,
|
||||
#define S2MPG11_IRQ_OCP_B9S_MASK BIT(0)
|
||||
#define S2MPG11_IRQ_OCP_B10S_MASK BIT(1)
|
||||
#define S2MPG11_IRQ_OCP_BDS_MASK BIT(2)
|
||||
#define S2MPG11_IRQ_OCP_BAS_MASK BIT(3)
|
||||
#define S2MPG11_IRQ_OCP_BBS_MASK BIT(4)
|
||||
#define S2MPG11_IRQ_WLWP_ACC_MASK BIT(5)
|
||||
#define S2MPG11_IRQ_SPD_SRP_PKT_RST_MASK BIT(7)
|
||||
|
||||
S2MPG11_IRQ_PWR_WARN_CH0,
|
||||
S2MPG11_IRQ_PWR_WARN_CH1,
|
||||
S2MPG11_IRQ_PWR_WARN_CH2,
|
||||
S2MPG11_IRQ_PWR_WARN_CH3,
|
||||
S2MPG11_IRQ_PWR_WARN_CH4,
|
||||
S2MPG11_IRQ_PWR_WARN_CH5,
|
||||
S2MPG11_IRQ_PWR_WARN_CH6,
|
||||
S2MPG11_IRQ_PWR_WARN_CH7,
|
||||
#define S2MPG11_IRQ_PWR_WARN_CH0_MASK BIT(0)
|
||||
#define S2MPG11_IRQ_PWR_WARN_CH1_MASK BIT(1)
|
||||
#define S2MPG11_IRQ_PWR_WARN_CH2_MASK BIT(2)
|
||||
#define S2MPG11_IRQ_PWR_WARN_CH3_MASK BIT(3)
|
||||
#define S2MPG11_IRQ_PWR_WARN_CH4_MASK BIT(4)
|
||||
#define S2MPG11_IRQ_PWR_WARN_CH5_MASK BIT(5)
|
||||
#define S2MPG11_IRQ_PWR_WARN_CH6_MASK BIT(6)
|
||||
#define S2MPG11_IRQ_PWR_WARN_CH7_MASK BIT(7)
|
||||
|
||||
S2MPG11_IRQ_NTC_WARN_CH0,
|
||||
S2MPG11_IRQ_NTC_WARN_CH1,
|
||||
S2MPG11_IRQ_NTC_WARN_CH2,
|
||||
S2MPG11_IRQ_NTC_WARN_CH3,
|
||||
S2MPG11_IRQ_NTC_WARN_CH4,
|
||||
S2MPG11_IRQ_NTC_WARN_CH5,
|
||||
S2MPG11_IRQ_NTC_WARN_CH6,
|
||||
S2MPG11_IRQ_NTC_WARN_CH7,
|
||||
#define S2MPG11_IRQ_NTC_WARN_CH0_MASK BIT(0)
|
||||
#define S2MPG11_IRQ_NTC_WARN_CH1_MASK BIT(1)
|
||||
#define S2MPG11_IRQ_NTC_WARN_CH2_MASK BIT(2)
|
||||
#define S2MPG11_IRQ_NTC_WARN_CH3_MASK BIT(3)
|
||||
#define S2MPG11_IRQ_NTC_WARN_CH4_MASK BIT(4)
|
||||
#define S2MPG11_IRQ_NTC_WARN_CH5_MASK BIT(5)
|
||||
#define S2MPG11_IRQ_NTC_WARN_CH6_MASK BIT(6)
|
||||
#define S2MPG11_IRQ_NTC_WARN_CH7_MASK BIT(7)
|
||||
|
||||
S2MPG11_IRQ_NR,
|
||||
};
|
||||
|
||||
enum s2mps11_irq {
|
||||
S2MPS11_IRQ_PWRONF,
|
||||
S2MPS11_IRQ_PWRONR,
|
||||
|
||||
@@ -290,6 +290,30 @@ enum s2mpg10_pmic_reg {
|
||||
S2MPG10_PMIC_LDO_SENSE4,
|
||||
};
|
||||
|
||||
/* Rail controlled externally, based on PCTRLSELx */
|
||||
#define S2MPG10_PMIC_CTRL_ENABLE_EXT BIT(0)
|
||||
|
||||
/* For S2MPG10_PMIC_PCTRLSELx */
|
||||
#define S2MPG10_PCTRLSEL_PWREN 0x1 /* PWREN pin */
|
||||
#define S2MPG10_PCTRLSEL_PWREN_TRG 0x2 /* PWREN_TRG bit in MIMICKING_CTRL */
|
||||
#define S2MPG10_PCTRLSEL_PWREN_MIF 0x3 /* PWREN_MIF pin */
|
||||
#define S2MPG10_PCTRLSEL_PWREN_MIF_TRG 0x4 /* PWREN_MIF_TRG bit in MIMICKING_CTRL */
|
||||
#define S2MPG10_PCTRLSEL_AP_ACTIVE_N 0x5 /* ~AP_ACTIVE_N pin */
|
||||
#define S2MPG10_PCTRLSEL_AP_ACTIVE_N_TRG 0x6 /* ~AP_ACTIVE_N_TRG bit in MIMICKING_CTRL */
|
||||
#define S2MPG10_PCTRLSEL_CPUCL1_EN 0x7 /* CPUCL1_EN pin */
|
||||
#define S2MPG10_PCTRLSEL_CPUCL1_EN2 0x8 /* CPUCL1_EN & PWREN pins */
|
||||
#define S2MPG10_PCTRLSEL_CPUCL2_EN 0x9 /* CPUCL2_EN pin */
|
||||
#define S2MPG10_PCTRLSEL_CPUCL2_EN2 0xa /* CPUCL2_E2 & PWREN pins */
|
||||
#define S2MPG10_PCTRLSEL_TPU_EN 0xb /* TPU_EN pin */
|
||||
#define S2MPG10_PCTRLSEL_TPU_EN2 0xc /* TPU_EN & ~AP_ACTIVE_N pins */
|
||||
#define S2MPG10_PCTRLSEL_TCXO_ON 0xd /* TCXO_ON pin */
|
||||
#define S2MPG10_PCTRLSEL_TCXO_ON2 0xe /* TCXO_ON & ~AP_ACTIVE_N pins */
|
||||
|
||||
/* For S2MPG10_PMIC_PCTRLSELx of LDO20M */
|
||||
#define S2MPG10_PCTRLSEL_LDO20M_EN2 0x1 /* VLDO20M_EN & LDO20M_SFR */
|
||||
#define S2MPG10_PCTRLSEL_LDO20M_EN 0x2 /* VLDO20M_EN pin */
|
||||
#define S2MPG10_PCTRLSEL_LDO20M_SFR 0x3 /* LDO20M_SFR bit in LDO_CTRL1 register */
|
||||
|
||||
/* Meter registers (type 0xa00) */
|
||||
enum s2mpg10_meter_reg {
|
||||
S2MPG10_METER_CTRL1,
|
||||
@@ -407,6 +431,16 @@ enum s2mpg10_meter_reg {
|
||||
|
||||
/* S2MPG10 regulator IDs */
|
||||
enum s2mpg10_regulators {
|
||||
S2MPG10_BUCK1,
|
||||
S2MPG10_BUCK2,
|
||||
S2MPG10_BUCK3,
|
||||
S2MPG10_BUCK4,
|
||||
S2MPG10_BUCK5,
|
||||
S2MPG10_BUCK6,
|
||||
S2MPG10_BUCK7,
|
||||
S2MPG10_BUCK8,
|
||||
S2MPG10_BUCK9,
|
||||
S2MPG10_BUCK10,
|
||||
S2MPG10_LDO1,
|
||||
S2MPG10_LDO2,
|
||||
S2MPG10_LDO3,
|
||||
@@ -438,16 +472,6 @@ enum s2mpg10_regulators {
|
||||
S2MPG10_LDO29,
|
||||
S2MPG10_LDO30,
|
||||
S2MPG10_LDO31,
|
||||
S2MPG10_BUCK1,
|
||||
S2MPG10_BUCK2,
|
||||
S2MPG10_BUCK3,
|
||||
S2MPG10_BUCK4,
|
||||
S2MPG10_BUCK5,
|
||||
S2MPG10_BUCK6,
|
||||
S2MPG10_BUCK7,
|
||||
S2MPG10_BUCK8,
|
||||
S2MPG10_BUCK9,
|
||||
S2MPG10_BUCK10,
|
||||
S2MPG10_REGULATOR_MAX,
|
||||
};
|
||||
|
||||
|
||||
434
include/linux/mfd/samsung/s2mpg11.h
Normal file
434
include/linux/mfd/samsung/s2mpg11.h
Normal file
@@ -0,0 +1,434 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2015 Samsung Electronics
|
||||
* Copyright 2020 Google Inc
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_S2MPG11_H
|
||||
#define __LINUX_MFD_S2MPG11_H
|
||||
|
||||
/* Common registers (type 0x000) */
|
||||
enum s2mpg11_common_reg {
|
||||
S2MPG11_COMMON_CHIPID,
|
||||
S2MPG11_COMMON_INT,
|
||||
S2MPG11_COMMON_INT_MASK,
|
||||
S2MPG11_COMMON_SPD_CTRL1 = 0x0a,
|
||||
S2MPG11_COMMON_SPD_CTRL2,
|
||||
S2MPG11_COMMON_SPD_CTRL3,
|
||||
S2MPG11_COMMON_MON1SEL = 0x1a,
|
||||
S2MPG11_COMMON_MON2SEL,
|
||||
S2MPG11_COMMON_MONR,
|
||||
S2MPG11_COMMON_DEBUG_CTRL1,
|
||||
S2MPG11_COMMON_DEBUG_CTRL2,
|
||||
S2MPG11_COMMON_DEBUG_CTRL3,
|
||||
S2MPG11_COMMON_DEBUG_CTRL4,
|
||||
S2MPG11_COMMON_DEBUG_CTRL5,
|
||||
S2MPG11_COMMON_DEBUG_CTRL6,
|
||||
S2MPG11_COMMON_TEST_MODE1,
|
||||
S2MPG11_COMMON_SPD_DEBUG1,
|
||||
S2MPG11_COMMON_SPD_DEBUG2,
|
||||
S2MPG11_COMMON_SPD_DEBUG3,
|
||||
S2MPG11_COMMON_SPD_DEBUG4,
|
||||
};
|
||||
|
||||
/* For S2MPG11_COMMON_INT and S2MPG11_COMMON_INT_MASK */
|
||||
#define S2MPG11_COMMON_INT_SRC GENMASK(2, 0)
|
||||
#define S2MPG11_COMMON_INT_SRC_PMIC BIT(0)
|
||||
|
||||
/* PMIC registers (type 0x100) */
|
||||
enum s2mpg11_pmic_reg {
|
||||
S2MPG11_PMIC_INT1,
|
||||
S2MPG11_PMIC_INT2,
|
||||
S2MPG11_PMIC_INT3,
|
||||
S2MPG11_PMIC_INT4,
|
||||
S2MPG11_PMIC_INT5,
|
||||
S2MPG11_PMIC_INT6,
|
||||
S2MPG11_PMIC_INT1M,
|
||||
S2MPG11_PMIC_INT2M,
|
||||
S2MPG11_PMIC_INT3M,
|
||||
S2MPG11_PMIC_INT4M,
|
||||
S2MPG11_PMIC_INT5M,
|
||||
S2MPG11_PMIC_INT6M,
|
||||
S2MPG11_PMIC_STATUS1,
|
||||
S2MPG11_PMIC_OFFSRC,
|
||||
S2MPG11_PMIC_COMMON_CTRL1,
|
||||
S2MPG11_PMIC_COMMON_CTRL2,
|
||||
S2MPG11_PMIC_COMMON_CTRL3,
|
||||
S2MPG11_PMIC_MIMICKING_CTRL,
|
||||
S2MPG11_PMIC_B1S_CTRL,
|
||||
S2MPG11_PMIC_B1S_OUT1,
|
||||
S2MPG11_PMIC_B1S_OUT2,
|
||||
S2MPG11_PMIC_B2S_CTRL,
|
||||
S2MPG11_PMIC_B2S_OUT1,
|
||||
S2MPG11_PMIC_B2S_OUT2,
|
||||
S2MPG11_PMIC_B3S_CTRL,
|
||||
S2MPG11_PMIC_B3S_OUT1,
|
||||
S2MPG11_PMIC_B3S_OUT2,
|
||||
S2MPG11_PMIC_B4S_CTRL,
|
||||
S2MPG11_PMIC_B4S_OUT,
|
||||
S2MPG11_PMIC_B5S_CTRL,
|
||||
S2MPG11_PMIC_B5S_OUT,
|
||||
S2MPG11_PMIC_B6S_CTRL,
|
||||
S2MPG11_PMIC_B6S_OUT1,
|
||||
S2MPG11_PMIC_B6S_OUT2,
|
||||
S2MPG11_PMIC_B7S_CTRL,
|
||||
S2MPG11_PMIC_B7S_OUT1,
|
||||
S2MPG11_PMIC_B7S_OUT2,
|
||||
S2MPG11_PMIC_B8S_CTRL,
|
||||
S2MPG11_PMIC_B8S_OUT1,
|
||||
S2MPG11_PMIC_B8S_OUT2,
|
||||
S2MPG11_PMIC_B9S_CTRL,
|
||||
S2MPG11_PMIC_B9S_OUT1,
|
||||
S2MPG11_PMIC_B9S_OUT2,
|
||||
S2MPG11_PMIC_B10S_CTRL,
|
||||
S2MPG11_PMIC_B10S_OUT,
|
||||
S2MPG11_PMIC_BUCKD_CTRL,
|
||||
S2MPG11_PMIC_BUCKD_OUT,
|
||||
S2MPG11_PMIC_BUCKA_CTRL,
|
||||
S2MPG11_PMIC_BUCKA_OUT,
|
||||
S2MPG11_PMIC_BB_CTRL,
|
||||
S2MPG11_PMIC_BB_OUT1,
|
||||
S2MPG11_PMIC_BB_OUT2,
|
||||
S2MPG11_PMIC_BUCK1S_USONIC,
|
||||
S2MPG11_PMIC_BUCK2S_USONIC,
|
||||
S2MPG11_PMIC_BUCK3S_USONIC,
|
||||
S2MPG11_PMIC_BUCK4S_USONIC,
|
||||
S2MPG11_PMIC_BUCK5S_USONIC,
|
||||
S2MPG11_PMIC_BUCK6S_USONIC,
|
||||
S2MPG11_PMIC_BUCK7S_USONIC,
|
||||
S2MPG11_PMIC_BUCK8S_USONIC,
|
||||
S2MPG11_PMIC_BUCK9S_USONIC,
|
||||
S2MPG11_PMIC_BUCK10S_USONIC,
|
||||
S2MPG11_PMIC_BUCKD_USONIC,
|
||||
S2MPG11_PMIC_BUCKA_USONIC,
|
||||
S2MPG11_PMIC_BB_USONIC,
|
||||
S2MPG11_PMIC_L1S_CTRL1,
|
||||
S2MPG11_PMIC_L1S_CTRL2,
|
||||
S2MPG11_PMIC_L2S_CTRL1,
|
||||
S2MPG11_PMIC_L2S_CTRL2,
|
||||
S2MPG11_PMIC_L3S_CTRL,
|
||||
S2MPG11_PMIC_L4S_CTRL,
|
||||
S2MPG11_PMIC_L5S_CTRL,
|
||||
S2MPG11_PMIC_L6S_CTRL,
|
||||
S2MPG11_PMIC_L7S_CTRL,
|
||||
S2MPG11_PMIC_L8S_CTRL,
|
||||
S2MPG11_PMIC_L9S_CTRL,
|
||||
S2MPG11_PMIC_L10S_CTRL,
|
||||
S2MPG11_PMIC_L11S_CTRL,
|
||||
S2MPG11_PMIC_L12S_CTRL,
|
||||
S2MPG11_PMIC_L13S_CTRL,
|
||||
S2MPG11_PMIC_L14S_CTRL,
|
||||
S2MPG11_PMIC_L15S_CTRL,
|
||||
S2MPG11_PMIC_LDO_CTRL1,
|
||||
S2MPG11_PMIC_LDO_DSCH1,
|
||||
S2MPG11_PMIC_LDO_DSCH2,
|
||||
S2MPG11_PMIC_DVS_RAMP1,
|
||||
S2MPG11_PMIC_DVS_RAMP2,
|
||||
S2MPG11_PMIC_DVS_RAMP3,
|
||||
S2MPG11_PMIC_DVS_RAMP4,
|
||||
S2MPG11_PMIC_DVS_RAMP5,
|
||||
S2MPG11_PMIC_DVS_RAMP6,
|
||||
/* Nothing @ 0x5a */
|
||||
S2MPG11_PMIC_DVS_SYNC_CTRL1 = 0x5c,
|
||||
S2MPG11_PMIC_DVS_SYNC_CTRL2,
|
||||
S2MPG11_PMIC_OFF_CTRL1,
|
||||
S2MPG11_PMIC_OFF_CTRL2,
|
||||
S2MPG11_PMIC_OFF_CTRL3,
|
||||
S2MPG11_PMIC_SEQ_CTRL1,
|
||||
S2MPG11_PMIC_SEQ_CTRL2,
|
||||
S2MPG11_PMIC_SEQ_CTRL3,
|
||||
S2MPG11_PMIC_SEQ_CTRL4,
|
||||
S2MPG11_PMIC_SEQ_CTRL5,
|
||||
S2MPG11_PMIC_SEQ_CTRL6,
|
||||
S2MPG11_PMIC_SEQ_CTRL7,
|
||||
S2MPG11_PMIC_SEQ_CTRL8,
|
||||
S2MPG11_PMIC_SEQ_CTRL9,
|
||||
S2MPG11_PMIC_SEQ_CTRL10,
|
||||
S2MPG11_PMIC_SEQ_CTRL11,
|
||||
S2MPG11_PMIC_SEQ_CTRL12,
|
||||
S2MPG11_PMIC_SEQ_CTRL13,
|
||||
S2MPG11_PMIC_SEQ_CTRL14,
|
||||
S2MPG11_PMIC_SEQ_CTRL15,
|
||||
S2MPG11_PMIC_SEQ_CTRL16,
|
||||
S2MPG11_PMIC_SEQ_CTRL17,
|
||||
S2MPG11_PMIC_SEQ_CTRL18,
|
||||
S2MPG11_PMIC_SEQ_CTRL19,
|
||||
S2MPG11_PMIC_SEQ_CTRL20,
|
||||
S2MPG11_PMIC_SEQ_CTRL21,
|
||||
S2MPG11_PMIC_SEQ_CTRL22,
|
||||
S2MPG11_PMIC_SEQ_CTRL23,
|
||||
S2MPG11_PMIC_SEQ_CTRL24,
|
||||
S2MPG11_PMIC_SEQ_CTRL25,
|
||||
S2MPG11_PMIC_SEQ_CTRL26,
|
||||
S2MPG11_PMIC_SEQ_CTRL27,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL1,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL2,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL3,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL4,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL5,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL6,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL7,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL8,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL9,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL10,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL11,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL12,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL13,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL14,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL15,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL16,
|
||||
S2MPG11_PMIC_OFF_SEQ_CTRL17,
|
||||
S2MPG11_PMIC_PCTRLSEL1,
|
||||
S2MPG11_PMIC_PCTRLSEL2,
|
||||
S2MPG11_PMIC_PCTRLSEL3,
|
||||
S2MPG11_PMIC_PCTRLSEL4,
|
||||
S2MPG11_PMIC_PCTRLSEL5,
|
||||
S2MPG11_PMIC_PCTRLSEL6,
|
||||
S2MPG11_PMIC_DCTRLSEL1,
|
||||
S2MPG11_PMIC_DCTRLSEL2,
|
||||
S2MPG11_PMIC_DCTRLSEL3,
|
||||
S2MPG11_PMIC_DCTRLSEL4,
|
||||
S2MPG11_PMIC_DCTRLSEL5,
|
||||
S2MPG11_PMIC_GPIO_CTRL1,
|
||||
S2MPG11_PMIC_GPIO_CTRL2,
|
||||
S2MPG11_PMIC_GPIO_CTRL3,
|
||||
S2MPG11_PMIC_GPIO_CTRL4,
|
||||
S2MPG11_PMIC_GPIO_CTRL5,
|
||||
S2MPG11_PMIC_GPIO_CTRL6,
|
||||
S2MPG11_PMIC_GPIO_CTRL7,
|
||||
S2MPG11_PMIC_B2S_OCP_WARN,
|
||||
S2MPG11_PMIC_B2S_OCP_WARN_X,
|
||||
S2MPG11_PMIC_B2S_OCP_WARN_Y,
|
||||
S2MPG11_PMIC_B2S_OCP_WARN_Z,
|
||||
S2MPG11_PMIC_B2S_SOFT_OCP_WARN,
|
||||
S2MPG11_PMIC_B2S_SOFT_OCP_WARN_X,
|
||||
S2MPG11_PMIC_B2S_SOFT_OCP_WARN_Y,
|
||||
S2MPG11_PMIC_B2S_SOFT_OCP_WARN_Z,
|
||||
S2MPG11_PMIC_BUCK_OCP_EN1,
|
||||
S2MPG11_PMIC_BUCK_OCP_EN2,
|
||||
S2MPG11_PMIC_BUCK_OCP_PD_EN1,
|
||||
S2MPG11_PMIC_BUCK_OCP_PD_EN2,
|
||||
S2MPG11_PMIC_BUCK_OCP_CTRL1,
|
||||
S2MPG11_PMIC_BUCK_OCP_CTRL2,
|
||||
S2MPG11_PMIC_BUCK_OCP_CTRL3,
|
||||
S2MPG11_PMIC_BUCK_OCP_CTRL4,
|
||||
S2MPG11_PMIC_BUCK_OCP_CTRL5,
|
||||
S2MPG11_PMIC_BUCK_OCP_CTRL6,
|
||||
S2MPG11_PMIC_BUCK_OCP_CTRL7,
|
||||
S2MPG11_PMIC_PIF_CTRL,
|
||||
S2MPG11_PMIC_BUCK_HR_MODE1,
|
||||
S2MPG11_PMIC_BUCK_HR_MODE2,
|
||||
S2MPG11_PMIC_FAULTOUT_CTRL,
|
||||
S2MPG11_PMIC_LDO_SENSE1,
|
||||
S2MPG11_PMIC_LDO_SENSE2,
|
||||
};
|
||||
|
||||
/* For S2MPG11_PMIC_PCTRLSELx */
|
||||
#define S2MPG11_PCTRLSEL_PWREN 0x1 /* PWREN pin */
|
||||
#define S2MPG11_PCTRLSEL_PWREN_TRG 0x2 /* PWREN_TRG bit in MIMICKING_CTRL */
|
||||
#define S2MPG11_PCTRLSEL_PWREN_MIF 0x3 /* PWREN_MIF pin */
|
||||
#define S2MPG11_PCTRLSEL_PWREN_MIF_TRG 0x4 /* PWREN_MIF_TRG bit in MIMICKING_CTRL */
|
||||
#define S2MPG11_PCTRLSEL_AP_ACTIVE_N 0x5 /* ~AP_ACTIVE_N pin */
|
||||
#define S2MPG11_PCTRLSEL_AP_ACTIVE_N_TRG 0x6 /* ~AP_ACTIVE_N_TRG bit in MIMICKING_CTRL */
|
||||
#define S2MPG11_PCTRLSEL_G3D_EN 0x7 /* G3D_EN pin */
|
||||
#define S2MPG11_PCTRLSEL_G3D_EN2 0x8 /* G3D_EN & ~AP_ACTIVE_N pins */
|
||||
#define S2MPG11_PCTRLSEL_AOC_VDD 0x9 /* AOC_VDD pin */
|
||||
#define S2MPG11_PCTRLSEL_AOC_RET 0xa /* AOC_RET pin */
|
||||
#define S2MPG11_PCTRLSEL_UFS_EN 0xb /* UFS_EN pin */
|
||||
#define S2MPG11_PCTRLSEL_LDO13S_EN 0xc /* VLDO13S_EN pin */
|
||||
|
||||
/* Meter registers (type 0xa00) */
|
||||
enum s2mpg11_meter_reg {
|
||||
S2MPG11_METER_CTRL1,
|
||||
S2MPG11_METER_CTRL2,
|
||||
S2MPG11_METER_CTRL3,
|
||||
S2MPG11_METER_CTRL4,
|
||||
S2MPG11_METER_CTRL5,
|
||||
S2MPG11_METER_BUCKEN1,
|
||||
S2MPG11_METER_BUCKEN2,
|
||||
S2MPG11_METER_MUXSEL0,
|
||||
S2MPG11_METER_MUXSEL1,
|
||||
S2MPG11_METER_MUXSEL2,
|
||||
S2MPG11_METER_MUXSEL3,
|
||||
S2MPG11_METER_MUXSEL4,
|
||||
S2MPG11_METER_MUXSEL5,
|
||||
S2MPG11_METER_MUXSEL6,
|
||||
S2MPG11_METER_MUXSEL7,
|
||||
S2MPG11_METER_LPF_C0_0,
|
||||
S2MPG11_METER_LPF_C0_1,
|
||||
S2MPG11_METER_LPF_C0_2,
|
||||
S2MPG11_METER_LPF_C0_3,
|
||||
S2MPG11_METER_LPF_C0_4,
|
||||
S2MPG11_METER_LPF_C0_5,
|
||||
S2MPG11_METER_LPF_C0_6,
|
||||
S2MPG11_METER_LPF_C0_7,
|
||||
S2MPG11_METER_NTC_LPF_C0_0,
|
||||
S2MPG11_METER_NTC_LPF_C0_1,
|
||||
S2MPG11_METER_NTC_LPF_C0_2,
|
||||
S2MPG11_METER_NTC_LPF_C0_3,
|
||||
S2MPG11_METER_NTC_LPF_C0_4,
|
||||
S2MPG11_METER_NTC_LPF_C0_5,
|
||||
S2MPG11_METER_NTC_LPF_C0_6,
|
||||
S2MPG11_METER_NTC_LPF_C0_7,
|
||||
S2MPG11_METER_PWR_WARN0,
|
||||
S2MPG11_METER_PWR_WARN1,
|
||||
S2MPG11_METER_PWR_WARN2,
|
||||
S2MPG11_METER_PWR_WARN3,
|
||||
S2MPG11_METER_PWR_WARN4,
|
||||
S2MPG11_METER_PWR_WARN5,
|
||||
S2MPG11_METER_PWR_WARN6,
|
||||
S2MPG11_METER_PWR_WARN7,
|
||||
S2MPG11_METER_NTC_L_WARN0,
|
||||
S2MPG11_METER_NTC_L_WARN1,
|
||||
S2MPG11_METER_NTC_L_WARN2,
|
||||
S2MPG11_METER_NTC_L_WARN3,
|
||||
S2MPG11_METER_NTC_L_WARN4,
|
||||
S2MPG11_METER_NTC_L_WARN5,
|
||||
S2MPG11_METER_NTC_L_WARN6,
|
||||
S2MPG11_METER_NTC_L_WARN7,
|
||||
S2MPG11_METER_NTC_H_WARN0,
|
||||
S2MPG11_METER_NTC_H_WARN1,
|
||||
S2MPG11_METER_NTC_H_WARN2,
|
||||
S2MPG11_METER_NTC_H_WARN3,
|
||||
S2MPG11_METER_NTC_H_WARN4,
|
||||
S2MPG11_METER_NTC_H_WARN5,
|
||||
S2MPG11_METER_NTC_H_WARN6,
|
||||
S2MPG11_METER_NTC_H_WARN7,
|
||||
S2MPG11_METER_PWR_HYS1,
|
||||
S2MPG11_METER_PWR_HYS2,
|
||||
S2MPG11_METER_PWR_HYS3,
|
||||
S2MPG11_METER_PWR_HYS4,
|
||||
S2MPG11_METER_NTC_HYS1,
|
||||
S2MPG11_METER_NTC_HYS2,
|
||||
S2MPG11_METER_NTC_HYS3,
|
||||
S2MPG11_METER_NTC_HYS4,
|
||||
/* Nothing @ 0x3f */
|
||||
S2MPG11_METER_ACC_DATA_CH0_1 = 0x40,
|
||||
S2MPG11_METER_ACC_DATA_CH0_2,
|
||||
S2MPG11_METER_ACC_DATA_CH0_3,
|
||||
S2MPG11_METER_ACC_DATA_CH0_4,
|
||||
S2MPG11_METER_ACC_DATA_CH0_5,
|
||||
S2MPG11_METER_ACC_DATA_CH0_6,
|
||||
S2MPG11_METER_ACC_DATA_CH1_1,
|
||||
S2MPG11_METER_ACC_DATA_CH1_2,
|
||||
S2MPG11_METER_ACC_DATA_CH1_3,
|
||||
S2MPG11_METER_ACC_DATA_CH1_4,
|
||||
S2MPG11_METER_ACC_DATA_CH1_5,
|
||||
S2MPG11_METER_ACC_DATA_CH1_6,
|
||||
S2MPG11_METER_ACC_DATA_CH2_1,
|
||||
S2MPG11_METER_ACC_DATA_CH2_2,
|
||||
S2MPG11_METER_ACC_DATA_CH2_3,
|
||||
S2MPG11_METER_ACC_DATA_CH2_4,
|
||||
S2MPG11_METER_ACC_DATA_CH2_5,
|
||||
S2MPG11_METER_ACC_DATA_CH2_6,
|
||||
S2MPG11_METER_ACC_DATA_CH3_1,
|
||||
S2MPG11_METER_ACC_DATA_CH3_2,
|
||||
S2MPG11_METER_ACC_DATA_CH3_3,
|
||||
S2MPG11_METER_ACC_DATA_CH3_4,
|
||||
S2MPG11_METER_ACC_DATA_CH3_5,
|
||||
S2MPG11_METER_ACC_DATA_CH3_6,
|
||||
S2MPG11_METER_ACC_DATA_CH4_1,
|
||||
S2MPG11_METER_ACC_DATA_CH4_2,
|
||||
S2MPG11_METER_ACC_DATA_CH4_3,
|
||||
S2MPG11_METER_ACC_DATA_CH4_4,
|
||||
S2MPG11_METER_ACC_DATA_CH4_5,
|
||||
S2MPG11_METER_ACC_DATA_CH4_6,
|
||||
S2MPG11_METER_ACC_DATA_CH5_1,
|
||||
S2MPG11_METER_ACC_DATA_CH5_2,
|
||||
S2MPG11_METER_ACC_DATA_CH5_3,
|
||||
S2MPG11_METER_ACC_DATA_CH5_4,
|
||||
S2MPG11_METER_ACC_DATA_CH5_5,
|
||||
S2MPG11_METER_ACC_DATA_CH5_6,
|
||||
S2MPG11_METER_ACC_DATA_CH6_1,
|
||||
S2MPG11_METER_ACC_DATA_CH6_2,
|
||||
S2MPG11_METER_ACC_DATA_CH6_3,
|
||||
S2MPG11_METER_ACC_DATA_CH6_4,
|
||||
S2MPG11_METER_ACC_DATA_CH6_5,
|
||||
S2MPG11_METER_ACC_DATA_CH6_6,
|
||||
S2MPG11_METER_ACC_DATA_CH7_1,
|
||||
S2MPG11_METER_ACC_DATA_CH7_2,
|
||||
S2MPG11_METER_ACC_DATA_CH7_3,
|
||||
S2MPG11_METER_ACC_DATA_CH7_4,
|
||||
S2MPG11_METER_ACC_DATA_CH7_5,
|
||||
S2MPG11_METER_ACC_DATA_CH7_6,
|
||||
S2MPG11_METER_ACC_COUNT_1,
|
||||
S2MPG11_METER_ACC_COUNT_2,
|
||||
S2MPG11_METER_ACC_COUNT_3,
|
||||
S2MPG11_METER_LPF_DATA_CH0_1,
|
||||
S2MPG11_METER_LPF_DATA_CH0_2,
|
||||
S2MPG11_METER_LPF_DATA_CH0_3,
|
||||
S2MPG11_METER_LPF_DATA_CH1_1,
|
||||
S2MPG11_METER_LPF_DATA_CH1_2,
|
||||
S2MPG11_METER_LPF_DATA_CH1_3,
|
||||
S2MPG11_METER_LPF_DATA_CH2_1,
|
||||
S2MPG11_METER_LPF_DATA_CH2_2,
|
||||
S2MPG11_METER_LPF_DATA_CH2_3,
|
||||
S2MPG11_METER_LPF_DATA_CH3_1,
|
||||
S2MPG11_METER_LPF_DATA_CH3_2,
|
||||
S2MPG11_METER_LPF_DATA_CH3_3,
|
||||
S2MPG11_METER_LPF_DATA_CH4_1,
|
||||
S2MPG11_METER_LPF_DATA_CH4_2,
|
||||
S2MPG11_METER_LPF_DATA_CH4_3,
|
||||
S2MPG11_METER_LPF_DATA_CH5_1,
|
||||
S2MPG11_METER_LPF_DATA_CH5_2,
|
||||
S2MPG11_METER_LPF_DATA_CH5_3,
|
||||
S2MPG11_METER_LPF_DATA_CH6_1,
|
||||
S2MPG11_METER_LPF_DATA_CH6_2,
|
||||
S2MPG11_METER_LPF_DATA_CH6_3,
|
||||
S2MPG11_METER_LPF_DATA_CH7_1,
|
||||
S2MPG11_METER_LPF_DATA_CH7_2,
|
||||
S2MPG11_METER_LPF_DATA_CH7_3,
|
||||
/* Nothing @ 0x8b 0x8c */
|
||||
S2MPG11_METER_LPF_DATA_NTC0_1 = 0x8d,
|
||||
S2MPG11_METER_LPF_DATA_NTC0_2,
|
||||
S2MPG11_METER_LPF_DATA_NTC1_1,
|
||||
S2MPG11_METER_LPF_DATA_NTC1_2,
|
||||
S2MPG11_METER_LPF_DATA_NTC2_1,
|
||||
S2MPG11_METER_LPF_DATA_NTC2_2,
|
||||
S2MPG11_METER_LPF_DATA_NTC3_1,
|
||||
S2MPG11_METER_LPF_DATA_NTC3_2,
|
||||
S2MPG11_METER_LPF_DATA_NTC4_1,
|
||||
S2MPG11_METER_LPF_DATA_NTC4_2,
|
||||
S2MPG11_METER_LPF_DATA_NTC5_1,
|
||||
S2MPG11_METER_LPF_DATA_NTC5_2,
|
||||
S2MPG11_METER_LPF_DATA_NTC6_1,
|
||||
S2MPG11_METER_LPF_DATA_NTC6_2,
|
||||
S2MPG11_METER_LPF_DATA_NTC7_1,
|
||||
S2MPG11_METER_LPF_DATA_NTC7_2,
|
||||
};
|
||||
|
||||
/* S2MPG11 regulator IDs */
|
||||
enum s2mpg11_regulators {
|
||||
S2MPG11_BUCKBOOST,
|
||||
S2MPG11_BUCK1,
|
||||
S2MPG11_BUCK2,
|
||||
S2MPG11_BUCK3,
|
||||
S2MPG11_BUCK4,
|
||||
S2MPG11_BUCK5,
|
||||
S2MPG11_BUCK6,
|
||||
S2MPG11_BUCK7,
|
||||
S2MPG11_BUCK8,
|
||||
S2MPG11_BUCK9,
|
||||
S2MPG11_BUCK10,
|
||||
S2MPG11_BUCKD,
|
||||
S2MPG11_BUCKA,
|
||||
S2MPG11_LDO1,
|
||||
S2MPG11_LDO2,
|
||||
S2MPG11_LDO3,
|
||||
S2MPG11_LDO4,
|
||||
S2MPG11_LDO5,
|
||||
S2MPG11_LDO6,
|
||||
S2MPG11_LDO7,
|
||||
S2MPG11_LDO8,
|
||||
S2MPG11_LDO9,
|
||||
S2MPG11_LDO10,
|
||||
S2MPG11_LDO11,
|
||||
S2MPG11_LDO12,
|
||||
S2MPG11_LDO13,
|
||||
S2MPG11_LDO14,
|
||||
S2MPG11_LDO15,
|
||||
S2MPG11_REGULATOR_MAX,
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MFD_S2MPG11_H */
|
||||
@@ -53,6 +53,11 @@ enum regulator_detection_severity {
|
||||
#define REGULATOR_LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV) \
|
||||
LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV)
|
||||
|
||||
/* Initialize struct linear_range using voltages, not selectors */
|
||||
#define REGULATOR_LINEAR_VRANGE(_offs_uV, _min_uV, _max_uV, _step_uV) \
|
||||
LINEAR_RANGE(_min_uV, ((_min_uV) - (_offs_uV)) / (_step_uV), \
|
||||
((_max_uV) - (_offs_uV)) / (_step_uV), _step_uV)
|
||||
|
||||
/**
|
||||
* struct regulator_ops - regulator operations.
|
||||
*
|
||||
@@ -635,6 +640,7 @@ struct regulator_dev {
|
||||
int ref_cnt;
|
||||
struct module *owner;
|
||||
struct device dev;
|
||||
struct device bdev;
|
||||
struct regulation_constraints *constraints;
|
||||
struct regulator *supply; /* for tree */
|
||||
const char *supply_name;
|
||||
@@ -649,6 +655,7 @@ struct regulator_dev {
|
||||
struct regulator_enable_gpio *ena_pin;
|
||||
unsigned int ena_gpio_state:1;
|
||||
|
||||
unsigned int constraints_pending:1;
|
||||
unsigned int is_switch:1;
|
||||
|
||||
/* time when this regulator was disabled last time */
|
||||
|
||||
@@ -4,48 +4,52 @@
|
||||
|
||||
#ifndef CONFIG_REGULATOR
|
||||
|
||||
void rust_helper_regulator_put(struct regulator *regulator)
|
||||
__rust_helper void rust_helper_regulator_put(struct regulator *regulator)
|
||||
{
|
||||
regulator_put(regulator);
|
||||
}
|
||||
|
||||
int rust_helper_regulator_set_voltage(struct regulator *regulator, int min_uV,
|
||||
int max_uV)
|
||||
__rust_helper int rust_helper_regulator_set_voltage(struct regulator *regulator,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
return regulator_set_voltage(regulator, min_uV, max_uV);
|
||||
}
|
||||
|
||||
int rust_helper_regulator_get_voltage(struct regulator *regulator)
|
||||
__rust_helper int rust_helper_regulator_get_voltage(struct regulator *regulator)
|
||||
{
|
||||
return regulator_get_voltage(regulator);
|
||||
}
|
||||
|
||||
struct regulator *rust_helper_regulator_get(struct device *dev, const char *id)
|
||||
__rust_helper struct regulator *rust_helper_regulator_get(struct device *dev,
|
||||
const char *id)
|
||||
{
|
||||
return regulator_get(dev, id);
|
||||
}
|
||||
|
||||
int rust_helper_regulator_enable(struct regulator *regulator)
|
||||
__rust_helper int rust_helper_regulator_enable(struct regulator *regulator)
|
||||
{
|
||||
return regulator_enable(regulator);
|
||||
}
|
||||
|
||||
int rust_helper_regulator_disable(struct regulator *regulator)
|
||||
__rust_helper int rust_helper_regulator_disable(struct regulator *regulator)
|
||||
{
|
||||
return regulator_disable(regulator);
|
||||
}
|
||||
|
||||
int rust_helper_regulator_is_enabled(struct regulator *regulator)
|
||||
__rust_helper int rust_helper_regulator_is_enabled(struct regulator *regulator)
|
||||
{
|
||||
return regulator_is_enabled(regulator);
|
||||
}
|
||||
|
||||
int rust_helper_devm_regulator_get_enable(struct device *dev, const char *id)
|
||||
__rust_helper int rust_helper_devm_regulator_get_enable(struct device *dev,
|
||||
const char *id)
|
||||
{
|
||||
return devm_regulator_get_enable(dev, id);
|
||||
}
|
||||
|
||||
int rust_helper_devm_regulator_get_enable_optional(struct device *dev, const char *id)
|
||||
__rust_helper int
|
||||
rust_helper_devm_regulator_get_enable_optional(struct device *dev,
|
||||
const char *id)
|
||||
{
|
||||
return devm_regulator_get_enable_optional(dev, id);
|
||||
}
|
||||
|
||||
@@ -122,12 +122,11 @@ pub fn devm_enable_optional(dev: &Device<Bound>, name: &CStr) -> Result {
|
||||
///
|
||||
/// ```
|
||||
/// # use kernel::prelude::*;
|
||||
/// # use kernel::c_str;
|
||||
/// # use kernel::device::Device;
|
||||
/// # use kernel::regulator::{Voltage, Regulator, Disabled, Enabled};
|
||||
/// fn enable(dev: &Device, min_voltage: Voltage, max_voltage: Voltage) -> Result {
|
||||
/// // Obtain a reference to a (fictitious) regulator.
|
||||
/// let regulator: Regulator<Disabled> = Regulator::<Disabled>::get(dev, c_str!("vcc"))?;
|
||||
/// let regulator: Regulator<Disabled> = Regulator::<Disabled>::get(dev, c"vcc")?;
|
||||
///
|
||||
/// // The voltage can be set before enabling the regulator if needed, e.g.:
|
||||
/// regulator.set_voltage(min_voltage, max_voltage)?;
|
||||
@@ -166,12 +165,11 @@ pub fn devm_enable_optional(dev: &Device<Bound>, name: &CStr) -> Result {
|
||||
///
|
||||
/// ```
|
||||
/// # use kernel::prelude::*;
|
||||
/// # use kernel::c_str;
|
||||
/// # use kernel::device::Device;
|
||||
/// # use kernel::regulator::{Voltage, Regulator, Enabled};
|
||||
/// fn enable(dev: &Device) -> Result {
|
||||
/// // Obtain a reference to a (fictitious) regulator and enable it.
|
||||
/// let regulator: Regulator<Enabled> = Regulator::<Enabled>::get(dev, c_str!("vcc"))?;
|
||||
/// let regulator: Regulator<Enabled> = Regulator::<Enabled>::get(dev, c"vcc")?;
|
||||
///
|
||||
/// // Dropping an enabled regulator will disable it. The refcount will be
|
||||
/// // decremented.
|
||||
@@ -193,13 +191,12 @@ pub fn devm_enable_optional(dev: &Device<Bound>, name: &CStr) -> Result {
|
||||
///
|
||||
/// ```
|
||||
/// # use kernel::prelude::*;
|
||||
/// # use kernel::c_str;
|
||||
/// # use kernel::device::{Bound, Device};
|
||||
/// # use kernel::regulator;
|
||||
/// fn enable(dev: &Device<Bound>) -> Result {
|
||||
/// // Obtain a reference to a (fictitious) regulator and enable it. This
|
||||
/// // call only returns whether the operation succeeded.
|
||||
/// regulator::devm_enable(dev, c_str!("vcc"))?;
|
||||
/// regulator::devm_enable(dev, c"vcc")?;
|
||||
///
|
||||
/// // The regulator will be disabled and put when `dev` is unbound.
|
||||
/// Ok(())
|
||||
|
||||
Reference in New Issue
Block a user