You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'regulator-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown: - Support for putting regulators into bypass mode where they simply switch their input to the output (mainly used for low power retention). - A new API for setting voltages based on a voltage plus tolerance rather than an explicit voltage range. - Lots of cleanups and API updates from Axel Lin. - New driver for MAX8907. * tag 'regulator-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (71 commits) regulator: arizona-ldo: Remove top voltage regulator: tps6586x: remove regulator-compatible from DT docs regulator: tps65217.txt: remove regulator-compatible from DT docs regulator: deprecate regulator-compatible DT property regulator: fan53555: remove vsel_max not used regulator: aat2870: Don't explicitly initialise the first field extcon: arizona: Use bypass mode for MICVDD regulator: wm831x-ldo: Add bypass support regulator: arizona-micsupp: Support get/set bypass regulator: arizona-ldo: Support get/set bypass regulator: core: Provide regmap get/set bypass operations regulator: core: Support bypass mode regulator: Fairchild fan53555 support regulator: twl: Remove another unused variable warning regulator: core: Try using the parent device for the default regmap regulator: core: Fast path non-deferred disables regulator: core: Report microvolts in sysfs even with only list_voltage() regulator: tps6586x: add support for SYS rail regulator: lp872x: remove unnecessary function regulator: lp872x: fix NULL pointer access problem ...
This commit is contained in:
@@ -349,3 +349,24 @@ Description:
|
||||
|
||||
This will be one of the same strings reported by
|
||||
the "state" attribute.
|
||||
|
||||
What: /sys/class/regulator/.../bypass
|
||||
Date: September 2012
|
||||
KernelVersion: 3.7
|
||||
Contact: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Some regulator directories will contain a field called
|
||||
bypass. This indicates if the device is in bypass mode.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'enabled'
|
||||
'disabled'
|
||||
'unknown'
|
||||
|
||||
'enabled' means the regulator is in bypass mode.
|
||||
|
||||
'disabled' means that the regulator is regulating.
|
||||
|
||||
'unknown' means software cannot determine the state, or
|
||||
the reported state is invalid.
|
||||
|
||||
@@ -11,10 +11,13 @@ Optional properties:
|
||||
- regulator-boot-on: bootloader/firmware enabled regulator
|
||||
- <name>-supply: phandle to the parent supply/regulator node
|
||||
- regulator-ramp-delay: ramp delay for regulator(in uV/uS)
|
||||
|
||||
Deprecated properties:
|
||||
- regulator-compatible: If a regulator chip contains multiple
|
||||
regulators, and if the chip's binding contains a child node that
|
||||
describes each regulator, then this property indicates which regulator
|
||||
this child node is intended to configure.
|
||||
this child node is intended to configure. If this property is missing,
|
||||
the node's name will be used instead.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@@ -22,66 +22,49 @@ Example:
|
||||
compatible = "ti,tps65217";
|
||||
|
||||
regulators {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
dcdc1_reg: regulator@0 {
|
||||
reg = <0>;
|
||||
regulator-compatible = "dcdc1";
|
||||
dcdc1_reg: dcdc1 {
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
dcdc2_reg: regulator@1 {
|
||||
reg = <1>;
|
||||
regulator-compatible = "dcdc2";
|
||||
dcdc2_reg: dcdc2 {
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
dcdc3_reg: regulator@2 {
|
||||
reg = <2>;
|
||||
regulator-compatible = "dcdc3";
|
||||
dcdc3_reg: dcc3 {
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo1_reg: regulator@3 {
|
||||
reg = <3>;
|
||||
regulator-compatible = "ldo1";
|
||||
ldo1_reg: ldo1 {
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo2_reg: regulator@4 {
|
||||
reg = <4>;
|
||||
regulator-compatible = "ldo2";
|
||||
ldo2_reg: ldo2 {
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo3_reg: regulator@5 {
|
||||
reg = <5>;
|
||||
regulator-compatible = "ldo3";
|
||||
ldo3_reg: ldo3 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo4_reg: regulator@6 {
|
||||
reg = <6>;
|
||||
regulator-compatible = "ldo4";
|
||||
ldo4_reg: ldo4 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
|
||||
@@ -6,9 +6,13 @@ Required properties:
|
||||
- interrupts: the interrupt outputs of the controller
|
||||
- #gpio-cells: number of cells to describe a GPIO
|
||||
- gpio-controller: mark the device as a GPIO controller
|
||||
- regulators: list of regulators provided by this controller, must have
|
||||
property "regulator-compatible" to match their hardware counterparts:
|
||||
sm[0-2], ldo[0-9] and ldo_rtc
|
||||
- regulators: A node that houses a sub-node for each regulator within the
|
||||
device. Each sub-node is identified using the node's name (or the deprecated
|
||||
regulator-compatible property if present), with valid values listed below.
|
||||
The content of each sub-node is defined by the standard binding for
|
||||
regulators; see regulator.txt.
|
||||
sys, sm[0-2], ldo[0-9] and ldo_rtc
|
||||
- sys-supply: The input supply for SYS.
|
||||
- vin-sm0-supply: The input supply for the SM0.
|
||||
- vin-sm1-supply: The input supply for the SM1.
|
||||
- vin-sm2-supply: The input supply for the SM2.
|
||||
@@ -20,6 +24,9 @@ Required properties:
|
||||
|
||||
Each regulator is defined using the standard binding for regulators.
|
||||
|
||||
Note: LDO5 and LDO_RTC is supplied by SYS regulator internally and driver
|
||||
take care of making proper parent child relationship.
|
||||
|
||||
Example:
|
||||
|
||||
pmu: tps6586x@34 {
|
||||
@@ -30,6 +37,7 @@ Example:
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
|
||||
sys-supply = <&some_reg>;
|
||||
vin-sm0-supply = <&some_reg>;
|
||||
vin-sm1-supply = <&some_reg>;
|
||||
vin-sm2-supply = <&some_reg>;
|
||||
@@ -40,103 +48,80 @@ Example:
|
||||
vinldo9-supply = <...>;
|
||||
|
||||
regulators {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
sys_reg: sys {
|
||||
regulator-name = "vdd_sys";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
sm0_reg: regulator@0 {
|
||||
reg = <0>;
|
||||
regulator-compatible = "sm0";
|
||||
sm0_reg: sm0 {
|
||||
regulator-min-microvolt = < 725000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
sm1_reg: regulator@1 {
|
||||
reg = <1>;
|
||||
regulator-compatible = "sm1";
|
||||
sm1_reg: sm1 {
|
||||
regulator-min-microvolt = < 725000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
sm2_reg: regulator@2 {
|
||||
reg = <2>;
|
||||
regulator-compatible = "sm2";
|
||||
sm2_reg: sm2 {
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <4550000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo0_reg: regulator@3 {
|
||||
reg = <3>;
|
||||
regulator-compatible = "ldo0";
|
||||
ldo0_reg: ldo0 {
|
||||
regulator-name = "PCIE CLK";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
ldo1_reg: regulator@4 {
|
||||
reg = <4>;
|
||||
regulator-compatible = "ldo1";
|
||||
ldo1_reg: ldo1 {
|
||||
regulator-min-microvolt = < 725000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
};
|
||||
|
||||
ldo2_reg: regulator@5 {
|
||||
reg = <5>;
|
||||
regulator-compatible = "ldo2";
|
||||
ldo2_reg: ldo2 {
|
||||
regulator-min-microvolt = < 725000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
};
|
||||
|
||||
ldo3_reg: regulator@6 {
|
||||
reg = <6>;
|
||||
regulator-compatible = "ldo3";
|
||||
ldo3_reg: ldo3 {
|
||||
regulator-min-microvolt = <1250000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
ldo4_reg: regulator@7 {
|
||||
reg = <7>;
|
||||
regulator-compatible = "ldo4";
|
||||
ldo4_reg: ldo4 {
|
||||
regulator-min-microvolt = <1700000>;
|
||||
regulator-max-microvolt = <2475000>;
|
||||
};
|
||||
|
||||
ldo5_reg: regulator@8 {
|
||||
reg = <8>;
|
||||
regulator-compatible = "ldo5";
|
||||
ldo5_reg: ldo5 {
|
||||
regulator-min-microvolt = <1250000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
ldo6_reg: regulator@9 {
|
||||
reg = <9>;
|
||||
regulator-compatible = "ldo6";
|
||||
ldo6_reg: ldo6 {
|
||||
regulator-min-microvolt = <1250000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
ldo7_reg: regulator@10 {
|
||||
reg = <10>;
|
||||
regulator-compatible = "ldo7";
|
||||
ldo7_reg: ldo7 {
|
||||
regulator-min-microvolt = <1250000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
ldo8_reg: regulator@11 {
|
||||
reg = <11>;
|
||||
regulator-compatible = "ldo8";
|
||||
ldo8_reg: ldo8 {
|
||||
regulator-min-microvolt = <1250000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
ldo9_reg: regulator@12 {
|
||||
reg = <12>;
|
||||
regulator-compatible = "ldo9";
|
||||
ldo9_reg: ldo9 {
|
||||
regulator-min-microvolt = <1250000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
@@ -67,6 +67,13 @@ static struct regulator_init_data ldo0_data = {
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct regulator_init_data sys_data = {
|
||||
.supply_regulator = "vdd_5v0",
|
||||
.constraints = {
|
||||
.name = "vdd_sys",
|
||||
},
|
||||
};
|
||||
|
||||
HARMONY_REGULATOR_INIT(sm0, "vdd_sm0", "vdd_sys", 725, 1500, 1);
|
||||
HARMONY_REGULATOR_INIT(sm1, "vdd_sm1", "vdd_sys", 725, 1500, 1);
|
||||
HARMONY_REGULATOR_INIT(sm2, "vdd_sm2", "vdd_sys", 3000, 4550, 1);
|
||||
@@ -74,7 +81,7 @@ HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500, 1);
|
||||
HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500, 0);
|
||||
HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300, 1);
|
||||
HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475, 1);
|
||||
HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL, 1250, 3300, 1);
|
||||
HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", "vdd_sys", 1250, 3300, 1);
|
||||
HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300, 0);
|
||||
HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300, 0);
|
||||
HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300, 0);
|
||||
@@ -88,6 +95,7 @@ HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300, 1);
|
||||
}
|
||||
|
||||
static struct tps6586x_subdev_info tps_devs[] = {
|
||||
TPS_REG(SYS, &sys_data),
|
||||
TPS_REG(SM_0, &sm0_data),
|
||||
TPS_REG(SM_1, &sm1_data),
|
||||
TPS_REG(SM_2, &sm2_data),
|
||||
@@ -120,7 +128,7 @@ static struct i2c_board_info __initdata harmony_regulators[] = {
|
||||
|
||||
int __init harmony_regulator_init(void)
|
||||
{
|
||||
regulator_register_always_on(0, "vdd_sys",
|
||||
regulator_register_always_on(0, "vdd_5v0",
|
||||
NULL, 0, 5000000);
|
||||
|
||||
if (machine_is_harmony()) {
|
||||
|
||||
@@ -434,6 +434,11 @@ static int __devinit arizona_extcon_probe(struct platform_device *pdev)
|
||||
regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
|
||||
ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
|
||||
|
||||
ret = regulator_allow_bypass(info->micvdd, true);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
|
||||
ret);
|
||||
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/tps6586x.h>
|
||||
@@ -346,6 +347,7 @@ failed:
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct of_regulator_match tps6586x_matches[] = {
|
||||
{ .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS },
|
||||
{ .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 },
|
||||
{ .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 },
|
||||
{ .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 },
|
||||
@@ -369,6 +371,7 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
|
||||
struct tps6586x_platform_data *pdata;
|
||||
struct tps6586x_subdev_info *devs;
|
||||
struct device_node *regs;
|
||||
const char *sys_rail_name = NULL;
|
||||
unsigned int count;
|
||||
unsigned int i, j;
|
||||
int err;
|
||||
@@ -391,12 +394,22 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
|
||||
return NULL;
|
||||
|
||||
for (i = 0, j = 0; i < num && j < count; i++) {
|
||||
struct regulator_init_data *reg_idata;
|
||||
|
||||
if (!tps6586x_matches[i].init_data)
|
||||
continue;
|
||||
|
||||
reg_idata = tps6586x_matches[i].init_data;
|
||||
devs[j].name = "tps6586x-regulator";
|
||||
devs[j].platform_data = tps6586x_matches[i].init_data;
|
||||
devs[j].id = (int)tps6586x_matches[i].driver_data;
|
||||
if (devs[j].id == TPS6586X_ID_SYS)
|
||||
sys_rail_name = reg_idata->constraints.name;
|
||||
|
||||
if ((devs[j].id == TPS6586X_ID_LDO_5) ||
|
||||
(devs[j].id == TPS6586X_ID_LDO_RTC))
|
||||
reg_idata->supply_regulator = sys_rail_name;
|
||||
|
||||
devs[j].of_node = tps6586x_matches[i].of_node;
|
||||
j++;
|
||||
}
|
||||
|
||||
+28
-10
@@ -33,9 +33,8 @@ config REGULATOR_DUMMY
|
||||
help
|
||||
If this option is enabled then when a regulator lookup fails
|
||||
and the board has not specified that it has provided full
|
||||
constraints then the regulator core will provide an always
|
||||
enabled dummy regulator will be provided, allowing consumer
|
||||
drivers to continue.
|
||||
constraints the regulator core will provide an always
|
||||
enabled dummy regulator, allowing consumer drivers to continue.
|
||||
|
||||
A warning will be generated when this substitution is done.
|
||||
|
||||
@@ -50,11 +49,11 @@ config REGULATOR_VIRTUAL_CONSUMER
|
||||
tristate "Virtual regulator consumer support"
|
||||
help
|
||||
This driver provides a virtual consumer for the voltage and
|
||||
current regulator API which provides sysfs controls for
|
||||
configuring the supplies requested. This is mainly useful
|
||||
for test purposes.
|
||||
current regulator API which provides sysfs controls for
|
||||
configuring the supplies requested. This is mainly useful
|
||||
for test purposes.
|
||||
|
||||
If unsure, say no.
|
||||
If unsure, say no.
|
||||
|
||||
config REGULATOR_USERSPACE_CONSUMER
|
||||
tristate "Userspace regulator consumer support"
|
||||
@@ -63,7 +62,7 @@ config REGULATOR_USERSPACE_CONSUMER
|
||||
from user space. Userspace consumer driver provides ability to
|
||||
control power supplies for such devices.
|
||||
|
||||
If unsure, say no.
|
||||
If unsure, say no.
|
||||
|
||||
config REGULATOR_GPIO
|
||||
tristate "GPIO regulator support"
|
||||
@@ -110,6 +109,17 @@ config REGULATOR_DA9052
|
||||
This driver supports the voltage regulators of DA9052-BC and
|
||||
DA9053-AA/Bx PMIC.
|
||||
|
||||
config REGULATOR_FAN53555
|
||||
tristate "Fairchild FAN53555 Regulator"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports Fairchild FAN53555 Digitally Programmable
|
||||
TinyBuck Regulator. The FAN53555 is a step-down switching voltage
|
||||
regulator that delivers a digitally programmable output from an
|
||||
input voltage supply of 2.5V to 5.5V. The output voltage is
|
||||
programmed through an I2C interface.
|
||||
|
||||
config REGULATOR_ANATOP
|
||||
tristate "Freescale i.MX on-chip ANATOP LDO regulators"
|
||||
depends on MFD_ANATOP
|
||||
@@ -172,6 +182,14 @@ config REGULATOR_MAX8660
|
||||
This driver controls a Maxim 8660/8661 voltage output
|
||||
regulator via I2C bus.
|
||||
|
||||
config REGULATOR_MAX8907
|
||||
tristate "Maxim 8907 voltage regulator"
|
||||
depends on MFD_MAX8907
|
||||
help
|
||||
This driver controls a Maxim 8907 voltage output regulator
|
||||
via I2C bus. The provided regulator is suitable for Tegra
|
||||
chip to control Step-Down DC-DC and LDOs.
|
||||
|
||||
config REGULATOR_MAX8925
|
||||
tristate "Maxim MAX8925 Power Management IC"
|
||||
depends on MFD_MAX8925
|
||||
@@ -247,7 +265,7 @@ config REGULATOR_LP8788
|
||||
|
||||
config REGULATOR_PCF50633
|
||||
tristate "NXP PCF50633 regulator driver"
|
||||
depends on MFD_PCF50633
|
||||
depends on MFD_PCF50633
|
||||
help
|
||||
Say Y here to support the voltage regulators and convertors
|
||||
on PCF50633
|
||||
@@ -416,7 +434,7 @@ config REGULATOR_WM8350
|
||||
depends on MFD_WM8350
|
||||
help
|
||||
This driver provides support for the voltage and current regulators
|
||||
of the WM8350 AudioPlus PMIC.
|
||||
of the WM8350 AudioPlus PMIC.
|
||||
|
||||
config REGULATOR_WM8400
|
||||
tristate "Wolfson Microelectronics WM8400 AudioPlus PMIC"
|
||||
|
||||
@@ -20,6 +20,7 @@ obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
|
||||
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
|
||||
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
|
||||
obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
|
||||
obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
|
||||
@@ -30,6 +31,7 @@ obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
|
||||
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
|
||||
|
||||
@@ -162,7 +162,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id)
|
||||
static int aat2870_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct aat2870_regulator *ri;
|
||||
struct regulator_config config = { 0 };
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
|
||||
ri = aat2870_get_regulator(pdev->id);
|
||||
|
||||
@@ -347,17 +347,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
|
||||
return abreg->plfdata->external_voltage;
|
||||
}
|
||||
|
||||
static int ab3100_get_fixed_voltage_regulator(struct regulator_dev *reg)
|
||||
{
|
||||
return reg->desc->min_uV;
|
||||
}
|
||||
|
||||
static struct regulator_ops regulator_ops_fixed = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.enable = ab3100_enable_regulator,
|
||||
.disable = ab3100_disable_regulator,
|
||||
.is_enabled = ab3100_is_enabled_regulator,
|
||||
.get_voltage = ab3100_get_fixed_voltage_regulator,
|
||||
};
|
||||
|
||||
static struct regulator_ops regulator_ops_variable = {
|
||||
|
||||
+11
-25
@@ -37,6 +37,7 @@
|
||||
* @voltage_bank: bank to control regulator voltage
|
||||
* @voltage_reg: register to control regulator voltage
|
||||
* @voltage_mask: mask to control regulator voltage
|
||||
* @voltage_shift: shift to control regulator voltage
|
||||
* @delay: startup/set voltage delay in us
|
||||
*/
|
||||
struct ab8500_regulator_info {
|
||||
@@ -50,6 +51,7 @@ struct ab8500_regulator_info {
|
||||
u8 voltage_bank;
|
||||
u8 voltage_reg;
|
||||
u8 voltage_mask;
|
||||
u8 voltage_shift;
|
||||
unsigned int delay;
|
||||
};
|
||||
|
||||
@@ -195,17 +197,14 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
|
||||
}
|
||||
|
||||
dev_vdbg(rdev_get_dev(rdev),
|
||||
"%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
|
||||
" 0x%x\n",
|
||||
info->desc.name, info->voltage_bank, info->voltage_reg,
|
||||
info->voltage_mask, regval);
|
||||
"%s-get_voltage (bank, reg, mask, shift, value): "
|
||||
"0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
|
||||
info->desc.name, info->voltage_bank,
|
||||
info->voltage_reg, info->voltage_mask,
|
||||
info->voltage_shift, regval);
|
||||
|
||||
/* vintcore has a different layout */
|
||||
val = regval & info->voltage_mask;
|
||||
if (info->desc.id == AB8500_LDO_INTCORE)
|
||||
return val >> 0x3;
|
||||
else
|
||||
return val;
|
||||
return val >> info->voltage_shift;
|
||||
}
|
||||
|
||||
static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
@@ -221,7 +220,7 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
}
|
||||
|
||||
/* set the registers for the request */
|
||||
regval = (u8)selector;
|
||||
regval = (u8)selector << info->voltage_shift;
|
||||
ret = abx500_mask_and_set_register_interruptible(info->dev,
|
||||
info->voltage_bank, info->voltage_reg,
|
||||
info->voltage_mask, regval);
|
||||
@@ -238,13 +237,6 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ab8500_regulator_enable_time(struct regulator_dev *rdev)
|
||||
{
|
||||
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
return info->delay;
|
||||
}
|
||||
|
||||
static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
unsigned int old_sel,
|
||||
unsigned int new_sel)
|
||||
@@ -261,22 +253,14 @@ static struct regulator_ops ab8500_regulator_ops = {
|
||||
.get_voltage_sel = ab8500_regulator_get_voltage_sel,
|
||||
.set_voltage_sel = ab8500_regulator_set_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.enable_time = ab8500_regulator_enable_time,
|
||||
.set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
return rdev->desc->min_uV;
|
||||
}
|
||||
|
||||
static struct regulator_ops ab8500_regulator_fixed_ops = {
|
||||
.enable = ab8500_regulator_enable,
|
||||
.disable = ab8500_regulator_disable,
|
||||
.is_enabled = ab8500_regulator_is_enabled,
|
||||
.get_voltage = ab8500_fixed_get_voltage,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.enable_time = ab8500_regulator_enable_time,
|
||||
};
|
||||
|
||||
static struct ab8500_regulator_info
|
||||
@@ -358,6 +342,7 @@ static struct ab8500_regulator_info
|
||||
.voltage_bank = 0x03,
|
||||
.voltage_reg = 0x80,
|
||||
.voltage_mask = 0x38,
|
||||
.voltage_shift = 3,
|
||||
},
|
||||
|
||||
/*
|
||||
@@ -374,6 +359,7 @@ static struct ab8500_regulator_info
|
||||
.owner = THIS_MODULE,
|
||||
.n_voltages = 1,
|
||||
.min_uV = 2000000,
|
||||
.enable_time = 10000,
|
||||
},
|
||||
.delay = 10000,
|
||||
.update_bank = 0x03,
|
||||
|
||||
@@ -39,6 +39,8 @@ static struct regulator_ops arizona_ldo1_ops = {
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_bypass = regulator_get_bypass_regmap,
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_desc arizona_ldo1 = {
|
||||
@@ -49,9 +51,11 @@ static const struct regulator_desc arizona_ldo1 = {
|
||||
|
||||
.vsel_reg = ARIZONA_LDO1_CONTROL_1,
|
||||
.vsel_mask = ARIZONA_LDO1_VSEL_MASK,
|
||||
.bypass_reg = ARIZONA_LDO1_CONTROL_1,
|
||||
.bypass_mask = ARIZONA_LDO1_BYPASS,
|
||||
.min_uV = 900000,
|
||||
.uV_step = 50000,
|
||||
.n_voltages = 7,
|
||||
.n_voltages = 6,
|
||||
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
@@ -82,6 +82,9 @@ static struct regulator_ops arizona_micsupp_ops = {
|
||||
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
|
||||
.get_bypass = regulator_get_bypass_regmap,
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_desc arizona_micsupp = {
|
||||
@@ -95,6 +98,8 @@ static const struct regulator_desc arizona_micsupp = {
|
||||
.vsel_mask = ARIZONA_LDO2_VSEL_MASK,
|
||||
.enable_reg = ARIZONA_MIC_CHARGE_PUMP_1,
|
||||
.enable_mask = ARIZONA_CPMIC_ENA,
|
||||
.bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
|
||||
.bypass_mask = ARIZONA_CPMIC_BYPASS,
|
||||
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
+147
-6
@@ -77,6 +77,7 @@ struct regulator {
|
||||
struct device *dev;
|
||||
struct list_head list;
|
||||
unsigned int always_on:1;
|
||||
unsigned int bypass:1;
|
||||
int uA_load;
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
@@ -394,6 +395,9 @@ static ssize_t regulator_status_show(struct device *dev,
|
||||
case REGULATOR_STATUS_STANDBY:
|
||||
label = "standby";
|
||||
break;
|
||||
case REGULATOR_STATUS_BYPASS:
|
||||
label = "bypass";
|
||||
break;
|
||||
case REGULATOR_STATUS_UNDEFINED:
|
||||
label = "undefined";
|
||||
break;
|
||||
@@ -585,6 +589,27 @@ static ssize_t regulator_suspend_standby_state_show(struct device *dev,
|
||||
static DEVICE_ATTR(suspend_standby_state, 0444,
|
||||
regulator_suspend_standby_state_show, NULL);
|
||||
|
||||
static ssize_t regulator_bypass_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct regulator_dev *rdev = dev_get_drvdata(dev);
|
||||
const char *report;
|
||||
bool bypass;
|
||||
int ret;
|
||||
|
||||
ret = rdev->desc->ops->get_bypass(rdev, &bypass);
|
||||
|
||||
if (ret != 0)
|
||||
report = "unknown";
|
||||
else if (bypass)
|
||||
report = "enabled";
|
||||
else
|
||||
report = "disabled";
|
||||
|
||||
return sprintf(buf, "%s\n", report);
|
||||
}
|
||||
static DEVICE_ATTR(bypass, 0444,
|
||||
regulator_bypass_show, NULL);
|
||||
|
||||
/*
|
||||
* These are the only attributes are present for all regulators.
|
||||
@@ -778,6 +803,9 @@ static void print_constraints(struct regulator_dev *rdev)
|
||||
if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
|
||||
count += sprintf(buf + count, "standby");
|
||||
|
||||
if (!count)
|
||||
sprintf(buf, "no parameters");
|
||||
|
||||
rdev_info(rdev, "%s\n", buf);
|
||||
|
||||
if ((constraints->min_uV != constraints->max_uV) &&
|
||||
@@ -974,6 +1002,7 @@ static int set_supply(struct regulator_dev *rdev,
|
||||
err = -ENOMEM;
|
||||
return err;
|
||||
}
|
||||
supply_rdev->open_count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1720,6 +1749,9 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
|
||||
if (regulator->always_on)
|
||||
return 0;
|
||||
|
||||
if (!ms)
|
||||
return regulator_disable(regulator);
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
rdev->deferred_disables++;
|
||||
mutex_unlock(&rdev->mutex);
|
||||
@@ -2178,9 +2210,12 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0 && best_val >= 0)
|
||||
if (ret == 0 && best_val >= 0) {
|
||||
unsigned long data = best_val;
|
||||
|
||||
_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
|
||||
(void *)best_val);
|
||||
(void *)data);
|
||||
}
|
||||
|
||||
trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
|
||||
|
||||
@@ -2291,8 +2326,8 @@ int regulator_set_voltage_time(struct regulator *regulator,
|
||||
EXPORT_SYMBOL_GPL(regulator_set_voltage_time);
|
||||
|
||||
/**
|
||||
*regulator_set_voltage_time_sel - get raise/fall time
|
||||
* @regulator: regulator source
|
||||
* regulator_set_voltage_time_sel - get raise/fall time
|
||||
* @rdev: regulator source device
|
||||
* @old_selector: selector for starting voltage
|
||||
* @new_selector: selector for target voltage
|
||||
*
|
||||
@@ -2388,6 +2423,8 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
|
||||
ret = rdev->desc->ops->list_voltage(rdev, sel);
|
||||
} else if (rdev->desc->ops->get_voltage) {
|
||||
ret = rdev->desc->ops->get_voltage(rdev);
|
||||
} else if (rdev->desc->ops->list_voltage) {
|
||||
ret = rdev->desc->ops->list_voltage(rdev, 0);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2673,6 +2710,100 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
|
||||
|
||||
/**
|
||||
* regulator_set_bypass_regmap - Default set_bypass() using regmap
|
||||
*
|
||||
* @rdev: device to operate on.
|
||||
* @enable: state to set.
|
||||
*/
|
||||
int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
if (enable)
|
||||
val = rdev->desc->bypass_mask;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
|
||||
rdev->desc->bypass_mask, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
|
||||
|
||||
/**
|
||||
* regulator_get_bypass_regmap - Default get_bypass() using regmap
|
||||
*
|
||||
* @rdev: device to operate on.
|
||||
* @enable: current state.
|
||||
*/
|
||||
int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
*enable = val & rdev->desc->bypass_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
|
||||
|
||||
/**
|
||||
* regulator_allow_bypass - allow the regulator to go into bypass mode
|
||||
*
|
||||
* @regulator: Regulator to configure
|
||||
* @allow: enable or disable bypass mode
|
||||
*
|
||||
* Allow the regulator to go into bypass mode if all other consumers
|
||||
* for the regulator also enable bypass mode and the machine
|
||||
* constraints allow this. Bypass mode means that the regulator is
|
||||
* simply passing the input directly to the output with no regulation.
|
||||
*/
|
||||
int regulator_allow_bypass(struct regulator *regulator, bool enable)
|
||||
{
|
||||
struct regulator_dev *rdev = regulator->rdev;
|
||||
int ret = 0;
|
||||
|
||||
if (!rdev->desc->ops->set_bypass)
|
||||
return 0;
|
||||
|
||||
if (rdev->constraints &&
|
||||
!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
|
||||
if (enable && !regulator->bypass) {
|
||||
rdev->bypass_count++;
|
||||
|
||||
if (rdev->bypass_count == rdev->open_count) {
|
||||
ret = rdev->desc->ops->set_bypass(rdev, enable);
|
||||
if (ret != 0)
|
||||
rdev->bypass_count--;
|
||||
}
|
||||
|
||||
} else if (!enable && regulator->bypass) {
|
||||
rdev->bypass_count--;
|
||||
|
||||
if (rdev->bypass_count != rdev->open_count) {
|
||||
ret = rdev->desc->ops->set_bypass(rdev, enable);
|
||||
if (ret != 0)
|
||||
rdev->bypass_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
regulator->bypass = enable;
|
||||
|
||||
mutex_unlock(&rdev->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_allow_bypass);
|
||||
|
||||
/**
|
||||
* regulator_register_notifier - register regulator event notifier
|
||||
* @regulator: regulator source
|
||||
@@ -3011,7 +3142,8 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
|
||||
|
||||
/* some attributes need specific methods to be displayed */
|
||||
if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
|
||||
(ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0)) {
|
||||
(ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) ||
|
||||
(ops->list_voltage && ops->list_voltage(rdev, 0) >= 0)) {
|
||||
status = device_create_file(dev, &dev_attr_microvolts);
|
||||
if (status < 0)
|
||||
return status;
|
||||
@@ -3036,6 +3168,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
if (ops->get_bypass) {
|
||||
status = device_create_file(dev, &dev_attr_bypass);
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* some attributes are type-specific */
|
||||
if (rdev->desc->type == REGULATOR_CURRENT) {
|
||||
@@ -3124,6 +3261,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
|
||||
&rdev->use_count);
|
||||
debugfs_create_u32("open_count", 0444, rdev->debugfs,
|
||||
&rdev->open_count);
|
||||
debugfs_create_u32("bypass_count", 0444, rdev->debugfs,
|
||||
&rdev->bypass_count);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3189,8 +3328,10 @@ regulator_register(const struct regulator_desc *regulator_desc,
|
||||
rdev->desc = regulator_desc;
|
||||
if (config->regmap)
|
||||
rdev->regmap = config->regmap;
|
||||
else
|
||||
else if (dev_get_regmap(dev, NULL))
|
||||
rdev->regmap = dev_get_regmap(dev, NULL);
|
||||
else if (dev->parent)
|
||||
rdev->regmap = dev_get_regmap(dev->parent, NULL);
|
||||
INIT_LIST_HEAD(&rdev->consumer_list);
|
||||
INIT_LIST_HEAD(&rdev->list);
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
|
||||
|
||||
@@ -133,8 +133,8 @@ static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA,
|
||||
max_uA < da9052_current_limits[row][DA9052_MIN_UA])
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < DA9052_CURRENT_RANGE; i++) {
|
||||
if (min_uA <= da9052_current_limits[row][i]) {
|
||||
for (i = DA9052_CURRENT_RANGE - 1; i >= 0; i--) {
|
||||
if (da9052_current_limits[row][i] <= max_uA) {
|
||||
reg_val = i;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ static struct regulator_init_data dummy_initdata;
|
||||
static struct regulator_ops dummy_ops;
|
||||
|
||||
static struct regulator_desc dummy_desc = {
|
||||
.name = "dummy",
|
||||
.name = "regulator-dummy",
|
||||
.id = -1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver.
|
||||
*
|
||||
* Supported Part Numbers:
|
||||
* FAN53555UC00X/01X/03X/04X/05X
|
||||
*
|
||||
* Copyright (c) 2012 Marvell Technology Ltd.
|
||||
* Yunfan Zhang <yfzhang@marvell.com>
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/fan53555.h>
|
||||
|
||||
/* Voltage setting */
|
||||
#define FAN53555_VSEL0 0x00
|
||||
#define FAN53555_VSEL1 0x01
|
||||
/* Control register */
|
||||
#define FAN53555_CONTROL 0x02
|
||||
/* IC Type */
|
||||
#define FAN53555_ID1 0x03
|
||||
/* IC mask version */
|
||||
#define FAN53555_ID2 0x04
|
||||
/* Monitor register */
|
||||
#define FAN53555_MONITOR 0x05
|
||||
|
||||
/* VSEL bit definitions */
|
||||
#define VSEL_BUCK_EN (1 << 7)
|
||||
#define VSEL_MODE (1 << 6)
|
||||
#define VSEL_NSEL_MASK 0x3F
|
||||
/* Chip ID and Verison */
|
||||
#define DIE_ID 0x0F /* ID1 */
|
||||
#define DIE_REV 0x0F /* ID2 */
|
||||
/* Control bit definitions */
|
||||
#define CTL_OUTPUT_DISCHG (1 << 7)
|
||||
#define CTL_SLEW_MASK (0x7 << 4)
|
||||
#define CTL_SLEW_SHIFT 4
|
||||
#define CTL_RESET (1 << 2)
|
||||
|
||||
#define FAN53555_NVOLTAGES 64 /* Numbers of voltages */
|
||||
|
||||
/* IC Type */
|
||||
enum {
|
||||
FAN53555_CHIP_ID_00 = 0,
|
||||
FAN53555_CHIP_ID_01,
|
||||
FAN53555_CHIP_ID_02,
|
||||
FAN53555_CHIP_ID_03,
|
||||
FAN53555_CHIP_ID_04,
|
||||
FAN53555_CHIP_ID_05,
|
||||
};
|
||||
|
||||
struct fan53555_device_info {
|
||||
struct regmap *regmap;
|
||||
struct device *dev;
|
||||
struct regulator_desc desc;
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_init_data *regulator;
|
||||
/* IC Type and Rev */
|
||||
int chip_id;
|
||||
int chip_rev;
|
||||
/* Voltage setting register */
|
||||
unsigned int vol_reg;
|
||||
unsigned int sleep_reg;
|
||||
/* Voltage range and step(linear) */
|
||||
unsigned int vsel_min;
|
||||
unsigned int vsel_step;
|
||||
/* Voltage slew rate limiting */
|
||||
unsigned int slew_rate;
|
||||
/* Sleep voltage cache */
|
||||
unsigned int sleep_vol_cache;
|
||||
};
|
||||
|
||||
static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
|
||||
{
|
||||
struct fan53555_device_info *di = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
if (di->sleep_vol_cache == uV)
|
||||
return 0;
|
||||
ret = regulator_map_voltage_linear(rdev, uV, uV);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
ret = regmap_update_bits(di->regmap, di->sleep_reg,
|
||||
VSEL_NSEL_MASK, ret);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
/* Cache the sleep voltage setting.
|
||||
* Might not be the real voltage which is rounded */
|
||||
di->sleep_vol_cache = uV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
struct fan53555_device_info *di = rdev_get_drvdata(rdev);
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_FAST:
|
||||
regmap_update_bits(di->regmap, di->vol_reg,
|
||||
VSEL_MODE, VSEL_MODE);
|
||||
break;
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
regmap_update_bits(di->regmap, di->vol_reg, VSEL_MODE, 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
struct fan53555_device_info *di = rdev_get_drvdata(rdev);
|
||||
unsigned int val;
|
||||
int ret = 0;
|
||||
|
||||
ret = regmap_read(di->regmap, di->vol_reg, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (val & VSEL_MODE)
|
||||
return REGULATOR_MODE_FAST;
|
||||
else
|
||||
return REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static struct regulator_ops fan53555_regulator_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.set_suspend_voltage = fan53555_set_suspend_voltage,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_mode = fan53555_set_mode,
|
||||
.get_mode = fan53555_get_mode,
|
||||
};
|
||||
|
||||
/* For 00,01,03,05 options:
|
||||
* VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V.
|
||||
* For 04 option:
|
||||
* VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V.
|
||||
* */
|
||||
static int fan53555_device_setup(struct fan53555_device_info *di,
|
||||
struct fan53555_platform_data *pdata)
|
||||
{
|
||||
unsigned int reg, data, mask;
|
||||
|
||||
/* Setup voltage control register */
|
||||
switch (pdata->sleep_vsel_id) {
|
||||
case FAN53555_VSEL_ID_0:
|
||||
di->sleep_reg = FAN53555_VSEL0;
|
||||
di->vol_reg = FAN53555_VSEL1;
|
||||
break;
|
||||
case FAN53555_VSEL_ID_1:
|
||||
di->sleep_reg = FAN53555_VSEL1;
|
||||
di->vol_reg = FAN53555_VSEL0;
|
||||
break;
|
||||
default:
|
||||
dev_err(di->dev, "Invalid VSEL ID!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Init voltage range and step */
|
||||
switch (di->chip_id) {
|
||||
case FAN53555_CHIP_ID_00:
|
||||
case FAN53555_CHIP_ID_01:
|
||||
case FAN53555_CHIP_ID_03:
|
||||
case FAN53555_CHIP_ID_05:
|
||||
di->vsel_min = 600000;
|
||||
di->vsel_step = 10000;
|
||||
break;
|
||||
case FAN53555_CHIP_ID_04:
|
||||
di->vsel_min = 603000;
|
||||
di->vsel_step = 12826;
|
||||
break;
|
||||
default:
|
||||
dev_err(di->dev,
|
||||
"Chip ID[%d]\n not supported!\n", di->chip_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Init slew rate */
|
||||
if (pdata->slew_rate & 0x7)
|
||||
di->slew_rate = pdata->slew_rate;
|
||||
else
|
||||
di->slew_rate = FAN53555_SLEW_RATE_64MV;
|
||||
reg = FAN53555_CONTROL;
|
||||
data = di->slew_rate << CTL_SLEW_SHIFT;
|
||||
mask = CTL_SLEW_MASK;
|
||||
return regmap_update_bits(di->regmap, reg, mask, data);
|
||||
}
|
||||
|
||||
static int fan53555_regulator_register(struct fan53555_device_info *di,
|
||||
struct regulator_config *config)
|
||||
{
|
||||
struct regulator_desc *rdesc = &di->desc;
|
||||
|
||||
rdesc->name = "fan53555-reg";
|
||||
rdesc->ops = &fan53555_regulator_ops;
|
||||
rdesc->type = REGULATOR_VOLTAGE;
|
||||
rdesc->n_voltages = FAN53555_NVOLTAGES;
|
||||
rdesc->enable_reg = di->vol_reg;
|
||||
rdesc->enable_mask = VSEL_BUCK_EN;
|
||||
rdesc->min_uV = di->vsel_min;
|
||||
rdesc->uV_step = di->vsel_step;
|
||||
rdesc->vsel_reg = di->vol_reg;
|
||||
rdesc->vsel_mask = VSEL_NSEL_MASK;
|
||||
rdesc->owner = THIS_MODULE;
|
||||
|
||||
di->rdev = regulator_register(&di->desc, config);
|
||||
if (IS_ERR(di->rdev))
|
||||
return PTR_ERR(di->rdev);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static struct regmap_config fan53555_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static int __devinit fan53555_regulator_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct fan53555_device_info *di;
|
||||
struct fan53555_platform_data *pdata;
|
||||
struct regulator_config config = { };
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
pdata = client->dev.platform_data;
|
||||
if (!pdata || !pdata->regulator) {
|
||||
dev_err(&client->dev, "Platform data not found!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
|
||||
GFP_KERNEL);
|
||||
if (!di) {
|
||||
dev_err(&client->dev, "Failed to allocate device info data!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
|
||||
if (IS_ERR(di->regmap)) {
|
||||
dev_err(&client->dev, "Failed to allocate regmap!\n");
|
||||
return PTR_ERR(di->regmap);
|
||||
}
|
||||
di->dev = &client->dev;
|
||||
di->regulator = pdata->regulator;
|
||||
i2c_set_clientdata(client, di);
|
||||
/* Get chip ID */
|
||||
ret = regmap_read(di->regmap, FAN53555_ID1, &val);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Failed to get chip ID!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
di->chip_id = val & DIE_ID;
|
||||
/* Get chip revision */
|
||||
ret = regmap_read(di->regmap, FAN53555_ID2, &val);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Failed to get chip Rev!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
di->chip_rev = val & DIE_REV;
|
||||
dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n",
|
||||
di->chip_id, di->chip_rev);
|
||||
/* Device init */
|
||||
ret = fan53555_device_setup(di, pdata);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Failed to setup device!\n");
|
||||
return ret;
|
||||
}
|
||||
/* Register regulator */
|
||||
config.dev = di->dev;
|
||||
config.init_data = di->regulator;
|
||||
config.regmap = di->regmap;
|
||||
config.driver_data = di;
|
||||
ret = fan53555_regulator_register(di, &config);
|
||||
if (ret < 0)
|
||||
dev_err(&client->dev, "Failed to register regulator!\n");
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int __devexit fan53555_regulator_remove(struct i2c_client *client)
|
||||
{
|
||||
struct fan53555_device_info *di = i2c_get_clientdata(client);
|
||||
|
||||
regulator_unregister(di->rdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id fan53555_id[] = {
|
||||
{"fan53555", -1},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct i2c_driver fan53555_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "fan53555-regulator",
|
||||
},
|
||||
.probe = fan53555_regulator_probe,
|
||||
.remove = __devexit_p(fan53555_regulator_remove),
|
||||
.id_table = fan53555_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(fan53555_regulator_driver);
|
||||
|
||||
MODULE_AUTHOR("Yunfan Zhang <yfzhang@marvell.com>");
|
||||
MODULE_DESCRIPTION("FAN53555 regulator driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -73,13 +73,7 @@ static struct regulator_ops isl_core_ops = {
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
};
|
||||
|
||||
static int isl6271a_get_fixed_voltage(struct regulator_dev *dev)
|
||||
{
|
||||
return dev->desc->min_uV;
|
||||
}
|
||||
|
||||
static struct regulator_ops isl_fixed_ops = {
|
||||
.get_voltage = isl6271a_get_fixed_voltage,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
|
||||
+35
-53
@@ -86,6 +86,10 @@
|
||||
#define EXTERN_DVS_USED 0
|
||||
#define MAX_DELAY 6
|
||||
|
||||
/* Default DVS Mode */
|
||||
#define LP8720_DEFAULT_DVS 0
|
||||
#define LP8725_DEFAULT_DVS BIT(2)
|
||||
|
||||
/* dump registers in regmap-debugfs */
|
||||
#define MAX_REGISTERS 0x0F
|
||||
|
||||
@@ -269,9 +273,9 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev)
|
||||
return val > MAX_DELAY ? 0 : val * time_step_us;
|
||||
}
|
||||
|
||||
static void lp872x_set_dvs(struct lp872x *lp, int gpio)
|
||||
static void lp872x_set_dvs(struct lp872x *lp, enum lp872x_dvs_sel dvs_sel,
|
||||
int gpio)
|
||||
{
|
||||
enum lp872x_dvs_sel dvs_sel = lp->pdata->dvs->vsel;
|
||||
enum lp872x_dvs_state state;
|
||||
|
||||
state = dvs_sel == SEL_V1 ? DVS_HIGH : DVS_LOW;
|
||||
@@ -339,10 +343,10 @@ static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev,
|
||||
struct lp872x *lp = rdev_get_drvdata(rdev);
|
||||
enum lp872x_regulator_id buck = rdev_get_id(rdev);
|
||||
u8 addr, mask = LP872X_VOUT_M;
|
||||
struct lp872x_dvs *dvs = lp->pdata->dvs;
|
||||
struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL;
|
||||
|
||||
if (dvs && gpio_is_valid(dvs->gpio))
|
||||
lp872x_set_dvs(lp, dvs->gpio);
|
||||
lp872x_set_dvs(lp, dvs->vsel, dvs->gpio);
|
||||
|
||||
addr = lp872x_select_buck_vout_addr(lp, buck);
|
||||
if (!lp872x_is_valid_buck_addr(addr))
|
||||
@@ -374,8 +378,8 @@ static int lp8725_buck_set_current_limit(struct regulator_dev *rdev,
|
||||
{
|
||||
struct lp872x *lp = rdev_get_drvdata(rdev);
|
||||
enum lp872x_regulator_id buck = rdev_get_id(rdev);
|
||||
int i, max = ARRAY_SIZE(lp8725_buck_uA);
|
||||
u8 addr, val;
|
||||
int i;
|
||||
u8 addr;
|
||||
|
||||
switch (buck) {
|
||||
case LP8725_ID_BUCK1:
|
||||
@@ -388,17 +392,15 @@ static int lp8725_buck_set_current_limit(struct regulator_dev *rdev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < max ; i++)
|
||||
for (i = ARRAY_SIZE(lp8725_buck_uA) - 1 ; i >= 0; i--) {
|
||||
if (lp8725_buck_uA[i] >= min_uA &&
|
||||
lp8725_buck_uA[i] <= max_uA)
|
||||
break;
|
||||
return lp872x_update_bits(lp, addr,
|
||||
LP8725_BUCK_CL_M,
|
||||
i << LP8725_BUCK_CL_S);
|
||||
}
|
||||
|
||||
if (i == max)
|
||||
return -EINVAL;
|
||||
|
||||
val = i << LP8725_BUCK_CL_S;
|
||||
|
||||
return lp872x_update_bits(lp, addr, LP8725_BUCK_CL_M, val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int lp8725_buck_get_current_limit(struct regulator_dev *rdev)
|
||||
@@ -727,39 +729,16 @@ static struct regulator_desc lp8725_regulator_desc[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int lp872x_check_dvs_validity(struct lp872x *lp)
|
||||
{
|
||||
struct lp872x_dvs *dvs = lp->pdata->dvs;
|
||||
u8 val = 0;
|
||||
int ret;
|
||||
|
||||
ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = 0;
|
||||
if (lp->chipid == LP8720) {
|
||||
if (val & LP8720_EXT_DVS_M)
|
||||
ret = dvs ? 0 : -EINVAL;
|
||||
} else {
|
||||
if ((val & LP8725_DVS1_M) == EXTERN_DVS_USED)
|
||||
ret = dvs ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lp872x_init_dvs(struct lp872x *lp)
|
||||
{
|
||||
int ret, gpio;
|
||||
struct lp872x_dvs *dvs = lp->pdata->dvs;
|
||||
struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL;
|
||||
enum lp872x_dvs_state pinstate;
|
||||
u8 mask[] = { LP8720_EXT_DVS_M, LP8725_DVS1_M | LP8725_DVS2_M };
|
||||
u8 default_dvs_mode[] = { LP8720_DEFAULT_DVS, LP8725_DEFAULT_DVS };
|
||||
|
||||
ret = lp872x_check_dvs_validity(lp);
|
||||
if (ret) {
|
||||
dev_warn(lp->dev, "invalid dvs data: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (!dvs)
|
||||
goto set_default_dvs_mode;
|
||||
|
||||
gpio = dvs->gpio;
|
||||
if (!gpio_is_valid(gpio)) {
|
||||
@@ -778,6 +757,10 @@ static int lp872x_init_dvs(struct lp872x *lp)
|
||||
lp->dvs_gpio = gpio;
|
||||
|
||||
return 0;
|
||||
|
||||
set_default_dvs_mode:
|
||||
return lp872x_update_bits(lp, LP872X_GENERAL_CFG, mask[lp->chipid],
|
||||
default_dvs_mode[lp->chipid]);
|
||||
}
|
||||
|
||||
static int lp872x_config(struct lp872x *lp)
|
||||
@@ -785,24 +768,29 @@ static int lp872x_config(struct lp872x *lp)
|
||||
struct lp872x_platform_data *pdata = lp->pdata;
|
||||
int ret;
|
||||
|
||||
if (!pdata->update_config)
|
||||
return 0;
|
||||
if (!pdata || !pdata->update_config)
|
||||
goto init_dvs;
|
||||
|
||||
ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
init_dvs:
|
||||
return lp872x_init_dvs(lp);
|
||||
}
|
||||
|
||||
static struct regulator_init_data
|
||||
*lp872x_find_regulator_init_data(int id, struct lp872x *lp)
|
||||
{
|
||||
struct lp872x_platform_data *pdata = lp->pdata;
|
||||
int i;
|
||||
|
||||
if (!pdata)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < lp->num_regulators; i++) {
|
||||
if (lp->pdata->regulator_data[i].id == id)
|
||||
return lp->pdata->regulator_data[i].init_data;
|
||||
if (pdata->regulator_data[i].id == id)
|
||||
return pdata->regulator_data[i].init_data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -863,18 +851,12 @@ static const struct regmap_config lp872x_regmap_config = {
|
||||
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
||||
{
|
||||
struct lp872x *lp;
|
||||
struct lp872x_platform_data *pdata = cl->dev.platform_data;
|
||||
int ret, size, num_regulators;
|
||||
const int lp872x_num_regulators[] = {
|
||||
[LP8720] = LP8720_NUM_REGULATORS,
|
||||
[LP8725] = LP8725_NUM_REGULATORS,
|
||||
};
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&cl->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
|
||||
if (!lp)
|
||||
goto err_mem;
|
||||
@@ -894,7 +876,7 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
||||
}
|
||||
|
||||
lp->dev = &cl->dev;
|
||||
lp->pdata = pdata;
|
||||
lp->pdata = cl->dev.platform_data;
|
||||
lp->chipid = id->driver_data;
|
||||
lp->num_regulators = num_regulators;
|
||||
i2c_set_clientdata(cl, lp);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user