提交 76f7a102 编写于 作者: L Linus Torvalds

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

Pull regulator updates from Mark Brown:
 "Very quiet release here, as well as the usual driver specific updates
  only a couple of new things:

   - New drivers for TI ABB LDOs and MAX77693 PMICs
   - Support for enabling bypass mode support via device tree"

* tag 'regulator-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (23 commits)
  regulator: max77693: Remove NULL test for rmatch[i].init_data
  regulator: max77693: Fix trivial typo
  regulator: ab8500-ext: Staticize local symbols
  regulator: max77693: Add max77693 regualtor driver.
  regulator: max8973: fix a typo in documentation
  regulator: max8973: initial DT support
  regulators: max8973: fix multiple instance support
  regulator: of: Added a property to indicate bypass mode support
  regulator: ti-abb: Convert to use devm_ioremap_resource
  regulator: tps62360: Fix crash in i2c_driver .probe
  regulator: ab8500: Provide supply names for the AUX regulators
  regulator: ab8500-ext: Enable for Device Tree
  regulator: ab8500-ext: Register as a device in its own right
  regulator: ab8500-ext: Provide a set_voltage call-back operation
  regulator: ab8500: Ensure AB8500 external registers are probed first
  regulator: core: add regulator_get_linear_step()
  regulator: lp397x: use devm_kzalloc() to make cleanup paths simpler
  regulator: lp872x: support the device tree feature
  regulator: Remove unnecessary include of linux/delay.h from regulator drivers
  regulator: isl6271a: Use NULL instead of 0
  ...
Maxim MAX77693 multi-function device
MAX77693 is a Multifunction device with the following submodules:
- PMIC,
- CHARGER,
- LED,
- MUIC,
- HAPTIC
It is interfaced to host controller using i2c.
This document describes the bindings for the mfd device.
Required properties:
- compatible : Must be "maxim,max77693".
- reg : Specifies the i2c slave address of PMIC block.
- interrupts : This i2c device has an IRQ line connected to the main SoC.
- interrupt-parent : The parent interrupt controller.
Optional properties:
- regulators : The regulators of max77693 have to be instantiated under subnod
named "regulators" using the following format.
regulators {
regualtor-compatible = ESAFEOUT1/ESAFEOUT2/CHARGER
standard regulator constratints[*].
};
[*] refer Documentation/devicetree/bindings/regulator/regulator.txt
Example:
max77693@66 {
compatible = "maxim,max77693";
reg = <0x66>;
interrupt-parent = <&gpx1>;
interrupts = <5 2>;
regulators {
esafeout@1 {
regulator-compatible = "ESAFEOUT1";
regulator-name = "ESAFEOUT1";
regulator-boot-on;
};
esafeout@2 {
regulator-compatible = "ESAFEOUT2";
regulator-name = "ESAFEOUT2";
};
charger@0 {
regulator-compatible = "CHARGER";
regulator-name = "CHARGER";
regulator-min-microamp = <60000>;
regulator-max-microamp = <2580000>;
regulator-boot-on;
};
};
};
Binding for TI/National Semiconductor LP872x Driver
Required properties:
- compatible: "ti,lp8720" or "ti,lp8725"
- reg: I2C slave address. 0x7d = LP8720, 0x7a = LP8725
Optional properties:
- ti,general-config: the value of LP872X_GENERAL_CFG register (u8)
(LP8720)
bit[2]: BUCK output voltage control by external DVS pin or register
1 = external pin, 0 = bit7 of register 08h
bit[1]: sleep control by external DVS pin or register
1 = external pin, 0 = bit6 of register 08h
bit[0]: time step unit(usec). 1 = 25, 0 = 50
(LP8725)
bit[7:6]: time step unit(usec). 00 = 32, 01 = 64, 10 = 128, 11 = 256
bit[4]: BUCK2 enable control. 1 = enable, 0 = disable
bit[3]: BUCK2 output voltage register address. 1 = 0Ah, 0 = 0Bh
bit[2]: BUCK1 output voltage control by external DVS pin or register
1 = register 08h, 0 = DVS
bit[1]: LDO sleep control. 1 = sleep mode, 0 = normal
bit[0]: BUCK1 enable control, 1 = enable, 0 = disable
For more details, please see the datasheet.
- ti,update-config: define it when LP872X_GENERAL_CFG register should be set
- ti,dvs-gpio: GPIO specifier for external DVS pin control of LP872x devices.
- ti,dvs-vsel: DVS selector. 0 = SEL_V1, 1 = SEL_V2.
- ti,dvs-state: initial DVS pin state. 0 = DVS_LOW, 1 = DVS_HIGH.
Sub nodes for regulator_init_data
LP8720 has maximum 6 nodes. (child name: ldo1 ~ 5 and buck)
LP8725 has maximum 9 nodes. (child name: ldo1 ~ 5, lilo1,2 and buck1,2)
For more details, please see the following binding document.
(Documentation/devicetree/bindings/regulator/regulator.txt)
Datasheet
- LP8720: http://www.ti.com/lit/ds/symlink/lp8720.pdf
- LP8725: http://www.ti.com/lit/ds/symlink/lp8725.pdf
Example 1) LP8720
lp8720@7d {
compatible = "ti,lp8720";
reg = <0x7d>;
/* external DVS pin used, timestep is 25usec */
ti,general-config = /bits/ 8 <0x03>;
ti,update-config;
/*
* The dvs-gpio depends on the processor environment.
* For example, following GPIO specifier means GPIO134 in OMAP4.
*/
ti,dvs-gpio = <&gpio5 6 0>;
ti,dvs-vsel = /bits/ 8 <1>; /* SEL_V2 */
ti,dvs-state = /bits/ 8 <1>; /* DVS_HIGH */
vaf: ldo1 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
};
vmmc: ldo2 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
};
vcam_io: ldo3 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
vcam_core: ldo4 {
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <2850000>;
regulator-boot-on;
};
vcam: ldo5 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
};
vcc: buck {
regulator-name = "VBUCK";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <2300000>;
};
};
Example 2) LP8725
lp8725@7a {
compatible = "ti,lp8725";
reg = <0x7a>;
/* Enable BUCK1,2, no DVS, normal LDO mode, timestep is 256usec */
ti,general-config = /bits/ 8 <0xdd>;
ti,update-config;
vcam_io: ldo1 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
};
vcam_core: ldo2 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
};
vcam: ldo3 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
};
vcmmb_io: ldo4 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
vcmmb_core: ldo5 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
vaux1: lilo1 {
regulator-name = "VAUX1";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3300000>;
};
vaux2: lilo2 {
regulator-name = "VAUX2";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3300000>;
};
vcc1: buck1 {
regulator-name = "VBUCK1";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3000000>;
regulator-min-microamp = <460000>;
regulator-max-microamp = <1370000>;
regulator-boot-on;
};
vcc2: buck2 {
regulator-name = "VBUCK2";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3000000>;
regulator-min-microamp = <460000>;
regulator-max-microamp = <1370000>;
regulator-boot-on;
};
};
* Maxim MAX8973 Voltage Regulator
Required properties:
- compatible: must be "maxim,max8973"
- reg: the i2c slave address of the regulator. It should be 0x1b.
Any standard regulator properties can be used to configure the single max8973
DCDC.
Example:
max8973@1b {
compatible = "maxim,max8973";
reg = <0x1b>;
regulator-min-microvolt = <935000>;
regulator-max-microvolt = <1200000>;
regulator-boot-on;
regulator-always-on;
};
......@@ -9,6 +9,7 @@ Optional properties:
- regulator-max-microamp: largest current consumers may set
- regulator-always-on: boolean, regulator should never be disabled
- regulator-boot-on: bootloader/firmware enabled regulator
- regulator-allow-bypass: allow the regulator to go into bypass mode
- <name>-supply: phandle to the parent supply/regulator node
- regulator-ramp-delay: ramp delay for regulator(in uV/uS)
......
Adaptive Body Bias(ABB) SoC internal LDO regulator for Texas Instruments SoCs
Required Properties:
- compatible: Should be one of:
- "ti,abb-v1" for older SoCs like OMAP3
- "ti,abb-v2" for newer SoCs like OMAP4, OMAP5
- reg: Address and length of the register set for the device. It contains
the information of registers in the same order as described by reg-names
- reg-names: Should contain the reg names
- "base-address" - contains base address of ABB module
- "int-address" - contains address of interrupt register for ABB module
(also see Optional properties)
- #address-cell: should be 0
- #size-cell: should be 0
- clocks: should point to the clock node used by ABB module
- ti,settling-time: Settling time in uSecs from SoC documentation for ABB module
to settle down(target time for SR2_WTCNT_VALUE).
- ti,clock-cycles: SoC specific data about count of system ti,clock-cycles used for
computing settling time from SoC Documentation for ABB module(clock
cycles for SR2_WTCNT_VALUE).
- ti,tranxdone-status-mask: Mask to the int-register to write-to-clear mask
indicating LDO tranxdone (operation complete).
- ti,abb_info: An array of 6-tuples u32 items providing information about ABB
configuration needed per operational voltage of the device.
Each item consists of the following in the same order:
volt: voltage in uV - Only used to index ABB information.
ABB mode: one of the following:
0-bypass
1-Forward Body Bias(FBB)
3-Reverse Body Bias(RBB)
efuse: (see Optional properties)
RBB enable efuse Mask: (See Optional properties)
FBB enable efuse Mask: (See Optional properties)
Vset value efuse Mask: (See Optional properties)
NOTE: If more than 1 entry is present, then regulator is setup to change
voltage, allowing for various modes to be selected indexed off
the regulator. Further, ABB LDOs are considered always-on by
default.
Optional Properties:
- reg-names: In addition to the required properties, the following are optional
- "efuse-address" - Contains efuse base address used to pick up ABB info.
- "ldo-address" - Contains address of ABB LDO overide register address.
"efuse-address" is required for this.
- ti,ldovbb-vset-mask - Required if ldo-address is set, mask for LDO override
register to provide override vset value.
- ti,ldovbb-override-mask - Required if ldo-address is set, mask for LDO
override register to enable override vset value.
- ti,abb_opp_sel: Addendum to the description in required properties
efuse: Mandatory if 'efuse-address' register is defined. Provides offset
from efuse-address to pick up ABB characteristics. Set to 0 if
'efuse-address' is not defined.
RBB enable efuse Mask: Optional if 'efuse-address' register is defined.
'ABB mode' is force set to RBB mode if value at "efuse-address"
+ efuse maps to RBB mask. Set to 0 to ignore this.
FBB enable efuse Mask: Optional if 'efuse-address' register is defined.
'ABB mode' is force set to FBB mode if value at "efuse-address"
+ efuse maps to FBB mask (valid only if RBB mask does not match)
Set to 0 to ignore this.
Vset value efuse Mask: Mandatory if ldo-address is set. Picks up from
efuse the value to set in 'ti,ldovbb-vset-mask' at ldo-address.
Example #1: Simplest configuration (no efuse data, hard coded ABB table):
abb_x: regulator-abb-x {
compatible = "ti,abb-v1";
regulator-name = "abb_x";
#address-cell = <0>;
#size-cells = <0>;
reg = <0x483072f0 0x8>, <0x48306818 0x4>;
reg-names = "base-address", "int-address";
ti,tranxdone-status-mask = <0x4000000>;
clocks = <&sysclk>;
ti,settling-time = <30>;
ti,clock-cycles = <8>;
ti,abb_info = <
/* uV ABB efuse rbb_m fbb_m vset_m */
1012500 0 0 0 0 0 /* Bypass */
1200000 3 0 0 0 0 /* RBB mandatory */
1320000 1 0 0 0 0 /* FBB mandatory */
>;
};
Example #2: Efuse bits contain ABB mode setting (no LDO override capability)
abb_y: regulator-abb-y {
compatible = "ti,abb-v2";
regulator-name = "abb_y";
#address-cell = <0>;
#size-cells = <0>;
reg = <0x4a307bd0 0x8>, <0x4a306014 0x4>, <0x4A002268 0x8>;
reg-names = "base-address", "int-address", "efuse-address";
ti,tranxdone-status-mask = <0x4000000>;
clocks = <&sysclk>;
ti,settling-time = <50>;
ti,clock-cycles = <16>;
ti,abb_info = <
/* uV ABB efuse rbb_m fbb_m vset_m */
975000 0 0 0 0 0 /* Bypass */
1012500 0 0 0x40000 0 0 /* RBB optional */
1200000 0 0x4 0 0x40000 0 /* FBB optional */
1320000 1 0 0 0 0 /* FBB mandatory */
>;
};
Example #3: Efuse bits contain ABB mode setting and LDO override capability
abb_z: regulator-abb-z {
compatible = "ti,abb-v2";
regulator-name = "abb_z";
#address-cell = <0>;
#size-cells = <0>;
reg = <0x4ae07ce4 0x8>, <0x4ae06010 0x4>,
<0x4a002194 0x8>, <0x4ae0C314 0x4>;
reg-names = "base-address", "int-address",
"efuse-address", "ldo-address";
ti,tranxdone-status-mask = <0x8000000>;
/* LDOVBBMM_MUX_CTRL */
ti,ldovbb-override-mask = <0x400>;
/* LDOVBBMM_VSET_OUT */
ti,ldovbb-vset-mask = <0x1F>;
clocks = <&sysclk>;
ti,settling-time = <50>;
ti,clock-cycles = <16>;
ti,abb_info = <
/* uV ABB efuse rbb_m fbb_m vset_m */
975000 0 0 0 0 0 /* Bypass */
1200000 0 0x4 0 0x40000 0x1f00 /* FBB optional, vset */
>;
};
......@@ -406,7 +406,6 @@ static int pm8607_regulator_remove(struct platform_device *pdev)
{
struct pm8607_regulator_info *info = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(info->regulator);
return 0;
}
......
......@@ -250,6 +250,15 @@ config REGULATOR_MAX77686
via I2C bus. The provided regulator is suitable for
Exynos-4 chips to control VARM and VINT voltages.
config REGULATOR_MAX77693
tristate "Maxim MAX77693 regulator"
depends on MFD_MAX77693
help
This driver controls a Maxim 77693 regulator via I2C bus.
The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2'
and one current regulator 'CHARGER'. This is suitable for
Exynos-4x12 chips.
config REGULATOR_PCAP
tristate "Motorola PCAP2 regulator driver"
depends on EZX_PCAP
......@@ -472,6 +481,16 @@ config REGULATOR_TWL4030
This driver supports the voltage regulators provided by
this family of companion chips.
config REGULATOR_TI_ABB
bool "TI Adaptive Body Bias on-chip LDO"
depends on ARCH_OMAP
help
Select this option to support Texas Instruments' on-chip Adaptive Body
Bias (ABB) LDO regulators. It is recommended that this option be
enabled on required TI SoC. Certain Operating Performance Points
on TI SoCs may be unstable without enabling this as it provides
device specific optimized bias to allow/optimize functionality.
config REGULATOR_VEXPRESS
tristate "Versatile Express regulators"
depends on VEXPRESS_CONFIG
......
......@@ -12,7 +12,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o ab8500-ext.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500-ext.o ab8500.o
obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
......@@ -41,6 +41,7 @@ obj-$(CONFIG_REGULATOR_MAX8973) += max8973-regulator.o
obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
......@@ -63,6 +64,7 @@ obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
......
......@@ -16,9 +16,11 @@
#include <linux/kernel.h>
#include <linux/err.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/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/regulator/ab8500.h>
......@@ -229,6 +231,28 @@ static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev)
return ret;
}
static int ab8500_ext_set_voltage(struct regulator_dev *rdev, int min_uV,
int max_uV, unsigned *selector)
{
struct regulation_constraints *regu_constraints = rdev->constraints;
if (!regu_constraints) {
dev_err(rdev_get_dev(rdev), "No regulator constraints\n");
return -EINVAL;
}
if (regu_constraints->min_uV == min_uV &&
regu_constraints->max_uV == max_uV)
return 0;
dev_err(rdev_get_dev(rdev),
"Requested min %duV max %duV != constrained min %duV max %duV\n",
min_uV, max_uV,
regu_constraints->min_uV, regu_constraints->max_uV);
return -EINVAL;
}
static int ab8500_ext_list_voltage(struct regulator_dev *rdev,
unsigned selector)
{
......@@ -252,6 +276,7 @@ static struct regulator_ops ab8500_ext_regulator_ops = {
.is_enabled = ab8500_ext_regulator_is_enabled,
.set_mode = ab8500_ext_regulator_set_mode,
.get_mode = ab8500_ext_regulator_get_mode,
.set_voltage = ab8500_ext_set_voltage,
.list_voltage = ab8500_ext_list_voltage,
};
......@@ -310,18 +335,37 @@ static struct ab8500_ext_regulator_info
},
};
int ab8500_ext_regulator_init(struct platform_device *pdev)
static struct of_regulator_match ab8500_ext_regulator_match[] = {
{ .name = "ab8500_ext1", .driver_data = (void *) AB8500_EXT_SUPPLY1, },
{ .name = "ab8500_ext2", .driver_data = (void *) AB8500_EXT_SUPPLY2, },
{ .name = "ab8500_ext3", .driver_data = (void *) AB8500_EXT_SUPPLY3, },
};
static int ab8500_ext_regulator_probe(struct platform_device *pdev)
{
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
struct ab8500_platform_data *ppdata;
struct ab8500_regulator_platform_data *pdata;
struct device_node *np = pdev->dev.of_node;
struct regulator_config config = { };
int i, err;
if (np) {
err = of_regulator_match(&pdev->dev, np,
ab8500_ext_regulator_match,
ARRAY_SIZE(ab8500_ext_regulator_match));
if (err < 0) {
dev_err(&pdev->dev,
"Error parsing regulator init data: %d\n", err);
return err;
}
}
if (!ab8500) {
dev_err(&pdev->dev, "null mfd parent\n");
return -EINVAL;
}
ppdata = dev_get_platdata(ab8500->dev);
if (!ppdata) {
dev_err(&pdev->dev, "null parent pdata\n");
......@@ -362,8 +406,11 @@ int ab8500_ext_regulator_init(struct platform_device *pdev)
pdata->ext_regulator[i].driver_data;
config.dev = &pdev->dev;
config.init_data = &pdata->ext_regulator[i];
config.driver_data = info;
config.of_node = ab8500_ext_regulator_match[i].of_node;
config.init_data = (np) ?
ab8500_ext_regulator_match[i].init_data :
&pdata->ext_regulator[i];
/* register regulator with framework */
info->rdev = regulator_register(&info->desc, &config);
......@@ -386,7 +433,7 @@ int ab8500_ext_regulator_init(struct platform_device *pdev)
return 0;
}
void ab8500_ext_regulator_exit(struct platform_device *pdev)
static int ab8500_ext_regulator_remove(struct platform_device *pdev)
{
int i;
......@@ -399,7 +446,36 @@ void ab8500_ext_regulator_exit(struct platform_device *pdev)
regulator_unregister(info->rdev);
}
return 0;
}
static struct platform_driver ab8500_ext_regulator_driver = {
.probe = ab8500_ext_regulator_probe,
.remove = ab8500_ext_regulator_remove,
.driver = {
.name = "ab8500-ext-regulator",
.owner = THIS_MODULE,
},
};
static int __init ab8500_ext_regulator_init(void)
{
int ret;
ret = platform_driver_register(&ab8500_ext_regulator_driver);
if (ret)
pr_err("Failed to register ab8500 ext regulator: %d\n", ret);
return ret;
}
subsys_initcall(ab8500_ext_regulator_init);
static void __exit ab8500_ext_regulator_exit(void)
{
platform_driver_unregister(&ab8500_ext_regulator_driver);
}
module_exit(ab8500_ext_regulator_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
......
......@@ -719,6 +719,7 @@ static struct ab8500_regulator_info
.n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
.volt_table = ldo_vauxn_voltages,
.enable_time = 200,
.supply_name = "vin",
},
.load_lp_uA = 5000,
.update_bank = 0x04,
......@@ -741,6 +742,7 @@ static struct ab8500_regulator_info
.n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
.volt_table = ldo_vauxn_voltages,
.enable_time = 200,
.supply_name = "vin",
},
.load_lp_uA = 5000,
.update_bank = 0x04,
......@@ -763,6 +765,7 @@ static struct ab8500_regulator_info
.n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
.volt_table = ldo_vaux3_voltages,
.enable_time = 450,
.supply_name = "vin",
},
.load_lp_uA = 5000,
.update_bank = 0x04,
......@@ -3156,22 +3159,12 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
return err;
}
if (!is_ab8505(ab8500)) {
/* register external regulators (before Vaux1, 2 and 3) */
err = ab8500_ext_regulator_init(pdev);
if (err)
return err;
}
/* register all regulators */
for (i = 0; i < abx500_regulator.info_size; i++) {
err = ab8500_regulator_register(pdev, &pdata->regulator[i],
i, NULL);
if (err < 0) {
if (!is_ab8505(ab8500))
ab8500_ext_regulator_exit(pdev);
if (err < 0)
return err;
}
}
return 0;
......@@ -3180,7 +3173,6 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
static int ab8500_regulator_remove(struct platform_device *pdev)
{
int i, err;
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
for (i = 0; i < abx500_regulator.info_size; i++) {
struct ab8500_regulator_info *info = NULL;
......@@ -3192,10 +3184,6 @@ static int ab8500_regulator_remove(struct platform_device *pdev)
regulator_unregister(info->regulator);
}
/* remove external regulators (after Vaux1, 2 and 3) */
if (!is_ab8505(ab8500))
ab8500_ext_regulator_exit(pdev);
/* remove regulator debug */
err = ab8500_regulator_debug_exit(pdev);
if (err)
......
......@@ -2137,6 +2137,21 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
}
EXPORT_SYMBOL_GPL(regulator_list_voltage);
/**
* regulator_get_linear_step - return the voltage step size between VSEL values
* @regulator: regulator source
*
* Returns the voltage step size between VSEL values for linear
* regulators, or return 0 if the regulator isn't a linear regulator.
*/
unsigned int regulator_get_linear_step(struct regulator *regulator)
{
struct regulator_dev *rdev = regulator->rdev;
return rdev->desc->uV_step;
}
EXPORT_SYMBOL_GPL(regulator_get_linear_step);
/**
* regulator_is_supported_voltage - check if a voltage range can be supported
*
......
......@@ -130,7 +130,7 @@ static int isl6271a_probe(struct i2c_client *i2c,
if (i == 0)
config.init_data = init_data;
else
config.init_data = 0;
config.init_data = NULL;
config.driver_data = pmic;
pmic->rdev[i] = regulator_register(&isl_rd[i], &config);
......
......@@ -434,7 +434,7 @@ static int lp3971_i2c_probe(struct i2c_client *i2c,
return -ENODEV;
}
lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
lp3971 = devm_kzalloc(&i2c->dev, sizeof(struct lp3971), GFP_KERNEL);
if (lp3971 == NULL)
return -ENOMEM;
......@@ -449,19 +449,15 @@ static int lp3971_i2c_probe(struct i2c_client *i2c,
ret = -ENODEV;
if (ret < 0) {
dev_err(&i2c->dev, "failed to detect device\n");
goto err_detect;
return ret;
}
ret = setup_regulators(lp3971, pdata);
if (ret < 0)
goto err_detect;
return ret;
i2c_set_clientdata(i2c, lp3971);
return 0;
err_detect:
kfree(lp3971);
return ret;
}
static int lp3971_i2c_remove(struct i2c_client *i2c)
......@@ -473,7 +469,6 @@ static int lp3971_i2c_remove(struct i2c_client *i2c)
regulator_unregister(lp3971->rdev[i]);
kfree(lp3971->rdev);
kfree(lp3971);
return 0;
}
......
......@@ -528,7 +528,7 @@ static int lp3972_i2c_probe(struct i2c_client *i2c,
return -ENODEV;
}
lp3972 = kzalloc(sizeof(struct lp3972), GFP_KERNEL);
lp3972 = devm_kzalloc(&i2c->dev, sizeof(struct lp3972), GFP_KERNEL);
if (!lp3972)
return -ENOMEM;
......@@ -546,19 +546,15 @@ static int lp3972_i2c_probe(struct i2c_client *i2c,
}
if (ret < 0) {
dev_err(&i2c->dev, "failed to detect device. ret = %d\n", ret);
goto err_detect;
return ret;
}
ret = setup_regulators(lp3972, pdata);
if (ret < 0)
goto err_detect;
return ret;
i2c_set_clientdata(i2c, lp3972);
return 0;
err_detect:
kfree(lp3972);
return ret;
}
static int lp3972_i2c_remove(struct i2c_client *i2c)
......@@ -569,7 +565,6 @@ static int lp3972_i2c_remove(struct i2c_client *i2c)
for (i = 0; i < lp3972->num_regulators; i++)
regulator_unregister(lp3972->rdev[i]);
kfree(lp3972->rdev);
kfree(lp3972);
return 0;
}
......
......@@ -18,6 +18,9 @@
#include <linux/regulator/lp872x.h>
#include <linux/regulator/driver.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regulator/of_regulator.h>
/* Registers : LP8720/8725 shared */
#define LP872X_GENERAL_CFG 0x00
......@@ -723,8 +726,8 @@ static int lp872x_init_dvs(struct lp872x *lp)
gpio = dvs->gpio;
if (!gpio_is_valid(gpio)) {
dev_err(lp->dev, "invalid gpio: %d\n", gpio);
return -EINVAL;
dev_warn(lp->dev, "invalid gpio: %d\n", gpio);
goto set_default_dvs_mode;
}
pinstate = dvs->init_state;
......@@ -829,6 +832,103 @@ static const struct regmap_config lp872x_regmap_config = {
.max_register = MAX_REGISTERS,
};
#ifdef CONFIG_OF
#define LP872X_VALID_OPMODE (REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL)
static struct of_regulator_match lp8720_matches[] = {
{ .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1, },
{ .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2, },
{ .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3, },
{ .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4, },
{ .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5, },
{ .name = "buck", .driver_data = (void *)LP8720_ID_BUCK, },
};
static struct of_regulator_match lp8725_matches[] = {
{ .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1, },
{ .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2, },
{ .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3, },
{ .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4, },
{ .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5, },
{ .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1, },
{ .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2, },
{ .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1, },
{ .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2, },
};
static struct lp872x_platform_data
*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which)
{
struct device_node *np = dev->of_node;
struct lp872x_platform_data *pdata;
struct of_regulator_match *match;
struct regulator_init_data *d;
int num_matches;
int count;
int i;
u8 dvs_state;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
goto out;
of_property_read_u8(np, "ti,general-config", &pdata->general_config);
if (of_find_property(np, "ti,update-config", NULL))
pdata->update_config = true;
pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL);
if (!pdata->dvs)
goto out;
pdata->dvs->gpio = of_get_named_gpio(np, "ti,dvs-gpio", 0);
of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel);
of_property_read_u8(np, "ti,dvs-state", &dvs_state);
pdata->dvs->init_state = dvs_state ? DVS_HIGH : DVS_LOW;
if (of_get_child_count(np) == 0)
goto out;
switch (which) {
case LP8720:
match = lp8720_matches;
num_matches = ARRAY_SIZE(lp8720_matches);
break;
case LP8725:
match = lp8725_matches;
num_matches = ARRAY_SIZE(lp8725_matches);
break;
default:
goto out;
}
count = of_regulator_match(dev, np, match, num_matches);
if (count <= 0)
goto out;
for (i = 0; i < num_matches; i++) {
pdata->regulator_data[i].id = (int)match[i].driver_data;
pdata->regulator_data[i].init_data = match[i].init_data;
/* Operation mode configuration for buck/buck1/buck2 */
if (strncmp(match[i].name, "buck", 4))
continue;
d = pdata->regulator_data[i].init_data;
d->constraints.valid_modes_mask |= LP872X_VALID_OPMODE;
d->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE;
}
out:
return pdata;
}
#else
static struct lp872x_platform_data
*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which)
{
return NULL;
}
#endif
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct lp872x *lp;
......@@ -838,6 +938,10 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
[LP8725] = LP8725_NUM_REGULATORS,
};
if (cl->dev.of_node)
cl->dev.platform_data = lp872x_populate_pdata_from_dt(&cl->dev,
(enum lp872x_id)id->driver_data);
lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
if (!lp)
goto err_mem;
......@@ -882,6 +986,13 @@ static int lp872x_remove(struct i2c_client *cl)
return 0;
}
static const struct of_device_id lp872x_dt_ids[] = {
{ .compatible = "ti,lp8720", },
{ .compatible = "ti,lp8725", },
{ }
};
MODULE_DEVICE_TABLE(of, lp872x_dt_ids);
static const struct i2c_device_id lp872x_ids[] = {
{"lp8720", LP8720},
{"lp8725", LP8725},
......@@ -893,6 +1004,7 @@ static struct i2c_driver lp872x_driver = {
.driver = {
.name = "lp872x",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(lp872x_dt_ids),
},
.probe = lp872x_probe,
.remove = lp872x_remove,
......
......@@ -19,7 +19,6 @@
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
......
......@@ -533,7 +533,6 @@ static int lp8788_buck_remove(struct platform_device *pdev)
{
struct lp8788_buck *buck = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(buck->regulator);
return 0;
......
......@@ -561,7 +561,6 @@ static int lp8788_dldo_remove(struct platform_device *pdev)
{
struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(ldo->regulator);
return 0;
......@@ -622,7 +621,6 @@ static int lp8788_aldo_remove(struct platform_device *pdev)
{
struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(ldo->regulator);
return 0;
......
......@@ -24,7 +24,6 @@
#include <linux/kernel.h>
#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/slab.h>
......
/*
* max77693.c - Regulator driver for the Maxim 77693
*
* Copyright (C) 2013 Samsung Electronics
* Jonghwa Lee <jonghwa3.lee@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This driver is based on max77686.c
*/
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/max77693.h>
#include <linux/mfd/max77693-private.h>
#include <linux/regulator/of_regulator.h>
#define CHGIN_ILIM_STEP_20mA 20000
struct max77693_pmic_dev {
struct device *dev;
struct max77693_dev *iodev;
int num_regulators;
struct regulator_dev **rdev;
};
/* CHARGER regulator ops */
/* CHARGER regulator uses two bits for enabling */
static int max77693_chg_is_enabled(struct regulator_dev *rdev)
{
int ret;
u8 val;
ret = max77693_read_reg(rdev->regmap, rdev->desc->enable_reg, &val);
if (ret)
return ret;
return (val & rdev->desc->enable_mask) == rdev->desc->enable_mask;
}
/*
* CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
* 0x00, 0x01, 0x2, 0x03 = 60 mA
* 0x04 ~ 0x7E = (60 + (X - 3) * 20) mA
*/
static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
{
unsigned int chg_min_uA = rdev->constraints->min_uA;
unsigned int chg_max_uA = rdev->constraints->max_uA;
u8 reg, sel;
unsigned int val;
int ret;
ret = max77693_read_reg(rdev->regmap,
MAX77693_CHG_REG_CHG_CNFG_09, &reg);
if (ret < 0)
return ret;
sel = reg & CHG_CNFG_09_CHGIN_ILIM_MASK;
/* the first four codes for charger current are all 60mA */
if (sel <= 3)
sel = 0;
else
sel -= 3;
val = chg_min_uA + CHGIN_ILIM_STEP_20mA * sel;
if (val > chg_max_uA)
return -EINVAL;
return val;
}
static int max77693_chg_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
unsigned int chg_min_uA = rdev->constraints->min_uA;
int sel = 0;
while (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel < min_uA)
sel++;
if (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel > max_uA)
return -EINVAL;
/* the first four codes for charger current are all 60mA */
sel += 3;
return max77693_write_reg(rdev->regmap,
MAX77693_CHG_REG_CHG_CNFG_09, sel);
}
/* end of CHARGER regulator ops */
static const unsigned int max77693_safeout_table[] = {
4850000,
4900000,
4950000,
3300000,
};
static struct regulator_ops max77693_safeout_ops = {
.list_voltage = regulator_list_voltage_table,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static struct regulator_ops max77693_charger_ops = {
.is_enabled = max77693_chg_is_enabled,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_current_limit = max77693_chg_get_current_limit,
.set_current_limit = max77693_chg_set_current_limit,
};
#define regulator_desc_esafeout(_num) { \
.name = "ESAFEOUT"#_num, \
.id = MAX77693_ESAFEOUT##_num, \
.n_voltages = 4, \
.ops = &max77693_safeout_ops, \
.type = REGULATOR_VOLTAGE, \
.volt_table = max77693_safeout_table, \
.vsel_reg = MAX77693_CHG_REG_SAFEOUT_CTRL, \
.vsel_mask = SAFEOUT_CTRL_SAFEOUT##_num##_MASK, \
.enable_reg = MAX77693_CHG_REG_SAFEOUT_CTRL, \
.enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \
}
static struct regulator_desc regulators[] = {
regulator_desc_esafeout(1),
regulator_desc_esafeout(2),
{
.name = "CHARGER",
.id = MAX77693_CHARGER,
.ops = &max77693_charger_ops,
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
.enable_reg = MAX77693_CHG_REG_CHG_CNFG_00,
.enable_mask = CHG_CNFG_00_CHG_MASK |
CHG_CNFG_00_BUCK_MASK,
},
};
#ifdef CONFIG_OF
static int max77693_pmic_dt_parse_rdata(struct device *dev,
struct max77693_regulator_data **rdata)
{
struct device_node *np;
struct of_regulator_match *rmatch;
struct max77693_regulator_data *tmp;
int i, matched = 0;
np = of_find_node_by_name(dev->parent->of_node, "regulators");
if (!np)
return -EINVAL;
rmatch = devm_kzalloc(dev,
sizeof(*rmatch) * ARRAY_SIZE(regulators), GFP_KERNEL);
if (!rmatch)
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(regulators); i++)
rmatch[i].name = regulators[i].name;
matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(regulators));
if (matched <= 0)
return matched;
*rdata = devm_kzalloc(dev, sizeof(**rdata) * matched, GFP_KERNEL);
if (!(*rdata))
return -ENOMEM;
tmp = *rdata;
for (i = 0; i < matched; i++) {
tmp->initdata = rmatch[i].init_data;
tmp->of_node = rmatch[i].of_node;
tmp->id = regulators[i].id;
tmp++;
}
return matched;
}
#else
static int max77693_pmic_dt_parse_rdata(struct device *dev,
struct max77693_regulator_data **rdata)
{
return 0;
}
#endif /* CONFIG_OF */
static int max77693_pmic_init_rdata(struct device *dev,
struct max77693_regulator_data **rdata)
{
struct max77693_platform_data *pdata;
int num_regulators = 0;
pdata = dev_get_platdata(dev->parent);
if (pdata) {
*rdata = pdata->regulators;
num_regulators = pdata->num_regulators;
}
if (!(*rdata) && dev->parent->of_node)
num_regulators = max77693_pmic_dt_parse_rdata(dev, rdata);
return num_regulators;
}
static int max77693_pmic_probe(struct platform_device *pdev)
{
struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max77693_pmic_dev *max77693_pmic;
struct max77693_regulator_data *rdata = NULL;
int num_rdata, i, ret;
struct regulator_config config;
num_rdata = max77693_pmic_init_rdata(&pdev->dev, &rdata);
if (!rdata || num_rdata <= 0) {
dev_err(&pdev->dev, "No init data supplied.\n");
return -ENODEV;
}
max77693_pmic = devm_kzalloc(&pdev->dev,
sizeof(struct max77693_pmic_dev),
GFP_KERNEL);
if (!max77693_pmic)
return -ENOMEM;
max77693_pmic->rdev = devm_kzalloc(&pdev->dev,
sizeof(struct regulator_dev *) * num_rdata,
GFP_KERNEL);
if (!max77693_pmic->rdev)
return -ENOMEM;
max77693_pmic->dev = &pdev->dev;
max77693_pmic->iodev = iodev;
max77693_pmic->num_regulators = num_rdata;
config.dev = &pdev->dev;
config.regmap = iodev->regmap;
config.driver_data = max77693_pmic;
platform_set_drvdata(pdev, max77693_pmic);
for (i = 0; i < max77693_pmic->num_regulators; i++) {
int id = rdata[i].id;
config.init_data = rdata[i].initdata;
config.of_node = rdata[i].of_node;
max77693_pmic->rdev[i] = regulator_register(&regulators[id],
&config);
if (IS_ERR(max77693_pmic->rdev[i])) {
ret = PTR_ERR(max77693_pmic->rdev[i]);
dev_err(max77693_pmic->dev,
"Failed to initialize regulator-%d\n", id);
max77693_pmic->rdev[i] = NULL;
goto err;
}
}
return 0;
err:
while (--i >= 0)
regulator_unregister(max77693_pmic->rdev[i]);
return ret;
}
static int max77693_pmic_remove(struct platform_device *pdev)
{
struct max77693_pmic_dev *max77693_pmic = platform_get_drvdata(pdev);
struct regulator_dev **rdev = max77693_pmic->rdev;
int i;
for (i = 0; i < max77693_pmic->num_regulators; i++)
if (rdev[i])
regulator_unregister(rdev[i]);
return 0;
}
static const struct platform_device_id max77693_pmic_id[] = {
{"max77693-pmic", 0},
{},
};
MODULE_DEVICE_TABLE(platform, max77693_pmic_id);
static struct platform_driver max77693_pmic_driver = {
.driver = {
.name = "max77693-pmic",
.owner = THIS_MODULE,
},
.probe = max77693_pmic_probe,
.remove = max77693_pmic_remove,
.id_table = max77693_pmic_id,
};
module_platform_driver(max77693_pmic_driver);
MODULE_DESCRIPTION("MAXIM MAX77693 regulator driver");
MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
MODULE_LICENSE("GPL");
......@@ -327,7 +327,6 @@ static int max8925_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(rdev);
return 0;
......
......@@ -26,10 +26,12 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/max8973-regulator.h>
#include <linux/regulator/of_regulator.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/slab.h>
......@@ -100,6 +102,7 @@ struct max8973_chip {
int curr_vout_reg;
int curr_gpio_val;
bool valid_dvs_gpio;
struct regulator_ops ops;
};
/*
......@@ -240,7 +243,7 @@ static unsigned int max8973_dcdc_get_mode(struct regulator_dev *rdev)
REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
}
static struct regulator_ops max8973_dcdc_ops = {
static const struct regulator_ops max8973_dcdc_ops = {
.get_voltage_sel = max8973_dcdc_get_voltage_sel,
.set_voltage_sel = max8973_dcdc_set_voltage_sel,
.list_voltage = regulator_list_voltage_linear,
......@@ -369,7 +372,8 @@ static int max8973_probe(struct i2c_client *client,
int ret;
pdata = client->dev.platform_data;
if (!pdata) {
if (!pdata && !client->dev.of_node) {
dev_err(&client->dev, "No Platform data");
return -EIO;
}
......@@ -388,30 +392,36 @@ static int max8973_probe(struct i2c_client *client,
}
i2c_set_clientdata(client, max);
max->ops = max8973_dcdc_ops;
max->dev = &client->dev;
max->desc.name = id->name;
max->desc.id = 0;
max->desc.ops = &max8973_dcdc_ops;
max->desc.ops = &max->ops;
max->desc.type = REGULATOR_VOLTAGE;
max->desc.owner = THIS_MODULE;
max->desc.min_uV = MAX8973_MIN_VOLATGE;
max->desc.uV_step = MAX8973_VOLATGE_STEP;
max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE;
if (!pdata->enable_ext_control) {
if (!pdata || !pdata->enable_ext_control) {
max->desc.enable_reg = MAX8973_VOUT;
max->desc.enable_mask = MAX8973_VOUT_ENABLE;
max8973_dcdc_ops.enable = regulator_enable_regmap;
max8973_dcdc_ops.disable = regulator_disable_regmap;
max8973_dcdc_ops.is_enabled = regulator_is_enabled_regmap;
max->ops.enable = regulator_enable_regmap;
max->ops.disable = regulator_disable_regmap;
max->ops.is_enabled = regulator_is_enabled_regmap;
}
if (pdata) {
max->dvs_gpio = pdata->dvs_gpio;
max->enable_external_control = pdata->enable_ext_control;
max->curr_gpio_val = pdata->dvs_def_state;
max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
} else {
max->dvs_gpio = -EINVAL;
max->curr_vout_reg = MAX8973_VOUT;
}
max->enable_external_control = pdata->enable_ext_control;
max->dvs_gpio = pdata->dvs_gpio;
max->curr_gpio_val = pdata->dvs_def_state;
max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
max->lru_index[0] = max->curr_vout_reg;
max->valid_dvs_gpio = false;
if (gpio_is_valid(max->dvs_gpio)) {
int gpio_flags;
......@@ -437,16 +447,21 @@ static int max8973_probe(struct i2c_client *client,
max->lru_index[i] = i;
max->lru_index[0] = max->curr_vout_reg;
max->lru_index[max->curr_vout_reg] = 0;
} else {
max->valid_dvs_gpio = false;
}
ret = max8973_init_dcdc(max, pdata);
if (ret < 0) {
dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
return ret;
if (pdata) {
ret = max8973_init_dcdc(max, pdata);
if (ret < 0) {
dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
return ret;
}
}
config.dev = &client->dev;
config.init_data = pdata->reg_init_data;
config.init_data = pdata ? pdata->reg_init_data :
of_get_regulator_init_data(&client->dev, client->dev.of_node);
config.driver_data = max;
config.of_node = client->dev.of_node;
config.regmap = max->regmap;
......
......@@ -466,8 +466,6 @@ static int mc13783_regulator_remove(struct platform_device *pdev)
struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
int i;
platform_set_drvdata(pdev, NULL);
for (i = 0; i < priv->num_regulators; i++)
regulator_unregister(priv->regulators[i]);
......
......@@ -636,8 +636,6 @@ static int mc13892_regulator_remove(struct platform_device *pdev)
struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
int i;
platform_set_drvdata(pdev, NULL);
for (i = 0; i < priv->num_regulators; i++)
regulator_unregister(priv->regulators[i]);
......
......@@ -61,6 +61,9 @@ static void of_get_regulation_constraints(struct device_node *np,
else /* status change should be possible if not always on. */
constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;
if (of_property_read_bool(np, "regulator-allow-bypass"))
constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS;
ramp_delay = of_get_property(np, "regulator-ramp-delay", NULL);
if (ramp_delay)
constraints->ramp_delay = be32_to_cpu(*ramp_delay);
......
......@@ -260,7 +260,6 @@ static int pcap_regulator_remove(struct platform_device *pdev)
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -106,7 +106,6 @@ static int pcf50633_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(rdev);
return 0;
......
......@@ -12,7 +12,6 @@
*/
#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/slab.h>
......
此差异已折叠。
......@@ -351,7 +351,6 @@ static int tps62360_probe(struct i2c_client *client,
int chip_id;
pdata = client->dev.platform_data;
chip_id = id->driver_data;
if (client->dev.of_node) {
const struct of_device_id *match;
......@@ -364,6 +363,11 @@ static int tps62360_probe(struct i2c_client *client,
chip_id = (int)match->data;
if (!pdata)
pdata = of_get_tps62360_platform_data(&client->dev);
} else if (id) {
chip_id = id->driver_data;
} else {
dev_err(&client->dev, "No device tree match or id table match found\n");
return -ENODEV;
}
if (!pdata) {
......@@ -402,7 +406,7 @@ static int tps62360_probe(struct i2c_client *client,
return -ENODEV;
}
tps->desc.name = id->name;
tps->desc.name = client->name;
tps->desc.id = 0;
tps->desc.ops = &tps62360_dcdc_ops;
tps->desc.type = REGULATOR_VOLTAGE;
......
......@@ -405,8 +405,6 @@ static int tps65217_regulator_remove(struct platform_device *pdev)
for (i = 0; i < TPS65217_NUM_REGULATOR; i++)
regulator_unregister(tps->rdev[i]);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -330,8 +330,6 @@ static int regulator_virtual_remove(struct platform_device *pdev)
if (drvdata->enabled)
regulator_disable(drvdata->regulator);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -567,8 +567,6 @@ static int wm831x_buckv_remove(struct platform_device *pdev)
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
struct wm831x *wm831x = dcdc->wm831x;
platform_set_drvdata(pdev, NULL);
free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "HC")),
dcdc);
free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")),
......@@ -714,8 +712,6 @@ static int wm831x_buckp_remove(struct platform_device *pdev)
{
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")),
dcdc);
regulator_unregister(dcdc->regulator);
......@@ -849,8 +845,6 @@ static int wm831x_boostp_remove(struct platform_device *pdev)
{
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")),
dcdc);
regulator_unregister(dcdc->regulator);
......@@ -940,7 +934,6 @@ static int wm831x_epe_remove(struct platform_device *pdev)
{
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(dcdc->regulator);
return 0;
......
......@@ -225,8 +225,6 @@ static int wm831x_isink_remove(struct platform_device *pdev)
{
struct wm831x_isink *isink = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
free_irq(wm831x_irq(isink->wm831x, platform_get_irq(pdev, 0)), isink);
regulator_unregister(isink->regulator);
......
......@@ -338,8 +338,6 @@ static int wm831x_gp_ldo_remove(struct platform_device *pdev)
{
struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
free_irq(wm831x_irq(ldo->wm831x,
platform_get_irq_byname(pdev, "UV")), ldo);
regulator_unregister(ldo->regulator);
......
......@@ -250,7 +250,6 @@ static int wm8400_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(rdev);
return 0;
......
......@@ -185,8 +185,6 @@ static int wm8994_ldo_remove(struct platform_device *pdev)
{
struct wm8994_ldo *ldo = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(ldo->regulator);
return 0;
......
......@@ -85,6 +85,19 @@ enum max77693_pmic_reg {
MAX77693_PMIC_REG_END,
};
/* MAX77693 CHG_CNFG_00 register */
#define CHG_CNFG_00_CHG_MASK 0x1
#define CHG_CNFG_00_BUCK_MASK 0x4
/* MAX77693 CHG_CNFG_09 Register */
#define CHG_CNFG_09_CHGIN_ILIM_MASK 0x7F
/* MAX77693 CHG_CTRL Register */
#define SAFEOUT_CTRL_SAFEOUT1_MASK 0x3
#define SAFEOUT_CTRL_SAFEOUT2_MASK 0xC
#define SAFEOUT_CTRL_ENSAFEOUT1_MASK 0x40
#define SAFEOUT_CTRL_ENSAFEOUT2_MASK 0x80
/* Slave addr = 0x4A: MUIC */
enum max77693_muic_reg {
MAX77693_MUIC_REG_ID = 0x00,
......
......@@ -30,6 +30,20 @@
#ifndef __LINUX_MFD_MAX77693_H
#define __LINUX_MFD_MAX77693_H
/* MAX77686 regulator IDs */
enum max77693_regulators {
MAX77693_ESAFEOUT1 = 0,
MAX77693_ESAFEOUT2,
MAX77693_CHARGER,
MAX77693_REG_MAX,
};
struct max77693_regulator_data {
int id;
struct regulator_init_data *initdata;
struct device_node *of_node;
};
struct max77693_reg_data {
u8 addr;
u8 data;
......@@ -52,6 +66,10 @@ struct max77693_muic_platform_data {
struct max77693_platform_data {
int wakeup;
/* regulator data */
struct max77693_regulator_data *regulators;
int num_regulators;
/* muic data */
struct max77693_muic_platform_data *muic_data;
};
......
......@@ -336,8 +336,4 @@ static inline int ab8500_regulator_debug_exit(struct platform_device *pdev)
}
#endif
/* AB8500 external regulator functions. */
int ab8500_ext_regulator_init(struct platform_device *pdev);
void ab8500_ext_regulator_exit(struct platform_device *pdev);
#endif
......@@ -165,6 +165,7 @@ int regulator_count_voltages(struct regulator *regulator);
int regulator_list_voltage(struct regulator *regulator, unsigned selector);
int regulator_is_supported_voltage(struct regulator *regulator,
int min_uV, int max_uV);
unsigned int regulator_get_linear_step(struct regulator *regulator);
int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
int regulator_set_voltage_time(struct regulator *regulator,
int old_uV, int new_uV);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册