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

Pull regulator updates from Mark Brown:
 - Support for putting regulators into bypass mode where they simply
   switch their input to the output (mainly used for low power
   retention).
 - A new API for setting voltages based on a voltage plus tolerance
   rather than an explicit voltage range.
 - Lots of cleanups and API updates from Axel Lin.
 - New driver for MAX8907.

* tag 'regulator-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (71 commits)
  regulator: arizona-ldo: Remove top voltage
  regulator: tps6586x: remove regulator-compatible from DT docs
  regulator: tps65217.txt: remove regulator-compatible from DT docs
  regulator: deprecate regulator-compatible DT property
  regulator: fan53555: remove vsel_max not used
  regulator: aat2870: Don't explicitly initialise the first field
  extcon: arizona: Use bypass mode for MICVDD
  regulator: wm831x-ldo: Add bypass support
  regulator: arizona-micsupp: Support get/set bypass
  regulator: arizona-ldo: Support get/set bypass
  regulator: core: Provide regmap get/set bypass operations
  regulator: core: Support bypass mode
  regulator: Fairchild fan53555 support
  regulator: twl: Remove another unused variable warning
  regulator: core: Try using the parent device for the default regmap
  regulator: core: Fast path non-deferred disables
  regulator: core: Report microvolts in sysfs even with only list_voltage()
  regulator: tps6586x: add support for SYS rail
  regulator: lp872x: remove unnecessary function
  regulator: lp872x: fix NULL pointer access problem
  ...
This commit is contained in:
Linus Torvalds
2012-10-01 08:58:47 -07:00
43 changed files with 1417 additions and 563 deletions
@@ -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>;
};
+10 -2
View File
@@ -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()) {
+5
View File
@@ -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;
+13
View File
@@ -25,6 +25,7 @@
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tps6586x.h>
@@ -346,6 +347,7 @@ failed:
#ifdef CONFIG_OF
static struct of_regulator_match tps6586x_matches[] = {
{ .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS },
{ .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 },
{ .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 },
{ .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 },
@@ -369,6 +371,7 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
struct tps6586x_platform_data *pdata;
struct tps6586x_subdev_info *devs;
struct device_node *regs;
const char *sys_rail_name = NULL;
unsigned int count;
unsigned int i, j;
int err;
@@ -391,12 +394,22 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
return NULL;
for (i = 0, j = 0; i < num && j < count; i++) {
struct regulator_init_data *reg_idata;
if (!tps6586x_matches[i].init_data)
continue;
reg_idata = tps6586x_matches[i].init_data;
devs[j].name = "tps6586x-regulator";
devs[j].platform_data = tps6586x_matches[i].init_data;
devs[j].id = (int)tps6586x_matches[i].driver_data;
if (devs[j].id == TPS6586X_ID_SYS)
sys_rail_name = reg_idata->constraints.name;
if ((devs[j].id == TPS6586X_ID_LDO_5) ||
(devs[j].id == TPS6586X_ID_LDO_RTC))
reg_idata->supply_regulator = sys_rail_name;
devs[j].of_node = tps6586x_matches[i].of_node;
j++;
}
+28 -10
View File
@@ -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"
+2
View File
@@ -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
+1 -1
View File
@@ -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);
-6
View File
@@ -347,17 +347,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
return abreg->plfdata->external_voltage;
}
static int ab3100_get_fixed_voltage_regulator(struct regulator_dev *reg)
{
return reg->desc->min_uV;
}
static struct regulator_ops regulator_ops_fixed = {
.list_voltage = regulator_list_voltage_linear,
.enable = ab3100_enable_regulator,
.disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator,
.get_voltage = ab3100_get_fixed_voltage_regulator,
};
static struct regulator_ops regulator_ops_variable = {
+11 -25
View File
@@ -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,
+5 -1
View File
@@ -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,
};
+5
View File
@@ -82,6 +82,9 @@ static struct regulator_ops arizona_micsupp_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_bypass = regulator_get_bypass_regmap,
.set_bypass = regulator_set_bypass_regmap,
};
static const struct regulator_desc arizona_micsupp = {
@@ -95,6 +98,8 @@ static const struct regulator_desc arizona_micsupp = {
.vsel_mask = ARIZONA_LDO2_VSEL_MASK,
.enable_reg = ARIZONA_MIC_CHARGE_PUMP_1,
.enable_mask = ARIZONA_CPMIC_ENA,
.bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
.bypass_mask = ARIZONA_CPMIC_BYPASS,
.owner = THIS_MODULE,
};
+147 -6
View File
@@ -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);
+2 -2
View File
@@ -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;
}
+1 -1
View File
@@ -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,
+322
View File
@@ -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");
-6
View File
@@ -73,13 +73,7 @@ static struct regulator_ops isl_core_ops = {
.map_voltage = regulator_map_voltage_linear,
};
static int isl6271a_get_fixed_voltage(struct regulator_dev *dev)
{
return dev->desc->min_uV;
}
static struct regulator_ops isl_fixed_ops = {
.get_voltage = isl6271a_get_fixed_voltage,
.list_voltage = regulator_list_voltage_linear,
};
+35 -53
View File
@@ -86,6 +86,10 @@
#define EXTERN_DVS_USED 0
#define MAX_DELAY 6
/* Default DVS Mode */
#define LP8720_DEFAULT_DVS 0
#define LP8725_DEFAULT_DVS BIT(2)
/* dump registers in regmap-debugfs */
#define MAX_REGISTERS 0x0F
@@ -269,9 +273,9 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev)
return val > MAX_DELAY ? 0 : val * time_step_us;
}
static void lp872x_set_dvs(struct lp872x *lp, int gpio)
static void lp872x_set_dvs(struct lp872x *lp, enum lp872x_dvs_sel dvs_sel,
int gpio)
{
enum lp872x_dvs_sel dvs_sel = lp->pdata->dvs->vsel;
enum lp872x_dvs_state state;
state = dvs_sel == SEL_V1 ? DVS_HIGH : DVS_LOW;
@@ -339,10 +343,10 @@ static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev,
struct lp872x *lp = rdev_get_drvdata(rdev);
enum lp872x_regulator_id buck = rdev_get_id(rdev);
u8 addr, mask = LP872X_VOUT_M;
struct lp872x_dvs *dvs = lp->pdata->dvs;
struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL;
if (dvs && gpio_is_valid(dvs->gpio))
lp872x_set_dvs(lp, dvs->gpio);
lp872x_set_dvs(lp, dvs->vsel, dvs->gpio);
addr = lp872x_select_buck_vout_addr(lp, buck);
if (!lp872x_is_valid_buck_addr(addr))
@@ -374,8 +378,8 @@ static int lp8725_buck_set_current_limit(struct regulator_dev *rdev,
{
struct lp872x *lp = rdev_get_drvdata(rdev);
enum lp872x_regulator_id buck = rdev_get_id(rdev);
int i, max = ARRAY_SIZE(lp8725_buck_uA);
u8 addr, val;
int i;
u8 addr;
switch (buck) {
case LP8725_ID_BUCK1:
@@ -388,17 +392,15 @@ static int lp8725_buck_set_current_limit(struct regulator_dev *rdev,
return -EINVAL;
}
for (i = 0 ; i < max ; i++)
for (i = ARRAY_SIZE(lp8725_buck_uA) - 1 ; i >= 0; i--) {
if (lp8725_buck_uA[i] >= min_uA &&
lp8725_buck_uA[i] <= max_uA)
break;
return lp872x_update_bits(lp, addr,
LP8725_BUCK_CL_M,
i << LP8725_BUCK_CL_S);
}
if (i == max)
return -EINVAL;
val = i << LP8725_BUCK_CL_S;
return lp872x_update_bits(lp, addr, LP8725_BUCK_CL_M, val);
return -EINVAL;
}
static int lp8725_buck_get_current_limit(struct regulator_dev *rdev)
@@ -727,39 +729,16 @@ static struct regulator_desc lp8725_regulator_desc[] = {
},
};
static int lp872x_check_dvs_validity(struct lp872x *lp)
{
struct lp872x_dvs *dvs = lp->pdata->dvs;
u8 val = 0;
int ret;
ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val);
if (ret)
return ret;
ret = 0;
if (lp->chipid == LP8720) {
if (val & LP8720_EXT_DVS_M)
ret = dvs ? 0 : -EINVAL;
} else {
if ((val & LP8725_DVS1_M) == EXTERN_DVS_USED)
ret = dvs ? 0 : -EINVAL;
}
return ret;
}
static int lp872x_init_dvs(struct lp872x *lp)
{
int ret, gpio;
struct lp872x_dvs *dvs = lp->pdata->dvs;
struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL;
enum lp872x_dvs_state pinstate;
u8 mask[] = { LP8720_EXT_DVS_M, LP8725_DVS1_M | LP8725_DVS2_M };
u8 default_dvs_mode[] = { LP8720_DEFAULT_DVS, LP8725_DEFAULT_DVS };
ret = lp872x_check_dvs_validity(lp);
if (ret) {
dev_warn(lp->dev, "invalid dvs data: %d\n", ret);
return ret;
}
if (!dvs)
goto set_default_dvs_mode;
gpio = dvs->gpio;
if (!gpio_is_valid(gpio)) {
@@ -778,6 +757,10 @@ static int lp872x_init_dvs(struct lp872x *lp)
lp->dvs_gpio = gpio;
return 0;
set_default_dvs_mode:
return lp872x_update_bits(lp, LP872X_GENERAL_CFG, mask[lp->chipid],
default_dvs_mode[lp->chipid]);
}
static int lp872x_config(struct lp872x *lp)
@@ -785,24 +768,29 @@ static int lp872x_config(struct lp872x *lp)
struct lp872x_platform_data *pdata = lp->pdata;
int ret;
if (!pdata->update_config)
return 0;
if (!pdata || !pdata->update_config)
goto init_dvs;
ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config);
if (ret)
return ret;
init_dvs:
return lp872x_init_dvs(lp);
}
static struct regulator_init_data
*lp872x_find_regulator_init_data(int id, struct lp872x *lp)
{
struct lp872x_platform_data *pdata = lp->pdata;
int i;
if (!pdata)
return NULL;
for (i = 0; i < lp->num_regulators; i++) {
if (lp->pdata->regulator_data[i].id == id)
return lp->pdata->regulator_data[i].init_data;
if (pdata->regulator_data[i].id == id)
return pdata->regulator_data[i].init_data;
}
return NULL;
@@ -863,18 +851,12 @@ static const struct regmap_config lp872x_regmap_config = {
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct lp872x *lp;
struct lp872x_platform_data *pdata = cl->dev.platform_data;
int ret, size, num_regulators;
const int lp872x_num_regulators[] = {
[LP8720] = LP8720_NUM_REGULATORS,
[LP8725] = LP8725_NUM_REGULATORS,
};
if (!pdata) {
dev_err(&cl->dev, "no platform data\n");
return -EINVAL;
}
lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
if (!lp)
goto err_mem;
@@ -894,7 +876,7 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
}
lp->dev = &cl->dev;
lp->pdata = pdata;
lp->pdata = cl->dev.platform_data;
lp->chipid = id->driver_data;
lp->num_regulators = num_regulators;
i2c_set_clientdata(cl, lp);

Some files were not shown because too many files have changed in this diff Show More