regulator: Updates for v6.6

Other tha new device support and some minor fixes this has been a really
 quiet release, the only notable things are the new drivers.  There's a
 couple of MFDs among the new devices so the generic parts are pulled in:
 
  - Support for Analog Devices MAX77831/57/59, Awinc AW37503, Qualcom
    PMX75 and RFGEN, RealTek RT5733, RichTek RTQ2208 and Texas
    Instruments TPS65086.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmTp6U4ACgkQJNaLcl1U
 h9Cu4gf/RZZirDVcISmKrIYn95Dc838pHFe3tIK9Ehbwms/pzBWBzT0Eiy36g4Vd
 1pUB6YJKJZIKLOfFAjmudGtT9C3Yrui+3cR3dPtxN793ixfCkT2RVdeaNJDCJ6xo
 cPpAekMroDpMSczDvsTaqJzCXb4y+rjsAQ201w+WhegkSLk/yMsW7Y+a6wpaMjwt
 qGD/+EDk/54aogPhrGvKq7uLwCgDo2A6HrU2rIIMHYnZuPaSjsPGcd0fZahlP7Mk
 1b6/SSJ+KvN0XSAgBz4yFixECb0OG9p5ukpV17hwDAPBbNqLRp+O/o3LFLq+nsoY
 yG3RpJQM6r3Bw3KqdxWF/e5sUNkEsQ==
 =ZB93
 -----END PGP SIGNATURE-----

Merge tag 'regulator-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "Other than new device support and some minor fixes this has been a
  really quiet release, the only notable things are the new drivers.

  There's a couple of MFDs among the new devices so the generic parts
  are pulled in:

   - Support for Analog Devices MAX77831/57/59, Awinc AW37503, Qualcom
     PMX75 and RFGEN, RealTek RT5733, RichTek RTQ2208 and Texas
     Instruments TPS65086"

* tag 'regulator-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (68 commits)
  regulator: userspace-consumer: Drop event support for this cycle
  regulator: aw37503: Switch back to use struct i2c_driver's .probe()
  dt-bindings: regulator: qcom,rpmh-regulator: allow i, j, l, m & n as RPMh resource name suffix
  regulator: dt-bindings: Add Awinic AW37503
  regulator: aw37503: add regulator driver for Awinic AW37503
  regulator: tps65086: Select dedicated regulator config for chip variant
  mfd: tps65086: Read DEVICE ID register 1 from device
  regulator: raa215300: Update help description
  regulator: raa215300: Add missing blank space
  regulator: raa215300: Change rate from 32000->32768
  regulator: db8500-prcmu: Remove unused declaration power_state_active_is_enabled()
  regulator: raa215300: Add const definition
  regulator: raa215300: Fix resource leak in case of error
  regulator: rtq2208: Switch back to use struct i2c_driver's .probe()
  regulator: lp872x: Fix Wvoid-pointer-to-enum-cast warning
  regulator: max77857: Fix Wvoid-pointer-to-enum-cast warning
  regulator: ltc3589: Fix Wvoid-pointer-to-enum-cast warning
  regulator: qcom_rpm-regulator: Use devm_kmemdup to replace devm_kmalloc + memcpy
  regulator: tps6286x-regulator: Remove redundant of_match_ptr() macros
  regulator: pfuze100-regulator: Remove redundant of_match_ptr() macro
  ...
This commit is contained in:
Linus Torvalds 2023-08-29 09:40:16 -07:00
commit 65234f96f2
94 changed files with 2535 additions and 351 deletions

View file

@ -28,75 +28,37 @@ properties:
the VSEL pin is assumed to be low.
type: boolean
inl1-supply:
description: Handle to the INL1 input supply (REG5-7)
inl2-supply:
description: Handle to the INL2 input supply (REG8-9)
inl3-supply:
description: Handle to the INL3 input supply (REG10-12)
vp1-supply:
description: Handle to the VP1 input supply (REG1)
vp2-supply:
description: Handle to the VP2 input supply (REG2)
vp3-supply:
description: Handle to the VP3 input supply (REG3)
vp4-supply:
description: Handle to the VP4 input supply (REG4)
regulators:
type: object
additionalProperties: false
properties:
REG1:
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
properties:
vp1-supply:
description: Handle to the VP1 input supply
REG2:
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
properties:
vp2-supply:
description: Handle to the VP2 input supply
REG3:
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
properties:
vp3-supply:
description: Handle to the VP3 input supply
REG4:
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
properties:
vp4-supply:
description: Handle to the VP4 input supply
patternProperties:
"^REG[5-7]$":
"^REG([1-9]|1[0-2])$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
properties:
inl1-supply:
description: Handle to the INL1 input supply
"^REG[8-9]$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
properties:
inl2-supply:
description: Handle to the INL2 input supply
"^REG1[0-2]$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
properties:
inl3-supply:
description: Handle to the INL3 input supply
additionalProperties: false
required:

View file

@ -0,0 +1,86 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2022 Analog Devices Inc.
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/adi,max77857.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices MAX77857 Buck-Boost Converter
maintainers:
- Ibrahim Tilki <Ibrahim.Tilki@analog.com>
- Okan Sahin <Okan.Sahin@analog.com>
description: Analog Devices MAX77857 Buck-Boost Converter
properties:
compatible:
enum:
- adi,max77831
- adi,max77857
- adi,max77859
- adi,max77859a
reg:
description: I2C address of the device
items:
- enum: [0x66, 0x67, 0x6E, 0x6F]
interrupts:
maxItems: 1
adi,switch-frequency-hz:
description: Switching frequency of the Buck-Boost converter in Hz.
items:
- enum: [1200000, 1500000, 1800000, 2100000]
adi,rtop-ohms:
description: Top feedback resistor value in ohms for external feedback.
minimum: 150000
maximum: 330000
adi,rbot-ohms:
description: Bottom feedback resistor value in ohms for external feedback.
dependencies:
adi,rtop-ohms: [ 'adi,rbot-ohms' ]
adi,rbot-ohms: [ 'adi,rtop-ohms' ]
required:
- compatible
- reg
allOf:
- $ref: regulator.yaml#
- if:
properties:
compatible:
contains:
enum:
- adi,max77831
then:
properties:
adi,switch-frequency-hz:
items:
enum: [1200000, 1500000, 1800000]
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
regulator@66 {
reg = <0x66>;
compatible = "adi,max77857";
interrupt-parent = <&gpio>;
interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
adi,rtop-ohms = <312000>;
adi,rbot-ohms = <12000>;
};
};

View file

@ -0,0 +1,78 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/awinic,aw37503.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Awinic AW37503 Voltage Regulator
maintainers:
- Alec Li <like@awinic.com>
description:
The AW37503 are dual voltage regulator, designed to support positive/negative
supply for driving TFT-LCD panels. It support software-configurable output
switching and monitoring. The output voltages can be programmed via an I2C
compatible interface.
properties:
compatible:
const: awinic,aw37503
reg:
maxItems: 1
patternProperties:
"^out[pn]$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for single regulator.
properties:
enable-gpios:
maxItems: 1
description:
GPIO specifier to enable the GPIO control (on/off) for regulator.
required:
- regulator-name
required:
- compatible
- reg
- outp
- outn
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
regulator@3e {
compatible = "awinic,aw37503";
reg = <0x3e>;
outp {
regulator-name = "outp";
regulator-boot-on;
regulator-always-on;
enable-gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
};
outn {
regulator-name = "outn";
regulator-boot-on;
regulator-always-on;
enable-gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
};
};
};
...

View file

@ -95,11 +95,6 @@ properties:
Properties for a single BUCK regulator
properties:
regulator-name:
pattern: "^BUCK([1-2])$"
description: |
BUCK2 present in DA9122, DA9220, DA9131, DA9132 only
regulator-initial-mode:
enum: [ 0, 1, 2, 3 ]
description: Defined in include/dt-bindings/regulator/dlg,da9121-regulator.h
@ -122,6 +117,23 @@ required:
- reg
- regulators
allOf:
- if:
properties:
compatible:
not:
contains:
enum:
- dlg,da9122
- dlg,da9131
- dlg,da9132
- dlg,da9220
then:
properties:
regulators:
properties:
buck2: false
additionalProperties: false
examples:

View file

@ -0,0 +1,132 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/dlg,slg51000.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Dialog Semiconductor SLG51000 Voltage Regulator
maintainers:
- Eric Jeong <eric.jeong.opensource@diasemi.com>
- Support Opensource <support.opensource@diasemi.com>
properties:
compatible:
const: dlg,slg51000
reg:
maxItems: 1
interrupts:
maxItems: 1
dlg,cs-gpios:
maxItems: 1
description:
GPIO for chip select
vin3-supply:
description:
Input supply for ldo3, required if regulator is enabled
vin4-supply:
description:
Input supply for ldo4, required if regulator is enabled
vin5-supply:
description:
Input supply for ldo5, required if regulator is enabled
vin6-supply:
description:
Input supply for ldo6, required if regulator is enabled
vin7-supply:
description:
Input supply for ldo7, required if regulator is enabled
regulators:
type: object
additionalProperties: false
patternProperties:
"^ldo[1-7]$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
properties:
enable-gpios:
maxItems: 1
required:
- regulator-name
required:
- compatible
- reg
- regulators
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/regulator/dlg,da9121-regulator.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@75 {
compatible = "dlg,slg51000";
reg = <0x75>;
dlg,cs-gpios = <&tlmm 69 GPIO_ACTIVE_HIGH>;
vin5-supply = <&vreg_s1f_1p2>;
vin6-supply = <&vreg_s1f_1p2>;
regulators {
ldo1 {
regulator-name = "slg51000_b_ldo1";
regulator-min-microvolt = <2400000>;
regulator-max-microvolt = <3300000>;
};
ldo2 {
regulator-name = "slg51000_b_ldo2";
regulator-min-microvolt = <2400000>;
regulator-max-microvolt = <3300000>;
};
ldo3 {
regulator-name = "slg51000_b_ldo3";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3750000>;
};
ldo4 {
regulator-name = "slg51000_b_ldo4";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3750000>;
};
ldo5 {
regulator-name = "slg51000_b_ldo5";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1200000>;
};
ldo6 {
regulator-name = "slg51000_b_ldo6";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1200000>;
};
ldo7 {
regulator-name = "slg51000_b_ldo7";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3750000>;
};
};
};
};

View file

@ -29,10 +29,12 @@ properties:
patternProperties:
"^buck[1-4]$":
$ref: regulator.yaml#
unevaluatedProperties: false
type: object
"^ldo[1-4]$":
$ref: regulator.yaml#
unevaluatedProperties: false
type: object
additionalProperties: false

View file

@ -21,7 +21,6 @@ properties:
regulators:
type: object
$ref: regulator.yaml#
description: |
list of regulators provided by this controller, must be named
@ -39,11 +38,13 @@ properties:
ldortc:
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
patternProperties:
"^ldo[1-4]$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
"^buck[1-4]$":
type: object

View file

@ -68,18 +68,22 @@ properties:
"^sw([1-4]|[1-4][a-c]|[1-4][a-c][a-c])$":
$ref: regulator.yaml#
type: object
unevaluatedProperties: false
"^vgen[1-6]$":
$ref: regulator.yaml#
type: object
unevaluatedProperties: false
"^vldo[1-4]$":
$ref: regulator.yaml#
type: object
unevaluatedProperties: false
"^(vsnvs|vref|vrefddr|swbst|coin|v33|vccsd)$":
$ref: regulator.yaml#
type: object
unevaluatedProperties: false
additionalProperties: false

View file

@ -49,7 +49,7 @@ patternProperties:
".*-supply$":
description: Input supply phandle(s) for this node
"^((s|l|lvs)[0-9]*)|(s[1-2][a-b])|(ncp)|(mvs)|(usb-switch)|(hdmi-switch)$":
"^((s|l|lvs)[0-9]*|s[1-2][a-b]|ncp|mvs|usb-switch|hdmi-switch)$":
description: List of regulators and its properties
$ref: regulator.yaml#
unevaluatedProperties: false

View file

@ -53,6 +53,7 @@ description: |
For PMR735A, smps1 - smps3, ldo1 - ldo7
For PMX55, smps1 - smps7, ldo1 - ldo16
For PMX65, smps1 - smps8, ldo1 - ldo21
For PMX75, smps1 - smps10, ldo1 - ldo21
properties:
compatible:
@ -84,13 +85,14 @@ properties:
- qcom,pmr735a-rpmh-regulators
- qcom,pmx55-rpmh-regulators
- qcom,pmx65-rpmh-regulators
- qcom,pmx75-rpmh-regulators
qcom,pmic-id:
description: |
RPMh resource name suffix used for the regulators found
on this PMIC.
$ref: /schemas/types.yaml#/definitions/string
enum: [a, b, c, d, e, f, g, h, k]
enum: [a, b, c, d, e, f, g, h, i, j, k, l, m, n]
qcom,always-wait-for-ack:
description: |
@ -109,6 +111,7 @@ properties:
bob:
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description: BOB regulator node.
dependencies:
regulator-allow-set-load: [ regulator-allowed-modes ]
@ -117,6 +120,7 @@ patternProperties:
"^(smps|ldo|lvs|bob)[0-9]+$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description: smps/ldo regulator nodes(s).
dependencies:
regulator-allow-set-load: [ regulator-allowed-modes ]
@ -424,10 +428,28 @@ allOf:
vdd-l11-l13-supply: true
patternProperties:
"^vdd-l[1347]-supply$": true
"^vdd-l1[0245789]-supply$": true
"^vdd-l1[024579]-supply$": true
"^vdd-l2[01]-supply$": true
"^vdd-s[1-8]-supply$": true
- if:
properties:
compatible:
enum:
- qcom,pmx75-rpmh-regulators
then:
properties:
vdd-l2-l18-supply: true
vdd-l4-l16-supply: true
vdd-l5-l6-supply: true
vdd-l8-l9-supply: true
vdd-l11-l13-supply: true
vdd-l20-l21-supply: true
patternProperties:
"^vdd-l[137]-supply$": true
"^vdd-l1[024579]-supply$": true
"^vdd-s([1-9]|10)-supply$": true
unevaluatedProperties: false
examples:

View file

@ -0,0 +1,57 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/qcom,sdm845-refgen-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. REFGEN Regulator
maintainers:
- Konrad Dybcio <konradybcio@kernel.org>
description:
The REFGEN (reference voltage generator) regulator provides reference
voltage for on-chip IPs (like PHYs) on some Qualcomm SoCs.
allOf:
- $ref: regulator.yaml#
properties:
compatible:
oneOf:
- items:
- enum:
- qcom,sc7180-refgen-regulator
- qcom,sc8180x-refgen-regulator
- qcom,sm8150-refgen-regulator
- const: qcom,sdm845-refgen-regulator
- items:
- enum:
- qcom,sc7280-refgen-regulator
- qcom,sc8280xp-refgen-regulator
- qcom,sm6350-refgen-regulator
- qcom,sm6375-refgen-regulator
- qcom,sm8350-refgen-regulator
- const: qcom,sm8250-refgen-regulator
- enum:
- qcom,sdm845-refgen-regulator
- qcom,sm8250-refgen-regulator
reg:
maxItems: 1
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
regulator@162f000 {
compatible = "qcom,sm8250-refgen-regulator";
reg = <0x0162f000 0x84>;
};
...

View file

@ -110,6 +110,7 @@ patternProperties:
"^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$":
description: List of regulators and its properties
$ref: regulator.yaml#
unevaluatedProperties: false
additionalProperties: false

View file

@ -29,6 +29,7 @@ patternProperties:
"^DSV(LCM|P|N)$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for single Display Bias Voltage regulator.

View file

@ -21,6 +21,7 @@ allOf:
properties:
compatible:
enum:
- richtek,rt5733
- richtek,rt5739
reg:

View file

@ -121,6 +121,7 @@ properties:
description: load switch current regulator description.
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
required:
- compatible

View file

@ -0,0 +1,197 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/richtek,rtq2208.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Richtek RTQ2208 SubPMIC Regulator
maintainers:
- Alina Yu <alina_yu@richtek.com>
description: |
RTQ2208 is a highly integrated power converter that offers functional safety dual
multi-configurable synchronous buck converters and two LDOs.
Bucks support "regulator-allowed-modes" and "regulator-mode". The former defines the permitted
switching operation in normal mode; the latter defines the operation in suspend to RAM mode.
No matter the RTQ2208 is configured to normal or suspend to RAM mode, there are two switching
operation modes for all buck rails, automatic power saving mode (Auto mode) and forced continuous
conduction mode (FCCM).
The definition of modes is in the datasheet which is available in below link
and their meaning is::
0 - Auto mode for power saving, which reducing the switching frequency at light load condition
to maintain high frequency.
1 - FCCM to meet the strict voltage regulation accuracy, which keeping constant switching frequency.
Datasheet will be available soon at
https://www.richtek.com/assets/Products
properties:
compatible:
enum:
- richtek,rtq2208
reg:
maxItems: 1
interrupts:
maxItems: 1
richtek,mtp-sel-high:
type: boolean
description:
vout register selection based on this boolean value.
false - Using DVS0 register setting to adjust vout
true - Using DVS1 register setting to adjust vout
regulators:
type: object
additionalProperties: false
patternProperties:
"^buck-[a-h]$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
description for buck-[a-h] regulator.
properties:
regulator-allowed-modes:
description:
two buck modes in different switching accuracy.
0 - Auto mode
1 - FCCM
items:
enum: [0, 1]
"^ldo[1-2]$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
regulator description for ldo[1-2].
required:
- compatible
- reg
- regulators
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@10 {
compatible = "richtek,rtq2208";
reg = <0x10>;
interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;
richtek,mtp-sel-high;
regulators {
buck-a {
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <2050000>;
regulator-allowed-modes = <0 1>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <1>;
};
};
buck-b {
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <2050000>;
regulator-allowed-modes = <0 1>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <1>;
};
};
buck-c {
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <2050000>;
regulator-allowed-modes = <0 1>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <1>;
};
};
buck-d {
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <2050000>;
regulator-allowed-modes = <0 1>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <1>;
};
};
buck-e {
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <2050000>;
regulator-allowed-modes = <0 1>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <1>;
};
};
buck-f {
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <2050000>;
regulator-allowed-modes = <0 1>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <1>;
};
};
buck-g {
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <2050000>;
regulator-allowed-modes = <0 1>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <1>;
};
};
buck-h {
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <2050000>;
regulator-allowed-modes = <0 1>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <1>;
};
};
ldo1 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
};
};
ldo2 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
};
};
};
};
};

View file

@ -35,6 +35,7 @@ properties:
"^(p|n)avdd$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description: |
regulator description for pavdd and navdd.

View file

@ -1,88 +0,0 @@
* Dialog Semiconductor SLG51000 Voltage Regulator
Required properties:
- compatible : Should be "dlg,slg51000" for SLG51000
- reg : Specifies the I2C slave address.
- xxx-supply: Input voltage supply regulator for ldo3 to ldo7.
These entries are required if regulators are enabled for a device.
An absence of these properties can cause the regulator registration to fail.
If some of input supply is powered through battery or always-on supply then
also it is required to have these parameters with proper node handle of always
on power supply.
vin3-supply: Input supply for ldo3
vin4-supply: Input supply for ldo4
vin5-supply: Input supply for ldo5
vin6-supply: Input supply for ldo6
vin7-supply: Input supply for ldo7
Optional properties:
- interrupt-parent : Specifies the reference to the interrupt controller.
- interrupts : IRQ line information.
- dlg,cs-gpios : Specify a valid GPIO for chip select
Sub-nodes:
- regulators : This node defines the settings for the regulators.
The content of the sub-node is defined by the standard binding
for regulators; see regulator.txt.
The SLG51000 regulators are bound using their names listed below:
ldo1
ldo2
ldo3
ldo4
ldo5
ldo6
ldo7
Optional properties for regulators:
- enable-gpios : Specify a valid GPIO for platform control of the regulator.
Example:
pmic: slg51000@75 {
compatible = "dlg,slg51000";
reg = <0x75>;
regulators {
ldo1 {
regulator-name = "ldo1";
regulator-min-microvolt = <2400000>;
regulator-max-microvolt = <3300000>;
};
ldo2 {
regulator-name = "ldo2";
regulator-min-microvolt = <2400000>;
regulator-max-microvolt = <3300000>;
};
ldo3 {
regulator-name = "ldo3";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3750000>;
};
ldo4 {
regulator-name = "ldo4";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3750000>;
};
ldo5 {
regulator-name = "ldo5";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1200000>;
};
ldo6 {
regulator-name = "ldo6";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1200000>;
};
ldo7 {
regulator-name = "ldo7";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3750000>;
};
};
};

View file

@ -25,8 +25,8 @@ properties:
patternProperties:
"^(reg11|reg18|usb33)$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
required:
- compatible

View file

@ -29,11 +29,13 @@ properties:
Initial data for the LDO1 regulator.
$ref: regulator.yaml#
type: object
unevaluatedProperties: false
micvdd:
description:
Initial data for the MICVDD regulator.
$ref: regulator.yaml#
type: object
unevaluatedProperties: false
additionalProperties: true

View file

@ -6010,7 +6010,7 @@ F: Documentation/devicetree/bindings/mfd/da90*.txt
F: Documentation/devicetree/bindings/mfd/dlg,da90*.yaml
F: Documentation/devicetree/bindings/regulator/da92*.txt
F: Documentation/devicetree/bindings/regulator/dlg,da9*.yaml
F: Documentation/devicetree/bindings/regulator/slg51000.txt
F: Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml
F: Documentation/devicetree/bindings/sound/da[79]*.txt
F: Documentation/devicetree/bindings/thermal/da90??-thermal.txt
F: Documentation/devicetree/bindings/watchdog/da90??-wdt.txt

View file

@ -81,16 +81,23 @@ static int tps65086_probe(struct i2c_client *client)
return PTR_ERR(tps->regmap);
}
ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
/* Store device ID to load regulator configuration that fit to IC variant */
ret = regmap_read(tps->regmap, TPS65086_DEVICEID1, &tps->chip_id);
if (ret) {
dev_err(tps->dev, "Failed to read revision register\n");
dev_err(tps->dev, "Failed to read revision register 1\n");
return ret;
}
ret = regmap_read(tps->regmap, TPS65086_DEVICEID2, &version);
if (ret) {
dev_err(tps->dev, "Failed to read revision register 2\n");
return ret;
}
dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
(version & TPS65086_DEVICEID_PART_MASK),
(char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
(version & TPS65086_DEVICEID_REV_MASK) >> 6);
(version & TPS65086_DEVICEID2_PART_MASK),
(char)((version & TPS65086_DEVICEID2_OTP_MASK) >> 4) + 'A',
(version & TPS65086_DEVICEID2_REV_MASK) >> 6);
if (tps->irq > 0) {
ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,

View file

@ -178,6 +178,14 @@ config REGULATOR_ATC260X
ATC260x PMICs. This will enable support for all the software
controllable DCDC/LDO regulators.
config REGULATOR_AW37503
tristate "Awinic AW37503 Dual Output Power regulators"
depends on I2C && GPIOLIB
select REGMAP_I2C
help
This driver supports AW37503 single inductor - dual output
power supply specifically designed for display panels.
config REGULATOR_AXP20X
tristate "X-POWERS AXP20X PMIC Regulators"
depends on MFD_AXP20X
@ -546,11 +554,11 @@ config REGULATOR_MAX1586
regulator via I2C bus. The provided regulator is suitable
for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
config REGULATOR_MAX597X
tristate "Maxim 597x power switch and monitor"
config REGULATOR_MAX5970
tristate "Maxim 5970/5978 power switch and monitor"
depends on I2C
depends on OF
depends on MFD_MAX597X
depends on MFD_MAX5970
help
This driver controls a Maxim 5970/5978 switch via I2C bus.
The MAX5970/5978 is a smart switch with no output regulation, but
@ -584,6 +592,16 @@ config REGULATOR_MAX77650
Semiconductor. This device has a SIMO with three independent
power rails and an LDO.
config REGULATOR_MAX77857
tristate "ADI MAX77857/MAX77831 regulator support"
depends on I2C
select REGMAP_I2C
help
This driver controls a ADI MAX77857 and MAX77831 regulators.
via I2C bus. MAX77857 and MAX77831 are high efficiency buck-boost
converters with input voltage range (2.5V to 16V). Say Y here to
enable the regulator driver
config REGULATOR_MAX8649
tristate "Maxim 8649 voltage regulator"
depends on I2C
@ -989,6 +1007,18 @@ config REGULATOR_PWM
This driver supports PWM controlled voltage regulators. PWM
duty cycle can increase or decrease the voltage.
config REGULATOR_QCOM_REFGEN
tristate "Qualcomm REFGEN regulator driver"
depends on ARCH_QCOM || COMPILE_TEST
depends on HAS_IOMEM
depends on REGMAP
help
This driver supports the MMIO-mapped reference voltage regulator,
used internally by some PHYs on many Qualcomm SoCs.
Say M here if you want to include support for this regulator as
a module. The module will be named "qcom-refgen-regulator".
config REGULATOR_QCOM_RPM
tristate "Qualcomm RPM regulator driver"
depends on MFD_QCOM_RPM
@ -1050,7 +1080,11 @@ config REGULATOR_RAA215300
depends on COMMON_CLK
depends on I2C
help
Support for the Renesas RAA215300 PMIC.
If you say yes to this option, support will be included for the
Renesas RAA215300 PMIC.
Say M here if you want to include support for Renesas RAA215300 PMIC
as a module. The module will be named "raa215300".
config REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY
tristate "Raspberry Pi 7-inch touchscreen panel ATTINY regulator"
@ -1232,6 +1266,17 @@ config REGULATOR_RTQ6752
synchronous boost converters for PAVDD, and one synchronous NAVDD
buck-boost. This device is suitable for automotive TFT-LCD panel.
config REGULATOR_RTQ2208
tristate "Richtek RTQ2208 SubPMIC Regulator"
depends on I2C
select REGMAP_I2C
help
This driver adds support for RTQ2208 SubPMIC regulators.
The RTQ2208 is a multi-phase, programmable power management IC that
integrate with dual multi-configurable, synchronous buck converters
and two ldos. It features wide output voltage range from 0.4V to 2.05V
and the capability to configure the corresponding power stages.
config REGULATOR_S2MPA01
tristate "Samsung S2MPA01 voltage regulator"
depends on MFD_SEC_CORE || COMPILE_TEST

View file

@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_ARM_SCMI) += scmi-regulator.o
obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
obj-$(CONFIG_REGULATOR_ATC260X) += atc260x-regulator.o
obj-$(CONFIG_REGULATOR_AW37503) += aw37503-regulator.o
obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
obj-$(CONFIG_REGULATOR_BD71815) += bd71815-regulator.o
@ -67,7 +68,7 @@ obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_MAX597X) += max597x-regulator.o
obj-$(CONFIG_REGULATOR_MAX5970) += max5970-regulator.o
obj-$(CONFIG_REGULATOR_MAX77541) += max77541-regulator.o
obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o
@ -86,6 +87,7 @@ obj-$(CONFIG_REGULATOR_MAX77686) += max77686-regulator.o
obj-$(CONFIG_REGULATOR_MAX77693) += max77693-regulator.o
obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o
obj-$(CONFIG_REGULATOR_MAX77826) += max77826-regulator.o
obj-$(CONFIG_REGULATOR_MAX77857) += max77857-regulator.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
@ -108,6 +110,7 @@ obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_REFGEN) += qcom-refgen-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
@ -145,6 +148,7 @@ obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o
obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
obj-$(CONFIG_REGULATOR_RTQ2134) += rtq2134-regulator.o
obj-$(CONFIG_REGULATOR_RTQ6752) += rtq6752-regulator.o
obj-$(CONFIG_REGULATOR_RTQ2208) += rtq2208-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o

View file

@ -8,7 +8,7 @@
*/
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>

View file

@ -7,7 +7,8 @@
#include <linux/mfd/atc260x/core.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
@ -37,7 +38,7 @@ static const struct linear_range atc2609a_ldo_voltage_ranges1[] = {
};
static const unsigned int atc260x_ldo_voltage_range_sel[] = {
0x0, 0x20,
0x0, 0x1,
};
static int atc260x_dcdc_set_voltage_time_sel(struct regulator_dev *rdev,
@ -427,7 +428,7 @@ enum atc2609a_reg_ids {
.vsel_mask = GENMASK(4, 1), \
.vsel_range_reg = ATC2609A_PMU_LDO##num##_CTL0, \
.vsel_range_mask = BIT(5), \
.linear_range_selectors = atc260x_ldo_voltage_range_sel, \
.linear_range_selectors_bitfield = atc260x_ldo_voltage_range_sel, \
.enable_reg = ATC2609A_PMU_LDO##num##_CTL0, \
.enable_mask = BIT(0), \
.enable_time = 2000, \

View file

@ -0,0 +1,240 @@
// SPDX-License-Identifier: GPL-2.0
//
// AWINIC AW37503 Regulator Driver
//
// Copyright (C) 2023 awinic. All Rights Reserved
//
// Author: <like@awinic.com>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#define AW37503_REG_VPOS 0x00
#define AW37503_REG_VNEG 0x01
#define AW37503_REG_APPS 0x03
#define AW37503_REG_CONTROL 0x04
#define AW37503_REG_WPRTEN 0x21
#define AW37503_VOUT_MASK 0x1F
#define AW37503_VOUT_N_VOLTAGE 0x15
#define AW37503_VOUT_VMIN 4000000
#define AW37503_VOUT_VMAX 6000000
#define AW37503_VOUT_STEP 100000
#define AW37503_REG_APPS_DIS_VPOS BIT(1)
#define AW37503_REG_APPS_DIS_VNEG BIT(0)
#define AW37503_REGULATOR_ID_VPOS 0
#define AW37503_REGULATOR_ID_VNEG 1
#define AW37503_MAX_REGULATORS 2
struct aw37503_reg_pdata {
struct gpio_desc *en_gpiod;
int ena_gpio_state;
};
struct aw37503_regulator {
struct device *dev;
struct aw37503_reg_pdata reg_pdata[AW37503_MAX_REGULATORS];
};
static int aw37503_regulator_enable(struct regulator_dev *rdev)
{
struct aw37503_regulator *chip = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[id];
int ret;
if (!IS_ERR(rpdata->en_gpiod)) {
gpiod_set_value_cansleep(rpdata->en_gpiod, 1);
rpdata->ena_gpio_state = 1;
}
/* Hardware automatically enable discharge bit in enable */
if (rdev->constraints->active_discharge ==
REGULATOR_ACTIVE_DISCHARGE_DISABLE) {
ret = regulator_set_active_discharge_regmap(rdev, false);
if (ret < 0) {
dev_err(chip->dev, "Failed to disable active discharge: %d\n",
ret);
return ret;
}
}
return 0;
}
static int aw37503_regulator_disable(struct regulator_dev *rdev)
{
struct aw37503_regulator *chip = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[id];
if (!IS_ERR(rpdata->en_gpiod)) {
gpiod_set_value_cansleep(rpdata->en_gpiod, 0);
rpdata->ena_gpio_state = 0;
}
return 0;
}
static int aw37503_regulator_is_enabled(struct regulator_dev *rdev)
{
struct aw37503_regulator *chip = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[id];
if (!IS_ERR(rpdata->en_gpiod))
return rpdata->ena_gpio_state;
return 1;
}
static const struct regulator_ops aw37503_regulator_ops = {
.enable = aw37503_regulator_enable,
.disable = aw37503_regulator_disable,
.is_enabled = aw37503_regulator_is_enabled,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
};
static int aw37503_of_parse_cb(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *config)
{
struct aw37503_regulator *chip = config->driver_data;
struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[desc->id];
int ret;
rpdata->en_gpiod = devm_fwnode_gpiod_get(chip->dev, of_fwnode_handle(np),
"enable", GPIOD_OUT_LOW,
"enable");
if (IS_ERR(rpdata->en_gpiod)) {
ret = PTR_ERR(rpdata->en_gpiod);
/* Ignore the error other than probe defer */
if (ret == -EPROBE_DEFER)
return ret;
return 0;
}
return 0;
}
#define AW37503_REGULATOR_DESC(_id, _name) \
[AW37503_REGULATOR_ID_##_id] = { \
.name = "aw37503-"#_name, \
.supply_name = "vin", \
.id = AW37503_REGULATOR_ID_##_id, \
.of_match = of_match_ptr(#_name), \
.of_parse_cb = aw37503_of_parse_cb, \
.ops = &aw37503_regulator_ops, \
.n_voltages = AW37503_VOUT_N_VOLTAGE, \
.min_uV = AW37503_VOUT_VMIN, \
.uV_step = AW37503_VOUT_STEP, \
.enable_time = 500, \
.vsel_mask = AW37503_VOUT_MASK, \
.vsel_reg = AW37503_REG_##_id, \
.active_discharge_off = 0, \
.active_discharge_on = AW37503_REG_APPS_DIS_##_id, \
.active_discharge_mask = AW37503_REG_APPS_DIS_##_id, \
.active_discharge_reg = AW37503_REG_APPS, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
static const struct regulator_desc aw_regs_desc[AW37503_MAX_REGULATORS] = {
AW37503_REGULATOR_DESC(VPOS, outp),
AW37503_REGULATOR_DESC(VNEG, outn),
};
static const struct regmap_range aw37503_no_reg_ranges[] = {
regmap_reg_range(AW37503_REG_CONTROL + 1,
AW37503_REG_WPRTEN - 1),
};
static const struct regmap_access_table aw37503_no_reg_table = {
.no_ranges = aw37503_no_reg_ranges,
.n_no_ranges = ARRAY_SIZE(aw37503_no_reg_ranges),
};
static const struct regmap_config aw37503_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = AW37503_REG_WPRTEN,
.rd_table = &aw37503_no_reg_table,
.wr_table = &aw37503_no_reg_table,
};
static int aw37503_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct aw37503_regulator *chip;
struct regulator_dev *rdev;
struct regmap *regmap;
struct regulator_config config = { };
int id;
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
regmap = devm_regmap_init_i2c(client, &aw37503_regmap_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap),
"Failed to init regmap\n");
i2c_set_clientdata(client, chip);
chip->dev = dev;
config.regmap = regmap;
config.dev = dev;
config.driver_data = chip;
for (id = 0; id < AW37503_MAX_REGULATORS; ++id) {
rdev = devm_regulator_register(dev, &aw_regs_desc[id],
&config);
if (IS_ERR(rdev))
return dev_err_probe(dev, PTR_ERR(rdev),
"Failed to register regulator %s\n",
aw_regs_desc[id].name);
}
return 0;
}
static const struct i2c_device_id aw37503_id[] = {
{.name = "aw37503",},
{},
};
MODULE_DEVICE_TABLE(i2c, aw37503_id);
static const struct of_device_id aw37503_of_match[] = {
{.compatible = "awinic,aw37503",},
{ /* Sentinel */ },
};
MODULE_DEVICE_TABLE(of, aw37503_of_match);
static struct i2c_driver aw37503_i2c_driver = {
.driver = {
.name = "aw37503",
.of_match_table = aw37503_of_match,
},
.probe = aw37503_probe,
.id_table = aw37503_id,
};
module_i2c_driver(aw37503_i2c_driver);
MODULE_DESCRIPTION("aw37503 regulator driver");
MODULE_AUTHOR("Alec Li <like@awinic.com>");
MODULE_LICENSE("GPL");

View file

@ -20,7 +20,6 @@
#include <linux/mfd/axp20x.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>

View file

@ -18,7 +18,6 @@
#include <linux/regulator/driver.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/mfd/rohm-generic.h>
#include <linux/mfd/rohm-bd71815.h>
#include <linux/regulator/of_regulator.h>

View file

@ -5,7 +5,6 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/rohm-bd71828.h>

View file

@ -289,7 +289,7 @@ static const struct linear_range bd71837_buck5_volts[] = {
* and 0x1 for last 3 ranges.
*/
static const unsigned int bd71837_buck5_volt_range_sel[] = {
0x0, 0x0, 0x0, 0x80, 0x80, 0x80
0x0, 0x0, 0x0, 0x1, 0x1, 0x1
};
/*
@ -309,7 +309,7 @@ static const struct linear_range bd71847_buck3_volts[] = {
};
static const unsigned int bd71847_buck3_volt_range_sel[] = {
0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80
0x0, 0x0, 0x0, 0x1, 0x2, 0x2, 0x2
};
static const struct linear_range bd71847_buck4_volts[] = {
@ -317,7 +317,7 @@ static const struct linear_range bd71847_buck4_volts[] = {
REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000),
};
static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 };
static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x1 };
/*
* BUCK6
@ -360,7 +360,7 @@ static const struct linear_range bd718xx_ldo1_volts[] = {
REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
};
static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x20 };
static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x1 };
/*
* LDO2
@ -403,7 +403,7 @@ static const struct linear_range bd71847_ldo5_volts[] = {
REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000),
};
static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 };
static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x1 };
/*
* LDO6
@ -817,7 +817,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
.vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
.vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
.vsel_range_mask = BD71847_BUCK3_RANGE_MASK,
.linear_range_selectors = bd71847_buck3_volt_range_sel,
.linear_range_selectors_bitfield = bd71847_buck3_volt_range_sel,
.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
.enable_mask = BD718XX_BUCK_EN,
.enable_time = BD71847_BUCK3_STARTUP_TIME,
@ -845,7 +845,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
.vsel_mask = BD71847_BUCK4_MASK,
.vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
.vsel_range_mask = BD71847_BUCK4_RANGE_MASK,
.linear_range_selectors = bd71847_buck4_volt_range_sel,
.linear_range_selectors_bitfield = bd71847_buck4_volt_range_sel,
.enable_mask = BD718XX_BUCK_EN,
.enable_time = BD71847_BUCK4_STARTUP_TIME,
.owner = THIS_MODULE,
@ -916,7 +916,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
.vsel_mask = BD718XX_LDO1_MASK,
.vsel_range_reg = BD718XX_REG_LDO1_VOLT,
.vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
.linear_range_selectors = bd718xx_ldo1_volt_range_sel,
.linear_range_selectors_bitfield = bd718xx_ldo1_volt_range_sel,
.enable_reg = BD718XX_REG_LDO1_VOLT,
.enable_mask = BD718XX_LDO_EN,
.enable_time = BD71847_LDO1_STARTUP_TIME,
@ -1010,7 +1010,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
.vsel_mask = BD71847_LDO5_MASK,
.vsel_range_reg = BD718XX_REG_LDO5_VOLT,
.vsel_range_mask = BD71847_LDO5_RANGE_MASK,
.linear_range_selectors = bd71847_ldo5_volt_range_sel,
.linear_range_selectors_bitfield = bd71847_ldo5_volt_range_sel,
.enable_reg = BD718XX_REG_LDO5_VOLT,
.enable_mask = BD718XX_LDO_EN,
.enable_time = BD71847_LDO5_STARTUP_TIME,
@ -1232,7 +1232,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
.vsel_mask = BD71837_BUCK5_MASK,
.vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
.vsel_range_mask = BD71837_BUCK5_RANGE_MASK,
.linear_range_selectors = bd71837_buck5_volt_range_sel,
.linear_range_selectors_bitfield = bd71837_buck5_volt_range_sel,
.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
.enable_mask = BD718XX_BUCK_EN,
.enable_time = BD71837_BUCK5_STARTUP_TIME,
@ -1328,7 +1328,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
.vsel_mask = BD718XX_LDO1_MASK,
.vsel_range_reg = BD718XX_REG_LDO1_VOLT,
.vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
.linear_range_selectors = bd718xx_ldo1_volt_range_sel,
.linear_range_selectors_bitfield = bd718xx_ldo1_volt_range_sel,
.enable_reg = BD718XX_REG_LDO1_VOLT,
.enable_mask = BD718XX_LDO_EN,
.enable_time = BD71837_LDO1_STARTUP_TIME,

View file

@ -12,7 +12,7 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>

View file

@ -924,7 +924,7 @@ static int da9062_regulator_probe(struct platform_device *pdev)
struct da9062_regulator *regl;
struct regulator_config config = { };
const struct da9062_regulator_info *rinfo;
int irq, n, ret;
int n, ret;
int max_regulators;
switch (chip->chip_type) {
@ -1012,12 +1012,11 @@ static int da9062_regulator_probe(struct platform_device *pdev)
}
/* LDOs overcurrent event support */
irq = platform_get_irq_byname(pdev, "LDO_LIM");
if (irq < 0)
return irq;
regulators->irq_ldo_lim = irq;
regulators->irq_ldo_lim = platform_get_irq_byname_optional(pdev, "LDO_LIM");
if (regulators->irq_ldo_lim < 0)
return 0;
ret = devm_request_threaded_irq(&pdev->dev, irq,
ret = devm_request_threaded_irq(&pdev->dev, regulators->irq_ldo_lim,
NULL, da9062_ldo_lim_event,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"LDO_LIM", regulators);

View file

@ -440,7 +440,7 @@ static const struct regulator_desc da9121_reg = {
.of_match = "buck1",
.of_parse_cb = da9121_of_parse_cb,
.owner = THIS_MODULE,
.regulators_node = of_match_ptr("regulators"),
.regulators_node = "regulators",
.of_map_mode = da9121_map_mode,
.ops = &da9121_buck_ops,
.type = REGULATOR_VOLTAGE,
@ -465,7 +465,7 @@ static const struct regulator_desc da9220_reg[2] = {
.of_match = "buck1",
.of_parse_cb = da9121_of_parse_cb,
.owner = THIS_MODULE,
.regulators_node = of_match_ptr("regulators"),
.regulators_node = "regulators",
.of_map_mode = da9121_map_mode,
.ops = &da9121_buck_ops,
.type = REGULATOR_VOLTAGE,
@ -484,7 +484,7 @@ static const struct regulator_desc da9220_reg[2] = {
.of_match = "buck2",
.of_parse_cb = da9121_of_parse_cb,
.owner = THIS_MODULE,
.regulators_node = of_match_ptr("regulators"),
.regulators_node = "regulators",
.of_map_mode = da9121_map_mode,
.ops = &da9121_buck_ops,
.type = REGULATOR_VOLTAGE,
@ -506,7 +506,7 @@ static const struct regulator_desc da9122_reg[2] = {
.of_match = "buck1",
.of_parse_cb = da9121_of_parse_cb,
.owner = THIS_MODULE,
.regulators_node = of_match_ptr("regulators"),
.regulators_node = "regulators",
.of_map_mode = da9121_map_mode,
.ops = &da9121_buck_ops,
.type = REGULATOR_VOLTAGE,
@ -525,7 +525,7 @@ static const struct regulator_desc da9122_reg[2] = {
.of_match = "buck2",
.of_parse_cb = da9121_of_parse_cb,
.owner = THIS_MODULE,
.regulators_node = of_match_ptr("regulators"),
.regulators_node = "regulators",
.of_map_mode = da9121_map_mode,
.ops = &da9121_buck_ops,
.type = REGULATOR_VOLTAGE,
@ -546,7 +546,7 @@ static const struct regulator_desc da9217_reg = {
.of_match = "buck1",
.of_parse_cb = da9121_of_parse_cb,
.owner = THIS_MODULE,
.regulators_node = of_match_ptr("regulators"),
.regulators_node = "regulators",
.of_map_mode = da9121_map_mode,
.ops = &da9121_buck_ops,
.type = REGULATOR_VOLTAGE,
@ -573,7 +573,7 @@ static const struct regulator_desc da9141_reg = {
.of_match = "buck1",
.of_parse_cb = da9121_of_parse_cb,
.owner = THIS_MODULE,
.regulators_node = of_match_ptr("regulators"),
.regulators_node = "regulators",
.of_map_mode = da9121_map_mode,
.ops = &da9121_buck_ops,
.type = REGULATOR_VOLTAGE,
@ -593,7 +593,7 @@ static const struct regulator_desc da9142_reg = {
.of_match = "buck1",
.of_parse_cb = da9121_of_parse_cb,
.owner = THIS_MODULE,
.regulators_node = of_match_ptr("regulators"),
.regulators_node = "regulators",
.of_map_mode = da9121_map_mode,
.ops = &da9121_buck_ops,
.type = REGULATOR_VOLTAGE,
@ -1195,7 +1195,7 @@ static struct i2c_driver da9121_regulator_driver = {
.driver = {
.name = "da9121",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.of_match_table = of_match_ptr(da9121_dt_ids),
.of_match_table = da9121_dt_ids,
},
.probe = da9121_i2c_probe,
.remove = da9121_i2c_remove,

View file

@ -12,7 +12,7 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/param.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

View file

@ -25,7 +25,6 @@
#include <linux/gpio/consumer.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
#include <linux/clk.h>

View file

@ -5,13 +5,14 @@
// Copyright 2007, 2008 Wolfson Microelectronics PLC.
// Copyright 2008 SlimLogic Ltd.
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/module.h>
#include "internal.h"
@ -104,13 +105,14 @@ static int regulator_range_selector_to_index(struct regulator_dev *rdev,
{
int i;
if (!rdev->desc->linear_range_selectors)
if (!rdev->desc->linear_range_selectors_bitfield)
return -EINVAL;
rval &= rdev->desc->vsel_range_mask;
rval >>= ffs(rdev->desc->vsel_range_mask) - 1;
for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
if (rdev->desc->linear_range_selectors[i] == rval)
if (rdev->desc->linear_range_selectors_bitfield[i] == rval)
return i;
}
return -EINVAL;
@ -194,7 +196,8 @@ int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
sel <<= ffs(rdev->desc->vsel_mask) - 1;
sel += rdev->desc->linear_ranges[i].min_sel;
range = rdev->desc->linear_range_selectors[i];
range = rdev->desc->linear_range_selectors_bitfield[i];
range <<= ffs(rdev->desc->vsel_mask) - 1;
if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) {
ret = regmap_update_bits(rdev->regmap,

View file

@ -131,8 +131,8 @@ static const struct regulator_ops hi6421_buck345_ops;
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.of_match = #_match, \
.regulators_node = "regulators", \
.ops = &hi6421_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \
@ -170,8 +170,8 @@ static const struct regulator_ops hi6421_buck345_ops;
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.of_match = #_match, \
.regulators_node = "regulators", \
.ops = &hi6421_ldo_linear_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \
@ -210,8 +210,8 @@ static const struct regulator_ops hi6421_buck345_ops;
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.of_match = #_match, \
.regulators_node = "regulators", \
.ops = &hi6421_ldo_linear_range_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \
@ -247,8 +247,8 @@ static const struct regulator_ops hi6421_buck345_ops;
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.of_match = #_match, \
.regulators_node = "regulators", \
.ops = &hi6421_buck012_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \
@ -284,8 +284,8 @@ static const struct regulator_ops hi6421_buck345_ops;
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.of_match = #_match, \
.regulators_node = "regulators", \
.ops = &hi6421_buck345_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \

View file

@ -864,7 +864,7 @@ static struct lp872x_platform_data
for (i = 0; i < num_matches; i++) {
pdata->regulator_data[i].id =
(enum lp872x_regulator_id)match[i].driver_data;
(uintptr_t)match[i].driver_data;
pdata->regulator_data[i].init_data = match[i].init_data;
}
out:

View file

@ -13,7 +13,6 @@
#include <linux/err.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/regmap.h>
#include <linux/uaccess.h>
#include <linux/regulator/driver.h>

View file

@ -29,8 +29,8 @@ enum LP87565_regulator_id {
.name = _name, \
.supply_name = _of "-in", \
.id = _id, \
.of_match = of_match_ptr(_of), \
.regulators_node = of_match_ptr("regulators"),\
.of_match = _of, \
.regulators_node = "regulators", \
.ops = &_ops, \
.n_voltages = _n, \
.type = REGULATOR_VOLTAGE, \

View file

@ -10,7 +10,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
@ -392,8 +391,7 @@ static int ltc3589_probe(struct i2c_client *client)
i2c_set_clientdata(client, ltc3589);
if (client->dev.of_node)
ltc3589->variant = (enum ltc3589_variant)
of_device_get_match_data(&client->dev);
ltc3589->variant = (uintptr_t)of_device_get_match_data(&client->dev);
else
ltc3589->variant = id->driver_data;
ltc3589->dev = dev;

View file

@ -6,7 +6,6 @@
// Copyright (C) 2018 Avnet, Inc.
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>

View file

@ -20,9 +20,9 @@
#include <linux/regulator/of_regulator.h>
#include <linux/platform_device.h>
#include <linux/mfd/max597x.h>
#include <linux/mfd/max5970.h>
struct max597x_regulator {
struct max5970_regulator {
int num_switches, mon_rng, irng, shunt_micro_ohms, lim_uA;
struct regmap *regmap;
};
@ -58,7 +58,7 @@ static int max597x_set_vp(struct regulator_dev *rdev, int lim_uV, int severity,
bool enable, bool overvoltage)
{
int off_h, off_l, reg, ret;
struct max597x_regulator *data = rdev_get_drvdata(rdev);
struct max5970_regulator *data = rdev_get_drvdata(rdev);
int channel = rdev_get_id(rdev);
if (overvoltage) {
@ -140,7 +140,7 @@ static int max597x_set_ocp(struct regulator_dev *rdev, int lim_uA,
int val, reg;
unsigned int vthst, vthfst;
struct max597x_regulator *data = rdev_get_drvdata(rdev);
struct max5970_regulator *data = rdev_get_drvdata(rdev);
int rdev_id = rdev_get_id(rdev);
/*
* MAX5970 doesn't has enable control for ocp.
@ -222,7 +222,7 @@ static int max597x_dt_parse(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *cfg)
{
struct max597x_regulator *data = cfg->driver_data;
struct max5970_regulator *data = cfg->driver_data;
int ret = 0;
ret =
@ -274,7 +274,7 @@ static int max597x_irq_handler(int irq, struct regulator_irq_data *rid,
unsigned long *dev_mask)
{
struct regulator_err_state *stat;
struct max597x_regulator *d = (struct max597x_regulator *)rid->data;
struct max5970_regulator *d = (struct max5970_regulator *)rid->data;
int val, ret, i;
ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT0, &val);
@ -394,7 +394,7 @@ static int max597x_adc_range(struct regmap *regmap, const int ch,
static int max597x_setup_irq(struct device *dev,
int irq,
struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES],
int num_switches, struct max597x_regulator *data)
int num_switches, struct max5970_regulator *data)
{
struct regulator_irq_desc max597x_notif = {
.name = "max597x-irq",
@ -425,9 +425,9 @@ static int max597x_setup_irq(struct device *dev,
static int max597x_regulator_probe(struct platform_device *pdev)
{
struct max597x_data *max597x;
struct max5970_data *max597x;
struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
struct max597x_regulator *data;
struct max5970_regulator *data;
struct i2c_client *i2c = to_i2c_client(pdev->dev.parent);
struct regulator_config config = { };
struct regulator_dev *rdev;
@ -438,16 +438,16 @@ static int max597x_regulator_probe(struct platform_device *pdev)
if (!regmap)
return -EPROBE_DEFER;
max597x = devm_kzalloc(&i2c->dev, sizeof(struct max597x_data), GFP_KERNEL);
max597x = devm_kzalloc(&i2c->dev, sizeof(struct max5970_data), GFP_KERNEL);
if (!max597x)
return -ENOMEM;
i2c_set_clientdata(i2c, max597x);
if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5978"))
max597x->num_switches = MAX597x_TYPE_MAX5978;
max597x->num_switches = MAX5978_NUM_SWITCHES;
else if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5970"))
max597x->num_switches = MAX597x_TYPE_MAX5970;
max597x->num_switches = MAX5970_NUM_SWITCHES;
else
return -ENODEV;
@ -456,7 +456,7 @@ static int max597x_regulator_probe(struct platform_device *pdev)
for (i = 0; i < num_switches; i++) {
data =
devm_kzalloc(&i2c->dev, sizeof(struct max597x_regulator),
devm_kzalloc(&i2c->dev, sizeof(struct max5970_regulator),
GFP_KERNEL);
if (!data)
return -ENOMEM;
@ -500,7 +500,7 @@ static int max597x_regulator_probe(struct platform_device *pdev)
static struct platform_driver max597x_regulator_driver = {
.driver = {
.name = "max597x-regulator",
.name = "max5970-regulator",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
.probe = max597x_regulator_probe,

View file

@ -44,7 +44,7 @@ static const struct linear_range max77541_buck_ranges[] = {
};
static const unsigned int max77541_buck_volt_range_sel[] = {
0x00, 0x00, 0x40, 0x40, 0x80, 0x80,
0x0, 0x0, 0x1, 0x1, 0x2, 0x2,
};
enum max77541_regulators {
@ -67,7 +67,7 @@ enum max77541_regulators {
.vsel_mask = MAX77541_BITS_MX_VOUT, \
.vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1, \
.vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG, \
.linear_range_selectors = max77541_buck_volt_range_sel, \
.linear_range_selectors_bitfield = max77541_buck_volt_range_sel, \
.owner = THIS_MODULE, \
}
@ -86,7 +86,7 @@ enum max77541_regulators {
.vsel_mask = MAX77541_BITS_MX_VOUT, \
.vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1, \
.vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG, \
.linear_range_selectors = max77541_buck_volt_range_sel, \
.linear_range_selectors_bitfield = max77541_buck_volt_range_sel, \
.owner = THIS_MODULE, \
}

View file

@ -239,7 +239,7 @@ static struct max77650_regulator_desc max77651_SBB1_desc = {
.supply_name = "in-sbb1",
.id = MAX77650_REGULATOR_ID_SBB1,
.ops = &max77651_SBB1_regulator_ops,
.linear_range_selectors = max77651_sbb1_volt_range_sel,
.linear_range_selectors_bitfield = max77651_sbb1_volt_range_sel,
.linear_ranges = max77651_sbb1_volt_ranges,
.n_linear_ranges = ARRAY_SIZE(max77651_sbb1_volt_ranges),
.n_voltages = 58,

View file

@ -9,7 +9,6 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -0,0 +1,461 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2023 Analog Devices, Inc.
* ADI Regulator driver for the MAX77857
* MAX77859 and MAX77831.
*/
#include <linux/bitfield.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/util_macros.h>
#define MAX77857_REG_INT_SRC 0x10
#define MAX77857_REG_INT_MASK 0x11
#define MAX77857_REG_CONT1 0x12
#define MAX77857_REG_CONT2 0x13
#define MAX77857_REG_CONT3 0x14
#define MAX77857_INT_SRC_OCP BIT(0)
#define MAX77857_INT_SRC_THS BIT(1)
#define MAX77857_INT_SRC_HARDSHORT BIT(2)
#define MAX77857_INT_SRC_OVP BIT(3)
#define MAX77857_INT_SRC_POK BIT(4)
#define MAX77857_ILIM_MASK GENMASK(2, 0)
#define MAX77857_CONT1_FREQ GENMASK(4, 3)
#define MAX77857_CONT3_FPWM BIT(5)
#define MAX77859_REG_INT_SRC 0x11
#define MAX77859_REG_CONT1 0x13
#define MAX77859_REG_CONT2 0x14
#define MAX77859_REG_CONT3 0x15
#define MAX77859_REG_CONT5 0x17
#define MAX77859_CONT2_FPWM BIT(2)
#define MAX77859_CONT2_INTB BIT(3)
#define MAX77859_CONT3_DVS_START BIT(2)
#define MAX77859_VOLTAGE_SEL_MASK GENMASK(9, 0)
#define MAX77859_CURRENT_MIN 1000000
#define MAX77859_CURRENT_MAX 5000000
#define MAX77859_CURRENT_STEP 50000
enum max77857_id {
ID_MAX77831 = 1,
ID_MAX77857,
ID_MAX77859,
ID_MAX77859A,
};
static bool max77857_volatile_reg(struct device *dev, unsigned int reg)
{
enum max77857_id id = (uintptr_t)dev_get_drvdata(dev);
switch (id) {
case ID_MAX77831:
case ID_MAX77857:
return reg == MAX77857_REG_INT_SRC;
case ID_MAX77859:
case ID_MAX77859A:
return reg == MAX77859_REG_INT_SRC;
default:
return true;
}
}
static struct regmap_config max77857_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_MAPLE,
.volatile_reg = max77857_volatile_reg,
};
static int max77857_get_status(struct regulator_dev *rdev)
{
unsigned int val;
int ret;
ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val);
if (ret)
return ret;
if (FIELD_GET(MAX77857_INT_SRC_POK, val))
return REGULATOR_STATUS_ON;
return REGULATOR_STATUS_ERROR;
}
static unsigned int max77857_get_mode(struct regulator_dev *rdev)
{
enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev);
unsigned int regval;
int ret;
switch (id) {
case ID_MAX77831:
case ID_MAX77857:
ret = regmap_read(rdev->regmap, MAX77857_REG_CONT3, &regval);
if (ret)
return ret;
if (FIELD_GET(MAX77857_CONT3_FPWM, regval))
return REGULATOR_MODE_FAST;
break;
case ID_MAX77859:
case ID_MAX77859A:
ret = regmap_read(rdev->regmap, MAX77859_REG_CONT2, &regval);
if (ret)
return ret;
if (FIELD_GET(MAX77859_CONT2_FPWM, regval))
return REGULATOR_MODE_FAST;
break;
default:
return -EINVAL;
}
return REGULATOR_MODE_NORMAL;
}
static int max77857_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev);
unsigned int reg, val;
switch (id) {
case ID_MAX77831:
case ID_MAX77857:
reg = MAX77857_REG_CONT3;
val = MAX77857_CONT3_FPWM;
break;
case ID_MAX77859:
case ID_MAX77859A:
reg = MAX77859_REG_CONT2;
val = MAX77859_CONT2_FPWM;
break;
default:
return -EINVAL;
}
switch (mode) {
case REGULATOR_MODE_FAST:
return regmap_set_bits(rdev->regmap, reg, val);
case REGULATOR_MODE_NORMAL:
return regmap_clear_bits(rdev->regmap, reg, val);
default:
return -EINVAL;
}
}
static int max77857_get_error_flags(struct regulator_dev *rdev,
unsigned int *flags)
{
unsigned int val;
int ret;
ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val);
if (ret)
return ret;
*flags = 0;
if (FIELD_GET(MAX77857_INT_SRC_OVP, val))
*flags |= REGULATOR_ERROR_OVER_VOLTAGE_WARN;
if (FIELD_GET(MAX77857_INT_SRC_OCP, val) ||
FIELD_GET(MAX77857_INT_SRC_HARDSHORT, val))
*flags |= REGULATOR_ERROR_OVER_CURRENT;
if (FIELD_GET(MAX77857_INT_SRC_THS, val))
*flags |= REGULATOR_ERROR_OVER_TEMP;
if (!FIELD_GET(MAX77857_INT_SRC_POK, val))
*flags |= REGULATOR_ERROR_FAIL;
return 0;
}
static struct linear_range max77859_lin_ranges[] = {
REGULATOR_LINEAR_RANGE(3200000, 0x0A0, 0x320, 20000)
};
static const unsigned int max77859_ramp_table[4] = {
1000, 500, 250, 125
};
static int max77859_set_voltage_sel(struct regulator_dev *rdev,
unsigned int sel)
{
__be16 reg;
int ret;
reg = cpu_to_be16(sel);
ret = regmap_bulk_write(rdev->regmap, MAX77859_REG_CONT3, &reg, 2);
if (ret)
return ret;
/* actually apply new voltage */
return regmap_set_bits(rdev->regmap, MAX77859_REG_CONT3,
MAX77859_CONT3_DVS_START);
}
static int max77859_get_voltage_sel(struct regulator_dev *rdev)
{
__be16 reg;
int ret;
ret = regmap_bulk_read(rdev->regmap, MAX77859_REG_CONT3, &reg, 2);
if (ret)
return ret;
return FIELD_GET(MAX77859_VOLTAGE_SEL_MASK, __be16_to_cpu(reg));
}
static int max77859_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)
{
u32 selector;
if (max_uA < MAX77859_CURRENT_MIN)
return -EINVAL;
selector = 0x12 + (max_uA - MAX77859_CURRENT_MIN) / MAX77859_CURRENT_STEP;
selector = clamp_val(selector, 0x00, 0x7F);
return regmap_write(rdev->regmap, MAX77859_REG_CONT5, selector);
}
static int max77859_get_current_limit(struct regulator_dev *rdev)
{
u32 selector;
int ret;
ret = regmap_read(rdev->regmap, MAX77859_REG_CONT5, &selector);
if (ret)
return ret;
if (selector <= 0x12)
return MAX77859_CURRENT_MIN;
if (selector >= 0x64)
return MAX77859_CURRENT_MAX;
return MAX77859_CURRENT_MIN + (selector - 0x12) * MAX77859_CURRENT_STEP;
}
static const struct regulator_ops max77859_regulator_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = max77859_set_voltage_sel,
.get_voltage_sel = max77859_get_voltage_sel,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.get_status = max77857_get_status,
.set_mode = max77857_set_mode,
.get_mode = max77857_get_mode,
.get_error_flags = max77857_get_error_flags,
};
static const struct regulator_ops max77859a_regulator_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = max77859_set_voltage_sel,
.get_voltage_sel = max77859_get_voltage_sel,
.set_current_limit = max77859_set_current_limit,
.get_current_limit = max77859_get_current_limit,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.get_status = max77857_get_status,
.set_mode = max77857_set_mode,
.get_mode = max77857_get_mode,
.get_error_flags = max77857_get_error_flags,
};
static const struct regulator_ops max77857_regulator_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.get_status = max77857_get_status,
.set_mode = max77857_set_mode,
.get_mode = max77857_get_mode,
.get_error_flags = max77857_get_error_flags,
};
static struct linear_range max77857_lin_ranges[] = {
REGULATOR_LINEAR_RANGE(4485000, 0x3D, 0xCC, 73500)
};
static const unsigned int max77857_switch_freq[] = {
1200000, 1500000, 1800000, 2100000
};
#define RAMAP_DELAY_INIT_VAL 1333
static const unsigned int max77857_ramp_table[2][4] = {
{ RAMAP_DELAY_INIT_VAL, 667, 333, 227 }, /* when switch freq is 1.8MHz or 2.1MHz */
{ 1166, 667, 333, 167 }, /* when switch freq is 1.2MHz or 1.5MHz */
};
static struct regulator_desc max77857_regulator_desc = {
.ops = &max77857_regulator_ops,
.name = "max77857",
.linear_ranges = max77857_lin_ranges,
.n_linear_ranges = ARRAY_SIZE(max77857_lin_ranges),
.vsel_mask = 0xFF,
.vsel_reg = MAX77857_REG_CONT2,
.ramp_delay_table = max77857_ramp_table[0],
.n_ramp_values = ARRAY_SIZE(max77857_ramp_table[0]),
.ramp_reg = MAX77857_REG_CONT3,
.ramp_mask = GENMASK(1, 0),
.ramp_delay = RAMAP_DELAY_INIT_VAL,
.owner = THIS_MODULE,
};
static void max77857_calc_range(struct device *dev, enum max77857_id id)
{
struct linear_range *range;
unsigned long vref_step;
u32 rtop = 0;
u32 rbot = 0;
device_property_read_u32(dev, "adi,rtop-ohms", &rtop);
device_property_read_u32(dev, "adi,rbot-ohms", &rbot);
if (!rbot || !rtop)
return;
switch (id) {
case ID_MAX77831:
case ID_MAX77857:
range = max77857_lin_ranges;
vref_step = 4900UL;
break;
case ID_MAX77859:
case ID_MAX77859A:
range = max77859_lin_ranges;
vref_step = 1250UL;
break;
}
range->step = DIV_ROUND_CLOSEST(vref_step * (rbot + rtop), rbot);
range->min = range->step * range->min_sel;
}
static int max77857_probe(struct i2c_client *client)
{
const struct i2c_device_id *i2c_id;
struct device *dev = &client->dev;
struct regulator_config cfg = { };
struct regulator_dev *rdev;
struct regmap *regmap;
enum max77857_id id;
u32 switch_freq = 0;
int ret;
i2c_id = i2c_client_get_device_id(client);
if (!i2c_id)
return -EINVAL;
id = i2c_id->driver_data;
dev_set_drvdata(dev, (void *)id);
if (id == ID_MAX77859 || id == ID_MAX77859A) {
max77857_regulator_desc.ops = &max77859_regulator_ops;
max77857_regulator_desc.linear_ranges = max77859_lin_ranges;
max77857_regulator_desc.ramp_delay_table = max77859_ramp_table;
max77857_regulator_desc.ramp_delay = max77859_ramp_table[0];
}
if (id == ID_MAX77859A)
max77857_regulator_desc.ops = &max77859a_regulator_ops;
max77857_calc_range(dev, id);
regmap = devm_regmap_init_i2c(client, &max77857_regmap_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap),
"cannot initialize regmap\n");
device_property_read_u32(dev, "adi,switch-frequency-hz", &switch_freq);
if (switch_freq) {
switch_freq = find_closest(switch_freq, max77857_switch_freq,
ARRAY_SIZE(max77857_switch_freq));
if (id == ID_MAX77831 && switch_freq == 3)
switch_freq = 2;
switch (id) {
case ID_MAX77831:
case ID_MAX77857:
ret = regmap_update_bits(regmap, MAX77857_REG_CONT1,
MAX77857_CONT1_FREQ, switch_freq);
if (switch_freq >= 2)
break;
max77857_regulator_desc.ramp_delay_table = max77857_ramp_table[1];
max77857_regulator_desc.ramp_delay = max77857_ramp_table[1][0];
break;
case ID_MAX77859:
case ID_MAX77859A:
ret = regmap_update_bits(regmap, MAX77859_REG_CONT1,
MAX77857_CONT1_FREQ, switch_freq);
break;
}
if (ret)
return ret;
}
cfg.dev = dev;
cfg.driver_data = (void *)id;
cfg.regmap = regmap;
cfg.init_data = of_get_regulator_init_data(dev, dev->of_node,
&max77857_regulator_desc);
if (!cfg.init_data)
return -ENOMEM;
rdev = devm_regulator_register(dev, &max77857_regulator_desc, &cfg);
if (IS_ERR(rdev))
return dev_err_probe(dev, PTR_ERR(rdev),
"cannot register regulator\n");
return 0;
}
const struct i2c_device_id max77857_id[] = {
{ "max77831", ID_MAX77831 },
{ "max77857", ID_MAX77857 },
{ "max77859", ID_MAX77859 },
{ "max77859a", ID_MAX77859A },
{ }
};
MODULE_DEVICE_TABLE(i2c, max77857_id);
static const struct of_device_id max77857_of_id[] = {
{ .compatible = "adi,max77831", .data = (void *)ID_MAX77831 },
{ .compatible = "adi,max77857", .data = (void *)ID_MAX77857 },
{ .compatible = "adi,max77859", .data = (void *)ID_MAX77859 },
{ .compatible = "adi,max77859a", .data = (void *)ID_MAX77859A },
{ }
};
MODULE_DEVICE_TABLE(of, max77857_of_id);
static struct i2c_driver max77857_driver = {
.driver = {
.name = "max77857",
.of_match_table = max77857_of_id,
},
.id_table = max77857_id,
.probe = max77857_probe,
};
module_i2c_driver(max77857_driver);
MODULE_DESCRIPTION("Analog Devices MAX77857 Buck-Boost Converter Driver");
MODULE_AUTHOR("Ibrahim Tilki <Ibrahim.Tilki@analog.com>");
MODULE_AUTHOR("Okan Sahin <Okan.Sahin@analog.com>");
MODULE_LICENSE("GPL");

View file

@ -125,7 +125,7 @@ static const struct regmap_config max8893_regmap = {
.val_bits = 8,
};
static int max8893_probe_new(struct i2c_client *i2c)
static int max8893_probe(struct i2c_client *i2c)
{
int id, ret;
struct regulator_config config = {.dev = &i2c->dev};
@ -168,7 +168,7 @@ static const struct i2c_device_id max8893_ids[] = {
MODULE_DEVICE_TABLE(i2c, max8893_ids);
static struct i2c_driver max8893_driver = {
.probe = max8893_probe_new,
.probe = max8893_probe,
.driver = {
.name = "max8893",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,

View file

@ -8,7 +8,6 @@
//
// Inspired from tps65086-regulator.c
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
@ -111,7 +110,7 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode)
#define MCP16502_REGULATOR(_name, _id, _ranges, _ops, _ramp_table) \
[_id] = { \
.name = _name, \
.regulators_node = of_match_ptr("regulators"), \
.regulators_node = "regulators", \
.id = _id, \
.ops = &(_ops), \
.type = REGULATOR_VOLTAGE, \
@ -120,7 +119,7 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode)
.linear_ranges = _ranges, \
.linear_min_sel = VDD_LOW_SEL, \
.n_linear_ranges = ARRAY_SIZE(_ranges), \
.of_match = of_match_ptr(_name), \
.of_match = _name, \
.of_map_mode = mcp16502_of_map_mode, \
.vsel_reg = (((_id) + 1) << 4), \
.vsel_mask = MCP16502_VSEL, \
@ -588,7 +587,7 @@ static struct i2c_driver mcp16502_drv = {
.driver = {
.name = "mcp16502-regulator",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.of_match_table = of_match_ptr(mcp16502_ids),
.of_match_table = mcp16502_ids,
#ifdef CONFIG_PM
.pm = &mcp16502_pm_ops,
#endif

View file

@ -10,7 +10,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>

View file

@ -9,7 +9,7 @@
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
@ -319,7 +318,7 @@ static struct i2c_driver mpq7920_regulator_driver = {
.driver = {
.name = "mpq7920",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.of_match_table = of_match_ptr(mpq7920_of_match),
.of_match_table = mpq7920_of_match,
},
.probe = mpq7920_i2c_probe,
.id_table = mpq7920_id,

View file

@ -4,7 +4,6 @@
// Author: Henry Chen <henryc.chen@mediatek.com>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>

View file

@ -3,7 +3,7 @@
// Copyright (c) 2021 MediaTek Inc.
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>

View file

@ -7,7 +7,7 @@
#include <linux/mfd/mt6359p/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>

View file

@ -6,8 +6,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/soc/mediatek/mtk_dvfsrc.h>

View file

@ -25,7 +25,6 @@
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
struct pbias_reg_info {
u32 enable;

View file

@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>

View file

@ -699,8 +699,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client)
return -ENOMEM;
if (client->dev.of_node) {
match = of_match_device(of_match_ptr(pfuze_dt_ids),
&client->dev);
match = of_match_device(pfuze_dt_ids, &client->dev);
if (!match) {
dev_err(&client->dev, "Error: No device match found\n");
return -ENODEV;

View file

@ -10,11 +10,11 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pwm.h>
#include <linux/gpio/consumer.h>

View file

@ -0,0 +1,154 @@
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2017, 2019-2020, The Linux Foundation. All rights reserved.
// Copyright (c) 2023, Linaro Limited
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#define REFGEN_REG_BIAS_EN 0x08
#define REFGEN_BIAS_EN_MASK GENMASK(2, 0)
#define REFGEN_BIAS_EN_ENABLE 0x7
#define REFGEN_BIAS_EN_DISABLE 0x6
#define REFGEN_REG_BG_CTRL 0x14
#define REFGEN_BG_CTRL_MASK GENMASK(2, 1)
#define REFGEN_BG_CTRL_ENABLE 0x3
#define REFGEN_BG_CTRL_DISABLE 0x2
#define REFGEN_REG_PWRDWN_CTRL5 0x80
#define REFGEN_PWRDWN_CTRL5_MASK BIT(0)
#define REFGEN_PWRDWN_CTRL5_ENABLE 0x1
static int qcom_sdm845_refgen_enable(struct regulator_dev *rdev)
{
regmap_update_bits(rdev->regmap, REFGEN_REG_BG_CTRL, REFGEN_BG_CTRL_MASK,
FIELD_PREP(REFGEN_BG_CTRL_MASK, REFGEN_BG_CTRL_ENABLE));
regmap_write(rdev->regmap, REFGEN_REG_BIAS_EN,
FIELD_PREP(REFGEN_BIAS_EN_MASK, REFGEN_BIAS_EN_ENABLE));
return 0;
}
static int qcom_sdm845_refgen_disable(struct regulator_dev *rdev)
{
regmap_write(rdev->regmap, REFGEN_REG_BIAS_EN,
FIELD_PREP(REFGEN_BIAS_EN_MASK, REFGEN_BIAS_EN_DISABLE));
regmap_update_bits(rdev->regmap, REFGEN_REG_BG_CTRL, REFGEN_BG_CTRL_MASK,
FIELD_PREP(REFGEN_BG_CTRL_MASK, REFGEN_BG_CTRL_DISABLE));
return 0;
}
static int qcom_sdm845_refgen_is_enabled(struct regulator_dev *rdev)
{
u32 val;
regmap_read(rdev->regmap, REFGEN_REG_BG_CTRL, &val);
if (FIELD_GET(REFGEN_BG_CTRL_MASK, val) != REFGEN_BG_CTRL_ENABLE)
return 0;
regmap_read(rdev->regmap, REFGEN_REG_BIAS_EN, &val);
if (FIELD_GET(REFGEN_BIAS_EN_MASK, val) != REFGEN_BIAS_EN_ENABLE)
return 0;
return 1;
}
static struct regulator_desc sdm845_refgen_desc = {
.enable_time = 5,
.name = "refgen",
.owner = THIS_MODULE,
.type = REGULATOR_VOLTAGE,
.ops = &(const struct regulator_ops) {
.enable = qcom_sdm845_refgen_enable,
.disable = qcom_sdm845_refgen_disable,
.is_enabled = qcom_sdm845_refgen_is_enabled,
},
};
static struct regulator_desc sm8250_refgen_desc = {
.enable_reg = REFGEN_REG_PWRDWN_CTRL5,
.enable_mask = REFGEN_PWRDWN_CTRL5_MASK,
.enable_val = REFGEN_PWRDWN_CTRL5_ENABLE,
.disable_val = 0,
.enable_time = 5,
.name = "refgen",
.owner = THIS_MODULE,
.type = REGULATOR_VOLTAGE,
.ops = &(const struct regulator_ops) {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
},
};
static const struct regmap_config qcom_refgen_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.fast_io = true,
};
static int qcom_refgen_probe(struct platform_device *pdev)
{
struct regulator_init_data *init_data;
struct regulator_config config = {};
const struct regulator_desc *rdesc;
struct device *dev = &pdev->dev;
struct regulator_dev *rdev;
struct regmap *regmap;
void __iomem *base;
rdesc = of_device_get_match_data(dev);
if (!rdesc)
return -ENODATA;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
regmap = devm_regmap_init_mmio(dev, base, &qcom_refgen_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
init_data = of_get_regulator_init_data(dev, dev->of_node, rdesc);
if (!init_data)
return -ENOMEM;
config.dev = dev;
config.init_data = init_data;
config.of_node = dev->of_node;
config.regmap = regmap;
rdev = devm_regulator_register(dev, rdesc, &config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
return 0;
}
static const struct of_device_id qcom_refgen_match_table[] = {
{ .compatible = "qcom,sdm845-refgen-regulator", .data = &sdm845_refgen_desc },
{ .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_refgen_desc },
{ }
};
static struct platform_driver qcom_refgen_driver = {
.probe = qcom_refgen_probe,
.driver = {
.name = "qcom-refgen-regulator",
.of_match_table = qcom_refgen_match_table,
},
};
module_platform_driver(qcom_refgen_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Qualcomm REFGEN regulator driver");

View file

@ -7,7 +7,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>
@ -1273,6 +1272,40 @@ static const struct rpmh_vreg_init_data pmx65_vreg_data[] = {
{}
};
static const struct rpmh_vreg_init_data pmx75_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525_lv, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525_lv, "vdd-s2"),
RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525_lv, "vdd-s3"),
RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525_mv, "vdd-s4"),
RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525_lv, "vdd-s5"),
RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525_lv, "vdd-s6"),
RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps525_lv, "vdd-s7"),
RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps525_lv, "vdd-s8"),
RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps525_lv, "vdd-s9"),
RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps525_lv, "vdd-s10"),
RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-l1"),
RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2-18"),
RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l3"),
RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo515, "vdd-l4-l16"),
RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo_lv, "vdd-l5-l6"),
RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo_lv, "vdd-l5-l6"),
RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo515, "vdd-l7"),
RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo515, "vdd-l8-l9"),
RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo515, "vdd-l8-l9"),
RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l10"),
RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l11-l13"),
RPMH_VREG("ldo12", "ldo%s12", &pmic5_nldo515, "vdd-l12"),
RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l11-l13"),
RPMH_VREG("ldo14", "ldo%s14", &pmic5_nldo515, "vdd-l14"),
RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo515, "vdd-l15"),
RPMH_VREG("ldo16", "ldo%s16", &pmic5_nldo515, "vdd-l4-l16"),
RPMH_VREG("ldo17", "ldo%s17", &pmic5_nldo515, "vdd-l17"),
/* ldo18 not configured */
RPMH_VREG("ldo19", "ldo%s19", &pmic5_nldo515, "vdd-l19"),
RPMH_VREG("ldo20", "ldo%s20", &pmic5_nldo515, "vdd-l20-l21"),
RPMH_VREG("ldo21", "ldo%s21", &pmic5_nldo515, "vdd-l20-l21"),
};
static const struct rpmh_vreg_init_data pm7325_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps520, "vdd-s2"),
@ -1494,6 +1527,10 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
.compatible = "qcom,pmx65-rpmh-regulators",
.data = pmx65_vreg_data,
},
{
.compatible = "qcom,pmx75-rpmh-regulators",
.data = pmx75_vreg_data,
},
{
.compatible = "qcom,pm7325-rpmh-regulators",
.data = pm7325_vreg_data,

View file

@ -956,11 +956,10 @@ static int rpm_reg_probe(struct platform_device *pdev)
}
for (reg = match->data; reg->name; reg++) {
vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
vreg = devm_kmemdup(&pdev->dev, reg->template, sizeof(*vreg), GFP_KERNEL);
if (!vreg)
return -ENOMEM;
memcpy(vreg, reg->template, sizeof(*vreg));
mutex_init(&vreg->lock);
vreg->dev = &pdev->dev;

View file

@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -8,7 +8,6 @@
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -38,10 +38,6 @@
#define RAA215300_REG_BLOCK_EN_RTC_EN BIT(6)
#define RAA215300_RTC_DEFAULT_ADDR 0x6f
const char *clkin_name = "clkin";
const char *xin_name = "xin";
static struct clk *clk;
static const struct regmap_config raa215300_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@ -51,10 +47,6 @@ static const struct regmap_config raa215300_regmap_config = {
static void raa215300_rtc_unregister_device(void *data)
{
i2c_unregister_device(data);
if (!clk) {
clk_unregister_fixed_rate(clk);
clk = NULL;
}
}
static int raa215300_clk_present(struct i2c_client *client, const char *name)
@ -71,8 +63,10 @@ static int raa215300_clk_present(struct i2c_client *client, const char *name)
static int raa215300_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
const char *clk_name = xin_name;
const char *clkin_name = "clkin";
unsigned int pmic_version, val;
const char *xin_name = "xin";
const char *clk_name = NULL;
struct regmap *regmap;
int ret;
@ -92,7 +86,7 @@ static int raa215300_i2c_probe(struct i2c_client *client)
val &= RAA215300_REG_BLOCK_EN_RTC_EN;
regmap_write(regmap, RAA215300_REG_BLOCK_EN, val);
/*Clear the latched registers */
/* Clear the latched registers */
regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_1, &val);
regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_1, val);
regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_2, &val);
@ -114,24 +108,32 @@ static int raa215300_i2c_probe(struct i2c_client *client)
ret = raa215300_clk_present(client, xin_name);
if (ret < 0) {
return ret;
} else if (!ret) {
} else if (ret) {
clk_name = xin_name;
} else {
ret = raa215300_clk_present(client, clkin_name);
if (ret < 0)
return ret;
clk_name = clkin_name;
if (ret)
clk_name = clkin_name;
}
if (ret) {
char *name = pmic_version >= 0x12 ? "isl1208" : "raa215300_a0";
if (clk_name) {
const char *name = pmic_version >= 0x12 ? "isl1208" : "raa215300_a0";
struct device_node *np = client->dev.of_node;
u32 addr = RAA215300_RTC_DEFAULT_ADDR;
struct i2c_board_info info = {};
struct i2c_client *rtc_client;
struct clk_hw *hw;
ssize_t size;
clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, 32000);
clk_register_clkdev(clk, clk_name, NULL);
hw = devm_clk_hw_register_fixed_rate(dev, clk_name, NULL, 0, 32768);
if (IS_ERR(hw))
return PTR_ERR(hw);
ret = devm_clk_hw_register_clkdev(dev, hw, clk_name, NULL);
if (ret)
return dev_err_probe(dev, ret, "Failed to initialize clkdev\n");
if (np) {
int i;
@ -180,7 +182,7 @@ static struct i2c_driver raa215300_i2c_driver = {
.name = "raa215300",
.of_match_table = raa215300_dt_match,
},
.probe_new = raa215300_i2c_probe,
.probe = raa215300_i2c_probe,
};
module_i2c_driver(raa215300_i2c_driver);

View file

@ -16,7 +16,6 @@
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/gpio.h>
#include <linux/mfd/rc5t583.h>
struct rc5t583_regulator_info {

View file

@ -17,9 +17,10 @@
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/mfd/rk808.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/gpio/consumer.h>

View file

@ -36,7 +36,7 @@ static int set_dvs_level(const struct regulator_desc *desc,
}
for (i = 0; i < desc->n_voltages; i++) {
/* NOTE to next hacker - Does not support pickable ranges */
if (desc->linear_range_selectors)
if (desc->linear_range_selectors_bitfield)
return -EINVAL;
if (desc->n_linear_ranges)
ret = regulator_desc_list_voltage_linear_range(desc, i);

View file

@ -7,7 +7,6 @@
#include <linux/backlight.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/i2c.h>
#include <linux/init.h>
@ -397,7 +396,7 @@ static struct i2c_driver attiny_regulator_driver = {
.driver = {
.name = "rpi_touchscreen_attiny",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.of_match_table = of_match_ptr(attiny_dt_ids),
.of_match_table = attiny_dt_ids,
},
.probe = attiny_i2c_probe,
.remove = attiny_i2c_remove,

View file

@ -31,10 +31,17 @@
#define RT5739_MODEVSEL1_MASK BIT(1)
#define RT5739_MODEVSEL0_MASK BIT(0)
#define RT5739_VID_MASK GENMASK(7, 5)
#define RT5739_DID_MASK GENMASK(3, 0)
#define RT5739_ACTD_MASK BIT(7)
#define RT5739_ENVSEL1_MASK BIT(1)
#define RT5739_ENVSEL0_MASK BIT(0)
#define RT5733_CHIPDIE_ID 0x1
#define RT5733_VOLT_MINUV 270000
#define RT5733_VOLT_MAXUV 1401250
#define RT5733_VOLT_STPUV 6250
#define RT5733_N_VOLTS 182
#define RT5739_VOLT_MINUV 300000
#define RT5739_VOLT_MAXUV 1300000
#define RT5739_VOLT_STPUV 5000
@ -93,8 +100,11 @@ static int rt5739_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 reg, vsel;
int max_uV;
if (uV < RT5739_VOLT_MINUV || uV > RT5739_VOLT_MAXUV)
max_uV = desc->min_uV + desc->uV_step * (desc->n_voltages - 1);
if (uV < desc->min_uV || uV > max_uV)
return -EINVAL;
if (desc->vsel_reg == RT5739_REG_NSEL0)
@ -102,7 +112,7 @@ static int rt5739_set_suspend_voltage(struct regulator_dev *rdev, int uV)
else
reg = RT5739_REG_NSEL0;
vsel = (uV - RT5739_VOLT_MINUV) / RT5739_VOLT_STPUV;
vsel = (uV - desc->min_uV) / desc->uV_step;
return regmap_write(regmap, reg, vsel);
}
@ -189,15 +199,12 @@ static unsigned int rt5739_of_map_mode(unsigned int mode)
}
static void rt5739_init_regulator_desc(struct regulator_desc *desc,
bool vsel_active_high)
bool vsel_active_high, u8 did)
{
/* Fixed */
desc->name = "rt5739-regulator";
desc->owner = THIS_MODULE;
desc->ops = &rt5739_regulator_ops;
desc->n_voltages = RT5739_N_VOLTS;
desc->min_uV = RT5739_VOLT_MINUV;
desc->uV_step = RT5739_VOLT_STPUV;
desc->vsel_mask = RT5739_VSEL_MASK;
desc->enable_reg = RT5739_REG_CNTL2;
desc->active_discharge_reg = RT5739_REG_CNTL1;
@ -213,6 +220,20 @@ static void rt5739_init_regulator_desc(struct regulator_desc *desc,
desc->vsel_reg = RT5739_REG_NSEL0;
desc->enable_mask = RT5739_ENVSEL0_MASK;
}
/* Assigned by CHIPDIE ID */
switch (did) {
case RT5733_CHIPDIE_ID:
desc->n_voltages = RT5733_N_VOLTS;
desc->min_uV = RT5733_VOLT_MINUV;
desc->uV_step = RT5733_VOLT_STPUV;
break;
default:
desc->n_voltages = RT5739_N_VOLTS;
desc->min_uV = RT5739_VOLT_MINUV;
desc->uV_step = RT5739_VOLT_STPUV;
break;
}
}
static const struct regmap_config rt5739_regmap_config = {
@ -258,7 +279,7 @@ static int rt5739_probe(struct i2c_client *i2c)
vsel_acth = device_property_read_bool(dev, "richtek,vsel-active-high");
rt5739_init_regulator_desc(desc, vsel_acth);
rt5739_init_regulator_desc(desc, vsel_acth, vid & RT5739_DID_MASK);
cfg.dev = dev;
cfg.of_node = dev_of_node(dev);
@ -271,6 +292,7 @@ static int rt5739_probe(struct i2c_client *i2c)
}
static const struct of_device_id rt5739_device_table[] = {
{ .compatible = "richtek,rt5733" },
{ .compatible = "richtek,rt5739" },
{ /* sentinel */ }
};

View file

@ -4,7 +4,7 @@
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -0,0 +1,583 @@
// SPDX-License-Identifier: GPL-2.0+
#include <linux/bitops.h>
#include <linux/bitfield.h>
#include <linux/util_macros.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/mod_devicetable.h>
/* Register */
#define RTQ2208_REG_GLOBAL_INT1 0x12
#define RTQ2208_REG_FLT_RECORDBUCK_CB 0x18
#define RTQ2208_REG_GLOBAL_INT1_MASK 0x1D
#define RTQ2208_REG_FLT_MASKBUCK_CB 0x1F
#define RTQ2208_REG_BUCK_C_CFG0 0x32
#define RTQ2208_REG_BUCK_B_CFG0 0x42
#define RTQ2208_REG_BUCK_A_CFG0 0x52
#define RTQ2208_REG_BUCK_D_CFG0 0x62
#define RTQ2208_REG_BUCK_G_CFG0 0x72
#define RTQ2208_REG_BUCK_F_CFG0 0x82
#define RTQ2208_REG_BUCK_E_CFG0 0x92
#define RTQ2208_REG_BUCK_H_CFG0 0xA2
#define RTQ2208_REG_LDO1_CFG 0xB1
#define RTQ2208_REG_LDO2_CFG 0xC1
/* Mask */
#define RTQ2208_BUCK_NR_MTP_SEL_MASK GENMASK(7, 0)
#define RTQ2208_BUCK_EN_NR_MTP_SEL0_MASK BIT(0)
#define RTQ2208_BUCK_EN_NR_MTP_SEL1_MASK BIT(1)
#define RTQ2208_BUCK_RSPUP_MASK GENMASK(6, 4)
#define RTQ2208_BUCK_RSPDN_MASK GENMASK(2, 0)
#define RTQ2208_BUCK_NRMODE_MASK BIT(5)
#define RTQ2208_BUCK_STRMODE_MASK BIT(5)
#define RTQ2208_BUCK_EN_STR_MASK BIT(0)
#define RTQ2208_LDO_EN_STR_MASK BIT(7)
#define RTQ2208_EN_DIS_MASK BIT(0)
#define RTQ2208_BUCK_RAMP_SEL_MASK GENMASK(2, 0)
#define RTQ2208_HD_INT_MASK BIT(0)
/* Size */
#define RTQ2208_VOUT_MAXNUM 256
#define RTQ2208_BUCK_NUM_IRQ_REGS 5
#define RTQ2208_STS_NUM_IRQ_REGS 2
/* Value */
#define RTQ2208_RAMP_VALUE_MIN_uV 500
#define RTQ2208_RAMP_VALUE_MAX_uV 64000
#define RTQ2208_BUCK_MASK(uv_irq, ov_irq) (1 << ((uv_irq) % 8) | 1 << ((ov_irq) % 8))
enum {
RTQ2208_BUCK_B = 0,
RTQ2208_BUCK_C,
RTQ2208_BUCK_D,
RTQ2208_BUCK_A,
RTQ2208_BUCK_F,
RTQ2208_BUCK_G,
RTQ2208_BUCK_H,
RTQ2208_BUCK_E,
RTQ2208_LDO2,
RTQ2208_LDO1,
RTQ2208_LDO_MAX,
};
enum {
RTQ2208_AUTO_MODE = 0,
RTQ2208_FCCM,
};
struct rtq2208_regulator_desc {
struct regulator_desc desc;
unsigned int mtp_sel_reg;
unsigned int mtp_sel_mask;
unsigned int mode_reg;
unsigned int mode_mask;
unsigned int suspend_config_reg;
unsigned int suspend_enable_mask;
unsigned int suspend_mode_mask;
};
struct rtq2208_rdev_map {
struct regulator_dev *rdev[RTQ2208_LDO_MAX];
struct regmap *regmap;
struct device *dev;
};
/* set Normal Auto/FCCM mode */
static int rtq2208_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
const struct rtq2208_regulator_desc *rdesc =
(const struct rtq2208_regulator_desc *)rdev->desc;
unsigned int val, shift;
switch (mode) {
case REGULATOR_MODE_NORMAL:
val = RTQ2208_AUTO_MODE;
break;
case REGULATOR_MODE_FAST:
val = RTQ2208_FCCM;
break;
default:
return -EINVAL;
}
shift = ffs(rdesc->mode_mask) - 1;
return regmap_update_bits(rdev->regmap, rdesc->mode_reg,
rdesc->mode_mask, val << shift);
}
static unsigned int rtq2208_get_mode(struct regulator_dev *rdev)
{
const struct rtq2208_regulator_desc *rdesc =
(const struct rtq2208_regulator_desc *)rdev->desc;
unsigned int mode_val;
int ret;
ret = regmap_read(rdev->regmap, rdesc->mode_reg, &mode_val);
if (ret)
return REGULATOR_MODE_INVALID;
return (mode_val & rdesc->mode_mask) ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
}
static int rtq2208_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
const struct regulator_desc *desc = rdev->desc;
unsigned int sel = 0, val;
ramp_delay = max(ramp_delay, RTQ2208_RAMP_VALUE_MIN_uV);
ramp_delay = min(ramp_delay, RTQ2208_RAMP_VALUE_MAX_uV);
ramp_delay /= RTQ2208_RAMP_VALUE_MIN_uV;
/*
* fls(ramp_delay) - 1: doing LSB shift, let it starts from 0
*
* RTQ2208_BUCK_RAMP_SEL_MASK - sel: doing descending order shifting.
* Because the relation of seleltion and value is like that
*
* seletion: value
* 000: 64mv
* 001: 32mv
* ...
* 111: 0.5mv
*
* For example, if I would like to select 64mv, the fls(ramp_delay) - 1 will be 0b111,
* and I need to use 0b111 - sel to do the shifting
*/
sel = fls(ramp_delay) - 1;
sel = RTQ2208_BUCK_RAMP_SEL_MASK - sel;
val = FIELD_PREP(RTQ2208_BUCK_RSPUP_MASK, sel) | FIELD_PREP(RTQ2208_BUCK_RSPDN_MASK, sel);
return regmap_update_bits(rdev->regmap, desc->ramp_reg,
RTQ2208_BUCK_RSPUP_MASK | RTQ2208_BUCK_RSPDN_MASK, val);
}
static int rtq2208_set_suspend_enable(struct regulator_dev *rdev)
{
const struct rtq2208_regulator_desc *rdesc =
(const struct rtq2208_regulator_desc *)rdev->desc;
return regmap_set_bits(rdev->regmap, rdesc->suspend_config_reg, rdesc->suspend_enable_mask);
}
static int rtq2208_set_suspend_disable(struct regulator_dev *rdev)
{
const struct rtq2208_regulator_desc *rdesc =
(const struct rtq2208_regulator_desc *)rdev->desc;
return regmap_update_bits(rdev->regmap, rdesc->suspend_config_reg, rdesc->suspend_enable_mask, 0);
}
static int rtq2208_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode)
{
const struct rtq2208_regulator_desc *rdesc =
(const struct rtq2208_regulator_desc *)rdev->desc;
unsigned int val, shift;
switch (mode) {
case REGULATOR_MODE_NORMAL:
val = RTQ2208_AUTO_MODE;
break;
case REGULATOR_MODE_FAST:
val = RTQ2208_FCCM;
break;
default:
return -EINVAL;
}
shift = ffs(rdesc->suspend_mode_mask) - 1;
return regmap_update_bits(rdev->regmap, rdesc->suspend_config_reg,
rdesc->suspend_mode_mask, val << shift);
}
static const struct regulator_ops rtq2208_regulator_buck_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_mode = rtq2208_set_mode,
.get_mode = rtq2208_get_mode,
.set_ramp_delay = rtq2208_set_ramp_delay,
.set_active_discharge = regulator_set_active_discharge_regmap,
.set_suspend_enable = rtq2208_set_suspend_enable,
.set_suspend_disable = rtq2208_set_suspend_disable,
.set_suspend_mode = rtq2208_set_suspend_mode,
};
static const struct regulator_ops rtq2208_regulator_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
.set_suspend_enable = rtq2208_set_suspend_enable,
.set_suspend_disable = rtq2208_set_suspend_disable,
};
static unsigned int rtq2208_of_map_mode(unsigned int mode)
{
switch (mode) {
case RTQ2208_AUTO_MODE:
return REGULATOR_MODE_NORMAL;
case RTQ2208_FCCM:
return REGULATOR_MODE_FAST;
default:
return REGULATOR_MODE_INVALID;
}
}
static int rtq2208_init_irq_mask(struct rtq2208_rdev_map *rdev_map, unsigned int *buck_masks)
{
unsigned char buck_clr_masks[5] = {0x33, 0x33, 0x33, 0x33, 0x33},
sts_clr_masks[2] = {0xE7, 0xF7}, sts_masks[2] = {0xE6, 0xF6};
int ret;
/* write clear all buck irq once */
ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_FLT_RECORDBUCK_CB, buck_clr_masks, 5);
if (ret)
return dev_err_probe(rdev_map->dev, ret, "Failed to clr buck irqs\n");
/* write clear general irq once */
ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1, sts_clr_masks, 2);
if (ret)
return dev_err_probe(rdev_map->dev, ret, "Failed to clr general irqs\n");
/* unmask buck ov/uv irq */
ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_FLT_MASKBUCK_CB, buck_masks, 5);
if (ret)
return dev_err_probe(rdev_map->dev, ret, "Failed to unmask buck irqs\n");
/* unmask needed general irq */
return regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1_MASK, sts_masks, 2);
}
static irqreturn_t rtq2208_irq_handler(int irqno, void *devid)
{
unsigned char buck_flags[RTQ2208_BUCK_NUM_IRQ_REGS], sts_flags[RTQ2208_STS_NUM_IRQ_REGS];
int ret = 0, i, uv_bit, ov_bit;
struct rtq2208_rdev_map *rdev_map = devid;
struct regulator_dev *rdev;
if (!rdev_map)
return IRQ_NONE;
/* read irq event */
ret = regmap_bulk_read(rdev_map->regmap, RTQ2208_REG_FLT_RECORDBUCK_CB,
buck_flags, ARRAY_SIZE(buck_flags));
if (ret)
return IRQ_NONE;
ret = regmap_bulk_read(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1,
sts_flags, ARRAY_SIZE(sts_flags));
if (ret)
return IRQ_NONE;
/* clear irq event */
ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_FLT_RECORDBUCK_CB,
buck_flags, ARRAY_SIZE(buck_flags));
if (ret)
return IRQ_NONE;
ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1,
sts_flags, ARRAY_SIZE(sts_flags));
if (ret)
return IRQ_NONE;
for (i = 0; i < RTQ2208_LDO_MAX; i++) {
if (!rdev_map->rdev[i])
continue;
rdev = rdev_map->rdev[i];
/* uv irq */
uv_bit = (i & 1) ? 4 : 0;
if (buck_flags[i >> 1] & (1 << uv_bit))
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_UNDER_VOLTAGE, NULL);
/* ov irq */
ov_bit = uv_bit + 1;
if (buck_flags[i >> 1] & (1 << ov_bit))
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_REGULATION_OUT, NULL);
/* hd irq */
if (sts_flags[1] & RTQ2208_HD_INT_MASK)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_OVER_TEMP, NULL);
}
return IRQ_HANDLED;
}
#define RTQ2208_REGULATOR_INFO(_name, _base) \
{ \
.name = #_name, \
.base = _base, \
}
#define BUCK_RG_BASE(_id) RTQ2208_REG_BUCK_##_id##_CFG0
#define BUCK_RG_SHIFT(_base, _shift) (_base + _shift)
#define LDO_RG_BASE(_id) RTQ2208_REG_LDO##_id##_CFG
#define LDO_RG_SHIFT(_base, _shift) (_base + _shift)
#define VSEL_SHIFT(_sel) (_sel ? 3 : 1)
#define MTP_SEL_MASK(_sel) RTQ2208_BUCK_EN_NR_MTP_SEL##_sel##_MASK
static const struct linear_range rtq2208_vout_range[] = {
REGULATOR_LINEAR_RANGE(400000, 0, 180, 5000),
REGULATOR_LINEAR_RANGE(1310000, 181, 255, 10000),
};
static int rtq2208_of_get_fixed_voltage(struct device *dev,
struct of_regulator_match *rtq2208_ldo_match, int n_fixed)
{
struct device_node *np;
struct of_regulator_match *match;
struct rtq2208_regulator_desc *rdesc;
struct regulator_init_data *init_data;
int ret, i;
if (!dev->of_node)
return -ENODEV;
np = of_get_child_by_name(dev->of_node, "regulators");
if (!np)
np = dev->of_node;
ret = of_regulator_match(dev, np, rtq2208_ldo_match, n_fixed);
of_node_put(np);
if (ret < 0)
return ret;
for (i = 0; i < n_fixed; i++) {
match = rtq2208_ldo_match + i;
init_data = match->init_data;
rdesc = (struct rtq2208_regulator_desc *)match->driver_data;
if (!init_data || !rdesc)
continue;
if (init_data->constraints.min_uV == init_data->constraints.max_uV)
rdesc->desc.fixed_uV = init_data->constraints.min_uV;
}
return 0;
}
static void rtq2208_init_regulator_desc(struct rtq2208_regulator_desc *rdesc, int mtp_sel,
int idx, struct of_regulator_match *rtq2208_ldo_match, int *ldo_idx)
{
struct regulator_desc *desc;
static const struct {
char *name;
int base;
} regulator_info[] = {
RTQ2208_REGULATOR_INFO(buck-b, BUCK_RG_BASE(B)),
RTQ2208_REGULATOR_INFO(buck-c, BUCK_RG_BASE(C)),
RTQ2208_REGULATOR_INFO(buck-d, BUCK_RG_BASE(D)),
RTQ2208_REGULATOR_INFO(buck-a, BUCK_RG_BASE(A)),
RTQ2208_REGULATOR_INFO(buck-f, BUCK_RG_BASE(F)),
RTQ2208_REGULATOR_INFO(buck-g, BUCK_RG_BASE(G)),
RTQ2208_REGULATOR_INFO(buck-h, BUCK_RG_BASE(H)),
RTQ2208_REGULATOR_INFO(buck-e, BUCK_RG_BASE(E)),
RTQ2208_REGULATOR_INFO(ldo2, LDO_RG_BASE(2)),
RTQ2208_REGULATOR_INFO(ldo1, LDO_RG_BASE(1)),
}, *curr_info;
curr_info = regulator_info + idx;
desc = &rdesc->desc;
desc->name = curr_info->name;
desc->of_match = of_match_ptr(curr_info->name);
desc->regulators_node = of_match_ptr("regulators");
desc->id = idx;
desc->owner = THIS_MODULE;
desc->type = REGULATOR_VOLTAGE;
desc->enable_mask = mtp_sel ? MTP_SEL_MASK(1) : MTP_SEL_MASK(0);
desc->active_discharge_on = RTQ2208_EN_DIS_MASK;
desc->active_discharge_off = 0;
desc->active_discharge_mask = RTQ2208_EN_DIS_MASK;
rdesc->mode_mask = RTQ2208_BUCK_NRMODE_MASK;
if (idx >= RTQ2208_BUCK_B && idx <= RTQ2208_BUCK_E) {
/* init buck desc */
desc->enable_reg = BUCK_RG_SHIFT(curr_info->base, 2);
desc->ops = &rtq2208_regulator_buck_ops;
desc->vsel_reg = curr_info->base + VSEL_SHIFT(mtp_sel);
desc->vsel_mask = RTQ2208_BUCK_NR_MTP_SEL_MASK;
desc->n_voltages = RTQ2208_VOUT_MAXNUM;
desc->linear_ranges = rtq2208_vout_range;
desc->n_linear_ranges = ARRAY_SIZE(rtq2208_vout_range);
desc->ramp_reg = BUCK_RG_SHIFT(curr_info->base, 5);
desc->active_discharge_reg = curr_info->base;
desc->of_map_mode = rtq2208_of_map_mode;
rdesc->mode_reg = BUCK_RG_SHIFT(curr_info->base, 2);
rdesc->suspend_config_reg = BUCK_RG_SHIFT(curr_info->base, 4);
rdesc->suspend_enable_mask = RTQ2208_BUCK_EN_STR_MASK;
rdesc->suspend_mode_mask = RTQ2208_BUCK_STRMODE_MASK;
} else {
/* init ldo desc */
desc->enable_reg = curr_info->base;
desc->ops = &rtq2208_regulator_ldo_ops;
desc->n_voltages = 1;
desc->active_discharge_reg = LDO_RG_SHIFT(curr_info->base, 2);
rtq2208_ldo_match[*ldo_idx].name = desc->name;
rtq2208_ldo_match[*ldo_idx].driver_data = rdesc;
rtq2208_ldo_match[(*ldo_idx)++].desc = desc;
rdesc->suspend_config_reg = curr_info->base;
rdesc->suspend_enable_mask = RTQ2208_LDO_EN_STR_MASK;
}
}
static int rtq2208_parse_regulator_dt_data(int n_regulator, const unsigned int *regulator_idx_table,
struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX], struct device *dev)
{
struct of_regulator_match rtq2208_ldo_match[2];
int mtp_sel, ret, i, idx, ldo_idx = 0;
/* get mtp_sel0 or mtp_sel1 */
mtp_sel = device_property_read_bool(dev, "richtek,mtp-sel-high");
for (i = 0; i < n_regulator; i++) {
idx = regulator_idx_table[i];
rdesc[i] = devm_kcalloc(dev, 1, sizeof(*rdesc[0]), GFP_KERNEL);
if (!rdesc[i])
return -ENOMEM;
rtq2208_init_regulator_desc(rdesc[i], mtp_sel, idx, rtq2208_ldo_match, &ldo_idx);
}
/* init ldo fixed_uV */
ret = rtq2208_of_get_fixed_voltage(dev, rtq2208_ldo_match, ldo_idx);
if (ret)
return dev_err_probe(dev, ret, "Failed to get ldo fixed_uV\n");
return 0;
}
/** different slave address corresponds different used bucks
* slave address 0x10: BUCK[BCA FGE]
* slave address 0x20: BUCK[BC FGHE]
* slave address 0x40: BUCK[C G]
*/
static int rtq2208_regulator_check(int slave_addr, int *num,
int *regulator_idx_table, unsigned int *buck_masks)
{
static bool rtq2208_used_table[3][RTQ2208_LDO_MAX] = {
/* BUCK[BCA FGE], LDO[12] */
{1, 1, 0, 1, 1, 1, 0, 1, 1, 1},
/* BUCK[BC FGHE], LDO[12]*/
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1},
/* BUCK[C G], LDO[12] */
{0, 1, 0, 0, 0, 1, 0, 0, 1, 1},
};
int i, idx = ffs(slave_addr >> 4) - 1;
u8 mask;
for (i = 0; i < RTQ2208_LDO_MAX; i++) {
if (!rtq2208_used_table[idx][i])
continue;
regulator_idx_table[(*num)++] = i;
mask = RTQ2208_BUCK_MASK(4 * i, 4 * i + 1);
buck_masks[i >> 1] &= ~mask;
}
return 0;
}
static const struct regmap_config rtq2208_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xEF,
};
static int rtq2208_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct regmap *regmap;
struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX];
struct regulator_dev *rdev;
struct regulator_config cfg;
struct rtq2208_rdev_map *rdev_map;
int i, ret = 0, idx, n_regulator = 0;
unsigned int regulator_idx_table[RTQ2208_LDO_MAX],
buck_masks[RTQ2208_BUCK_NUM_IRQ_REGS] = {0x33, 0x33, 0x33, 0x33, 0x33};
rdev_map = devm_kzalloc(dev, sizeof(struct rtq2208_rdev_map), GFP_KERNEL);
if (!rdev_map)
return -ENOMEM;
regmap = devm_regmap_init_i2c(i2c, &rtq2208_regmap_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "Failed to allocate regmap\n");
/* get needed regulator */
ret = rtq2208_regulator_check(i2c->addr, &n_regulator, regulator_idx_table, buck_masks);
if (ret)
return dev_err_probe(dev, ret, "Failed to check used regulators\n");
rdev_map->regmap = regmap;
rdev_map->dev = dev;
cfg.dev = dev;
/* init regulator desc */
ret = rtq2208_parse_regulator_dt_data(n_regulator, regulator_idx_table, rdesc, dev);
if (ret)
return ret;
for (i = 0; i < n_regulator; i++) {
idx = regulator_idx_table[i];
/* register regulator */
rdev = devm_regulator_register(dev, &rdesc[i]->desc, &cfg);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
rdev_map->rdev[idx] = rdev;
}
/* init interrupt mask */
ret = rtq2208_init_irq_mask(rdev_map, buck_masks);
if (ret)
return ret;
/* register interrupt */
return devm_request_threaded_irq(dev, i2c->irq, NULL, rtq2208_irq_handler,
IRQF_ONESHOT, dev_name(dev), rdev_map);
}
static const struct of_device_id rtq2208_device_tables[] = {
{ .compatible = "richtek,rtq2208" },
{}
};
MODULE_DEVICE_TABLE(of, rtq2208_device_tables);
static struct i2c_driver rtq2208_driver = {
.driver = {
.name = "rtq2208",
.of_match_table = rtq2208_device_tables,
},
.probe = rtq2208_probe,
};
module_i2c_driver(rtq2208_driver);
MODULE_AUTHOR("Alina Yu <alina_yu@richtek.com>");
MODULE_DESCRIPTION("Richtek RTQ2208 Regulator Driver");
MODULE_LICENSE("GPL");

View file

@ -5,7 +5,6 @@
#include <linux/bug.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/of.h>

View file

@ -6,8 +6,7 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -10,7 +10,7 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -8,7 +8,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -9,7 +9,7 @@
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -4,7 +4,7 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
@ -84,11 +84,11 @@ static unsigned int tps6286x_of_map_mode(unsigned int mode)
static const struct regulator_desc tps6286x_reg = {
.name = "tps6286x",
.of_match = of_match_ptr("SW"),
.of_match = "SW",
.owner = THIS_MODULE,
.ops = &tps6286x_regulator_ops,
.of_map_mode = tps6286x_of_map_mode,
.regulators_node = of_match_ptr("regulators"),
.regulators_node = "regulators",
.type = REGULATOR_VOLTAGE,
.n_voltages = ((TPS6286X_MAX_MV - TPS6286X_MIN_MV) / TPS6286X_STEP_MV) + 1,
.min_uV = TPS6286X_MIN_MV * 1000,
@ -148,7 +148,7 @@ static struct i2c_driver tps6286x_regulator_driver = {
.driver = {
.name = "tps6286x",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.of_match_table = of_match_ptr(tps6286x_dt_ids),
.of_match_table = tps6286x_dt_ids,
},
.probe = tps6286x_i2c_probe,
.id_table = tps6286x_i2c_id,

View file

@ -8,8 +8,8 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
@ -41,7 +41,7 @@ static const struct linear_range tps6287x_voltage_ranges[] = {
};
static const unsigned int tps6287x_voltage_range_sel[] = {
0x0, 0x4, 0x8, 0xC
0x0, 0x1, 0x2, 0x3
};
static const unsigned int tps6287x_ramp_table[] = {
@ -122,7 +122,7 @@ static struct regulator_desc tps6287x_reg = {
.n_voltages = 256,
.linear_ranges = tps6287x_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(tps6287x_voltage_ranges),
.linear_range_selectors = tps6287x_voltage_range_sel,
.linear_range_selectors_bitfield = tps6287x_voltage_range_sel,
};
static int tps6287x_i2c_probe(struct i2c_client *i2c)

View file

@ -15,7 +15,15 @@
#include <linux/mfd/tps65086.h>
enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
LDOA2, LDOA3, SWA1, SWB1, SWB2, VTT };
LDOA2, LDOA3, VTT, SWA1, SWB1, SWB2 };
/* Selector for regulator configuration regarding PMIC chip ID. */
enum tps65086_ids {
TPS6508640 = 0,
TPS65086401,
TPS6508641,
TPS65086470,
};
#define TPS65086_REGULATOR(_name, _of, _id, _nv, _vr, _vm, _er, _em, _lr, _dr, _dm) \
[_id] = { \
@ -57,12 +65,24 @@ enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
}, \
}
#define TPS65086_REGULATOR_CONFIG(_chip_id, _config) \
[_chip_id] = { \
.config = _config, \
.num_elems = ARRAY_SIZE(_config), \
}
struct tps65086_regulator {
struct regulator_desc desc;
unsigned int decay_reg;
unsigned int decay_mask;
};
struct tps65086_regulator_config {
struct tps65086_regulator * const config;
const unsigned int num_elems;
};
static const struct linear_range tps65086_10mv_ranges[] = {
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000),
@ -114,7 +134,125 @@ static int tps65086_of_parse_cb(struct device_node *dev,
const struct regulator_desc *desc,
struct regulator_config *config);
static struct tps65086_regulator regulators[] = {
static struct tps65086_regulator tps6508640_regulator_config[] = {
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
BIT(0)),
TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
BIT(0)),
TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
BIT(0)),
TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK4VID,
BIT(0)),
TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
BIT(0)),
TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
BIT(0)),
TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
tps65086_ldoa1_ranges, 0, 0),
TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_LDOA1CTRL, BIT(0)),
};
static struct tps65086_regulator tps65086401_regulator_config[] = {
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
BIT(0)),
TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
BIT(0)),
TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
BIT(0)),
TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK4VID,
BIT(0)),
TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
BIT(0)),
TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
BIT(0)),
TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
tps65086_ldoa1_ranges, 0, 0),
TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
};
static struct tps65086_regulator tps6508641_regulator_config[] = {
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
BIT(0)),
TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
BIT(0)),
TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
BIT(0)),
TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK4VID,
BIT(0)),
TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
BIT(0)),
TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
BIT(0)),
TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
tps65086_ldoa1_ranges, 0, 0),
TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
};
static struct tps65086_regulator tps65086470_regulator_config[] = {
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
@ -148,16 +286,25 @@ static struct tps65086_regulator regulators[] = {
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_SWVTT_EN, BIT(7)),
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
};
static const struct tps65086_regulator_config regulator_configs[] = {
TPS65086_REGULATOR_CONFIG(TPS6508640, tps6508640_regulator_config),
TPS65086_REGULATOR_CONFIG(TPS65086401, tps65086401_regulator_config),
TPS65086_REGULATOR_CONFIG(TPS6508641, tps6508641_regulator_config),
TPS65086_REGULATOR_CONFIG(TPS65086470, tps65086470_regulator_config)
};
static int tps65086_of_parse_cb(struct device_node *node,
const struct regulator_desc *desc,
struct regulator_config *config)
{
struct tps65086 * const tps = dev_get_drvdata(config->dev);
struct tps65086_regulator *regulators = tps->reg_config->config;
int ret;
/* Check for 25mV step mode */
@ -203,9 +350,30 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
{
struct tps65086 *tps = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
unsigned int selector_reg_config;
struct regulator_dev *rdev;
int i;
/* Select regulator configuration for used PMIC device */
switch (tps->chip_id) {
case TPS6508640_ID:
selector_reg_config = TPS6508640;
break;
case TPS65086401_ID:
selector_reg_config = TPS65086401;
break;
case TPS6508641_ID:
selector_reg_config = TPS6508641;
break;
case TPS65086470_ID:
selector_reg_config = TPS65086470;
break;
default:
dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n");
return -ENODEV;
}
tps->reg_config = &regulator_configs[selector_reg_config];
platform_set_drvdata(pdev, tps);
config.dev = &pdev->dev;
@ -213,12 +381,16 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
config.driver_data = tps;
config.regmap = tps->regmap;
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
rdev = devm_regulator_register(&pdev->dev, &regulators[i].desc,
&config);
for (i = 0; i < tps->reg_config->num_elems; ++i) {
struct regulator_desc * const desc_ptr = &tps->reg_config->config[i].desc;
dev_dbg(tps->dev, "Index: %u; Regulator name: \"%s\"; Regulator ID: %d\n",
i, desc_ptr->name, desc_ptr->id);
rdev = devm_regulator_register(&pdev->dev, desc_ptr, &config);
if (IS_ERR(rdev)) {
dev_err(tps->dev, "failed to register %s regulator\n",
pdev->name);
dev_err(tps->dev, "failed to register %d \"%s\" regulator\n",
i, desc_ptr->name);
return PTR_ERR(rdev);
}
}

View file

@ -8,12 +8,12 @@
*/
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/driver.h>

View file

@ -15,8 +15,8 @@
#include <linux/device.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/driver.h>

View file

@ -17,7 +17,6 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/mfd/tps65910.h>
#include <linux/regulator/of_regulator.h>

View file

@ -9,7 +9,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>

View file

@ -12,7 +12,6 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>

View file

@ -13,7 +13,6 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>

View file

@ -7,7 +7,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>

View file

@ -10,7 +10,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/coupler.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

View file

@ -8,7 +8,8 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>

View file

@ -13,8 +13,9 @@
#include <linux/regmap.h>
/* List of registers for TPS65086 */
#define TPS65086_DEVICEID 0x01
#define TPS65086_IRQ 0x02
#define TPS65086_DEVICEID1 0x00
#define TPS65086_DEVICEID2 0x01
#define TPS65086_IRQ 0x02
#define TPS65086_IRQ_MASK 0x03
#define TPS65086_PMICSTAT 0x04
#define TPS65086_SHUTDNSRC 0x05
@ -75,10 +76,16 @@
#define TPS65086_IRQ_SHUTDN_MASK BIT(3)
#define TPS65086_IRQ_FAULT_MASK BIT(7)
/* DEVICEID Register field definitions */
#define TPS65086_DEVICEID_PART_MASK GENMASK(3, 0)
#define TPS65086_DEVICEID_OTP_MASK GENMASK(5, 4)
#define TPS65086_DEVICEID_REV_MASK GENMASK(7, 6)
/* DEVICEID1 Register field definitions */
#define TPS6508640_ID 0x00
#define TPS65086401_ID 0x01
#define TPS6508641_ID 0x10
#define TPS65086470_ID 0x70
/* DEVICEID2 Register field definitions */
#define TPS65086_DEVICEID2_PART_MASK GENMASK(3, 0)
#define TPS65086_DEVICEID2_OTP_MASK GENMASK(5, 4)
#define TPS65086_DEVICEID2_REV_MASK GENMASK(7, 6)
/* VID Masks */
#define BUCK_VID_MASK GENMASK(7, 1)
@ -92,6 +99,8 @@ enum tps65086_irqs {
TPS65086_IRQ_FAULT,
};
struct tps65086_regulator_config;
/**
* struct tps65086 - state holder for the tps65086 driver
*
@ -100,6 +109,8 @@ enum tps65086_irqs {
struct tps65086 {
struct device *dev;
struct regmap *regmap;
unsigned int chip_id;
const struct tps65086_regulator_config *reg_config;
/* IRQ Data */
int irq;

View file

@ -35,10 +35,4 @@ enum db8500_regulator_id {
DB8500_NUM_REGULATORS
};
/*
* Exported interface for CPUIdle only. This function is called with all
* interrupts turned off.
*/
int power_state_active_is_enabled(void);
#endif

View file

@ -292,11 +292,12 @@ enum regulator_type {
* @ramp_delay: Time to settle down after voltage change (unit: uV/us)
* @min_dropout_uV: The minimum dropout voltage this regulator can handle
* @linear_ranges: A constant table of possible voltage ranges.
* @linear_range_selectors: A constant table of voltage range selectors.
* If pickable ranges are used each range must
* have corresponding selector here.
* @linear_range_selectors_bitfield: A constant table of voltage range
* selectors as bitfield values. If
* pickable ranges are used each range
* must have corresponding selector here.
* @n_linear_ranges: Number of entries in the @linear_ranges (and in
* linear_range_selectors if used) table(s).
* linear_range_selectors_bitfield if used) table(s).
* @volt_table: Voltage mapping table (if table based mapping)
* @curr_table: Current limit mapping table (if table based mapping)
*
@ -384,7 +385,7 @@ struct regulator_desc {
int min_dropout_uV;
const struct linear_range *linear_ranges;
const unsigned int *linear_range_selectors;
const unsigned int *linear_range_selectors_bitfield;
int n_linear_ranges;