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

Pull regulator updates from Mark Brown:
 "The diffstat and changelog here is dominated by Lee Jones' heroic
  efforts to sync the ab8500 driver that's been maintained out of tree
  with mainline (plus Axel's cleanup work on the results) but there's a
  few other things here:

   - Axel Lin added regulator_map_voltage_ascend() optimising a common
     pattern for drivers using the core code.
   - Milo Kim tought the regulator core to handle regulators sharing an
     enable GPIO, avoiding the need to do hacks to support such systems.
   - Andrew Bresticker added code to handle missing supplies for
     regulators more sensibly for device tree systems, reducing the need
     for stubbing there.

  plus the usual batch of driver specific updates and fixes"

* tag 'regulator-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (152 commits)
  regulator: mc13892: Fix MC13892_SWITCHERS0_SWxHI bit in set_voltage_sel
  regulator: Remove NULL test before calling regulator_unregister()
  regulator: mc13783: Add device tree probe support
  regulator: mc13xxx: Add warning of incorrect names of regulators
  regulator: max77686: Don't update max77686->opmode if update register fails
  regulator: max8952: Add missing config.of_node setting for regulator register
  regulator: ab3100: Fix regulator register error handling
  regulator: tps6524x: Use regulator_map_voltage_ascend
  regulator: lp8788-buck: Use regulator_map_voltage_ascend
  regulator: lp872x: Use regulator_map_voltage_ascend
  regulator: mc13892: Use regulator_map_voltage_ascend for mc13892_sw_regulator_ops
  regulator: tps65023: Use regulator_map_voltage_ascend
  regulator: tps65023: Merge tps65020 ldo1 and ldo2 vsel table
  regulator: tps6507x: Use regulator_map_voltage_ascend
  regulator: mc13892: Fix MC13892_SWITCHERS0_SWxHI bit in set_voltage_sel
  regulator: ab3100: device tree support
  regulator: ab3100: refactor probe to use IDs
  regulator: max8973: Don't override control1 variable when set ramp delay bits
  regulator: tps80031: Convert tps80031_dcdc_ops to [get|set]_voltage_sel_regmap
  regulator: tps80031: Fix LDO2 track mode for TPS80031 or TPS80032-ES1.0
  ...
This commit is contained in:
Linus Torvalds
2013-04-29 16:32:25 -07:00
54 changed files with 5050 additions and 833 deletions
@@ -10,10 +10,40 @@ Optional properties:
- fsl,mc13xxx-uses-touch : Indicate the touchscreen controller is being used
Sub-nodes:
- regulators : Contain the regulator nodes. The MC13892 regulators are
bound using their names as listed below with their registers and bits
for enabling.
- regulators : Contain the regulator nodes. The regulators are bound using
their names as listed below with their registers and bits for enabling.
MC13783 regulators:
sw1a : regulator SW1A (register 24, bit 0)
sw1b : regulator SW1B (register 25, bit 0)
sw2a : regulator SW2A (register 26, bit 0)
sw2b : regulator SW2B (register 27, bit 0)
sw3 : regulator SW3 (register 29, bit 20)
vaudio : regulator VAUDIO (register 32, bit 0)
viohi : regulator VIOHI (register 32, bit 3)
violo : regulator VIOLO (register 32, bit 6)
vdig : regulator VDIG (register 32, bit 9)
vgen : regulator VGEN (register 32, bit 12)
vrfdig : regulator VRFDIG (register 32, bit 15)
vrfref : regulator VRFREF (register 32, bit 18)
vrfcp : regulator VRFCP (register 32, bit 21)
vsim : regulator VSIM (register 33, bit 0)
vesim : regulator VESIM (register 33, bit 3)
vcam : regulator VCAM (register 33, bit 6)
vrfbg : regulator VRFBG (register 33, bit 9)
vvib : regulator VVIB (register 33, bit 11)
vrf1 : regulator VRF1 (register 33, bit 12)
vrf2 : regulator VRF2 (register 33, bit 15)
vmmc1 : regulator VMMC1 (register 33, bit 18)
vmmc2 : regulator VMMC2 (register 33, bit 21)
gpo1 : regulator GPO1 (register 34, bit 6)
gpo2 : regulator GPO2 (register 34, bit 8)
gpo3 : regulator GPO3 (register 34, bit 10)
gpo4 : regulator GPO4 (register 34, bit 12)
pwgt1spi : regulator PWGT1SPI (register 34, bit 15)
pwgt2spi : regulator PWGT2SPI (register 34, bit 16)
MC13892 regulators:
vcoincell : regulator VCOINCELL (register 13, bit 23)
sw1 : regulator SW1 (register 24, bit 0)
sw2 : regulator SW2 (register 25, bit 0)
@@ -0,0 +1,52 @@
Maxim MAX8952 voltage regulator
Required properties:
- compatible: must be equal to "maxim,max8952"
- reg: I2C slave address, usually 0x60
- max8952,dvs-mode-microvolt: array of 4 integer values defining DVS voltages
in microvolts. All values must be from range <770000, 1400000>
- any required generic properties defined in regulator.txt
Optional properties:
- max8952,vid-gpios: array of two GPIO pins used for DVS voltage selection
- max8952,en-gpio: GPIO used to control enable status of regulator
- max8952,default-mode: index of default DVS voltage, from <0, 3> range
- max8952,sync-freq: sync frequency, must be one of following values:
- 0: 26 MHz
- 1: 13 MHz
- 2: 19.2 MHz
Defaults to 26 MHz if not specified.
- max8952,ramp-speed: voltage ramp speed, must be one of following values:
- 0: 32mV/us
- 1: 16mV/us
- 2: 8mV/us
- 3: 4mV/us
- 4: 2mV/us
- 5: 1mV/us
- 6: 0.5mV/us
- 7: 0.25mV/us
Defaults to 32mV/us if not specified.
- any available generic properties defined in regulator.txt
Example:
vdd_arm_reg: pmic@60 {
compatible = "maxim,max8952";
reg = <0x60>;
/* max8952-specific properties */
max8952,vid-gpios = <&gpx0 3 0>, <&gpx0 4 0>;
max8952,en-gpio = <&gpx0 1 0>;
max8952,default-mode = <0>;
max8952,dvs-mode-microvolt = <1250000>, <1200000>,
<1050000>, <950000>;
max8952,sync-freq = <0>;
max8952,ramp-speed = <0>;
/* generic regulator properties */
regulator-name = "vdd_arm";
regulator-min-microvolt = <770000>;
regulator-max-microvolt = <1400000>;
regulator-always-on;
regulator-boot-on;
};
+1 -1
View File
@@ -8732,7 +8732,7 @@ F: drivers/scsi/vmw_pvscsi.c
F: drivers/scsi/vmw_pvscsi.h
VOLTAGE AND CURRENT REGULATOR FRAMEWORK
M: Liam Girdwood <lrg@ti.com>
M: Liam Girdwood <lgirdwood@gmail.com>
M: Mark Brown <broonie@kernel.org>
W: http://opensource.wolfsonmicro.com/node/15
W: http://www.slimlogic.co.uk/?p=48
+14 -13
View File
@@ -97,6 +97,19 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
static struct regulator_consumer_supply max8952_consumer =
REGULATOR_SUPPLY("vdd_arm", NULL);
static struct regulator_init_data universal_max8952_reg_data = {
.constraints = {
.name = "VARM_1.2V",
.min_uV = 770000,
.max_uV = 1400000,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
.boot_on = 1,
},
.num_consumer_supplies = 1,
.consumer_supplies = &max8952_consumer,
};
static struct max8952_platform_data universal_max8952_pdata __initdata = {
.gpio_vid0 = EXYNOS4_GPX0(3),
.gpio_vid1 = EXYNOS4_GPX0(4),
@@ -105,19 +118,7 @@ static struct max8952_platform_data universal_max8952_pdata __initdata = {
.dvs_mode = { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */
.sync_freq = 0, /* default: fastest */
.ramp_speed = 0, /* default: fastest */
.reg_data = {
.constraints = {
.name = "VARM_1.2V",
.min_uV = 770000,
.max_uV = 1400000,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
.boot_on = 1,
},
.num_consumer_supplies = 1,
.consumer_supplies = &max8952_consumer,
},
.reg_data = &universal_max8952_reg_data,
};
static struct regulator_consumer_supply lp3974_buck1_consumer =
File diff suppressed because it is too large Load Diff
@@ -14,10 +14,11 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/ab8500.h>
extern struct ab8500_regulator_reg_init
ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS];
extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS];
extern struct ab8500_regulator_platform_data ab8500_regulator_plat_data;
extern struct ab8500_regulator_platform_data ab8505_regulator_plat_data;
extern struct regulator_init_data tps61052_regulator;
extern struct regulator_init_data gpio_en_3v3_regulator;
void mop500_regulator_init(void);
#endif
+1 -4
View File
@@ -199,10 +199,7 @@ static struct platform_device snowball_sbnet_dev = {
struct ab8500_platform_data ab8500_platdata = {
.irq_base = MOP500_AB8500_IRQ_BASE,
.regulator_reg_init = ab8500_regulator_reg_init,
.num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init),
.regulator = ab8500_regulators,
.num_regulator = ARRAY_SIZE(ab8500_regulators),
.regulator = &ab8500_regulator_plat_data,
.gpio = &ab8500_gpio_pdata,
.codec = &ab8500_codec_pdata,
};
+1
View File
@@ -753,6 +753,7 @@ static struct mfd_cell ab3100_devs[] = {
},
{
.name = "ab3100-regulators",
.of_compatible = "stericsson,ab3100-regulators",
.id = -1,
},
{
+4 -32
View File
@@ -220,35 +220,6 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
return ret;
}
static int pm8606_preg_enable(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
1 << rdev->desc->enable_mask, 0);
}
static int pm8606_preg_disable(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
1 << rdev->desc->enable_mask,
1 << rdev->desc->enable_mask);
}
static int pm8606_preg_is_enabled(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
int ret;
ret = pm860x_reg_read(info->i2c, rdev->desc->enable_reg);
if (ret < 0)
return ret;
return !((unsigned char)ret & (1 << rdev->desc->enable_mask));
}
static struct regulator_ops pm8607_regulator_ops = {
.list_voltage = pm8607_list_voltage,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
@@ -259,9 +230,9 @@ static struct regulator_ops pm8607_regulator_ops = {
};
static struct regulator_ops pm8606_preg_ops = {
.enable = pm8606_preg_enable,
.disable = pm8606_preg_disable,
.is_enabled = pm8606_preg_is_enabled,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
#define PM8606_PREG(ereg, ebit) \
@@ -274,6 +245,7 @@ static struct regulator_ops pm8606_preg_ops = {
.owner = THIS_MODULE, \
.enable_reg = PM8606_##ereg, \
.enable_mask = (ebit), \
.enable_is_inverted = true, \
}, \
}
+1 -1
View File
@@ -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
obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o ab8500-ext.o
obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
+186 -50
View File
@@ -17,6 +17,8 @@
#include <linux/regulator/driver.h>
#include <linux/mfd/ab3100.h>
#include <linux/mfd/abx500.h>
#include <linux/of.h>
#include <linux/regulator/of_regulator.h>
/* LDO registers and some handy masking definitions for AB3100 */
#define AB3100_LDO_A 0x40
@@ -345,7 +347,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
{
struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
return abreg->plfdata->external_voltage;
if (abreg->plfdata)
return abreg->plfdata->external_voltage;
else
/* TODO: encode external voltage into device tree */
return 0;
}
static struct regulator_ops regulator_ops_fixed = {
@@ -488,16 +494,174 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
},
};
static int ab3100_regulator_register(struct platform_device *pdev,
struct ab3100_platform_data *plfdata,
struct regulator_init_data *init_data,
struct device_node *np,
int id)
{
struct regulator_desc *desc;
struct ab3100_regulator *reg;
struct regulator_dev *rdev;
struct regulator_config config = { };
int err, i;
for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
desc = &ab3100_regulator_desc[i];
if (desc->id == id)
break;
}
if (desc->id != id)
return -ENODEV;
/* Same index used for this array */
reg = &ab3100_regulators[i];
/*
* Initialize per-regulator struct.
* Inherit platform data, this comes down from the
* i2c boarddata, from the machine. So if you want to
* see what it looks like for a certain machine, go
* into the machine I2C setup.
*/
reg->dev = &pdev->dev;
if (plfdata) {
reg->plfdata = plfdata;
config.init_data = &plfdata->reg_constraints[i];
} else if (np) {
config.of_node = np;
config.init_data = init_data;
}
config.dev = &pdev->dev;
config.driver_data = reg;
rdev = regulator_register(desc, &config);
if (IS_ERR(rdev)) {
err = PTR_ERR(rdev);
dev_err(&pdev->dev,
"%s: failed to register regulator %s err %d\n",
__func__, desc->name,
err);
return err;
}
/* Then set a pointer back to the registered regulator */
reg->rdev = rdev;
return 0;
}
static struct of_regulator_match ab3100_regulator_matches[] = {
{ .name = "ab3100_ldo_a", .driver_data = (void *) AB3100_LDO_A, },
{ .name = "ab3100_ldo_c", .driver_data = (void *) AB3100_LDO_C, },
{ .name = "ab3100_ldo_d", .driver_data = (void *) AB3100_LDO_D, },
{ .name = "ab3100_ldo_e", .driver_data = (void *) AB3100_LDO_E, },
{ .name = "ab3100_ldo_f", .driver_data = (void *) AB3100_LDO_F },
{ .name = "ab3100_ldo_g", .driver_data = (void *) AB3100_LDO_G },
{ .name = "ab3100_ldo_h", .driver_data = (void *) AB3100_LDO_H },
{ .name = "ab3100_ldo_k", .driver_data = (void *) AB3100_LDO_K },
{ .name = "ab3100_ext", .driver_data = (void *) AB3100_LDO_EXT },
{ .name = "ab3100_buck", .driver_data = (void *) AB3100_BUCK },
};
/*
* NOTE: the following functions are regulators pluralis - it is the
* binding to the AB3100 core driver and the parent platform device
* for all the different regulators.
* Initial settings of ab3100 registers.
* Common for below LDO regulator settings are that
* bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0).
* Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode.
*/
/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */
#define LDO_A_SETTING 0x16
/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */
#define LDO_C_SETTING 0x10
/* LDO_D 0x10: 2.65V, ON, sleep mode not used */
#define LDO_D_SETTING 0x10
/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */
#define LDO_E_SETTING 0x10
/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */
#define LDO_E_SLEEP_SETTING 0x00
/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */
#define LDO_F_SETTING 0xD0
/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */
#define LDO_G_SETTING 0x00
/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */
#define LDO_H_SETTING 0x18
/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */
#define LDO_K_SETTING 0x00
/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */
#define LDO_EXT_SETTING 0x00
/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */
#define BUCK_SETTING 0x7D
/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */
#define BUCK_SLEEP_SETTING 0xAC
static const u8 ab3100_reg_initvals[] = {
LDO_A_SETTING,
LDO_C_SETTING,
LDO_E_SETTING,
LDO_E_SLEEP_SETTING,
LDO_F_SETTING,
LDO_G_SETTING,
LDO_H_SETTING,
LDO_K_SETTING,
LDO_EXT_SETTING,
BUCK_SETTING,
BUCK_SLEEP_SETTING,
LDO_D_SETTING,
};
static int ab3100_regulators_remove(struct platform_device *pdev)
{
int i;
for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
struct ab3100_regulator *reg = &ab3100_regulators[i];
regulator_unregister(reg->rdev);
reg->rdev = NULL;
}
return 0;
}
static int
ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
{
int err, i;
/*
* Set up the regulator registers, as was previously done with
* platform data.
*/
/* Set up regulators */
for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
err = abx500_set_register_interruptible(&pdev->dev, 0,
ab3100_reg_init_order[i],
ab3100_reg_initvals[i]);
if (err) {
dev_err(&pdev->dev, "regulator initialization failed with error %d\n",
err);
return err;
}
}
for (i = 0; i < ARRAY_SIZE(ab3100_regulator_matches); i++) {
err = ab3100_regulator_register(
pdev, NULL, ab3100_regulator_matches[i].init_data,
ab3100_regulator_matches[i].of_node,
(int) ab3100_regulator_matches[i].driver_data);
if (err) {
ab3100_regulators_remove(pdev);
return err;
}
}
return 0;
}
static int ab3100_regulators_probe(struct platform_device *pdev)
{
struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
struct regulator_config config = { };
struct device_node *np = pdev->dev.of_node;
int err = 0;
u8 data;
int i;
@@ -516,6 +680,18 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
dev_notice(&pdev->dev,
"chip is in inactive mode (Cold start)\n");
if (np) {
err = of_regulator_match(&pdev->dev, np,
ab3100_regulator_matches,
ARRAY_SIZE(ab3100_regulator_matches));
if (err < 0) {
dev_err(&pdev->dev,
"Error parsing regulator init data: %d\n", err);
return err;
}
return ab3100_regulator_of_probe(pdev, np);
}
/* Set up regulators */
for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
err = abx500_set_register_interruptible(&pdev->dev, 0,
@@ -530,59 +706,19 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
/* Register the regulators */
for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
struct ab3100_regulator *reg = &ab3100_regulators[i];
struct regulator_dev *rdev;
struct regulator_desc *desc = &ab3100_regulator_desc[i];
/*
* Initialize per-regulator struct.
* Inherit platform data, this comes down from the
* i2c boarddata, from the machine. So if you want to
* see what it looks like for a certain machine, go
* into the machine I2C setup.
*/
reg->dev = &pdev->dev;
reg->plfdata = plfdata;
config.dev = &pdev->dev;
config.driver_data = reg;
config.init_data = &plfdata->reg_constraints[i];
/*
* Register the regulator, pass around
* the ab3100_regulator struct
*/
rdev = regulator_register(&ab3100_regulator_desc[i], &config);
if (IS_ERR(rdev)) {
err = PTR_ERR(rdev);
dev_err(&pdev->dev,
"%s: failed to register regulator %s err %d\n",
__func__, ab3100_regulator_desc[i].name,
err);
/* remove the already registered regulators */
while (--i >= 0)
regulator_unregister(ab3100_regulators[i].rdev);
err = ab3100_regulator_register(pdev, plfdata, NULL, NULL,
desc->id);
if (err) {
ab3100_regulators_remove(pdev);
return err;
}
/* Then set a pointer back to the registered regulator */
reg->rdev = rdev;
}
return 0;
}
static int ab3100_regulators_remove(struct platform_device *pdev)
{
int i;
for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
struct ab3100_regulator *reg = &ab3100_regulators[i];
regulator_unregister(reg->rdev);
}
return 0;
}
static struct platform_driver ab3100_regulators_driver = {
.driver = {
.name = "ab3100-regulators",
+407
View File
@@ -0,0 +1,407 @@
/*
* Copyright (C) ST-Ericsson SA 2010
*
* License Terms: GNU General Public License v2
*
* Authors: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
*
* This file is based on drivers/regulator/ab8500.c
*
* AB8500 external regulators
*
* ab8500-ext supports the following regulators:
* - VextSupply3
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/regulator/ab8500.h>
/**
* struct ab8500_ext_regulator_info - ab8500 regulator information
* @dev: device pointer
* @desc: regulator description
* @rdev: regulator device
* @cfg: regulator configuration (extension of regulator FW configuration)
* @update_bank: bank to control on/off
* @update_reg: register to control on/off
* @update_mask: mask to enable/disable and set mode of regulator
* @update_val: bits holding the regulator current mode
* @update_val_hp: bits to set EN pin active (LPn pin deactive)
* normally this means high power mode
* @update_val_lp: bits to set EN pin active and LPn pin active
* normally this means low power mode
* @update_val_hw: bits to set regulator pins in HW control
* SysClkReq pins and logic will choose mode
*/
struct ab8500_ext_regulator_info {
struct device *dev;
struct regulator_desc desc;
struct regulator_dev *rdev;
struct ab8500_ext_regulator_cfg *cfg;
u8 update_bank;
u8 update_reg;
u8 update_mask;
u8 update_val;
u8 update_val_hp;
u8 update_val_lp;
u8 update_val_hw;
};
static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
{
int ret;
struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
u8 regval;
if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
return -EINVAL;
}
/*
* To satisfy both HW high power request and SW request, the regulator
* must be on in high power.
*/
if (info->cfg && info->cfg->hwreq)
regval = info->update_val_hp;
else
regval = info->update_val;
ret = abx500_mask_and_set_register_interruptible(info->dev,
info->update_bank, info->update_reg,
info->update_mask, regval);
if (ret < 0) {
dev_err(rdev_get_dev(info->rdev),
"couldn't set enable bits for regulator\n");
return ret;
}
dev_dbg(rdev_get_dev(rdev),
"%s-enable (bank, reg, mask, value): 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
info->desc.name, info->update_bank, info->update_reg,
info->update_mask, regval);
return 0;
}
static int ab8500_ext_regulator_disable(struct regulator_dev *rdev)
{
int ret;
struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
u8 regval;
if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
return -EINVAL;
}
/*
* Set the regulator in HW request mode if configured
*/
if (info->cfg && info->cfg->hwreq)
regval = info->update_val_hw;
else
regval = 0;
ret = abx500_mask_and_set_register_interruptible(info->dev,
info->update_bank, info->update_reg,
info->update_mask, regval);
if (ret < 0) {
dev_err(rdev_get_dev(info->rdev),
"couldn't set disable bits for regulator\n");
return ret;
}
dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):"
" 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
info->desc.name, info->update_bank, info->update_reg,
info->update_mask, regval);
return 0;
}
static int ab8500_ext_regulator_is_enabled(struct regulator_dev *rdev)
{
int ret;
struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
u8 regval;
if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
return -EINVAL;
}
ret = abx500_get_register_interruptible(info->dev,
info->update_bank, info->update_reg, &regval);
if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"couldn't read 0x%x register\n", info->update_reg);
return ret;
}
dev_dbg(rdev_get_dev(rdev), "%s-is_enabled (bank, reg, mask, value):"
" 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
info->desc.name, info->update_bank, info->update_reg,
info->update_mask, regval);
if (((regval & info->update_mask) == info->update_val_lp) ||
((regval & info->update_mask) == info->update_val_hp))
return 1;
else
return 0;
}
static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
int ret = 0;
struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
u8 regval;
if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
return -EINVAL;
}
switch (mode) {
case REGULATOR_MODE_NORMAL:
regval = info->update_val_hp;
break;
case REGULATOR_MODE_IDLE:
regval = info->update_val_lp;
break;
default:
return -EINVAL;
}
/* If regulator is enabled and info->cfg->hwreq is set, the regulator
must be on in high power, so we don't need to write the register with
the same value.
*/
if (ab8500_ext_regulator_is_enabled(rdev) &&
!(info->cfg && info->cfg->hwreq)) {
ret = abx500_mask_and_set_register_interruptible(info->dev,
info->update_bank, info->update_reg,
info->update_mask, regval);
if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"Could not set regulator mode.\n");
return ret;
}
dev_dbg(rdev_get_dev(rdev),
"%s-set_mode (bank, reg, mask, value): "
"0x%x, 0x%x, 0x%x, 0x%x\n",
info->desc.name, info->update_bank, info->update_reg,
info->update_mask, regval);
}
info->update_val = regval;
return 0;
}
static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev)
{
struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
int ret;
if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
return -EINVAL;
}
if (info->update_val == info->update_val_hp)
ret = REGULATOR_MODE_NORMAL;
else if (info->update_val == info->update_val_lp)
ret = REGULATOR_MODE_IDLE;
else
ret = -EINVAL;
return ret;
}
static int ab8500_ext_list_voltage(struct regulator_dev *rdev,
unsigned selector)
{
struct regulation_constraints *regu_constraints = rdev->constraints;
if (regu_constraints == NULL) {
dev_err(rdev_get_dev(rdev), "regulator constraints null pointer\n");
return -EINVAL;
}
/* return the uV for the fixed regulators */
if (regu_constraints->min_uV && regu_constraints->max_uV) {
if (regu_constraints->min_uV == regu_constraints->max_uV)
return regu_constraints->min_uV;
}
return -EINVAL;
}
static struct regulator_ops ab8500_ext_regulator_ops = {
.enable = ab8500_ext_regulator_enable,
.disable = ab8500_ext_regulator_disable,
.is_enabled = ab8500_ext_regulator_is_enabled,
.set_mode = ab8500_ext_regulator_set_mode,
.get_mode = ab8500_ext_regulator_get_mode,
.list_voltage = ab8500_ext_list_voltage,
};
static struct ab8500_ext_regulator_info
ab8500_ext_regulator_info[AB8500_NUM_EXT_REGULATORS] = {
[AB8500_EXT_SUPPLY1] = {
.desc = {
.name = "VEXTSUPPLY1",
.ops = &ab8500_ext_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_EXT_SUPPLY1,
.owner = THIS_MODULE,
.n_voltages = 1,
},
.update_bank = 0x04,
.update_reg = 0x08,
.update_mask = 0x03,
.update_val = 0x01,
.update_val_hp = 0x01,
.update_val_lp = 0x03,
.update_val_hw = 0x02,
},
[AB8500_EXT_SUPPLY2] = {
.desc = {
.name = "VEXTSUPPLY2",
.ops = &ab8500_ext_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_EXT_SUPPLY2,
.owner = THIS_MODULE,
.n_voltages = 1,
},
.update_bank = 0x04,
.update_reg = 0x08,
.update_mask = 0x0c,
.update_val = 0x04,
.update_val_hp = 0x04,
.update_val_lp = 0x0c,
.update_val_hw = 0x08,
},
[AB8500_EXT_SUPPLY3] = {
.desc = {
.name = "VEXTSUPPLY3",
.ops = &ab8500_ext_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_EXT_SUPPLY3,
.owner = THIS_MODULE,
.n_voltages = 1,
},
.update_bank = 0x04,
.update_reg = 0x08,
.update_mask = 0x30,
.update_val = 0x10,
.update_val_hp = 0x10,
.update_val_lp = 0x30,
.update_val_hw = 0x20,
},
};
int ab8500_ext_regulator_init(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 regulator_config config = { };
int i, 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");
return -EINVAL;
}
pdata = ppdata->regulator;
if (!pdata) {
dev_err(&pdev->dev, "null pdata\n");
return -EINVAL;
}
/* make sure the platform data has the correct size */
if (pdata->num_ext_regulator != ARRAY_SIZE(ab8500_ext_regulator_info)) {
dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
return -EINVAL;
}
/* check for AB8500 2.x */
if (is_ab8500_2p0_or_earlier(ab8500)) {
struct ab8500_ext_regulator_info *info;
/* VextSupply3LPn is inverted on AB8500 2.x */
info = &ab8500_ext_regulator_info[AB8500_EXT_SUPPLY3];
info->update_val = 0x30;
info->update_val_hp = 0x30;
info->update_val_lp = 0x10;
}
/* register all regulators */
for (i = 0; i < ARRAY_SIZE(ab8500_ext_regulator_info); i++) {
struct ab8500_ext_regulator_info *info = NULL;
/* assign per-regulator data */
info = &ab8500_ext_regulator_info[i];
info->dev = &pdev->dev;
info->cfg = (struct ab8500_ext_regulator_cfg *)
pdata->ext_regulator[i].driver_data;
config.dev = &pdev->dev;
config.init_data = &pdata->ext_regulator[i];
config.driver_data = info;
/* register regulator with framework */
info->rdev = regulator_register(&info->desc, &config);
if (IS_ERR(info->rdev)) {
err = PTR_ERR(info->rdev);
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);
/* when we fail, un-register all earlier regulators */
while (--i >= 0) {
info = &ab8500_ext_regulator_info[i];
regulator_unregister(info->rdev);
}
return err;
}
dev_dbg(rdev_get_dev(info->rdev),
"%s-probed\n", info->desc.name);
}
return 0;
}
void ab8500_ext_regulator_exit(struct platform_device *pdev)
{
int i;
for (i = 0; i < ARRAY_SIZE(ab8500_ext_regulator_info); i++) {
struct ab8500_ext_regulator_info *info = NULL;
info = &ab8500_ext_regulator_info[i];
dev_vdbg(rdev_get_dev(info->rdev),
"%s-remove\n", info->desc.name);
regulator_unregister(info->rdev);
}
}
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
MODULE_DESCRIPTION("AB8500 external regulator driver");
MODULE_ALIAS("platform:ab8500-ext-regulator");
+2520 -148
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -131,7 +131,7 @@ static const struct regulator_desc arizona_ldo1_hc = {
.min_uV = 900000,
.uV_step = 50000,
.n_voltages = 8,
.enable_time = 500,
.enable_time = 1500,
.owner = THIS_MODULE,
};
+64 -3
View File
@@ -13,9 +13,11 @@
#include <linux/init.h>
#include <linux/mfd/as3711.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
struct as3711_regulator_info {
@@ -276,6 +278,53 @@ static struct as3711_regulator_info as3711_reg_info[] = {
#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info)
static struct of_regulator_match
as3711_regulator_matches[AS3711_REGULATOR_NUM] = {
[AS3711_REGULATOR_SD_1] = { .name = "sd1" },
[AS3711_REGULATOR_SD_2] = { .name = "sd2" },
[AS3711_REGULATOR_SD_3] = { .name = "sd3" },
[AS3711_REGULATOR_SD_4] = { .name = "sd4" },
[AS3711_REGULATOR_LDO_1] = { .name = "ldo1" },
[AS3711_REGULATOR_LDO_2] = { .name = "ldo2" },
[AS3711_REGULATOR_LDO_3] = { .name = "ldo3" },
[AS3711_REGULATOR_LDO_4] = { .name = "ldo4" },
[AS3711_REGULATOR_LDO_5] = { .name = "ldo5" },
[AS3711_REGULATOR_LDO_6] = { .name = "ldo6" },
[AS3711_REGULATOR_LDO_7] = { .name = "ldo7" },
[AS3711_REGULATOR_LDO_8] = { .name = "ldo8" },
};
static int as3711_regulator_parse_dt(struct device *dev,
struct device_node **of_node, const int count)
{
struct as3711_regulator_pdata *pdata = dev_get_platdata(dev);
struct device_node *regulators =
of_find_node_by_name(dev->parent->of_node, "regulators");
struct of_regulator_match *match;
int ret, i;
if (!regulators) {
dev_err(dev, "regulator node not found\n");
return -ENODEV;
}
ret = of_regulator_match(dev->parent, regulators,
as3711_regulator_matches, count);
of_node_put(regulators);
if (ret < 0) {
dev_err(dev, "Error parsing regulator init data: %d\n", ret);
return ret;
}
for (i = 0, match = as3711_regulator_matches; i < count; i++, match++)
if (match->of_node) {
pdata->init_data[i] = match->init_data;
of_node[i] = match->of_node;
}
return 0;
}
static int as3711_regulator_probe(struct platform_device *pdev)
{
struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev);
@@ -284,13 +333,24 @@ static int as3711_regulator_probe(struct platform_device *pdev)
struct regulator_config config = {.dev = &pdev->dev,};
struct as3711_regulator *reg = NULL;
struct as3711_regulator *regs;
struct device_node *of_node[AS3711_REGULATOR_NUM] = {};
struct regulator_dev *rdev;
struct as3711_regulator_info *ri;
int ret;
int id;
if (!pdata)
dev_dbg(&pdev->dev, "No platform data...\n");
if (!pdata) {
dev_err(&pdev->dev, "No platform data...\n");
return -ENODEV;
}
if (pdev->dev.parent->of_node) {
ret = as3711_regulator_parse_dt(&pdev->dev, of_node, AS3711_REGULATOR_NUM);
if (ret < 0) {
dev_err(&pdev->dev, "DT parsing failed: %d\n", ret);
return ret;
}
}
regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM *
sizeof(struct as3711_regulator), GFP_KERNEL);
@@ -300,7 +360,7 @@ static int as3711_regulator_probe(struct platform_device *pdev)
}
for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) {
reg_data = pdata ? pdata->init_data[id] : NULL;
reg_data = pdata->init_data[id];
/* No need to register if there is no regulator data */
if (!reg_data)
@@ -312,6 +372,7 @@ static int as3711_regulator_probe(struct platform_device *pdev)
config.init_data = reg_data;
config.driver_data = reg;
config.regmap = as3711->regmap;
config.of_node = of_node[id];
rdev = regulator_register(&ri->desc, &config);
if (IS_ERR(rdev)) {
+194 -26
View File
@@ -51,6 +51,7 @@
static DEFINE_MUTEX(regulator_list_mutex);
static LIST_HEAD(regulator_list);
static LIST_HEAD(regulator_map_list);
static LIST_HEAD(regulator_ena_gpio_list);
static bool has_full_constraints;
static bool board_wants_dummy_regulator;
@@ -68,6 +69,19 @@ struct regulator_map {
struct regulator_dev *regulator;
};
/*
* struct regulator_enable_gpio
*
* Management for shared enable GPIO pin
*/
struct regulator_enable_gpio {
struct list_head list;
int gpio;
u32 enable_count; /* a number of enabled shared GPIO */
u32 request_count; /* a number of requested shared GPIO */
unsigned int ena_gpio_invert:1;
};
/*
* struct regulator
*
@@ -116,7 +130,7 @@ static const char *rdev_get_name(struct regulator_dev *rdev)
* @supply: regulator supply name
*
* Extract the regulator device node corresponding to the supply name.
* retruns the device node corresponding to the regulator if found, else
* returns the device node corresponding to the regulator if found, else
* returns NULL.
*/
static struct device_node *of_get_regulator(struct device *dev, const char *supply)
@@ -1229,7 +1243,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
struct regulator_dev *rdev;
struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
const char *devname = NULL;
int ret;
int ret = 0;
if (id == NULL) {
pr_err("get() with no identifier\n");
@@ -1245,6 +1259,15 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
if (rdev)
goto found;
/*
* If we have return value from dev_lookup fail, we do not expect to
* succeed, so, quit with appropriate error value
*/
if (ret) {
regulator = ERR_PTR(ret);
goto out;
}
if (board_wants_dummy_regulator) {
rdev = dummy_regulator_rdev;
goto found;
@@ -1456,6 +1479,101 @@ void devm_regulator_put(struct regulator *regulator)
}
EXPORT_SYMBOL_GPL(devm_regulator_put);
/* Manage enable GPIO list. Same GPIO pin can be shared among regulators */
static int regulator_ena_gpio_request(struct regulator_dev *rdev,
const struct regulator_config *config)
{
struct regulator_enable_gpio *pin;
int ret;
list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
if (pin->gpio == config->ena_gpio) {
rdev_dbg(rdev, "GPIO %d is already used\n",
config->ena_gpio);
goto update_ena_gpio_to_rdev;
}
}
ret = gpio_request_one(config->ena_gpio,
GPIOF_DIR_OUT | config->ena_gpio_flags,
rdev_get_name(rdev));
if (ret)
return ret;
pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL);
if (pin == NULL) {
gpio_free(config->ena_gpio);
return -ENOMEM;
}
pin->gpio = config->ena_gpio;
pin->ena_gpio_invert = config->ena_gpio_invert;
list_add(&pin->list, &regulator_ena_gpio_list);
update_ena_gpio_to_rdev:
pin->request_count++;
rdev->ena_pin = pin;
return 0;
}
static void regulator_ena_gpio_free(struct regulator_dev *rdev)
{
struct regulator_enable_gpio *pin, *n;
if (!rdev->ena_pin)
return;
/* Free the GPIO only in case of no use */
list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) {
if (pin->gpio == rdev->ena_pin->gpio) {
if (pin->request_count <= 1) {
pin->request_count = 0;
gpio_free(pin->gpio);
list_del(&pin->list);
kfree(pin);
} else {
pin->request_count--;
}
}
}
}
/**
* Balance enable_count of each GPIO and actual GPIO pin control.
* GPIO is enabled in case of initial use. (enable_count is 0)
* GPIO is disabled when it is not shared any more. (enable_count <= 1)
*/
static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
{
struct regulator_enable_gpio *pin = rdev->ena_pin;
if (!pin)
return -EINVAL;
if (enable) {
/* Enable GPIO at initial use */
if (pin->enable_count == 0)
gpio_set_value_cansleep(pin->gpio,
!pin->ena_gpio_invert);
pin->enable_count++;
} else {
if (pin->enable_count > 1) {
pin->enable_count--;
return 0;
}
/* Disable GPIO if not used */
if (pin->enable_count <= 1) {
gpio_set_value_cansleep(pin->gpio,
pin->ena_gpio_invert);
pin->enable_count = 0;
}
}
return 0;
}
static int _regulator_do_enable(struct regulator_dev *rdev)
{
int ret, delay;
@@ -1471,9 +1589,10 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
trace_regulator_enable(rdev_get_name(rdev));
if (rdev->ena_gpio) {
gpio_set_value_cansleep(rdev->ena_gpio,
!rdev->ena_gpio_invert);
if (rdev->ena_pin) {
ret = regulator_ena_gpio_ctrl(rdev, true);
if (ret < 0)
return ret;
rdev->ena_gpio_state = 1;
} else if (rdev->desc->ops->enable) {
ret = rdev->desc->ops->enable(rdev);
@@ -1575,9 +1694,10 @@ static int _regulator_do_disable(struct regulator_dev *rdev)
trace_regulator_disable(rdev_get_name(rdev));
if (rdev->ena_gpio) {
gpio_set_value_cansleep(rdev->ena_gpio,
rdev->ena_gpio_invert);
if (rdev->ena_pin) {
ret = regulator_ena_gpio_ctrl(rdev, false);
if (ret < 0)
return ret;
rdev->ena_gpio_state = 0;
} else if (rdev->desc->ops->disable) {
@@ -1794,7 +1914,10 @@ int regulator_is_enabled_regmap(struct regulator_dev *rdev)
if (ret != 0)
return ret;
return (val & rdev->desc->enable_mask) != 0;
if (rdev->desc->enable_is_inverted)
return (val & rdev->desc->enable_mask) == 0;
else
return (val & rdev->desc->enable_mask) != 0;
}
EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
@@ -1809,9 +1932,15 @@ EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
*/
int regulator_enable_regmap(struct regulator_dev *rdev)
{
unsigned int val;
if (rdev->desc->enable_is_inverted)
val = 0;
else
val = rdev->desc->enable_mask;
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask,
rdev->desc->enable_mask);
rdev->desc->enable_mask, val);
}
EXPORT_SYMBOL_GPL(regulator_enable_regmap);
@@ -1826,15 +1955,22 @@ EXPORT_SYMBOL_GPL(regulator_enable_regmap);
*/
int regulator_disable_regmap(struct regulator_dev *rdev)
{
unsigned int val;
if (rdev->desc->enable_is_inverted)
val = rdev->desc->enable_mask;
else
val = 0;
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, 0);
rdev->desc->enable_mask, val);
}
EXPORT_SYMBOL_GPL(regulator_disable_regmap);
static int _regulator_is_enabled(struct regulator_dev *rdev)
{
/* A GPIO control always takes precedence */
if (rdev->ena_gpio)
if (rdev->ena_pin)
return rdev->ena_gpio_state;
/* If we don't know then assume that the regulator is always on */
@@ -2137,6 +2273,37 @@ int regulator_map_voltage_iterate(struct regulator_dev *rdev,
}
EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);
/**
* regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
* @max_uV: Upper bound for voltage
*
* Drivers that have ascendant voltage list can use this as their
* map_voltage() operation.
*/
int regulator_map_voltage_ascend(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
int i, ret;
for (i = 0; i < rdev->desc->n_voltages; i++) {
ret = rdev->desc->ops->list_voltage(rdev, i);
if (ret < 0)
continue;
if (ret > max_uV)
break;
if (ret >= min_uV && ret <= max_uV)
return i;
}
return -EINVAL;
}
EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend);
/**
* regulator_map_voltage_linear - map_voltage() for simple linear mappings
*
@@ -3237,7 +3404,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
if (status < 0)
return status;
}
if (rdev->ena_gpio || ops->is_enabled) {
if (rdev->ena_pin || ops->is_enabled) {
status = device_create_file(dev, &dev_attr_state);
if (status < 0)
return status;
@@ -3439,22 +3606,17 @@ regulator_register(const struct regulator_desc *regulator_desc,
dev_set_drvdata(&rdev->dev, rdev);
if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) {
ret = gpio_request_one(config->ena_gpio,
GPIOF_DIR_OUT | config->ena_gpio_flags,
rdev_get_name(rdev));
ret = regulator_ena_gpio_request(rdev, config);
if (ret != 0) {
rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
config->ena_gpio, ret);
goto wash;
}
rdev->ena_gpio = config->ena_gpio;
rdev->ena_gpio_invert = config->ena_gpio_invert;
if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH)
rdev->ena_gpio_state = 1;
if (rdev->ena_gpio_invert)
if (config->ena_gpio_invert)
rdev->ena_gpio_state = !rdev->ena_gpio_state;
}
@@ -3481,7 +3643,14 @@ regulator_register(const struct regulator_desc *regulator_desc,
r = regulator_dev_lookup(dev, supply, &ret);
if (!r) {
if (ret == -ENODEV) {
/*
* No supply was specified for this regulator and
* there will never be one.
*/
ret = 0;
goto add_dev;
} else if (!r) {
dev_err(dev, "Failed to find supply %s\n", supply);
ret = -EPROBE_DEFER;
goto scrub;
@@ -3499,6 +3668,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
}
}
add_dev:
/* add consumers devices */
if (init_data) {
for (i = 0; i < init_data->num_consumer_supplies; i++) {
@@ -3526,8 +3696,7 @@ unset_supplies:
scrub:
if (rdev->supply)
_regulator_put(rdev->supply);
if (rdev->ena_gpio)
gpio_free(rdev->ena_gpio);
regulator_ena_gpio_free(rdev);
kfree(rdev->constraints);
wash:
device_unregister(&rdev->dev);
@@ -3562,8 +3731,7 @@ void regulator_unregister(struct regulator_dev *rdev)
unset_regulator_supplies(rdev);
list_del(&rdev->list);
kfree(rdev->constraints);
if (rdev->ena_gpio)
gpio_free(rdev->ena_gpio);
regulator_ena_gpio_free(rdev);
device_unregister(&rdev->dev);
mutex_unlock(&regulator_list_mutex);
}
-2
View File
@@ -21,7 +21,6 @@
* @is_enabled: status of the regulator
* @epod_id: id for EPOD (power domain)
* @is_ramret: RAM retention switch for EPOD (power domain)
* @operating_point: operating point (only for vape, to be removed)
*
*/
struct dbx500_regulator_info {
@@ -32,7 +31,6 @@ struct dbx500_regulator_info {
u16 epod_id;
bool is_ramret;
bool exclude_from_power_state;
unsigned int operating_point;
};
void power_state_active_enable(void);
+1 -3
View File
@@ -219,9 +219,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
rdesc->owner = THIS_MODULE;
di->rdev = regulator_register(&di->desc, config);
if (IS_ERR(di->rdev))
return PTR_ERR(di->rdev);
return 0;
return PTR_RET(di->rdev);
}
+2
View File
@@ -163,6 +163,7 @@ static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev,
static struct regulator_ops lp3971_ldo_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.is_enabled = lp3971_ldo_is_enabled,
.enable = lp3971_ldo_enable,
.disable = lp3971_ldo_disable,
@@ -236,6 +237,7 @@ static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev,
static struct regulator_ops lp3971_dcdc_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.is_enabled = lp3971_dcdc_is_enabled,
.enable = lp3971_dcdc_enable,
.disable = lp3971_dcdc_disable,
+2
View File
@@ -309,6 +309,7 @@ static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev,
static struct regulator_ops lp3972_ldo_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.is_enabled = lp3972_ldo_is_enabled,
.enable = lp3972_ldo_enable,
.disable = lp3972_ldo_disable,
@@ -389,6 +390,7 @@ static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev,
static struct regulator_ops lp3972_dcdc_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.is_enabled = lp3972_dcdc_is_enabled,
.enable = lp3972_dcdc_enable,
.disable = lp3972_dcdc_disable,

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