Hardly anything going on in the core this time around with the regulator
 API and pretty quiet on the driver front:
 
  - An API for comparing regulators, useful for devices that need to
    check if supply voltages exactly match rather than just nominally
    match.
  - Conversion of several DT bindings to YAML format.
  - Conversion of I2C drivers to probe_new().
  - New drivers for Monolithic MPQ7920 and MP8859, and Rohm BD71828.
 -----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCgAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAl4vH54THGJyb29uaWVA
 a2VybmVsLm9yZwAKCRAk1otyXVSH0J3sB/9vdpvQa2ei2jyEna4w0ynscV/6HFbF
 br6U3E7gDzeyNHCz11x8q8cJidD20t44ICitSJkVsjbiJenRbDmrwUpCccCTS/fH
 byhirQTr+j9+4I/F4U26dpUU3ApOdT2Lsgm3C/SSQHjXg9BuyfdQYXIZjGpPns5F
 hD/ujf4n+2rPACnWiZC37a781Uct42OHM+ewRCMNdi7pm8lZuEE5edZ+HE+ipT/e
 QE9ZTXuNvpKOT1LRenXGiv03y3SJHFqRynjWBI5PLTFTO3dg5gY+mEWusLoSufas
 F3fZtOw0Q1kI7R/SPteYDT5l/htnKJA2g2VHTgwvgObUFSdwM4Eq4efj
 =++OR
 -----END PGP SIGNATURE-----

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

Pull regulator updates from Mark Brown:
 "Hardly anything going on in the core this time around with the
  regulator API and pretty quiet on the driver front:

   - An API for comparing regulators, useful for devices that need to
     check if supply voltages exactly match rather than just nominally
     match.

   - Conversion of several DT bindings to YAML format.

   - Conversion of I2C drivers to probe_new().

   - New drivers for Monolithic MPQ7920 and MP8859, and Rohm BD71828"

* tag 'regulator-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (34 commits)
  dt-bindings: regulator: add document bindings for mpq7920
  regulator: core: Fix exported symbols to the exported GPL version
  regulator: mpq7920: Fix incorrect defines
  regulator: vqmmc-ipq4019: Fix platform_no_drv_owner.cocci warnings
  regulator: vctrl-regulator: Avoid deadlock getting and setting the voltage
  regulator fix for "regulator: core: Add regulator_is_equal() helper"
  regulator: core: Add regulator_is_equal() helper
  regulator: mpq7920: Convert to use .probe_new
  regulator: mpq7920: Remove unneeded fields from struct mpq7920_regulator_info
  regulator: vqmmc-ipq4019: Trivial clean up
  regulator: vqmmc-ipq4019: Remove ipq4019_regulator_remove
  regulator: bindings: Drop document bindings for mpq7920
  dt-bindings: Drop entry for Monolithic Power System, MPS
  regulator: bd718x7: Simplify the code by removing struct bd718xx_pmic_inits
  regulator: add IPQ4019 SDHCI VQMMC LDO driver
  regulator: Convert i2c drivers to use .probe_new
  regulator: mpq7920: Check the correct variable in mpq7920_regulator_register()
  regulator: mpq7920: Fix Woverflow warning on conversion
  regulator: mp8859: tidy up white space in probe
  regulator: mpq7920: add mpq7920 regulator driver
  ...
This commit is contained in:
Linus Torvalds 2020-01-27 11:18:55 -08:00
Родитель 1e1ab4ba47 e4e4c2ff78
Коммит aae1464f46
38 изменённых файлов: 2014 добавлений и 156 удалений

Просмотреть файл

@ -0,0 +1,22 @@
Monolithic Power Systems MP8859 voltage regulator
Required properties:
- compatible: "mps,mp8859";
- reg: I2C slave address.
Optional subnode for regulator: "mp8859_dcdc", using common regulator
bindings given in <Documentation/devicetree/bindings/regulator/regulator.txt>.
Example:
mp8859: regulator@66 {
compatible = "mps,mp8859";
reg = <0x66>;
dc_12v: mp8859_dcdc {
regulator-name = "dc_12v";
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
regulator-boot-on;
regulator-always-on;
};
};

Просмотреть файл

@ -0,0 +1,121 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/mps,mpq7920.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Monolithic Power System MPQ7920 PMIC
maintainers:
- Saravanan Sekar <sravanhome@gmail.com>
properties:
$nodename:
pattern: "pmic@[0-9a-f]{1,2}"
compatible:
enum:
- mps,mpq7920
reg:
maxItems: 1
regulators:
type: object
allOf:
- $ref: regulator.yaml#
description: |
list of regulators provided by this controller, must be named
after their hardware counterparts BUCK[1-4], one LDORTC, and LDO[2-5]
properties:
mps,switch-freq:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint8"
enum: [ 0, 1, 2, 3 ]
default: 2
description: |
switching frequency must be one of following corresponding value
1.1MHz, 1.65MHz, 2.2MHz, 2.75MHz
patternProperties:
"^ldo[1-4]$":
type: object
allOf:
- $ref: regulator.yaml#
"^ldortc$":
type: object
allOf:
- $ref: regulator.yaml#
"^buck[1-4]$":
type: object
allOf:
- $ref: regulator.yaml#
properties:
mps,buck-softstart:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint8"
enum: [ 0, 1, 2, 3 ]
description: |
defines the soft start time of this buck, must be one of the following
corresponding values 150us, 300us, 610us, 920us
mps,buck-phase-delay:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint8"
enum: [ 0, 1, 2, 3 ]
description: |
defines the phase delay of this buck, must be one of the following
corresponding values 0deg, 90deg, 180deg, 270deg
mps,buck-ovp-disable:
type: boolean
description: |
disables over voltage protection of this buck
additionalProperties: false
additionalProperties: false
required:
- compatible
- reg
- regulators
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@69 {
compatible = "mps,mpq7920";
reg = <0x69>;
regulators {
mps,switch-freq = /bits/ 8 <1>;
buck1 {
regulator-name = "buck1";
regulator-min-microvolt = <400000>;
regulator-max-microvolt = <3587500>;
regulator-min-microamp = <460000>;
regulator-max-microamp = <7600000>;
regulator-boot-on;
mps,buck-ovp-disable;
mps,buck-phase-delay = /bits/ 8 <2>;
mps,buck-softstart = /bits/ 8 <1>;
};
ldo2 {
regulator-name = "ldo2";
regulator-min-microvolt = <650000>;
regulator-max-microvolt = <3587500>;
};
};
};
};
...

Просмотреть файл

@ -0,0 +1,107 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/rohm,bd71828-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ROHM BD71828 Power Management Integrated Circuit regulators
maintainers:
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
description: |
This module is part of the ROHM BD71828 MFD device. For more details
see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
The regulator controller is represented as a sub-node of the PMIC node
on the device tree.
Regulator nodes should be named to BUCK_<number> and LDO_<number>.
The valid names for BD71828 regulator nodes are
BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7
LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7
patternProperties:
"^LDO[1-7]$":
type: object
allOf:
- $ref: regulator.yaml#
description:
Properties for single LDO regulator.
properties:
regulator-name:
pattern: "^ldo[1-7]$"
description:
should be "ldo1", ..., "ldo7"
"^BUCK[1-7]$":
type: object
allOf:
- $ref: regulator.yaml#
description:
Properties for single BUCK regulator.
properties:
regulator-name:
pattern: "^buck[1-7]$"
description:
should be "buck1", ..., "buck7"
rohm,dvs-run-voltage:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32"
- minimum: 0
maximum: 3300000
description:
PMIC default "RUN" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-idle-voltage:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32"
- minimum: 0
maximum: 3300000
description:
PMIC default "IDLE" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-suspend-voltage:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32"
- minimum: 0
maximum: 3300000
description:
PMIC default "SUSPEND" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-lpsr-voltage:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32"
- minimum: 0
maximum: 3300000
description:
PMIC default "LPSR" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
# Supported default DVS states:
# buck | run | idle | suspend | lpsr
#--------------------------------------------------------------
# 1, 2, 6, and 7 | supported | supported | supported (*)
#--------------------------------------------------------------
# 3, 4, and 5 | supported (**)
#--------------------------------------------------------------
#
#(*) LPSR and SUSPEND states use same voltage but both states have own
# enable /
# disable settings. Voltage 0 can be specified for a state to make
# regulator disabled on that state.
#
#(**) All states use same voltage but have own enable / disable
# settings. Voltage 0 can be specified for a state to make
# regulator disabled on that state.
required:
- regulator-name
additionalProperties: false
additionalProperties: false

Просмотреть файл

@ -1,18 +0,0 @@
STM32 BOOSTER - Booster for ADC analog input switches
Some STM32 devices embed a 3.3V booster supplied by Vdda, that can be used
to supply ADC analog input switches.
Required properties:
- compatible: Should be one of:
"st,stm32h7-booster"
"st,stm32mp1-booster"
- st,syscfg: Phandle to system configuration controller.
- vdda-supply: Phandle to the vdda input analog voltage.
Example:
booster: regulator-booster {
compatible = "st,stm32mp1-booster";
st,syscfg = <&syscfg>;
vdda-supply = <&vdda>;
};

Просмотреть файл

@ -0,0 +1,46 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/st,stm32-booster.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics STM32 booster for ADC analog input switches bindings
maintainers:
- Fabrice Gasnier <fabrice.gasnier@st.com>
description: |
Some STM32 devices embed a 3.3V booster supplied by Vdda, that can be used
to supply ADC analog input switches.
allOf:
- $ref: "regulator.yaml#"
properties:
compatible:
enum:
- st,stm32h7-booster
- st,stm32mp1-booster
st,syscfg:
allOf:
- $ref: "/schemas/types.yaml#/definitions/phandle-array"
description: phandle to system configuration controller.
vdda-supply:
description: phandle to the vdda input analog voltage.
required:
- compatible
- st,syscfg
- vdda-supply
examples:
- |
regulator-booster {
compatible = "st,stm32mp1-booster";
st,syscfg = <&syscfg>;
vdda-supply = <&vdda>;
};
...

Просмотреть файл

@ -1,20 +0,0 @@
STM32 VREFBUF - Voltage reference buffer
Some STM32 devices embed a voltage reference buffer which can be used as
voltage reference for ADCs, DACs and also as voltage reference for external
components through the dedicated VREF+ pin.
Required properties:
- compatible: Must be "st,stm32-vrefbuf".
- reg: Offset and length of VREFBUF register set.
- clocks: Must contain an entry for peripheral clock.
Example:
vrefbuf: regulator@58003c00 {
compatible = "st,stm32-vrefbuf";
reg = <0x58003C00 0x8>;
clocks = <&rcc VREF_CK>;
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2500000>;
vdda-supply = <&vdda>;
};

Просмотреть файл

@ -0,0 +1,52 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/st,stm32-vrefbuf.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics STM32 Voltage reference buffer bindings
description: |
Some STM32 devices embed a voltage reference buffer which can be used as
voltage reference for ADCs, DACs and also as voltage reference for external
components through the dedicated VREF+ pin.
maintainers:
- Fabrice Gasnier <fabrice.gasnier@st.com>
allOf:
- $ref: "regulator.yaml#"
properties:
compatible:
const: st,stm32-vrefbuf
reg:
maxItems: 1
clocks:
maxItems: 1
vdda-supply:
description: phandle to the vdda input analog voltage.
required:
- compatible
- reg
- clocks
- vdda-supply
examples:
- |
#include <dt-bindings/clock/stm32mp1-clks.h>
vrefbuf@50025000 {
compatible = "st,stm32-vrefbuf";
reg = <0x50025000 0x8>;
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2500000>;
clocks = <&rcc VREF>;
vdda-supply = <&vdda>;
};
...

Просмотреть файл

@ -1,43 +0,0 @@
STM32MP1 PWR Regulators
-----------------------
Available Regulators in STM32MP1 PWR block are:
- reg11 for regulator 1V1
- reg18 for regulator 1V8
- usb33 for the swtich USB3V3
Required properties:
- compatible: Must be "st,stm32mp1,pwr-reg"
- list of child nodes that specify the regulator reg11, reg18 or usb33
initialization data for defined regulators. The definition for each of
these nodes is defined using the standard binding for regulators found at
Documentation/devicetree/bindings/regulator/regulator.txt.
- vdd-supply: phandle to the parent supply/regulator node for vdd input
- vdd_3v3_usbfs-supply: phandle to the parent supply/regulator node for usb33
Example:
pwr_regulators: pwr@50001000 {
compatible = "st,stm32mp1,pwr-reg";
reg = <0x50001000 0x10>;
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
reg11: reg11 {
regulator-name = "reg11";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
};
reg18: reg18 {
regulator-name = "reg18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
usb33: usb33 {
regulator-name = "usb33";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
};

Просмотреть файл

@ -0,0 +1,64 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/st,stm32mp1-pwr-reg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STM32MP1 PWR voltage regulators
maintainers:
- Pascal Paillet <p.paillet@st.com>
properties:
compatible:
const: st,stm32mp1,pwr-reg
reg:
maxItems: 1
vdd-supply:
description: Input supply phandle(s) for vdd input
vdd_3v3_usbfs-supply:
description: Input supply phandle(s) for vdd_3v3_usbfs input
patternProperties:
"^(reg11|reg18|usb33)$":
type: object
allOf:
- $ref: "regulator.yaml#"
required:
- compatible
- reg
additionalProperties: false
examples:
- |
pwr@50001000 {
compatible = "st,stm32mp1,pwr-reg";
reg = <0x50001000 0x10>;
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
reg11 {
regulator-name = "reg11";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
};
reg18 {
regulator-name = "reg18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
usb33 {
regulator-name = "usb33";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
};
...

Просмотреть файл

@ -11174,6 +11174,13 @@ S: Maintained
F: Documentation/driver-api/serial/moxa-smartio.rst
F: drivers/tty/mxser.*
MONOLITHIC POWER SYSTEM PMIC DRIVER
M: Saravanan Sekar <sravanhome@gmail.com>
S: Maintained
F: Documentation/devicetree/bindings/regulator/mpq7920.yaml
F: drivers/regulator/mpq7920.c
F: drivers/regulator/mpq7920.h
MR800 AVERMEDIA USB FM RADIO DRIVER
M: Alexey Klimov <klimov.linux@gmail.com>
L: linux-media@vger.kernel.org

Просмотреть файл

@ -194,6 +194,18 @@ config REGULATOR_BD70528
This driver can also be built as a module. If so, the module
will be called bd70528-regulator.
config REGULATOR_BD71828
tristate "ROHM BD71828 Power Regulator"
depends on MFD_ROHM_BD71828
select REGULATOR_ROHM
help
This driver supports voltage regulators on ROHM BD71828 PMIC.
This will enable support for the software controllable buck
and LDO regulators.
This driver can also be built as a module. If so, the module
will be called bd71828-regulator.
config REGULATOR_BD718XX
tristate "ROHM BD71837 Power Regulator"
depends on MFD_ROHM_BD718XX
@ -600,6 +612,27 @@ config REGULATOR_MCP16502
through the regulator interface. In addition it enables
suspend-to-ram/standby transition.
config REGULATOR_MP8859
tristate "MPS MP8859 regulator driver"
depends on I2C
select REGMAP_I2C
help
Say y here to support the MP8859 voltage regulator. This driver
supports basic operations (get/set voltage) through the regulator
interface.
Say M here if you want to include support for the regulator as a
module. The module will be named "mp8859".
config REGULATOR_MPQ7920
tristate "Monolithic MPQ7920 PMIC"
depends on I2C && OF
select REGMAP_I2C
help
Say y here to support the MPQ7920 PMIC. This will enable supports
the software controllable 4 buck and 5 LDO regulators.
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
@ -1077,6 +1110,13 @@ config REGULATOR_VEXPRESS
This driver provides support for voltage regulators available
on the ARM Ltd's Versatile Express platform.
config REGULATOR_VQMMC_IPQ4019
tristate "IPQ4019 VQMMC SD LDO regulator support"
depends on ARCH_QCOM
help
This driver provides support for the VQMMC LDO I/0
voltage regulator of the IPQ4019 SD/EMMC controller.
config REGULATOR_WM831X
tristate "Wolfson Microelectronics WM831x PMIC regulators"
depends on MFD_WM831X

Просмотреть файл

@ -28,6 +28,7 @@ obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o
obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o
obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
@ -77,6 +78,8 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
obj-$(CONFIG_REGULATOR_MP8859) += mp8859.o
obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
@ -132,6 +135,7 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
obj-$(CONFIG_REGULATOR_UNIPHIER) += uniphier-regulator.o
obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o
obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
obj-$(CONFIG_REGULATOR_VQMMC_IPQ4019) += vqmmc-ipq4019-regulator.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o

Просмотреть файл

@ -0,0 +1,807 @@
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (C) 2019 ROHM Semiconductors
// bd71828-regulator.c ROHM BD71828GW-DS1 regulator driver
//
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/rohm-bd71828.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
struct reg_init {
unsigned int reg;
unsigned int mask;
unsigned int val;
};
struct bd71828_regulator_data {
struct regulator_desc desc;
const struct rohm_dvs_config dvs;
const struct reg_init *reg_inits;
int reg_init_amnt;
};
static const struct reg_init buck1_inits[] = {
/*
* DVS Buck voltages can be changed by register values or via GPIO.
* Use register accesses by default.
*/
{
.reg = BD71828_REG_PS_CTRL_1,
.mask = BD71828_MASK_DVS_BUCK1_CTRL,
.val = BD71828_DVS_BUCK1_CTRL_I2C,
},
};
static const struct reg_init buck2_inits[] = {
{
.reg = BD71828_REG_PS_CTRL_1,
.mask = BD71828_MASK_DVS_BUCK2_CTRL,
.val = BD71828_DVS_BUCK2_CTRL_I2C,
},
};
static const struct reg_init buck6_inits[] = {
{
.reg = BD71828_REG_PS_CTRL_1,
.mask = BD71828_MASK_DVS_BUCK6_CTRL,
.val = BD71828_DVS_BUCK6_CTRL_I2C,
},
};
static const struct reg_init buck7_inits[] = {
{
.reg = BD71828_REG_PS_CTRL_1,
.mask = BD71828_MASK_DVS_BUCK7_CTRL,
.val = BD71828_DVS_BUCK7_CTRL_I2C,
},
};
static const struct regulator_linear_range bd71828_buck1267_volts[] = {
REGULATOR_LINEAR_RANGE(500000, 0x00, 0xef, 6250),
REGULATOR_LINEAR_RANGE(2000000, 0xf0, 0xff, 0),
};
static const struct regulator_linear_range bd71828_buck3_volts[] = {
REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x0f, 50000),
REGULATOR_LINEAR_RANGE(2000000, 0x10, 0x1f, 0),
};
static const struct regulator_linear_range bd71828_buck4_volts[] = {
REGULATOR_LINEAR_RANGE(1000000, 0x00, 0x1f, 25000),
REGULATOR_LINEAR_RANGE(1800000, 0x20, 0x3f, 0),
};
static const struct regulator_linear_range bd71828_buck5_volts[] = {
REGULATOR_LINEAR_RANGE(2500000, 0x00, 0x0f, 50000),
REGULATOR_LINEAR_RANGE(3300000, 0x10, 0x1f, 0),
};
static const struct regulator_linear_range bd71828_ldo_volts[] = {
REGULATOR_LINEAR_RANGE(800000, 0x00, 0x31, 50000),
REGULATOR_LINEAR_RANGE(3300000, 0x32, 0x3f, 0),
};
static int bd71828_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int val;
switch (ramp_delay) {
case 1 ... 2500:
val = 0;
break;
case 2501 ... 5000:
val = 1;
break;
case 5001 ... 10000:
val = 2;
break;
case 10001 ... 20000:
val = 3;
break;
default:
val = 3;
dev_err(&rdev->dev,
"ramp_delay: %d not supported, setting 20mV/uS",
ramp_delay);
}
/*
* On BD71828 the ramp delay level control reg is at offset +2 to
* enable reg
*/
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg + 2,
BD71828_MASK_RAMP_DELAY,
val << (ffs(BD71828_MASK_RAMP_DELAY) - 1));
}
static int buck_set_hw_dvs_levels(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *cfg)
{
struct bd71828_regulator_data *data;
data = container_of(desc, struct bd71828_regulator_data, desc);
return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
}
static int ldo6_parse_dt(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *cfg)
{
int ret, i;
uint32_t uv = 0;
unsigned int en;
struct regmap *regmap = cfg->regmap;
static const char * const props[] = { "rohm,dvs-run-voltage",
"rohm,dvs-idle-voltage",
"rohm,dvs-suspend-voltage",
"rohm,dvs-lpsr-voltage" };
unsigned int mask[] = { BD71828_MASK_RUN_EN, BD71828_MASK_IDLE_EN,
BD71828_MASK_SUSP_EN, BD71828_MASK_LPSR_EN };
for (i = 0; i < ARRAY_SIZE(props); i++) {
ret = of_property_read_u32(np, props[i], &uv);
if (ret) {
if (ret != -EINVAL)
return ret;
continue;
}
if (uv)
en = 0xffffffff;
else
en = 0;
ret = regmap_update_bits(regmap, desc->enable_reg, mask[i], en);
if (ret)
return ret;
}
return 0;
}
static const struct regulator_ops bd71828_buck_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
static const struct regulator_ops bd71828_dvs_buck_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = bd71828_set_ramp_delay,
};
static const struct regulator_ops bd71828_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
static const struct regulator_ops bd71828_ldo6_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static const struct bd71828_regulator_data bd71828_rdata[] = {
{
.desc = {
.name = "buck1",
.of_match = of_match_ptr("BUCK1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_BUCK1,
.ops = &bd71828_dvs_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_buck1267_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
.n_voltages = BD71828_BUCK1267_VOLTS,
.enable_reg = BD71828_REG_BUCK1_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_BUCK1_VOLT,
.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK1_VOLT,
.run_mask = BD71828_MASK_BUCK1267_VOLT,
.idle_reg = BD71828_REG_BUCK1_IDLE_VOLT,
.idle_mask = BD71828_MASK_BUCK1267_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_reg = BD71828_REG_BUCK1_SUSP_VOLT,
.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
/*
* LPSR voltage is same as SUSPEND voltage. Allow
* setting it so that regulator can be set enabled at
* LPSR state
*/
.lpsr_reg = BD71828_REG_BUCK1_SUSP_VOLT,
.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
},
.reg_inits = buck1_inits,
.reg_init_amnt = ARRAY_SIZE(buck1_inits),
},
{
.desc = {
.name = "buck2",
.of_match = of_match_ptr("BUCK2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_BUCK2,
.ops = &bd71828_dvs_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_buck1267_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
.n_voltages = BD71828_BUCK1267_VOLTS,
.enable_reg = BD71828_REG_BUCK2_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_BUCK2_VOLT,
.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK2_VOLT,
.run_mask = BD71828_MASK_BUCK1267_VOLT,
.idle_reg = BD71828_REG_BUCK2_IDLE_VOLT,
.idle_mask = BD71828_MASK_BUCK1267_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_reg = BD71828_REG_BUCK2_SUSP_VOLT,
.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
.lpsr_reg = BD71828_REG_BUCK2_SUSP_VOLT,
.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
},
.reg_inits = buck2_inits,
.reg_init_amnt = ARRAY_SIZE(buck2_inits),
},
{
.desc = {
.name = "buck3",
.of_match = of_match_ptr("BUCK3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_BUCK3,
.ops = &bd71828_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_buck3_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_buck3_volts),
.n_voltages = BD71828_BUCK3_VOLTS,
.enable_reg = BD71828_REG_BUCK3_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_BUCK3_VOLT,
.vsel_mask = BD71828_MASK_BUCK3_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
/*
* BUCK3 only supports single voltage for all states.
* voltage can be individually enabled for each state
* though => allow setting all states to support
* enabling power rail on different states.
*/
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK3_VOLT,
.idle_reg = BD71828_REG_BUCK3_VOLT,
.suspend_reg = BD71828_REG_BUCK3_VOLT,
.lpsr_reg = BD71828_REG_BUCK3_VOLT,
.run_mask = BD71828_MASK_BUCK3_VOLT,
.idle_mask = BD71828_MASK_BUCK3_VOLT,
.suspend_mask = BD71828_MASK_BUCK3_VOLT,
.lpsr_mask = BD71828_MASK_BUCK3_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
},
{
.desc = {
.name = "buck4",
.of_match = of_match_ptr("BUCK4"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_BUCK4,
.ops = &bd71828_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_buck4_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_buck4_volts),
.n_voltages = BD71828_BUCK4_VOLTS,
.enable_reg = BD71828_REG_BUCK4_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_BUCK4_VOLT,
.vsel_mask = BD71828_MASK_BUCK4_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
/*
* BUCK4 only supports single voltage for all states.
* voltage can be individually enabled for each state
* though => allow setting all states to support
* enabling power rail on different states.
*/
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK4_VOLT,
.idle_reg = BD71828_REG_BUCK4_VOLT,
.suspend_reg = BD71828_REG_BUCK4_VOLT,
.lpsr_reg = BD71828_REG_BUCK4_VOLT,
.run_mask = BD71828_MASK_BUCK4_VOLT,
.idle_mask = BD71828_MASK_BUCK4_VOLT,
.suspend_mask = BD71828_MASK_BUCK4_VOLT,
.lpsr_mask = BD71828_MASK_BUCK4_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
},
{
.desc = {
.name = "buck5",
.of_match = of_match_ptr("BUCK5"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_BUCK5,
.ops = &bd71828_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_buck5_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_buck5_volts),
.n_voltages = BD71828_BUCK5_VOLTS,
.enable_reg = BD71828_REG_BUCK5_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_BUCK5_VOLT,
.vsel_mask = BD71828_MASK_BUCK5_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
/*
* BUCK5 only supports single voltage for all states.
* voltage can be individually enabled for each state
* though => allow setting all states to support
* enabling power rail on different states.
*/
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK5_VOLT,
.idle_reg = BD71828_REG_BUCK5_VOLT,
.suspend_reg = BD71828_REG_BUCK5_VOLT,
.lpsr_reg = BD71828_REG_BUCK5_VOLT,
.run_mask = BD71828_MASK_BUCK5_VOLT,
.idle_mask = BD71828_MASK_BUCK5_VOLT,
.suspend_mask = BD71828_MASK_BUCK5_VOLT,
.lpsr_mask = BD71828_MASK_BUCK5_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
},
{
.desc = {
.name = "buck6",
.of_match = of_match_ptr("BUCK6"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_BUCK6,
.ops = &bd71828_dvs_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_buck1267_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
.n_voltages = BD71828_BUCK1267_VOLTS,
.enable_reg = BD71828_REG_BUCK6_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_BUCK6_VOLT,
.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK6_VOLT,
.run_mask = BD71828_MASK_BUCK1267_VOLT,
.idle_reg = BD71828_REG_BUCK6_IDLE_VOLT,
.idle_mask = BD71828_MASK_BUCK1267_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_reg = BD71828_REG_BUCK6_SUSP_VOLT,
.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
.lpsr_reg = BD71828_REG_BUCK6_SUSP_VOLT,
.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
},
.reg_inits = buck6_inits,
.reg_init_amnt = ARRAY_SIZE(buck6_inits),
},
{
.desc = {
.name = "buck7",
.of_match = of_match_ptr("BUCK7"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_BUCK7,
.ops = &bd71828_dvs_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_buck1267_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
.n_voltages = BD71828_BUCK1267_VOLTS,
.enable_reg = BD71828_REG_BUCK7_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_BUCK7_VOLT,
.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK7_VOLT,
.run_mask = BD71828_MASK_BUCK1267_VOLT,
.idle_reg = BD71828_REG_BUCK7_IDLE_VOLT,
.idle_mask = BD71828_MASK_BUCK1267_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_reg = BD71828_REG_BUCK7_SUSP_VOLT,
.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
.lpsr_reg = BD71828_REG_BUCK7_SUSP_VOLT,
.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
},
.reg_inits = buck7_inits,
.reg_init_amnt = ARRAY_SIZE(buck7_inits),
},
{
.desc = {
.name = "ldo1",
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_LDO1,
.ops = &bd71828_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
.n_voltages = BD71828_LDO_VOLTS,
.enable_reg = BD71828_REG_LDO1_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_LDO1_VOLT,
.vsel_mask = BD71828_MASK_LDO_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
/*
* LDO1 only supports single voltage for all states.
* voltage can be individually enabled for each state
* though => allow setting all states to support
* enabling power rail on different states.
*/
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO1_VOLT,
.idle_reg = BD71828_REG_LDO1_VOLT,
.suspend_reg = BD71828_REG_LDO1_VOLT,
.lpsr_reg = BD71828_REG_LDO1_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
.idle_mask = BD71828_MASK_LDO_VOLT,
.suspend_mask = BD71828_MASK_LDO_VOLT,
.lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
}, {
.desc = {
.name = "ldo2",
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_LDO2,
.ops = &bd71828_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
.n_voltages = BD71828_LDO_VOLTS,
.enable_reg = BD71828_REG_LDO2_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_LDO2_VOLT,
.vsel_mask = BD71828_MASK_LDO_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
/*
* LDO2 only supports single voltage for all states.
* voltage can be individually enabled for each state
* though => allow setting all states to support
* enabling power rail on different states.
*/
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO2_VOLT,
.idle_reg = BD71828_REG_LDO2_VOLT,
.suspend_reg = BD71828_REG_LDO2_VOLT,
.lpsr_reg = BD71828_REG_LDO2_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
.idle_mask = BD71828_MASK_LDO_VOLT,
.suspend_mask = BD71828_MASK_LDO_VOLT,
.lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
}, {
.desc = {
.name = "ldo3",
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_LDO3,
.ops = &bd71828_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
.n_voltages = BD71828_LDO_VOLTS,
.enable_reg = BD71828_REG_LDO3_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_LDO3_VOLT,
.vsel_mask = BD71828_MASK_LDO_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
/*
* LDO3 only supports single voltage for all states.
* voltage can be individually enabled for each state
* though => allow setting all states to support
* enabling power rail on different states.
*/
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO3_VOLT,
.idle_reg = BD71828_REG_LDO3_VOLT,
.suspend_reg = BD71828_REG_LDO3_VOLT,
.lpsr_reg = BD71828_REG_LDO3_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
.idle_mask = BD71828_MASK_LDO_VOLT,
.suspend_mask = BD71828_MASK_LDO_VOLT,
.lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
}, {
.desc = {
.name = "ldo4",
.of_match = of_match_ptr("LDO4"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_LDO4,
.ops = &bd71828_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
.n_voltages = BD71828_LDO_VOLTS,
.enable_reg = BD71828_REG_LDO4_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_LDO4_VOLT,
.vsel_mask = BD71828_MASK_LDO_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
/*
* LDO1 only supports single voltage for all states.
* voltage can be individually enabled for each state
* though => allow setting all states to support
* enabling power rail on different states.
*/
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO4_VOLT,
.idle_reg = BD71828_REG_LDO4_VOLT,
.suspend_reg = BD71828_REG_LDO4_VOLT,
.lpsr_reg = BD71828_REG_LDO4_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
.idle_mask = BD71828_MASK_LDO_VOLT,
.suspend_mask = BD71828_MASK_LDO_VOLT,
.lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
}, {
.desc = {
.name = "ldo5",
.of_match = of_match_ptr("LDO5"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_LDO5,
.ops = &bd71828_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
.n_voltages = BD71828_LDO_VOLTS,
.enable_reg = BD71828_REG_LDO5_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_LDO5_VOLT,
.vsel_mask = BD71828_MASK_LDO_VOLT,
.of_parse_cb = buck_set_hw_dvs_levels,
.owner = THIS_MODULE,
},
/*
* LDO5 is special. It can choose vsel settings to be configured
* from 2 different registers (by GPIO).
*
* This driver supports only configuration where
* BD71828_REG_LDO5_VOLT_L is used.
*/
.dvs = {
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO5_VOLT,
.idle_reg = BD71828_REG_LDO5_VOLT,
.suspend_reg = BD71828_REG_LDO5_VOLT,
.lpsr_reg = BD71828_REG_LDO5_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
.idle_mask = BD71828_MASK_LDO_VOLT,
.suspend_mask = BD71828_MASK_LDO_VOLT,
.lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
}, {
.desc = {
.name = "ldo6",
.of_match = of_match_ptr("LDO6"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_LDO6,
.ops = &bd71828_ldo6_ops,
.type = REGULATOR_VOLTAGE,
.fixed_uV = BD71828_LDO_6_VOLTAGE,
.n_voltages = 1,
.enable_reg = BD71828_REG_LDO6_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.owner = THIS_MODULE,
/*
* LDO6 only supports enable/disable for all states.
* Voltage for LDO6 is fixed.
*/
.of_parse_cb = ldo6_parse_dt,
},
}, {
.desc = {
/* SNVS LDO in data-sheet */
.name = "ldo7",
.of_match = of_match_ptr("LDO7"),
.regulators_node = of_match_ptr("regulators"),
.id = BD71828_LDO_SNVS,
.ops = &bd71828_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd71828_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
.n_voltages = BD71828_LDO_VOLTS,
.enable_reg = BD71828_REG_LDO7_EN,
.enable_mask = BD71828_MASK_RUN_EN,
.vsel_reg = BD71828_REG_LDO7_VOLT,
.vsel_mask = BD71828_MASK_LDO_VOLT,
.owner = THIS_MODULE,
.of_parse_cb = buck_set_hw_dvs_levels,
},
.dvs = {
/*
* LDO7 only supports single voltage for all states.
* voltage can be individually enabled for each state
* though => allow setting all states to support
* enabling power rail on different states.
*/
.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO7_VOLT,
.idle_reg = BD71828_REG_LDO7_VOLT,
.suspend_reg = BD71828_REG_LDO7_VOLT,
.lpsr_reg = BD71828_REG_LDO7_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
.idle_mask = BD71828_MASK_LDO_VOLT,
.suspend_mask = BD71828_MASK_LDO_VOLT,
.lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
},
};
static int bd71828_probe(struct platform_device *pdev)
{
struct rohm_regmap_dev *bd71828;
int i, j, ret;
struct regulator_config config = {
.dev = pdev->dev.parent,
};
bd71828 = dev_get_drvdata(pdev->dev.parent);
if (!bd71828) {
dev_err(&pdev->dev, "No MFD driver data\n");
return -EINVAL;
}
config.regmap = bd71828->regmap;
for (i = 0; i < ARRAY_SIZE(bd71828_rdata); i++) {
struct regulator_dev *rdev;
const struct bd71828_regulator_data *rd;
rd = &bd71828_rdata[i];
rdev = devm_regulator_register(&pdev->dev,
&rd->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
rd->desc.name);
return PTR_ERR(rdev);
}
for (j = 0; j < rd->reg_init_amnt; j++) {
ret = regmap_update_bits(bd71828->regmap,
rd->reg_inits[j].reg,
rd->reg_inits[j].mask,
rd->reg_inits[j].val);
if (ret) {
dev_err(&pdev->dev,
"regulator %s init failed\n",
rd->desc.name);
return ret;
}
}
}
return 0;
}
static struct platform_driver bd71828_regulator = {
.driver = {
.name = "bd71828-pmic"
},
.probe = bd71828_probe,
};
module_platform_driver(bd71828_regulator);
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
MODULE_DESCRIPTION("BD71828 voltage regulator driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:bd71828-pmic");

Просмотреть файл

@ -1142,28 +1142,14 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
},
};
struct bd718xx_pmic_inits {
const struct bd718xx_regulator_data *r_datas;
unsigned int r_amount;
};
static int bd718xx_probe(struct platform_device *pdev)
{
struct bd718xx *mfd;
struct regulator_config config = { 0 };
struct bd718xx_pmic_inits pmic_regulators[ROHM_CHIP_TYPE_AMOUNT] = {
[ROHM_CHIP_TYPE_BD71837] = {
.r_datas = bd71837_regulators,
.r_amount = ARRAY_SIZE(bd71837_regulators),
},
[ROHM_CHIP_TYPE_BD71847] = {
.r_datas = bd71847_regulators,
.r_amount = ARRAY_SIZE(bd71847_regulators),
},
};
int i, j, err;
bool use_snvs;
const struct bd718xx_regulator_data *reg_data;
unsigned int num_reg_data;
mfd = dev_get_drvdata(pdev->dev.parent);
if (!mfd) {
@ -1172,8 +1158,16 @@ static int bd718xx_probe(struct platform_device *pdev)
goto err;
}
if (mfd->chip.chip_type >= ROHM_CHIP_TYPE_AMOUNT ||
!pmic_regulators[mfd->chip.chip_type].r_datas) {
switch (mfd->chip.chip_type) {
case ROHM_CHIP_TYPE_BD71837:
reg_data = bd71837_regulators;
num_reg_data = ARRAY_SIZE(bd71837_regulators);
break;
case ROHM_CHIP_TYPE_BD71847:
reg_data = bd71847_regulators;
num_reg_data = ARRAY_SIZE(bd71847_regulators);
break;
default:
dev_err(&pdev->dev, "Unsupported chip type\n");
err = -EINVAL;
goto err;
@ -1215,13 +1209,13 @@ static int bd718xx_probe(struct platform_device *pdev)
}
}
for (i = 0; i < pmic_regulators[mfd->chip.chip_type].r_amount; i++) {
for (i = 0; i < num_reg_data; i++) {
const struct regulator_desc *desc;
struct regulator_dev *rdev;
const struct bd718xx_regulator_data *r;
r = &pmic_regulators[mfd->chip.chip_type].r_datas[i];
r = &reg_data[i];
desc = &r->desc;
config.dev = pdev->dev.parent;

Просмотреть файл

@ -3470,6 +3470,7 @@ int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
out:
return ret;
}
EXPORT_SYMBOL_GPL(regulator_set_voltage_rdev);
static int regulator_limit_voltage_step(struct regulator_dev *rdev,
int *current_uV, int *min_uV)
@ -4034,6 +4035,7 @@ int regulator_get_voltage_rdev(struct regulator_dev *rdev)
return ret;
return ret - rdev->constraints->uV_offset;
}
EXPORT_SYMBOL_GPL(regulator_get_voltage_rdev);
/**
* regulator_get_voltage - get regulator output voltage

Просмотреть файл

@ -131,8 +131,7 @@ static const struct of_device_id da9210_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, da9210_dt_ids);
static int da9210_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int da9210_i2c_probe(struct i2c_client *i2c)
{
struct da9210 *chip;
struct device *dev = &i2c->dev;
@ -228,7 +227,7 @@ static struct i2c_driver da9210_regulator_driver = {
.name = "da9210",
.of_match_table = of_match_ptr(da9210_dt_ids),
},
.probe = da9210_i2c_probe,
.probe_new = da9210_i2c_probe,
.id_table = da9210_i2c_id,
};

Просмотреть файл

@ -416,8 +416,7 @@ static int da9211_regulator_init(struct da9211 *chip)
/*
* I2C driver interface functions
*/
static int da9211_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int da9211_i2c_probe(struct i2c_client *i2c)
{
struct da9211 *chip;
int error, ret;
@ -526,7 +525,7 @@ static struct i2c_driver da9211_regulator_driver = {
.name = "da9211",
.of_match_table = of_match_ptr(da9211_dt_ids),
},
.probe = da9211_i2c_probe,
.probe_new = da9211_i2c_probe,
.id_table = da9211_i2c_id,
};

Просмотреть файл

@ -13,6 +13,8 @@
#include <linux/regulator/driver.h>
#include <linux/module.h>
#include "internal.h"
/**
* regulator_is_enabled_regmap - standard is_enabled() for regmap users
*
@ -881,3 +883,15 @@ void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
consumers[i].supply = supply_names[i];
}
EXPORT_SYMBOL_GPL(regulator_bulk_set_supply_names);
/**
* regulator_is_equal - test whether two regulators are the same
*
* @reg1: first regulator to operate on
* @reg2: second regulator to operate on
*/
bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
{
return reg1->rdev == reg2->rdev;
}
EXPORT_SYMBOL_GPL(regulator_is_equal);

Просмотреть файл

@ -137,8 +137,7 @@ static const struct regmap_config isl9305_regmap = {
.cache_type = REGCACHE_RBTREE,
};
static int isl9305_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int isl9305_i2c_probe(struct i2c_client *i2c)
{
struct regulator_config config = { };
struct isl9305_pdata *pdata = i2c->dev.platform_data;
@ -198,7 +197,7 @@ static struct i2c_driver isl9305_regulator_driver = {
.name = "isl9305",
.of_match_table = of_match_ptr(isl9305_dt_ids),
},
.probe = isl9305_i2c_probe,
.probe_new = isl9305_i2c_probe,
.id_table = isl9305_i2c_id,
};

Просмотреть файл

@ -400,8 +400,7 @@ static int setup_regulators(struct lp3971 *lp3971,
return 0;
}
static int lp3971_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int lp3971_i2c_probe(struct i2c_client *i2c)
{
struct lp3971 *lp3971;
struct lp3971_platform_data *pdata = dev_get_platdata(&i2c->dev);
@ -449,7 +448,7 @@ static struct i2c_driver lp3971_i2c_driver = {
.driver = {
.name = "LP3971",
},
.probe = lp3971_i2c_probe,
.probe_new = lp3971_i2c_probe,
.id_table = lp3971_i2c_id,
};

Просмотреть файл

@ -301,8 +301,7 @@ static irqreturn_t ltc3676_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
static int ltc3676_regulator_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int ltc3676_regulator_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct regulator_init_data *init_data = dev_get_platdata(dev);
@ -380,7 +379,7 @@ static struct i2c_driver ltc3676_driver = {
.name = DRIVER_NAME,
.of_match_table = of_match_ptr(ltc3676_of_match),
},
.probe = ltc3676_regulator_probe,
.probe_new = ltc3676_regulator_probe,
.id_table = ltc3676_i2c_id,
};
module_i2c_driver(ltc3676_driver);

156
drivers/regulator/mp8859.c Normal file
Просмотреть файл

@ -0,0 +1,156 @@
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2019 five technologies GmbH
// Author: Markus Reichl <m.reichl@fivetechno.de>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/regulator/driver.h>
#include <linux/regmap.h>
#define VOL_MIN_IDX 0x00
#define VOL_MAX_IDX 0x7ff
/* Register definitions */
#define MP8859_VOUT_L_REG 0 //3 lo Bits
#define MP8859_VOUT_H_REG 1 //8 hi Bits
#define MP8859_VOUT_GO_REG 2
#define MP8859_IOUT_LIM_REG 3
#define MP8859_CTL1_REG 4
#define MP8859_CTL2_REG 5
#define MP8859_RESERVED1_REG 6
#define MP8859_RESERVED2_REG 7
#define MP8859_RESERVED3_REG 8
#define MP8859_STATUS_REG 9
#define MP8859_INTERRUPT_REG 0x0A
#define MP8859_MASK_REG 0x0B
#define MP8859_ID1_REG 0x0C
#define MP8859_MFR_ID_REG 0x27
#define MP8859_DEV_ID_REG 0x28
#define MP8859_IC_REV_REG 0x29
#define MP8859_MAX_REG 0x29
#define MP8859_GO_BIT 0x01
static int mp8859_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
{
int ret;
ret = regmap_write(rdev->regmap, MP8859_VOUT_L_REG, sel & 0x7);
if (ret)
return ret;
ret = regmap_write(rdev->regmap, MP8859_VOUT_H_REG, sel >> 3);
if (ret)
return ret;
ret = regmap_update_bits(rdev->regmap, MP8859_VOUT_GO_REG,
MP8859_GO_BIT, 1);
return ret;
}
static int mp8859_get_voltage_sel(struct regulator_dev *rdev)
{
unsigned int val_tmp;
unsigned int val;
int ret;
ret = regmap_read(rdev->regmap, MP8859_VOUT_H_REG, &val_tmp);
if (ret)
return ret;
val = val_tmp << 3;
ret = regmap_read(rdev->regmap, MP8859_VOUT_L_REG, &val_tmp);
if (ret)
return ret;
val |= val_tmp & 0x07;
return val;
}
static const struct regulator_linear_range mp8859_dcdc_ranges[] = {
REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000),
};
static const struct regmap_config mp8859_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MP8859_MAX_REG,
.cache_type = REGCACHE_RBTREE,
};
static const struct regulator_ops mp8859_ops = {
.set_voltage_sel = mp8859_set_voltage_sel,
.get_voltage_sel = mp8859_get_voltage_sel,
.list_voltage = regulator_list_voltage_linear_range,
};
static const struct regulator_desc mp8859_regulators[] = {
{
.id = 0,
.type = REGULATOR_VOLTAGE,
.name = "mp8859_dcdc",
.of_match = of_match_ptr("mp8859_dcdc"),
.n_voltages = VOL_MAX_IDX + 1,
.linear_ranges = mp8859_dcdc_ranges,
.n_linear_ranges = 1,
.ops = &mp8859_ops,
.owner = THIS_MODULE,
},
};
static int mp8859_i2c_probe(struct i2c_client *i2c)
{
int ret;
struct regulator_config config = {.dev = &i2c->dev};
struct regmap *regmap = devm_regmap_init_i2c(i2c, &mp8859_regmap);
struct regulator_dev *rdev;
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
return ret;
}
rdev = devm_regulator_register(&i2c->dev, &mp8859_regulators[0],
&config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&i2c->dev, "failed to register %s: %d\n",
mp8859_regulators[0].name, ret);
return ret;
}
return 0;
}
static const struct of_device_id mp8859_dt_id[] = {
{.compatible = "mps,mp8859"},
{},
};
MODULE_DEVICE_TABLE(of, mp8859_dt_id);
static const struct i2c_device_id mp8859_i2c_id[] = {
{ "mp8859", },
{ },
};
MODULE_DEVICE_TABLE(i2c, mp8859_i2c_id);
static struct i2c_driver mp8859_regulator_driver = {
.driver = {
.name = "mp8859",
.of_match_table = of_match_ptr(mp8859_dt_id),
},
.probe_new = mp8859_i2c_probe,
.id_table = mp8859_i2c_id,
};
module_i2c_driver(mp8859_regulator_driver);
MODULE_DESCRIPTION("Monolithic Power Systems MP8859 voltage regulator driver");
MODULE_AUTHOR("Markus Reichl <m.reichl@fivetechno.de>");
MODULE_LICENSE("GPL v2");

330
drivers/regulator/mpq7920.c Normal file
Просмотреть файл

@ -0,0 +1,330 @@
// SPDX-License-Identifier: GPL-2.0+
//
// mpq7920.c - regulator driver for mps mpq7920
//
// Copyright 2019 Monolithic Power Systems, Inc
//
// Author: Saravanan Sekar <sravanhome@gmail.com>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include "mpq7920.h"
#define MPQ7920_BUCK_VOLT_RANGE \
((MPQ7920_VOLT_MAX - MPQ7920_BUCK_VOLT_MIN)/MPQ7920_VOLT_STEP + 1)
#define MPQ7920_LDO_VOLT_RANGE \
((MPQ7920_VOLT_MAX - MPQ7920_LDO_VOLT_MIN)/MPQ7920_VOLT_STEP + 1)
#define MPQ7920BUCK(_name, _id, _ilim) \
[MPQ7920_BUCK ## _id] = { \
.id = MPQ7920_BUCK ## _id, \
.name = _name, \
.of_match = _name, \
.regulators_node = "regulators", \
.of_parse_cb = mpq7920_parse_cb, \
.ops = &mpq7920_buck_ops, \
.min_uV = MPQ7920_BUCK_VOLT_MIN, \
.uV_step = MPQ7920_VOLT_STEP, \
.n_voltages = MPQ7920_BUCK_VOLT_RANGE, \
.curr_table = _ilim, \
.n_current_limits = ARRAY_SIZE(_ilim), \
.csel_reg = MPQ7920_BUCK ##_id## _REG_C, \
.csel_mask = MPQ7920_MASK_BUCK_ILIM, \
.enable_reg = MPQ7920_REG_REGULATOR_EN, \
.enable_mask = BIT(MPQ7920_REGULATOR_EN_OFFSET - \
MPQ7920_BUCK ## _id), \
.vsel_reg = MPQ7920_BUCK ##_id## _REG_A, \
.vsel_mask = MPQ7920_MASK_VREF, \
.active_discharge_on = MPQ7920_DISCHARGE_ON, \
.active_discharge_reg = MPQ7920_BUCK ##_id## _REG_B, \
.active_discharge_mask = MPQ7920_MASK_DISCHARGE, \
.soft_start_reg = MPQ7920_BUCK ##_id## _REG_C, \
.soft_start_mask = MPQ7920_MASK_SOFTSTART, \
.owner = THIS_MODULE, \
}
#define MPQ7920LDO(_name, _id, _ops, _ilim, _ilim_sz, _creg, _cmask) \
[MPQ7920_LDO ## _id] = { \
.id = MPQ7920_LDO ## _id, \
.name = _name, \
.of_match = _name, \
.regulators_node = "regulators", \
.ops = _ops, \
.min_uV = MPQ7920_LDO_VOLT_MIN, \
.uV_step = MPQ7920_VOLT_STEP, \
.n_voltages = MPQ7920_LDO_VOLT_RANGE, \
.vsel_reg = MPQ7920_LDO ##_id## _REG_A, \
.vsel_mask = MPQ7920_MASK_VREF, \
.curr_table = _ilim, \
.n_current_limits = _ilim_sz, \
.csel_reg = _creg, \
.csel_mask = _cmask, \
.enable_reg = (_id == 1) ? 0 : MPQ7920_REG_REGULATOR_EN,\
.enable_mask = BIT(MPQ7920_REGULATOR_EN_OFFSET - \
MPQ7920_LDO ##_id + 1), \
.active_discharge_on = MPQ7920_DISCHARGE_ON, \
.active_discharge_mask = MPQ7920_MASK_DISCHARGE, \
.active_discharge_reg = MPQ7920_LDO ##_id## _REG_B, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
enum mpq7920_regulators {
MPQ7920_BUCK1,
MPQ7920_BUCK2,
MPQ7920_BUCK3,
MPQ7920_BUCK4,
MPQ7920_LDO1, /* LDORTC */
MPQ7920_LDO2,
MPQ7920_LDO3,
MPQ7920_LDO4,
MPQ7920_LDO5,
MPQ7920_MAX_REGULATORS,
};
struct mpq7920_regulator_info {
struct regmap *regmap;
struct regulator_desc *rdesc;
};
static const struct regmap_config mpq7920_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x25,
};
/* Current limits array (in uA)
* ILIM1 & ILIM3
*/
static const unsigned int mpq7920_I_limits1[] = {
4600000, 6600000, 7600000, 9300000
};
/* ILIM2 & ILIM4 */
static const unsigned int mpq7920_I_limits2[] = {
2700000, 3900000, 5100000, 6100000
};
/* LDO4 & LDO5 */
static const unsigned int mpq7920_I_limits3[] = {
300000, 700000
};
static int mpq7920_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay);
static int mpq7920_parse_cb(struct device_node *np,
const struct regulator_desc *rdesc,
struct regulator_config *config);
/* RTCLDO not controllable, always ON */
static const struct regulator_ops mpq7920_ldortc_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static const struct regulator_ops mpq7920_ldo_wo_current_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
};
static const struct regulator_ops mpq7920_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
};
static const struct regulator_ops mpq7920_buck_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
.set_soft_start = regulator_set_soft_start_regmap,
.set_ramp_delay = mpq7920_set_ramp_delay,
};
static struct regulator_desc mpq7920_regulators_desc[MPQ7920_MAX_REGULATORS] = {
MPQ7920BUCK("buck1", 1, mpq7920_I_limits1),
MPQ7920BUCK("buck2", 2, mpq7920_I_limits2),
MPQ7920BUCK("buck3", 3, mpq7920_I_limits1),
MPQ7920BUCK("buck4", 4, mpq7920_I_limits2),
MPQ7920LDO("ldortc", 1, &mpq7920_ldortc_ops, NULL, 0, 0, 0),
MPQ7920LDO("ldo2", 2, &mpq7920_ldo_wo_current_ops, NULL, 0, 0, 0),
MPQ7920LDO("ldo3", 3, &mpq7920_ldo_wo_current_ops, NULL, 0, 0, 0),
MPQ7920LDO("ldo4", 4, &mpq7920_ldo_ops, mpq7920_I_limits3,
ARRAY_SIZE(mpq7920_I_limits3), MPQ7920_LDO4_REG_B,
MPQ7920_MASK_LDO_ILIM),
MPQ7920LDO("ldo5", 5, &mpq7920_ldo_ops, mpq7920_I_limits3,
ARRAY_SIZE(mpq7920_I_limits3), MPQ7920_LDO5_REG_B,
MPQ7920_MASK_LDO_ILIM),
};
/*
* DVS ramp rate BUCK1 to BUCK4
* 00-01: Reserved
* 10: 8mV/us
* 11: 4mV/us
*/
static int mpq7920_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_val;
if (ramp_delay > 8000 || ramp_delay < 0)
return -EINVAL;
if (ramp_delay <= 4000)
ramp_val = 3;
else
ramp_val = 2;
return regmap_update_bits(rdev->regmap, MPQ7920_REG_CTL0,
MPQ7920_MASK_DVS_SLEWRATE, ramp_val << 6);
}
static int mpq7920_parse_cb(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *config)
{
uint8_t val;
int ret;
struct mpq7920_regulator_info *info = config->driver_data;
struct regulator_desc *rdesc = &info->rdesc[desc->id];
if (of_property_read_bool(np, "mps,buck-ovp-disable")) {
regmap_update_bits(config->regmap,
MPQ7920_BUCK1_REG_B + (rdesc->id * 4),
MPQ7920_MASK_OVP, MPQ7920_OVP_DISABLE);
}
ret = of_property_read_u8(np, "mps,buck-phase-delay", &val);
if (!ret) {
regmap_update_bits(config->regmap,
MPQ7920_BUCK1_REG_C + (rdesc->id * 4),
MPQ7920_MASK_BUCK_PHASE_DEALY,
(val & 3) << 4);
}
ret = of_property_read_u8(np, "mps,buck-softstart", &val);
if (!ret)
rdesc->soft_start_val_on = (val & 3) << 2;
return 0;
}
static void mpq7920_parse_dt(struct device *dev,
struct mpq7920_regulator_info *info)
{
int ret;
struct device_node *np = dev->of_node;
uint8_t freq;
np = of_get_child_by_name(np, "regulators");
if (!np) {
dev_err(dev, "missing 'regulators' subnode in DT\n");
return;
}
ret = of_property_read_u8(np, "mps,switch-freq", &freq);
if (!ret) {
regmap_update_bits(info->regmap, MPQ7920_REG_CTL0,
MPQ7920_MASK_SWITCH_FREQ,
(freq & 3) << 4);
}
of_node_put(np);
}
static int mpq7920_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct mpq7920_regulator_info *info;
struct regulator_config config = { NULL, };
struct regulator_dev *rdev;
struct regmap *regmap;
int i;
info = devm_kzalloc(dev, sizeof(struct mpq7920_regulator_info),
GFP_KERNEL);
if (!info)
return -ENOMEM;
info->rdesc = mpq7920_regulators_desc;
regmap = devm_regmap_init_i2c(client, &mpq7920_regmap_config);
if (IS_ERR(regmap)) {
dev_err(dev, "Failed to allocate regmap!\n");
return PTR_ERR(regmap);
}
i2c_set_clientdata(client, info);
info->regmap = regmap;
if (client->dev.of_node)
mpq7920_parse_dt(&client->dev, info);
config.dev = dev;
config.regmap = regmap;
config.driver_data = info;
for (i = 0; i < MPQ7920_MAX_REGULATORS; i++) {
rdev = devm_regulator_register(dev,
&mpq7920_regulators_desc[i],
&config);
if (IS_ERR(rdev)) {
dev_err(dev, "Failed to register regulator!\n");
return PTR_ERR(rdev);
}
}
return 0;
}
static const struct of_device_id mpq7920_of_match[] = {
{ .compatible = "mps,mpq7920"},
{},
};
MODULE_DEVICE_TABLE(of, mpq7920_of_match);
static const struct i2c_device_id mpq7920_id[] = {
{ "mpq7920", },
{ },
};
MODULE_DEVICE_TABLE(i2c, mpq7920_id);
static struct i2c_driver mpq7920_regulator_driver = {
.driver = {
.name = "mpq7920",
.of_match_table = of_match_ptr(mpq7920_of_match),
},
.probe_new = mpq7920_i2c_probe,
.id_table = mpq7920_id,
};
module_i2c_driver(mpq7920_regulator_driver);
MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>");
MODULE_DESCRIPTION("MPQ7920 PMIC regulator driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -0,0 +1,69 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* mpq7920.h - Regulator definitions for mpq7920
*
* Copyright 2019 Monolithic Power Systems, Inc
*
*/
#ifndef __MPQ7920_H__
#define __MPQ7920_H__
#define MPQ7920_REG_CTL0 0x00
#define MPQ7920_REG_CTL1 0x01
#define MPQ7920_REG_CTL2 0x02
#define MPQ7920_BUCK1_REG_A 0x03
#define MPQ7920_BUCK1_REG_B 0x04
#define MPQ7920_BUCK1_REG_C 0x05
#define MPQ7920_BUCK1_REG_D 0x06
#define MPQ7920_BUCK2_REG_A 0x07
#define MPQ7920_BUCK2_REG_B 0x08
#define MPQ7920_BUCK2_REG_C 0x09
#define MPQ7920_BUCK2_REG_D 0x0a
#define MPQ7920_BUCK3_REG_A 0x0b
#define MPQ7920_BUCK3_REG_B 0x0c
#define MPQ7920_BUCK3_REG_C 0x0d
#define MPQ7920_BUCK3_REG_D 0x0e
#define MPQ7920_BUCK4_REG_A 0x0f
#define MPQ7920_BUCK4_REG_B 0x10
#define MPQ7920_BUCK4_REG_C 0x11
#define MPQ7920_BUCK4_REG_D 0x12
#define MPQ7920_LDO1_REG_A 0x13
#define MPQ7920_LDO1_REG_B 0x0
#define MPQ7920_LDO2_REG_A 0x14
#define MPQ7920_LDO2_REG_B 0x15
#define MPQ7920_LDO2_REG_C 0x16
#define MPQ7920_LDO3_REG_A 0x17
#define MPQ7920_LDO3_REG_B 0x18
#define MPQ7920_LDO3_REG_C 0x19
#define MPQ7920_LDO4_REG_A 0x1a
#define MPQ7920_LDO4_REG_B 0x1b
#define MPQ7920_LDO4_REG_C 0x1c
#define MPQ7920_LDO5_REG_A 0x1d
#define MPQ7920_LDO5_REG_B 0x1e
#define MPQ7920_LDO5_REG_C 0x1f
#define MPQ7920_REG_MODE 0x20
#define MPQ7920_REG_REGULATOR_EN 0x22
#define MPQ7920_MASK_VREF 0x7f
#define MPQ7920_MASK_BUCK_ILIM 0xc0
#define MPQ7920_MASK_LDO_ILIM BIT(6)
#define MPQ7920_MASK_DISCHARGE BIT(5)
#define MPQ7920_MASK_MODE 0xc0
#define MPQ7920_MASK_SOFTSTART 0x0c
#define MPQ7920_MASK_SWITCH_FREQ 0x30
#define MPQ7920_MASK_BUCK_PHASE_DEALY 0x30
#define MPQ7920_MASK_DVS_SLEWRATE 0xc0
#define MPQ7920_MASK_OVP 0x40
#define MPQ7920_OVP_DISABLE ~(0x40)
#define MPQ7920_DISCHARGE_ON BIT(5)
#define MPQ7920_REGULATOR_EN_OFFSET 7
/* values in mV */
#define MPQ7920_BUCK_VOLT_MIN 400000
#define MPQ7920_LDO_VOLT_MIN 650000
#define MPQ7920_VOLT_MAX 3587500
#define MPQ7920_VOLT_STEP 12500
#endif /* __MPQ7920_H__ */

Просмотреть файл

@ -85,8 +85,7 @@ static const struct regulator_desc mt6311_regulators[] = {
/*
* I2C driver interface functions
*/
static int mt6311_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int mt6311_i2c_probe(struct i2c_client *i2c)
{
struct regulator_config config = { };
struct regulator_dev *rdev;
@ -154,7 +153,7 @@ static struct i2c_driver mt6311_regulator_driver = {
.name = "mt6311",
.of_match_table = of_match_ptr(mt6311_dt_ids),
},
.probe = mt6311_i2c_probe,
.probe_new = mt6311_i2c_probe,
.id_table = mt6311_i2c_id,
};

Просмотреть файл

@ -279,8 +279,7 @@ error_i2c:
/*
* I2C driver interface functions
*/
static int pv88060_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int pv88060_i2c_probe(struct i2c_client *i2c)
{
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
struct pv88060 *chip;
@ -385,7 +384,7 @@ static struct i2c_driver pv88060_regulator_driver = {
.name = "pv88060",
.of_match_table = of_match_ptr(pv88060_dt_ids),
},
.probe = pv88060_i2c_probe,
.probe_new = pv88060_i2c_probe,
.id_table = pv88060_i2c_id,
};

Просмотреть файл

@ -272,8 +272,7 @@ error_i2c:
/*
* I2C driver interface functions
*/
static int pv88090_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int pv88090_i2c_probe(struct i2c_client *i2c)
{
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
struct pv88090 *chip;
@ -406,7 +405,7 @@ static struct i2c_driver pv88090_regulator_driver = {
.name = "pv88090",
.of_match_table = of_match_ptr(pv88090_dt_ids),
},
.probe = pv88090_i2c_probe,
.probe_new = pv88090_i2c_probe,
.id_table = pv88090_i2c_id,
};

Просмотреть файл

@ -1282,7 +1282,7 @@ static int rk808_regulator_dt_parse_pdata(struct device *dev,
}
if (!pdata->dvs_gpio[i]) {
dev_warn(dev, "there is no dvs%d gpio\n", i);
dev_info(dev, "there is no dvs%d gpio\n", i);
continue;
}

Просмотреть файл

@ -390,5 +390,5 @@ module_platform_driver(s2mpa01_pmic_driver);
/* Module information */
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>");
MODULE_DESCRIPTION("SAMSUNG S2MPA01 Regulator Driver");
MODULE_DESCRIPTION("Samsung S2MPA01 Regulator Driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -1265,5 +1265,5 @@ module_platform_driver(s2mps11_pmic_driver);
/* Module information */
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver");
MODULE_DESCRIPTION("Samsung S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -1015,5 +1015,5 @@ module_exit(s5m8767_pmic_exit);
/* Module information */
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver");
MODULE_DESCRIPTION("Samsung S5M8767 Regulator Driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -439,8 +439,7 @@ static void slg51000_clear_fault_log(struct slg51000 *chip)
dev_dbg(chip->dev, "Fault log: FLT_POR\n");
}
static int slg51000_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int slg51000_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct slg51000 *chip;
@ -509,7 +508,7 @@ static struct i2c_driver slg51000_regulator_driver = {
.driver = {
.name = "slg51000-regulator",
},
.probe = slg51000_i2c_probe,
.probe_new = slg51000_i2c_probe,
.id_table = slg51000_i2c_id,
};

Просмотреть файл

@ -61,8 +61,7 @@ static const struct regulator_desc sy8106a_reg = {
/*
* I2C driver interface functions
*/
static int sy8106a_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int sy8106a_i2c_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct regulator_dev *rdev;
@ -141,7 +140,7 @@ static struct i2c_driver sy8106a_regulator_driver = {
.name = "sy8106a",
.of_match_table = of_match_ptr(sy8106a_i2c_of_match),
},
.probe = sy8106a_i2c_probe,
.probe_new = sy8106a_i2c_probe,
.id_table = sy8106a_i2c_id,
};

Просмотреть файл

@ -112,8 +112,7 @@ static const struct regmap_config sy8824_regmap_config = {
.val_bits = 8,
};
static int sy8824_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int sy8824_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct device_node *np = dev->of_node;
@ -222,7 +221,7 @@ static struct i2c_driver sy8824_regulator_driver = {
.name = "sy8824-regulator",
.of_match_table = of_match_ptr(sy8824_dt_ids),
},
.probe = sy8824_i2c_probe,
.probe_new = sy8824_i2c_probe,
.id_table = sy8824_id,
};
module_i2c_driver(sy8824_regulator_driver);

Просмотреть файл

@ -220,8 +220,7 @@ static const struct regmap_config tps65132_regmap_config = {
.wr_table = &tps65132_no_reg_table,
};
static int tps65132_probe(struct i2c_client *client,
const struct i2c_device_id *client_id)
static int tps65132_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct tps65132_regulator *tps;
@ -272,7 +271,7 @@ static struct i2c_driver tps65132_i2c_driver = {
.driver = {
.name = "tps65132",
},
.probe = tps65132_probe,
.probe_new = tps65132_probe,
.id_table = tps65132_id,
};

Просмотреть файл

@ -11,10 +11,13 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regulator/coupler.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/sort.h>
#include "internal.h"
struct vctrl_voltage_range {
int min_uV;
int max_uV;
@ -79,7 +82,7 @@ static int vctrl_calc_output_voltage(struct vctrl_data *vctrl, int ctrl_uV)
static int vctrl_get_voltage(struct regulator_dev *rdev)
{
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
int ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
int ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
return vctrl_calc_output_voltage(vctrl, ctrl_uV);
}
@ -90,16 +93,16 @@ static int vctrl_set_voltage(struct regulator_dev *rdev,
{
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
struct regulator *ctrl_reg = vctrl->ctrl_reg;
int orig_ctrl_uV = regulator_get_voltage(ctrl_reg);
int orig_ctrl_uV = regulator_get_voltage_rdev(ctrl_reg->rdev);
int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV);
int ret;
if (req_min_uV >= uV || !vctrl->ovp_threshold)
/* voltage rising or no OVP */
return regulator_set_voltage(
ctrl_reg,
return regulator_set_voltage_rdev(ctrl_reg->rdev,
vctrl_calc_ctrl_voltage(vctrl, req_min_uV),
vctrl_calc_ctrl_voltage(vctrl, req_max_uV));
vctrl_calc_ctrl_voltage(vctrl, req_max_uV),
PM_SUSPEND_ON);
while (uV > req_min_uV) {
int max_drop_uV = (uV * vctrl->ovp_threshold) / 100;
@ -114,9 +117,10 @@ static int vctrl_set_voltage(struct regulator_dev *rdev,
next_uV = max_t(int, req_min_uV, uV - max_drop_uV);
next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV);
ret = regulator_set_voltage(ctrl_reg,
ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
next_ctrl_uV,
next_ctrl_uV);
next_ctrl_uV,
PM_SUSPEND_ON);
if (ret)
goto err;
@ -130,7 +134,8 @@ static int vctrl_set_voltage(struct regulator_dev *rdev,
err:
/* Try to go back to original voltage */
regulator_set_voltage(ctrl_reg, orig_ctrl_uV, orig_ctrl_uV);
regulator_set_voltage_rdev(ctrl_reg->rdev, orig_ctrl_uV, orig_ctrl_uV,
PM_SUSPEND_ON);
return ret;
}
@ -155,9 +160,10 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
if (selector >= vctrl->sel || !vctrl->ovp_threshold) {
/* voltage rising or no OVP */
ret = regulator_set_voltage(ctrl_reg,
ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
vctrl->vtable[selector].ctrl,
vctrl->vtable[selector].ctrl);
vctrl->vtable[selector].ctrl,
PM_SUSPEND_ON);
if (!ret)
vctrl->sel = selector;
@ -173,9 +179,10 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
else
next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel;
ret = regulator_set_voltage(ctrl_reg,
ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
vctrl->vtable[next_sel].ctrl,
vctrl->vtable[next_sel].ctrl);
vctrl->vtable[next_sel].ctrl,
PM_SUSPEND_ON);
if (ret) {
dev_err(&rdev->dev,
"failed to set control voltage to %duV\n",
@ -195,9 +202,10 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
err:
if (vctrl->sel != orig_sel) {
/* Try to go back to original voltage */
if (!regulator_set_voltage(ctrl_reg,
if (!regulator_set_voltage_rdev(ctrl_reg->rdev,
vctrl->vtable[orig_sel].ctrl,
vctrl->vtable[orig_sel].ctrl))
vctrl->vtable[orig_sel].ctrl,
PM_SUSPEND_ON))
vctrl->sel = orig_sel;
else
dev_warn(&rdev->dev,
@ -482,7 +490,7 @@ static int vctrl_probe(struct platform_device *pdev)
if (ret)
return ret;
ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
if (ctrl_uV < 0) {
dev_err(&pdev->dev, "failed to get control voltage\n");
return ctrl_uV;

Просмотреть файл

@ -0,0 +1,101 @@
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (c) 2019 Mantas Pucka <mantas@8devices.com>
// Copyright (c) 2019 Robert Marko <robert.marko@sartura.hr>
//
// Driver for IPQ4019 SD/MMC controller's I/O LDO voltage regulator
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
static const unsigned int ipq4019_vmmc_voltages[] = {
1500000, 1800000, 2500000, 3000000,
};
static const struct regulator_ops ipq4019_regulator_voltage_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static const struct regulator_desc vmmc_regulator = {
.name = "vmmcq",
.ops = &ipq4019_regulator_voltage_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.volt_table = ipq4019_vmmc_voltages,
.n_voltages = ARRAY_SIZE(ipq4019_vmmc_voltages),
.vsel_reg = 0,
.vsel_mask = 0x3,
};
static const struct regmap_config ipq4019_vmmcq_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
};
static int ipq4019_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct regulator_init_data *init_data;
struct regulator_config cfg = {};
struct regulator_dev *rdev;
struct resource *res;
struct regmap *rmap;
void __iomem *base;
init_data = of_get_regulator_init_data(dev, dev->of_node,
&vmmc_regulator);
if (!init_data)
return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
rmap = devm_regmap_init_mmio(dev, base, &ipq4019_vmmcq_regmap_config);
if (IS_ERR(rmap))
return PTR_ERR(rmap);
cfg.dev = dev;
cfg.init_data = init_data;
cfg.of_node = dev->of_node;
cfg.regmap = rmap;
rdev = devm_regulator_register(dev, &vmmc_regulator, &cfg);
if (IS_ERR(rdev)) {
dev_err(dev, "Failed to register regulator: %ld\n",
PTR_ERR(rdev));
return PTR_ERR(rdev);
}
platform_set_drvdata(pdev, rdev);
return 0;
}
static const struct of_device_id regulator_ipq4019_of_match[] = {
{ .compatible = "qcom,vqmmc-ipq4019-regulator", },
{},
};
static struct platform_driver ipq4019_regulator_driver = {
.probe = ipq4019_regulator_probe,
.driver = {
.name = "vqmmc-ipq4019-regulator",
.of_match_table = of_match_ptr(regulator_ipq4019_of_match),
},
};
module_platform_driver(ipq4019_regulator_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mantas Pucka <mantas@8devices.com>");
MODULE_DESCRIPTION("IPQ4019 VQMMC voltage regulator");

Просмотреть файл

@ -287,6 +287,8 @@ void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
const char *const *supply_names,
unsigned int num_supplies);
bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2);
#else
/*
@ -593,6 +595,11 @@ regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
{
}
static inline bool
regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
{
return false;
}
#endif
static inline int regulator_set_voltage_triplet(struct regulator *regulator,