Merge remote-tracking branches 'regulator/topic/core', 'regulator/topic/bypass', 'regulator/topic/tol', 'regulator/topic/drivers' and 'regulator/topic/tps6586x' into regulator-next
This commit is contained in:
Коммит
6a2027abd2
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -69,6 +69,9 @@
|
|||
#define PIN_HIGH 1
|
||||
#define ENABLE_TIME_USEC 32
|
||||
|
||||
#define BUCK_FPWM_MASK(x) (1 << (x))
|
||||
#define BUCK_FPWM_SHIFT(x) (x)
|
||||
|
||||
enum lp8788_dvs_state {
|
||||
DVS_LOW = GPIOF_OUT_INIT_LOW,
|
||||
DVS_HIGH = GPIOF_OUT_INIT_HIGH,
|
||||
|
@ -86,15 +89,9 @@ enum lp8788_buck_id {
|
|||
BUCK4,
|
||||
};
|
||||
|
||||
struct lp8788_pwm_map {
|
||||
u8 mask;
|
||||
u8 shift;
|
||||
};
|
||||
|
||||
struct lp8788_buck {
|
||||
struct lp8788 *lp;
|
||||
struct regulator_dev *regulator;
|
||||
struct lp8788_pwm_map *pmap;
|
||||
void *dvs;
|
||||
};
|
||||
|
||||
|
@ -106,29 +103,6 @@ static const int lp8788_buck_vtbl[] = {
|
|||
1950000, 2000000,
|
||||
};
|
||||
|
||||
/* buck pwm mode selection : used for set/get_mode in regulator ops
|
||||
* @forced pwm : fast mode
|
||||
* @auto pwm : normal mode
|
||||
*/
|
||||
static struct lp8788_pwm_map buck_pmap[] = {
|
||||
[BUCK1] = {
|
||||
.mask = LP8788_FPWM_BUCK1_M,
|
||||
.shift = LP8788_FPWM_BUCK1_S,
|
||||
},
|
||||
[BUCK2] = {
|
||||
.mask = LP8788_FPWM_BUCK2_M,
|
||||
.shift = LP8788_FPWM_BUCK2_S,
|
||||
},
|
||||
[BUCK3] = {
|
||||
.mask = LP8788_FPWM_BUCK3_M,
|
||||
.shift = LP8788_FPWM_BUCK3_S,
|
||||
},
|
||||
[BUCK4] = {
|
||||
.mask = LP8788_FPWM_BUCK4_M,
|
||||
.shift = LP8788_FPWM_BUCK4_S,
|
||||
},
|
||||
};
|
||||
|
||||
static const u8 buck1_vout_addr[] = {
|
||||
LP8788_BUCK1_VOUT0, LP8788_BUCK1_VOUT1,
|
||||
LP8788_BUCK1_VOUT2, LP8788_BUCK1_VOUT3,
|
||||
|
@ -347,41 +321,37 @@ static int lp8788_buck_enable_time(struct regulator_dev *rdev)
|
|||
static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
struct lp8788_buck *buck = rdev_get_drvdata(rdev);
|
||||
struct lp8788_pwm_map *pmap = buck->pmap;
|
||||
u8 val;
|
||||
|
||||
if (!pmap)
|
||||
return -EINVAL;
|
||||
enum lp8788_buck_id id = rdev_get_id(rdev);
|
||||
u8 mask, val;
|
||||
|
||||
mask = BUCK_FPWM_MASK(id);
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_FAST:
|
||||
val = LP8788_FORCE_PWM << pmap->shift;
|
||||
val = LP8788_FORCE_PWM << BUCK_FPWM_SHIFT(id);
|
||||
break;
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
val = LP8788_AUTO_PWM << pmap->shift;
|
||||
val = LP8788_AUTO_PWM << BUCK_FPWM_SHIFT(id);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, pmap->mask, val);
|
||||
return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, mask, val);
|
||||
}
|
||||
|
||||
static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
struct lp8788_buck *buck = rdev_get_drvdata(rdev);
|
||||
struct lp8788_pwm_map *pmap = buck->pmap;
|
||||
enum lp8788_buck_id id = rdev_get_id(rdev);
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
if (!pmap)
|
||||
return -EINVAL;
|
||||
|
||||
ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return val & pmap->mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
|
||||
return val & BUCK_FPWM_MASK(id) ?
|
||||
REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static struct regulator_ops lp8788_buck12_ops = {
|
||||
|
@ -459,27 +429,6 @@ static struct regulator_desc lp8788_buck_desc[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static int lp8788_set_default_dvs_ctrl_mode(struct lp8788 *lp,
|
||||
enum lp8788_buck_id id)
|
||||
{
|
||||
u8 mask, val;
|
||||
|
||||
switch (id) {
|
||||
case BUCK1:
|
||||
mask = LP8788_BUCK1_DVS_SEL_M;
|
||||
val = LP8788_BUCK1_DVS_I2C;
|
||||
break;
|
||||
case BUCK2:
|
||||
mask = LP8788_BUCK2_DVS_SEL_M;
|
||||
val = LP8788_BUCK2_DVS_I2C;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return lp8788_update_bits(lp, LP8788_BUCK_DVS_SEL, mask, val);
|
||||
}
|
||||
|
||||
static int _gpio_request(struct lp8788_buck *buck, int gpio, char *name)
|
||||
{
|
||||
struct device *dev = buck->lp->dev;
|
||||
|
@ -530,6 +479,7 @@ static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
|
|||
struct lp8788_platform_data *pdata = buck->lp->pdata;
|
||||
u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M };
|
||||
u8 val[] = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN };
|
||||
u8 default_dvs_mode[] = { LP8788_BUCK1_DVS_I2C, LP8788_BUCK2_DVS_I2C };
|
||||
|
||||
/* no dvs for buck3, 4 */
|
||||
if (id == BUCK3 || id == BUCK4)
|
||||
|
@ -550,7 +500,8 @@ static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
|
|||
val[id]);
|
||||
|
||||
set_default_dvs_mode:
|
||||
return lp8788_set_default_dvs_ctrl_mode(buck->lp, id);
|
||||
return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
|
||||
default_dvs_mode[id]);
|
||||
}
|
||||
|
||||
static __devinit int lp8788_buck_probe(struct platform_device *pdev)
|
||||
|
@ -567,7 +518,6 @@ static __devinit int lp8788_buck_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
|
||||
buck->lp = lp;
|
||||
buck->pmap = &buck_pmap[id];
|
||||
|
||||
ret = lp8788_init_dvs(buck, id);
|
||||
if (ret)
|
||||
|
|
|
@ -496,6 +496,7 @@ static struct regulator_desc lp8788_dldo_desc[] = {
|
|||
.name = "dldo12",
|
||||
.id = DLDO12,
|
||||
.ops = &lp8788_ldo_voltage_fixed_ops,
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_LDO_B,
|
||||
|
@ -521,6 +522,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
|
|||
.name = "aldo2",
|
||||
.id = ALDO2,
|
||||
.ops = &lp8788_ldo_voltage_fixed_ops,
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_LDO_B,
|
||||
|
@ -530,6 +532,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
|
|||
.name = "aldo3",
|
||||
.id = ALDO3,
|
||||
.ops = &lp8788_ldo_voltage_fixed_ops,
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_LDO_B,
|
||||
|
@ -539,6 +542,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
|
|||
.name = "aldo4",
|
||||
.id = ALDO4,
|
||||
.ops = &lp8788_ldo_voltage_fixed_ops,
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_LDO_B,
|
||||
|
@ -548,6 +552,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
|
|||
.name = "aldo5",
|
||||
.id = ALDO5,
|
||||
.ops = &lp8788_ldo_voltage_fixed_ops,
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_LDO_C,
|
||||
|
@ -583,6 +588,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
|
|||
.name = "aldo8",
|
||||
.id = ALDO8,
|
||||
.ops = &lp8788_ldo_voltage_fixed_ops,
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_LDO_C,
|
||||
|
@ -592,6 +598,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
|
|||
.name = "aldo9",
|
||||
.id = ALDO9,
|
||||
.ops = &lp8788_ldo_voltage_fixed_ops,
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_LDO_C,
|
||||
|
@ -601,6 +608,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
|
|||
.name = "aldo10",
|
||||
.id = ALDO10,
|
||||
.ops = &lp8788_ldo_voltage_fixed_ops,
|
||||
.n_voltages = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_LDO_C,
|
||||
|
|
|
@ -66,7 +66,7 @@ enum max77686_ramp_rate {
|
|||
};
|
||||
|
||||
struct max77686_data {
|
||||
struct regulator_dev **rdev;
|
||||
struct regulator_dev *rdev[MAX77686_REGULATORS];
|
||||
};
|
||||
|
||||
static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
|
||||
|
@ -265,6 +265,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,
|
|||
rmatch.of_node = NULL;
|
||||
of_regulator_match(iodev->dev, regulators_np, &rmatch, 1);
|
||||
rdata[i].initdata = rmatch.init_data;
|
||||
rdata[i].of_node = rmatch.of_node;
|
||||
}
|
||||
|
||||
pdata->regulators = rdata;
|
||||
|
@ -283,10 +284,8 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev);
|
||||
struct regulator_dev **rdev;
|
||||
struct max77686_data *max77686;
|
||||
int i, size;
|
||||
int ret = 0;
|
||||
int i, ret = 0;
|
||||
struct regulator_config config = { };
|
||||
|
||||
dev_dbg(&pdev->dev, "%s\n", __func__);
|
||||
|
@ -313,45 +312,38 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev)
|
|||
if (!max77686)
|
||||
return -ENOMEM;
|
||||
|
||||
size = sizeof(struct regulator_dev *) * MAX77686_REGULATORS;
|
||||
max77686->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
|
||||
if (!max77686->rdev)
|
||||
return -ENOMEM;
|
||||
|
||||
rdev = max77686->rdev;
|
||||
config.dev = &pdev->dev;
|
||||
config.regmap = iodev->regmap;
|
||||
platform_set_drvdata(pdev, max77686);
|
||||
|
||||
for (i = 0; i < MAX77686_REGULATORS; i++) {
|
||||
config.init_data = pdata->regulators[i].initdata;
|
||||
config.of_node = pdata->regulators[i].of_node;
|
||||
|
||||
rdev[i] = regulator_register(®ulators[i], &config);
|
||||
if (IS_ERR(rdev[i])) {
|
||||
ret = PTR_ERR(rdev[i]);
|
||||
max77686->rdev[i] = regulator_register(®ulators[i], &config);
|
||||
if (IS_ERR(max77686->rdev[i])) {
|
||||
ret = PTR_ERR(max77686->rdev[i]);
|
||||
dev_err(&pdev->dev,
|
||||
"regulator init failed for %d\n", i);
|
||||
rdev[i] = NULL;
|
||||
goto err;
|
||||
max77686->rdev[i] = NULL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
while (--i >= 0)
|
||||
regulator_unregister(rdev[i]);
|
||||
regulator_unregister(max77686->rdev[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit max77686_pmic_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct max77686_data *max77686 = platform_get_drvdata(pdev);
|
||||
struct regulator_dev **rdev = max77686->rdev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX77686_REGULATORS; i++)
|
||||
if (rdev[i])
|
||||
regulator_unregister(rdev[i]);
|
||||
regulator_unregister(max77686->rdev[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* max8907-regulator.c -- support regulators in max8907
|
||||
*
|
||||
* Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
|
||||
* Copyright (C) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Portions based on drivers/regulator/tps65910-regulator.c,
|
||||
* Copyright 2010 Texas Instruments Inc.
|
||||
* Author: Graeme Gregory <gg@slimlogic.co.uk>
|
||||
* Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
|
||||
*
|
||||
* This program 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/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/max8907.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define MAX8907_II2RR_VERSION_MASK 0xF0
|
||||
#define MAX8907_II2RR_VERSION_REV_A 0x00
|
||||
#define MAX8907_II2RR_VERSION_REV_B 0x10
|
||||
#define MAX8907_II2RR_VERSION_REV_C 0x30
|
||||
|
||||
struct max8907_regulator {
|
||||
struct regulator_desc desc[MAX8907_NUM_REGULATORS];
|
||||
struct regulator_dev *rdev[MAX8907_NUM_REGULATORS];
|
||||
};
|
||||
|
||||
#define REG_MBATT() \
|
||||
[MAX8907_MBATT] = { \
|
||||
.name = "MBATT", \
|
||||
.supply_name = "mbatt", \
|
||||
.id = MAX8907_MBATT, \
|
||||
.ops = &max8907_mbatt_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
#define REG_LDO(ids, supply, base, min, max, step) \
|
||||
[MAX8907_##ids] = { \
|
||||
.name = #ids, \
|
||||
.supply_name = supply, \
|
||||
.id = MAX8907_##ids, \
|
||||
.n_voltages = ((max) - (min)) / (step) + 1, \
|
||||
.ops = &max8907_ldo_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = (min), \
|
||||
.uV_step = (step), \
|
||||
.vsel_reg = (base) + MAX8907_VOUT, \
|
||||
.vsel_mask = 0x3f, \
|
||||
.enable_reg = (base) + MAX8907_CTL, \
|
||||
.enable_mask = MAX8907_MASK_LDO_EN, \
|
||||
}
|
||||
|
||||
#define REG_FIXED(ids, supply, voltage) \
|
||||
[MAX8907_##ids] = { \
|
||||
.name = #ids, \
|
||||
.supply_name = supply, \
|
||||
.id = MAX8907_##ids, \
|
||||
.n_voltages = 1, \
|
||||
.ops = &max8907_fixed_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = (voltage), \
|
||||
}
|
||||
|
||||
#define REG_OUT5V(ids, supply, base, voltage) \
|
||||
[MAX8907_##ids] = { \
|
||||
.name = #ids, \
|
||||
.supply_name = supply, \
|
||||
.id = MAX8907_##ids, \
|
||||
.n_voltages = 1, \
|
||||
.ops = &max8907_out5v_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = (voltage), \
|
||||
.enable_reg = (base), \
|
||||
.enable_mask = MAX8907_MASK_OUT5V_EN, \
|
||||
}
|
||||
|
||||
#define REG_BBAT(ids, supply, base, min, max, step) \
|
||||
[MAX8907_##ids] = { \
|
||||
.name = #ids, \
|
||||
.supply_name = supply, \
|
||||
.id = MAX8907_##ids, \
|
||||
.n_voltages = ((max) - (min)) / (step) + 1, \
|
||||
.ops = &max8907_bbat_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = (min), \
|
||||
.uV_step = (step), \
|
||||
.vsel_reg = (base), \
|
||||
.vsel_mask = MAX8907_MASK_VBBATTCV, \
|
||||
}
|
||||
|
||||
#define LDO_750_50(id, supply, base) REG_LDO(id, supply, (base), \
|
||||
750000, 3900000, 50000)
|
||||
#define LDO_650_25(id, supply, base) REG_LDO(id, supply, (base), \
|
||||
650000, 2225000, 25000)
|
||||
|
||||
static struct regulator_ops max8907_mbatt_ops = {
|
||||
};
|
||||
|
||||
static struct regulator_ops max8907_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops max8907_ldo_hwctl_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops max8907_fixed_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
static struct regulator_ops max8907_out5v_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops max8907_out5v_hwctl_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
static struct regulator_ops max8907_bbat_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_desc max8907_regulators[] = {
|
||||
REG_MBATT(),
|
||||
REG_LDO(SD1, "in-v1", MAX8907_REG_SDCTL1, 650000, 2225000, 25000),
|
||||
REG_LDO(SD2, "in-v2", MAX8907_REG_SDCTL2, 637500, 1425000, 12500),
|
||||
REG_LDO(SD3, "in-v3", MAX8907_REG_SDCTL3, 750000, 3900000, 50000),
|
||||
LDO_750_50(LDO1, "in1", MAX8907_REG_LDOCTL1),
|
||||
LDO_650_25(LDO2, "in2", MAX8907_REG_LDOCTL2),
|
||||
LDO_650_25(LDO3, "in3", MAX8907_REG_LDOCTL3),
|
||||
LDO_750_50(LDO4, "in4", MAX8907_REG_LDOCTL4),
|
||||
LDO_750_50(LDO5, "in5", MAX8907_REG_LDOCTL5),
|
||||
LDO_750_50(LDO6, "in6", MAX8907_REG_LDOCTL6),
|
||||
LDO_750_50(LDO7, "in7", MAX8907_REG_LDOCTL7),
|
||||
LDO_750_50(LDO8, "in8", MAX8907_REG_LDOCTL8),
|
||||
LDO_750_50(LDO9, "in9", MAX8907_REG_LDOCTL9),
|
||||
LDO_750_50(LDO10, "in10", MAX8907_REG_LDOCTL10),
|
||||
LDO_750_50(LDO11, "in11", MAX8907_REG_LDOCTL11),
|
||||
LDO_750_50(LDO12, "in12", MAX8907_REG_LDOCTL12),
|
||||
LDO_750_50(LDO13, "in13", MAX8907_REG_LDOCTL13),
|
||||
LDO_750_50(LDO14, "in14", MAX8907_REG_LDOCTL14),
|
||||
LDO_750_50(LDO15, "in15", MAX8907_REG_LDOCTL15),
|
||||
LDO_750_50(LDO16, "in16", MAX8907_REG_LDOCTL16),
|
||||
LDO_650_25(LDO17, "in17", MAX8907_REG_LDOCTL17),
|
||||
LDO_650_25(LDO18, "in18", MAX8907_REG_LDOCTL18),
|
||||
LDO_750_50(LDO19, "in19", MAX8907_REG_LDOCTL19),
|
||||
LDO_750_50(LDO20, "in20", MAX8907_REG_LDOCTL20),
|
||||
REG_OUT5V(OUT5V, "mbatt", MAX8907_REG_OUT5VEN, 5000000),
|
||||
REG_OUT5V(OUT33V, "mbatt", MAX8907_REG_OUT33VEN, 3300000),
|
||||
REG_BBAT(BBAT, "MBATT", MAX8907_REG_BBAT_CNFG,
|
||||
2400000, 3000000, 200000),
|
||||
REG_FIXED(SDBY, "MBATT", 1200000),
|
||||
REG_FIXED(VRTC, "MBATT", 3300000),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
#define MATCH(_name, _id) \
|
||||
[MAX8907_##_id] = { \
|
||||
.name = #_name, \
|
||||
.driver_data = (void *)&max8907_regulators[MAX8907_##_id], \
|
||||
}
|
||||
|
||||
static struct of_regulator_match max8907_matches[] = {
|
||||
MATCH(mbatt, MBATT),
|
||||
MATCH(sd1, SD1),
|
||||
MATCH(sd2, SD2),
|
||||
MATCH(sd3, SD3),
|
||||
MATCH(ldo1, LDO1),
|
||||
MATCH(ldo2, LDO2),
|
||||
MATCH(ldo3, LDO3),
|
||||
MATCH(ldo4, LDO4),
|
||||
MATCH(ldo5, LDO5),
|
||||
MATCH(ldo6, LDO6),
|
||||
MATCH(ldo7, LDO7),
|
||||
MATCH(ldo8, LDO8),
|
||||
MATCH(ldo9, LDO9),
|
||||
MATCH(ldo10, LDO10),
|
||||
MATCH(ldo11, LDO11),
|
||||
MATCH(ldo12, LDO12),
|
||||
MATCH(ldo13, LDO13),
|
||||
MATCH(ldo14, LDO14),
|
||||
MATCH(ldo15, LDO15),
|
||||
MATCH(ldo16, LDO16),
|
||||
MATCH(ldo17, LDO17),
|
||||
MATCH(ldo18, LDO18),
|
||||
MATCH(ldo19, LDO19),
|
||||
MATCH(ldo20, LDO20),
|
||||
MATCH(out5v, OUT5V),
|
||||
MATCH(out33v, OUT33V),
|
||||
MATCH(bbat, BBAT),
|
||||
MATCH(sdby, SDBY),
|
||||
MATCH(vrtc, VRTC),
|
||||
};
|
||||
|
||||
static int max8907_regulator_parse_dt(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.parent->of_node;
|
||||
struct device_node *regulators;
|
||||
int ret;
|
||||
|
||||
if (!pdev->dev.parent->of_node)
|
||||
return 0;
|
||||
|
||||
regulators = of_find_node_by_name(np, "regulators");
|
||||
if (!regulators) {
|
||||
dev_err(&pdev->dev, "regulators node not found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_regulator_match(pdev->dev.parent, regulators,
|
||||
max8907_matches,
|
||||
ARRAY_SIZE(max8907_matches));
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct regulator_init_data *match_init_data(int index)
|
||||
{
|
||||
return max8907_matches[index].init_data;
|
||||
}
|
||||
|
||||
static inline struct device_node *match_of_node(int index)
|
||||
{
|
||||
return max8907_matches[index].of_node;
|
||||
}
|
||||
#else
|
||||
static int max8907_regulator_parse_dt(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct regulator_init_data *match_init_data(int index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct device_node *match_of_node(int index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static __devinit int max8907_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct max8907_platform_data *pdata = dev_get_platdata(max8907->dev);
|
||||
int ret;
|
||||
struct max8907_regulator *pmic;
|
||||
unsigned int val;
|
||||
int i;
|
||||
struct regulator_config config = {};
|
||||
struct regulator_init_data *idata;
|
||||
const char *mbatt_rail_name = NULL;
|
||||
|
||||
ret = max8907_regulator_parse_dt(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
|
||||
if (!pmic) {
|
||||
dev_err(&pdev->dev, "Failed to alloc pmic\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
platform_set_drvdata(pdev, pmic);
|
||||
|
||||
memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc));
|
||||
|
||||
/* Backwards compatibility with MAX8907B; SD1 uses different voltages */
|
||||
regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val);
|
||||
if ((val & MAX8907_II2RR_VERSION_MASK) ==
|
||||
MAX8907_II2RR_VERSION_REV_B) {
|
||||
pmic->desc[MAX8907_SD1].min_uV = 637500;
|
||||
pmic->desc[MAX8907_SD1].uV_step = 12500;
|
||||
pmic->desc[MAX8907_SD1].n_voltages =
|
||||
(1425000 - 637500) / 12500 + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX8907_NUM_REGULATORS; i++) {
|
||||
config.dev = pdev->dev.parent;
|
||||
if (pdata)
|
||||
idata = pdata->init_data[i];
|
||||
else
|
||||
idata = match_init_data(i);
|
||||
config.init_data = idata;
|
||||
config.driver_data = pmic;
|
||||
config.regmap = max8907->regmap_gen;
|
||||
config.of_node = match_of_node(i);
|
||||
|
||||
switch (pmic->desc[i].id) {
|
||||
case MAX8907_MBATT:
|
||||
if (idata && idata->constraints.name)
|
||||
mbatt_rail_name = idata->constraints.name;
|
||||
else
|
||||
mbatt_rail_name = pmic->desc[i].name;
|
||||
break;
|
||||
case MAX8907_BBAT:
|
||||
case MAX8907_SDBY:
|
||||
case MAX8907_VRTC:
|
||||
idata->supply_regulator = mbatt_rail_name;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pmic->desc[i].ops == &max8907_ldo_ops) {
|
||||
regmap_read(config.regmap, pmic->desc[i].enable_reg,
|
||||
&val);
|
||||
if ((val & MAX8907_MASK_LDO_SEQ) !=
|
||||
MAX8907_MASK_LDO_SEQ)
|
||||
pmic->desc[i].ops = &max8907_ldo_hwctl_ops;
|
||||
} else if (pmic->desc[i].ops == &max8907_out5v_ops) {
|
||||
regmap_read(config.regmap, pmic->desc[i].enable_reg,
|
||||
&val);
|
||||
if ((val & (MAX8907_MASK_OUT5V_VINEN |
|
||||
MAX8907_MASK_OUT5V_ENSRC)) !=
|
||||
MAX8907_MASK_OUT5V_ENSRC)
|
||||
pmic->desc[i].ops = &max8907_out5v_hwctl_ops;
|
||||
}
|
||||
|
||||
pmic->rdev[i] = regulator_register(&pmic->desc[i], &config);
|
||||
if (IS_ERR(pmic->rdev[i])) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to register %s regulator\n",
|
||||
pmic->desc[i].name);
|
||||
ret = PTR_ERR(pmic->rdev[i]);
|
||||
goto err_unregister_regulator;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_regulator:
|
||||
while (--i >= 0)
|
||||
regulator_unregister(pmic->rdev[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __devexit int max8907_regulator_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct max8907_regulator *pmic = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX8907_NUM_REGULATORS; i++)
|
||||
regulator_unregister(pmic->rdev[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver max8907_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "max8907-regulator",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = max8907_regulator_probe,
|
||||
.remove = __devexit_p(max8907_regulator_remove),
|
||||
};
|
||||
|
||||
static int __init max8907_regulator_init(void)
|
||||
{
|
||||
return platform_driver_register(&max8907_regulator_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(max8907_regulator_init);
|
||||
|
||||
static void __exit max8907_reg_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&max8907_regulator_driver);
|
||||
}
|
||||
|
||||
module_exit(max8907_reg_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MAX8907 regulator driver");
|
||||
MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:max8907-regulator");
|
|
@ -21,6 +21,30 @@
|
|||
#include <linux/module.h>
|
||||
#include "mc13xxx.h"
|
||||
|
||||
#define MC13783_REG_SWITCHERS0 24
|
||||
/* Enable does not exist for SW1A */
|
||||
#define MC13783_REG_SWITCHERS0_SW1AEN 0
|
||||
#define MC13783_REG_SWITCHERS0_SW1AVSEL 0
|
||||
#define MC13783_REG_SWITCHERS0_SW1AVSEL_M (63 << 0)
|
||||
|
||||
#define MC13783_REG_SWITCHERS1 25
|
||||
/* Enable does not exist for SW1B */
|
||||
#define MC13783_REG_SWITCHERS1_SW1BEN 0
|
||||
#define MC13783_REG_SWITCHERS1_SW1BVSEL 0
|
||||
#define MC13783_REG_SWITCHERS1_SW1BVSEL_M (63 << 0)
|
||||
|
||||
#define MC13783_REG_SWITCHERS2 26
|
||||
/* Enable does not exist for SW2A */
|
||||
#define MC13783_REG_SWITCHERS2_SW2AEN 0
|
||||
#define MC13783_REG_SWITCHERS2_SW2AVSEL 0
|
||||
#define MC13783_REG_SWITCHERS2_SW2AVSEL_M (63 << 0)
|
||||
|
||||
#define MC13783_REG_SWITCHERS3 27
|
||||
/* Enable does not exist for SW2B */
|
||||
#define MC13783_REG_SWITCHERS3_SW2BEN 0
|
||||
#define MC13783_REG_SWITCHERS3_SW2BVSEL 0
|
||||
#define MC13783_REG_SWITCHERS3_SW2BVSEL_M (63 << 0)
|
||||
|
||||
#define MC13783_REG_SWITCHERS5 29
|
||||
#define MC13783_REG_SWITCHERS5_SW3EN (1 << 20)
|
||||
#define MC13783_REG_SWITCHERS5_SW3VSEL 18
|
||||
|
@ -93,6 +117,44 @@
|
|||
|
||||
|
||||
/* Voltage Values */
|
||||
static const int mc13783_sw1x_val[] = {
|
||||
900000, 925000, 950000, 975000,
|
||||
1000000, 1025000, 1050000, 1075000,
|
||||
1100000, 1125000, 1150000, 1175000,
|
||||
1200000, 1225000, 1250000, 1275000,
|
||||
1300000, 1325000, 1350000, 1375000,
|
||||
1400000, 1425000, 1450000, 1475000,
|
||||
1500000, 1525000, 1550000, 1575000,
|
||||
1600000, 1625000, 1650000, 1675000,
|
||||
1700000, 1700000, 1700000, 1700000,
|
||||
1800000, 1800000, 1800000, 1800000,
|
||||
1850000, 1850000, 1850000, 1850000,
|
||||
2000000, 2000000, 2000000, 2000000,
|
||||
2100000, 2100000, 2100000, 2100000,
|
||||
2200000, 2200000, 2200000, 2200000,
|
||||
2200000, 2200000, 2200000, 2200000,
|
||||
2200000, 2200000, 2200000, 2200000,
|
||||
};
|
||||
|
||||
static const int mc13783_sw2x_val[] = {
|
||||
900000, 925000, 950000, 975000,
|
||||
1000000, 1025000, 1050000, 1075000,
|
||||
1100000, 1125000, 1150000, 1175000,
|
||||
1200000, 1225000, 1250000, 1275000,
|
||||
1300000, 1325000, 1350000, 1375000,
|
||||
1400000, 1425000, 1450000, 1475000,
|
||||
1500000, 1525000, 1550000, 1575000,
|
||||
1600000, 1625000, 1650000, 1675000,
|
||||
1700000, 1700000, 1700000, 1700000,
|
||||
1800000, 1800000, 1800000, 1800000,
|
||||
1900000, 1900000, 1900000, 1900000,
|
||||
2000000, 2000000, 2000000, 2000000,
|
||||
2100000, 2100000, 2100000, 2100000,
|
||||
2200000, 2200000, 2200000, 2200000,
|
||||
2200000, 2200000, 2200000, 2200000,
|
||||
2200000, 2200000, 2200000, 2200000,
|
||||
};
|
||||
|
||||
static const unsigned int mc13783_sw3_val[] = {
|
||||
5000000, 5000000, 5000000, 5500000,
|
||||
};
|
||||
|
@ -188,6 +250,10 @@ static struct regulator_ops mc13783_gpo_regulator_ops;
|
|||
MC13783_DEFINE(REG, _name, _reg, _vsel_reg, _voltages)
|
||||
|
||||
static struct mc13xxx_regulator mc13783_regulators[] = {
|
||||
MC13783_DEFINE_SW(SW1A, SWITCHERS0, SWITCHERS0, mc13783_sw1x_val),
|
||||
MC13783_DEFINE_SW(SW1B, SWITCHERS1, SWITCHERS1, mc13783_sw1x_val),
|
||||
MC13783_DEFINE_SW(SW2A, SWITCHERS2, SWITCHERS2, mc13783_sw2x_val),
|
||||
MC13783_DEFINE_SW(SW2B, SWITCHERS3, SWITCHERS3, mc13783_sw2x_val),
|
||||
MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val),
|
||||
|
||||
MC13783_FIXED_DEFINE(REG, VAUDIO, REGULATORMODE0, mc13783_vaudio_val),
|
||||
|
@ -238,9 +304,10 @@ static int mc13783_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask,
|
|||
|
||||
BUG_ON(val & ~mask);
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13xxx_reg_read(mc13783, MC13783_REG_POWERMISC, &valread);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
/* Update the stored state for Power Gates. */
|
||||
priv->powermisc_pwgt_state =
|
||||
|
@ -253,7 +320,10 @@ static int mc13783_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask,
|
|||
valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
|
||||
priv->powermisc_pwgt_state;
|
||||
|
||||
return mc13xxx_reg_write(mc13783, MC13783_REG_POWERMISC, valread);
|
||||
ret = mc13xxx_reg_write(mc13783, MC13783_REG_POWERMISC, valread);
|
||||
out:
|
||||
mc13xxx_unlock(priv->mc13xxx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev)
|
||||
|
@ -261,7 +331,6 @@ static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev)
|
|||
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
|
||||
struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
|
||||
int id = rdev_get_id(rdev);
|
||||
int ret;
|
||||
u32 en_val = mc13xxx_regulators[id].enable_bit;
|
||||
|
||||
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
|
||||
|
@ -271,12 +340,8 @@ static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev)
|
|||
id == MC13783_REG_PWGT2SPI)
|
||||
en_val = 0;
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit,
|
||||
return mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit,
|
||||
en_val);
|
||||
mc13xxx_unlock(priv->mc13xxx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev)
|
||||
|
@ -284,7 +349,6 @@ static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev)
|
|||
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
|
||||
struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
|
||||
int id = rdev_get_id(rdev);
|
||||
int ret;
|
||||
u32 dis_val = 0;
|
||||
|
||||
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
|
||||
|
@ -294,12 +358,8 @@ static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev)
|
|||
id == MC13783_REG_PWGT2SPI)
|
||||
dis_val = mc13xxx_regulators[id].enable_bit;
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit,
|
||||
return mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit,
|
||||
dis_val);
|
||||
mc13xxx_unlock(priv->mc13xxx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
|
@ -330,7 +390,6 @@ static struct regulator_ops mc13783_gpo_regulator_ops = {
|
|||
.is_enabled = mc13783_gpo_regulator_is_enabled,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.set_voltage = mc13xxx_fixed_regulator_set_voltage,
|
||||
.get_voltage = mc13xxx_fixed_regulator_get_voltage,
|
||||
};
|
||||
|
||||
static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
|
||||
|
|
|
@ -305,9 +305,10 @@ static int mc13892_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask,
|
|||
|
||||
BUG_ON(val & ~mask);
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13xxx_reg_read(mc13892, MC13892_POWERMISC, &valread);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
/* Update the stored state for Power Gates. */
|
||||
priv->powermisc_pwgt_state =
|
||||
|
@ -320,14 +321,16 @@ static int mc13892_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask,
|
|||
valread = (valread & ~MC13892_POWERMISC_PWGTSPI_M) |
|
||||
priv->powermisc_pwgt_state;
|
||||
|
||||
return mc13xxx_reg_write(mc13892, MC13892_POWERMISC, valread);
|
||||
ret = mc13xxx_reg_write(mc13892, MC13892_POWERMISC, valread);
|
||||
out:
|
||||
mc13xxx_unlock(priv->mc13xxx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mc13892_gpo_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
|
||||
int id = rdev_get_id(rdev);
|
||||
int ret;
|
||||
u32 en_val = mc13892_regulators[id].enable_bit;
|
||||
u32 mask = mc13892_regulators[id].enable_bit;
|
||||
|
||||
|
@ -340,18 +343,13 @@ static int mc13892_gpo_regulator_enable(struct regulator_dev *rdev)
|
|||
if (id == MC13892_GPO4)
|
||||
mask |= MC13892_POWERMISC_GPO4ADINEN;
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13892_powermisc_rmw(priv, mask, en_val);
|
||||
mc13xxx_unlock(priv->mc13xxx);
|
||||
|
||||
return ret;
|
||||
return mc13892_powermisc_rmw(priv, mask, en_val);
|
||||
}
|
||||
|
||||
static int mc13892_gpo_regulator_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
|
||||
int id = rdev_get_id(rdev);
|
||||
int ret;
|
||||
u32 dis_val = 0;
|
||||
|
||||
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
|
||||
|
@ -360,12 +358,8 @@ static int mc13892_gpo_regulator_disable(struct regulator_dev *rdev)
|
|||
if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI)
|
||||
dis_val = mc13892_regulators[id].enable_bit;
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13892_powermisc_rmw(priv, mc13892_regulators[id].enable_bit,
|
||||
return mc13892_powermisc_rmw(priv, mc13892_regulators[id].enable_bit,
|
||||
dis_val);
|
||||
mc13xxx_unlock(priv->mc13xxx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
|
@ -396,14 +390,13 @@ static struct regulator_ops mc13892_gpo_regulator_ops = {
|
|||
.is_enabled = mc13892_gpo_regulator_is_enabled,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.set_voltage = mc13xxx_fixed_regulator_set_voltage,
|
||||
.get_voltage = mc13xxx_fixed_regulator_get_voltage,
|
||||
};
|
||||
|
||||
static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev)
|
||||
static int mc13892_sw_regulator_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
|
||||
int ret, id = rdev_get_id(rdev);
|
||||
unsigned int val, hi;
|
||||
unsigned int val;
|
||||
|
||||
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
|
||||
|
||||
|
@ -414,17 +407,11 @@ static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
hi = val & MC13892_SWITCHERS0_SWxHI;
|
||||
val = (val & mc13892_regulators[id].vsel_mask)
|
||||
>> mc13892_regulators[id].vsel_shift;
|
||||
|
||||
dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
|
||||
|
||||
if (hi)
|
||||
val = (25000 * val) + 1100000;
|
||||
else
|
||||
val = (25000 * val) + 600000;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -432,37 +419,25 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
|||
unsigned selector)
|
||||
{
|
||||
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
|
||||
int hi, value, mask, id = rdev_get_id(rdev);
|
||||
u32 valread;
|
||||
int volt, mask, id = rdev_get_id(rdev);
|
||||
u32 reg_value;
|
||||
int ret;
|
||||
|
||||
value = rdev->desc->volt_table[selector];
|
||||
volt = rdev->desc->volt_table[selector];
|
||||
mask = mc13892_regulators[id].vsel_mask;
|
||||
reg_value = selector << mc13892_regulators[id].vsel_shift;
|
||||
|
||||
if (volt > 1375000) {
|
||||
mask |= MC13892_SWITCHERS0_SWxHI;
|
||||
reg_value |= MC13892_SWITCHERS0_SWxHI;
|
||||
} else if (volt < 1100000) {
|
||||
mask |= MC13892_SWITCHERS0_SWxHI;
|
||||
reg_value &= ~MC13892_SWITCHERS0_SWxHI;
|
||||
}
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13xxx_reg_read(priv->mc13xxx,
|
||||
mc13892_regulators[id].vsel_reg, &valread);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (value > 1375000)
|
||||
hi = 1;
|
||||
else if (value < 1100000)
|
||||
hi = 0;
|
||||
else
|
||||
hi = valread & MC13892_SWITCHERS0_SWxHI;
|
||||
|
||||
if (hi) {
|
||||
value = (value - 1100000) / 25000;
|
||||
value |= MC13892_SWITCHERS0_SWxHI;
|
||||
} else
|
||||
value = (value - 600000) / 25000;
|
||||
|
||||
mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI;
|
||||
valread = (valread & ~mask) |
|
||||
(value << mc13892_regulators[id].vsel_shift);
|
||||
ret = mc13xxx_reg_write(priv->mc13xxx, mc13892_regulators[id].vsel_reg,
|
||||
valread);
|
||||
err:
|
||||
ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].reg, mask,
|
||||
reg_value);
|
||||
mc13xxx_unlock(priv->mc13xxx);
|
||||
|
||||
return ret;
|
||||
|
@ -471,7 +446,7 @@ err:
|
|||
static struct regulator_ops mc13892_sw_regulator_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.set_voltage_sel = mc13892_sw_regulator_set_voltage_sel,
|
||||
.get_voltage = mc13892_sw_regulator_get_voltage,
|
||||
.get_voltage_sel = mc13892_sw_regulator_get_voltage_sel,
|
||||
};
|
||||
|
||||
static int mc13892_vcam_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
|
|
|
@ -143,30 +143,21 @@ int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
|
|||
__func__, id, min_uV, max_uV);
|
||||
|
||||
if (min_uV <= rdev->desc->volt_table[0] &&
|
||||
rdev->desc->volt_table[0] <= max_uV)
|
||||
rdev->desc->volt_table[0] <= max_uV) {
|
||||
*selector = 0;
|
||||
return 0;
|
||||
else
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage);
|
||||
|
||||
int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
int id = rdev_get_id(rdev);
|
||||
|
||||
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
|
||||
|
||||
return rdev->desc->volt_table[0];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage);
|
||||
|
||||
struct regulator_ops mc13xxx_fixed_regulator_ops = {
|
||||
.enable = mc13xxx_regulator_enable,
|
||||
.disable = mc13xxx_regulator_disable,
|
||||
.is_enabled = mc13xxx_regulator_is_enabled,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.set_voltage = mc13xxx_fixed_regulator_set_voltage,
|
||||
.get_voltage = mc13xxx_fixed_regulator_get_voltage,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops);
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ struct mc13xxx_regulator_priv {
|
|||
|
||||
extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector);
|
||||
extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
extern int mc13xxx_get_num_regulators_dt(struct platform_device *pdev);
|
||||
|
|
|
@ -92,16 +92,18 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
|
|||
EXPORT_SYMBOL_GPL(of_get_regulator_init_data);
|
||||
|
||||
/**
|
||||
* of_regulator_match - extract regulator init data when node
|
||||
* property "regulator-compatible" matches with the regulator name.
|
||||
* of_regulator_match - extract multiple regulator init data from device tree.
|
||||
* @dev: device requesting the data
|
||||
* @node: parent device node of the regulators
|
||||
* @matches: match table for the regulators
|
||||
* @num_matches: number of entries in match table
|
||||
*
|
||||
* This function uses a match table specified by the regulator driver and
|
||||
* looks up the corresponding init data in the device tree if
|
||||
* regulator-compatible matches. Note that the match table is modified
|
||||
* This function uses a match table specified by the regulator driver to
|
||||
* parse regulator init data from the device tree. @node is expected to
|
||||
* contain a set of child nodes, each providing the init data for one
|
||||
* regulator. The data parsed from a child node will be matched to a regulator
|
||||
* based on either the deprecated property regulator-compatible if present,
|
||||
* or otherwise the child node's name. Note that the match table is modified
|
||||
* in place.
|
||||
*
|
||||
* Returns the number of matches found or a negative error code on failure.
|
||||
|
@ -112,26 +114,23 @@ int of_regulator_match(struct device *dev, struct device_node *node,
|
|||
{
|
||||
unsigned int count = 0;
|
||||
unsigned int i;
|
||||
const char *regulator_comp;
|
||||
const char *name;
|
||||
struct device_node *child;
|
||||
|
||||
if (!dev || !node)
|
||||
return -EINVAL;
|
||||
|
||||
for_each_child_of_node(node, child) {
|
||||
regulator_comp = of_get_property(child,
|
||||
name = of_get_property(child,
|
||||
"regulator-compatible", NULL);
|
||||
if (!regulator_comp) {
|
||||
dev_err(dev, "regulator-compatible is missing for node %s\n",
|
||||
child->name);
|
||||
continue;
|
||||
}
|
||||
if (!name)
|
||||
name = child->name;
|
||||
for (i = 0; i < num_matches; i++) {
|
||||
struct of_regulator_match *match = &matches[i];
|
||||
if (match->of_node)
|
||||
continue;
|
||||
|
||||
if (strcmp(match->name, regulator_comp))
|
||||
if (strcmp(match->name, name))
|
||||
continue;
|
||||
|
||||
match->init_data =
|
||||
|
|
|
@ -443,44 +443,6 @@ static int palmas_list_voltage_ldo(struct regulator_dev *dev,
|
|||
return 850000 + (selector * 50000);
|
||||
}
|
||||
|
||||
static int palmas_get_voltage_ldo_sel(struct regulator_dev *dev)
|
||||
{
|
||||
struct palmas_pmic *pmic = rdev_get_drvdata(dev);
|
||||
int id = rdev_get_id(dev);
|
||||
int selector;
|
||||
unsigned int reg;
|
||||
unsigned int addr;
|
||||
|
||||
addr = palmas_regs_info[id].vsel_addr;
|
||||
|
||||
palmas_ldo_read(pmic->palmas, addr, ®);
|
||||
|
||||
selector = reg & PALMAS_LDO1_VOLTAGE_VSEL_MASK;
|
||||
|
||||
/* Adjust selector to match list_voltage ranges */
|
||||
if (selector > 49)
|
||||
selector = 49;
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
static int palmas_set_voltage_ldo_sel(struct regulator_dev *dev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct palmas_pmic *pmic = rdev_get_drvdata(dev);
|
||||
int id = rdev_get_id(dev);
|
||||
unsigned int reg = 0;
|
||||
unsigned int addr;
|
||||
|
||||
addr = palmas_regs_info[id].vsel_addr;
|
||||
|
||||
reg = selector;
|
||||
|
||||
palmas_ldo_write(pmic->palmas, addr, reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int palmas_map_voltage_ldo(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
|
@ -505,8 +467,8 @@ static struct regulator_ops palmas_ops_ldo = {
|
|||
.is_enabled = palmas_is_enabled_ldo,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = palmas_get_voltage_ldo_sel,
|
||||
.set_voltage_sel = palmas_set_voltage_ldo_sel,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.list_voltage = palmas_list_voltage_ldo,
|
||||
.map_voltage = palmas_map_voltage_ldo,
|
||||
};
|
||||
|
@ -757,6 +719,9 @@ static __devinit int palmas_probe(struct platform_device *pdev)
|
|||
|
||||
pmic->desc[id].type = REGULATOR_VOLTAGE;
|
||||
pmic->desc[id].owner = THIS_MODULE;
|
||||
pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
|
||||
palmas_regs_info[id].vsel_addr);
|
||||
pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK;
|
||||
pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
|
||||
palmas_regs_info[id].ctrl_addr);
|
||||
pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <linux/mfd/samsung/s2mps11.h>
|
||||
|
||||
struct s2mps11_info {
|
||||
struct regulator_dev **rdev;
|
||||
struct regulator_dev *rdev[S2MPS11_REGULATOR_MAX];
|
||||
|
||||
int ramp_delay2;
|
||||
int ramp_delay34;
|
||||
|
@ -236,9 +236,8 @@ static __devinit int s2mps11_pmic_probe(struct platform_device *pdev)
|
|||
struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev **rdev;
|
||||
struct s2mps11_info *s2mps11;
|
||||
int i, ret, size;
|
||||
int i, ret;
|
||||
unsigned char ramp_enable, ramp_reg = 0;
|
||||
|
||||
if (!pdata) {
|
||||
|
@ -251,13 +250,6 @@ static __devinit int s2mps11_pmic_probe(struct platform_device *pdev)
|
|||
if (!s2mps11)
|
||||
return -ENOMEM;
|
||||
|
||||
size = sizeof(struct regulator_dev *) * S2MPS11_REGULATOR_MAX;
|
||||
s2mps11->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
|
||||
if (!s2mps11->rdev) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rdev = s2mps11->rdev;
|
||||
platform_set_drvdata(pdev, s2mps11);
|
||||
|
||||
s2mps11->ramp_delay2 = pdata->buck2_ramp_delay;
|
||||
|
@ -297,12 +289,12 @@ static __devinit int s2mps11_pmic_probe(struct platform_device *pdev)
|
|||
config.init_data = pdata->regulators[i].initdata;
|
||||
config.driver_data = s2mps11;
|
||||
|
||||
rdev[i] = regulator_register(®ulators[i], &config);
|
||||
if (IS_ERR(rdev[i])) {
|
||||
ret = PTR_ERR(rdev[i]);
|
||||
s2mps11->rdev[i] = regulator_register(®ulators[i], &config);
|
||||
if (IS_ERR(s2mps11->rdev[i])) {
|
||||
ret = PTR_ERR(s2mps11->rdev[i]);
|
||||
dev_err(&pdev->dev, "regulator init failed for %d\n",
|
||||
i);
|
||||
rdev[i] = NULL;
|
||||
s2mps11->rdev[i] = NULL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -310,8 +302,7 @@ static __devinit int s2mps11_pmic_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
err:
|
||||
for (i = 0; i < S2MPS11_REGULATOR_MAX; i++)
|
||||
if (rdev[i])
|
||||
regulator_unregister(rdev[i]);
|
||||
regulator_unregister(s2mps11->rdev[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -319,12 +310,10 @@ err:
|
|||
static int __devexit s2mps11_pmic_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct s2mps11_info *s2mps11 = platform_get_drvdata(pdev);
|
||||
struct regulator_dev **rdev = s2mps11->rdev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < S2MPS11_REGULATOR_MAX; i++)
|
||||
if (rdev[i])
|
||||
regulator_unregister(rdev[i]);
|
||||
regulator_unregister(s2mps11->rdev[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -502,15 +502,13 @@ static int set_current_limit(struct regulator_dev *rdev, int min_uA,
|
|||
if (info->n_ilimsels == 1)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < info->n_ilimsels; i++)
|
||||
for (i = info->n_ilimsels - 1; i >= 0; i--) {
|
||||
if (min_uA <= info->ilimsels[i] &&
|
||||
max_uA >= info->ilimsels[i])
|
||||
break;
|
||||
return write_field(hw, &info->ilimsel, i);
|
||||
}
|
||||
|
||||
if (i >= info->n_ilimsels)
|
||||
return -EINVAL;
|
||||
|
||||
return write_field(hw, &info->ilimsel, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int get_current_limit(struct regulator_dev *rdev)
|
||||
|
|
|
@ -57,9 +57,6 @@
|
|||
struct tps6586x_regulator {
|
||||
struct regulator_desc desc;
|
||||
|
||||
int volt_reg;
|
||||
int volt_shift;
|
||||
int volt_nbits;
|
||||
int enable_bit[2];
|
||||
int enable_reg[2];
|
||||
|
||||
|
@ -81,10 +78,10 @@ static int tps6586x_set_voltage_sel(struct regulator_dev *rdev,
|
|||
int ret, val, rid = rdev_get_id(rdev);
|
||||
uint8_t mask;
|
||||
|
||||
val = selector << ri->volt_shift;
|
||||
mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
|
||||
val = selector << (ffs(rdev->desc->vsel_mask) - 1);
|
||||
mask = rdev->desc->vsel_mask;
|
||||
|
||||
ret = tps6586x_update(parent, ri->volt_reg, val, mask);
|
||||
ret = tps6586x_update(parent, rdev->desc->vsel_reg, val, mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -100,66 +97,17 @@ static int tps6586x_set_voltage_sel(struct regulator_dev *rdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int tps6586x_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
|
||||
struct device *parent = to_tps6586x_dev(rdev);
|
||||
uint8_t val, mask;
|
||||
int ret;
|
||||
|
||||
ret = tps6586x_read(parent, ri->volt_reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
|
||||
val = (val & mask) >> ri->volt_shift;
|
||||
|
||||
if (val >= ri->desc.n_voltages)
|
||||
BUG();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int tps6586x_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
|
||||
struct device *parent = to_tps6586x_dev(rdev);
|
||||
|
||||
return tps6586x_set_bits(parent, ri->enable_reg[0],
|
||||
1 << ri->enable_bit[0]);
|
||||
}
|
||||
|
||||
static int tps6586x_regulator_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
|
||||
struct device *parent = to_tps6586x_dev(rdev);
|
||||
|
||||
return tps6586x_clr_bits(parent, ri->enable_reg[0],
|
||||
1 << ri->enable_bit[0]);
|
||||
}
|
||||
|
||||
static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
|
||||
struct device *parent = to_tps6586x_dev(rdev);
|
||||
uint8_t reg_val;
|
||||
int ret;
|
||||
|
||||
ret = tps6586x_read(parent, ri->enable_reg[0], ®_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return !!(reg_val & (1 << ri->enable_bit[0]));
|
||||
}
|
||||
|
||||
static struct regulator_ops tps6586x_regulator_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.get_voltage_sel = tps6586x_get_voltage_sel,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = tps6586x_set_voltage_sel,
|
||||
|
||||
.is_enabled = tps6586x_regulator_is_enabled,
|
||||
.enable = tps6586x_regulator_enable,
|
||||
.disable = tps6586x_regulator_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops tps6586x_sys_regulator_ops = {
|
||||
};
|
||||
|
||||
static const unsigned int tps6586x_ldo0_voltages[] = {
|
||||
|
@ -202,10 +150,11 @@ static const unsigned int tps6586x_dvm_voltages[] = {
|
|||
.n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \
|
||||
.volt_table = tps6586x_##vdata##_voltages, \
|
||||
.owner = THIS_MODULE, \
|
||||
.enable_reg = TPS6586X_SUPPLY##ereg0, \
|
||||
.enable_mask = 1 << (ebit0), \
|
||||
.vsel_reg = TPS6586X_##vreg, \
|
||||
.vsel_mask = ((1 << (nbits)) - 1) << (shift), \
|
||||
}, \
|
||||
.volt_reg = TPS6586X_##vreg, \
|
||||
.volt_shift = (shift), \
|
||||
.volt_nbits = (nbits), \
|
||||
.enable_reg[0] = TPS6586X_SUPPLY##ereg0, \
|
||||
.enable_bit[0] = (ebit0), \
|
||||
.enable_reg[1] = TPS6586X_SUPPLY##ereg1, \
|
||||
|
@ -230,15 +179,28 @@ static const unsigned int tps6586x_dvm_voltages[] = {
|
|||
TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
|
||||
}
|
||||
|
||||
#define TPS6586X_SYS_REGULATOR() \
|
||||
{ \
|
||||
.desc = { \
|
||||
.supply_name = "sys", \
|
||||
.name = "REG-SYS", \
|
||||
.ops = &tps6586x_sys_regulator_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = TPS6586X_ID_SYS, \
|
||||
.owner = THIS_MODULE, \
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct tps6586x_regulator tps6586x_regulator[] = {
|
||||
TPS6586X_SYS_REGULATOR(),
|
||||
TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0),
|
||||
TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2),
|
||||
TPS6586X_LDO(LDO_5, NULL, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
|
||||
TPS6586X_LDO(LDO_5, "REG-SYS", ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
|
||||
TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
|
||||
TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
|
||||
TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
|
||||
TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
|
||||
TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
|
||||
TPS6586X_LDO(LDO_RTC, "REG-SYS", ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
|
||||
TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
|
||||
TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -624,18 +626,9 @@ static int twlfixed_list_voltage(struct regulator_dev *rdev, unsigned index)
|
|||
return info->min_mV * 1000;
|
||||
}
|
||||
|
||||
static int twlfixed_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
return info->min_mV * 1000;
|
||||
}
|
||||
|
||||
static struct regulator_ops twl4030fixed_ops = {
|
||||
.list_voltage = twlfixed_list_voltage,
|
||||
|
||||
.get_voltage = twlfixed_get_voltage,
|
||||
|
||||
.enable = twl4030reg_enable,
|
||||
.disable = twl4030reg_disable,
|
||||
.is_enabled = twl4030reg_is_enabled,
|
||||
|
@ -648,8 +641,6 @@ static struct regulator_ops twl4030fixed_ops = {
|
|||
static struct regulator_ops twl6030fixed_ops = {
|
||||
.list_voltage = twlfixed_list_voltage,
|
||||
|
||||
.get_voltage = twlfixed_get_voltage,
|
||||
|
||||
.enable = twl6030reg_enable,
|
||||
.disable = twl6030reg_disable,
|
||||
.is_enabled = twl6030reg_is_enabled,
|
||||
|
@ -659,13 +650,6 @@ static struct regulator_ops twl6030fixed_ops = {
|
|||
.get_status = twl6030reg_get_status,
|
||||
};
|
||||
|
||||
static struct regulator_ops twl6030_fixed_resource = {
|
||||
.enable = twl6030reg_enable,
|
||||
.disable = twl6030reg_disable,
|
||||
.is_enabled = twl6030reg_is_enabled,
|
||||
.get_status = twl6030reg_get_status,
|
||||
};
|
||||
|
||||
/*
|
||||
* SMPS status and control
|
||||
*/
|
||||
|
@ -757,37 +741,32 @@ static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index)
|
|||
return voltage;
|
||||
}
|
||||
|
||||
static int
|
||||
twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
||||
unsigned int *selector)
|
||||
static int twl6030smps_map_voltage(struct regulator_dev *rdev, int min_uV,
|
||||
int max_uV)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int vsel = 0;
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int vsel = 0;
|
||||
|
||||
switch (info->flags) {
|
||||
case 0:
|
||||
if (min_uV == 0)
|
||||
vsel = 0;
|
||||
else if ((min_uV >= 600000) && (min_uV <= 1300000)) {
|
||||
int calc_uV;
|
||||
vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
|
||||
vsel++;
|
||||
calc_uV = twl6030smps_list_voltage(rdev, vsel);
|
||||
if (calc_uV > max_uV)
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Values 1..57 for vsel are linear and can be calculated
|
||||
* values 58..62 are non linear.
|
||||
*/
|
||||
else if ((min_uV > 1900000) && (max_uV >= 2100000))
|
||||
else if ((min_uV > 1900000) && (min_uV <= 2100000))
|
||||
vsel = 62;
|
||||
else if ((min_uV > 1800000) && (max_uV >= 1900000))
|
||||
else if ((min_uV > 1800000) && (min_uV <= 1900000))
|
||||
vsel = 61;
|
||||
else if ((min_uV > 1500000) && (max_uV >= 1800000))
|
||||
else if ((min_uV > 1500000) && (min_uV <= 1800000))
|
||||
vsel = 60;
|
||||
else if ((min_uV > 1350000) && (max_uV >= 1500000))
|
||||
else if ((min_uV > 1350000) && (min_uV <= 1500000))
|
||||
vsel = 59;
|
||||
else if ((min_uV > 1300000) && (max_uV >= 1350000))
|
||||
else if ((min_uV > 1300000) && (min_uV <= 1350000))
|
||||
vsel = 58;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
@ -796,25 +775,21 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
if (min_uV == 0)
|
||||
vsel = 0;
|
||||
else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
|
||||
int calc_uV;
|
||||
vsel = DIV_ROUND_UP(min_uV - 700000, 12500);
|
||||
vsel++;
|
||||
calc_uV = twl6030smps_list_voltage(rdev, vsel);
|
||||
if (calc_uV > max_uV)
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Values 1..57 for vsel are linear and can be calculated
|
||||
* values 58..62 are non linear.
|
||||
*/
|
||||
else if ((min_uV > 1900000) && (max_uV >= 2100000))
|
||||
else if ((min_uV > 1900000) && (min_uV <= 2100000))
|
||||
vsel = 62;
|
||||
else if ((min_uV > 1800000) && (max_uV >= 1900000))
|
||||
else if ((min_uV > 1800000) && (min_uV <= 1900000))
|
||||
vsel = 61;
|
||||
else if ((min_uV > 1350000) && (max_uV >= 1800000))
|
||||
else if ((min_uV > 1350000) && (min_uV <= 1800000))
|
||||
vsel = 60;
|
||||
else if ((min_uV > 1350000) && (max_uV >= 1500000))
|
||||
else if ((min_uV > 1350000) && (min_uV <= 1500000))
|
||||
vsel = 59;
|
||||
else if ((min_uV > 1300000) && (max_uV >= 1350000))
|
||||
else if ((min_uV > 1300000) && (min_uV <= 1350000))
|
||||
vsel = 58;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
@ -830,17 +805,23 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
|
||||
if (min_uV == 0) {
|
||||
vsel = 0;
|
||||
} else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
|
||||
} else if ((min_uV >= 2161000) && (min_uV <= 4321000)) {
|
||||
vsel = DIV_ROUND_UP(min_uV - 2161000, 38600);
|
||||
vsel++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*selector = vsel;
|
||||
return vsel;
|
||||
}
|
||||
|
||||
static int twl6030smps_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
|
||||
vsel);
|
||||
selector);
|
||||
}
|
||||
|
||||
static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)
|
||||
|
@ -852,8 +833,9 @@ static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)
|
|||
|
||||
static struct regulator_ops twlsmps_ops = {
|
||||
.list_voltage = twl6030smps_list_voltage,
|
||||
.map_voltage = twl6030smps_map_voltage,
|
||||
|
||||
.set_voltage = twl6030smps_set_voltage,
|
||||
.set_voltage_sel = twl6030smps_set_voltage_sel,
|
||||
.get_voltage_sel = twl6030smps_get_voltage_sel,
|
||||
|
||||
.enable = twl6030reg_enable,
|
||||
|
@ -876,7 +858,7 @@ static struct regulator_ops twlsmps_ops = {
|
|||
0x0, TWL6030, twl6030fixed_ops)
|
||||
|
||||
#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \
|
||||
static struct twlreg_info TWL4030_INFO_##label = { \
|
||||
static const struct twlreg_info TWL4030_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.id = num, \
|
||||
.table_len = ARRAY_SIZE(label##_VSEL_table), \
|
||||
|
@ -894,7 +876,7 @@ static struct twlreg_info TWL4030_INFO_##label = { \
|
|||
}
|
||||
|
||||
#define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \
|
||||
static struct twlreg_info TWL4030_INFO_##label = { \
|
||||
static const struct twlreg_info TWL4030_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.id = num, \
|
||||
.remap = remap_conf, \
|
||||
|
@ -909,7 +891,7 @@ static struct twlreg_info TWL4030_INFO_##label = { \
|
|||
}
|
||||
|
||||
#define TWL6030_ADJUSTABLE_SMPS(label) \
|
||||
static struct twlreg_info TWL6030_INFO_##label = { \
|
||||
static const struct twlreg_info TWL6030_INFO_##label = { \
|
||||
.desc = { \
|
||||
.name = #label, \
|
||||
.id = TWL6030_REG_##label, \
|
||||
|
@ -920,7 +902,7 @@ static struct twlreg_info TWL6030_INFO_##label = { \
|
|||
}
|
||||
|
||||
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \
|
||||
static struct twlreg_info TWL6030_INFO_##label = { \
|
||||
static const struct twlreg_info TWL6030_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.min_mV = min_mVolts, \
|
||||
.max_mV = max_mVolts, \
|
||||
|
@ -935,7 +917,7 @@ static struct twlreg_info TWL6030_INFO_##label = { \
|
|||
}
|
||||
|
||||
#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \
|
||||
static struct twlreg_info TWL6025_INFO_##label = { \
|
||||
static const struct twlreg_info TWL6025_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.min_mV = min_mVolts, \
|
||||
.max_mV = max_mVolts, \
|
||||
|
@ -951,7 +933,7 @@ static struct twlreg_info TWL6025_INFO_##label = { \
|
|||
|
||||
#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \
|
||||
family, operations) \
|
||||
static struct twlreg_info TWLFIXED_INFO_##label = { \
|
||||
static const struct twlreg_info TWLFIXED_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.id = num, \
|
||||
.min_mV = mVolts, \
|
||||
|
@ -981,7 +963,7 @@ static struct twlreg_info TWLRES_INFO_##label = { \
|
|||
}
|
||||
|
||||
#define TWL6025_ADJUSTABLE_SMPS(label, offset) \
|
||||
static struct twlreg_info TWLSMPS_INFO_##label = { \
|
||||
static const struct twlreg_info TWLSMPS_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.min_mV = 600, \
|
||||
.max_mV = 2100, \
|
||||
|
@ -1138,6 +1120,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
{
|
||||
int i, id;
|
||||
struct twlreg_info *info;
|
||||
const struct twlreg_info *template;
|
||||
struct regulator_init_data *initdata;
|
||||
struct regulation_constraints *c;
|
||||
struct regulator_dev *rdev;
|
||||
|
@ -1147,17 +1130,17 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
|
||||
match = of_match_device(twl_of_match, &pdev->dev);
|
||||
if (match) {
|
||||
info = match->data;
|
||||
id = info->desc.id;
|
||||
template = match->data;
|
||||
id = template->desc.id;
|
||||
initdata = of_get_regulator_init_data(&pdev->dev,
|
||||
pdev->dev.of_node);
|
||||
drvdata = NULL;
|
||||
} else {
|
||||
id = pdev->id;
|
||||
initdata = pdev->dev.platform_data;
|
||||
for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
|
||||
info = twl_of_match[i].data;
|
||||
if (info && info->desc.id == id)
|
||||
for (i = 0, template = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
|
||||
template = twl_of_match[i].data;
|
||||
if (template && template->desc.id == id)
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(twl_of_match))
|
||||
|
@ -1168,12 +1151,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!info)
|
||||
if (!template)
|
||||
return -ENODEV;
|
||||
|
||||
if (!initdata)
|
||||
return -EINVAL;
|
||||
|
||||
info = kmemdup(template, sizeof (*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
if (drvdata) {
|
||||
/* copy the driver data into regulator data */
|
||||
info->features = drvdata->features;
|
||||
|
@ -1234,6 +1221,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "can't register %s, %ld\n",
|
||||
info->desc.name, PTR_ERR(rdev));
|
||||
kfree(info);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
platform_set_drvdata(pdev, rdev);
|
||||
|
@ -1255,7 +1243,11 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
|
||||
static int __devexit twlreg_remove(struct platform_device *pdev)
|
||||
{
|
||||
regulator_unregister(platform_get_drvdata(pdev));
|
||||
struct regulator_dev *rdev = platform_get_drvdata(pdev);
|
||||
struct twlreg_info *info = rdev->reg_data;
|
||||
|
||||
regulator_unregister(rdev);
|
||||
kfree(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -339,16 +339,15 @@ static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev,
|
|||
u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wm831x_dcdc_ilim); i++) {
|
||||
for (i = ARRAY_SIZE(wm831x_dcdc_ilim) - 1; i >= 0; i--) {
|
||||
if ((min_uA <= wm831x_dcdc_ilim[i]) &&
|
||||
(wm831x_dcdc_ilim[i] <= max_uA))
|
||||
break;
|
||||
return wm831x_set_bits(wm831x, reg,
|
||||
WM831X_DC1_HC_THR_MASK,
|
||||
i << WM831X_DC1_HC_THR_SHIFT);
|
||||
}
|
||||
if (i == ARRAY_SIZE(wm831x_dcdc_ilim))
|
||||
return -EINVAL;
|
||||
|
||||
return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK,
|
||||
i << WM831X_DC1_HC_THR_SHIFT);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev)
|
||||
|
|
|
@ -205,6 +205,8 @@ static int wm831x_gp_ldo_get_status(struct regulator_dev *rdev)
|
|||
|
||||
/* Is it reporting under voltage? */
|
||||
ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret & mask)
|
||||
return REGULATOR_STATUS_ERROR;
|
||||
|
||||
|
@ -237,6 +239,8 @@ static struct regulator_ops wm831x_gp_ldo_ops = {
|
|||
.set_mode = wm831x_gp_ldo_set_mode,
|
||||
.get_status = wm831x_gp_ldo_get_status,
|
||||
.get_optimum_mode = wm831x_gp_ldo_get_optimum_mode,
|
||||
.get_bypass = regulator_get_bypass_regmap,
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
|
@ -293,6 +297,8 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
|
|||
ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK;
|
||||
ldo->desc.enable_reg = WM831X_LDO_ENABLE;
|
||||
ldo->desc.enable_mask = 1 << id;
|
||||
ldo->desc.bypass_reg = ldo->base;
|
||||
ldo->desc.bypass_mask = WM831X_LDO1_SWI;
|
||||
|
||||
config.dev = pdev->dev.parent;
|
||||
if (pdata)
|
||||
|
@ -469,6 +475,8 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev)
|
|||
|
||||
/* Is it reporting under voltage? */
|
||||
ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret & mask)
|
||||
return REGULATOR_STATUS_ERROR;
|
||||
|
||||
|
@ -488,6 +496,8 @@ static struct regulator_ops wm831x_aldo_ops = {
|
|||
.get_mode = wm831x_aldo_get_mode,
|
||||
.set_mode = wm831x_aldo_set_mode,
|
||||
.get_status = wm831x_aldo_get_status,
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
.get_bypass = regulator_get_bypass_regmap,
|
||||
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
|
@ -544,6 +554,8 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
|
|||
ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK;
|
||||
ldo->desc.enable_reg = WM831X_LDO_ENABLE;
|
||||
ldo->desc.enable_mask = 1 << id;
|
||||
ldo->desc.bypass_reg = ldo->base;
|
||||
ldo->desc.bypass_mask = WM831X_LDO7_SWI;
|
||||
|
||||
config.dev = pdev->dev.parent;
|
||||
if (pdata)
|
||||
|
|
|
@ -120,13 +120,8 @@ static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
|
|||
|
||||
case REGULATOR_MODE_IDLE:
|
||||
/* Datasheet: standby */
|
||||
ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
|
||||
WM8400_DC1_ACTIVE, 0);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
|
||||
WM8400_DC1_SLEEP, 0);
|
||||
|
||||
WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, 0);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ enum max77686_regulators {
|
|||
struct max77686_regulator_data {
|
||||
int id;
|
||||
struct regulator_init_data *initdata;
|
||||
struct device_node *of_node;
|
||||
};
|
||||
|
||||
enum max77686_opmode {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define TPS6586X_SLEW_RATE_MASK 0x07
|
||||
|
||||
enum {
|
||||
TPS6586X_ID_SYS,
|
||||
TPS6586X_ID_SM_0,
|
||||
TPS6586X_ID_SM_1,
|
||||
TPS6586X_ID_SM_2,
|
||||
|
|
|
@ -177,6 +177,8 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode);
|
|||
unsigned int regulator_get_mode(struct regulator *regulator);
|
||||
int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
|
||||
|
||||
int regulator_allow_bypass(struct regulator *regulator, bool allow);
|
||||
|
||||
/* regulator notifier block */
|
||||
int regulator_register_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb);
|
||||
|
@ -328,6 +330,12 @@ static inline int regulator_set_optimum_mode(struct regulator *regulator,
|
|||
return REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static inline int regulator_allow_bypass(struct regulator *regulator,
|
||||
bool allow)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_register_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
|
@ -352,4 +360,11 @@ static inline void regulator_set_drvdata(struct regulator *regulator,
|
|||
|
||||
#endif
|
||||
|
||||
static inline int regulator_set_voltage_tol(struct regulator *regulator,
|
||||
int new_uV, int tol_uV)
|
||||
{
|
||||
return regulator_set_voltage(regulator,
|
||||
new_uV - tol_uV, new_uV + tol_uV);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,8 @@ enum regulator_status {
|
|||
REGULATOR_STATUS_NORMAL,
|
||||
REGULATOR_STATUS_IDLE,
|
||||
REGULATOR_STATUS_STANDBY,
|
||||
/* The regulator is enabled but not regulating */
|
||||
REGULATOR_STATUS_BYPASS,
|
||||
/* in case that any other status doesn't apply */
|
||||
REGULATOR_STATUS_UNDEFINED,
|
||||
};
|
||||
|
@ -58,6 +60,7 @@ enum regulator_status {
|
|||
* regulator_desc.n_voltages. Voltages may be reported in any order.
|
||||
*
|
||||
* @set_current_limit: Configure a limit for a current-limited regulator.
|
||||
* The driver should select the current closest to max_uA.
|
||||
* @get_current_limit: Get the configured limit for a current-limited regulator.
|
||||
*
|
||||
* @set_mode: Set the configured operating mode for the regulator.
|
||||
|
@ -67,6 +70,9 @@ enum regulator_status {
|
|||
* @get_optimum_mode: Get the most efficient operating mode for the regulator
|
||||
* when running with the specified parameters.
|
||||
*
|
||||
* @set_bypass: Set the regulator in bypass mode.
|
||||
* @get_bypass: Get the regulator bypass mode state.
|
||||
*
|
||||
* @enable_time: Time taken for the regulator voltage output voltage to
|
||||
* stabilise after being enabled, in microseconds.
|
||||
* @set_ramp_delay: Set the ramp delay for the regulator. The driver should
|
||||
|
@ -133,6 +139,10 @@ struct regulator_ops {
|
|||
unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV,
|
||||
int output_uV, int load_uA);
|
||||
|
||||
/* control and report on bypass mode */
|
||||
int (*set_bypass)(struct regulator_dev *dev, bool enable);
|
||||
int (*get_bypass)(struct regulator_dev *dev, bool *enable);
|
||||
|
||||
/* the operations below are for configuration of regulator state when
|
||||
* its parent PMIC enters a global STANDBY/HIBERNATE state */
|
||||
|
||||
|
@ -205,6 +215,8 @@ struct regulator_desc {
|
|||
unsigned int vsel_mask;
|
||||
unsigned int enable_reg;
|
||||
unsigned int enable_mask;
|
||||
unsigned int bypass_reg;
|
||||
unsigned int bypass_mask;
|
||||
|
||||
unsigned int enable_time;
|
||||
};
|
||||
|
@ -221,7 +233,8 @@ struct regulator_desc {
|
|||
* @driver_data: private regulator data
|
||||
* @of_node: OpenFirmware node to parse for device tree bindings (may be
|
||||
* NULL).
|
||||
* @regmap: regmap to use for core regmap helpers
|
||||
* @regmap: regmap to use for core regmap helpers if dev_get_regulator() is
|
||||
* insufficient.
|
||||
* @ena_gpio: GPIO controlling regulator enable.
|
||||
* @ena_gpio_invert: Sense for GPIO enable control.
|
||||
* @ena_gpio_flags: Flags to use when calling gpio_request_one()
|
||||
|
@ -253,6 +266,7 @@ struct regulator_dev {
|
|||
int exclusive;
|
||||
u32 use_count;
|
||||
u32 open_count;
|
||||
u32 bypass_count;
|
||||
|
||||
/* lists we belong to */
|
||||
struct list_head list; /* list of all regulators */
|
||||
|
@ -310,6 +324,8 @@ int regulator_disable_regmap(struct regulator_dev *rdev);
|
|||
int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
unsigned int old_selector,
|
||||
unsigned int new_selector);
|
||||
int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable);
|
||||
int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable);
|
||||
|
||||
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* fan53555.h - Fairchild Regulator FAN53555 Driver
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FAN53555_H__
|
||||
|
||||
/* VSEL ID */
|
||||
enum {
|
||||
FAN53555_VSEL_ID_0 = 0,
|
||||
FAN53555_VSEL_ID_1,
|
||||
};
|
||||
|
||||
/* Transition slew rate limiting from a low to high voltage.
|
||||
* -----------------------
|
||||
* Bin |Slew Rate(mV/uS)
|
||||
* ------|----------------
|
||||
* 000 | 64.00
|
||||
* ------|----------------
|
||||
* 001 | 32.00
|
||||
* ------|----------------
|
||||
* 010 | 16.00
|
||||
* ------|----------------
|
||||
* 011 | 8.00
|
||||
* ------|----------------
|
||||
* 100 | 4.00
|
||||
* ------|----------------
|
||||
* 101 | 2.00
|
||||
* ------|----------------
|
||||
* 110 | 1.00
|
||||
* ------|----------------
|
||||
* 111 | 0.50
|
||||
* -----------------------
|
||||
*/
|
||||
enum {
|
||||
FAN53555_SLEW_RATE_64MV = 0,
|
||||
FAN53555_SLEW_RATE_32MV,
|
||||
FAN53555_SLEW_RATE_16MV,
|
||||
FAN53555_SLEW_RATE_8MV,
|
||||
FAN53555_SLEW_RATE_4MV,
|
||||
FAN53555_SLEW_RATE_2MV,
|
||||
FAN53555_SLEW_RATE_1MV,
|
||||
FAN53555_SLEW_RATE_0_5MV,
|
||||
};
|
||||
|
||||
struct fan53555_platform_data {
|
||||
struct regulator_init_data *regulator;
|
||||
unsigned int slew_rate;
|
||||
/* Sleep VSEL ID */
|
||||
unsigned int sleep_vsel_id;
|
||||
};
|
||||
|
||||
#endif /* __FAN53555_H__ */
|
|
@ -32,6 +32,7 @@ struct regulator;
|
|||
* board/machine.
|
||||
* STATUS: Regulator can be enabled and disabled.
|
||||
* DRMS: Dynamic Regulator Mode Switching is enabled for this regulator.
|
||||
* BYPASS: Regulator can be put into bypass mode
|
||||
*/
|
||||
|
||||
#define REGULATOR_CHANGE_VOLTAGE 0x1
|
||||
|
@ -39,6 +40,7 @@ struct regulator;
|
|||
#define REGULATOR_CHANGE_MODE 0x4
|
||||
#define REGULATOR_CHANGE_STATUS 0x8
|
||||
#define REGULATOR_CHANGE_DRMS 0x10
|
||||
#define REGULATOR_CHANGE_BYPASS 0x20
|
||||
|
||||
/**
|
||||
* struct regulator_state - regulator state during low power system states
|
||||
|
|
Загрузка…
Ссылка в новой задаче