forked from Minki/linux
regulator: Updates for v5.8
The big change in this release is that Matti Vaittinen has factored out the linear ranges support into a separate library in lib/ since it is also useful for at least the power subsystem (and most likely others too), it helps subsystems which need to map register values into more useful real world values do so with minimal per-driver code. - Factoring out of the linear ranges support into a library in lib/ from Matti Vaittinen. - Trace points for bypass mode. - Use the consumer name in debugfs to make it easier to understand. - New drivers for Maxim MAX77826 and MAX8998. -----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAl7U8oETHGJyb29uaWVA a2VybmVsLm9yZwAKCRAk1otyXVSH0Fi+B/47cqB4/3uchKAXCHn4WE0hDANfeK4k SkyBl9OH/UC0I/+V/nFrl1CfZgPMm18MuXG+D6fO+qqd1Df7EIgtehxh3MOjD15m ZFFGybKBG2xg5G/dULE58/N5ZNTd03x8kgYePFmJEFe+m4qUvuICDEoOTHq+tvOO sgeZPKYuipmGNrUAV4l49SSPuTFBhvAIg5VoR+K9TxxWAacMu7JM7GuGUMij8XwR i1AryKGvDuCa7hfdWGVwbE+W/XmXiAWsmyz04YDXsYLTk9TjqviCJgf1Bst5EphP ACr+KMDUIl+Y06wd7DE1UYnXtIxQg/MQ6wlJxG+wtIiZUt2vZcP2pbT6 =w291 -----END PGP SIGNATURE----- Merge tag 'regulator-v5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator Pull regulator updates from Mark Brown: "The big change in this release is that Matti Vaittinen has factored out the linear ranges support into a separate library in lib/ since it is also useful for at least the power subsystem (and most likely others too), it helps subsystems which need to map register values into more useful real world values do so with minimal per-driver code. - Factoring out of the linear ranges support into a library in lib/ from Matti Vaittinen. - Trace points for bypass mode. - Use the consumer name in debugfs to make it easier to understand. - New drivers for Maxim MAX77826 and MAX8998" * tag 'regulator-v5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (23 commits) regulator: max8998: max8998_set_current_limit() can be static dt-bindings: regulator: Convert anatop regulator to json-schema regulator: core: Add regulator bypass trace points regulator: extract voltage balancing code to the separate function regulator/mfd: max8998: Document charger regulator regulator: max8998: Add charger regulator MAINTAINERS: Add maintainer entry for linear ranges helper regulator: bd718x7: remove voltage change restriction from BD71847 LDOs lib: linear_ranges: Add missing MODULE_LICENSE() regulator: use linear_ranges helper power: supply: bd70528: rename linear_range to avoid collision lib/test_linear_ranges: add a test for the 'linear_ranges' lib: add linear ranges helpers regulator: db8500-prcmu: Use true,false for bool variable regulator: bd718x7: remove voltage change restriction from BD71847 regulator: max77826: Remove erroneous additionalProperties regulator: qcom-rpmh: Fix typos in pm8150 and pm8150l regulator: Document bindings for max77826 regulator: max77826: Add max77826 regulator driver regulator: tps80031: remove redundant assignment to variables ret and val ...
This commit is contained in:
commit
d30fc97c60
@ -73,6 +73,8 @@ number as described in MAX8998 datasheet.
|
||||
- ESAFEOUT1: (ldo19)
|
||||
- ESAFEOUT2: (ld020)
|
||||
|
||||
- CHARGER: main battery charger current control
|
||||
|
||||
Standard regulator bindings are used inside regulator subnodes. Check
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
for more details.
|
||||
@ -113,5 +115,11 @@ Example:
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
charger_reg: CHARGER {
|
||||
regulator-name = "CHARGER";
|
||||
regulator-min-microamp = <90000>;
|
||||
regulator-max-microamp = <800000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,40 +0,0 @@
|
||||
Anatop Voltage regulators
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "fsl,anatop-regulator"
|
||||
- regulator-name: A string used as a descriptive name for regulator outputs
|
||||
- anatop-reg-offset: Anatop MFD register offset
|
||||
- anatop-vol-bit-shift: Bit shift for the register
|
||||
- anatop-vol-bit-width: Number of bits used in the register
|
||||
- anatop-min-bit-val: Minimum value of this register
|
||||
- anatop-min-voltage: Minimum voltage of this regulator
|
||||
- anatop-max-voltage: Maximum voltage of this regulator
|
||||
|
||||
Optional properties:
|
||||
- anatop-delay-reg-offset: Anatop MFD step time register offset
|
||||
- anatop-delay-bit-shift: Bit shift for the step time register
|
||||
- anatop-delay-bit-width: Number of bits used in the step time register
|
||||
- vin-supply: The supply for this regulator
|
||||
- anatop-enable-bit: Regulator enable bit offset
|
||||
|
||||
Any property defined as part of the core regulator
|
||||
binding, defined in regulator.txt, can also be used.
|
||||
|
||||
Example:
|
||||
|
||||
regulator-vddpu {
|
||||
compatible = "fsl,anatop-regulator";
|
||||
regulator-name = "vddpu";
|
||||
regulator-min-microvolt = <725000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-always-on;
|
||||
anatop-reg-offset = <0x140>;
|
||||
anatop-vol-bit-shift = <9>;
|
||||
anatop-vol-bit-width = <5>;
|
||||
anatop-delay-reg-offset = <0x170>;
|
||||
anatop-delay-bit-shift = <24>;
|
||||
anatop-delay-bit-width = <2>;
|
||||
anatop-min-bit-val = <1>;
|
||||
anatop-min-voltage = <725000>;
|
||||
anatop-max-voltage = <1300000>;
|
||||
};
|
@ -0,0 +1,94 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/anatop-regulator.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale Anatop Voltage Regulators
|
||||
|
||||
maintainers:
|
||||
- Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
|
||||
|
||||
allOf:
|
||||
- $ref: "regulator.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: fsl,anatop-regulator
|
||||
|
||||
regulator-name: true
|
||||
|
||||
anatop-reg-offset:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing the anatop MFD register offset.
|
||||
|
||||
anatop-vol-bit-shift:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing the bit shift for the register.
|
||||
|
||||
anatop-vol-bit-width:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing the number of bits used in the register.
|
||||
|
||||
anatop-min-bit-val:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing the minimum value of this register.
|
||||
|
||||
anatop-min-voltage:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing the minimum voltage of this regulator.
|
||||
|
||||
anatop-max-voltage:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing the maximum voltage of this regulator.
|
||||
|
||||
anatop-delay-reg-offset:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing the anatop MFD step time register offset.
|
||||
|
||||
anatop-delay-bit-shift:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing the bit shift for the step time register.
|
||||
|
||||
anatop-delay-bit-width:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing the number of bits used in the step time register.
|
||||
|
||||
anatop-enable-bit:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: u32 value representing regulator enable bit offset.
|
||||
|
||||
vin-supply:
|
||||
$ref: '/schemas/types.yaml#/definitions/phandle'
|
||||
description: input supply phandle.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- regulator-name
|
||||
- anatop-reg-offset
|
||||
- anatop-vol-bit-shift
|
||||
- anatop-vol-bit-width
|
||||
- anatop-min-bit-val
|
||||
- anatop-min-voltage
|
||||
- anatop-max-voltage
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
regulator-vddpu {
|
||||
compatible = "fsl,anatop-regulator";
|
||||
regulator-name = "vddpu";
|
||||
regulator-min-microvolt = <725000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-always-on;
|
||||
anatop-reg-offset = <0x140>;
|
||||
anatop-vol-bit-shift = <9>;
|
||||
anatop-vol-bit-width = <5>;
|
||||
anatop-delay-reg-offset = <0x170>;
|
||||
anatop-delay-bit-shift = <24>;
|
||||
anatop-delay-bit-width = <2>;
|
||||
anatop-min-bit-val = <1>;
|
||||
anatop-min-voltage = <725000>;
|
||||
anatop-max-voltage = <1300000>;
|
||||
};
|
@ -0,0 +1,68 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/maxim,max77826.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Maxim Integrated MAX77826 PMIC
|
||||
|
||||
maintainers:
|
||||
- Iskren Chernev <iskren.chernev@gmail.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "pmic@[0-9a-f]{1,2}"
|
||||
compatible:
|
||||
enum:
|
||||
- maxim,max77826
|
||||
|
||||
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 LDO[1-15], BUCK and BUCKBOOST
|
||||
|
||||
patternProperties:
|
||||
"^LDO([1-9]|1[0-5])$":
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
|
||||
"^BUCK|BUCKBOOST$":
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- regulators
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic@69 {
|
||||
compatible = "maxim,max77826";
|
||||
reg = <0x69>;
|
||||
|
||||
regulators {
|
||||
LDO2 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <3587500>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -9748,6 +9748,13 @@ F: drivers/lightnvm/
|
||||
F: include/linux/lightnvm.h
|
||||
F: include/uapi/linux/lightnvm.h
|
||||
|
||||
LINEAR RANGES HELPERS
|
||||
M: Mark Brown <broonie@kernel.org>
|
||||
R: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
F: lib/linear_ranges.c
|
||||
F: lib/test_linear_ranges.c
|
||||
F: include/linux/linear_range.h
|
||||
|
||||
LINUX FOR POWER MACINTOSH
|
||||
M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
|
@ -335,14 +335,14 @@ static int bd70528_get_present(struct bd70528_psy *bdpsy, int *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct linear_range {
|
||||
struct bd70528_linear_range {
|
||||
int min;
|
||||
int step;
|
||||
int vals;
|
||||
int low_sel;
|
||||
};
|
||||
|
||||
static const struct linear_range current_limit_ranges[] = {
|
||||
static const struct bd70528_linear_range current_limit_ranges[] = {
|
||||
{
|
||||
.min = 5,
|
||||
.step = 1,
|
||||
@ -374,7 +374,7 @@ static const struct linear_range current_limit_ranges[] = {
|
||||
* voltage for low temperatures. The driver currently only reads
|
||||
* the charge current at room temperature. We do set both though.
|
||||
*/
|
||||
static const struct linear_range warm_charge_curr[] = {
|
||||
static const struct bd70528_linear_range warm_charge_curr[] = {
|
||||
{
|
||||
.min = 10,
|
||||
.step = 10,
|
||||
@ -398,7 +398,7 @@ static const struct linear_range warm_charge_curr[] = {
|
||||
#define MAX_WARM_CHG_CURR_SEL 0x1f
|
||||
#define MIN_CHG_CURR_SEL 0x0
|
||||
|
||||
static int find_value_for_selector_low(const struct linear_range *r,
|
||||
static int find_value_for_selector_low(const struct bd70528_linear_range *r,
|
||||
int selectors, unsigned int sel,
|
||||
unsigned int *val)
|
||||
{
|
||||
@ -420,7 +420,7 @@ static int find_value_for_selector_low(const struct linear_range *r,
|
||||
* I guess it is enough if we use voltage/current which is closest (below)
|
||||
* the requested?
|
||||
*/
|
||||
static int find_selector_for_value_low(const struct linear_range *r,
|
||||
static int find_selector_for_value_low(const struct bd70528_linear_range *r,
|
||||
int selectors, unsigned int val,
|
||||
unsigned int *sel, bool *found)
|
||||
{
|
||||
|
@ -11,13 +11,13 @@ static const struct regulator_ops pg86x_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range pg86x_buck1_ranges[] = {
|
||||
static const struct linear_range pg86x_buck1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE( 0, 0, 10, 0),
|
||||
REGULATOR_LINEAR_RANGE(1000000, 11, 34, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1600000, 35, 47, 50000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range pg86x_buck2_ranges[] = {
|
||||
static const struct linear_range pg86x_buck2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE( 0, 0, 15, 0),
|
||||
REGULATOR_LINEAR_RANGE(1000000, 16, 39, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1600000, 40, 52, 50000),
|
||||
|
@ -134,13 +134,13 @@ struct pm800_regulator_info {
|
||||
}
|
||||
|
||||
/* Ranges are sorted in ascending order. */
|
||||
static const struct regulator_linear_range buck1_volt_range[] = {
|
||||
static const struct linear_range buck1_volt_range[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x54, 50000),
|
||||
};
|
||||
|
||||
/* BUCK 2~5 have same ranges. */
|
||||
static const struct regulator_linear_range buck2_5_volt_range[] = {
|
||||
static const struct linear_range buck2_5_volt_range[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x72, 50000),
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
menuconfig REGULATOR
|
||||
bool "Voltage and Current Regulator Support"
|
||||
select LINEAR_RANGES
|
||||
help
|
||||
Generic Voltage and Current Regulator support.
|
||||
|
||||
@ -585,6 +586,16 @@ config REGULATOR_MAX77802
|
||||
Exynos5420/Exynos5800 SoCs to control various voltages.
|
||||
It includes support for control of voltage and ramp speed.
|
||||
|
||||
config REGULATOR_MAX77826
|
||||
tristate "Maxim 77826 regulator"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver controls a Maxim 77826 regulator via I2C bus.
|
||||
The regulator include 15 LDOs, BUCK and BUCK BOOST regulator.
|
||||
It includes support for control of output voltage. This
|
||||
regulator is found on the Samsung Galaxy S5 (klte) smartphone.
|
||||
|
||||
config REGULATOR_MC13XXX_CORE
|
||||
tristate
|
||||
|
||||
|
@ -74,6 +74,7 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
|
||||
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_MC13783) += mc13783-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
|
||||
|
@ -139,17 +139,6 @@ static const unsigned int ldo_vintcore_voltages[] = {
|
||||
1350000,
|
||||
};
|
||||
|
||||
static const unsigned int ldo_sdio_voltages[] = {
|
||||
1160000,
|
||||
1050000,
|
||||
1100000,
|
||||
1500000,
|
||||
1800000,
|
||||
2200000,
|
||||
2910000,
|
||||
3050000,
|
||||
};
|
||||
|
||||
static const unsigned int fixed_1200000_voltage[] = {
|
||||
1200000,
|
||||
};
|
||||
@ -166,10 +155,6 @@ static const unsigned int fixed_2050000_voltage[] = {
|
||||
2050000,
|
||||
};
|
||||
|
||||
static const unsigned int fixed_3300000_voltage[] = {
|
||||
3300000,
|
||||
};
|
||||
|
||||
static const unsigned int ldo_vana_voltages[] = {
|
||||
1050000,
|
||||
1075000,
|
||||
@ -192,13 +177,6 @@ static const unsigned int ldo_vaudio_voltages[] = {
|
||||
2600000, /* Duplicated in Vaudio and IsoUicc Control register. */
|
||||
};
|
||||
|
||||
static const unsigned int ldo_vdmic_voltages[] = {
|
||||
1800000,
|
||||
1900000,
|
||||
2000000,
|
||||
2850000,
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(shared_mode_mutex);
|
||||
static struct ab8500_shared_mode ldo_anamic1_shared;
|
||||
static struct ab8500_shared_mode ldo_anamic2_shared;
|
||||
|
@ -220,13 +220,13 @@ static const struct regmap_config act8865_regmap_config = {
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range act8865_voltage_ranges[] = {
|
||||
static const struct linear_range act8865_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000),
|
||||
REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = {
|
||||
static const struct linear_range act8600_sudcdc_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(3000000, 0, 63, 0),
|
||||
REGULATOR_LINEAR_RANGE(3000000, 64, 159, 100000),
|
||||
REGULATOR_LINEAR_RANGE(12600000, 160, 191, 200000),
|
||||
|
@ -73,7 +73,7 @@ struct act8945a_pmic {
|
||||
u32 op_mode[ACT8945A_ID_MAX];
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range act8945a_voltage_ranges[] = {
|
||||
static const struct linear_range act8945a_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000),
|
||||
REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
|
||||
|
@ -87,7 +87,7 @@ static const struct regulator_ops arizona_ldo1_hc_ops = {
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range arizona_ldo1_hc_ranges[] = {
|
||||
static const struct linear_range arizona_ldo1_hc_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 0x6, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0x7, 0x7, 0),
|
||||
};
|
||||
|
@ -125,7 +125,7 @@ static const struct regulator_ops arizona_micsupp_ops = {
|
||||
.set_bypass = arizona_micsupp_set_bypass,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range arizona_micsupp_ranges[] = {
|
||||
static const struct linear_range arizona_micsupp_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 0x1e, 50000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 0x1f, 0x1f, 0),
|
||||
};
|
||||
@ -152,7 +152,7 @@ static const struct regulator_desc arizona_micsupp = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range arizona_micsupp_ext_ranges[] = {
|
||||
static const struct linear_range arizona_micsupp_ext_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 0x14, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 0x15, 0x27, 100000),
|
||||
};
|
||||
|
@ -103,18 +103,18 @@ static const struct regulator_ops as3711_dldo_ops = {
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range as3711_sd_ranges[] = {
|
||||
static const struct linear_range as3711_sd_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(612500, 0x1, 0x40, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000),
|
||||
REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7f, 50000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range as3711_aldo_ranges[] = {
|
||||
static const struct linear_range as3711_aldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1200000, 0, 0xf, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0x10, 0x1f, 100000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range as3711_dldo_ranges[] = {
|
||||
static const struct linear_range as3711_dldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 0x10, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1750000, 0x20, 0x3f, 50000),
|
||||
};
|
||||
|
@ -389,7 +389,7 @@ static const struct regulator_ops as3722_ldo6_extcntrl_ops = {
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range as3722_ldo_ranges[] = {
|
||||
static const struct linear_range as3722_ldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0),
|
||||
REGULATOR_LINEAR_RANGE(825000, 0x01, 0x24, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1725000, 0x40, 0x7F, 25000),
|
||||
@ -487,7 +487,7 @@ static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs)
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range as3722_sd2345_ranges[] = {
|
||||
static const struct linear_range as3722_sd2345_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0),
|
||||
REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000),
|
||||
|
@ -510,7 +510,7 @@ static const struct regulator_ops axp20x_ops_sw = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range axp20x_ldo4_ranges[] = {
|
||||
static const struct linear_range axp20x_ldo4_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1250000,
|
||||
AXP20X_LDO4_V_OUT_1250mV_START,
|
||||
AXP20X_LDO4_V_OUT_1250mV_END,
|
||||
@ -638,7 +638,7 @@ static const struct regulator_desc axp22x_drivevbus_regulator = {
|
||||
};
|
||||
|
||||
/* DCDC ranges shared with AXP813 */
|
||||
static const struct regulator_linear_range axp803_dcdc234_ranges[] = {
|
||||
static const struct linear_range axp803_dcdc234_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000,
|
||||
AXP803_DCDC234_500mV_START,
|
||||
AXP803_DCDC234_500mV_END,
|
||||
@ -649,7 +649,7 @@ static const struct regulator_linear_range axp803_dcdc234_ranges[] = {
|
||||
20000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range axp803_dcdc5_ranges[] = {
|
||||
static const struct linear_range axp803_dcdc5_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000,
|
||||
AXP803_DCDC5_800mV_START,
|
||||
AXP803_DCDC5_800mV_END,
|
||||
@ -660,7 +660,7 @@ static const struct regulator_linear_range axp803_dcdc5_ranges[] = {
|
||||
20000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range axp803_dcdc6_ranges[] = {
|
||||
static const struct linear_range axp803_dcdc6_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000,
|
||||
AXP803_DCDC6_600mV_START,
|
||||
AXP803_DCDC6_600mV_END,
|
||||
@ -672,7 +672,7 @@ static const struct regulator_linear_range axp803_dcdc6_ranges[] = {
|
||||
};
|
||||
|
||||
/* AXP806's CLDO2 and AXP809's DLDO1 share the same range */
|
||||
static const struct regulator_linear_range axp803_dldo2_ranges[] = {
|
||||
static const struct linear_range axp803_dldo2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(700000,
|
||||
AXP803_DLDO2_700mV_START,
|
||||
AXP803_DLDO2_700mV_END,
|
||||
@ -758,7 +758,7 @@ static const struct regulator_desc axp803_regulators[] = {
|
||||
AXP_DESC_FIXED(AXP803, RTC_LDO, "rtc-ldo", "ips", 3000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range axp806_dcdca_ranges[] = {
|
||||
static const struct linear_range axp806_dcdca_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000,
|
||||
AXP806_DCDCA_600mV_START,
|
||||
AXP806_DCDCA_600mV_END,
|
||||
@ -769,7 +769,7 @@ static const struct regulator_linear_range axp806_dcdca_ranges[] = {
|
||||
20000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range axp806_dcdcd_ranges[] = {
|
||||
static const struct linear_range axp806_dcdcd_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000,
|
||||
AXP806_DCDCD_600mV_START,
|
||||
AXP806_DCDCD_600mV_END,
|
||||
@ -834,7 +834,7 @@ static const struct regulator_desc axp806_regulators[] = {
|
||||
AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_SW_MASK),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range axp809_dcdc4_ranges[] = {
|
||||
static const struct linear_range axp809_dcdc4_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000,
|
||||
AXP809_DCDC4_600mV_START,
|
||||
AXP809_DCDC4_600mV_END,
|
||||
|
@ -116,14 +116,14 @@ static const unsigned int ldo_vbus[] = {
|
||||
};
|
||||
|
||||
/* DCDC group CSR: supported voltages in microvolts */
|
||||
static const struct regulator_linear_range dcdc_csr_ranges[] = {
|
||||
static const struct linear_range dcdc_csr_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000),
|
||||
REGULATOR_LINEAR_RANGE(900000, 56, 63, 0),
|
||||
};
|
||||
|
||||
/* DCDC group IOSR1: supported voltages in microvolts */
|
||||
static const struct regulator_linear_range dcdc_iosr1_ranges[] = {
|
||||
static const struct linear_range dcdc_iosr1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0),
|
||||
@ -131,7 +131,7 @@ static const struct regulator_linear_range dcdc_iosr1_ranges[] = {
|
||||
};
|
||||
|
||||
/* DCDC group SDSR1: supported voltages in microvolts */
|
||||
static const struct regulator_linear_range dcdc_sdsr1_ranges[] = {
|
||||
static const struct linear_range dcdc_sdsr1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0),
|
||||
REGULATOR_LINEAR_RANGE(900000, 52, 63, 0),
|
||||
@ -143,7 +143,7 @@ struct bcm590xx_info {
|
||||
u8 n_voltages;
|
||||
const unsigned int *volt_table;
|
||||
u8 n_linear_ranges;
|
||||
const struct regulator_linear_range *linear_ranges;
|
||||
const struct linear_range *linear_ranges;
|
||||
};
|
||||
|
||||
#define BCM590XX_REG_TABLE(_name, _table) \
|
||||
|
@ -20,22 +20,22 @@
|
||||
#define BUCK_RAMPRATE_125MV 1
|
||||
#define BUCK_RAMP_MAX 250
|
||||
|
||||
static const struct regulator_linear_range bd70528_buck1_volts[] = {
|
||||
static const struct linear_range bd70528_buck1_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000),
|
||||
REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000),
|
||||
};
|
||||
static const struct regulator_linear_range bd70528_buck2_volts[] = {
|
||||
static const struct linear_range bd70528_buck2_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 300000),
|
||||
REGULATOR_LINEAR_RANGE(1550000, 0x2, 0xd, 50000),
|
||||
REGULATOR_LINEAR_RANGE(3000000, 0xe, 0xf, 300000),
|
||||
};
|
||||
static const struct regulator_linear_range bd70528_buck3_volts[] = {
|
||||
static const struct linear_range bd70528_buck3_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0x00, 0xd, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0xe, 0xf, 0),
|
||||
};
|
||||
|
||||
/* All LDOs have same voltage ranges */
|
||||
static const struct regulator_linear_range bd70528_ldo_volts[] = {
|
||||
static const struct linear_range bd70528_ldo_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1650000, 0x0, 0x07, 50000),
|
||||
REGULATOR_LINEAR_RANGE(2100000, 0x8, 0x0f, 100000),
|
||||
REGULATOR_LINEAR_RANGE(2850000, 0x10, 0x19, 50000),
|
||||
|
@ -65,27 +65,27 @@ static const struct reg_init buck7_inits[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range bd71828_buck1267_volts[] = {
|
||||
static const struct 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[] = {
|
||||
static const struct 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[] = {
|
||||
static const struct 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[] = {
|
||||
static const struct 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[] = {
|
||||
static const struct linear_range bd71828_ldo_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0x00, 0x31, 50000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 0x32, 0x3f, 0),
|
||||
};
|
||||
|
@ -55,12 +55,20 @@ static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev,
|
||||
BUCK_RAMPRATE_MASK, ramp_value << 6);
|
||||
}
|
||||
|
||||
/* Bucks 1 to 4 support DVS. PWM mode is used when voltage is changed.
|
||||
/*
|
||||
* On BD71837 (not on BD71847, BD71850, ...)
|
||||
* Bucks 1 to 4 support DVS. PWM mode is used when voltage is changed.
|
||||
* Bucks 5 to 8 and LDOs can use PFM and must be disabled when voltage
|
||||
* is changed. Hence we return -EBUSY for these if voltage is changed
|
||||
* when BUCK/LDO is enabled.
|
||||
*
|
||||
* On BD71847, BD71850, ... The LDO voltage can be changed when LDO is
|
||||
* enabled. But if voltage is increased the LDO power-good monitoring
|
||||
* must be disabled for the duration of changing + 1mS to ensure voltage
|
||||
* has reached the higher level before HW does next under voltage detection
|
||||
* cycle.
|
||||
*/
|
||||
static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev,
|
||||
static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
|
||||
unsigned int sel)
|
||||
{
|
||||
if (regulator_is_enabled_regmap(rdev))
|
||||
@ -69,8 +77,123 @@ static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev,
|
||||
return regulator_set_voltage_sel_regmap(rdev, sel);
|
||||
}
|
||||
|
||||
static void voltage_change_done(struct regulator_dev *rdev, unsigned int sel,
|
||||
unsigned int *mask)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (*mask) {
|
||||
/*
|
||||
* Let's allow scheduling as we use I2C anyways. We just need to
|
||||
* guarantee minimum of 1ms sleep - it shouldn't matter if we
|
||||
* exceed it due to the scheduling.
|
||||
*/
|
||||
msleep(1);
|
||||
/*
|
||||
* Note for next hacker. The PWRGOOD should not be masked on
|
||||
* BD71847 so we will just unconditionally enable detection
|
||||
* when voltage is set.
|
||||
* If someone want's to disable PWRGOOD he must implement
|
||||
* caching and restoring the old value here. I am not
|
||||
* aware of such use-cases so for the sake of the simplicity
|
||||
* we just always enable PWRGOOD here.
|
||||
*/
|
||||
ret = regmap_update_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2,
|
||||
*mask, 0);
|
||||
if (ret)
|
||||
dev_err(&rdev->dev,
|
||||
"Failed to re-enable voltage monitoring (%d)\n",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
|
||||
static int voltage_change_prepare(struct regulator_dev *rdev, unsigned int sel,
|
||||
unsigned int *mask)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*mask = 0;
|
||||
if (regulator_is_enabled_regmap(rdev)) {
|
||||
int now, new;
|
||||
|
||||
now = rdev->desc->ops->get_voltage_sel(rdev);
|
||||
if (now < 0)
|
||||
return now;
|
||||
|
||||
now = rdev->desc->ops->list_voltage(rdev, now);
|
||||
if (now < 0)
|
||||
return now;
|
||||
|
||||
new = rdev->desc->ops->list_voltage(rdev, sel);
|
||||
if (new < 0)
|
||||
return new;
|
||||
|
||||
/*
|
||||
* If we increase LDO voltage when LDO is enabled we need to
|
||||
* disable the power-good detection until voltage has reached
|
||||
* the new level. According to HW colleagues the maximum time
|
||||
* it takes is 1000us. I assume that on systems with light load
|
||||
* this might be less - and we could probably use DT to give
|
||||
* system specific delay value if performance matters.
|
||||
*
|
||||
* Well, knowing we use I2C here and can add scheduling delays
|
||||
* I don't think it is worth the hassle and I just add fixed
|
||||
* 1ms sleep here (and allow scheduling). If this turns out to
|
||||
* be a problem we can change it to delay and make the delay
|
||||
* time configurable.
|
||||
*/
|
||||
if (new > now) {
|
||||
int ldo_offset = rdev->desc->id - BD718XX_LDO1;
|
||||
|
||||
*mask = BD718XX_LDO1_VRMON80 << ldo_offset;
|
||||
ret = regmap_update_bits(rdev->regmap,
|
||||
BD718XX_REG_MVRFLTMASK2,
|
||||
*mask, *mask);
|
||||
if (ret) {
|
||||
dev_err(&rdev->dev,
|
||||
"Failed to stop voltage monitoring\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev,
|
||||
unsigned int sel)
|
||||
{
|
||||
int ret;
|
||||
int mask;
|
||||
|
||||
ret = voltage_change_prepare(rdev, sel, &mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regulator_set_voltage_sel_regmap(rdev, sel);
|
||||
voltage_change_done(rdev, sel, &mask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bd718xx_set_voltage_sel_pickable_restricted(
|
||||
struct regulator_dev *rdev, unsigned int sel)
|
||||
{
|
||||
int ret;
|
||||
int mask;
|
||||
|
||||
ret = voltage_change_prepare(rdev, sel, &mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regulator_set_voltage_sel_pickable_regmap(rdev, sel);
|
||||
voltage_change_done(rdev, sel, &mask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bd71837_set_voltage_sel_pickable_restricted(
|
||||
struct regulator_dev *rdev, unsigned int sel)
|
||||
{
|
||||
if (regulator_is_enabled_regmap(rdev))
|
||||
return -EBUSY;
|
||||
@ -85,6 +208,16 @@ static const struct regulator_ops bd718xx_pickable_range_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_pickable_linear_range,
|
||||
.set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
|
||||
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd71837_pickable_range_ldo_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_pickable_linear_range,
|
||||
.set_voltage_sel = bd71837_set_voltage_sel_pickable_restricted,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd718xx_pickable_range_buck_ops = {
|
||||
@ -92,11 +225,30 @@ static const struct regulator_ops bd718xx_pickable_range_buck_ops = {
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_pickable_linear_range,
|
||||
.set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd71837_pickable_range_buck_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_pickable_linear_range,
|
||||
.set_voltage_sel = bd71837_set_voltage_sel_pickable_restricted,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd71837_ldo_regulator_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 = bd71837_set_voltage_sel_restricted,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd718xx_ldo_regulator_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
@ -106,6 +258,15 @@ static const struct regulator_ops bd718xx_ldo_regulator_ops = {
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd71837_ldo_regulator_nolinear_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.set_voltage_sel = bd71837_set_voltage_sel_restricted,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
@ -120,12 +281,33 @@ static const struct regulator_ops bd718xx_buck_regulator_ops = {
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.set_voltage_sel = bd718xx_set_voltage_sel_restricted,
|
||||
.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,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd71837_buck_regulator_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 = bd71837_set_voltage_sel_restricted,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd718xx_buck_regulator_nolinear_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.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,
|
||||
};
|
||||
|
||||
static const struct regulator_ops bd71837_buck_regulator_nolinear_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -152,7 +334,7 @@ static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = {
|
||||
* BD71847 BUCK1/2
|
||||
* 0.70 to 1.30V (10mV step)
|
||||
*/
|
||||
static const struct regulator_linear_range bd718xx_dvs_buck_volts[] = {
|
||||
static const struct linear_range bd718xx_dvs_buck_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0),
|
||||
};
|
||||
@ -163,7 +345,7 @@ static const struct regulator_linear_range bd718xx_dvs_buck_volts[] = {
|
||||
* and
|
||||
* 0.675 to 1.325 (range 1)
|
||||
*/
|
||||
static const struct regulator_linear_range bd71837_buck5_volts[] = {
|
||||
static const struct linear_range bd71837_buck5_volts[] = {
|
||||
/* Ranges when VOLT_SEL bit is 0 */
|
||||
REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
|
||||
REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
|
||||
@ -185,7 +367,7 @@ static const unsigned int bd71837_buck5_volt_range_sel[] = {
|
||||
/*
|
||||
* BD71847 BUCK3
|
||||
*/
|
||||
static const struct regulator_linear_range bd71847_buck3_volts[] = {
|
||||
static const struct linear_range bd71847_buck3_volts[] = {
|
||||
/* Ranges when VOLT_SEL bits are 00 */
|
||||
REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
|
||||
REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
|
||||
@ -202,7 +384,7 @@ static const unsigned int bd71847_buck3_volt_range_sel[] = {
|
||||
0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range bd71847_buck4_volts[] = {
|
||||
static const struct linear_range bd71847_buck4_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
|
||||
REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000),
|
||||
};
|
||||
@ -213,7 +395,7 @@ static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 };
|
||||
* BUCK6
|
||||
* 3.0V to 3.3V (step 100mV)
|
||||
*/
|
||||
static const struct regulator_linear_range bd71837_buck6_volts[] = {
|
||||
static const struct linear_range bd71837_buck6_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
|
||||
};
|
||||
|
||||
@ -237,7 +419,7 @@ static const unsigned int bd718xx_3rd_nodvs_buck_volts[] = {
|
||||
* BUCK8
|
||||
* 0.8V to 1.40V (step 10mV)
|
||||
*/
|
||||
static const struct regulator_linear_range bd718xx_4th_nodvs_buck_volts[] = {
|
||||
static const struct linear_range bd718xx_4th_nodvs_buck_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000),
|
||||
};
|
||||
|
||||
@ -245,7 +427,7 @@ static const struct regulator_linear_range bd718xx_4th_nodvs_buck_volts[] = {
|
||||
* LDO1
|
||||
* 3.0 to 3.3V (100mV step)
|
||||
*/
|
||||
static const struct regulator_linear_range bd718xx_ldo1_volts[] = {
|
||||
static const struct linear_range bd718xx_ldo1_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
|
||||
REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
|
||||
};
|
||||
@ -264,7 +446,7 @@ static const unsigned int ldo_2_volts[] = {
|
||||
* LDO3
|
||||
* 1.8 to 3.3V (100mV step)
|
||||
*/
|
||||
static const struct regulator_linear_range bd718xx_ldo3_volts[] = {
|
||||
static const struct linear_range bd718xx_ldo3_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
|
||||
};
|
||||
|
||||
@ -272,7 +454,7 @@ static const struct regulator_linear_range bd718xx_ldo3_volts[] = {
|
||||
* LDO4
|
||||
* 0.9 to 1.8V (100mV step)
|
||||
*/
|
||||
static const struct regulator_linear_range bd718xx_ldo4_volts[] = {
|
||||
static const struct linear_range bd718xx_ldo4_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
|
||||
};
|
||||
|
||||
@ -280,7 +462,7 @@ static const struct regulator_linear_range bd718xx_ldo4_volts[] = {
|
||||
* LDO5 for BD71837
|
||||
* 1.8 to 3.3V (100mV step)
|
||||
*/
|
||||
static const struct regulator_linear_range bd71837_ldo5_volts[] = {
|
||||
static const struct linear_range bd71837_ldo5_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
|
||||
};
|
||||
|
||||
@ -288,7 +470,7 @@ static const struct regulator_linear_range bd71837_ldo5_volts[] = {
|
||||
* LDO5 for BD71837
|
||||
* 1.8 to 3.3V (100mV step)
|
||||
*/
|
||||
static const struct regulator_linear_range bd71847_ldo5_volts[] = {
|
||||
static const struct linear_range bd71847_ldo5_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
|
||||
REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000),
|
||||
};
|
||||
@ -299,7 +481,7 @@ static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 };
|
||||
* LDO6
|
||||
* 0.9 to 1.8V (100mV step)
|
||||
*/
|
||||
static const struct regulator_linear_range bd718xx_ldo6_volts[] = {
|
||||
static const struct linear_range bd718xx_ldo6_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
|
||||
};
|
||||
|
||||
@ -307,7 +489,7 @@ static const struct regulator_linear_range bd718xx_ldo6_volts[] = {
|
||||
* LDO7
|
||||
* 1.8 to 3.3V (100mV step)
|
||||
*/
|
||||
static const struct regulator_linear_range bd71837_ldo7_volts[] = {
|
||||
static const struct linear_range bd71837_ldo7_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
|
||||
};
|
||||
|
||||
@ -805,7 +987,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("BUCK5"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_BUCK5,
|
||||
.ops = &bd718xx_pickable_range_buck_ops,
|
||||
.ops = &bd71837_pickable_range_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
|
||||
.linear_ranges = bd71837_buck5_volts,
|
||||
@ -832,7 +1014,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("BUCK6"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_BUCK6,
|
||||
.ops = &bd718xx_buck_regulator_ops,
|
||||
.ops = &bd71837_buck_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
|
||||
.linear_ranges = bd71837_buck6_volts,
|
||||
@ -856,7 +1038,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("BUCK7"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_BUCK7,
|
||||
.ops = &bd718xx_buck_regulator_nolinear_ops,
|
||||
.ops = &bd71837_buck_regulator_nolinear_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.volt_table = &bd718xx_3rd_nodvs_buck_volts[0],
|
||||
.n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts),
|
||||
@ -878,7 +1060,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("BUCK8"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_BUCK8,
|
||||
.ops = &bd718xx_buck_regulator_ops,
|
||||
.ops = &bd71837_buck_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM,
|
||||
.linear_ranges = bd718xx_4th_nodvs_buck_volts,
|
||||
@ -902,7 +1084,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("LDO1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_LDO1,
|
||||
.ops = &bd718xx_pickable_range_ldo_ops,
|
||||
.ops = &bd71837_pickable_range_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
|
||||
.linear_ranges = bd718xx_ldo1_volts,
|
||||
@ -928,7 +1110,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("LDO2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_LDO2,
|
||||
.ops = &bd718xx_ldo_regulator_nolinear_ops,
|
||||
.ops = &bd71837_ldo_regulator_nolinear_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.volt_table = &ldo_2_volts[0],
|
||||
.vsel_reg = BD718XX_REG_LDO2_VOLT,
|
||||
@ -950,7 +1132,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("LDO3"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_LDO3,
|
||||
.ops = &bd718xx_ldo_regulator_ops,
|
||||
.ops = &bd71837_ldo_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = BD718XX_LDO3_VOLTAGE_NUM,
|
||||
.linear_ranges = bd718xx_ldo3_volts,
|
||||
@ -973,7 +1155,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("LDO4"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_LDO4,
|
||||
.ops = &bd718xx_ldo_regulator_ops,
|
||||
.ops = &bd71837_ldo_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = BD718XX_LDO4_VOLTAGE_NUM,
|
||||
.linear_ranges = bd718xx_ldo4_volts,
|
||||
@ -996,7 +1178,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("LDO5"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_LDO5,
|
||||
.ops = &bd718xx_ldo_regulator_ops,
|
||||
.ops = &bd71837_ldo_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = BD71837_LDO5_VOLTAGE_NUM,
|
||||
.linear_ranges = bd71837_ldo5_volts,
|
||||
@ -1023,7 +1205,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("LDO6"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_LDO6,
|
||||
.ops = &bd718xx_ldo_regulator_ops,
|
||||
.ops = &bd71837_ldo_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = BD718XX_LDO6_VOLTAGE_NUM,
|
||||
.linear_ranges = bd718xx_ldo6_volts,
|
||||
@ -1050,7 +1232,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.of_match = of_match_ptr("LDO7"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD718XX_LDO7,
|
||||
.ops = &bd718xx_ldo_regulator_ops,
|
||||
.ops = &bd71837_ldo_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = BD71837_LDO7_VOLTAGE_NUM,
|
||||
.linear_ranges = bd71837_ldo7_volts,
|
||||
|
@ -3642,36 +3642,19 @@ finish:
|
||||
return done;
|
||||
}
|
||||
|
||||
static int regulator_balance_voltage(struct regulator_dev *rdev,
|
||||
suspend_state_t state)
|
||||
int regulator_do_balance_voltage(struct regulator_dev *rdev,
|
||||
suspend_state_t state, bool skip_coupled)
|
||||
{
|
||||
struct regulator_dev **c_rdevs;
|
||||
struct regulator_dev *best_rdev;
|
||||
struct coupling_desc *c_desc = &rdev->coupling_desc;
|
||||
struct regulator_coupler *coupler = c_desc->coupler;
|
||||
int i, ret, n_coupled, best_min_uV, best_max_uV, best_c_rdev;
|
||||
unsigned int delta, best_delta;
|
||||
unsigned long c_rdev_done = 0;
|
||||
bool best_c_rdev_done;
|
||||
|
||||
c_rdevs = c_desc->coupled_rdevs;
|
||||
n_coupled = c_desc->n_coupled;
|
||||
|
||||
/*
|
||||
* If system is in a state other than PM_SUSPEND_ON, don't check
|
||||
* other coupled regulators.
|
||||
*/
|
||||
if (state != PM_SUSPEND_ON)
|
||||
n_coupled = 1;
|
||||
|
||||
if (c_desc->n_resolved < n_coupled) {
|
||||
rdev_err(rdev, "Not all coupled regulators registered\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* Invoke custom balancer for customized couplers */
|
||||
if (coupler && coupler->balance_voltage)
|
||||
return coupler->balance_voltage(coupler, rdev, state);
|
||||
n_coupled = skip_coupled ? 1 : c_desc->n_coupled;
|
||||
|
||||
/*
|
||||
* Find the best possible voltage change on each loop. Leave the loop
|
||||
@ -3742,6 +3725,32 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int regulator_balance_voltage(struct regulator_dev *rdev,
|
||||
suspend_state_t state)
|
||||
{
|
||||
struct coupling_desc *c_desc = &rdev->coupling_desc;
|
||||
struct regulator_coupler *coupler = c_desc->coupler;
|
||||
bool skip_coupled = false;
|
||||
|
||||
/*
|
||||
* If system is in a state other than PM_SUSPEND_ON, don't check
|
||||
* other coupled regulators.
|
||||
*/
|
||||
if (state != PM_SUSPEND_ON)
|
||||
skip_coupled = true;
|
||||
|
||||
if (c_desc->n_resolved < c_desc->n_coupled) {
|
||||
rdev_err(rdev, "Not all coupled regulators registered\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* Invoke custom balancer for customized couplers */
|
||||
if (coupler && coupler->balance_voltage)
|
||||
return coupler->balance_voltage(coupler, rdev, state);
|
||||
|
||||
return regulator_do_balance_voltage(rdev, state, skip_coupled);
|
||||
}
|
||||
|
||||
/**
|
||||
* regulator_set_voltage - set regulator output voltage
|
||||
* @regulator: regulator source
|
||||
@ -4312,6 +4321,7 @@ EXPORT_SYMBOL_GPL(regulator_set_load);
|
||||
int regulator_allow_bypass(struct regulator *regulator, bool enable)
|
||||
{
|
||||
struct regulator_dev *rdev = regulator->rdev;
|
||||
const char *name = rdev_get_name(rdev);
|
||||
int ret = 0;
|
||||
|
||||
if (!rdev->desc->ops->set_bypass)
|
||||
@ -4326,18 +4336,26 @@ int regulator_allow_bypass(struct regulator *regulator, bool enable)
|
||||
rdev->bypass_count++;
|
||||
|
||||
if (rdev->bypass_count == rdev->open_count) {
|
||||
trace_regulator_bypass_enable(name);
|
||||
|
||||
ret = rdev->desc->ops->set_bypass(rdev, enable);
|
||||
if (ret != 0)
|
||||
rdev->bypass_count--;
|
||||
else
|
||||
trace_regulator_bypass_enable_complete(name);
|
||||
}
|
||||
|
||||
} else if (!enable && regulator->bypass) {
|
||||
rdev->bypass_count--;
|
||||
|
||||
if (rdev->bypass_count != rdev->open_count) {
|
||||
trace_regulator_bypass_disable(name);
|
||||
|
||||
ret = rdev->desc->ops->set_bypass(rdev, enable);
|
||||
if (ret != 0)
|
||||
rdev->bypass_count++;
|
||||
else
|
||||
trace_regulator_bypass_disable_complete(name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5496,6 +5514,7 @@ static void regulator_summary_show_subtree(struct seq_file *s,
|
||||
seq_printf(s, "%*s%-*s ",
|
||||
(level + 1) * 3 + 1, "",
|
||||
30 - (level + 1) * 3,
|
||||
consumer->supply_name ? consumer->supply_name :
|
||||
consumer->dev ? dev_name(consumer->dev) : "deviceless");
|
||||
|
||||
switch (rdev->desc->type) {
|
||||
|
@ -248,7 +248,7 @@ static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range da9034_ldo12_ranges[] = {
|
||||
static const struct linear_range da9034_ldo12_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 50000),
|
||||
REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000),
|
||||
};
|
||||
|
@ -181,7 +181,7 @@ static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
info->is_enabled = 0;
|
||||
info->is_enabled = false;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -131,10 +131,11 @@ int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev)
|
||||
unsigned int r_val;
|
||||
int range;
|
||||
unsigned int val;
|
||||
int ret, i;
|
||||
unsigned int voltages_in_range = 0;
|
||||
int ret;
|
||||
unsigned int voltages = 0;
|
||||
const struct linear_range *r = rdev->desc->linear_ranges;
|
||||
|
||||
if (!rdev->desc->linear_ranges)
|
||||
if (!r)
|
||||
return -EINVAL;
|
||||
|
||||
ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
|
||||
@ -152,11 +153,9 @@ int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev)
|
||||
if (range < 0)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < range; i++)
|
||||
voltages_in_range += (rdev->desc->linear_ranges[i].max_sel -
|
||||
rdev->desc->linear_ranges[i].min_sel) + 1;
|
||||
voltages = linear_range_values_in_range_array(r, range);
|
||||
|
||||
return val + voltages_in_range;
|
||||
return val + voltages;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap);
|
||||
|
||||
@ -179,8 +178,11 @@ int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
|
||||
unsigned int voltages_in_range = 0;
|
||||
|
||||
for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
|
||||
voltages_in_range = (rdev->desc->linear_ranges[i].max_sel -
|
||||
rdev->desc->linear_ranges[i].min_sel) + 1;
|
||||
const struct linear_range *r;
|
||||
|
||||
r = &rdev->desc->linear_ranges[i];
|
||||
voltages_in_range = linear_range_values_in_range(r);
|
||||
|
||||
if (sel < voltages_in_range)
|
||||
break;
|
||||
sel -= voltages_in_range;
|
||||
@ -405,8 +407,10 @@ EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
|
||||
int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
const struct regulator_linear_range *range;
|
||||
const struct linear_range *range;
|
||||
int ret = -EINVAL;
|
||||
unsigned int sel;
|
||||
bool found;
|
||||
int voltage, i;
|
||||
|
||||
if (!rdev->desc->n_linear_ranges) {
|
||||
@ -415,35 +419,19 @@ int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
|
||||
}
|
||||
|
||||
for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
|
||||
int linear_max_uV;
|
||||
|
||||
range = &rdev->desc->linear_ranges[i];
|
||||
linear_max_uV = range->min_uV +
|
||||
(range->max_sel - range->min_sel) * range->uV_step;
|
||||
|
||||
if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV))
|
||||
ret = linear_range_get_selector_high(range, min_uV, &sel,
|
||||
&found);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
if (min_uV <= range->min_uV)
|
||||
min_uV = range->min_uV;
|
||||
|
||||
/* range->uV_step == 0 means fixed voltage range */
|
||||
if (range->uV_step == 0) {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = DIV_ROUND_UP(min_uV - range->min_uV,
|
||||
range->uV_step);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret += range->min_sel;
|
||||
ret = sel;
|
||||
|
||||
/*
|
||||
* Map back into a voltage to verify we're still in bounds.
|
||||
* If we are not, then continue checking rest of the ranges.
|
||||
*/
|
||||
voltage = rdev->desc->ops->list_voltage(rdev, ret);
|
||||
voltage = rdev->desc->ops->list_voltage(rdev, sel);
|
||||
if (voltage >= min_uV && voltage <= max_uV)
|
||||
break;
|
||||
}
|
||||
@ -468,7 +456,7 @@ EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
|
||||
int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
const struct regulator_linear_range *range;
|
||||
const struct linear_range *range;
|
||||
int ret = -EINVAL;
|
||||
int voltage, i;
|
||||
unsigned int selector = 0;
|
||||
@ -480,30 +468,25 @@ int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,
|
||||
|
||||
for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
|
||||
int linear_max_uV;
|
||||
bool found;
|
||||
unsigned int sel;
|
||||
|
||||
range = &rdev->desc->linear_ranges[i];
|
||||
linear_max_uV = range->min_uV +
|
||||
(range->max_sel - range->min_sel) * range->uV_step;
|
||||
linear_max_uV = linear_range_get_max_value(range);
|
||||
|
||||
if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV)) {
|
||||
selector += (range->max_sel - range->min_sel + 1);
|
||||
if (!(min_uV <= linear_max_uV && max_uV >= range->min)) {
|
||||
selector += linear_range_values_in_range(range);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (min_uV <= range->min_uV)
|
||||
min_uV = range->min_uV;
|
||||
|
||||
/* range->uV_step == 0 means fixed voltage range */
|
||||
if (range->uV_step == 0) {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = DIV_ROUND_UP(min_uV - range->min_uV,
|
||||
range->uV_step);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = linear_range_get_selector_high(range, min_uV, &sel,
|
||||
&found);
|
||||
if (ret) {
|
||||
selector += linear_range_values_in_range(range);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret += selector;
|
||||
ret = selector + sel;
|
||||
|
||||
voltage = rdev->desc->ops->list_voltage(rdev, ret);
|
||||
|
||||
@ -513,7 +496,7 @@ int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,
|
||||
* exit but retry until we have checked all ranges.
|
||||
*/
|
||||
if (voltage < min_uV || voltage > max_uV)
|
||||
selector += (range->max_sel - range->min_sel + 1);
|
||||
selector += linear_range_values_in_range(range);
|
||||
else
|
||||
break;
|
||||
}
|
||||
@ -561,7 +544,7 @@ EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
|
||||
int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
const struct regulator_linear_range *range;
|
||||
const struct linear_range *range;
|
||||
int i;
|
||||
unsigned int all_sels = 0;
|
||||
|
||||
@ -571,18 +554,28 @@ int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,
|
||||
}
|
||||
|
||||
for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
|
||||
unsigned int sels_in_range;
|
||||
unsigned int sel_indexes;
|
||||
|
||||
range = &rdev->desc->linear_ranges[i];
|
||||
|
||||
sels_in_range = range->max_sel - range->min_sel;
|
||||
sel_indexes = linear_range_values_in_range(range) - 1;
|
||||
|
||||
if (all_sels + sels_in_range >= selector) {
|
||||
if (all_sels + sel_indexes >= selector) {
|
||||
selector -= all_sels;
|
||||
return range->min_uV + (range->uV_step * selector);
|
||||
/*
|
||||
* As we see here, pickable ranges work only as
|
||||
* long as the first selector for each pickable
|
||||
* range is 0, and the each subsequent range for
|
||||
* this 'pick' follow immediately at next unused
|
||||
* selector (Eg. there is no gaps between ranges).
|
||||
* I think this is fine but it probably should be
|
||||
* documented. OTOH, whole pickable range stuff
|
||||
* might benefit from some documentation
|
||||
*/
|
||||
return range->min + (range->step * selector);
|
||||
}
|
||||
|
||||
all_sels += (sels_in_range + 1);
|
||||
all_sels += (sel_indexes + 1);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
@ -604,27 +597,18 @@ EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range);
|
||||
int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc,
|
||||
unsigned int selector)
|
||||
{
|
||||
const struct regulator_linear_range *range;
|
||||
int i;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
if (!desc->n_linear_ranges) {
|
||||
BUG_ON(!desc->n_linear_ranges);
|
||||
return -EINVAL;
|
||||
}
|
||||
BUG_ON(!desc->n_linear_ranges);
|
||||
|
||||
for (i = 0; i < desc->n_linear_ranges; i++) {
|
||||
range = &desc->linear_ranges[i];
|
||||
ret = linear_range_get_value_array(desc->linear_ranges,
|
||||
desc->n_linear_ranges, selector,
|
||||
&val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(selector >= range->min_sel &&
|
||||
selector <= range->max_sel))
|
||||
continue;
|
||||
|
||||
selector -= range->min_sel;
|
||||
|
||||
return range->min_uV + (range->uV_step * selector);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear_range);
|
||||
|
||||
|
@ -87,7 +87,7 @@ static const unsigned int ldo_8_voltages[] = {
|
||||
};
|
||||
|
||||
/* Ranges are sorted in ascending order. */
|
||||
static const struct regulator_linear_range ldo_audio_volt_range[] = {
|
||||
static const struct linear_range ldo_audio_volt_range[] = {
|
||||
REGULATOR_LINEAR_RANGE(2800000, 0, 3, 50000),
|
||||
REGULATOR_LINEAR_RANGE(3000000, 4, 7, 100000),
|
||||
};
|
||||
@ -195,7 +195,7 @@ static const struct regulator_ops hi6421_buck345_ops;
|
||||
* _id - LDO id name string
|
||||
* _match - of match name string
|
||||
* n_volt - number of votages available
|
||||
* volt_ranges - array of regulator_linear_range
|
||||
* volt_ranges - array of linear_range
|
||||
* vstep - voltage increase in each linear step in uV
|
||||
* vreg - voltage select register
|
||||
* vmask - voltage select mask
|
||||
|
@ -36,7 +36,7 @@ static const struct regulator_ops lochnagar_micvdd_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range lochnagar_micvdd_ranges[] = {
|
||||
static const struct linear_range lochnagar_micvdd_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0, 0xC, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0xD, 0x1F, 100000),
|
||||
};
|
||||
@ -97,7 +97,7 @@ static const struct regulator_ops lochnagar_vddcore_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range lochnagar_vddcore_ranges[] = {
|
||||
static const struct linear_range lochnagar_vddcore_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0x8, 0x41, 12500),
|
||||
};
|
||||
|
||||
|
@ -54,14 +54,14 @@ struct lp873x_regulator {
|
||||
|
||||
static const struct lp873x_regulator regulators[];
|
||||
|
||||
static const struct regulator_linear_range buck0_buck1_ranges[] = {
|
||||
static const struct linear_range buck0_buck1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0x0, 0x13, 0),
|
||||
REGULATOR_LINEAR_RANGE(700000, 0x14, 0x17, 10000),
|
||||
REGULATOR_LINEAR_RANGE(735000, 0x18, 0x9d, 5000),
|
||||
REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range ldo0_ldo1_ranges[] = {
|
||||
static const struct linear_range ldo0_ldo1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0x0, 0x19, 100000),
|
||||
};
|
||||
|
||||
|
@ -46,7 +46,7 @@ struct lp87565_regulator {
|
||||
|
||||
static const struct lp87565_regulator regulators[];
|
||||
|
||||
static const struct regulator_linear_range buck0_1_2_3_ranges[] = {
|
||||
static const struct linear_range buck0_1_2_3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0xA, 0x17, 10000),
|
||||
REGULATOR_LINEAR_RANGE(735000, 0x18, 0x9d, 5000),
|
||||
REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000),
|
||||
|
@ -92,7 +92,7 @@ struct lp8788_buck {
|
||||
};
|
||||
|
||||
/* BUCK 1 ~ 4 voltage ranges */
|
||||
static const struct regulator_linear_range buck_volt_ranges[] = {
|
||||
static const struct linear_range buck_volt_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 0, 0),
|
||||
REGULATOR_LINEAR_RANGE(800000, 1, 25, 50000),
|
||||
};
|
||||
|
@ -49,7 +49,7 @@ static const unsigned int max77651_sbb1_volt_range_sel[] = {
|
||||
0x0, 0x1, 0x2, 0x3
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range max77651_sbb1_volt_ranges[] = {
|
||||
static const struct linear_range max77651_sbb1_volt_ranges[] = {
|
||||
/* range index 0 */
|
||||
REGULATOR_LINEAR_RANGE(2400000, 0x00, 0x0f, 50000),
|
||||
/* range index 1 */
|
||||
|
301
drivers/regulator/max77826-regulator.c
Normal file
301
drivers/regulator/max77826-regulator.c
Normal file
@ -0,0 +1,301 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
//
|
||||
// max77826-regulator.c - regulator driver for Maxim MAX77826
|
||||
//
|
||||
// Author: Iskren Chernev <iskren.chernev@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>
|
||||
|
||||
enum max77826_registers {
|
||||
MAX77826_REG_INT_SRC = 0x00,
|
||||
MAX77826_REG_SYS_INT,
|
||||
MAX77826_REG_INT1,
|
||||
MAX77826_REG_INT2,
|
||||
MAX77826_REG_BB_INT,
|
||||
MAX77826_REG_INT_SRC_M,
|
||||
MAX77826_REG_TOPSYS_INT_M,
|
||||
MAX77826_REG_INT1_M,
|
||||
MAX77826_REG_INT2_M,
|
||||
MAX77826_REG_BB_INT_M,
|
||||
MAX77826_REG_TOPSYS_STAT,
|
||||
MAX77826_REG_STAT1,
|
||||
MAX77826_REG_STAT2,
|
||||
MAX77826_REG_BB_STAT,
|
||||
/* 0x0E - 0x0F: Reserved */
|
||||
MAX77826_REG_LDO_OPMD1 = 0x10,
|
||||
MAX77826_REG_LDO_OPMD2,
|
||||
MAX77826_REG_LDO_OPMD3,
|
||||
MAX77826_REG_LDO_OPMD4,
|
||||
MAX77826_REG_B_BB_OPMD,
|
||||
/* 0x15 - 0x1F: Reserved */
|
||||
MAX77826_REG_LDO1_CFG = 0x20,
|
||||
MAX77826_REG_LDO2_CFG,
|
||||
MAX77826_REG_LDO3_CFG,
|
||||
MAX77826_REG_LDO4_CFG,
|
||||
MAX77826_REG_LDO5_CFG,
|
||||
MAX77826_REG_LDO6_CFG,
|
||||
MAX77826_REG_LDO7_CFG,
|
||||
MAX77826_REG_LDO8_CFG,
|
||||
MAX77826_REG_LDO9_CFG,
|
||||
MAX77826_REG_LDO10_CFG,
|
||||
MAX77826_REG_LDO11_CFG,
|
||||
MAX77826_REG_LDO12_CFG,
|
||||
MAX77826_REG_LDO13_CFG,
|
||||
MAX77826_REG_LDO14_CFG,
|
||||
MAX77826_REG_LDO15_CFG,
|
||||
/* 0x2F: Reserved */
|
||||
MAX77826_REG_BUCK_CFG = 0x30,
|
||||
MAX77826_REG_BUCK_VOUT,
|
||||
MAX77826_REG_BB_CFG,
|
||||
MAX77826_REG_BB_VOUT,
|
||||
/* 0x34 - 0x3F: Reserved */
|
||||
MAX77826_REG_BUCK_SS_FREQ = 0x40,
|
||||
MAX77826_REG_UVLO_FALL,
|
||||
/* 0x42 - 0xCE: Reserved */
|
||||
MAX77826_REG_DEVICE_ID = 0xCF,
|
||||
};
|
||||
|
||||
enum max77826_regulators {
|
||||
MAX77826_LDO1 = 0,
|
||||
MAX77826_LDO2,
|
||||
MAX77826_LDO3,
|
||||
MAX77826_LDO4,
|
||||
MAX77826_LDO5,
|
||||
MAX77826_LDO6,
|
||||
MAX77826_LDO7,
|
||||
MAX77826_LDO8,
|
||||
MAX77826_LDO9,
|
||||
MAX77826_LDO10,
|
||||
MAX77826_LDO11,
|
||||
MAX77826_LDO12,
|
||||
MAX77826_LDO13,
|
||||
MAX77826_LDO14,
|
||||
MAX77826_LDO15,
|
||||
MAX77826_BUCK,
|
||||
MAX77826_BUCKBOOST,
|
||||
MAX77826_MAX_REGULATORS,
|
||||
};
|
||||
|
||||
#define MAX77826_MASK_LDO 0x7f
|
||||
#define MAX77826_MASK_BUCK 0xff
|
||||
#define MAX77826_MASK_BUCKBOOST 0x7f
|
||||
#define MAX77826_BUCK_RAMP_DELAY 12500
|
||||
|
||||
/* values in mV */
|
||||
/* for LDO1-3 */
|
||||
#define MAX77826_NMOS_LDO_VOLT_MIN 600000
|
||||
#define MAX77826_NMOS_LDO_VOLT_MAX 2187500
|
||||
#define MAX77826_NMOS_LDO_VOLT_STEP 12500
|
||||
|
||||
/* for LDO4-15 */
|
||||
#define MAX77826_PMOS_LDO_VOLT_MIN 800000
|
||||
#define MAX77826_PMOS_LDO_VOLT_MAX 3975000
|
||||
#define MAX77826_PMOS_LDO_VOLT_STEP 25000
|
||||
|
||||
/* for BUCK */
|
||||
#define MAX77826_BUCK_VOLT_MIN 500000
|
||||
#define MAX77826_BUCK_VOLT_MAX 1800000
|
||||
#define MAX77826_BUCK_VOLT_STEP 6250
|
||||
|
||||
/* for BUCKBOOST */
|
||||
#define MAX77826_BUCKBOOST_VOLT_MIN 2600000
|
||||
#define MAX77826_BUCKBOOST_VOLT_MAX 4187500
|
||||
#define MAX77826_BUCKBOOST_VOLT_STEP 12500
|
||||
#define MAX77826_VOLT_RANGE(_type) \
|
||||
((MAX77826_ ## _type ## _VOLT_MAX - \
|
||||
MAX77826_ ## _type ## _VOLT_MIN) / \
|
||||
MAX77826_ ## _type ## _VOLT_STEP + 1)
|
||||
|
||||
#define MAX77826_LDO(_id, _type) \
|
||||
[MAX77826_LDO ## _id] = { \
|
||||
.id = MAX77826_LDO ## _id, \
|
||||
.name = "LDO"#_id, \
|
||||
.of_match = of_match_ptr("LDO"#_id), \
|
||||
.regulators_node = "regulators", \
|
||||
.ops = &max77826_most_ops, \
|
||||
.min_uV = MAX77826_ ## _type ## _LDO_VOLT_MIN, \
|
||||
.uV_step = MAX77826_ ## _type ## _LDO_VOLT_STEP, \
|
||||
.n_voltages = MAX77826_VOLT_RANGE(_type ## _LDO), \
|
||||
.enable_reg = MAX77826_REG_LDO_OPMD1 + (_id - 1) / 4, \
|
||||
.enable_mask = BIT(((_id - 1) % 4) * 2 + 1), \
|
||||
.vsel_reg = MAX77826_REG_LDO1_CFG + (_id - 1), \
|
||||
.vsel_mask = MAX77826_MASK_LDO, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
#define MAX77826_BUCK(_idx, _id, _ops) \
|
||||
[MAX77826_ ## _id] = { \
|
||||
.id = MAX77826_ ## _id, \
|
||||
.name = #_id, \
|
||||
.of_match = of_match_ptr(#_id), \
|
||||
.regulators_node = "regulators", \
|
||||
.ops = &_ops, \
|
||||
.min_uV = MAX77826_ ## _id ## _VOLT_MIN, \
|
||||
.uV_step = MAX77826_ ## _id ## _VOLT_STEP, \
|
||||
.n_voltages = MAX77826_VOLT_RANGE(_id), \
|
||||
.enable_reg = MAX77826_REG_B_BB_OPMD, \
|
||||
.enable_mask = BIT(_idx * 2 + 1), \
|
||||
.vsel_reg = MAX77826_REG_BUCK_VOUT + _idx * 2, \
|
||||
.vsel_mask = MAX77826_MASK_ ## _id, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct max77826_regulator_info {
|
||||
struct regmap *regmap;
|
||||
struct regulator_desc *rdesc;
|
||||
};
|
||||
|
||||
static const struct regmap_config max77826_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = MAX77826_REG_DEVICE_ID,
|
||||
};
|
||||
|
||||
static int max77826_set_voltage_time_sel(struct regulator_dev *,
|
||||
unsigned int old_selector,
|
||||
unsigned int new_selector);
|
||||
|
||||
static const struct regulator_ops max77826_most_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops max77826_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_voltage_time_sel = max77826_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static struct regulator_desc max77826_regulators_desc[] = {
|
||||
MAX77826_LDO(1, NMOS),
|
||||
MAX77826_LDO(2, NMOS),
|
||||
MAX77826_LDO(3, NMOS),
|
||||
MAX77826_LDO(4, PMOS),
|
||||
MAX77826_LDO(5, PMOS),
|
||||
MAX77826_LDO(6, PMOS),
|
||||
MAX77826_LDO(7, PMOS),
|
||||
MAX77826_LDO(8, PMOS),
|
||||
MAX77826_LDO(9, PMOS),
|
||||
MAX77826_LDO(10, PMOS),
|
||||
MAX77826_LDO(11, PMOS),
|
||||
MAX77826_LDO(12, PMOS),
|
||||
MAX77826_LDO(13, PMOS),
|
||||
MAX77826_LDO(14, PMOS),
|
||||
MAX77826_LDO(15, PMOS),
|
||||
MAX77826_BUCK(0, BUCK, max77826_buck_ops),
|
||||
MAX77826_BUCK(1, BUCKBOOST, max77826_most_ops),
|
||||
};
|
||||
|
||||
static int max77826_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
unsigned int old_selector,
|
||||
unsigned int new_selector)
|
||||
{
|
||||
if (new_selector > old_selector) {
|
||||
return DIV_ROUND_UP(MAX77826_BUCK_VOLT_STEP *
|
||||
(new_selector - old_selector),
|
||||
MAX77826_BUCK_RAMP_DELAY);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77826_read_device_id(struct regmap *regmap, struct device *dev)
|
||||
{
|
||||
unsigned int device_id;
|
||||
int res;
|
||||
|
||||
res = regmap_read(regmap, MAX77826_REG_DEVICE_ID, &device_id);
|
||||
if (!res)
|
||||
dev_dbg(dev, "DEVICE_ID: 0x%x\n", device_id);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int max77826_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct max77826_regulator_info *info;
|
||||
struct regulator_config config = {};
|
||||
struct regulator_dev *rdev;
|
||||
struct regmap *regmap;
|
||||
int i;
|
||||
|
||||
info = devm_kzalloc(dev, sizeof(struct max77826_regulator_info),
|
||||
GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
info->rdesc = max77826_regulators_desc;
|
||||
regmap = devm_regmap_init_i2c(client, &max77826_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(dev, "Failed to allocate regmap!\n");
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
info->regmap = regmap;
|
||||
i2c_set_clientdata(client, info);
|
||||
|
||||
config.dev = dev;
|
||||
config.regmap = regmap;
|
||||
config.driver_data = info;
|
||||
|
||||
for (i = 0; i < MAX77826_MAX_REGULATORS; i++) {
|
||||
rdev = devm_regulator_register(dev,
|
||||
&max77826_regulators_desc[i],
|
||||
&config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(dev, "Failed to register regulator!\n");
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
}
|
||||
|
||||
return max77826_read_device_id(regmap, dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id max77826_of_match[] = {
|
||||
{ .compatible = "maxim,max77826" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max77826_of_match);
|
||||
|
||||
static const struct i2c_device_id max77826_id[] = {
|
||||
{ "max77826-regulator" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max77826_id);
|
||||
|
||||
static struct i2c_driver max77826_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "max77826",
|
||||
.of_match_table = of_match_ptr(max77826_of_match),
|
||||
},
|
||||
.probe_new = max77826_i2c_probe,
|
||||
.id_table = max77826_id,
|
||||
};
|
||||
module_i2c_driver(max77826_regulator_driver);
|
||||
|
||||
MODULE_AUTHOR("Iskren Chernev <iskren.chernev@gmail.com>");
|
||||
MODULE_DESCRIPTION("MAX77826 PMIC regulator driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -33,6 +33,10 @@ struct max8998_data {
|
||||
unsigned int buck2_idx;
|
||||
};
|
||||
|
||||
static const unsigned int charger_current_table[] = {
|
||||
90000, 380000, 475000, 550000, 570000, 600000, 700000, 800000,
|
||||
};
|
||||
|
||||
static int max8998_get_enable_register(struct regulator_dev *rdev,
|
||||
int *reg, int *shift)
|
||||
{
|
||||
@ -63,6 +67,10 @@ static int max8998_get_enable_register(struct regulator_dev *rdev,
|
||||
*reg = MAX8998_REG_CHGR2;
|
||||
*shift = 7 - (ldo - MAX8998_ESAFEOUT1);
|
||||
break;
|
||||
case MAX8998_CHARGER:
|
||||
*reg = MAX8998_REG_CHGR2;
|
||||
*shift = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -88,6 +96,11 @@ static int max8998_ldo_is_enabled(struct regulator_dev *rdev)
|
||||
return val & (1 << shift);
|
||||
}
|
||||
|
||||
static int max8998_ldo_is_enabled_inverted(struct regulator_dev *rdev)
|
||||
{
|
||||
return (!max8998_ldo_is_enabled(rdev));
|
||||
}
|
||||
|
||||
static int max8998_ldo_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
|
||||
@ -358,6 +371,74 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max8998_set_current_limit(struct regulator_dev *rdev,
|
||||
int min_uA, int max_uA)
|
||||
{
|
||||
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
|
||||
struct i2c_client *i2c = max8998->iodev->i2c;
|
||||
unsigned int n_currents = rdev->desc->n_current_limits;
|
||||
int i, sel = -1;
|
||||
|
||||
if (n_currents == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (rdev->desc->curr_table) {
|
||||
const unsigned int *curr_table = rdev->desc->curr_table;
|
||||
bool ascend = curr_table[n_currents - 1] > curr_table[0];
|
||||
|
||||
/* search for closest to maximum */
|
||||
if (ascend) {
|
||||
for (i = n_currents - 1; i >= 0; i--) {
|
||||
if (min_uA <= curr_table[i] &&
|
||||
curr_table[i] <= max_uA) {
|
||||
sel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < n_currents; i++) {
|
||||
if (min_uA <= curr_table[i] &&
|
||||
curr_table[i] <= max_uA) {
|
||||
sel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sel < 0)
|
||||
return -EINVAL;
|
||||
|
||||
sel <<= ffs(rdev->desc->csel_mask) - 1;
|
||||
|
||||
return max8998_update_reg(i2c, rdev->desc->csel_reg,
|
||||
sel, rdev->desc->csel_mask);
|
||||
}
|
||||
|
||||
int max8998_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
|
||||
struct i2c_client *i2c = max8998->iodev->i2c;
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = max8998_read_reg(i2c, rdev->desc->csel_reg, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
val &= rdev->desc->csel_mask;
|
||||
val >>= ffs(rdev->desc->csel_mask) - 1;
|
||||
|
||||
if (rdev->desc->curr_table) {
|
||||
if (val >= rdev->desc->n_current_limits)
|
||||
return -EINVAL;
|
||||
|
||||
return rdev->desc->curr_table[val];
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct regulator_ops max8998_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
@ -379,6 +460,15 @@ static const struct regulator_ops max8998_buck_ops = {
|
||||
.set_voltage_time_sel = max8998_set_voltage_buck_time_sel,
|
||||
};
|
||||
|
||||
static const struct regulator_ops max8998_charger_ops = {
|
||||
.set_current_limit = max8998_set_current_limit,
|
||||
.get_current_limit = max8998_get_current_limit,
|
||||
.is_enabled = max8998_ldo_is_enabled_inverted,
|
||||
/* Swapped as register is inverted */
|
||||
.enable = max8998_ldo_disable,
|
||||
.disable = max8998_ldo_enable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops max8998_others_ops = {
|
||||
.is_enabled = max8998_ldo_is_enabled,
|
||||
.enable = max8998_ldo_enable,
|
||||
@ -397,6 +487,19 @@ static const struct regulator_ops max8998_others_ops = {
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
#define MAX8998_CURRENT_REG(_name, _ops, _table, _reg, _mask) \
|
||||
{ \
|
||||
.name = #_name, \
|
||||
.id = MAX8998_##_name, \
|
||||
.ops = _ops, \
|
||||
.curr_table = _table, \
|
||||
.n_current_limits = ARRAY_SIZE(_table), \
|
||||
.csel_reg = _reg, \
|
||||
.csel_mask = _mask, \
|
||||
.type = REGULATOR_CURRENT, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
#define MAX8998_OTHERS_REG(_name, _id) \
|
||||
{ \
|
||||
.name = #_name, \
|
||||
@ -432,6 +535,8 @@ static const struct regulator_desc regulators[] = {
|
||||
MAX8998_OTHERS_REG(ENVICHG, MAX8998_ENVICHG),
|
||||
MAX8998_OTHERS_REG(ESAFEOUT1, MAX8998_ESAFEOUT1),
|
||||
MAX8998_OTHERS_REG(ESAFEOUT2, MAX8998_ESAFEOUT2),
|
||||
MAX8998_CURRENT_REG(CHARGER, &max8998_charger_ops,
|
||||
charger_current_table, MAX8998_REG_CHGR1, 0x7),
|
||||
};
|
||||
|
||||
static int max8998_pmic_dt_parse_dvs_gpio(struct max8998_dev *iodev,
|
||||
|
@ -391,11 +391,11 @@ static const struct of_device_id mcp16502_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mcp16502_ids);
|
||||
|
||||
static const struct regulator_linear_range b1l12_ranges[] = {
|
||||
static const struct linear_range b1l12_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1200000, VDD_LOW_SEL, VDD_HIGH_SEL, 50000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range b234_ranges[] = {
|
||||
static const struct linear_range b234_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, VDD_LOW_SEL, VDD_HIGH_SEL, 25000),
|
||||
};
|
||||
|
||||
|
@ -73,7 +73,7 @@ static int mp8859_get_voltage_sel(struct regulator_dev *rdev)
|
||||
return val;
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range mp8859_dcdc_ranges[] = {
|
||||
static const struct linear_range mp8859_dcdc_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000),
|
||||
};
|
||||
|
||||
|
@ -102,15 +102,15 @@ struct mt6323_regulator_info {
|
||||
.modeset_mask = _modeset_mask, \
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range1[] = {
|
||||
static const struct linear_range buck_volt_range1[] = {
|
||||
REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range2[] = {
|
||||
static const struct linear_range buck_volt_range2[] = {
|
||||
REGULATOR_LINEAR_RANGE(1400000, 0, 0x7f, 12500),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range3[] = {
|
||||
static const struct linear_range buck_volt_range3[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
|
||||
};
|
||||
|
||||
|
@ -137,19 +137,19 @@ struct mt6358_regulator_info {
|
||||
.qi = BIT(15), \
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range1[] = {
|
||||
static const struct linear_range buck_volt_range1[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range2[] = {
|
||||
static const struct linear_range buck_volt_range2[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range3[] = {
|
||||
static const struct linear_range buck_volt_range3[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range4[] = {
|
||||
static const struct linear_range buck_volt_range4[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500),
|
||||
};
|
||||
|
||||
|
@ -152,15 +152,15 @@ struct mt6380_regulator_info {
|
||||
.modeset_mask = _modeset_mask, \
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range1[] = {
|
||||
static const struct linear_range buck_volt_range1[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 0xfe, 6250),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range2[] = {
|
||||
static const struct linear_range buck_volt_range2[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 0xfe, 6250),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range3[] = {
|
||||
static const struct linear_range buck_volt_range3[] = {
|
||||
REGULATOR_LINEAR_RANGE(1200000, 0, 0x3c, 25000),
|
||||
};
|
||||
|
||||
|
@ -102,15 +102,15 @@ struct mt6397_regulator_info {
|
||||
.qi = BIT(15), \
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range1[] = {
|
||||
static const struct linear_range buck_volt_range1[] = {
|
||||
REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range2[] = {
|
||||
static const struct linear_range buck_volt_range2[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0, 0x7f, 6250),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range3[] = {
|
||||
static const struct linear_range buck_volt_range3[] = {
|
||||
REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000),
|
||||
};
|
||||
|
||||
|
@ -22,14 +22,14 @@
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
|
||||
static const struct regulator_linear_range smps_low_ranges[] = {
|
||||
static const struct linear_range smps_low_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
|
||||
REGULATOR_LINEAR_RANGE(500000, 0x1, 0x6, 0),
|
||||
REGULATOR_LINEAR_RANGE(510000, 0x7, 0x79, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1650000, 0x7A, 0x7f, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range smps_high_ranges[] = {
|
||||
static const struct linear_range smps_high_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x6, 0),
|
||||
REGULATOR_LINEAR_RANGE(1020000, 0x7, 0x79, 20000),
|
||||
|
@ -86,7 +86,7 @@ enum rpmh_regulator_type {
|
||||
struct rpmh_vreg_hw_data {
|
||||
enum rpmh_regulator_type regulator_type;
|
||||
const struct regulator_ops *ops;
|
||||
const struct regulator_linear_range voltage_range;
|
||||
const struct linear_range voltage_range;
|
||||
int n_voltages;
|
||||
int hpm_min_load_uA;
|
||||
const int *pmic_mode_map;
|
||||
@ -832,11 +832,11 @@ static const struct rpmh_vreg_init_data pm8150_vreg_data[] = {
|
||||
RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l2-l10"),
|
||||
RPMH_VREG("ldo11", "ldo%s11", &pmic5_nldo, "vdd-l1-l8-l11"),
|
||||
RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"),
|
||||
RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l13-l6-l17"),
|
||||
RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l13-l16-l17"),
|
||||
RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"),
|
||||
RPMH_VREG("ldo15", "ldo%s15", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"),
|
||||
RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l13-l6-l17"),
|
||||
RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l13-l6-l17"),
|
||||
RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l13-l16-l17"),
|
||||
RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l13-l16-l17"),
|
||||
RPMH_VREG("ldo18", "ldo%s18", &pmic5_nldo, "vdd-l3-l4-l5-l18"),
|
||||
{},
|
||||
};
|
||||
@ -857,7 +857,7 @@ static const struct rpmh_vreg_init_data pm8150l_vreg_data[] = {
|
||||
RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l4-l5-l6"),
|
||||
RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l4-l5-l6"),
|
||||
RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-l11"),
|
||||
RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo_lv, "vdd-l1-l8-l11"),
|
||||
RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo_lv, "vdd-l1-l8"),
|
||||
RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l9-l10"),
|
||||
RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l9-l10"),
|
||||
RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l7-l11"),
|
||||
|
@ -148,41 +148,41 @@ static const struct rpm_reg_parts rpm8960_ncp_parts = {
|
||||
/*
|
||||
* Physically available PMIC regulator voltage ranges
|
||||
*/
|
||||
static const struct regulator_linear_range pldo_ranges[] = {
|
||||
static const struct linear_range pldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE( 750000, 0, 59, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 60, 123, 25000),
|
||||
REGULATOR_LINEAR_RANGE(3100000, 124, 160, 50000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range nldo_ranges[] = {
|
||||
static const struct linear_range nldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range nldo1200_ranges[] = {
|
||||
static const struct linear_range nldo1200_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE( 375000, 0, 59, 6250),
|
||||
REGULATOR_LINEAR_RANGE( 750000, 60, 123, 12500),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range smps_ranges[] = {
|
||||
static const struct linear_range smps_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE( 375000, 0, 29, 12500),
|
||||
REGULATOR_LINEAR_RANGE( 750000, 30, 89, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 90, 153, 25000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range ftsmps_ranges[] = {
|
||||
static const struct linear_range ftsmps_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE( 350000, 0, 6, 50000),
|
||||
REGULATOR_LINEAR_RANGE( 700000, 7, 63, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 64, 100, 50000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range smb208_ranges[] = {
|
||||
static const struct linear_range smb208_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE( 375000, 0, 29, 12500),
|
||||
REGULATOR_LINEAR_RANGE( 750000, 30, 89, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 90, 153, 25000),
|
||||
REGULATOR_LINEAR_RANGE(3100000, 154, 234, 25000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range ncp_ranges[] = {
|
||||
static const struct linear_range ncp_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1500000, 0, 31, 50000),
|
||||
};
|
||||
|
||||
@ -604,16 +604,6 @@ static const struct qcom_rpm_reg pm8921_smps = {
|
||||
.supports_force_mode_bypass = false,
|
||||
};
|
||||
|
||||
static const struct qcom_rpm_reg pm8921_ftsmps = {
|
||||
.desc.linear_ranges = ftsmps_ranges,
|
||||
.desc.n_linear_ranges = ARRAY_SIZE(ftsmps_ranges),
|
||||
.desc.n_voltages = 101,
|
||||
.desc.ops = &uV_ops,
|
||||
.parts = &rpm8960_smps_parts,
|
||||
.supports_force_mode_auto = true,
|
||||
.supports_force_mode_bypass = false,
|
||||
};
|
||||
|
||||
static const struct qcom_rpm_reg pm8921_ncp = {
|
||||
.desc.linear_ranges = ncp_ranges,
|
||||
.desc.n_linear_ranges = ARRAY_SIZE(ncp_ranges),
|
||||
|
@ -199,7 +199,7 @@ static const struct regulator_ops rpm_bob_ops = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pma8084_hfsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000),
|
||||
},
|
||||
@ -209,7 +209,7 @@ static const struct regulator_desc pma8084_hfsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pma8084_ftsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000),
|
||||
REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000),
|
||||
},
|
||||
@ -219,7 +219,7 @@ static const struct regulator_desc pma8084_ftsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pma8084_pldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000),
|
||||
REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000),
|
||||
@ -230,7 +230,7 @@ static const struct regulator_desc pma8084_pldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pma8084_nldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -243,7 +243,7 @@ static const struct regulator_desc pma8084_switch = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8x41_hfsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1575000, 96, 158, 25000),
|
||||
},
|
||||
@ -253,7 +253,7 @@ static const struct regulator_desc pm8x41_hfsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8841_ftsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000),
|
||||
REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000),
|
||||
},
|
||||
@ -263,7 +263,7 @@ static const struct regulator_desc pm8841_ftsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8941_boost = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(4000000, 0, 30, 50000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -272,7 +272,7 @@ static const struct regulator_desc pm8941_boost = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8941_pldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000),
|
||||
REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000),
|
||||
@ -283,7 +283,7 @@ static const struct regulator_desc pm8941_pldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8941_nldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -302,7 +302,7 @@ static const struct regulator_desc pm8941_switch = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8916_pldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -311,7 +311,7 @@ static const struct regulator_desc pm8916_pldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8916_nldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(375000, 0, 93, 12500),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -320,7 +320,7 @@ static const struct regulator_desc pm8916_nldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8916_buck_lvo_smps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500),
|
||||
REGULATOR_LINEAR_RANGE(750000, 96, 127, 25000),
|
||||
},
|
||||
@ -330,7 +330,7 @@ static const struct regulator_desc pm8916_buck_lvo_smps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8916_buck_hvo_smps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1550000, 0, 31, 25000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -339,7 +339,7 @@ static const struct regulator_desc pm8916_buck_hvo_smps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8950_hfsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1550000, 96, 127, 25000),
|
||||
},
|
||||
@ -349,7 +349,7 @@ static const struct regulator_desc pm8950_hfsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8950_ftsmps2p5 = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(80000, 0, 255, 5000),
|
||||
REGULATOR_LINEAR_RANGE(160000, 256, 460, 10000),
|
||||
},
|
||||
@ -359,7 +359,7 @@ static const struct regulator_desc pm8950_ftsmps2p5 = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8950_ult_nldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(375000, 0, 202, 12500),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -368,7 +368,7 @@ static const struct regulator_desc pm8950_ult_nldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8950_ult_pldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1750000, 0, 127, 12500),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -377,7 +377,7 @@ static const struct regulator_desc pm8950_ult_pldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8950_pldo_lv = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1500000, 0, 16, 25000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -386,7 +386,7 @@ static const struct regulator_desc pm8950_pldo_lv = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8950_pldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(975000, 0, 164, 12500),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -396,7 +396,7 @@ static const struct regulator_desc pm8950_pldo = {
|
||||
|
||||
|
||||
static const struct regulator_desc pm8994_hfsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000),
|
||||
},
|
||||
@ -406,7 +406,7 @@ static const struct regulator_desc pm8994_hfsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8994_ftsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(350000, 0, 199, 5000),
|
||||
REGULATOR_LINEAR_RANGE(700000, 200, 349, 10000),
|
||||
},
|
||||
@ -416,7 +416,7 @@ static const struct regulator_desc pm8994_ftsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8994_nldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -425,7 +425,7 @@ static const struct regulator_desc pm8994_nldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8994_pldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000),
|
||||
REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000),
|
||||
@ -446,7 +446,7 @@ static const struct regulator_desc pm8994_lnldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pmi8994_ftsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(350000, 0, 199, 5000),
|
||||
REGULATOR_LINEAR_RANGE(700000, 200, 349, 10000),
|
||||
},
|
||||
@ -456,7 +456,7 @@ static const struct regulator_desc pmi8994_ftsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pmi8994_hfsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(350000, 0, 80, 12500),
|
||||
REGULATOR_LINEAR_RANGE(700000, 81, 141, 25000),
|
||||
},
|
||||
@ -466,7 +466,7 @@ static const struct regulator_desc pmi8994_hfsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pmi8994_bby = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(3000000, 0, 44, 50000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -475,7 +475,7 @@ static const struct regulator_desc pmi8994_bby = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pmi8994_boost = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(4000000, 0, 30, 50000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -484,7 +484,7 @@ static const struct regulator_desc pmi8994_boost = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8998_ftsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -493,7 +493,7 @@ static const struct regulator_desc pm8998_ftsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8998_hfsmps = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -502,7 +502,7 @@ static const struct regulator_desc pm8998_hfsmps = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8998_nldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -511,7 +511,7 @@ static const struct regulator_desc pm8998_nldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8998_pldo = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -520,7 +520,7 @@ static const struct regulator_desc pm8998_pldo = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pm8998_pldo_lv = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -533,7 +533,7 @@ static const struct regulator_desc pm8998_switch = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pmi8998_bob = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -542,7 +542,7 @@ static const struct regulator_desc pmi8998_bob = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pms405_hfsmps3 = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -551,7 +551,7 @@ static const struct regulator_desc pms405_hfsmps3 = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pms405_nldo300 = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -560,7 +560,7 @@ static const struct regulator_desc pms405_nldo300 = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pms405_nldo1200 = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -569,7 +569,7 @@ static const struct regulator_desc pms405_nldo1200 = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pms405_pldo50 = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1664000, 0, 128, 16000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -578,7 +578,7 @@ static const struct regulator_desc pms405_pldo50 = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pms405_pldo150 = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1664000, 0, 128, 16000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
@ -587,7 +587,7 @@ static const struct regulator_desc pms405_pldo150 = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc pms405_pldo600 = {
|
||||
.linear_ranges = (struct regulator_linear_range[]) {
|
||||
.linear_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1256000, 0, 98, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
|
@ -165,14 +165,14 @@ static const int rk808_buck_config_regs[] = {
|
||||
RK808_BUCK4_CONFIG_REG,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = {
|
||||
static const struct linear_range rk808_ldo3_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000),
|
||||
REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
|
||||
};
|
||||
|
||||
#define RK809_BUCK5_SEL_CNT (8)
|
||||
|
||||
static const struct regulator_linear_range rk809_buck5_voltage_ranges[] = {
|
||||
static const struct linear_range rk809_buck5_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1500000, 0, 0, 0),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 1, 3, 200000),
|
||||
REGULATOR_LINEAR_RANGE(2800000, 4, 5, 200000),
|
||||
@ -201,14 +201,14 @@ static const struct regulator_linear_range rk809_buck5_voltage_ranges[] = {
|
||||
#define RK817_BUCK1_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK1_SEL1 + 1)
|
||||
#define RK817_BUCK3_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK3_SEL1 + 1)
|
||||
|
||||
static const struct regulator_linear_range rk817_buck1_voltage_ranges[] = {
|
||||
static const struct linear_range rk817_buck1_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
|
||||
RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
|
||||
REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
|
||||
RK817_BUCK1_SEL_CNT, RK817_BUCK1_STP1),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range rk817_buck3_voltage_ranges[] = {
|
||||
static const struct linear_range rk817_buck3_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
|
||||
RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
|
||||
REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
|
||||
@ -665,7 +665,7 @@ static const struct regulator_ops rk808_switch_ops = {
|
||||
.set_suspend_disable = rk808_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range rk805_buck_1_2_voltage_ranges[] = {
|
||||
static const struct linear_range rk805_buck_1_2_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),
|
||||
REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0),
|
||||
|
@ -749,37 +749,37 @@ static const struct regulator_ops s2mps15_reg_buck_ops = {
|
||||
}
|
||||
|
||||
/* voltage range for s2mps15 LDO 3, 5, 15, 16, 18, 20, 23 and 27 */
|
||||
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges1[] = {
|
||||
static const struct linear_range s2mps15_ldo_voltage_ranges1[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0xc, 0x38, 25000),
|
||||
};
|
||||
|
||||
/* voltage range for s2mps15 LDO 2, 6, 14, 17, 19, 21, 24 and 25 */
|
||||
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges2[] = {
|
||||
static const struct linear_range s2mps15_ldo_voltage_ranges2[] = {
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0x0, 0x3f, 25000),
|
||||
};
|
||||
|
||||
/* voltage range for s2mps15 LDO 4, 11, 12, 13, 22 and 26 */
|
||||
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges3[] = {
|
||||
static const struct linear_range s2mps15_ldo_voltage_ranges3[] = {
|
||||
REGULATOR_LINEAR_RANGE(700000, 0x0, 0x34, 12500),
|
||||
};
|
||||
|
||||
/* voltage range for s2mps15 LDO 7, 8, 9 and 10 */
|
||||
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges4[] = {
|
||||
static const struct linear_range s2mps15_ldo_voltage_ranges4[] = {
|
||||
REGULATOR_LINEAR_RANGE(700000, 0x10, 0x20, 25000),
|
||||
};
|
||||
|
||||
/* voltage range for s2mps15 LDO 1 */
|
||||
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges5[] = {
|
||||
static const struct linear_range s2mps15_ldo_voltage_ranges5[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0x0, 0x20, 12500),
|
||||
};
|
||||
|
||||
/* voltage range for s2mps15 BUCK 1, 2, 3, 4, 5, 6 and 7 */
|
||||
static const struct regulator_linear_range s2mps15_buck_voltage_ranges1[] = {
|
||||
static const struct linear_range s2mps15_buck_voltage_ranges1[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0x20, 0xc0, 6250),
|
||||
};
|
||||
|
||||
/* voltage range for s2mps15 BUCK 8, 9 and 10 */
|
||||
static const struct regulator_linear_range s2mps15_buck_voltage_ranges2[] = {
|
||||
static const struct linear_range s2mps15_buck_voltage_ranges2[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0x20, 0x78, 12500),
|
||||
};
|
||||
|
||||
|
@ -32,7 +32,7 @@ static const struct regulator_ops sky81452_reg_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range sky81452_reg_ranges[] = {
|
||||
static const struct linear_range sky81452_reg_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(4500000, 0, 14, 250000),
|
||||
REGULATOR_LINEAR_RANGE(9000000, 15, 31, 1000000),
|
||||
};
|
||||
|
@ -57,13 +57,13 @@ enum {
|
||||
/* Ramp delay worst case is (2250uV/uS) */
|
||||
#define PMIC_RAMP_DELAY 2200
|
||||
|
||||
static const struct regulator_linear_range buck1_ranges[] = {
|
||||
static const struct linear_range buck1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(725000, 0, 4, 0),
|
||||
REGULATOR_LINEAR_RANGE(725000, 5, 36, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 37, 63, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck2_ranges[] = {
|
||||
static const struct linear_range buck2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0, 17, 0),
|
||||
REGULATOR_LINEAR_RANGE(1050000, 18, 19, 0),
|
||||
REGULATOR_LINEAR_RANGE(1100000, 20, 21, 0),
|
||||
@ -77,7 +77,7 @@ static const struct regulator_linear_range buck2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1500000, 36, 63, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck3_ranges[] = {
|
||||
static const struct linear_range buck3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0, 19, 0),
|
||||
REGULATOR_LINEAR_RANGE(1100000, 20, 23, 0),
|
||||
REGULATOR_LINEAR_RANGE(1200000, 24, 27, 0),
|
||||
@ -87,7 +87,7 @@ static const struct regulator_linear_range buck3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(3400000, 56, 63, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range buck4_ranges[] = {
|
||||
static const struct linear_range buck4_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 27, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0),
|
||||
REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0),
|
||||
@ -97,19 +97,19 @@ static const struct regulator_linear_range buck4_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(3900000, 61, 63, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range ldo1_ranges[] = {
|
||||
static const struct linear_range ldo1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range ldo2_ranges[] = {
|
||||
static const struct linear_range ldo2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range ldo3_ranges[] = {
|
||||
static const struct linear_range ldo3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
|
||||
@ -117,13 +117,13 @@ static const struct regulator_linear_range ldo3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 31, 31, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range ldo5_ranges[] = {
|
||||
static const struct linear_range ldo5_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 8, 30, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3900000, 31, 31, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range ldo6_ranges[] = {
|
||||
static const struct linear_range ldo6_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
|
||||
};
|
||||
|
@ -71,23 +71,23 @@ struct tps65086_regulator {
|
||||
unsigned int decay_mask;
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range tps65086_10mv_ranges[] = {
|
||||
static const struct linear_range tps65086_10mv_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
|
||||
REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range tps65086_buck126_25mv_ranges[] = {
|
||||
static const struct linear_range tps65086_buck126_25mv_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x18, 0),
|
||||
REGULATOR_LINEAR_RANGE(1025000, 0x19, 0x7F, 25000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range tps65086_buck345_25mv_ranges[] = {
|
||||
static const struct linear_range tps65086_buck345_25mv_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
|
||||
REGULATOR_LINEAR_RANGE(425000, 0x1, 0x7F, 25000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range tps65086_ldoa1_ranges[] = {
|
||||
static const struct linear_range tps65086_ldoa1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1350000, 0x0, 0x0, 0),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 0x1, 0x7, 100000),
|
||||
REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xB, 100000),
|
||||
@ -95,7 +95,7 @@ static const struct regulator_linear_range tps65086_ldoa1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(3300000, 0xE, 0xE, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range tps65086_ldoa23_ranges[] = {
|
||||
static const struct linear_range tps65086_ldoa23_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(700000, 0x0, 0xD, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1400000, 0xE, 0xF, 100000),
|
||||
};
|
||||
|
@ -56,14 +56,14 @@ static const unsigned int LDO1_VSEL_table[] = {
|
||||
2800000, 3000000, 3100000, 3300000,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range tps65217_uv1_ranges[] = {
|
||||
static const struct linear_range tps65217_uv1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 24, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1550000, 25, 52, 50000),
|
||||
REGULATOR_LINEAR_RANGE(3000000, 53, 55, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 56, 63, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range tps65217_uv2_ranges[] = {
|
||||
static const struct linear_range tps65217_uv2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1500000, 0, 8, 50000),
|
||||
REGULATOR_LINEAR_RANGE(2000000, 9, 13, 100000),
|
||||
REGULATOR_LINEAR_RANGE(2450000, 14, 31, 50000),
|
||||
|
@ -56,17 +56,17 @@
|
||||
.bypass_mask = _sm, \
|
||||
} \
|
||||
|
||||
static const struct regulator_linear_range dcdc1_dcdc2_ranges[] = {
|
||||
static const struct linear_range dcdc1_dcdc2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(850000, 0x0, 0x32, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1375000, 0x33, 0x3f, 25000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range ldo1_dcdc3_ranges[] = {
|
||||
static const struct linear_range ldo1_dcdc3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0x0, 0x1a, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1600000, 0x1b, 0x3f, 50000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range dcdc4_ranges[] = {
|
||||
static const struct linear_range dcdc4_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000),
|
||||
};
|
||||
|
@ -46,11 +46,11 @@ enum tps65912_regulators { DCDC1, DCDC2, DCDC3, DCDC4, LDO1, LDO2, LDO3,
|
||||
.n_linear_ranges = ARRAY_SIZE(_lr), \
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range tps65912_dcdc_ranges[] = {
|
||||
static const struct linear_range tps65912_dcdc_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0x0, 0x3f, 50000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range tps65912_ldo_ranges[] = {
|
||||
static const struct linear_range tps65912_ldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0x0, 0x20, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1650000, 0x21, 0x3c, 50000),
|
||||
REGULATOR_LINEAR_RANGE(3100000, 0x3d, 0x3f, 100000),
|
||||
|
@ -271,7 +271,7 @@ static int tps80031_vbus_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
|
||||
struct device *parent = to_tps80031_dev(rdev);
|
||||
int ret = -EIO;
|
||||
int ret;
|
||||
uint8_t ctrl1 = 0;
|
||||
uint8_t ctrl3 = 0;
|
||||
|
||||
@ -322,7 +322,7 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
|
||||
struct device *parent = to_tps80031_dev(rdev);
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (ri->config_flags & TPS80031_VBUS_DISCHRG_EN_PDN) {
|
||||
ret = tps80031_write(parent, TPS80031_SLAVE_ID2,
|
||||
@ -530,7 +530,8 @@ static int tps80031_regulator_config(struct device *parent,
|
||||
case TPS80031_REGULATOR_LDOUSB:
|
||||
if (ri->config_flags & (TPS80031_USBLDO_INPUT_VSYS |
|
||||
TPS80031_USBLDO_INPUT_PMID)) {
|
||||
unsigned val = 0;
|
||||
unsigned val;
|
||||
|
||||
if (ri->config_flags & TPS80031_USBLDO_INPUT_VSYS)
|
||||
val = MISC2_LDOUSB_IN_VSYS;
|
||||
else
|
||||
|
@ -360,12 +360,12 @@ static const u16 VINTANA2_VSEL_table[] = {
|
||||
};
|
||||
|
||||
/* 600mV to 1450mV in 12.5 mV steps */
|
||||
static const struct regulator_linear_range VDD1_ranges[] = {
|
||||
static const struct linear_range VDD1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 68, 12500)
|
||||
};
|
||||
|
||||
/* 600mV to 1450mV in 12.5 mV steps, everything above = 1500mV */
|
||||
static const struct regulator_linear_range VDD2_ranges[] = {
|
||||
static const struct linear_range VDD2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 68, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 69, 69, 12500)
|
||||
};
|
||||
|
@ -495,7 +495,7 @@ static const struct regulator_ops twlsmps_ops = {
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static const struct regulator_linear_range twl6030ldo_linear_range[] = {
|
||||
static const struct linear_range twl6030ldo_linear_range[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0, 0, 0),
|
||||
REGULATOR_LINEAR_RANGE(1000000, 1, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(2750000, 31, 31, 0),
|
||||
|
@ -204,7 +204,7 @@ static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data)
|
||||
* BUCKV specifics
|
||||
*/
|
||||
|
||||
static const struct regulator_linear_range wm831x_buckv_ranges[] = {
|
||||
static const struct linear_range wm831x_buckv_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 0x7, 0),
|
||||
REGULATOR_LINEAR_RANGE(600000, 0x8, 0x68, 12500),
|
||||
};
|
||||
|
@ -59,7 +59,7 @@ static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
|
||||
* General purpose LDOs
|
||||
*/
|
||||
|
||||
static const struct regulator_linear_range wm831x_gp_ldo_ranges[] = {
|
||||
static const struct linear_range wm831x_gp_ldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 14, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000),
|
||||
};
|
||||
@ -312,7 +312,7 @@ static struct platform_driver wm831x_gp_ldo_driver = {
|
||||
* Analogue LDOs
|
||||
*/
|
||||
|
||||
static const struct regulator_linear_range wm831x_aldo_ranges[] = {
|
||||
static const struct linear_range wm831x_aldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0, 12, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 13, 31, 100000),
|
||||
};
|
||||
|
@ -470,7 +470,7 @@ static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range wm8350_ldo_ranges[] = {
|
||||
static const struct linear_range wm8350_ldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 15, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 16, 31, 100000),
|
||||
};
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/mfd/wm8400-private.h>
|
||||
|
||||
static const struct regulator_linear_range wm8400_ldo_ranges[] = {
|
||||
static const struct linear_range wm8400_ldo_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 14, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000),
|
||||
};
|
||||
|
48
include/linux/linear_range.h
Normal file
48
include/linux/linear_range.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2020 ROHM Semiconductors */
|
||||
|
||||
#ifndef LINEAR_RANGE_H
|
||||
#define LINEAR_RANGE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/**
|
||||
* struct linear_range - table of selector - value pairs
|
||||
*
|
||||
* Define a lookup-table for range of values. Intended to help when looking
|
||||
* for a register value matching certaing physical measure (like voltage).
|
||||
* Usable when increment of one in register always results a constant increment
|
||||
* of the physical measure (like voltage).
|
||||
*
|
||||
* @min: Lowest value in range
|
||||
* @min_sel: Lowest selector for range
|
||||
* @max_sel: Highest selector for range
|
||||
* @step: Value step size
|
||||
*/
|
||||
struct linear_range {
|
||||
unsigned int min;
|
||||
unsigned int min_sel;
|
||||
unsigned int max_sel;
|
||||
unsigned int step;
|
||||
};
|
||||
|
||||
unsigned int linear_range_values_in_range(const struct linear_range *r);
|
||||
unsigned int linear_range_values_in_range_array(const struct linear_range *r,
|
||||
int ranges);
|
||||
unsigned int linear_range_get_max_value(const struct linear_range *r);
|
||||
|
||||
int linear_range_get_value(const struct linear_range *r, unsigned int selector,
|
||||
unsigned int *val);
|
||||
int linear_range_get_value_array(const struct linear_range *r, int ranges,
|
||||
unsigned int selector, unsigned int *val);
|
||||
int linear_range_get_selector_low(const struct linear_range *r,
|
||||
unsigned int val, unsigned int *selector,
|
||||
bool *found);
|
||||
int linear_range_get_selector_high(const struct linear_range *r,
|
||||
unsigned int val, unsigned int *selector,
|
||||
bool *found);
|
||||
int linear_range_get_selector_low_array(const struct linear_range *r,
|
||||
int ranges, unsigned int val,
|
||||
unsigned int *selector, bool *found);
|
||||
|
||||
#endif
|
@ -39,6 +39,7 @@ enum {
|
||||
MAX8998_ENVICHG,
|
||||
MAX8998_ESAFEOUT1,
|
||||
MAX8998_ESAFEOUT2,
|
||||
MAX8998_CHARGER,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -62,6 +62,8 @@ int regulator_get_voltage_rdev(struct regulator_dev *rdev);
|
||||
int regulator_set_voltage_rdev(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV,
|
||||
suspend_state_t state);
|
||||
int regulator_do_balance_voltage(struct regulator_dev *rdev,
|
||||
suspend_state_t state, bool skip_coupled);
|
||||
#else
|
||||
static inline int regulator_coupler_register(struct regulator_coupler *coupler)
|
||||
{
|
||||
@ -92,6 +94,12 @@ static inline int regulator_set_voltage_rdev(struct regulator_dev *rdev,
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int regulator_do_balance_voltage(struct regulator_dev *rdev,
|
||||
suspend_state_t state,
|
||||
bool skip_coupled)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define __LINUX_REGULATOR_DRIVER_H_
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/linear_range.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/ww_mutex.h>
|
||||
@ -39,31 +40,13 @@ enum regulator_status {
|
||||
REGULATOR_STATUS_UNDEFINED,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct regulator_linear_range - specify linear voltage ranges
|
||||
*
|
||||
* Specify a range of voltages for regulator_map_linear_range() and
|
||||
* regulator_list_linear_range().
|
||||
*
|
||||
* @min_uV: Lowest voltage in range
|
||||
* @min_sel: Lowest selector for range
|
||||
* @max_sel: Highest selector for range
|
||||
* @uV_step: Step size
|
||||
*/
|
||||
struct regulator_linear_range {
|
||||
unsigned int min_uV;
|
||||
unsigned int min_sel;
|
||||
unsigned int max_sel;
|
||||
unsigned int uV_step;
|
||||
};
|
||||
|
||||
/* Initialize struct regulator_linear_range */
|
||||
/* Initialize struct linear_range for regulators */
|
||||
#define REGULATOR_LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV) \
|
||||
{ \
|
||||
.min_uV = _min_uV, \
|
||||
.min = _min_uV, \
|
||||
.min_sel = _min_sel, \
|
||||
.max_sel = _max_sel, \
|
||||
.uV_step = _step_uV, \
|
||||
.step = _step_uV, \
|
||||
}
|
||||
|
||||
/**
|
||||
@ -348,7 +331,7 @@ struct regulator_desc {
|
||||
unsigned int ramp_delay;
|
||||
int min_dropout_uV;
|
||||
|
||||
const struct regulator_linear_range *linear_ranges;
|
||||
const struct linear_range *linear_ranges;
|
||||
const unsigned int *linear_range_selectors;
|
||||
|
||||
int n_linear_ranges;
|
||||
|
@ -70,6 +70,38 @@ DEFINE_EVENT(regulator_basic, regulator_disable_complete,
|
||||
|
||||
);
|
||||
|
||||
DEFINE_EVENT(regulator_basic, regulator_bypass_enable,
|
||||
|
||||
TP_PROTO(const char *name),
|
||||
|
||||
TP_ARGS(name)
|
||||
|
||||
);
|
||||
|
||||
DEFINE_EVENT(regulator_basic, regulator_bypass_enable_complete,
|
||||
|
||||
TP_PROTO(const char *name),
|
||||
|
||||
TP_ARGS(name)
|
||||
|
||||
);
|
||||
|
||||
DEFINE_EVENT(regulator_basic, regulator_bypass_disable,
|
||||
|
||||
TP_PROTO(const char *name),
|
||||
|
||||
TP_ARGS(name)
|
||||
|
||||
);
|
||||
|
||||
DEFINE_EVENT(regulator_basic, regulator_bypass_disable_complete,
|
||||
|
||||
TP_PROTO(const char *name),
|
||||
|
||||
TP_ARGS(name)
|
||||
|
||||
);
|
||||
|
||||
/*
|
||||
* Events that take a range of numerical values, mostly for voltages
|
||||
* and so on.
|
||||
|
@ -19,6 +19,9 @@ config RAID6_PQ_BENCHMARK
|
||||
Benchmark all available RAID6 PQ functions on init and choose the
|
||||
fastest one.
|
||||
|
||||
config LINEAR_RANGES
|
||||
tristate
|
||||
|
||||
config PACKING
|
||||
bool "Generic bitfield packing and unpacking"
|
||||
default n
|
||||
|
@ -2092,6 +2092,18 @@ config LIST_KUNIT_TEST
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config LINEAR_RANGES_TEST
|
||||
tristate "KUnit test for linear_ranges"
|
||||
depends on KUNIT
|
||||
select LINEAR_RANGES
|
||||
help
|
||||
This builds the linear_ranges unit test, which runs on boot.
|
||||
Tests the linear_ranges logic correctness.
|
||||
For more information on KUnit and unit tests in general please refer
|
||||
to the KUnit documentation in Documentation/dev-tools/kunit/.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config TEST_UDELAY
|
||||
tristate "udelay test driver"
|
||||
help
|
||||
|
@ -125,6 +125,7 @@ obj-$(CONFIG_DEBUG_LIST) += list_debug.o
|
||||
obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o
|
||||
|
||||
obj-$(CONFIG_BITREVERSE) += bitrev.o
|
||||
obj-$(CONFIG_LINEAR_RANGES) += linear_ranges.o
|
||||
obj-$(CONFIG_PACKING) += packing.o
|
||||
obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
|
||||
obj-$(CONFIG_CRC16) += crc16.o
|
||||
@ -309,3 +310,4 @@ obj-$(CONFIG_OBJAGG) += objagg.o
|
||||
|
||||
# KUnit tests
|
||||
obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
|
||||
obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
|
||||
|
245
lib/linear_ranges.c
Normal file
245
lib/linear_ranges.c
Normal file
@ -0,0 +1,245 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* helpers to map values in a linear range to range index
|
||||
*
|
||||
* Original idea borrowed from regulator framework
|
||||
*
|
||||
* It might be useful if we could support also inversely proportional ranges?
|
||||
* Copyright 2020 ROHM Semiconductors
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/linear_range.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/**
|
||||
* linear_range_values_in_range - return the amount of values in a range
|
||||
* @r: pointer to linear range where values are counted
|
||||
*
|
||||
* Compute the amount of values in range pointed by @r. Note, values can
|
||||
* be all equal - range with selectors 0,...,2 with step 0 still contains
|
||||
* 3 values even though they are all equal.
|
||||
*
|
||||
* Return: the amount of values in range pointed by @r
|
||||
*/
|
||||
unsigned int linear_range_values_in_range(const struct linear_range *r)
|
||||
{
|
||||
if (!r)
|
||||
return 0;
|
||||
return r->max_sel - r->min_sel + 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(linear_range_values_in_range);
|
||||
|
||||
/**
|
||||
* linear_range_values_in_range_array - return the amount of values in ranges
|
||||
* @r: pointer to array of linear ranges where values are counted
|
||||
* @ranges: amount of ranges we include in computation.
|
||||
*
|
||||
* Compute the amount of values in ranges pointed by @r. Note, values can
|
||||
* be all equal - range with selectors 0,...,2 with step 0 still contains
|
||||
* 3 values even though they are all equal.
|
||||
*
|
||||
* Return: the amount of values in first @ranges ranges pointed by @r
|
||||
*/
|
||||
unsigned int linear_range_values_in_range_array(const struct linear_range *r,
|
||||
int ranges)
|
||||
{
|
||||
int i, values_in_range = 0;
|
||||
|
||||
for (i = 0; i < ranges; i++) {
|
||||
int values;
|
||||
|
||||
values = linear_range_values_in_range(&r[i]);
|
||||
if (!values)
|
||||
return values;
|
||||
|
||||
values_in_range += values;
|
||||
}
|
||||
return values_in_range;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(linear_range_values_in_range_array);
|
||||
|
||||
/**
|
||||
* linear_range_get_max_value - return the largest value in a range
|
||||
* @r: pointer to linear range where value is looked from
|
||||
*
|
||||
* Return: the largest value in the given range
|
||||
*/
|
||||
unsigned int linear_range_get_max_value(const struct linear_range *r)
|
||||
{
|
||||
return r->min + (r->max_sel - r->min_sel) * r->step;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(linear_range_get_max_value);
|
||||
|
||||
/**
|
||||
* linear_range_get_value - fetch a value from given range
|
||||
* @r: pointer to linear range where value is looked from
|
||||
* @selector: selector for which the value is searched
|
||||
* @val: address where found value is updated
|
||||
*
|
||||
* Search given ranges for value which matches given selector.
|
||||
*
|
||||
* Return: 0 on success, -EINVAL given selector is not found from any of the
|
||||
* ranges.
|
||||
*/
|
||||
int linear_range_get_value(const struct linear_range *r, unsigned int selector,
|
||||
unsigned int *val)
|
||||
{
|
||||
if (r->min_sel > selector || r->max_sel < selector)
|
||||
return -EINVAL;
|
||||
|
||||
*val = r->min + (selector - r->min_sel) * r->step;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(linear_range_get_value);
|
||||
|
||||
/**
|
||||
* linear_range_get_value_array - fetch a value from array of ranges
|
||||
* @r: pointer to array of linear ranges where value is looked from
|
||||
* @ranges: amount of ranges in an array
|
||||
* @selector: selector for which the value is searched
|
||||
* @val: address where found value is updated
|
||||
*
|
||||
* Search through an array of ranges for value which matches given selector.
|
||||
*
|
||||
* Return: 0 on success, -EINVAL given selector is not found from any of the
|
||||
* ranges.
|
||||
*/
|
||||
int linear_range_get_value_array(const struct linear_range *r, int ranges,
|
||||
unsigned int selector, unsigned int *val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ranges; i++)
|
||||
if (r[i].min_sel <= selector && r[i].max_sel >= selector)
|
||||
return linear_range_get_value(&r[i], selector, val);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(linear_range_get_value_array);
|
||||
|
||||
/**
|
||||
* linear_range_get_selector_low - return linear range selector for value
|
||||
* @r: pointer to linear range where selector is looked from
|
||||
* @val: value for which the selector is searched
|
||||
* @selector: address where found selector value is updated
|
||||
* @found: flag to indicate that given value was in the range
|
||||
*
|
||||
* Return selector which which range value is closest match for given
|
||||
* input value. Value is matching if it is equal or smaller than given
|
||||
* value. If given value is in the range, then @found is set true.
|
||||
*
|
||||
* Return: 0 on success, -EINVAL if range is invalid or does not contain
|
||||
* value smaller or equal to given value
|
||||
*/
|
||||
int linear_range_get_selector_low(const struct linear_range *r,
|
||||
unsigned int val, unsigned int *selector,
|
||||
bool *found)
|
||||
{
|
||||
*found = false;
|
||||
|
||||
if (r->min > val)
|
||||
return -EINVAL;
|
||||
|
||||
if (linear_range_get_max_value(r) < val) {
|
||||
*selector = r->max_sel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*found = true;
|
||||
|
||||
if (r->step == 0)
|
||||
*selector = r->min_sel;
|
||||
else
|
||||
*selector = (val - r->min) / r->step + r->min_sel;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(linear_range_get_selector_low);
|
||||
|
||||
/**
|
||||
* linear_range_get_selector_low_array - return linear range selector for value
|
||||
* @r: pointer to array of linear ranges where selector is looked from
|
||||
* @ranges: amount of ranges to scan from array
|
||||
* @val: value for which the selector is searched
|
||||
* @selector: address where found selector value is updated
|
||||
* @found: flag to indicate that given value was in the range
|
||||
*
|
||||
* Scan array of ranges for selector which which range value matches given
|
||||
* input value. Value is matching if it is equal or smaller than given
|
||||
* value. If given value is found to be in a range scanning is stopped and
|
||||
* @found is set true. If a range with values smaller than given value is found
|
||||
* but the range max is being smaller than given value, then the ranges
|
||||
* biggest selector is updated to @selector but scanning ranges is continued
|
||||
* and @found is set to false.
|
||||
*
|
||||
* Return: 0 on success, -EINVAL if range array is invalid or does not contain
|
||||
* range with a value smaller or equal to given value
|
||||
*/
|
||||
int linear_range_get_selector_low_array(const struct linear_range *r,
|
||||
int ranges, unsigned int val,
|
||||
unsigned int *selector, bool *found)
|
||||
{
|
||||
int i;
|
||||
int ret = -EINVAL;
|
||||
|
||||
for (i = 0; i < ranges; i++) {
|
||||
int tmpret;
|
||||
|
||||
tmpret = linear_range_get_selector_low(&r[i], val, selector,
|
||||
found);
|
||||
if (!tmpret)
|
||||
ret = 0;
|
||||
|
||||
if (*found)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(linear_range_get_selector_low_array);
|
||||
|
||||
/**
|
||||
* linear_range_get_selector_high - return linear range selector for value
|
||||
* @r: pointer to linear range where selector is looked from
|
||||
* @val: value for which the selector is searched
|
||||
* @selector: address where found selector value is updated
|
||||
* @found: flag to indicate that given value was in the range
|
||||
*
|
||||
* Return selector which which range value is closest match for given
|
||||
* input value. Value is matching if it is equal or higher than given
|
||||
* value. If given value is in the range, then @found is set true.
|
||||
*
|
||||
* Return: 0 on success, -EINVAL if range is invalid or does not contain
|
||||
* value greater or equal to given value
|
||||
*/
|
||||
int linear_range_get_selector_high(const struct linear_range *r,
|
||||
unsigned int val, unsigned int *selector,
|
||||
bool *found)
|
||||
{
|
||||
*found = false;
|
||||
|
||||
if (linear_range_get_max_value(r) < val)
|
||||
return -EINVAL;
|
||||
|
||||
if (r->min > val) {
|
||||
*selector = r->min_sel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*found = true;
|
||||
|
||||
if (r->step == 0)
|
||||
*selector = r->max_sel;
|
||||
else
|
||||
*selector = DIV_ROUND_UP(val - r->min, r->step) + r->min_sel;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(linear_range_get_selector_high);
|
||||
|
||||
MODULE_DESCRIPTION("linear-ranges helper");
|
||||
MODULE_LICENSE("GPL");
|
228
lib/test_linear_ranges.c
Normal file
228
lib/test_linear_ranges.c
Normal file
@ -0,0 +1,228 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* KUnit test for the linear_ranges helper.
|
||||
*
|
||||
* Copyright (C) 2020, ROHM Semiconductors.
|
||||
* Author: Matti Vaittinen <matti.vaittien@fi.rohmeurope.com>
|
||||
*/
|
||||
#include <kunit/test.h>
|
||||
|
||||
#include <linux/linear_range.h>
|
||||
|
||||
/* First things first. I deeply dislike unit-tests. I have seen all the hell
|
||||
* breaking loose when people who think the unit tests are "the silver bullet"
|
||||
* to kill bugs get to decide how a company should implement testing strategy...
|
||||
*
|
||||
* Believe me, it may get _really_ ridiculous. It is tempting to think that
|
||||
* walking through all the possible execution branches will nail down 100% of
|
||||
* bugs. This may lead to ideas about demands to get certain % of "test
|
||||
* coverage" - measured as line coverage. And that is one of the worst things
|
||||
* you can do.
|
||||
*
|
||||
* Ask people to provide line coverage and they do. I've seen clever tools
|
||||
* which generate test cases to test the existing functions - and by default
|
||||
* these tools expect code to be correct and just generate checks which are
|
||||
* passing when ran against current code-base. Run this generator and you'll get
|
||||
* tests that do not test code is correct but just verify nothing changes.
|
||||
* Problem is that testing working code is pointless. And if it is not
|
||||
* working, your test must not assume it is working. You won't catch any bugs
|
||||
* by such tests. What you can do is to generate a huge amount of tests.
|
||||
* Especially if you were are asked to proivde 100% line-coverage x_x. So what
|
||||
* does these tests - which are not finding any bugs now - do?
|
||||
*
|
||||
* They add inertia to every future development. I think it was Terry Pratchet
|
||||
* who wrote someone having same impact as thick syrup has to chronometre.
|
||||
* Excessive amount of unit-tests have this effect to development. If you do
|
||||
* actually find _any_ bug from code in such environment and try fixing it...
|
||||
* ...chances are you also need to fix the test cases. In sunny day you fix one
|
||||
* test. But I've done refactoring which resulted 500+ broken tests (which had
|
||||
* really zero value other than proving to managers that we do do "quality")...
|
||||
*
|
||||
* After this being said - there are situations where UTs can be handy. If you
|
||||
* have algorithms which take some input and should produce output - then you
|
||||
* can implement few, carefully selected simple UT-cases which test this. I've
|
||||
* previously used this for example for netlink and device-tree data parsing
|
||||
* functions. Feed some data examples to functions and verify the output is as
|
||||
* expected. I am not covering all the cases but I will see the logic should be
|
||||
* working.
|
||||
*
|
||||
* Here we also do some minor testing. I don't want to go through all branches
|
||||
* or test more or less obvious things - but I want to see the main logic is
|
||||
* working. And I definitely don't want to add 500+ test cases that break when
|
||||
* some simple fix is done x_x. So - let's only add few, well selected tests
|
||||
* which ensure as much logic is good as possible.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Test Range 1:
|
||||
* selectors: 2 3 4 5 6
|
||||
* values (5): 10 20 30 40 50
|
||||
*
|
||||
* Test Range 2:
|
||||
* selectors: 7 8 9 10
|
||||
* values (4): 100 150 200 250
|
||||
*/
|
||||
|
||||
#define RANGE1_MIN 10
|
||||
#define RANGE1_MIN_SEL 2
|
||||
#define RANGE1_STEP 10
|
||||
|
||||
/* 2, 3, 4, 5, 6 */
|
||||
static const unsigned int range1_sels[] = { RANGE1_MIN_SEL, RANGE1_MIN_SEL + 1,
|
||||
RANGE1_MIN_SEL + 2,
|
||||
RANGE1_MIN_SEL + 3,
|
||||
RANGE1_MIN_SEL + 4 };
|
||||
/* 10, 20, 30, 40, 50 */
|
||||
static const unsigned int range1_vals[] = { RANGE1_MIN, RANGE1_MIN +
|
||||
RANGE1_STEP,
|
||||
RANGE1_MIN + RANGE1_STEP * 2,
|
||||
RANGE1_MIN + RANGE1_STEP * 3,
|
||||
RANGE1_MIN + RANGE1_STEP * 4 };
|
||||
|
||||
#define RANGE2_MIN 100
|
||||
#define RANGE2_MIN_SEL 7
|
||||
#define RANGE2_STEP 50
|
||||
|
||||
/* 7, 8, 9, 10 */
|
||||
static const unsigned int range2_sels[] = { RANGE2_MIN_SEL, RANGE2_MIN_SEL + 1,
|
||||
RANGE2_MIN_SEL + 2,
|
||||
RANGE2_MIN_SEL + 3 };
|
||||
/* 100, 150, 200, 250 */
|
||||
static const unsigned int range2_vals[] = { RANGE2_MIN, RANGE2_MIN +
|
||||
RANGE2_STEP,
|
||||
RANGE2_MIN + RANGE2_STEP * 2,
|
||||
RANGE2_MIN + RANGE2_STEP * 3 };
|
||||
|
||||
#define RANGE1_NUM_VALS (ARRAY_SIZE(range1_vals))
|
||||
#define RANGE2_NUM_VALS (ARRAY_SIZE(range2_vals))
|
||||
#define RANGE_NUM_VALS (RANGE1_NUM_VALS + RANGE2_NUM_VALS)
|
||||
|
||||
#define RANGE1_MAX_SEL (RANGE1_MIN_SEL + RANGE1_NUM_VALS - 1)
|
||||
#define RANGE1_MAX_VAL (range1_vals[RANGE1_NUM_VALS - 1])
|
||||
|
||||
#define RANGE2_MAX_SEL (RANGE2_MIN_SEL + RANGE2_NUM_VALS - 1)
|
||||
#define RANGE2_MAX_VAL (range2_vals[RANGE2_NUM_VALS - 1])
|
||||
|
||||
#define SMALLEST_SEL RANGE1_MIN_SEL
|
||||
#define SMALLEST_VAL RANGE1_MIN
|
||||
|
||||
static struct linear_range testr[] = {
|
||||
{
|
||||
.min = RANGE1_MIN,
|
||||
.min_sel = RANGE1_MIN_SEL,
|
||||
.max_sel = RANGE1_MAX_SEL,
|
||||
.step = RANGE1_STEP,
|
||||
}, {
|
||||
.min = RANGE2_MIN,
|
||||
.min_sel = RANGE2_MIN_SEL,
|
||||
.max_sel = RANGE2_MAX_SEL,
|
||||
.step = RANGE2_STEP
|
||||
},
|
||||
};
|
||||
|
||||
static void range_test_get_value(struct kunit *test)
|
||||
{
|
||||
int ret, i;
|
||||
unsigned int sel, val;
|
||||
|
||||
for (i = 0; i < RANGE1_NUM_VALS; i++) {
|
||||
sel = range1_sels[i];
|
||||
ret = linear_range_get_value_array(&testr[0], 2, sel, &val);
|
||||
KUNIT_EXPECT_EQ(test, 0, ret);
|
||||
KUNIT_EXPECT_EQ(test, val, range1_vals[i]);
|
||||
}
|
||||
for (i = 0; i < RANGE2_NUM_VALS; i++) {
|
||||
sel = range2_sels[i];
|
||||
ret = linear_range_get_value_array(&testr[0], 2, sel, &val);
|
||||
KUNIT_EXPECT_EQ(test, 0, ret);
|
||||
KUNIT_EXPECT_EQ(test, val, range2_vals[i]);
|
||||
}
|
||||
ret = linear_range_get_value_array(&testr[0], 2, sel + 1, &val);
|
||||
KUNIT_EXPECT_NE(test, 0, ret);
|
||||
}
|
||||
|
||||
static void range_test_get_selector_high(struct kunit *test)
|
||||
{
|
||||
int ret, i;
|
||||
unsigned int sel;
|
||||
bool found;
|
||||
|
||||
for (i = 0; i < RANGE1_NUM_VALS; i++) {
|
||||
ret = linear_range_get_selector_high(&testr[0], range1_vals[i],
|
||||
&sel, &found);
|
||||
KUNIT_EXPECT_EQ(test, 0, ret);
|
||||
KUNIT_EXPECT_EQ(test, sel, range1_sels[i]);
|
||||
KUNIT_EXPECT_TRUE(test, found);
|
||||
}
|
||||
|
||||
ret = linear_range_get_selector_high(&testr[0], RANGE1_MAX_VAL + 1,
|
||||
&sel, &found);
|
||||
KUNIT_EXPECT_LE(test, ret, 0);
|
||||
|
||||
ret = linear_range_get_selector_high(&testr[0], RANGE1_MIN - 1,
|
||||
&sel, &found);
|
||||
KUNIT_EXPECT_EQ(test, 0, ret);
|
||||
KUNIT_EXPECT_FALSE(test, found);
|
||||
KUNIT_EXPECT_EQ(test, sel, range1_sels[0]);
|
||||
}
|
||||
|
||||
static void range_test_get_value_amount(struct kunit *test)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = linear_range_values_in_range_array(&testr[0], 2);
|
||||
KUNIT_EXPECT_EQ(test, (int)RANGE_NUM_VALS, ret);
|
||||
}
|
||||
|
||||
static void range_test_get_selector_low(struct kunit *test)
|
||||
{
|
||||
int i, ret;
|
||||
unsigned int sel;
|
||||
bool found;
|
||||
|
||||
for (i = 0; i < RANGE1_NUM_VALS; i++) {
|
||||
ret = linear_range_get_selector_low_array(&testr[0], 2,
|
||||
range1_vals[i], &sel,
|
||||
&found);
|
||||
KUNIT_EXPECT_EQ(test, 0, ret);
|
||||
KUNIT_EXPECT_EQ(test, sel, range1_sels[i]);
|
||||
KUNIT_EXPECT_TRUE(test, found);
|
||||
}
|
||||
for (i = 0; i < RANGE2_NUM_VALS; i++) {
|
||||
ret = linear_range_get_selector_low_array(&testr[0], 2,
|
||||
range2_vals[i], &sel,
|
||||
&found);
|
||||
KUNIT_EXPECT_EQ(test, 0, ret);
|
||||
KUNIT_EXPECT_EQ(test, sel, range2_sels[i]);
|
||||
KUNIT_EXPECT_TRUE(test, found);
|
||||
}
|
||||
|
||||
/*
|
||||
* Seek value greater than range max => get_selector_*_low should
|
||||
* return Ok - but set found to false as value is not in range
|
||||
*/
|
||||
ret = linear_range_get_selector_low_array(&testr[0], 2,
|
||||
range2_vals[RANGE2_NUM_VALS - 1] + 1,
|
||||
&sel, &found);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, 0, ret);
|
||||
KUNIT_EXPECT_EQ(test, sel, range2_sels[RANGE2_NUM_VALS - 1]);
|
||||
KUNIT_EXPECT_FALSE(test, found);
|
||||
}
|
||||
|
||||
static struct kunit_case range_test_cases[] = {
|
||||
KUNIT_CASE(range_test_get_value_amount),
|
||||
KUNIT_CASE(range_test_get_selector_high),
|
||||
KUNIT_CASE(range_test_get_selector_low),
|
||||
KUNIT_CASE(range_test_get_value),
|
||||
{},
|
||||
};
|
||||
|
||||
static struct kunit_suite range_test_module = {
|
||||
.name = "linear-ranges-test",
|
||||
.test_cases = range_test_cases,
|
||||
};
|
||||
|
||||
kunit_test_suites(&range_test_module);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
Loading…
Reference in New Issue
Block a user