Merge remote-tracking branches 'regulator/topic/core', 'regulator/topic/regmap' and 'regulator/topic/register' into regulator-next
This commit is contained in:
Коммит
178e43aef2
|
@ -11,8 +11,7 @@ Registration
|
|||
Drivers can register a regulator by calling :-
|
||||
|
||||
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
||||
struct device *dev, struct regulator_init_data *init_data,
|
||||
void *driver_data, struct device_node *of_node);
|
||||
const struct regulator_config *config);
|
||||
|
||||
This will register the regulators capabilities and operations to the regulator
|
||||
core.
|
||||
|
|
|
@ -78,17 +78,6 @@ static struct mfd_cell tps65090s[] = {
|
|||
},
|
||||
};
|
||||
|
||||
struct tps65090 {
|
||||
struct mutex lock;
|
||||
struct device *dev;
|
||||
struct i2c_client *client;
|
||||
struct regmap *rmap;
|
||||
struct irq_chip irq_chip;
|
||||
struct mutex irq_lock;
|
||||
int irq_base;
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
int tps65090_write(struct device *dev, int reg, uint8_t val)
|
||||
{
|
||||
struct tps65090 *tps = dev_get_drvdata(dev);
|
||||
|
|
|
@ -27,13 +27,8 @@ struct pm8607_regulator_info {
|
|||
unsigned int *vol_table;
|
||||
unsigned int *vol_suspend;
|
||||
|
||||
int vol_reg;
|
||||
int vol_shift;
|
||||
int vol_nbits;
|
||||
int update_reg;
|
||||
int update_bit;
|
||||
int enable_reg;
|
||||
int enable_bit;
|
||||
int slope_double;
|
||||
};
|
||||
|
||||
|
@ -216,7 +211,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
|
|||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (info->vol_table && (index < (1 << info->vol_nbits))) {
|
||||
if (info->vol_table && (index < rdev->desc->n_voltages)) {
|
||||
ret = info->vol_table[index];
|
||||
if (info->slope_double)
|
||||
ret <<= 1;
|
||||
|
@ -224,51 +219,16 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
|
||||
static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
|
||||
{
|
||||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
int i, ret = -ENOENT;
|
||||
|
||||
if (info->slope_double) {
|
||||
min_uV = min_uV >> 1;
|
||||
max_uV = max_uV >> 1;
|
||||
}
|
||||
if (info->vol_table) {
|
||||
for (i = 0; i < (1 << info->vol_nbits); i++) {
|
||||
if (!info->vol_table[i])
|
||||
break;
|
||||
if ((min_uV <= info->vol_table[i])
|
||||
&& (max_uV >= info->vol_table[i])) {
|
||||
ret = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret < 0)
|
||||
pr_err("invalid voltage range (%d %d) uV\n", min_uV, max_uV);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pm8607_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
{
|
||||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
uint8_t val, mask;
|
||||
uint8_t val;
|
||||
int ret;
|
||||
|
||||
if (min_uV > max_uV) {
|
||||
pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
|
||||
return -EINVAL;
|
||||
}
|
||||
val = (uint8_t)(selector << (ffs(rdev->desc->vsel_mask) - 1));
|
||||
|
||||
ret = choose_voltage(rdev, min_uV, max_uV);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
*selector = ret;
|
||||
val = (uint8_t)(ret << info->vol_shift);
|
||||
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
|
||||
|
||||
ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val);
|
||||
ret = pm860x_set_bits(info->i2c, rdev->desc->vsel_reg,
|
||||
rdev->desc->vsel_mask, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
switch (info->desc.id) {
|
||||
|
@ -282,60 +242,16 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int pm8607_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
uint8_t val, mask;
|
||||
int ret;
|
||||
|
||||
ret = pm860x_reg_read(info->i2c, info->vol_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
|
||||
val = ((unsigned char)ret & mask) >> info->vol_shift;
|
||||
|
||||
return pm8607_list_voltage(rdev, val);
|
||||
}
|
||||
|
||||
static int pm8607_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
return pm860x_set_bits(info->i2c, info->enable_reg,
|
||||
1 << info->enable_bit,
|
||||
1 << info->enable_bit);
|
||||
}
|
||||
|
||||
static int pm8607_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
return pm860x_set_bits(info->i2c, info->enable_reg,
|
||||
1 << info->enable_bit, 0);
|
||||
}
|
||||
|
||||
static int pm8607_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
ret = pm860x_reg_read(info->i2c, info->enable_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return !!((unsigned char)ret & (1 << info->enable_bit));
|
||||
}
|
||||
|
||||
static struct regulator_ops pm8607_regulator_ops = {
|
||||
.set_voltage = pm8607_set_voltage,
|
||||
.get_voltage = pm8607_get_voltage,
|
||||
.enable = pm8607_enable,
|
||||
.disable = pm8607_disable,
|
||||
.is_enabled = pm8607_is_enabled,
|
||||
.list_voltage = pm8607_list_voltage,
|
||||
.set_voltage_sel = pm8607_set_voltage_sel,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
#define PM8607_DVC(vreg, nbits, ureg, ubit, ereg, ebit) \
|
||||
#define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \
|
||||
{ \
|
||||
.desc = { \
|
||||
.name = #vreg, \
|
||||
|
@ -343,20 +259,20 @@ static struct regulator_ops pm8607_regulator_ops = {
|
|||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = PM8607_ID_##vreg, \
|
||||
.owner = THIS_MODULE, \
|
||||
.n_voltages = ARRAY_SIZE(vreg##_table), \
|
||||
.vsel_reg = PM8607_##vreg, \
|
||||
.vsel_mask = ARRAY_SIZE(vreg##_table) - 1, \
|
||||
.enable_reg = PM8607_##ereg, \
|
||||
.enable_mask = 1 << (ebit), \
|
||||
}, \
|
||||
.vol_reg = PM8607_##vreg, \
|
||||
.vol_shift = (0), \
|
||||
.vol_nbits = (nbits), \
|
||||
.update_reg = PM8607_##ureg, \
|
||||
.update_bit = (ubit), \
|
||||
.enable_reg = PM8607_##ereg, \
|
||||
.enable_bit = (ebit), \
|
||||
.slope_double = (0), \
|
||||
.vol_table = (unsigned int *)&vreg##_table, \
|
||||
.vol_suspend = (unsigned int *)&vreg##_suspend_table, \
|
||||
}
|
||||
|
||||
#define PM8607_LDO(_id, vreg, shift, nbits, ereg, ebit) \
|
||||
#define PM8607_LDO(_id, vreg, shift, ereg, ebit) \
|
||||
{ \
|
||||
.desc = { \
|
||||
.name = "LDO" #_id, \
|
||||
|
@ -364,35 +280,35 @@ static struct regulator_ops pm8607_regulator_ops = {
|
|||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = PM8607_ID_LDO##_id, \
|
||||
.owner = THIS_MODULE, \
|
||||
.n_voltages = ARRAY_SIZE(LDO##_id##_table), \
|
||||
.vsel_reg = PM8607_##vreg, \
|
||||
.vsel_mask = (ARRAY_SIZE(LDO##_id##_table) - 1) << (shift), \
|
||||
.enable_reg = PM8607_##ereg, \
|
||||
.enable_mask = 1 << (ebit), \
|
||||
}, \
|
||||
.vol_reg = PM8607_##vreg, \
|
||||
.vol_shift = (shift), \
|
||||
.vol_nbits = (nbits), \
|
||||
.enable_reg = PM8607_##ereg, \
|
||||
.enable_bit = (ebit), \
|
||||
.slope_double = (0), \
|
||||
.vol_table = (unsigned int *)&LDO##_id##_table, \
|
||||
.vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \
|
||||
}
|
||||
|
||||
static struct pm8607_regulator_info pm8607_regulator_info[] = {
|
||||
PM8607_DVC(BUCK1, 6, GO, 0, SUPPLIES_EN11, 0),
|
||||
PM8607_DVC(BUCK2, 6, GO, 1, SUPPLIES_EN11, 1),
|
||||
PM8607_DVC(BUCK3, 6, GO, 2, SUPPLIES_EN11, 2),
|
||||
PM8607_DVC(BUCK1, GO, 0, SUPPLIES_EN11, 0),
|
||||
PM8607_DVC(BUCK2, GO, 1, SUPPLIES_EN11, 1),
|
||||
PM8607_DVC(BUCK3, GO, 2, SUPPLIES_EN11, 2),
|
||||
|
||||
PM8607_LDO( 1, LDO1, 0, 2, SUPPLIES_EN11, 3),
|
||||
PM8607_LDO( 2, LDO2, 0, 3, SUPPLIES_EN11, 4),
|
||||
PM8607_LDO( 3, LDO3, 0, 3, SUPPLIES_EN11, 5),
|
||||
PM8607_LDO( 4, LDO4, 0, 3, SUPPLIES_EN11, 6),
|
||||
PM8607_LDO( 5, LDO5, 0, 2, SUPPLIES_EN11, 7),
|
||||
PM8607_LDO( 6, LDO6, 0, 3, SUPPLIES_EN12, 0),
|
||||
PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1),
|
||||
PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2),
|
||||
PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3),
|
||||
PM8607_LDO(10, LDO10, 0, 4, SUPPLIES_EN12, 4),
|
||||
PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5),
|
||||
PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0),
|
||||
PM8607_LDO(14, LDO14, 0, 3, SUPPLIES_EN12, 6),
|
||||
PM8607_LDO(1, LDO1, 0, SUPPLIES_EN11, 3),
|
||||
PM8607_LDO(2, LDO2, 0, SUPPLIES_EN11, 4),
|
||||
PM8607_LDO(3, LDO3, 0, SUPPLIES_EN11, 5),
|
||||
PM8607_LDO(4, LDO4, 0, SUPPLIES_EN11, 6),
|
||||
PM8607_LDO(5, LDO5, 0, SUPPLIES_EN11, 7),
|
||||
PM8607_LDO(6, LDO6, 0, SUPPLIES_EN12, 0),
|
||||
PM8607_LDO(7, LDO7, 0, SUPPLIES_EN12, 1),
|
||||
PM8607_LDO(8, LDO8, 0, SUPPLIES_EN12, 2),
|
||||
PM8607_LDO(9, LDO9, 0, SUPPLIES_EN12, 3),
|
||||
PM8607_LDO(10, LDO10, 0, SUPPLIES_EN12, 4),
|
||||
PM8607_LDO(12, LDO12, 0, SUPPLIES_EN12, 5),
|
||||
PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0),
|
||||
PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6),
|
||||
};
|
||||
|
||||
static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
|
||||
|
@ -400,6 +316,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
|
|||
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
|
||||
struct pm8607_regulator_info *info = NULL;
|
||||
struct regulator_init_data *pdata = pdev->dev.platform_data;
|
||||
struct regulator_config config = { };
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
|
@ -425,9 +342,17 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
|
|||
if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double)
|
||||
info->slope_double = 1;
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdata;
|
||||
config.driver_data = info;
|
||||
|
||||
if (chip->id == CHIP_PM8607)
|
||||
config.regmap = chip->regmap;
|
||||
else
|
||||
config.regmap = chip->regmap_companion;
|
||||
|
||||
/* replace driver_data with info */
|
||||
info->regulator = regulator_register(&info->desc, &pdev->dev,
|
||||
pdata, info, NULL);
|
||||
info->regulator = regulator_register(&info->desc, &config);
|
||||
if (IS_ERR(info->regulator)) {
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
info->desc.name);
|
||||
|
|
|
@ -223,6 +223,16 @@ config REGULATOR_PCF50633
|
|||
Say Y here to support the voltage regulators and convertors
|
||||
on PCF50633
|
||||
|
||||
config REGULATOR_RC5T583
|
||||
tristate "RICOH RC5T583 Power regulators"
|
||||
depends on MFD_RC5T583
|
||||
help
|
||||
Select this option to enable the power regulator of RICOH
|
||||
PMIC RC5T583.
|
||||
This driver supports the control of different power rails of device
|
||||
through regulator interface. The device supports multiple DCDC/LDO
|
||||
outputs which can be controlled by i2c communication.
|
||||
|
||||
config REGULATOR_S5M8767
|
||||
tristate "Samsung S5M8767A voltage regulator"
|
||||
depends on MFD_S5M_CORE
|
||||
|
@ -268,11 +278,11 @@ config REGULATOR_TPS6105X
|
|||
audio amplifiers.
|
||||
|
||||
config REGULATOR_TPS62360
|
||||
tristate "TI TPS62360 Power Regulator"
|
||||
tristate "TI TPS6236x Power Regulator"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports TPS62360 voltage regulator chip. This
|
||||
This driver supports TPS6236x voltage regulator chip. This
|
||||
regulator is meant for processor core supply. This chip is
|
||||
high-frequency synchronous step down dc-dc converter optimized
|
||||
for battery-powered portable applications.
|
||||
|
@ -294,6 +304,13 @@ config REGULATOR_TPS6507X
|
|||
three step-down converters and two general-purpose LDO voltage regulators.
|
||||
It supports TI's software based Class-2 SmartReflex implementation.
|
||||
|
||||
config REGULATOR_TPS65090
|
||||
tristate "TI TPS65090 Power regulator"
|
||||
depends on MFD_TPS65090
|
||||
help
|
||||
This driver provides support for the voltage regulators on the
|
||||
TI TPS65090 PMIC.
|
||||
|
||||
config REGULATOR_TPS65217
|
||||
tristate "TI TPS65217 Power regulators"
|
||||
depends on MFD_TPS65217
|
||||
|
|
|
@ -9,7 +9,6 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
|
|||
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
|
||||
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
|
||||
|
||||
obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
|
||||
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
|
||||
|
@ -20,6 +19,7 @@ obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
|
|||
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
|
||||
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
|
||||
obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
|
||||
obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o
|
||||
|
@ -35,11 +35,13 @@ obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
|
|||
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
|
||||
obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
|
||||
|
|
|
@ -178,6 +178,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id)
|
|||
static int aat2870_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct aat2870_regulator *ri;
|
||||
struct regulator_config config = { 0 };
|
||||
struct regulator_dev *rdev;
|
||||
|
||||
ri = aat2870_get_regulator(pdev->id);
|
||||
|
@ -187,8 +188,11 @@ static int aat2870_regulator_probe(struct platform_device *pdev)
|
|||
}
|
||||
ri->aat2870 = dev_get_drvdata(pdev->dev.parent);
|
||||
|
||||
rdev = regulator_register(&ri->desc, &pdev->dev,
|
||||
pdev->dev.platform_data, ri, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.driver_data = ri;
|
||||
config.init_data = pdev->dev.platform_data;
|
||||
|
||||
rdev = regulator_register(&ri->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "Failed to register regulator %s\n",
|
||||
ri->desc.name);
|
||||
|
@ -231,3 +235,4 @@ module_exit(aat2870_regulator_exit);
|
|||
MODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
|
||||
MODULE_ALIAS("platform:aat2870-regulator");
|
||||
|
|
|
@ -338,20 +338,12 @@ static int ab3100_get_best_voltage_index(struct regulator_dev *reg,
|
|||
return bestindex;
|
||||
}
|
||||
|
||||
static int ab3100_set_voltage_regulator(struct regulator_dev *reg,
|
||||
int min_uV, int max_uV,
|
||||
unsigned *selector)
|
||||
static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg,
|
||||
unsigned selector)
|
||||
{
|
||||
struct ab3100_regulator *abreg = reg->reg_data;
|
||||
u8 regval;
|
||||
int err;
|
||||
int bestindex;
|
||||
|
||||
bestindex = ab3100_get_best_voltage_index(reg, min_uV, max_uV);
|
||||
if (bestindex < 0)
|
||||
return bestindex;
|
||||
|
||||
*selector = bestindex;
|
||||
|
||||
err = abx500_get_register_interruptible(abreg->dev, 0,
|
||||
abreg->regreg, ®val);
|
||||
|
@ -364,7 +356,7 @@ static int ab3100_set_voltage_regulator(struct regulator_dev *reg,
|
|||
|
||||
/* The highest three bits control the variable regulators */
|
||||
regval &= ~0xE0;
|
||||
regval |= (bestindex << 5);
|
||||
regval |= (selector << 5);
|
||||
|
||||
err = abx500_set_register_interruptible(abreg->dev, 0,
|
||||
abreg->regreg, regval);
|
||||
|
@ -464,7 +456,7 @@ static struct regulator_ops regulator_ops_variable = {
|
|||
.disable = ab3100_disable_regulator,
|
||||
.is_enabled = ab3100_is_enabled_regulator,
|
||||
.get_voltage = ab3100_get_voltage_regulator,
|
||||
.set_voltage = ab3100_set_voltage_regulator,
|
||||
.set_voltage_sel = ab3100_set_voltage_regulator_sel,
|
||||
.list_voltage = ab3100_list_voltage_regulator,
|
||||
.enable_time = ab3100_enable_time_regulator,
|
||||
};
|
||||
|
@ -474,7 +466,7 @@ static struct regulator_ops regulator_ops_variable_sleepable = {
|
|||
.disable = ab3100_disable_regulator,
|
||||
.is_enabled = ab3100_is_enabled_regulator,
|
||||
.get_voltage = ab3100_get_voltage_regulator,
|
||||
.set_voltage = ab3100_set_voltage_regulator,
|
||||
.set_voltage_sel = ab3100_set_voltage_regulator_sel,
|
||||
.set_suspend_voltage = ab3100_set_suspend_voltage_regulator,
|
||||
.list_voltage = ab3100_list_voltage_regulator,
|
||||
.enable_time = ab3100_enable_time_regulator,
|
||||
|
@ -582,6 +574,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
|
|||
static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
|
||||
struct regulator_config config = { };
|
||||
int err = 0;
|
||||
u8 data;
|
||||
int i;
|
||||
|
@ -627,15 +620,15 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
|
|||
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],
|
||||
&pdev->dev,
|
||||
&plfdata->reg_constraints[i],
|
||||
reg, NULL);
|
||||
|
||||
rdev = regulator_register(&ab3100_regulator_desc[i], &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
err = PTR_ERR(rdev);
|
||||
dev_err(&pdev->dev,
|
||||
|
|
|
@ -234,25 +234,8 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
|
|||
return val;
|
||||
}
|
||||
|
||||
static int ab8500_get_best_voltage_index(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
int i;
|
||||
|
||||
/* check the supported voltage */
|
||||
for (i = 0; i < info->voltages_len; i++) {
|
||||
if ((info->voltages[i] >= min_uV) &&
|
||||
(info->voltages[i] <= max_uV))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned *selector)
|
||||
static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
{
|
||||
int ret;
|
||||
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
@ -263,18 +246,8 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* get the appropriate voltages within the range */
|
||||
ret = ab8500_get_best_voltage_index(rdev, min_uV, max_uV);
|
||||
if (ret < 0) {
|
||||
dev_err(rdev_get_dev(rdev),
|
||||
"couldn't get best voltage for regulator\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*selector = ret;
|
||||
|
||||
/* set the registers for the request */
|
||||
regval = (u8)ret;
|
||||
regval = (u8)selector;
|
||||
ret = abx500_mask_and_set_register_interruptible(info->dev,
|
||||
info->voltage_bank, info->voltage_reg,
|
||||
info->voltage_mask, regval);
|
||||
|
@ -319,7 +292,7 @@ static struct regulator_ops ab8500_regulator_ops = {
|
|||
.disable = ab8500_regulator_disable,
|
||||
.is_enabled = ab8500_regulator_is_enabled,
|
||||
.get_voltage_sel = ab8500_regulator_get_voltage_sel,
|
||||
.set_voltage = ab8500_regulator_set_voltage,
|
||||
.set_voltage_sel = ab8500_regulator_set_voltage_sel,
|
||||
.list_voltage = ab8500_list_voltage,
|
||||
.enable_time = ab8500_regulator_enable_time,
|
||||
.set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
|
||||
|
@ -739,6 +712,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct ab8500_platform_data *pdata;
|
||||
struct regulator_config config = { };
|
||||
int i, err;
|
||||
|
||||
if (!ab8500) {
|
||||
|
@ -806,6 +780,10 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
|
|||
info = &ab8500_regulator_info[i];
|
||||
info->dev = &pdev->dev;
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = &pdata->regulator[i];
|
||||
config.driver_data = info;
|
||||
|
||||
/* fix for hardware before ab8500v2.0 */
|
||||
if (abx500_get_chip_id(info->dev) < 0x20) {
|
||||
if (info->desc.id == AB8500_LDO_AUX3) {
|
||||
|
@ -819,8 +797,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/* register regulator with framework */
|
||||
info->regulator = regulator_register(&info->desc, &pdev->dev,
|
||||
&pdata->regulator[i], info, NULL);
|
||||
info->regulator = regulator_register(&info->desc, &config);
|
||||
if (IS_ERR(info->regulator)) {
|
||||
err = PTR_ERR(info->regulator);
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
|
|
|
@ -99,8 +99,8 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int
|
|||
if (ad5398_calc_current(chip, selector) > max_uA)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(&client->dev, "changing current %dmA\n",
|
||||
ad5398_calc_current(chip, selector) / 1000);
|
||||
dev_dbg(&client->dev, "changing current %duA\n",
|
||||
ad5398_calc_current(chip, selector));
|
||||
|
||||
/* read chip enable bit */
|
||||
ret = ad5398_read_reg(client, &data);
|
||||
|
@ -184,7 +184,7 @@ static struct regulator_ops ad5398_ops = {
|
|||
.is_enabled = ad5398_is_enabled,
|
||||
};
|
||||
|
||||
static struct regulator_desc ad5398_reg = {
|
||||
static const struct regulator_desc ad5398_reg = {
|
||||
.name = "isink",
|
||||
.id = 0,
|
||||
.ops = &ad5398_ops,
|
||||
|
@ -212,6 +212,7 @@ static int __devinit ad5398_probe(struct i2c_client *client,
|
|||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct regulator_init_data *init_data = client->dev.platform_data;
|
||||
struct regulator_config config = { };
|
||||
struct ad5398_chip_info *chip;
|
||||
const struct ad5398_current_data_format *df =
|
||||
(struct ad5398_current_data_format *)id->driver_data;
|
||||
|
@ -220,10 +221,14 @@ static int __devinit ad5398_probe(struct i2c_client *client,
|
|||
if (!init_data)
|
||||
return -EINVAL;
|
||||
|
||||
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
||||
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
config.dev = &client->dev;
|
||||
config.init_data = init_data;
|
||||
config.driver_data = chip;
|
||||
|
||||
chip->client = client;
|
||||
|
||||
chip->min_uA = df->min_uA;
|
||||
|
@ -232,8 +237,7 @@ static int __devinit ad5398_probe(struct i2c_client *client,
|
|||
chip->current_offset = df->current_offset;
|
||||
chip->current_mask = (chip->current_level - 1) << chip->current_offset;
|
||||
|
||||
chip->rdev = regulator_register(&ad5398_reg, &client->dev,
|
||||
init_data, chip, NULL);
|
||||
chip->rdev = regulator_register(&ad5398_reg, &config);
|
||||
if (IS_ERR(chip->rdev)) {
|
||||
ret = PTR_ERR(chip->rdev);
|
||||
dev_err(&client->dev, "failed to register %s %s\n",
|
||||
|
@ -246,7 +250,6 @@ static int __devinit ad5398_probe(struct i2c_client *client,
|
|||
return 0;
|
||||
|
||||
err:
|
||||
kfree(chip);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -255,8 +258,6 @@ static int __devexit ad5398_remove(struct i2c_client *client)
|
|||
struct ad5398_chip_info *chip = i2c_get_clientdata(client);
|
||||
|
||||
regulator_unregister(chip->rdev);
|
||||
kfree(chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
|
|||
struct anatop_regulator *sreg;
|
||||
struct regulator_init_data *initdata;
|
||||
struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_config config = { };
|
||||
int ret = 0;
|
||||
|
||||
initdata = of_get_regulator_init_data(dev, np);
|
||||
|
@ -178,9 +179,13 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
|
|||
rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage)
|
||||
/ 25000 + 1;
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = initdata;
|
||||
config.driver_data = sreg;
|
||||
config.of_node = pdev->dev.of_node;
|
||||
|
||||
/* register regulator */
|
||||
rdev = regulator_register(rdesc, dev,
|
||||
initdata, sreg, pdev->dev.of_node);
|
||||
rdev = regulator_register(rdesc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(dev, "failed to register %s\n",
|
||||
rdesc->name);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/suspend.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
|
@ -74,6 +75,7 @@ struct regulator_map {
|
|||
struct regulator {
|
||||
struct device *dev;
|
||||
struct list_head list;
|
||||
unsigned int always_on:1;
|
||||
int uA_load;
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
|
@ -155,6 +157,17 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp
|
|||
return regnode;
|
||||
}
|
||||
|
||||
static int _regulator_can_change_status(struct regulator_dev *rdev)
|
||||
{
|
||||
if (!rdev->constraints)
|
||||
return 0;
|
||||
|
||||
if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Platform voltage constraint check */
|
||||
static int regulator_check_voltage(struct regulator_dev *rdev,
|
||||
int *min_uV, int *max_uV)
|
||||
|
@ -649,7 +662,7 @@ static void drms_uA_update(struct regulator_dev *rdev)
|
|||
/* get input voltage */
|
||||
input_uV = 0;
|
||||
if (rdev->supply)
|
||||
input_uV = _regulator_get_voltage(rdev);
|
||||
input_uV = regulator_get_voltage(rdev->supply);
|
||||
if (input_uV <= 0)
|
||||
input_uV = rdev->constraints->input_uV;
|
||||
if (input_uV <= 0)
|
||||
|
@ -673,17 +686,14 @@ static int suspend_set_state(struct regulator_dev *rdev,
|
|||
struct regulator_state *rstate)
|
||||
{
|
||||
int ret = 0;
|
||||
bool can_set_state;
|
||||
|
||||
can_set_state = rdev->desc->ops->set_suspend_enable &&
|
||||
rdev->desc->ops->set_suspend_disable;
|
||||
|
||||
/* If we have no suspend mode configration don't set anything;
|
||||
* only warn if the driver actually makes the suspend mode
|
||||
* configurable.
|
||||
* only warn if the driver implements set_suspend_voltage or
|
||||
* set_suspend_mode callback.
|
||||
*/
|
||||
if (!rstate->enabled && !rstate->disabled) {
|
||||
if (can_set_state)
|
||||
if (rdev->desc->ops->set_suspend_voltage ||
|
||||
rdev->desc->ops->set_suspend_mode)
|
||||
rdev_warn(rdev, "No configuration\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -693,15 +703,13 @@ static int suspend_set_state(struct regulator_dev *rdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!can_set_state) {
|
||||
rdev_err(rdev, "no way to set suspend state\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rstate->enabled)
|
||||
if (rstate->enabled && rdev->desc->ops->set_suspend_enable)
|
||||
ret = rdev->desc->ops->set_suspend_enable(rdev);
|
||||
else
|
||||
else if (rstate->disabled && rdev->desc->ops->set_suspend_disable)
|
||||
ret = rdev->desc->ops->set_suspend_disable(rdev);
|
||||
else /* OK if set_suspend_enable or set_suspend_disable is NULL */
|
||||
ret = 0;
|
||||
|
||||
if (ret < 0) {
|
||||
rdev_err(rdev, "failed to enabled/disable\n");
|
||||
return ret;
|
||||
|
@ -1146,6 +1154,15 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
|||
®ulator->max_uV);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check now if the regulator is an always on regulator - if
|
||||
* it is then we don't need to do nearly so much work for
|
||||
* enable/disable calls.
|
||||
*/
|
||||
if (!_regulator_can_change_status(rdev) &&
|
||||
_regulator_is_enabled(rdev))
|
||||
regulator->always_on = true;
|
||||
|
||||
mutex_unlock(&rdev->mutex);
|
||||
return regulator;
|
||||
link_name_err:
|
||||
|
@ -1169,26 +1186,52 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev)
|
|||
}
|
||||
|
||||
static struct regulator_dev *regulator_dev_lookup(struct device *dev,
|
||||
const char *supply)
|
||||
const char *supply,
|
||||
int *ret)
|
||||
{
|
||||
struct regulator_dev *r;
|
||||
struct device_node *node;
|
||||
struct regulator_map *map;
|
||||
const char *devname = NULL;
|
||||
|
||||
/* first do a dt based lookup */
|
||||
if (dev && dev->of_node) {
|
||||
node = of_get_regulator(dev, supply);
|
||||
if (node)
|
||||
if (node) {
|
||||
list_for_each_entry(r, ®ulator_list, list)
|
||||
if (r->dev.parent &&
|
||||
node == r->dev.of_node)
|
||||
return r;
|
||||
} else {
|
||||
/*
|
||||
* If we couldn't even get the node then it's
|
||||
* not just that the device didn't register
|
||||
* yet, there's no node and we'll never
|
||||
* succeed.
|
||||
*/
|
||||
*ret = -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
/* if not found, try doing it non-dt way */
|
||||
if (dev)
|
||||
devname = dev_name(dev);
|
||||
|
||||
list_for_each_entry(r, ®ulator_list, list)
|
||||
if (strcmp(rdev_get_name(r), supply) == 0)
|
||||
return r;
|
||||
|
||||
list_for_each_entry(map, ®ulator_map_list, list) {
|
||||
/* If the mapping has a device set up it must match */
|
||||
if (map->dev_name &&
|
||||
(!devname || strcmp(map->dev_name, devname)))
|
||||
continue;
|
||||
|
||||
if (strcmp(map->supply, supply) == 0)
|
||||
return map->regulator;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1197,7 +1240,6 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
|
|||
int exclusive)
|
||||
{
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_map *map;
|
||||
struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
|
||||
const char *devname = NULL;
|
||||
int ret;
|
||||
|
@ -1212,22 +1254,10 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
|
|||
|
||||
mutex_lock(®ulator_list_mutex);
|
||||
|
||||
rdev = regulator_dev_lookup(dev, id);
|
||||
rdev = regulator_dev_lookup(dev, id, &ret);
|
||||
if (rdev)
|
||||
goto found;
|
||||
|
||||
list_for_each_entry(map, ®ulator_map_list, list) {
|
||||
/* If the mapping has a device set up it must match */
|
||||
if (map->dev_name &&
|
||||
(!devname || strcmp(map->dev_name, devname)))
|
||||
continue;
|
||||
|
||||
if (strcmp(map->supply, id) == 0) {
|
||||
rdev = map->regulator;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if (board_wants_dummy_regulator) {
|
||||
rdev = dummy_regulator_rdev;
|
||||
goto found;
|
||||
|
@ -1435,17 +1465,6 @@ void devm_regulator_put(struct regulator *regulator)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regulator_put);
|
||||
|
||||
static int _regulator_can_change_status(struct regulator_dev *rdev)
|
||||
{
|
||||
if (!rdev->constraints)
|
||||
return 0;
|
||||
|
||||
if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* locks held by regulator_enable() */
|
||||
static int _regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
|
@ -1525,6 +1544,9 @@ int regulator_enable(struct regulator *regulator)
|
|||
struct regulator_dev *rdev = regulator->rdev;
|
||||
int ret = 0;
|
||||
|
||||
if (regulator->always_on)
|
||||
return 0;
|
||||
|
||||
if (rdev->supply) {
|
||||
ret = regulator_enable(rdev->supply);
|
||||
if (ret != 0)
|
||||
|
@ -1603,6 +1625,9 @@ int regulator_disable(struct regulator *regulator)
|
|||
struct regulator_dev *rdev = regulator->rdev;
|
||||
int ret = 0;
|
||||
|
||||
if (regulator->always_on)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
ret = _regulator_disable(rdev);
|
||||
mutex_unlock(&rdev->mutex);
|
||||
|
@ -1711,6 +1736,9 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
|
|||
struct regulator_dev *rdev = regulator->rdev;
|
||||
int ret;
|
||||
|
||||
if (regulator->always_on)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
rdev->deferred_disables++;
|
||||
mutex_unlock(&rdev->mutex);
|
||||
|
@ -1724,6 +1752,61 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_disable_deferred);
|
||||
|
||||
/**
|
||||
* regulator_is_enabled_regmap - standard is_enabled() for regmap users
|
||||
*
|
||||
* @rdev: regulator to operate on
|
||||
*
|
||||
* Regulators that use regmap for their register I/O can set the
|
||||
* enable_reg and enable_mask fields in their descriptor and then use
|
||||
* this as their is_enabled operation, saving some code.
|
||||
*/
|
||||
int regulator_is_enabled_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return (val & rdev->desc->enable_mask) != 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
|
||||
|
||||
/**
|
||||
* regulator_enable_regmap - standard enable() for regmap users
|
||||
*
|
||||
* @rdev: regulator to operate on
|
||||
*
|
||||
* Regulators that use regmap for their register I/O can set the
|
||||
* enable_reg and enable_mask fields in their descriptor and then use
|
||||
* this as their enable() operation, saving some code.
|
||||
*/
|
||||
int regulator_enable_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
|
||||
rdev->desc->enable_mask,
|
||||
rdev->desc->enable_mask);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_enable_regmap);
|
||||
|
||||
/**
|
||||
* regulator_disable_regmap - standard disable() for regmap users
|
||||
*
|
||||
* @rdev: regulator to operate on
|
||||
*
|
||||
* Regulators that use regmap for their register I/O can set the
|
||||
* enable_reg and enable_mask fields in their descriptor and then use
|
||||
* this as their disable() operation, saving some code.
|
||||
*/
|
||||
int regulator_disable_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
|
||||
rdev->desc->enable_mask, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_disable_regmap);
|
||||
|
||||
static int _regulator_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
/* If we don't know then assume that the regulator is always on */
|
||||
|
@ -1749,6 +1832,9 @@ int regulator_is_enabled(struct regulator *regulator)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (regulator->always_on)
|
||||
return 1;
|
||||
|
||||
mutex_lock(®ulator->rdev->mutex);
|
||||
ret = _regulator_is_enabled(regulator->rdev);
|
||||
mutex_unlock(®ulator->rdev->mutex);
|
||||
|
@ -1837,29 +1923,85 @@ int regulator_is_supported_voltage(struct regulator *regulator,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_is_supported_voltage);
|
||||
|
||||
/**
|
||||
* regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
|
||||
*
|
||||
* @rdev: regulator to operate on
|
||||
*
|
||||
* Regulators that use regmap for their register I/O can set the
|
||||
* vsel_reg and vsel_mask fields in their descriptor and then use this
|
||||
* as their get_voltage_vsel operation, saving some code.
|
||||
*/
|
||||
int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
val &= rdev->desc->vsel_mask;
|
||||
val >>= ffs(rdev->desc->vsel_mask) - 1;
|
||||
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
|
||||
|
||||
/**
|
||||
* regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
|
||||
*
|
||||
* @rdev: regulator to operate on
|
||||
* @sel: Selector to set
|
||||
*
|
||||
* Regulators that use regmap for their register I/O can set the
|
||||
* vsel_reg and vsel_mask fields in their descriptor and then use this
|
||||
* as their set_voltage_vsel operation, saving some code.
|
||||
*/
|
||||
int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
|
||||
{
|
||||
sel <<= ffs(rdev->desc->vsel_mask) - 1;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
|
||||
rdev->desc->vsel_mask, sel);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
|
||||
|
||||
static int _regulator_do_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
int ret;
|
||||
int delay = 0;
|
||||
unsigned int selector;
|
||||
int old_selector = -1;
|
||||
int best_val = INT_MAX;
|
||||
|
||||
trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
|
||||
|
||||
min_uV += rdev->constraints->uV_offset;
|
||||
max_uV += rdev->constraints->uV_offset;
|
||||
|
||||
/*
|
||||
* If we can't obtain the old selector there is not enough
|
||||
* info to call set_voltage_time_sel().
|
||||
*/
|
||||
if (rdev->desc->ops->set_voltage_time_sel &&
|
||||
rdev->desc->ops->get_voltage_sel) {
|
||||
old_selector = rdev->desc->ops->get_voltage_sel(rdev);
|
||||
if (old_selector < 0)
|
||||
return old_selector;
|
||||
}
|
||||
|
||||
if (rdev->desc->ops->set_voltage) {
|
||||
ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
|
||||
&selector);
|
||||
|
||||
if (rdev->desc->ops->list_voltage)
|
||||
selector = rdev->desc->ops->list_voltage(rdev,
|
||||
best_val = rdev->desc->ops->list_voltage(rdev,
|
||||
selector);
|
||||
else
|
||||
selector = -1;
|
||||
best_val = -1;
|
||||
} else if (rdev->desc->ops->set_voltage_sel) {
|
||||
int best_val = INT_MAX;
|
||||
int i;
|
||||
|
||||
selector = 0;
|
||||
|
@ -1878,36 +2020,27 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we can't obtain the old selector there is not enough
|
||||
* info to call set_voltage_time_sel().
|
||||
*/
|
||||
if (rdev->desc->ops->set_voltage_time_sel &&
|
||||
rdev->desc->ops->get_voltage_sel) {
|
||||
unsigned int old_selector = 0;
|
||||
|
||||
ret = rdev->desc->ops->get_voltage_sel(rdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
old_selector = ret;
|
||||
ret = rdev->desc->ops->set_voltage_time_sel(rdev,
|
||||
old_selector, selector);
|
||||
if (ret < 0)
|
||||
rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", ret);
|
||||
else
|
||||
delay = ret;
|
||||
}
|
||||
|
||||
if (best_val != INT_MAX) {
|
||||
if (best_val != INT_MAX)
|
||||
ret = rdev->desc->ops->set_voltage_sel(rdev, selector);
|
||||
selector = best_val;
|
||||
} else {
|
||||
else
|
||||
ret = -EINVAL;
|
||||
}
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
/* Call set_voltage_time_sel if successfully obtained old_selector */
|
||||
if (ret == 0 && old_selector >= 0 &&
|
||||
rdev->desc->ops->set_voltage_time_sel) {
|
||||
|
||||
delay = rdev->desc->ops->set_voltage_time_sel(rdev,
|
||||
old_selector, selector);
|
||||
if (delay < 0) {
|
||||
rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n",
|
||||
delay);
|
||||
delay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert any necessary delays */
|
||||
if (delay >= 1000) {
|
||||
mdelay(delay / 1000);
|
||||
|
@ -1920,7 +2053,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
|
|||
_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
|
||||
NULL);
|
||||
|
||||
trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector);
|
||||
trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2324,6 +2457,9 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
|
|||
*/
|
||||
ret = -EINVAL;
|
||||
|
||||
if (!rdev->desc->ops->set_mode)
|
||||
goto out;
|
||||
|
||||
/* get output voltage */
|
||||
output_uV = _regulator_get_voltage(rdev);
|
||||
if (output_uV <= 0) {
|
||||
|
@ -2525,9 +2661,13 @@ int regulator_bulk_enable(int num_consumers,
|
|||
int i;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < num_consumers; i++)
|
||||
async_schedule_domain(regulator_bulk_enable_async,
|
||||
&consumers[i], &async_domain);
|
||||
for (i = 0; i < num_consumers; i++) {
|
||||
if (consumers[i].consumer->always_on)
|
||||
consumers[i].ret = 0;
|
||||
else
|
||||
async_schedule_domain(regulator_bulk_enable_async,
|
||||
&consumers[i], &async_domain);
|
||||
}
|
||||
|
||||
async_synchronize_full_domain(&async_domain);
|
||||
|
||||
|
@ -2566,7 +2706,7 @@ int regulator_bulk_disable(int num_consumers,
|
|||
struct regulator_bulk_data *consumers)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
int ret, r;
|
||||
|
||||
for (i = num_consumers - 1; i >= 0; --i) {
|
||||
ret = regulator_disable(consumers[i].consumer);
|
||||
|
@ -2578,8 +2718,12 @@ int regulator_bulk_disable(int num_consumers,
|
|||
|
||||
err:
|
||||
pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
|
||||
for (++i; i < num_consumers; ++i)
|
||||
regulator_enable(consumers[i].consumer);
|
||||
for (++i; i < num_consumers; ++i) {
|
||||
r = regulator_enable(consumers[i].consumer);
|
||||
if (r != 0)
|
||||
pr_err("Failed to reename %s: %d\n",
|
||||
consumers[i].supply, r);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2756,10 +2900,6 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
|
|||
return status;
|
||||
}
|
||||
|
||||
/* suspend mode constraints need multiple supporting methods */
|
||||
if (!(ops->set_suspend_enable && ops->set_suspend_disable))
|
||||
return status;
|
||||
|
||||
status = device_create_file(dev, &dev_attr_suspend_standby_state);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
@ -2820,28 +2960,29 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
|
|||
/**
|
||||
* regulator_register - register regulator
|
||||
* @regulator_desc: regulator to register
|
||||
* @dev: struct device for the regulator
|
||||
* @init_data: platform provided init data, passed through by driver
|
||||
* @driver_data: private regulator data
|
||||
* @of_node: OpenFirmware node to parse for device tree bindings (may be
|
||||
* NULL).
|
||||
* @config: runtime configuration for regulator
|
||||
*
|
||||
* Called by regulator drivers to register a regulator.
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
||||
struct device *dev, const struct regulator_init_data *init_data,
|
||||
void *driver_data, struct device_node *of_node)
|
||||
struct regulator_dev *
|
||||
regulator_register(const struct regulator_desc *regulator_desc,
|
||||
const struct regulator_config *config)
|
||||
{
|
||||
const struct regulation_constraints *constraints = NULL;
|
||||
const struct regulator_init_data *init_data;
|
||||
static atomic_t regulator_no = ATOMIC_INIT(0);
|
||||
struct regulator_dev *rdev;
|
||||
struct device *dev;
|
||||
int ret, i;
|
||||
const char *supply = NULL;
|
||||
|
||||
if (regulator_desc == NULL)
|
||||
if (regulator_desc == NULL || config == NULL)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
dev = config->dev;
|
||||
WARN_ON(!dev);
|
||||
|
||||
if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
|
@ -2865,6 +3006,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
|||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
init_data = config->init_data;
|
||||
|
||||
rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
|
||||
if (rdev == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -2872,9 +3015,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
|||
mutex_lock(®ulator_list_mutex);
|
||||
|
||||
mutex_init(&rdev->mutex);
|
||||
rdev->reg_data = driver_data;
|
||||
rdev->reg_data = config->driver_data;
|
||||
rdev->owner = regulator_desc->owner;
|
||||
rdev->desc = regulator_desc;
|
||||
rdev->regmap = config->regmap;
|
||||
INIT_LIST_HEAD(&rdev->consumer_list);
|
||||
INIT_LIST_HEAD(&rdev->list);
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
|
||||
|
@ -2889,7 +3033,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
|||
|
||||
/* register with sysfs */
|
||||
rdev->dev.class = ®ulator_class;
|
||||
rdev->dev.of_node = of_node;
|
||||
rdev->dev.of_node = config->of_node;
|
||||
rdev->dev.parent = dev;
|
||||
dev_set_name(&rdev->dev, "regulator.%d",
|
||||
atomic_inc_return(®ulator_no) - 1);
|
||||
|
@ -2922,7 +3066,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
|||
if (supply) {
|
||||
struct regulator_dev *r;
|
||||
|
||||
r = regulator_dev_lookup(dev, supply);
|
||||
r = regulator_dev_lookup(dev, supply, &ret);
|
||||
|
||||
if (!r) {
|
||||
dev_err(dev, "Failed to find supply %s\n", supply);
|
||||
|
|
|
@ -517,6 +517,7 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct da903x_regulator_info *ri = NULL;
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_config config = { };
|
||||
|
||||
ri = find_regulator_info(pdev->id);
|
||||
if (ri == NULL) {
|
||||
|
@ -536,8 +537,11 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
|
|||
if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
|
||||
ri->desc.ops = &da9030_regulator_ldo1_15_ops;
|
||||
|
||||
rdev = regulator_register(&ri->desc, &pdev->dev,
|
||||
pdev->dev.platform_data, ri, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdev->dev.platform_data;
|
||||
config.driver_data = ri;
|
||||
|
||||
rdev = regulator_register(&ri->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
ri->desc.name);
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#endif
|
||||
|
||||
#include <linux/mfd/da9052/da9052.h>
|
||||
#include <linux/mfd/da9052/reg.h>
|
||||
|
@ -37,6 +40,22 @@
|
|||
#define DA9052_BUCK_ILIM_MASK_EVEN 0x0c
|
||||
#define DA9052_BUCK_ILIM_MASK_ODD 0xc0
|
||||
|
||||
/* DA9052 REGULATOR IDs */
|
||||
#define DA9052_ID_BUCK1 0
|
||||
#define DA9052_ID_BUCK2 1
|
||||
#define DA9052_ID_BUCK3 2
|
||||
#define DA9052_ID_BUCK4 3
|
||||
#define DA9052_ID_LDO1 4
|
||||
#define DA9052_ID_LDO2 5
|
||||
#define DA9052_ID_LDO3 6
|
||||
#define DA9052_ID_LDO4 7
|
||||
#define DA9052_ID_LDO5 8
|
||||
#define DA9052_ID_LDO6 9
|
||||
#define DA9052_ID_LDO7 10
|
||||
#define DA9052_ID_LDO8 11
|
||||
#define DA9052_ID_LDO9 12
|
||||
#define DA9052_ID_LDO10 13
|
||||
|
||||
static const u32 da9052_current_limits[3][4] = {
|
||||
{700000, 800000, 1000000, 1200000}, /* DA9052-BC BUCKs */
|
||||
{1600000, 2000000, 2400000, 3000000}, /* DA9053-AA/Bx BUCK-CORE */
|
||||
|
@ -50,8 +69,6 @@ struct da9052_regulator_info {
|
|||
int step_uV;
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
unsigned char volt_shift;
|
||||
unsigned char en_bit;
|
||||
unsigned char activate_bit;
|
||||
};
|
||||
|
||||
|
@ -70,42 +87,6 @@ static int verify_range(struct da9052_regulator_info *info,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int da9052_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int offset = rdev_get_id(rdev);
|
||||
|
||||
return da9052_reg_update(regulator->da9052,
|
||||
DA9052_BUCKCORE_REG + offset,
|
||||
1 << info->en_bit, 1 << info->en_bit);
|
||||
}
|
||||
|
||||
static int da9052_regulator_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int offset = rdev_get_id(rdev);
|
||||
|
||||
return da9052_reg_update(regulator->da9052,
|
||||
DA9052_BUCKCORE_REG + offset,
|
||||
1 << info->en_bit, 0);
|
||||
}
|
||||
|
||||
static int da9052_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int offset = rdev_get_id(rdev);
|
||||
int ret;
|
||||
|
||||
ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret & (1 << info->en_bit);
|
||||
}
|
||||
|
||||
static int da9052_dcdc_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
|
@ -173,36 +154,23 @@ static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA,
|
|||
reg_val << 6);
|
||||
}
|
||||
|
||||
static int da9052_list_buckperi_voltage(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int volt_uV;
|
||||
|
||||
if ((regulator->da9052->chip_id == DA9052) &&
|
||||
(selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) {
|
||||
volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV)
|
||||
+ info->min_uV);
|
||||
volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)
|
||||
* (DA9052_BUCK_PERI_3uV_STEP);
|
||||
} else
|
||||
volt_uV = (selector * info->step_uV) + info->min_uV;
|
||||
|
||||
if (volt_uV > info->max_uV)
|
||||
return -EINVAL;
|
||||
|
||||
return volt_uV;
|
||||
}
|
||||
|
||||
static int da9052_list_voltage(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int id = rdev_get_id(rdev);
|
||||
int volt_uV;
|
||||
|
||||
volt_uV = info->min_uV + info->step_uV * selector;
|
||||
if ((id == DA9052_ID_BUCK4) && (regulator->da9052->chip_id == DA9052)
|
||||
&& (selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) {
|
||||
volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV)
|
||||
+ info->min_uV);
|
||||
volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)
|
||||
* (DA9052_BUCK_PERI_3uV_STEP);
|
||||
} else {
|
||||
volt_uV = (selector * info->step_uV) + info->min_uV;
|
||||
}
|
||||
|
||||
if (volt_uV > info->max_uV)
|
||||
return -EINVAL;
|
||||
|
@ -210,13 +178,13 @@ static int da9052_list_voltage(struct regulator_dev *rdev,
|
|||
return volt_uV;
|
||||
}
|
||||
|
||||
static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev,
|
||||
static int da9052_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned int *selector)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int offset = rdev_get_id(rdev);
|
||||
int id = rdev_get_id(rdev);
|
||||
int ret;
|
||||
|
||||
ret = verify_range(info, min_uV, max_uV);
|
||||
|
@ -226,281 +194,135 @@ static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev,
|
|||
if (min_uV < info->min_uV)
|
||||
min_uV = info->min_uV;
|
||||
|
||||
*selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
|
||||
if ((id == DA9052_ID_BUCK4) && (regulator->da9052->chip_id == DA9052)
|
||||
&& (min_uV >= DA9052_CONST_3uV)) {
|
||||
*selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
|
||||
DIV_ROUND_UP(min_uV - DA9052_CONST_3uV,
|
||||
DA9052_BUCK_PERI_3uV_STEP);
|
||||
} else {
|
||||
*selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
|
||||
}
|
||||
|
||||
ret = da9052_list_voltage(rdev, *selector);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return da9052_reg_update(regulator->da9052,
|
||||
DA9052_BUCKCORE_REG + offset,
|
||||
(1 << info->volt_shift) - 1, *selector);
|
||||
}
|
||||
|
||||
static int da9052_set_ldo_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned int *selector)
|
||||
{
|
||||
return da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
|
||||
}
|
||||
|
||||
static int da9052_set_ldo5_6_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned int *selector)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int ret;
|
||||
|
||||
ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
|
||||
ret = da9052_reg_update(regulator->da9052, rdev->desc->vsel_reg,
|
||||
rdev->desc->vsel_mask, *selector);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Some LDOs are DVC controlled which requires enabling of
|
||||
* the LDO activate bit to implment the changes on the
|
||||
* LDO output.
|
||||
*/
|
||||
return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
|
||||
info->activate_bit, info->activate_bit);
|
||||
}
|
||||
|
||||
static int da9052_set_dcdc_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned int *selector)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int ret;
|
||||
|
||||
ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Some DCDCs are DVC controlled which requires enabling of
|
||||
* the DCDC activate bit to implment the changes on the
|
||||
* DCDC output.
|
||||
*/
|
||||
return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
|
||||
info->activate_bit, info->activate_bit);
|
||||
}
|
||||
|
||||
static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int offset = rdev_get_id(rdev);
|
||||
int ret;
|
||||
|
||||
ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret &= ((1 << info->volt_shift) - 1);
|
||||
/* Some LDOs and DCDCs are DVC controlled which requires enabling of
|
||||
* the activate bit to implment the changes on the output.
|
||||
*/
|
||||
switch (id) {
|
||||
case DA9052_ID_BUCK1:
|
||||
case DA9052_ID_BUCK2:
|
||||
case DA9052_ID_BUCK3:
|
||||
case DA9052_ID_LDO2:
|
||||
case DA9052_ID_LDO3:
|
||||
ret = da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
|
||||
info->activate_bit, info->activate_bit);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV,
|
||||
int max_uV, unsigned int *selector)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int offset = rdev_get_id(rdev);
|
||||
int ret;
|
||||
|
||||
ret = verify_range(info, min_uV, max_uV);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (min_uV < info->min_uV)
|
||||
min_uV = info->min_uV;
|
||||
|
||||
if ((regulator->da9052->chip_id == DA9052) &&
|
||||
(min_uV >= DA9052_CONST_3uV))
|
||||
*selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
|
||||
DIV_ROUND_UP(min_uV - DA9052_CONST_3uV,
|
||||
DA9052_BUCK_PERI_3uV_STEP);
|
||||
else
|
||||
*selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
|
||||
|
||||
ret = da9052_list_buckperi_voltage(rdev, *selector);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return da9052_reg_update(regulator->da9052,
|
||||
DA9052_BUCKCORE_REG + offset,
|
||||
(1 << info->volt_shift) - 1, *selector);
|
||||
}
|
||||
|
||||
static int da9052_get_buckperi_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int offset = rdev_get_id(rdev);
|
||||
int ret;
|
||||
|
||||
ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret &= ((1 << info->volt_shift) - 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct regulator_ops da9052_buckperi_ops = {
|
||||
.list_voltage = da9052_list_buckperi_voltage,
|
||||
.get_voltage_sel = da9052_get_buckperi_voltage_sel,
|
||||
.set_voltage = da9052_set_buckperi_voltage,
|
||||
|
||||
.get_current_limit = da9052_dcdc_get_current_limit,
|
||||
.set_current_limit = da9052_dcdc_set_current_limit,
|
||||
|
||||
.is_enabled = da9052_regulator_is_enabled,
|
||||
.enable = da9052_regulator_enable,
|
||||
.disable = da9052_regulator_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops da9052_dcdc_ops = {
|
||||
.set_voltage = da9052_set_dcdc_voltage,
|
||||
.set_voltage = da9052_regulator_set_voltage,
|
||||
.get_current_limit = da9052_dcdc_get_current_limit,
|
||||
.set_current_limit = da9052_dcdc_set_current_limit,
|
||||
|
||||
.list_voltage = da9052_list_voltage,
|
||||
.get_voltage_sel = da9052_get_regulator_voltage_sel,
|
||||
.is_enabled = da9052_regulator_is_enabled,
|
||||
.enable = da9052_regulator_enable,
|
||||
.disable = da9052_regulator_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops da9052_ldo5_6_ops = {
|
||||
.set_voltage = da9052_set_ldo5_6_voltage,
|
||||
|
||||
.list_voltage = da9052_list_voltage,
|
||||
.get_voltage_sel = da9052_get_regulator_voltage_sel,
|
||||
.is_enabled = da9052_regulator_is_enabled,
|
||||
.enable = da9052_regulator_enable,
|
||||
.disable = da9052_regulator_disable,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops da9052_ldo_ops = {
|
||||
.set_voltage = da9052_set_ldo_voltage,
|
||||
.set_voltage = da9052_regulator_set_voltage,
|
||||
|
||||
.list_voltage = da9052_list_voltage,
|
||||
.get_voltage_sel = da9052_get_regulator_voltage_sel,
|
||||
.is_enabled = da9052_regulator_is_enabled,
|
||||
.enable = da9052_regulator_enable,
|
||||
.disable = da9052_regulator_disable,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
};
|
||||
|
||||
#define DA9052_LDO5_6(_id, step, min, max, sbits, ebits, abits) \
|
||||
{\
|
||||
.reg_desc = {\
|
||||
.name = "LDO" #_id,\
|
||||
.ops = &da9052_ldo5_6_ops,\
|
||||
.type = REGULATOR_VOLTAGE,\
|
||||
.id = _id,\
|
||||
.n_voltages = (max - min) / step + 1, \
|
||||
.owner = THIS_MODULE,\
|
||||
},\
|
||||
.min_uV = (min) * 1000,\
|
||||
.max_uV = (max) * 1000,\
|
||||
.step_uV = (step) * 1000,\
|
||||
.volt_shift = (sbits),\
|
||||
.en_bit = (ebits),\
|
||||
.activate_bit = (abits),\
|
||||
}
|
||||
|
||||
#define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \
|
||||
{\
|
||||
.reg_desc = {\
|
||||
.name = "LDO" #_id,\
|
||||
.name = #_id,\
|
||||
.ops = &da9052_ldo_ops,\
|
||||
.type = REGULATOR_VOLTAGE,\
|
||||
.id = _id,\
|
||||
.id = DA9052_ID_##_id,\
|
||||
.n_voltages = (max - min) / step + 1, \
|
||||
.owner = THIS_MODULE,\
|
||||
.vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
|
||||
.vsel_mask = (1 << (sbits)) - 1,\
|
||||
.enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
|
||||
.enable_mask = 1 << (ebits),\
|
||||
},\
|
||||
.min_uV = (min) * 1000,\
|
||||
.max_uV = (max) * 1000,\
|
||||
.step_uV = (step) * 1000,\
|
||||
.volt_shift = (sbits),\
|
||||
.en_bit = (ebits),\
|
||||
.activate_bit = (abits),\
|
||||
}
|
||||
|
||||
#define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \
|
||||
{\
|
||||
.reg_desc = {\
|
||||
.name = "BUCK" #_id,\
|
||||
.name = #_id,\
|
||||
.ops = &da9052_dcdc_ops,\
|
||||
.type = REGULATOR_VOLTAGE,\
|
||||
.id = _id,\
|
||||
.id = DA9052_ID_##_id,\
|
||||
.n_voltages = (max - min) / step + 1, \
|
||||
.owner = THIS_MODULE,\
|
||||
.vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
|
||||
.vsel_mask = (1 << (sbits)) - 1,\
|
||||
.enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
|
||||
.enable_mask = 1 << (ebits),\
|
||||
},\
|
||||
.min_uV = (min) * 1000,\
|
||||
.max_uV = (max) * 1000,\
|
||||
.step_uV = (step) * 1000,\
|
||||
.volt_shift = (sbits),\
|
||||
.en_bit = (ebits),\
|
||||
.activate_bit = (abits),\
|
||||
}
|
||||
|
||||
#define DA9052_BUCKPERI(_id, step, min, max, sbits, ebits, abits) \
|
||||
{\
|
||||
.reg_desc = {\
|
||||
.name = "BUCK" #_id,\
|
||||
.ops = &da9052_buckperi_ops,\
|
||||
.type = REGULATOR_VOLTAGE,\
|
||||
.id = _id,\
|
||||
.n_voltages = (max - min) / step + 1, \
|
||||
.owner = THIS_MODULE,\
|
||||
},\
|
||||
.min_uV = (min) * 1000,\
|
||||
.max_uV = (max) * 1000,\
|
||||
.step_uV = (step) * 1000,\
|
||||
.volt_shift = (sbits),\
|
||||
.en_bit = (ebits),\
|
||||
.activate_bit = (abits),\
|
||||
}
|
||||
|
||||
static struct da9052_regulator_info da9052_regulator_info[] = {
|
||||
/* Buck1 - 4 */
|
||||
DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
|
||||
DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
|
||||
DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
|
||||
DA9052_BUCKPERI(3, 50, 1800, 3600, 5, 6, 0),
|
||||
/* LD01 - LDO10 */
|
||||
DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
|
||||
DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
|
||||
DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
|
||||
DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
|
||||
DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
|
||||
DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
|
||||
DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
|
||||
DA9052_DCDC(BUCK3, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
|
||||
DA9052_DCDC(BUCK4, 50, 1800, 3600, 5, 6, 0),
|
||||
DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0),
|
||||
DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
|
||||
DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
|
||||
DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0),
|
||||
DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0),
|
||||
DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0),
|
||||
};
|
||||
|
||||
static struct da9052_regulator_info da9053_regulator_info[] = {
|
||||
/* Buck1 - 4 */
|
||||
DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
|
||||
DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
|
||||
DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
|
||||
DA9052_BUCKPERI(3, 25, 925, 2500, 6, 6, 0),
|
||||
/* LD01 - LDO10 */
|
||||
DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
|
||||
DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
|
||||
DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
|
||||
DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
|
||||
DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
|
||||
DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
|
||||
DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
|
||||
DA9052_DCDC(BUCK3, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
|
||||
DA9052_DCDC(BUCK4, 25, 925, 2500, 6, 6, 0),
|
||||
DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0),
|
||||
DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
|
||||
DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
|
||||
DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0),
|
||||
DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0),
|
||||
DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0),
|
||||
DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0),
|
||||
};
|
||||
|
||||
static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
|
||||
|
@ -533,10 +355,10 @@ static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
|
|||
|
||||
static int __devinit da9052_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_config config = { };
|
||||
struct da9052_regulator *regulator;
|
||||
struct da9052 *da9052;
|
||||
struct da9052_pdata *pdata;
|
||||
int ret;
|
||||
|
||||
regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9052_regulator),
|
||||
GFP_KERNEL);
|
||||
|
@ -551,26 +373,49 @@ static int __devinit da9052_regulator_probe(struct platform_device *pdev)
|
|||
pdev->id);
|
||||
if (regulator->info == NULL) {
|
||||
dev_err(&pdev->dev, "invalid regulator ID specified\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.driver_data = regulator;
|
||||
config.regmap = da9052->regmap;
|
||||
if (pdata && pdata->regulators) {
|
||||
config.init_data = pdata->regulators[pdev->id];
|
||||
} else {
|
||||
#ifdef CONFIG_OF
|
||||
struct device_node *nproot = da9052->dev->of_node;
|
||||
struct device_node *np;
|
||||
|
||||
if (!nproot)
|
||||
return -ENODEV;
|
||||
|
||||
nproot = of_find_node_by_name(nproot, "regulators");
|
||||
if (!nproot)
|
||||
return -ENODEV;
|
||||
|
||||
for (np = of_get_next_child(nproot, NULL); !np;
|
||||
np = of_get_next_child(nproot, np)) {
|
||||
if (!of_node_cmp(np->name,
|
||||
regulator->info->reg_desc.name)) {
|
||||
config.init_data = of_get_regulator_init_data(
|
||||
&pdev->dev, np);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
regulator->rdev = regulator_register(®ulator->info->reg_desc,
|
||||
&pdev->dev,
|
||||
pdata->regulators[pdev->id],
|
||||
regulator, NULL);
|
||||
&config);
|
||||
if (IS_ERR(regulator->rdev)) {
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
regulator->info->reg_desc.name);
|
||||
ret = PTR_ERR(regulator->rdev);
|
||||
goto err;
|
||||
return PTR_ERR(regulator->rdev);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, regulator);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
devm_kfree(&pdev->dev, regulator);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit da9052_regulator_remove(struct platform_device *pdev)
|
||||
|
@ -578,8 +423,6 @@ static int __devexit da9052_regulator_remove(struct platform_device *pdev)
|
|||
struct da9052_regulator *regulator = platform_get_drvdata(pdev);
|
||||
|
||||
regulator_unregister(regulator->rdev);
|
||||
devm_kfree(&pdev->dev, regulator);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -414,6 +414,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct regulator_init_data *db8500_init_data =
|
||||
dev_get_platdata(&pdev->dev);
|
||||
struct regulator_config config = { };
|
||||
int i, err;
|
||||
|
||||
/* register all regulators */
|
||||
|
@ -425,9 +426,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
|
|||
info = &dbx500_regulator_info[i];
|
||||
info->dev = &pdev->dev;
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = init_data;
|
||||
config.driver_data = info;
|
||||
|
||||
/* register with the regulator framework */
|
||||
info->rdev = regulator_register(&info->desc, &pdev->dev,
|
||||
init_data, info, NULL);
|
||||
info->rdev = regulator_register(&info->desc, &config);
|
||||
if (IS_ERR(info->rdev)) {
|
||||
err = PTR_ERR(info->rdev);
|
||||
dev_err(&pdev->dev, "failed to register %s: err %i\n",
|
||||
|
|
|
@ -39,10 +39,13 @@ static struct regulator_desc dummy_desc = {
|
|||
|
||||
static int __devinit dummy_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_config config = { };
|
||||
int ret;
|
||||
|
||||
dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
|
||||
&dummy_initdata, NULL, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = &dummy_initdata;
|
||||
|
||||
dummy_regulator_rdev = regulator_register(&dummy_desc, &config);
|
||||
if (IS_ERR(dummy_regulator_rdev)) {
|
||||
ret = PTR_ERR(dummy_regulator_rdev);
|
||||
pr_err("Failed to register regulator: %d\n", ret);
|
||||
|
|
|
@ -105,10 +105,8 @@ static int fixed_voltage_enable(struct regulator_dev *dev)
|
|||
{
|
||||
struct fixed_voltage_data *data = rdev_get_drvdata(dev);
|
||||
|
||||
if (gpio_is_valid(data->gpio)) {
|
||||
gpio_set_value_cansleep(data->gpio, data->enable_high);
|
||||
data->is_enabled = true;
|
||||
}
|
||||
gpio_set_value_cansleep(data->gpio, data->enable_high);
|
||||
data->is_enabled = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -117,10 +115,8 @@ static int fixed_voltage_disable(struct regulator_dev *dev)
|
|||
{
|
||||
struct fixed_voltage_data *data = rdev_get_drvdata(dev);
|
||||
|
||||
if (gpio_is_valid(data->gpio)) {
|
||||
gpio_set_value_cansleep(data->gpio, !data->enable_high);
|
||||
data->is_enabled = false;
|
||||
}
|
||||
gpio_set_value_cansleep(data->gpio, !data->enable_high);
|
||||
data->is_enabled = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -153,7 +149,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev,
|
|||
return data->microvolts;
|
||||
}
|
||||
|
||||
static struct regulator_ops fixed_voltage_ops = {
|
||||
static struct regulator_ops fixed_voltage_gpio_ops = {
|
||||
.is_enabled = fixed_voltage_is_enabled,
|
||||
.enable = fixed_voltage_enable,
|
||||
.disable = fixed_voltage_disable,
|
||||
|
@ -162,10 +158,16 @@ static struct regulator_ops fixed_voltage_ops = {
|
|||
.list_voltage = fixed_voltage_list_voltage,
|
||||
};
|
||||
|
||||
static struct regulator_ops fixed_voltage_ops = {
|
||||
.get_voltage = fixed_voltage_get_voltage,
|
||||
.list_voltage = fixed_voltage_list_voltage,
|
||||
};
|
||||
|
||||
static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct fixed_voltage_config *config;
|
||||
struct fixed_voltage_data *drvdata;
|
||||
struct regulator_config cfg = { };
|
||||
int ret;
|
||||
|
||||
if (pdev->dev.of_node)
|
||||
|
@ -176,7 +178,8 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
|
|||
if (!config)
|
||||
return -ENOMEM;
|
||||
|
||||
drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);
|
||||
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
|
||||
GFP_KERNEL);
|
||||
if (drvdata == NULL) {
|
||||
dev_err(&pdev->dev, "Failed to allocate device data\n");
|
||||
ret = -ENOMEM;
|
||||
|
@ -191,7 +194,6 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
|
|||
}
|
||||
drvdata->desc.type = REGULATOR_VOLTAGE;
|
||||
drvdata->desc.owner = THIS_MODULE;
|
||||
drvdata->desc.ops = &fixed_voltage_ops;
|
||||
|
||||
if (config->microvolts)
|
||||
drvdata->desc.n_voltages = 1;
|
||||
|
@ -201,6 +203,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
|
|||
drvdata->startup_delay = config->startup_delay;
|
||||
|
||||
if (gpio_is_valid(config->gpio)) {
|
||||
int gpio_flag;
|
||||
drvdata->enable_high = config->enable_high;
|
||||
|
||||
/* FIXME: Remove below print warning
|
||||
|
@ -218,7 +221,20 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
|
|||
dev_warn(&pdev->dev,
|
||||
"using GPIO 0 for regulator enable control\n");
|
||||
|
||||
ret = gpio_request(config->gpio, config->supply_name);
|
||||
/*
|
||||
* set output direction without changing state
|
||||
* to prevent glitch
|
||||
*/
|
||||
drvdata->is_enabled = config->enabled_at_boot;
|
||||
ret = drvdata->is_enabled ?
|
||||
config->enable_high : !config->enable_high;
|
||||
gpio_flag = ret ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
|
||||
|
||||
if (config->gpio_is_open_drain)
|
||||
gpio_flag |= GPIOF_OPEN_DRAIN;
|
||||
|
||||
ret = gpio_request_one(config->gpio, gpio_flag,
|
||||
config->supply_name);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Could not obtain regulator enable GPIO %d: %d\n",
|
||||
|
@ -226,31 +242,18 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
|
|||
goto err_name;
|
||||
}
|
||||
|
||||
/* set output direction without changing state
|
||||
* to prevent glitch
|
||||
*/
|
||||
drvdata->is_enabled = config->enabled_at_boot;
|
||||
ret = drvdata->is_enabled ?
|
||||
config->enable_high : !config->enable_high;
|
||||
|
||||
ret = gpio_direction_output(config->gpio, ret);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Could not configure regulator enable GPIO %d direction: %d\n",
|
||||
config->gpio, ret);
|
||||
goto err_gpio;
|
||||
}
|
||||
drvdata->desc.ops = &fixed_voltage_gpio_ops;
|
||||
|
||||
} else {
|
||||
/* Regulator without GPIO control is considered
|
||||
* always enabled
|
||||
*/
|
||||
drvdata->is_enabled = true;
|
||||
drvdata->desc.ops = &fixed_voltage_ops;
|
||||
}
|
||||
|
||||
drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
|
||||
config->init_data, drvdata,
|
||||
pdev->dev.of_node);
|
||||
cfg.dev = &pdev->dev;
|
||||
cfg.init_data = config->init_data;
|
||||
cfg.driver_data = drvdata;
|
||||
cfg.of_node = pdev->dev.of_node;
|
||||
|
||||
drvdata->dev = regulator_register(&drvdata->desc, &cfg);
|
||||
if (IS_ERR(drvdata->dev)) {
|
||||
ret = PTR_ERR(drvdata->dev);
|
||||
dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
|
||||
|
@ -270,7 +273,6 @@ err_gpio:
|
|||
err_name:
|
||||
kfree(drvdata->desc.name);
|
||||
err:
|
||||
kfree(drvdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -282,7 +284,6 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev)
|
|||
if (gpio_is_valid(drvdata->gpio))
|
||||
gpio_free(drvdata->gpio);
|
||||
kfree(drvdata->desc.name);
|
||||
kfree(drvdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -105,15 +105,15 @@ static int gpio_regulator_set_value(struct regulator_dev *dev,
|
|||
int min, int max)
|
||||
{
|
||||
struct gpio_regulator_data *data = rdev_get_drvdata(dev);
|
||||
int ptr, target, state;
|
||||
int ptr, target, state, best_val = INT_MAX;
|
||||
|
||||
target = -1;
|
||||
for (ptr = 0; ptr < data->nr_states; ptr++)
|
||||
if (data->states[ptr].value >= min &&
|
||||
if (data->states[ptr].value < best_val &&
|
||||
data->states[ptr].value >= min &&
|
||||
data->states[ptr].value <= max)
|
||||
target = data->states[ptr].gpios;
|
||||
|
||||
if (target < 0)
|
||||
if (best_val == INT_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
for (ptr = 0; ptr < data->nr_gpios; ptr++) {
|
||||
|
@ -172,9 +172,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct gpio_regulator_config *config = pdev->dev.platform_data;
|
||||
struct gpio_regulator_data *drvdata;
|
||||
struct regulator_config cfg = { };
|
||||
int ptr, ret, state;
|
||||
|
||||
drvdata = kzalloc(sizeof(struct gpio_regulator_data), GFP_KERNEL);
|
||||
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data),
|
||||
GFP_KERNEL);
|
||||
if (drvdata == NULL) {
|
||||
dev_err(&pdev->dev, "Failed to allocate device data\n");
|
||||
return -ENOMEM;
|
||||
|
@ -283,8 +285,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev)
|
|||
}
|
||||
drvdata->state = state;
|
||||
|
||||
drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
|
||||
config->init_data, drvdata, NULL);
|
||||
cfg.dev = &pdev->dev;
|
||||
cfg.init_data = config->init_data;
|
||||
cfg.driver_data = &drvdata;
|
||||
|
||||
drvdata->dev = regulator_register(&drvdata->desc, &cfg);
|
||||
if (IS_ERR(drvdata->dev)) {
|
||||
ret = PTR_ERR(drvdata->dev);
|
||||
dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
|
||||
|
@ -307,7 +312,6 @@ err_memgpio:
|
|||
err_name:
|
||||
kfree(drvdata->desc.name);
|
||||
err:
|
||||
kfree(drvdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -326,7 +330,6 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev)
|
|||
gpio_free(drvdata->enable_gpio);
|
||||
|
||||
kfree(drvdata->desc.name);
|
||||
kfree(drvdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ static struct regulator_ops isl_fixed_ops = {
|
|||
.list_voltage = isl6271a_list_fixed_voltage,
|
||||
};
|
||||
|
||||
static struct regulator_desc isl_rd[] = {
|
||||
static const struct regulator_desc isl_rd[] = {
|
||||
{
|
||||
.name = "Core Buck",
|
||||
.id = 0,
|
||||
|
@ -140,6 +140,7 @@ static struct regulator_desc isl_rd[] = {
|
|||
static int __devinit isl6271a_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct regulator_config config = { };
|
||||
struct regulator_init_data *init_data = i2c->dev.platform_data;
|
||||
struct isl_pmic *pmic;
|
||||
int err, i;
|
||||
|
@ -147,12 +148,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
|
|||
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -EIO;
|
||||
|
||||
if (!init_data) {
|
||||
dev_err(&i2c->dev, "no platform data supplied\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pmic = kzalloc(sizeof(struct isl_pmic), GFP_KERNEL);
|
||||
pmic = devm_kzalloc(&i2c->dev, sizeof(struct isl_pmic), GFP_KERNEL);
|
||||
if (!pmic)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -161,8 +157,14 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
|
|||
mutex_init(&pmic->mtx);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev,
|
||||
init_data, pmic, NULL);
|
||||
config.dev = &i2c->dev;
|
||||
if (i == 0)
|
||||
config.init_data = init_data;
|
||||
else
|
||||
config.init_data = 0;
|
||||
config.driver_data = pmic;
|
||||
|
||||
pmic->rdev[i] = regulator_register(&isl_rd[i], &config);
|
||||
if (IS_ERR(pmic->rdev[i])) {
|
||||
dev_err(&i2c->dev, "failed to register %s\n", id->name);
|
||||
err = PTR_ERR(pmic->rdev[i]);
|
||||
|
@ -177,8 +179,6 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
|
|||
error:
|
||||
while (--i >= 0)
|
||||
regulator_unregister(pmic->rdev[i]);
|
||||
|
||||
kfree(pmic);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -189,9 +189,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c)
|
|||
|
||||
for (i = 0; i < 3; i++)
|
||||
regulator_unregister(pmic->rdev[i]);
|
||||
|
||||
kfree(pmic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,10 @@ static const int *ldo_voltage_map[] = {
|
|||
static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
|
||||
{
|
||||
int ldo = rdev_get_id(dev) - LP3971_LDO1;
|
||||
|
||||
if (index > LDO_VOL_MAX_IDX)
|
||||
return -EINVAL;
|
||||
|
||||
return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
|
||||
}
|
||||
|
||||
|
@ -168,32 +172,15 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
|
|||
return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
|
||||
}
|
||||
|
||||
static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned int *selector)
|
||||
static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct lp3971 *lp3971 = rdev_get_drvdata(dev);
|
||||
int ldo = rdev_get_id(dev) - LP3971_LDO1;
|
||||
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
|
||||
const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
|
||||
u16 val;
|
||||
|
||||
if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
|
||||
min_vol > vol_map[LDO_VOL_MAX_IDX])
|
||||
return -EINVAL;
|
||||
|
||||
for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
|
||||
if (vol_map[val] >= min_vol)
|
||||
break;
|
||||
|
||||
if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol)
|
||||
return -EINVAL;
|
||||
|
||||
*selector = val;
|
||||
|
||||
return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
|
||||
LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo),
|
||||
val << LDO_VOL_CONTR_SHIFT(ldo));
|
||||
selector << LDO_VOL_CONTR_SHIFT(ldo));
|
||||
}
|
||||
|
||||
static struct regulator_ops lp3971_ldo_ops = {
|
||||
|
@ -202,11 +189,14 @@ static struct regulator_ops lp3971_ldo_ops = {
|
|||
.enable = lp3971_ldo_enable,
|
||||
.disable = lp3971_ldo_disable,
|
||||
.get_voltage = lp3971_ldo_get_voltage,
|
||||
.set_voltage = lp3971_ldo_set_voltage,
|
||||
.set_voltage_sel = lp3971_ldo_set_voltage_sel,
|
||||
};
|
||||
|
||||
static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
|
||||
{
|
||||
if (index < BUCK_TARGET_VOL_MIN_IDX || index > BUCK_TARGET_VOL_MAX_IDX)
|
||||
return -EINVAL;
|
||||
|
||||
return 1000 * buck_voltage_map[index];
|
||||
}
|
||||
|
||||
|
@ -259,33 +249,15 @@ static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
|
|||
return val;
|
||||
}
|
||||
|
||||
static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned int *selector)
|
||||
static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct lp3971 *lp3971 = rdev_get_drvdata(dev);
|
||||
int buck = rdev_get_id(dev) - LP3971_DCDC1;
|
||||
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
|
||||
const int *vol_map = buck_voltage_map;
|
||||
u16 val;
|
||||
int ret;
|
||||
|
||||
if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
|
||||
min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
|
||||
return -EINVAL;
|
||||
|
||||
for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
|
||||
val++)
|
||||
if (vol_map[val] >= min_vol)
|
||||
break;
|
||||
|
||||
if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol)
|
||||
return -EINVAL;
|
||||
|
||||
*selector = val;
|
||||
|
||||
ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
|
||||
BUCK_TARGET_VOL_MASK, val);
|
||||
BUCK_TARGET_VOL_MASK, selector);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -306,10 +278,10 @@ static struct regulator_ops lp3971_dcdc_ops = {
|
|||
.enable = lp3971_dcdc_enable,
|
||||
.disable = lp3971_dcdc_disable,
|
||||
.get_voltage = lp3971_dcdc_get_voltage,
|
||||
.set_voltage = lp3971_dcdc_set_voltage,
|
||||
.set_voltage_sel = lp3971_dcdc_set_voltage_sel,
|
||||
};
|
||||
|
||||
static struct regulator_desc regulators[] = {
|
||||
static const struct regulator_desc regulators[] = {
|
||||
{
|
||||
.name = "LDO1",
|
||||
.id = LP3971_LDO1,
|
||||
|
@ -449,10 +421,15 @@ static int __devinit setup_regulators(struct lp3971 *lp3971,
|
|||
|
||||
/* Instantiate the regulators */
|
||||
for (i = 0; i < pdata->num_regulators; i++) {
|
||||
struct regulator_config config = { };
|
||||
struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
|
||||
lp3971->rdev[i] = regulator_register(®ulators[reg->id],
|
||||
lp3971->dev, reg->initdata, lp3971, NULL);
|
||||
|
||||
config.dev = lp3971->dev;
|
||||
config.init_data = reg->initdata;
|
||||
config.driver_data = lp3971;
|
||||
|
||||
lp3971->rdev[i] = regulator_register(®ulators[reg->id],
|
||||
&config);
|
||||
if (IS_ERR(lp3971->rdev[i])) {
|
||||
err = PTR_ERR(lp3971->rdev[i]);
|
||||
dev_err(lp3971->dev, "regulator init failed: %d\n",
|
||||
|
@ -545,23 +522,7 @@ static struct i2c_driver lp3971_i2c_driver = {
|
|||
.id_table = lp3971_i2c_id,
|
||||
};
|
||||
|
||||
static int __init lp3971_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = i2c_add_driver(&lp3971_i2c_driver);
|
||||
if (ret != 0)
|
||||
pr_err("Failed to register I2C driver: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
module_init(lp3971_module_init);
|
||||
|
||||
static void __exit lp3971_module_exit(void)
|
||||
{
|
||||
i2c_del_driver(&lp3971_i2c_driver);
|
||||
}
|
||||
module_exit(lp3971_module_exit);
|
||||
module_i2c_driver(lp3971_i2c_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
|
||||
|
|
|
@ -245,6 +245,11 @@ static int lp3972_set_bits(struct lp3972 *lp3972, u8 reg, u16 mask, u16 val)
|
|||
static int lp3972_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
|
||||
{
|
||||
int ldo = rdev_get_id(dev) - LP3972_LDO1;
|
||||
|
||||
if (index < LP3972_LDO_VOL_MIN_IDX(ldo) ||
|
||||
index > LP3972_LDO_VOL_MAX_IDX(ldo))
|
||||
return -EINVAL;
|
||||
|
||||
return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[index];
|
||||
}
|
||||
|
||||
|
@ -292,34 +297,16 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev)
|
|||
return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[val];
|
||||
}
|
||||
|
||||
static int lp3972_ldo_set_voltage(struct regulator_dev *dev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned int *selector)
|
||||
static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct lp3972 *lp3972 = rdev_get_drvdata(dev);
|
||||
int ldo = rdev_get_id(dev) - LP3972_LDO1;
|
||||
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
|
||||
const int *vol_map = LP3972_LDO_VOL_VALUE_MAP(ldo);
|
||||
u16 val;
|
||||
int shift, ret;
|
||||
|
||||
if (min_vol < vol_map[LP3972_LDO_VOL_MIN_IDX(ldo)] ||
|
||||
min_vol > vol_map[LP3972_LDO_VOL_MAX_IDX(ldo)])
|
||||
return -EINVAL;
|
||||
|
||||
for (val = LP3972_LDO_VOL_MIN_IDX(ldo);
|
||||
val <= LP3972_LDO_VOL_MAX_IDX(ldo); val++)
|
||||
if (vol_map[val] >= min_vol)
|
||||
break;
|
||||
|
||||
if (val > LP3972_LDO_VOL_MAX_IDX(ldo) || vol_map[val] > max_vol)
|
||||
return -EINVAL;
|
||||
|
||||
*selector = val;
|
||||
|
||||
shift = LP3972_LDO_VOL_CONTR_SHIFT(ldo);
|
||||
ret = lp3972_set_bits(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo),
|
||||
LP3972_LDO_VOL_MASK(ldo) << shift, val << shift);
|
||||
LP3972_LDO_VOL_MASK(ldo) << shift, selector << shift);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -355,12 +342,17 @@ static struct regulator_ops lp3972_ldo_ops = {
|
|||
.enable = lp3972_ldo_enable,
|
||||
.disable = lp3972_ldo_disable,
|
||||
.get_voltage = lp3972_ldo_get_voltage,
|
||||
.set_voltage = lp3972_ldo_set_voltage,
|
||||
.set_voltage_sel = lp3972_ldo_set_voltage_sel,
|
||||
};
|
||||
|
||||
static int lp3972_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
|
||||
{
|
||||
int buck = rdev_get_id(dev) - LP3972_DCDC1;
|
||||
|
||||
if (index < LP3972_BUCK_VOL_MIN_IDX(buck) ||
|
||||
index > LP3972_BUCK_VOL_MAX_IDX(buck))
|
||||
return -EINVAL;
|
||||
|
||||
return 1000 * buck_voltage_map[buck][index];
|
||||
}
|
||||
|
||||
|
@ -419,34 +411,15 @@ static int lp3972_dcdc_get_voltage(struct regulator_dev *dev)
|
|||
return val;
|
||||
}
|
||||
|
||||
static int lp3972_dcdc_set_voltage(struct regulator_dev *dev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned int *selector)
|
||||
static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct lp3972 *lp3972 = rdev_get_drvdata(dev);
|
||||
int buck = rdev_get_id(dev) - LP3972_DCDC1;
|
||||
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
|
||||
const int *vol_map = buck_voltage_map[buck];
|
||||
u16 val;
|
||||
int ret;
|
||||
|
||||
if (min_vol < vol_map[LP3972_BUCK_VOL_MIN_IDX(buck)] ||
|
||||
min_vol > vol_map[LP3972_BUCK_VOL_MAX_IDX(buck)])
|
||||
return -EINVAL;
|
||||
|
||||
for (val = LP3972_BUCK_VOL_MIN_IDX(buck);
|
||||
val <= LP3972_BUCK_VOL_MAX_IDX(buck); val++)
|
||||
if (vol_map[val] >= min_vol)
|
||||
break;
|
||||
|
||||
if (val > LP3972_BUCK_VOL_MAX_IDX(buck) ||
|
||||
vol_map[val] > max_vol)
|
||||
return -EINVAL;
|
||||
|
||||
*selector = val;
|
||||
|
||||
ret = lp3972_set_bits(lp3972, LP3972_BUCK_VOL1_REG(buck),
|
||||
LP3972_BUCK_VOL_MASK, val);
|
||||
LP3972_BUCK_VOL_MASK, selector);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -468,10 +441,10 @@ static struct regulator_ops lp3972_dcdc_ops = {
|
|||
.enable = lp3972_dcdc_enable,
|
||||
.disable = lp3972_dcdc_disable,
|
||||
.get_voltage = lp3972_dcdc_get_voltage,
|
||||
.set_voltage = lp3972_dcdc_set_voltage,
|
||||
.set_voltage_sel = lp3972_dcdc_set_voltage_sel,
|
||||
};
|
||||
|
||||
static struct regulator_desc regulators[] = {
|
||||
static const struct regulator_desc regulators[] = {
|
||||
{
|
||||
.name = "LDO1",
|
||||
.id = LP3972_LDO1,
|
||||
|
@ -554,9 +527,14 @@ static int __devinit setup_regulators(struct lp3972 *lp3972,
|
|||
/* Instantiate the regulators */
|
||||
for (i = 0; i < pdata->num_regulators; i++) {
|
||||
struct lp3972_regulator_subdev *reg = &pdata->regulators[i];
|
||||
lp3972->rdev[i] = regulator_register(®ulators[reg->id],
|
||||
lp3972->dev, reg->initdata, lp3972, NULL);
|
||||
struct regulator_config config = { };
|
||||
|
||||
config.dev = lp3972->dev;
|
||||
config.init_data = reg->initdata;
|
||||
config.driver_data = lp3972;
|
||||
|
||||
lp3972->rdev[i] = regulator_register(®ulators[reg->id],
|
||||
&config);
|
||||
if (IS_ERR(lp3972->rdev[i])) {
|
||||
err = PTR_ERR(lp3972->rdev[i]);
|
||||
dev_err(lp3972->dev, "regulator init failed: %d\n",
|
||||
|
|
|
@ -161,7 +161,7 @@ static struct regulator_ops max1586_v6_ops = {
|
|||
.list_voltage = max1586_v6_list,
|
||||
};
|
||||
|
||||
static struct regulator_desc max1586_reg[] = {
|
||||
static const struct regulator_desc max1586_reg[] = {
|
||||
{
|
||||
.name = "Output_V3",
|
||||
.id = MAX1586_V3,
|
||||
|
@ -185,21 +185,21 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
|
|||
{
|
||||
struct regulator_dev **rdev;
|
||||
struct max1586_platform_data *pdata = client->dev.platform_data;
|
||||
struct regulator_config config = { };
|
||||
struct max1586_data *max1586;
|
||||
int i, id, ret = -ENOMEM;
|
||||
|
||||
max1586 = kzalloc(sizeof(struct max1586_data) +
|
||||
max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data) +
|
||||
sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
|
||||
GFP_KERNEL);
|
||||
if (!max1586)
|
||||
goto out;
|
||||
return -ENOMEM;
|
||||
|
||||
max1586->client = client;
|
||||
|
||||
if (!pdata->v3_gain) {
|
||||
ret = -EINVAL;
|
||||
goto out_unmap;
|
||||
}
|
||||
if (!pdata->v3_gain)
|
||||
return -EINVAL;
|
||||
|
||||
max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000;
|
||||
max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000;
|
||||
|
||||
|
@ -212,9 +212,12 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
|
|||
dev_err(&client->dev, "invalid regulator id %d\n", id);
|
||||
goto err;
|
||||
}
|
||||
rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
|
||||
pdata->subdevs[i].platform_data,
|
||||
max1586, NULL);
|
||||
|
||||
config.dev = &client->dev;
|
||||
config.init_data = pdata->subdevs[i].platform_data;
|
||||
config.driver_data = max1586;
|
||||
|
||||
rdev[i] = regulator_register(&max1586_reg[id], &config);
|
||||
if (IS_ERR(rdev[i])) {
|
||||
ret = PTR_ERR(rdev[i]);
|
||||
dev_err(&client->dev, "failed to register %s\n",
|
||||
|
@ -230,9 +233,6 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
|
|||
err:
|
||||
while (--i >= 0)
|
||||
regulator_unregister(rdev[i]);
|
||||
out_unmap:
|
||||
kfree(max1586);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -244,8 +244,6 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client)
|
|||
for (i = 0; i <= MAX1586_V6; i++)
|
||||
if (max1586->rdev[i])
|
||||
regulator_unregister(max1586->rdev[i]);
|
||||
kfree(max1586);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ static struct regulator_ops max8649_dcdc_ops = {
|
|||
|
||||
};
|
||||
|
||||
static struct regulator_desc dcdc_desc = {
|
||||
static const struct regulator_desc dcdc_desc = {
|
||||
.name = "max8649",
|
||||
.ops = &max8649_dcdc_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
|
@ -225,21 +225,23 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
|
|||
{
|
||||
struct max8649_platform_data *pdata = client->dev.platform_data;
|
||||
struct max8649_regulator_info *info = NULL;
|
||||
struct regulator_config config = { };
|
||||
unsigned int val;
|
||||
unsigned char data;
|
||||
int ret;
|
||||
|
||||
info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL);
|
||||
info = devm_kzalloc(&client->dev, sizeof(struct max8649_regulator_info),
|
||||
GFP_KERNEL);
|
||||
if (!info) {
|
||||
dev_err(&client->dev, "No enough memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
info->regmap = regmap_init_i2c(client, &max8649_regmap_config);
|
||||
info->regmap = devm_regmap_init_i2c(client, &max8649_regmap_config);
|
||||
if (IS_ERR(info->regmap)) {
|
||||
ret = PTR_ERR(info->regmap);
|
||||
dev_err(&client->dev, "Failed to allocate register map: %d\n", ret);
|
||||
goto fail;
|
||||
return ret;
|
||||
}
|
||||
|
||||
info->dev = &client->dev;
|
||||
|
@ -267,7 +269,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
|
|||
if (ret != 0) {
|
||||
dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n",
|
||||
ret);
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val);
|
||||
|
||||
|
@ -297,22 +299,18 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
|
|||
MAX8649_RAMP_DOWN);
|
||||
}
|
||||
|
||||
info->regulator = regulator_register(&dcdc_desc, &client->dev,
|
||||
pdata->regulator, info, NULL);
|
||||
config.dev = &client->dev;
|
||||
config.init_data = pdata->regulator;
|
||||
config.driver_data = info;
|
||||
|
||||
info->regulator = regulator_register(&dcdc_desc, &config);
|
||||
if (IS_ERR(info->regulator)) {
|
||||
dev_err(info->dev, "failed to register regulator %s\n",
|
||||
dcdc_desc.name);
|
||||
ret = PTR_ERR(info->regulator);
|
||||
goto out;
|
||||
return PTR_ERR(info->regulator);
|
||||
}
|
||||
|
||||
dev_info(info->dev, "Max8649 regulator device is detected.\n");
|
||||
return 0;
|
||||
out:
|
||||
regmap_exit(info->regmap);
|
||||
fail:
|
||||
kfree(info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit max8649_regulator_remove(struct i2c_client *client)
|
||||
|
@ -322,8 +320,6 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client)
|
|||
if (info) {
|
||||
if (info->regulator)
|
||||
regulator_unregister(info->regulator);
|
||||
regmap_exit(info->regmap);
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -313,7 +313,7 @@ static struct regulator_ops max8660_ldo67_ops = {
|
|||
.set_voltage = max8660_ldo67_set,
|
||||
};
|
||||
|
||||
static struct regulator_desc max8660_reg[] = {
|
||||
static const struct regulator_desc max8660_reg[] = {
|
||||
{
|
||||
.name = "V3(DCDC)",
|
||||
.id = MAX8660_V3,
|
||||
|
@ -361,21 +361,20 @@ static int __devinit max8660_probe(struct i2c_client *client,
|
|||
{
|
||||
struct regulator_dev **rdev;
|
||||
struct max8660_platform_data *pdata = client->dev.platform_data;
|
||||
struct regulator_config config = { };
|
||||
struct max8660 *max8660;
|
||||
int boot_on, i, id, ret = -EINVAL;
|
||||
|
||||
if (pdata->num_subdevs > MAX8660_V_END) {
|
||||
dev_err(&client->dev, "Too many regulators found!\n");
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
max8660 = kzalloc(sizeof(struct max8660) +
|
||||
sizeof(struct regulator_dev *) * MAX8660_V_END,
|
||||
GFP_KERNEL);
|
||||
if (!max8660) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (!max8660)
|
||||
return -ENOMEM;
|
||||
|
||||
max8660->client = client;
|
||||
rdev = max8660->rdev;
|
||||
|
@ -404,7 +403,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
|
|||
for (i = 0; i < pdata->num_subdevs; i++) {
|
||||
|
||||
if (!pdata->subdevs[i].platform_data)
|
||||
goto err_free;
|
||||
goto err_out;
|
||||
|
||||
boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
|
||||
|
||||
|
@ -430,7 +429,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
|
|||
case MAX8660_V7:
|
||||
if (!strcmp(i2c_id->name, "max8661")) {
|
||||
dev_err(&client->dev, "Regulator not on this chip!\n");
|
||||
goto err_free;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (boot_on)
|
||||
|
@ -440,7 +439,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
|
|||
default:
|
||||
dev_err(&client->dev, "invalid regulator %s\n",
|
||||
pdata->subdevs[i].name);
|
||||
goto err_free;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,9 +448,11 @@ static int __devinit max8660_probe(struct i2c_client *client,
|
|||
|
||||
id = pdata->subdevs[i].id;
|
||||
|
||||
rdev[i] = regulator_register(&max8660_reg[id], &client->dev,
|
||||
pdata->subdevs[i].platform_data,
|
||||
max8660, NULL);
|
||||
config.dev = &client->dev;
|
||||
config.init_data = pdata->subdevs[i].platform_data;
|
||||
config.driver_data = max8660;
|
||||
|
||||
rdev[i] = regulator_register(&max8660_reg[id], &config);
|
||||
if (IS_ERR(rdev[i])) {
|
||||
ret = PTR_ERR(rdev[i]);
|
||||
dev_err(&client->dev, "failed to register %s\n",
|
||||
|
@ -461,15 +462,12 @@ static int __devinit max8660_probe(struct i2c_client *client,
|
|||
}
|
||||
|
||||
i2c_set_clientdata(client, max8660);
|
||||
dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n");
|
||||
return 0;
|
||||
|
||||
err_unregister:
|
||||
while (--i >= 0)
|
||||
regulator_unregister(rdev[i]);
|
||||
err_free:
|
||||
kfree(max8660);
|
||||
out:
|
||||
err_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -481,8 +479,6 @@ static int __devexit max8660_remove(struct i2c_client *client)
|
|||
for (i = 0; i < MAX8660_V_END; i++)
|
||||
if (max8660->rdev[i])
|
||||
regulator_unregister(max8660->rdev[i]);
|
||||
kfree(max8660);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,8 +42,6 @@ struct max8925_regulator_info {
|
|||
int max_uV;
|
||||
int step_uV;
|
||||
int vol_reg;
|
||||
int vol_shift;
|
||||
int vol_nbits;
|
||||
int enable_reg;
|
||||
};
|
||||
|
||||
|
@ -75,8 +73,7 @@ static int max8925_set_voltage(struct regulator_dev *rdev,
|
|||
}
|
||||
data = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
|
||||
*selector = data;
|
||||
data <<= info->vol_shift;
|
||||
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
|
||||
mask = rdev->desc->n_voltages - 1;
|
||||
|
||||
return max8925_set_bits(info->i2c, info->vol_reg, mask, data);
|
||||
}
|
||||
|
@ -90,8 +87,8 @@ static int max8925_get_voltage(struct regulator_dev *rdev)
|
|||
ret = max8925_reg_read(info->i2c, info->vol_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
|
||||
data = (ret & mask) >> info->vol_shift;
|
||||
mask = rdev->desc->n_voltages - 1;
|
||||
data = ret & mask;
|
||||
|
||||
return max8925_list_voltage(rdev, data);
|
||||
}
|
||||
|
@ -163,6 +160,7 @@ static int max8925_set_dvm_disable(struct regulator_dev *rdev)
|
|||
}
|
||||
|
||||
static struct regulator_ops max8925_regulator_sdv_ops = {
|
||||
.list_voltage = max8925_list_voltage,
|
||||
.set_voltage = max8925_set_voltage,
|
||||
.get_voltage = max8925_get_voltage,
|
||||
.enable = max8925_enable,
|
||||
|
@ -174,6 +172,7 @@ static struct regulator_ops max8925_regulator_sdv_ops = {
|
|||
};
|
||||
|
||||
static struct regulator_ops max8925_regulator_ldo_ops = {
|
||||
.list_voltage = max8925_list_voltage,
|
||||
.set_voltage = max8925_set_voltage,
|
||||
.get_voltage = max8925_get_voltage,
|
||||
.enable = max8925_enable,
|
||||
|
@ -189,13 +188,12 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
|
|||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = MAX8925_ID_SD##_id, \
|
||||
.owner = THIS_MODULE, \
|
||||
.n_voltages = 64, \
|
||||
}, \
|
||||
.min_uV = min * 1000, \
|
||||
.max_uV = max * 1000, \
|
||||
.step_uV = step * 1000, \
|
||||
.vol_reg = MAX8925_SDV##_id, \
|
||||
.vol_shift = 0, \
|
||||
.vol_nbits = 6, \
|
||||
.enable_reg = MAX8925_SDCTL##_id, \
|
||||
}
|
||||
|
||||
|
@ -207,13 +205,12 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
|
|||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = MAX8925_ID_LDO##_id, \
|
||||
.owner = THIS_MODULE, \
|
||||
.n_voltages = 64, \
|
||||
}, \
|
||||
.min_uV = min * 1000, \
|
||||
.max_uV = max * 1000, \
|
||||
.step_uV = step * 1000, \
|
||||
.vol_reg = MAX8925_LDOVOUT##_id, \
|
||||
.vol_shift = 0, \
|
||||
.vol_nbits = 6, \
|
||||
.enable_reg = MAX8925_LDOCTL##_id, \
|
||||
}
|
||||
|
||||
|
@ -261,6 +258,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
|
||||
struct max8925_platform_data *pdata = chip->dev->platform_data;
|
||||
struct regulator_config config = { };
|
||||
struct max8925_regulator_info *ri;
|
||||
struct regulator_dev *rdev;
|
||||
|
||||
|
@ -272,8 +270,11 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
|
|||
ri->i2c = chip->i2c;
|
||||
ri->chip = chip;
|
||||
|
||||
rdev = regulator_register(&ri->desc, &pdev->dev,
|
||||
pdata->regulator[pdev->id], ri, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdata->regulator[pdev->id];
|
||||
config.driver_data = ri;
|
||||
|
||||
rdev = regulator_register(&ri->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
ri->desc.name);
|
||||
|
|
|
@ -130,11 +130,10 @@ static int max8952_get_voltage(struct regulator_dev *rdev)
|
|||
return max8952_voltage(max8952, vid);
|
||||
}
|
||||
|
||||
static int max8952_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
static int max8952_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct max8952_data *max8952 = rdev_get_drvdata(rdev);
|
||||
s8 vid = -1, i;
|
||||
|
||||
if (!gpio_is_valid(max8952->pdata->gpio_vid0) ||
|
||||
!gpio_is_valid(max8952->pdata->gpio_vid1)) {
|
||||
|
@ -142,23 +141,10 @@ static int max8952_set_voltage(struct regulator_dev *rdev,
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX8952_NUM_DVS_MODE; i++) {
|
||||
int volt = max8952_voltage(max8952, i);
|
||||
|
||||
/* Set the voltage as low as possible within the range */
|
||||
if (volt <= max_uV && volt >= min_uV)
|
||||
if (vid == -1 || max8952_voltage(max8952, vid) > volt)
|
||||
vid = i;
|
||||
}
|
||||
|
||||
if (vid >= 0 && vid < MAX8952_NUM_DVS_MODE) {
|
||||
max8952->vid0 = (vid % 2 == 1);
|
||||
max8952->vid1 = (((vid >> 1) % 2) == 1);
|
||||
*selector = vid;
|
||||
gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0);
|
||||
gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1);
|
||||
} else
|
||||
return -EINVAL;
|
||||
max8952->vid0 = selector & 0x1;
|
||||
max8952->vid1 = (selector >> 1) & 0x1;
|
||||
gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0);
|
||||
gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -169,11 +155,11 @@ static struct regulator_ops max8952_ops = {
|
|||
.enable = max8952_enable,
|
||||
.disable = max8952_disable,
|
||||
.get_voltage = max8952_get_voltage,
|
||||
.set_voltage = max8952_set_voltage,
|
||||
.set_voltage_sel = max8952_set_voltage_sel,
|
||||
.set_suspend_disable = max8952_disable,
|
||||
};
|
||||
|
||||
static struct regulator_desc regulator = {
|
||||
static const struct regulator_desc regulator = {
|
||||
.name = "MAX8952_VOUT",
|
||||
.id = 0,
|
||||
.n_voltages = MAX8952_NUM_DVS_MODE,
|
||||
|
@ -187,6 +173,7 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
|
|||
{
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
struct max8952_platform_data *pdata = client->dev.platform_data;
|
||||
struct regulator_config config = { };
|
||||
struct max8952_data *max8952;
|
||||
|
||||
int ret = 0, err = 0;
|
||||
|
@ -207,8 +194,11 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
|
|||
max8952->dev = &client->dev;
|
||||
max8952->pdata = pdata;
|
||||
|
||||
max8952->rdev = regulator_register(®ulator, max8952->dev,
|
||||
&pdata->reg_data, max8952, NULL);
|
||||
config.dev = max8952->dev;
|
||||
config.init_data = &pdata->reg_data;
|
||||
config.driver_data = max8952;
|
||||
|
||||
max8952->rdev = regulator_register(®ulator, &config);
|
||||
|
||||
if (IS_ERR(max8952->rdev)) {
|
||||
ret = PTR_ERR(max8952->rdev);
|
||||
|
@ -217,8 +207,8 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
|
|||
}
|
||||
|
||||
max8952->en = !!(pdata->reg_data.constraints.boot_on);
|
||||
max8952->vid0 = (pdata->default_mode % 2) == 1;
|
||||
max8952->vid1 = ((pdata->default_mode >> 1) % 2) == 1;
|
||||
max8952->vid0 = pdata->default_mode & 0x1;
|
||||
max8952->vid1 = (pdata->default_mode >> 1) & 0x1;
|
||||
|
||||
if (gpio_is_valid(pdata->gpio_en)) {
|
||||
if (!gpio_request(pdata->gpio_en, "MAX8952 EN"))
|
||||
|
@ -241,13 +231,13 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
|
|||
gpio_is_valid(pdata->gpio_vid1)) {
|
||||
if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0"))
|
||||
gpio_direction_output(pdata->gpio_vid0,
|
||||
(pdata->default_mode) % 2);
|
||||
(pdata->default_mode) & 0x1);
|
||||
else
|
||||
err = 1;
|
||||
|
||||
if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1"))
|
||||
gpio_direction_output(pdata->gpio_vid1,
|
||||
(pdata->default_mode >> 1) % 2);
|
||||
(pdata->default_mode >> 1) & 0x1);
|
||||
else {
|
||||
if (!err)
|
||||
gpio_free(pdata->gpio_vid0);
|
||||
|
|
|
@ -68,29 +68,28 @@ struct voltage_map_desc {
|
|||
int min;
|
||||
int max;
|
||||
int step;
|
||||
unsigned int n_bits;
|
||||
};
|
||||
|
||||
/* Voltage maps in mV */
|
||||
static const struct voltage_map_desc ldo_voltage_map_desc = {
|
||||
.min = 800, .max = 3950, .step = 50, .n_bits = 6,
|
||||
.min = 800, .max = 3950, .step = 50,
|
||||
}; /* LDO1 ~ 18, 21 all */
|
||||
|
||||
static const struct voltage_map_desc buck1245_voltage_map_desc = {
|
||||
.min = 650, .max = 2225, .step = 25, .n_bits = 6,
|
||||
.min = 650, .max = 2225, .step = 25,
|
||||
}; /* Buck1, 2, 4, 5 */
|
||||
|
||||
static const struct voltage_map_desc buck37_voltage_map_desc = {
|
||||
.min = 750, .max = 3900, .step = 50, .n_bits = 6,
|
||||
.min = 750, .max = 3900, .step = 50,
|
||||
}; /* Buck3, 7 */
|
||||
|
||||
/* current map in mA */
|
||||
static const struct voltage_map_desc charger_current_map_desc = {
|
||||
.min = 200, .max = 950, .step = 50, .n_bits = 4,
|
||||
.min = 200, .max = 950, .step = 50,
|
||||
};
|
||||
|
||||
static const struct voltage_map_desc topoff_current_map_desc = {
|
||||
.min = 50, .max = 200, .step = 10, .n_bits = 4,
|
||||
.min = 50, .max = 200, .step = 10,
|
||||
};
|
||||
|
||||
static const struct voltage_map_desc *reg_voltage_map[] = {
|
||||
|
@ -320,6 +319,7 @@ static int max8997_reg_disable(struct regulator_dev *rdev)
|
|||
static int max8997_get_voltage_register(struct regulator_dev *rdev,
|
||||
int *_reg, int *_shift, int *_mask)
|
||||
{
|
||||
struct max8997_data *max8997 = rdev_get_drvdata(rdev);
|
||||
int rid = rdev_get_id(rdev);
|
||||
int reg, shift = 0, mask = 0x3f;
|
||||
|
||||
|
@ -329,9 +329,13 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev,
|
|||
break;
|
||||
case MAX8997_BUCK1:
|
||||
reg = MAX8997_REG_BUCK1DVS1;
|
||||
if (max8997->buck1_gpiodvs)
|
||||
reg += max8997->buck125_gpioindex;
|
||||
break;
|
||||
case MAX8997_BUCK2:
|
||||
reg = MAX8997_REG_BUCK2DVS1;
|
||||
if (max8997->buck2_gpiodvs)
|
||||
reg += max8997->buck125_gpioindex;
|
||||
break;
|
||||
case MAX8997_BUCK3:
|
||||
reg = MAX8997_REG_BUCK3DVS;
|
||||
|
@ -341,6 +345,8 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev,
|
|||
break;
|
||||
case MAX8997_BUCK5:
|
||||
reg = MAX8997_REG_BUCK5DVS1;
|
||||
if (max8997->buck5_gpiodvs)
|
||||
reg += max8997->buck125_gpioindex;
|
||||
break;
|
||||
case MAX8997_BUCK7:
|
||||
reg = MAX8997_REG_BUCK7DVS;
|
||||
|
@ -381,18 +387,12 @@ static int max8997_get_voltage(struct regulator_dev *rdev)
|
|||
struct max8997_data *max8997 = rdev_get_drvdata(rdev);
|
||||
struct i2c_client *i2c = max8997->iodev->i2c;
|
||||
int reg, shift, mask, ret;
|
||||
int rid = rdev_get_id(rdev);
|
||||
u8 val;
|
||||
|
||||
ret = max8997_get_voltage_register(rdev, ®, &shift, &mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((rid == MAX8997_BUCK1 && max8997->buck1_gpiodvs) ||
|
||||
(rid == MAX8997_BUCK2 && max8997->buck2_gpiodvs) ||
|
||||
(rid == MAX8997_BUCK5 && max8997->buck5_gpiodvs))
|
||||
reg += max8997->buck125_gpioindex;
|
||||
|
||||
ret = max8997_read_reg(i2c, reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -415,7 +415,7 @@ static inline int max8997_get_voltage_proper_val(
|
|||
const struct voltage_map_desc *desc,
|
||||
int min_vol, int max_vol)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
|
||||
if (desc == NULL)
|
||||
return -EINVAL;
|
||||
|
@ -423,16 +423,14 @@ static inline int max8997_get_voltage_proper_val(
|
|||
if (max_vol < desc->min || min_vol > desc->max)
|
||||
return -EINVAL;
|
||||
|
||||
while (desc->min + desc->step * i < min_vol &&
|
||||
desc->min + desc->step * i < desc->max)
|
||||
i++;
|
||||
if (min_vol < desc->min)
|
||||
min_vol = desc->min;
|
||||
|
||||
i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
|
||||
|
||||
if (desc->min + desc->step * i > max_vol)
|
||||
return -EINVAL;
|
||||
|
||||
if (i >= (1 << desc->n_bits))
|
||||
return -EINVAL;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -854,109 +852,65 @@ static struct regulator_ops max8997_charger_fixedstate_ops = {
|
|||
.set_current_limit = max8997_set_voltage_ldobuck_wrap,
|
||||
};
|
||||
|
||||
#define regulator_desc_ldo(num) { \
|
||||
.name = "LDO"#num, \
|
||||
.id = MAX8997_LDO##num, \
|
||||
.ops = &max8997_ldo_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
#define regulator_desc_buck(num) { \
|
||||
.name = "BUCK"#num, \
|
||||
.id = MAX8997_BUCK##num, \
|
||||
.ops = &max8997_buck_ops, \
|
||||
#define MAX8997_VOLTAGE_REGULATOR(_name, _ops) {\
|
||||
.name = #_name, \
|
||||
.id = MAX8997_##_name, \
|
||||
.ops = &_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
#define MAX8997_CURRENT_REGULATOR(_name, _ops) {\
|
||||
.name = #_name, \
|
||||
.id = MAX8997_##_name, \
|
||||
.ops = &_ops, \
|
||||
.type = REGULATOR_CURRENT, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
static struct regulator_desc regulators[] = {
|
||||
regulator_desc_ldo(1),
|
||||
regulator_desc_ldo(2),
|
||||
regulator_desc_ldo(3),
|
||||
regulator_desc_ldo(4),
|
||||
regulator_desc_ldo(5),
|
||||
regulator_desc_ldo(6),
|
||||
regulator_desc_ldo(7),
|
||||
regulator_desc_ldo(8),
|
||||
regulator_desc_ldo(9),
|
||||
regulator_desc_ldo(10),
|
||||
regulator_desc_ldo(11),
|
||||
regulator_desc_ldo(12),
|
||||
regulator_desc_ldo(13),
|
||||
regulator_desc_ldo(14),
|
||||
regulator_desc_ldo(15),
|
||||
regulator_desc_ldo(16),
|
||||
regulator_desc_ldo(17),
|
||||
regulator_desc_ldo(18),
|
||||
regulator_desc_ldo(21),
|
||||
regulator_desc_buck(1),
|
||||
regulator_desc_buck(2),
|
||||
regulator_desc_buck(3),
|
||||
regulator_desc_buck(4),
|
||||
regulator_desc_buck(5),
|
||||
{
|
||||
.name = "BUCK6",
|
||||
.id = MAX8997_BUCK6,
|
||||
.ops = &max8997_fixedvolt_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
regulator_desc_buck(7),
|
||||
{
|
||||
.name = "EN32KHz_AP",
|
||||
.id = MAX8997_EN32KHZ_AP,
|
||||
.ops = &max8997_fixedvolt_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "EN32KHz_CP",
|
||||
.id = MAX8997_EN32KHZ_CP,
|
||||
.ops = &max8997_fixedvolt_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "ENVICHG",
|
||||
.id = MAX8997_ENVICHG,
|
||||
.ops = &max8997_fixedvolt_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "ESAFEOUT1",
|
||||
.id = MAX8997_ESAFEOUT1,
|
||||
.ops = &max8997_safeout_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "ESAFEOUT2",
|
||||
.id = MAX8997_ESAFEOUT2,
|
||||
.ops = &max8997_safeout_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "CHARGER_CV",
|
||||
.id = MAX8997_CHARGER_CV,
|
||||
.ops = &max8997_fixedstate_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "CHARGER",
|
||||
.id = MAX8997_CHARGER,
|
||||
.ops = &max8997_charger_ops,
|
||||
.type = REGULATOR_CURRENT,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "CHARGER_TOPOFF",
|
||||
.id = MAX8997_CHARGER_TOPOFF,
|
||||
.ops = &max8997_charger_fixedstate_ops,
|
||||
.type = REGULATOR_CURRENT,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO1, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO2, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO3, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO4, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO5, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO6, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO7, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO8, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO9, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO10, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO11, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO12, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO13, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO14, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO15, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO16, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO17, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO18, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(LDO21, max8997_ldo_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(BUCK1, max8997_buck_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(BUCK2, max8997_buck_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(BUCK3, max8997_buck_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(BUCK4, max8997_buck_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(BUCK5, max8997_buck_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(BUCK6, max8997_fixedvolt_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(BUCK7, max8997_buck_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(EN32KHZ_AP, max8997_fixedvolt_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(EN32KHZ_CP, max8997_fixedvolt_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(ENVICHG, max8997_fixedvolt_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(ESAFEOUT1, max8997_safeout_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(ESAFEOUT2, max8997_safeout_ops),
|
||||
MAX8997_VOLTAGE_REGULATOR(CHARGER_CV, max8997_fixedstate_ops),
|
||||
MAX8997_CURRENT_REGULATOR(CHARGER, max8997_charger_ops),
|
||||
MAX8997_CURRENT_REGULATOR(CHARGER_TOPOFF,
|
||||
max8997_charger_fixedstate_ops),
|
||||
};
|
||||
|
||||
static __devinit int max8997_pmic_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev **rdev;
|
||||
struct max8997_data *max8997;
|
||||
struct i2c_client *i2c;
|
||||
|
@ -1140,8 +1094,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
|
|||
else if (id == MAX8997_CHARGER_CV)
|
||||
regulators[id].n_voltages = 16;
|
||||
|
||||
rdev[i] = regulator_register(®ulators[id], max8997->dev,
|
||||
pdata->regulators[i].initdata, max8997, NULL);
|
||||
config.dev = max8997->dev;
|
||||
config.init_data = pdata->regulators[i].initdata;
|
||||
config.driver_data = max8997;
|
||||
|
||||
rdev[i] = regulator_register(®ulators[id], &config);
|
||||
if (IS_ERR(rdev[i])) {
|
||||
ret = PTR_ERR(rdev[i]);
|
||||
dev_err(max8997->dev, "regulator init failed for %d\n",
|
||||
|
|
|
@ -277,7 +277,7 @@ static int max8998_get_voltage_register(struct regulator_dev *rdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int max8998_get_voltage(struct regulator_dev *rdev)
|
||||
static int max8998_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
|
||||
struct i2c_client *i2c = max8998->iodev->i2c;
|
||||
|
@ -295,7 +295,7 @@ static int max8998_get_voltage(struct regulator_dev *rdev)
|
|||
val >>= shift;
|
||||
val &= mask;
|
||||
|
||||
return max8998_list_voltage(rdev, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
|
||||
|
@ -306,8 +306,7 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
|
|||
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
|
||||
const struct voltage_map_desc *desc;
|
||||
int ldo = rdev_get_id(rdev);
|
||||
int reg, shift = 0, mask, ret;
|
||||
int i = 0;
|
||||
int reg, shift = 0, mask, ret, i;
|
||||
|
||||
if (ldo >= ARRAY_SIZE(ldo_voltage_map))
|
||||
return -EINVAL;
|
||||
|
@ -319,9 +318,10 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
|
|||
if (max_vol < desc->min || min_vol > desc->max)
|
||||
return -EINVAL;
|
||||
|
||||
while (desc->min + desc->step*i < min_vol &&
|
||||
desc->min + desc->step*i < desc->max)
|
||||
i++;
|
||||
if (min_vol < desc->min)
|
||||
min_vol = desc->min;
|
||||
|
||||
i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
|
||||
|
||||
if (desc->min + desc->step*i > max_vol)
|
||||
return -EINVAL;
|
||||
|
@ -359,8 +359,7 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
|
|||
const struct voltage_map_desc *desc;
|
||||
int buck = rdev_get_id(rdev);
|
||||
int reg, shift = 0, mask, ret;
|
||||
int difference = 0, i = 0, j = 0, previous_vol = 0;
|
||||
u8 val = 0;
|
||||
int i, j, previous_sel;
|
||||
static u8 buck1_last_val;
|
||||
|
||||
if (buck >= ARRAY_SIZE(ldo_voltage_map))
|
||||
|
@ -374,9 +373,10 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
|
|||
if (max_vol < desc->min || min_vol > desc->max)
|
||||
return -EINVAL;
|
||||
|
||||
while (desc->min + desc->step*i < min_vol &&
|
||||
desc->min + desc->step*i < desc->max)
|
||||
i++;
|
||||
if (min_vol < desc->min)
|
||||
min_vol = desc->min;
|
||||
|
||||
i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
|
||||
|
||||
if (desc->min + desc->step*i > max_vol)
|
||||
return -EINVAL;
|
||||
|
@ -387,13 +387,14 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
previous_vol = max8998_get_voltage(rdev);
|
||||
previous_sel = max8998_get_voltage_sel(rdev);
|
||||
|
||||
/* Check if voltage needs to be changed */
|
||||
/* if previous_voltage equal new voltage, return */
|
||||
if (previous_vol == max8998_list_voltage(rdev, i)) {
|
||||
if (previous_sel == i) {
|
||||
dev_dbg(max8998->dev, "No voltage change, old:%d, new:%d\n",
|
||||
previous_vol, max8998_list_voltage(rdev, i));
|
||||
max8998_list_voltage(rdev, previous_sel),
|
||||
max8998_list_voltage(rdev, i));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -482,19 +483,40 @@ buck2_exit:
|
|||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev,
|
||||
unsigned int old_selector,
|
||||
unsigned int new_selector)
|
||||
{
|
||||
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
|
||||
struct i2c_client *i2c = max8998->iodev->i2c;
|
||||
const struct voltage_map_desc *desc;
|
||||
int buck = rdev_get_id(rdev);
|
||||
u8 val = 0;
|
||||
int difference, ret;
|
||||
|
||||
if (buck < MAX8998_BUCK1 || buck > MAX8998_BUCK4)
|
||||
return -EINVAL;
|
||||
|
||||
desc = ldo_voltage_map[buck];
|
||||
|
||||
/* Voltage stabilization */
|
||||
max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val);
|
||||
ret = max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* lp3974 hasn't got ENRAMP bit - ramp is assumed as true */
|
||||
/* MAX8998 has ENRAMP bit implemented, so test it*/
|
||||
if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP))
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
difference = desc->min + desc->step*i - previous_vol/1000;
|
||||
difference = (new_selector - old_selector) * desc->step;
|
||||
if (difference > 0)
|
||||
udelay(difference / ((val & 0x0f) + 1));
|
||||
return difference / ((val & 0x0f) + 1);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct regulator_ops max8998_ldo_ops = {
|
||||
|
@ -502,7 +524,7 @@ static struct regulator_ops max8998_ldo_ops = {
|
|||
.is_enabled = max8998_ldo_is_enabled,
|
||||
.enable = max8998_ldo_enable,
|
||||
.disable = max8998_ldo_disable,
|
||||
.get_voltage = max8998_get_voltage,
|
||||
.get_voltage_sel = max8998_get_voltage_sel,
|
||||
.set_voltage = max8998_set_voltage_ldo,
|
||||
.set_suspend_enable = max8998_ldo_enable,
|
||||
.set_suspend_disable = max8998_ldo_disable,
|
||||
|
@ -513,8 +535,9 @@ static struct regulator_ops max8998_buck_ops = {
|
|||
.is_enabled = max8998_ldo_is_enabled,
|
||||
.enable = max8998_ldo_enable,
|
||||
.disable = max8998_ldo_disable,
|
||||
.get_voltage = max8998_get_voltage,
|
||||
.get_voltage_sel = max8998_get_voltage_sel,
|
||||
.set_voltage = max8998_set_voltage_buck,
|
||||
.set_voltage_time_sel = max8998_set_voltage_buck_time_sel,
|
||||
.set_suspend_enable = max8998_ldo_enable,
|
||||
.set_suspend_disable = max8998_ldo_disable,
|
||||
};
|
||||
|
@ -685,6 +708,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev **rdev;
|
||||
struct max8998_data *max8998;
|
||||
struct i2c_client *i2c;
|
||||
|
@ -840,8 +864,12 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
|||
int count = (desc->max - desc->min) / desc->step + 1;
|
||||
regulators[index].n_voltages = count;
|
||||
}
|
||||
rdev[i] = regulator_register(®ulators[index], max8998->dev,
|
||||
pdata->regulators[i].initdata, max8998, NULL);
|
||||
|
||||
config.dev = max8998->dev;
|
||||
config.init_data = pdata->regulators[i].initdata;
|
||||
config.driver_data = max8998;
|
||||
|
||||
rdev[i] = regulator_register(®ulators[index], &config);
|
||||
if (IS_ERR(rdev[i])) {
|
||||
ret = PTR_ERR(rdev[i]);
|
||||
dev_err(max8998->dev, "regulator init failed\n");
|
||||
|
|
|
@ -340,6 +340,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
|
|||
struct mc13xxx_regulator_platform_data *pdata =
|
||||
dev_get_platdata(&pdev->dev);
|
||||
struct mc13xxx_regulator_init_data *init_data;
|
||||
struct regulator_config config = { };
|
||||
int i, ret;
|
||||
|
||||
dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id);
|
||||
|
@ -357,11 +358,16 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
|
|||
priv->mc13xxx = mc13783;
|
||||
|
||||
for (i = 0; i < pdata->num_regulators; i++) {
|
||||
init_data = &pdata->regulators[i];
|
||||
priv->regulators[i] = regulator_register(
|
||||
&mc13783_regulators[init_data->id].desc,
|
||||
&pdev->dev, init_data->init_data, priv, NULL);
|
||||
struct regulator_desc *desc;
|
||||
|
||||
init_data = &pdata->regulators[i];
|
||||
desc = &mc13783_regulators[init_data->id].desc;
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = init_data->init_data;
|
||||
config.driver_data = priv;
|
||||
|
||||
priv->regulators[i] = regulator_register(desc, &config);
|
||||
if (IS_ERR(priv->regulators[i])) {
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
mc13783_regulators[i].desc.name);
|
||||
|
|
|
@ -428,24 +428,15 @@ static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev)
|
|||
return val;
|
||||
}
|
||||
|
||||
static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
|
||||
int hi, value, mask, id = rdev_get_id(rdev);
|
||||
u32 valread;
|
||||
int ret;
|
||||
|
||||
dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
|
||||
__func__, id, min_uV, max_uV);
|
||||
|
||||
/* Find the best index */
|
||||
value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV);
|
||||
dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value);
|
||||
if (value < 0)
|
||||
return value;
|
||||
|
||||
value = mc13892_regulators[id].voltages[value];
|
||||
value = mc13892_regulators[id].voltages[selector];
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13xxx_reg_read(priv->mc13xxx,
|
||||
|
@ -480,7 +471,7 @@ err:
|
|||
static struct regulator_ops mc13892_sw_regulator_ops = {
|
||||
.is_enabled = mc13xxx_sw_regulator_is_enabled,
|
||||
.list_voltage = mc13xxx_regulator_list_voltage,
|
||||
.set_voltage = mc13892_sw_regulator_set_voltage,
|
||||
.set_voltage_sel = mc13892_sw_regulator_set_voltage_sel,
|
||||
.get_voltage = mc13892_sw_regulator_get_voltage,
|
||||
};
|
||||
|
||||
|
@ -528,6 +519,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
|
|||
struct mc13xxx_regulator_platform_data *pdata =
|
||||
dev_get_platdata(&pdev->dev);
|
||||
struct mc13xxx_regulator_init_data *mc13xxx_data;
|
||||
struct regulator_config config = { };
|
||||
int i, ret;
|
||||
int num_regulators = 0;
|
||||
u32 val;
|
||||
|
@ -597,9 +589,12 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
|
|||
}
|
||||
desc = &mc13892_regulators[id].desc;
|
||||
|
||||
priv->regulators[i] = regulator_register(
|
||||
desc, &pdev->dev, init_data, priv, node);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = init_data;
|
||||
config.driver_data = priv;
|
||||
config.of_node = node;
|
||||
|
||||
priv->regulators[i] = regulator_register(desc, &config);
|
||||
if (IS_ERR(priv->regulators[i])) {
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
mc13892_regulators[i].desc.name);
|
||||
|
|
|
@ -94,62 +94,18 @@ int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage);
|
||||
|
||||
int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
|
||||
struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
|
||||
int reg_id = rdev_get_id(rdev);
|
||||
int i;
|
||||
int bestmatch;
|
||||
int bestindex;
|
||||
|
||||
/*
|
||||
* Locate the minimum voltage fitting the criteria on
|
||||
* this regulator. The switchable voltages are not
|
||||
* in strict falling order so we need to check them
|
||||
* all for the best match.
|
||||
*/
|
||||
bestmatch = INT_MAX;
|
||||
bestindex = -1;
|
||||
for (i = 0; i < mc13xxx_regulators[reg_id].desc.n_voltages; i++) {
|
||||
if (mc13xxx_regulators[reg_id].voltages[i] >= min_uV &&
|
||||
mc13xxx_regulators[reg_id].voltages[i] < bestmatch) {
|
||||
bestmatch = mc13xxx_regulators[reg_id].voltages[i];
|
||||
bestindex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestindex < 0 || bestmatch > max_uV) {
|
||||
dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n",
|
||||
min_uV, max_uV);
|
||||
return -EINVAL;
|
||||
}
|
||||
return bestindex;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index);
|
||||
|
||||
static int mc13xxx_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
|
||||
int max_uV, unsigned *selector)
|
||||
{
|
||||
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
|
||||
struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
|
||||
int value, id = rdev_get_id(rdev);
|
||||
int id = rdev_get_id(rdev);
|
||||
int ret;
|
||||
|
||||
dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
|
||||
__func__, id, min_uV, max_uV);
|
||||
|
||||
/* Find the best index */
|
||||
value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV);
|
||||
dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value);
|
||||
if (value < 0)
|
||||
return value;
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
|
||||
mc13xxx_regulators[id].vsel_mask,
|
||||
value << mc13xxx_regulators[id].vsel_shift);
|
||||
selector << mc13xxx_regulators[id].vsel_shift);
|
||||
mc13xxx_unlock(priv->mc13xxx);
|
||||
|
||||
return ret;
|
||||
|
@ -187,7 +143,7 @@ struct regulator_ops mc13xxx_regulator_ops = {
|
|||
.disable = mc13xxx_regulator_disable,
|
||||
.is_enabled = mc13xxx_regulator_is_enabled,
|
||||
.list_voltage = mc13xxx_regulator_list_voltage,
|
||||
.set_voltage = mc13xxx_regulator_set_voltage,
|
||||
.set_voltage_sel = mc13xxx_regulator_set_voltage_sel,
|
||||
.get_voltage = mc13xxx_regulator_get_voltage,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops);
|
||||
|
|
|
@ -35,8 +35,6 @@ struct mc13xxx_regulator_priv {
|
|||
|
||||
extern int mc13xxx_sw_regulator(struct regulator_dev *rdev);
|
||||
extern int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev);
|
||||
extern int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV);
|
||||
extern int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
|
||||
unsigned selector);
|
||||
extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
|
|
|
@ -150,57 +150,33 @@ static struct pcap_regulator vreg_table[] = {
|
|||
VREG_INFO(SW2S, PCAP_REG_LOWPWR, NA, 20, NA, NA), */
|
||||
};
|
||||
|
||||
static int pcap_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned *selector)
|
||||
static int pcap_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
|
||||
void *pcap = rdev_get_drvdata(rdev);
|
||||
int uV;
|
||||
u8 i;
|
||||
|
||||
/* the regulator doesn't support voltage switching */
|
||||
if (vreg->n_voltages == 1)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < vreg->n_voltages; i++) {
|
||||
/* For V1 the first is not the best match */
|
||||
if (i == 0 && rdev_get_id(rdev) == V1)
|
||||
i = 1;
|
||||
else if (i + 1 == vreg->n_voltages && rdev_get_id(rdev) == V1)
|
||||
i = 0;
|
||||
|
||||
uV = vreg->voltage_table[i] * 1000;
|
||||
if (min_uV <= uV && uV <= max_uV) {
|
||||
*selector = i;
|
||||
return ezx_pcap_set_bits(pcap, vreg->reg,
|
||||
(vreg->n_voltages - 1) << vreg->index,
|
||||
i << vreg->index);
|
||||
}
|
||||
|
||||
if (i == 0 && rdev_get_id(rdev) == V1)
|
||||
i = vreg->n_voltages - 1;
|
||||
}
|
||||
|
||||
/* the requested voltage range is not supported by this regulator */
|
||||
return -EINVAL;
|
||||
return ezx_pcap_set_bits(pcap, vreg->reg,
|
||||
(vreg->n_voltages - 1) << vreg->index,
|
||||
selector << vreg->index);
|
||||
}
|
||||
|
||||
static int pcap_regulator_get_voltage(struct regulator_dev *rdev)
|
||||
static int pcap_regulator_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
|
||||
void *pcap = rdev_get_drvdata(rdev);
|
||||
u32 tmp;
|
||||
int mV;
|
||||
|
||||
if (vreg->n_voltages == 1)
|
||||
return vreg->voltage_table[0] * 1000;
|
||||
return 0;
|
||||
|
||||
ezx_pcap_read(pcap, vreg->reg, &tmp);
|
||||
tmp = ((tmp >> vreg->index) & (vreg->n_voltages - 1));
|
||||
mV = vreg->voltage_table[tmp];
|
||||
|
||||
return mV * 1000;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int pcap_regulator_enable(struct regulator_dev *rdev)
|
||||
|
@ -248,8 +224,8 @@ static int pcap_regulator_list_voltage(struct regulator_dev *rdev,
|
|||
|
||||
static struct regulator_ops pcap_regulator_ops = {
|
||||
.list_voltage = pcap_regulator_list_voltage,
|
||||
.set_voltage = pcap_regulator_set_voltage,
|
||||
.get_voltage = pcap_regulator_get_voltage,
|
||||
.set_voltage_sel = pcap_regulator_set_voltage_sel,
|
||||
.get_voltage_sel = pcap_regulator_get_voltage_sel,
|
||||
.enable = pcap_regulator_enable,
|
||||
.disable = pcap_regulator_disable,
|
||||
.is_enabled = pcap_regulator_is_enabled,
|
||||
|
@ -265,7 +241,7 @@ static struct regulator_ops pcap_regulator_ops = {
|
|||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
static struct regulator_desc pcap_regulators[] = {
|
||||
static const struct regulator_desc pcap_regulators[] = {
|
||||
VREG(V1), VREG(V2), VREG(V3), VREG(V4), VREG(V5), VREG(V6), VREG(V7),
|
||||
VREG(V8), VREG(V9), VREG(V10), VREG(VAUX1), VREG(VAUX2), VREG(VAUX3),
|
||||
VREG(VAUX4), VREG(VSIM), VREG(VSIM2), VREG(VVIB), VREG(SW1), VREG(SW2),
|
||||
|
@ -275,9 +251,13 @@ static int __devinit pcap_regulator_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct regulator_dev *rdev;
|
||||
void *pcap = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_config config = { };
|
||||
|
||||
rdev = regulator_register(&pcap_regulators[pdev->id], &pdev->dev,
|
||||
pdev->dev.platform_data, pcap, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdev->dev.platform_data;
|
||||
config.driver_data = pcap;
|
||||
|
||||
rdev = regulator_register(&pcap_regulators[pdev->id], &config);
|
||||
if (IS_ERR(rdev))
|
||||
return PTR_ERR(rdev);
|
||||
|
||||
|
|
|
@ -24,35 +24,25 @@
|
|||
#include <linux/mfd/pcf50633/core.h>
|
||||
#include <linux/mfd/pcf50633/pmic.h>
|
||||
|
||||
#define PCF50633_REGULATOR(_name, _id, _n) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.id = _id, \
|
||||
.ops = &pcf50633_regulator_ops, \
|
||||
.n_voltages = _n, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
#define PCF50633_REGULATOR(_name, _id, _n) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.id = PCF50633_REGULATOR_##_id, \
|
||||
.ops = &pcf50633_regulator_ops, \
|
||||
.n_voltages = _n, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.vsel_reg = PCF50633_REG_##_id##OUT, \
|
||||
.vsel_mask = 0xff, \
|
||||
.enable_reg = PCF50633_REG_##_id##OUT + 1, \
|
||||
.enable_mask = PCF50633_REGULATOR_ON, \
|
||||
}
|
||||
|
||||
static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
|
||||
[PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT,
|
||||
[PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT,
|
||||
[PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT,
|
||||
[PCF50633_REGULATOR_MEMLDO] = PCF50633_REG_MEMLDOOUT,
|
||||
[PCF50633_REGULATOR_LDO1] = PCF50633_REG_LDO1OUT,
|
||||
[PCF50633_REGULATOR_LDO2] = PCF50633_REG_LDO2OUT,
|
||||
[PCF50633_REGULATOR_LDO3] = PCF50633_REG_LDO3OUT,
|
||||
[PCF50633_REGULATOR_LDO4] = PCF50633_REG_LDO4OUT,
|
||||
[PCF50633_REGULATOR_LDO5] = PCF50633_REG_LDO5OUT,
|
||||
[PCF50633_REGULATOR_LDO6] = PCF50633_REG_LDO6OUT,
|
||||
[PCF50633_REGULATOR_HCLDO] = PCF50633_REG_HCLDOOUT,
|
||||
};
|
||||
|
||||
/* Bits from voltage value */
|
||||
static u8 auto_voltage_bits(unsigned int millivolts)
|
||||
{
|
||||
if (millivolts < 1800)
|
||||
return 0;
|
||||
return 0x2f;
|
||||
if (millivolts > 3800)
|
||||
return 0xff;
|
||||
|
||||
|
@ -87,6 +77,9 @@ static u8 ldo_voltage_bits(unsigned int millivolts)
|
|||
/* Obtain voltage value from bits */
|
||||
static unsigned int auto_voltage_value(u8 bits)
|
||||
{
|
||||
/* AUTOOUT: 00000000 to 00101110 are reserved.
|
||||
* Return 0 for bits in reserved range, which means this selector code
|
||||
* can't be used on this system */
|
||||
if (bits < 0x2f)
|
||||
return 0;
|
||||
|
||||
|
@ -123,7 +116,7 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
|
|||
|
||||
millivolts = min_uV / 1000;
|
||||
|
||||
regnr = pcf50633_regulator_registers[regulator_id];
|
||||
regnr = rdev->desc->vsel_reg;
|
||||
|
||||
switch (regulator_id) {
|
||||
case PCF50633_REGULATOR_AUTO:
|
||||
|
@ -154,20 +147,22 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
|
|||
return pcf50633_reg_write(pcf, regnr, volt_bits);
|
||||
}
|
||||
|
||||
static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
|
||||
u8 bits)
|
||||
static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
|
||||
unsigned int index)
|
||||
{
|
||||
int regulator_id = rdev_get_id(rdev);
|
||||
|
||||
int millivolts;
|
||||
|
||||
switch (id) {
|
||||
switch (regulator_id) {
|
||||
case PCF50633_REGULATOR_AUTO:
|
||||
millivolts = auto_voltage_value(bits);
|
||||
millivolts = auto_voltage_value(index);
|
||||
break;
|
||||
case PCF50633_REGULATOR_DOWN1:
|
||||
millivolts = down_voltage_value(bits);
|
||||
millivolts = down_voltage_value(index);
|
||||
break;
|
||||
case PCF50633_REGULATOR_DOWN2:
|
||||
millivolts = down_voltage_value(bits);
|
||||
millivolts = down_voltage_value(index);
|
||||
break;
|
||||
case PCF50633_REGULATOR_LDO1:
|
||||
case PCF50633_REGULATOR_LDO2:
|
||||
|
@ -177,7 +172,7 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
|
|||
case PCF50633_REGULATOR_LDO6:
|
||||
case PCF50633_REGULATOR_HCLDO:
|
||||
case PCF50633_REGULATOR_MEMLDO:
|
||||
millivolts = ldo_voltage_value(bits);
|
||||
millivolts = ldo_voltage_value(index);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -186,140 +181,44 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
|
|||
return millivolts * 1000;
|
||||
}
|
||||
|
||||
static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pcf50633 *pcf;
|
||||
int regulator_id;
|
||||
u8 volt_bits, regnr;
|
||||
|
||||
pcf = rdev_get_drvdata(rdev);
|
||||
|
||||
regulator_id = rdev_get_id(rdev);
|
||||
if (regulator_id >= PCF50633_NUM_REGULATORS)
|
||||
return -EINVAL;
|
||||
|
||||
regnr = pcf50633_regulator_registers[regulator_id];
|
||||
|
||||
volt_bits = pcf50633_reg_read(pcf, regnr);
|
||||
|
||||
return pcf50633_regulator_voltage_value(regulator_id, volt_bits);
|
||||
}
|
||||
|
||||
static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
|
||||
unsigned int index)
|
||||
{
|
||||
struct pcf50633 *pcf;
|
||||
int regulator_id;
|
||||
|
||||
pcf = rdev_get_drvdata(rdev);
|
||||
|
||||
regulator_id = rdev_get_id(rdev);
|
||||
|
||||
switch (regulator_id) {
|
||||
case PCF50633_REGULATOR_AUTO:
|
||||
index += 0x2f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return pcf50633_regulator_voltage_value(regulator_id, index);
|
||||
}
|
||||
|
||||
static int pcf50633_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pcf50633 *pcf = rdev_get_drvdata(rdev);
|
||||
int regulator_id;
|
||||
u8 regnr;
|
||||
|
||||
regulator_id = rdev_get_id(rdev);
|
||||
if (regulator_id >= PCF50633_NUM_REGULATORS)
|
||||
return -EINVAL;
|
||||
|
||||
/* The *ENA register is always one after the *OUT register */
|
||||
regnr = pcf50633_regulator_registers[regulator_id] + 1;
|
||||
|
||||
return pcf50633_reg_set_bit_mask(pcf, regnr, PCF50633_REGULATOR_ON,
|
||||
PCF50633_REGULATOR_ON);
|
||||
}
|
||||
|
||||
static int pcf50633_regulator_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pcf50633 *pcf = rdev_get_drvdata(rdev);
|
||||
int regulator_id;
|
||||
u8 regnr;
|
||||
|
||||
regulator_id = rdev_get_id(rdev);
|
||||
if (regulator_id >= PCF50633_NUM_REGULATORS)
|
||||
return -EINVAL;
|
||||
|
||||
/* the *ENA register is always one after the *OUT register */
|
||||
regnr = pcf50633_regulator_registers[regulator_id] + 1;
|
||||
|
||||
return pcf50633_reg_set_bit_mask(pcf, regnr,
|
||||
PCF50633_REGULATOR_ON, 0);
|
||||
}
|
||||
|
||||
static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pcf50633 *pcf = rdev_get_drvdata(rdev);
|
||||
int regulator_id = rdev_get_id(rdev);
|
||||
u8 regnr;
|
||||
|
||||
regulator_id = rdev_get_id(rdev);
|
||||
if (regulator_id >= PCF50633_NUM_REGULATORS)
|
||||
return -EINVAL;
|
||||
|
||||
/* the *ENA register is always one after the *OUT register */
|
||||
regnr = pcf50633_regulator_registers[regulator_id] + 1;
|
||||
|
||||
return pcf50633_reg_read(pcf, regnr) & PCF50633_REGULATOR_ON;
|
||||
}
|
||||
|
||||
static struct regulator_ops pcf50633_regulator_ops = {
|
||||
.set_voltage = pcf50633_regulator_set_voltage,
|
||||
.get_voltage = pcf50633_regulator_get_voltage,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = pcf50633_regulator_list_voltage,
|
||||
.enable = pcf50633_regulator_enable,
|
||||
.disable = pcf50633_regulator_disable,
|
||||
.is_enabled = pcf50633_regulator_is_enabled,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_desc regulators[] = {
|
||||
[PCF50633_REGULATOR_AUTO] =
|
||||
PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 81),
|
||||
[PCF50633_REGULATOR_DOWN1] =
|
||||
PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 96),
|
||||
[PCF50633_REGULATOR_DOWN2] =
|
||||
PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 96),
|
||||
[PCF50633_REGULATOR_LDO1] =
|
||||
PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 28),
|
||||
[PCF50633_REGULATOR_LDO2] =
|
||||
PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 28),
|
||||
[PCF50633_REGULATOR_LDO3] =
|
||||
PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 28),
|
||||
[PCF50633_REGULATOR_LDO4] =
|
||||
PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 28),
|
||||
[PCF50633_REGULATOR_LDO5] =
|
||||
PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 28),
|
||||
[PCF50633_REGULATOR_LDO6] =
|
||||
PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 28),
|
||||
[PCF50633_REGULATOR_HCLDO] =
|
||||
PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 28),
|
||||
[PCF50633_REGULATOR_MEMLDO] =
|
||||
PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 28),
|
||||
static const struct regulator_desc regulators[] = {
|
||||
[PCF50633_REGULATOR_AUTO] = PCF50633_REGULATOR("auto", AUTO, 128),
|
||||
[PCF50633_REGULATOR_DOWN1] = PCF50633_REGULATOR("down1", DOWN1, 96),
|
||||
[PCF50633_REGULATOR_DOWN2] = PCF50633_REGULATOR("down2", DOWN2, 96),
|
||||
[PCF50633_REGULATOR_LDO1] = PCF50633_REGULATOR("ldo1", LDO1, 28),
|
||||
[PCF50633_REGULATOR_LDO2] = PCF50633_REGULATOR("ldo2", LDO2, 28),
|
||||
[PCF50633_REGULATOR_LDO3] = PCF50633_REGULATOR("ldo3", LDO3, 28),
|
||||
[PCF50633_REGULATOR_LDO4] = PCF50633_REGULATOR("ldo4", LDO4, 28),
|
||||
[PCF50633_REGULATOR_LDO5] = PCF50633_REGULATOR("ldo5", LDO5, 28),
|
||||
[PCF50633_REGULATOR_LDO6] = PCF50633_REGULATOR("ldo6", LDO6, 28),
|
||||
[PCF50633_REGULATOR_HCLDO] = PCF50633_REGULATOR("hcldo", HCLDO, 28),
|
||||
[PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28),
|
||||
};
|
||||
|
||||
static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_dev *rdev;
|
||||
struct pcf50633 *pcf;
|
||||
struct regulator_config config = { };
|
||||
|
||||
/* Already set by core driver */
|
||||
pcf = dev_to_pcf50633(pdev->dev.parent);
|
||||
|
||||
rdev = regulator_register(®ulators[pdev->id], &pdev->dev,
|
||||
pdev->dev.platform_data, pcf, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdev->dev.platform_data;
|
||||
config.driver_data = pcf;
|
||||
config.regmap = pcf->regmap;
|
||||
|
||||
rdev = regulator_register(®ulators[pdev->id], &config);
|
||||
if (IS_ERR(rdev))
|
||||
return PTR_ERR(rdev);
|
||||
|
||||
|
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* Regulator driver for RICOH RC5T583 power management chip.
|
||||
*
|
||||
* Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
* Author: Laxman dewangan <ldewangan@nvidia.com>
|
||||
*
|
||||
* based on code
|
||||
* Copyright (C) 2011 RICOH COMPANY,LTD
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/mfd/rc5t583.h>
|
||||
|
||||
struct rc5t583_regulator_info {
|
||||
int deepsleep_id;
|
||||
|
||||
/* Regulator register address.*/
|
||||
uint8_t reg_disc_reg;
|
||||
uint8_t disc_bit;
|
||||
uint8_t deepsleep_reg;
|
||||
|
||||
/* Chip constraints on regulator behavior */
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
int step_uV;
|
||||
|
||||
/* Regulator specific turn-on delay and voltage settling time*/
|
||||
int enable_uv_per_us;
|
||||
int change_uv_per_us;
|
||||
|
||||
/* Used by regulator core */
|
||||
struct regulator_desc desc;
|
||||
};
|
||||
|
||||
struct rc5t583_regulator {
|
||||
struct rc5t583_regulator_info *reg_info;
|
||||
|
||||
/* Devices */
|
||||
struct device *dev;
|
||||
struct rc5t583 *mfd;
|
||||
struct regulator_dev *rdev;
|
||||
};
|
||||
|
||||
static int rc5t583_list_voltage(struct regulator_dev *rdev, unsigned selector)
|
||||
{
|
||||
struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
|
||||
struct rc5t583_regulator_info *ri = reg->reg_info;
|
||||
return ri->min_uV + (ri->step_uV * selector);
|
||||
}
|
||||
|
||||
static int rc5t583_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
{
|
||||
struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
|
||||
struct rc5t583_regulator_info *ri = reg->reg_info;
|
||||
int sel, ret;
|
||||
|
||||
if (min_uV < ri->min_uV)
|
||||
min_uV = ri->min_uV;
|
||||
|
||||
sel = DIV_ROUND_UP(min_uV - ri->min_uV, ri->step_uV);
|
||||
|
||||
if (sel >= rdev->desc->n_voltages) {
|
||||
dev_err(&rdev->dev, "Invalid selector 0x%02x\n", sel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*selector = sel;
|
||||
|
||||
ret = rc5t583_update(reg->mfd->dev, rdev->desc->vsel_reg, sel,
|
||||
rdev->desc->vsel_mask);
|
||||
if (ret < 0)
|
||||
dev_err(&rdev->dev, "Error in update voltage register 0x%02x\n",
|
||||
rdev->desc->vsel_reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rc5t583_regulator_enable_time(struct regulator_dev *rdev)
|
||||
{
|
||||
struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
|
||||
int vsel = regulator_get_voltage_sel_regmap(rdev);
|
||||
int curr_uV = rc5t583_list_voltage(rdev, vsel);
|
||||
|
||||
return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us);
|
||||
}
|
||||
|
||||
static int rc5t583_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
unsigned int old_selector, unsigned int new_selector)
|
||||
{
|
||||
struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
|
||||
int old_uV, new_uV;
|
||||
old_uV = rc5t583_list_voltage(rdev, old_selector);
|
||||
|
||||
if (old_uV < 0)
|
||||
return old_uV;
|
||||
|
||||
new_uV = rc5t583_list_voltage(rdev, new_selector);
|
||||
if (new_uV < 0)
|
||||
return new_uV;
|
||||
|
||||
return DIV_ROUND_UP(abs(old_uV - new_uV),
|
||||
reg->reg_info->change_uv_per_us);
|
||||
}
|
||||
|
||||
|
||||
static struct regulator_ops rc5t583_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.enable_time = rc5t583_regulator_enable_time,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage = rc5t583_set_voltage,
|
||||
.list_voltage = rc5t583_list_voltage,
|
||||
.set_voltage_time_sel = rc5t583_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
#define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \
|
||||
_vout_mask, _min_mv, _max_mv, _step_uV, _enable_mv) \
|
||||
{ \
|
||||
.reg_disc_reg = RC5T583_REG_##_disc_reg, \
|
||||
.disc_bit = _disc_bit, \
|
||||
.deepsleep_reg = RC5T583_REG_##_id##DAC_DS, \
|
||||
.min_uV = _min_mv * 1000, \
|
||||
.max_uV = _max_mv * 1000, \
|
||||
.step_uV = _step_uV, \
|
||||
.enable_uv_per_us = _enable_mv * 1000, \
|
||||
.change_uv_per_us = 40 * 1000, \
|
||||
.deepsleep_id = RC5T583_DS_##_id, \
|
||||
.desc = { \
|
||||
.name = "rc5t583-regulator-"#_id, \
|
||||
.id = RC5T583_REGULATOR_##_id, \
|
||||
.n_voltages = (_max_mv - _min_mv) * 1000 / _step_uV + 1, \
|
||||
.ops = &rc5t583_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.vsel_reg = RC5T583_REG_##_id##DAC, \
|
||||
.vsel_mask = _vout_mask, \
|
||||
.enable_reg = RC5T583_REG_##_en_reg, \
|
||||
.enable_mask = BIT(_en_bit), \
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct rc5t583_regulator_info rc5t583_reg_info[RC5T583_REGULATOR_MAX] = {
|
||||
RC5T583_REG(DC0, DC0CTL, 0, DC0CTL, 1, 0x7F, 700, 1500, 12500, 4),
|
||||
RC5T583_REG(DC1, DC1CTL, 0, DC1CTL, 1, 0x7F, 700, 1500, 12500, 14),
|
||||
RC5T583_REG(DC2, DC2CTL, 0, DC2CTL, 1, 0x7F, 900, 2400, 12500, 14),
|
||||
RC5T583_REG(DC3, DC3CTL, 0, DC3CTL, 1, 0x7F, 900, 2400, 12500, 14),
|
||||
RC5T583_REG(LDO0, LDOEN2, 0, LDODIS2, 0, 0x7F, 900, 3400, 25000, 160),
|
||||
RC5T583_REG(LDO1, LDOEN2, 1, LDODIS2, 1, 0x7F, 900, 3400, 25000, 160),
|
||||
RC5T583_REG(LDO2, LDOEN2, 2, LDODIS2, 2, 0x7F, 900, 3400, 25000, 160),
|
||||
RC5T583_REG(LDO3, LDOEN2, 3, LDODIS2, 3, 0x7F, 900, 3400, 25000, 160),
|
||||
RC5T583_REG(LDO4, LDOEN2, 4, LDODIS2, 4, 0x3F, 750, 1500, 12500, 133),
|
||||
RC5T583_REG(LDO5, LDOEN2, 5, LDODIS2, 5, 0x7F, 900, 3400, 25000, 267),
|
||||
RC5T583_REG(LDO6, LDOEN2, 6, LDODIS2, 6, 0x7F, 900, 3400, 25000, 133),
|
||||
RC5T583_REG(LDO7, LDOEN2, 7, LDODIS2, 7, 0x7F, 900, 3400, 25000, 233),
|
||||
RC5T583_REG(LDO8, LDOEN1, 0, LDODIS1, 0, 0x7F, 900, 3400, 25000, 233),
|
||||
RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133),
|
||||
};
|
||||
|
||||
static int __devinit rc5t583_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
|
||||
struct regulator_init_data *reg_data;
|
||||
struct regulator_config config = { };
|
||||
struct rc5t583_regulator *reg = NULL;
|
||||
struct rc5t583_regulator *regs;
|
||||
struct regulator_dev *rdev;
|
||||
struct rc5t583_regulator_info *ri;
|
||||
int ret;
|
||||
int id;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "No platform data, exiting...\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX *
|
||||
sizeof(struct rc5t583_regulator), GFP_KERNEL);
|
||||
if (!regs) {
|
||||
dev_err(&pdev->dev, "Memory allocation failed exiting..\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) {
|
||||
reg_data = pdata->reg_init_data[id];
|
||||
|
||||
/* No need to register if there is no regulator data */
|
||||
if (!reg_data)
|
||||
continue;
|
||||
|
||||
reg = ®s[id];
|
||||
ri = &rc5t583_reg_info[id];
|
||||
reg->reg_info = ri;
|
||||
reg->mfd = rc5t583;
|
||||
reg->dev = &pdev->dev;
|
||||
|
||||
if (ri->deepsleep_id == RC5T583_DS_NONE)
|
||||
goto skip_ext_pwr_config;
|
||||
|
||||
ret = rc5t583_ext_power_req_config(rc5t583->dev,
|
||||
ri->deepsleep_id,
|
||||
pdata->regulator_ext_pwr_control[id],
|
||||
pdata->regulator_deepsleep_slot[id]);
|
||||
/*
|
||||
* Configuring external control is not a major issue,
|
||||
* just give warning.
|
||||
*/
|
||||
if (ret < 0)
|
||||
dev_warn(&pdev->dev,
|
||||
"Failed to configure ext control %d\n", id);
|
||||
|
||||
skip_ext_pwr_config:
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = reg_data;
|
||||
config.driver_data = reg;
|
||||
config.regmap = rc5t583->regmap;
|
||||
|
||||
rdev = regulator_register(&ri->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "Failed to register regulator %s\n",
|
||||
ri->desc.name);
|
||||
ret = PTR_ERR(rdev);
|
||||
goto clean_exit;
|
||||
}
|
||||
reg->rdev = rdev;
|
||||
}
|
||||
platform_set_drvdata(pdev, regs);
|
||||
return 0;
|
||||
|
||||
clean_exit:
|
||||
while (--id >= 0)
|
||||
regulator_unregister(regs[id].rdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit rc5t583_regulator_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rc5t583_regulator *regs = platform_get_drvdata(pdev);
|
||||
int id;
|
||||
|
||||
for (id = 0; id < RC5T583_REGULATOR_MAX; ++id)
|
||||
regulator_unregister(regs[id].rdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rc5t583_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "rc5t583-regulator",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = rc5t583_regulator_probe,
|
||||
.remove = __devexit_p(rc5t583_regulator_remove),
|
||||
};
|
||||
|
||||
static int __init rc5t583_regulator_init(void)
|
||||
{
|
||||
return platform_driver_register(&rc5t583_regulator_driver);
|
||||
}
|
||||
subsys_initcall(rc5t583_regulator_init);
|
||||
|
||||
static void __exit rc5t583_regulator_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rc5t583_regulator_driver);
|
||||
}
|
||||
module_exit(rc5t583_regulator_exit);
|
||||
|
||||
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
|
||||
MODULE_DESCRIPTION("RC5T583 regulator driver");
|
||||
MODULE_ALIAS("platform:rc5t583-regulator");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -28,6 +28,7 @@ struct s5m8767_info {
|
|||
struct s5m87xx_dev *iodev;
|
||||
int num_regulators;
|
||||
struct regulator_dev **rdev;
|
||||
struct s5m_opmode_data *opmode;
|
||||
|
||||
int ramp_delay;
|
||||
bool buck2_ramp;
|
||||
|
@ -141,9 +142,56 @@ static int s5m8767_list_voltage(struct regulator_dev *rdev,
|
|||
return val;
|
||||
}
|
||||
|
||||
static int s5m8767_get_register(struct regulator_dev *rdev, int *reg)
|
||||
unsigned int s5m8767_opmode_reg[][4] = {
|
||||
/* {OFF, ON, LOWPOWER, SUSPEND} */
|
||||
/* LDO1 ... LDO28 */
|
||||
{0x0, 0x3, 0x2, 0x1}, /* LDO1 */
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x0, 0x0, 0x0},
|
||||
{0x0, 0x3, 0x2, 0x1}, /* LDO5 */
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1}, /* LDO10 */
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1}, /* LDO15 */
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x0, 0x0, 0x0},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1}, /* LDO20 */
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x0, 0x0, 0x0},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1}, /* LDO25 */
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1}, /* LDO28 */
|
||||
|
||||
/* BUCK1 ... BUCK9 */
|
||||
{0x0, 0x3, 0x1, 0x1}, /* BUCK1 */
|
||||
{0x0, 0x3, 0x1, 0x1},
|
||||
{0x0, 0x3, 0x1, 0x1},
|
||||
{0x0, 0x3, 0x1, 0x1},
|
||||
{0x0, 0x3, 0x2, 0x1}, /* BUCK5 */
|
||||
{0x0, 0x3, 0x1, 0x1},
|
||||
{0x0, 0x3, 0x1, 0x1},
|
||||
{0x0, 0x3, 0x1, 0x1},
|
||||
{0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
|
||||
};
|
||||
|
||||
static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
|
||||
int *enable_ctrl)
|
||||
{
|
||||
int reg_id = rdev_get_id(rdev);
|
||||
unsigned int mode;
|
||||
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
||||
|
||||
switch (reg_id) {
|
||||
case S5M8767_LDO1 ... S5M8767_LDO2:
|
||||
|
@ -168,6 +216,8 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
mode = s5m8767->opmode[reg_id].mode;
|
||||
*enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -175,10 +225,10 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
|
|||
{
|
||||
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
||||
int ret, reg;
|
||||
int mask = 0xc0, pattern = 0xc0;
|
||||
int mask = 0xc0, enable_ctrl;
|
||||
u8 val;
|
||||
|
||||
ret = s5m8767_get_register(rdev, ®);
|
||||
ret = s5m8767_get_register(rdev, ®, &enable_ctrl);
|
||||
if (ret == -EINVAL)
|
||||
return 1;
|
||||
else if (ret)
|
||||
|
@ -188,33 +238,33 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return (val & mask) == pattern;
|
||||
return (val & mask) == enable_ctrl;
|
||||
}
|
||||
|
||||
static int s5m8767_reg_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
||||
int ret, reg;
|
||||
int mask = 0xc0, pattern = 0xc0;
|
||||
int mask = 0xc0, enable_ctrl;
|
||||
|
||||
ret = s5m8767_get_register(rdev, ®);
|
||||
ret = s5m8767_get_register(rdev, ®, &enable_ctrl);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return s5m_reg_update(s5m8767->iodev, reg, pattern, mask);
|
||||
return s5m_reg_update(s5m8767->iodev, reg, enable_ctrl, mask);
|
||||
}
|
||||
|
||||
static int s5m8767_reg_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
||||
int ret, reg;
|
||||
int mask = 0xc0, pattern = 0xc0;
|
||||
int mask = 0xc0, enable_ctrl;
|
||||
|
||||
ret = s5m8767_get_register(rdev, ®);
|
||||
ret = s5m8767_get_register(rdev, ®, &enable_ctrl);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask);
|
||||
return s5m_reg_update(s5m8767->iodev, reg, ~mask, mask);
|
||||
}
|
||||
|
||||
static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg)
|
||||
|
@ -305,51 +355,6 @@ static int s5m8767_convert_voltage_to_sel(
|
|||
return selector;
|
||||
}
|
||||
|
||||
static int s5m8767_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
{
|
||||
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
||||
const struct s5m_voltage_desc *desc;
|
||||
int reg_id = rdev_get_id(rdev);
|
||||
int sel, reg, mask, ret;
|
||||
u8 val;
|
||||
|
||||
switch (reg_id) {
|
||||
case S5M8767_LDO1 ... S5M8767_LDO28:
|
||||
mask = 0x3f;
|
||||
break;
|
||||
case S5M8767_BUCK1 ... S5M8767_BUCK6:
|
||||
mask = 0xff;
|
||||
break;
|
||||
case S5M8767_BUCK7 ... S5M8767_BUCK8:
|
||||
return -EINVAL;
|
||||
case S5M8767_BUCK9:
|
||||
mask = 0xff;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc = reg_voltage_map[reg_id];
|
||||
|
||||
sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
|
||||
if (sel < 0)
|
||||
return sel;
|
||||
|
||||
ret = s5m8767_get_voltage_register(rdev, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
s5m_reg_read(s5m8767->iodev, reg, &val);
|
||||
val &= ~mask;
|
||||
val |= sel;
|
||||
|
||||
ret = s5m_reg_write(s5m8767->iodev, reg, val);
|
||||
*selector = sel;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
|
||||
{
|
||||
int temp_index = s5m8767->buck_gpioindex;
|
||||
|
@ -368,70 +373,70 @@ static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
|
|||
gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
|
||||
}
|
||||
|
||||
static int s5m8767_set_voltage_buck(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
static int s5m8767_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
{
|
||||
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
||||
int reg_id = rdev_get_id(rdev);
|
||||
const struct s5m_voltage_desc *desc;
|
||||
int new_val, old_val, i = 0;
|
||||
|
||||
if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6)
|
||||
return -EINVAL;
|
||||
int reg_id = rdev_get_id(rdev);
|
||||
int sel, reg, mask, ret = 0, old_index, index = 0;
|
||||
u8 val;
|
||||
u8 *buck234_vol = NULL;
|
||||
|
||||
switch (reg_id) {
|
||||
case S5M8767_BUCK1:
|
||||
return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
|
||||
case S5M8767_BUCK2 ... S5M8767_BUCK4:
|
||||
case S5M8767_LDO1 ... S5M8767_LDO28:
|
||||
mask = 0x3f;
|
||||
break;
|
||||
case S5M8767_BUCK5 ... S5M8767_BUCK6:
|
||||
return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
|
||||
case S5M8767_BUCK1 ... S5M8767_BUCK6:
|
||||
mask = 0xff;
|
||||
if (reg_id == S5M8767_BUCK2 && s5m8767->buck2_gpiodvs)
|
||||
buck234_vol = &s5m8767->buck2_vol[0];
|
||||
else if (reg_id == S5M8767_BUCK3 && s5m8767->buck3_gpiodvs)
|
||||
buck234_vol = &s5m8767->buck3_vol[0];
|
||||
else if (reg_id == S5M8767_BUCK4 && s5m8767->buck4_gpiodvs)
|
||||
buck234_vol = &s5m8767->buck4_vol[0];
|
||||
break;
|
||||
case S5M8767_BUCK7 ... S5M8767_BUCK8:
|
||||
return -EINVAL;
|
||||
case S5M8767_BUCK9:
|
||||
return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
|
||||
mask = 0xff;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc = reg_voltage_map[reg_id];
|
||||
new_val = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
|
||||
if (new_val < 0)
|
||||
return new_val;
|
||||
|
||||
switch (reg_id) {
|
||||
case S5M8767_BUCK2:
|
||||
if (s5m8767->buck2_gpiodvs) {
|
||||
while (s5m8767->buck2_vol[i] != new_val)
|
||||
i++;
|
||||
} else
|
||||
return s5m8767_set_voltage(rdev, min_uV,
|
||||
max_uV, selector);
|
||||
break;
|
||||
case S5M8767_BUCK3:
|
||||
if (s5m8767->buck3_gpiodvs) {
|
||||
while (s5m8767->buck3_vol[i] != new_val)
|
||||
i++;
|
||||
} else
|
||||
return s5m8767_set_voltage(rdev, min_uV,
|
||||
max_uV, selector);
|
||||
break;
|
||||
case S5M8767_BUCK4:
|
||||
if (s5m8767->buck3_gpiodvs) {
|
||||
while (s5m8767->buck4_vol[i] != new_val)
|
||||
i++;
|
||||
} else
|
||||
return s5m8767_set_voltage(rdev, min_uV,
|
||||
max_uV, selector);
|
||||
break;
|
||||
sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
|
||||
if (sel < 0)
|
||||
return sel;
|
||||
|
||||
/* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */
|
||||
if (buck234_vol) {
|
||||
while (*buck234_vol != sel) {
|
||||
buck234_vol++;
|
||||
index++;
|
||||
}
|
||||
old_index = s5m8767->buck_gpioindex;
|
||||
s5m8767->buck_gpioindex = index;
|
||||
|
||||
if (index > old_index)
|
||||
s5m8767_set_high(s5m8767);
|
||||
else
|
||||
s5m8767_set_low(s5m8767);
|
||||
} else {
|
||||
ret = s5m8767_get_voltage_register(rdev, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
s5m_reg_read(s5m8767->iodev, reg, &val);
|
||||
val = (val & ~mask) | sel;
|
||||
|
||||
ret = s5m_reg_write(s5m8767->iodev, reg, val);
|
||||
}
|
||||
|
||||
old_val = s5m8767->buck_gpioindex;
|
||||
s5m8767->buck_gpioindex = i;
|
||||
|
||||
if (i > old_val)
|
||||
s5m8767_set_high(s5m8767);
|
||||
else
|
||||
s5m8767_set_low(s5m8767);
|
||||
|
||||
*selector = new_val;
|
||||
return 0;
|
||||
*selector = sel;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
|
@ -450,7 +455,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct regulator_ops s5m8767_ldo_ops = {
|
||||
static struct regulator_ops s5m8767_ops = {
|
||||
.list_voltage = s5m8767_list_voltage,
|
||||
.is_enabled = s5m8767_reg_is_enabled,
|
||||
.enable = s5m8767_reg_enable,
|
||||
|
@ -460,75 +465,59 @@ static struct regulator_ops s5m8767_ldo_ops = {
|
|||
.set_voltage_time_sel = s5m8767_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static struct regulator_ops s5m8767_buck_ops = {
|
||||
.list_voltage = s5m8767_list_voltage,
|
||||
.is_enabled = s5m8767_reg_is_enabled,
|
||||
.enable = s5m8767_reg_enable,
|
||||
.disable = s5m8767_reg_disable,
|
||||
.get_voltage_sel = s5m8767_get_voltage_sel,
|
||||
.set_voltage = s5m8767_set_voltage_buck,
|
||||
.set_voltage_time_sel = s5m8767_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
#define regulator_desc_ldo(num) { \
|
||||
.name = "LDO"#num, \
|
||||
.id = S5M8767_LDO##num, \
|
||||
.ops = &s5m8767_ldo_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
#define regulator_desc_buck(num) { \
|
||||
.name = "BUCK"#num, \
|
||||
.id = S5M8767_BUCK##num, \
|
||||
.ops = &s5m8767_buck_ops, \
|
||||
#define s5m8767_regulator_desc(_name) { \
|
||||
.name = #_name, \
|
||||
.id = S5M8767_##_name, \
|
||||
.ops = &s5m8767_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
static struct regulator_desc regulators[] = {
|
||||
regulator_desc_ldo(1),
|
||||
regulator_desc_ldo(2),
|
||||
regulator_desc_ldo(3),
|
||||
regulator_desc_ldo(4),
|
||||
regulator_desc_ldo(5),
|
||||
regulator_desc_ldo(6),
|
||||
regulator_desc_ldo(7),
|
||||
regulator_desc_ldo(8),
|
||||
regulator_desc_ldo(9),
|
||||
regulator_desc_ldo(10),
|
||||
regulator_desc_ldo(11),
|
||||
regulator_desc_ldo(12),
|
||||
regulator_desc_ldo(13),
|
||||
regulator_desc_ldo(14),
|
||||
regulator_desc_ldo(15),
|
||||
regulator_desc_ldo(16),
|
||||
regulator_desc_ldo(17),
|
||||
regulator_desc_ldo(18),
|
||||
regulator_desc_ldo(19),
|
||||
regulator_desc_ldo(20),
|
||||
regulator_desc_ldo(21),
|
||||
regulator_desc_ldo(22),
|
||||
regulator_desc_ldo(23),
|
||||
regulator_desc_ldo(24),
|
||||
regulator_desc_ldo(25),
|
||||
regulator_desc_ldo(26),
|
||||
regulator_desc_ldo(27),
|
||||
regulator_desc_ldo(28),
|
||||
regulator_desc_buck(1),
|
||||
regulator_desc_buck(2),
|
||||
regulator_desc_buck(3),
|
||||
regulator_desc_buck(4),
|
||||
regulator_desc_buck(5),
|
||||
regulator_desc_buck(6),
|
||||
regulator_desc_buck(7),
|
||||
regulator_desc_buck(8),
|
||||
regulator_desc_buck(9),
|
||||
s5m8767_regulator_desc(LDO1),
|
||||
s5m8767_regulator_desc(LDO2),
|
||||
s5m8767_regulator_desc(LDO3),
|
||||
s5m8767_regulator_desc(LDO4),
|
||||
s5m8767_regulator_desc(LDO5),
|
||||
s5m8767_regulator_desc(LDO6),
|
||||
s5m8767_regulator_desc(LDO7),
|
||||
s5m8767_regulator_desc(LDO8),
|
||||
s5m8767_regulator_desc(LDO9),
|
||||
s5m8767_regulator_desc(LDO10),
|
||||
s5m8767_regulator_desc(LDO11),
|
||||
s5m8767_regulator_desc(LDO12),
|
||||
s5m8767_regulator_desc(LDO13),
|
||||
s5m8767_regulator_desc(LDO14),
|
||||
s5m8767_regulator_desc(LDO15),
|
||||
s5m8767_regulator_desc(LDO16),
|
||||
s5m8767_regulator_desc(LDO17),
|
||||
s5m8767_regulator_desc(LDO18),
|
||||
s5m8767_regulator_desc(LDO19),
|
||||
s5m8767_regulator_desc(LDO20),
|
||||
s5m8767_regulator_desc(LDO21),
|
||||
s5m8767_regulator_desc(LDO22),
|
||||
s5m8767_regulator_desc(LDO23),
|
||||
s5m8767_regulator_desc(LDO24),
|
||||
s5m8767_regulator_desc(LDO25),
|
||||
s5m8767_regulator_desc(LDO26),
|
||||
s5m8767_regulator_desc(LDO27),
|
||||
s5m8767_regulator_desc(LDO28),
|
||||
s5m8767_regulator_desc(BUCK1),
|
||||
s5m8767_regulator_desc(BUCK2),
|
||||
s5m8767_regulator_desc(BUCK3),
|
||||
s5m8767_regulator_desc(BUCK4),
|
||||
s5m8767_regulator_desc(BUCK5),
|
||||
s5m8767_regulator_desc(BUCK6),
|
||||
s5m8767_regulator_desc(BUCK7),
|
||||
s5m8767_regulator_desc(BUCK8),
|
||||
s5m8767_regulator_desc(BUCK9),
|
||||
};
|
||||
|
||||
static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct s5m_platform_data *pdata = dev_get_platdata(iodev->dev);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev **rdev;
|
||||
struct s5m8767_info *s5m8767;
|
||||
int i, ret, size;
|
||||
|
@ -586,6 +575,7 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
|
|||
s5m8767->buck2_ramp = pdata->buck2_ramp_enable;
|
||||
s5m8767->buck3_ramp = pdata->buck3_ramp_enable;
|
||||
s5m8767->buck4_ramp = pdata->buck4_ramp_enable;
|
||||
s5m8767->opmode = pdata->opmode;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (s5m8767->buck2_gpiodvs) {
|
||||
|
@ -723,8 +713,11 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
|
|||
regulators[id].n_voltages =
|
||||
(desc->max - desc->min) / desc->step + 1;
|
||||
|
||||
rdev[i] = regulator_register(®ulators[id], s5m8767->dev,
|
||||
pdata->regulators[i].initdata, s5m8767, NULL);
|
||||
config.dev = s5m8767->dev;
|
||||
config.init_data = pdata->regulators[i].initdata;
|
||||
config.driver_data = s5m8767;
|
||||
|
||||
rdev[i] = regulator_register(®ulators[id], &config);
|
||||
if (IS_ERR(rdev[i])) {
|
||||
ret = PTR_ERR(rdev[i]);
|
||||
dev_err(s5m8767->dev, "regulator init failed for %d\n",
|
||||
|
|
|
@ -123,7 +123,7 @@ static struct regulator_ops tps6105x_regulator_ops = {
|
|||
.list_voltage = tps6105x_regulator_list_voltage,
|
||||
};
|
||||
|
||||
static struct regulator_desc tps6105x_regulator_desc = {
|
||||
static const struct regulator_desc tps6105x_regulator_desc = {
|
||||
.name = "tps6105x-boost",
|
||||
.ops = &tps6105x_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
|
@ -139,6 +139,7 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
|
||||
struct tps6105x_platform_data *pdata = tps6105x->pdata;
|
||||
struct regulator_config config = { };
|
||||
int ret;
|
||||
|
||||
/* This instance is not set for regulator mode so bail out */
|
||||
|
@ -148,11 +149,13 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
config.dev = &tps6105x->client->dev;
|
||||
config.init_data = pdata->regulator_data;
|
||||
config.driver_data = tps6105x;
|
||||
|
||||
/* Register regulator with framework */
|
||||
tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
|
||||
&tps6105x->client->dev,
|
||||
pdata->regulator_data, tps6105x,
|
||||
NULL);
|
||||
&config);
|
||||
if (IS_ERR(tps6105x->regulator)) {
|
||||
ret = PTR_ERR(tps6105x->regulator);
|
||||
dev_err(&tps6105x->client->dev,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* tps62360.c -- TI tps62360
|
||||
*
|
||||
* Driver for processor core supply tps62360 and tps62361B
|
||||
* Driver for processor core supply tps62360, tps62361B, tps62362 and tps62363.
|
||||
*
|
||||
* Copyright (c) 2012, NVIDIA Corporation.
|
||||
*
|
||||
|
@ -46,7 +46,7 @@
|
|||
#define REG_RAMPCTRL 6
|
||||
#define REG_CHIPID 8
|
||||
|
||||
enum chips {TPS62360, TPS62361};
|
||||
enum chips {TPS62360, TPS62361, TPS62362, TPS62363};
|
||||
|
||||
#define TPS62360_BASE_VOLTAGE 770
|
||||
#define TPS62360_N_VOLTAGES 64
|
||||
|
@ -56,10 +56,8 @@ enum chips {TPS62360, TPS62361};
|
|||
|
||||
/* tps 62360 chip information */
|
||||
struct tps62360_chip {
|
||||
const char *name;
|
||||
struct device *dev;
|
||||
struct regulator_desc desc;
|
||||
struct i2c_client *client;
|
||||
struct regulator_dev *rdev;
|
||||
struct regmap *regmap;
|
||||
int chip_id;
|
||||
|
@ -272,6 +270,7 @@ static const struct regmap_config tps62360_regmap_config = {
|
|||
static int __devinit tps62360_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct regulator_config config = { };
|
||||
struct tps62360_regulator_platform_data *pdata;
|
||||
struct regulator_dev *rdev;
|
||||
struct tps62360_chip *tps;
|
||||
|
@ -297,21 +296,31 @@ static int __devinit tps62360_probe(struct i2c_client *client,
|
|||
tps->en_internal_pulldn = pdata->en_internal_pulldn;
|
||||
tps->vsel0_gpio = pdata->vsel0_gpio;
|
||||
tps->vsel1_gpio = pdata->vsel1_gpio;
|
||||
tps->client = client;
|
||||
tps->dev = &client->dev;
|
||||
tps->name = id->name;
|
||||
tps->voltage_base = (id->driver_data == TPS62360) ?
|
||||
TPS62360_BASE_VOLTAGE : TPS62361_BASE_VOLTAGE;
|
||||
tps->voltage_reg_mask = (id->driver_data == TPS62360) ? 0x3F : 0x7F;
|
||||
|
||||
switch (id->driver_data) {
|
||||
case TPS62360:
|
||||
case TPS62362:
|
||||
tps->voltage_base = TPS62360_BASE_VOLTAGE;
|
||||
tps->voltage_reg_mask = 0x3F;
|
||||
tps->desc.n_voltages = TPS62360_N_VOLTAGES;
|
||||
break;
|
||||
case TPS62361:
|
||||
case TPS62363:
|
||||
tps->voltage_base = TPS62361_BASE_VOLTAGE;
|
||||
tps->voltage_reg_mask = 0x7F;
|
||||
tps->desc.n_voltages = TPS62361_N_VOLTAGES;
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
tps->desc.name = id->name;
|
||||
tps->desc.id = 0;
|
||||
tps->desc.n_voltages = (id->driver_data == TPS62360) ?
|
||||
TPS62360_N_VOLTAGES : TPS62361_N_VOLTAGES;
|
||||
tps->desc.ops = &tps62360_dcdc_ops;
|
||||
tps->desc.type = REGULATOR_VOLTAGE;
|
||||
tps->desc.owner = THIS_MODULE;
|
||||
tps->regmap = regmap_init_i2c(client, &tps62360_regmap_config);
|
||||
tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config);
|
||||
if (IS_ERR(tps->regmap)) {
|
||||
ret = PTR_ERR(tps->regmap);
|
||||
dev_err(&client->dev, "%s() Err: Failed to allocate register"
|
||||
|
@ -376,9 +385,12 @@ static int __devinit tps62360_probe(struct i2c_client *client,
|
|||
goto err_init;
|
||||
}
|
||||
|
||||
config.dev = &client->dev;
|
||||
config.init_data = &pdata->reg_init_data;
|
||||
config.driver_data = tps;
|
||||
|
||||
/* Register the regulators */
|
||||
rdev = regulator_register(&tps->desc, &client->dev,
|
||||
&pdata->reg_init_data, tps, NULL);
|
||||
rdev = regulator_register(&tps->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(tps->dev, "%s() Err: Failed to register %s\n",
|
||||
__func__, id->name);
|
||||
|
@ -396,7 +408,6 @@ err_gpio1:
|
|||
if (gpio_is_valid(tps->vsel0_gpio))
|
||||
gpio_free(tps->vsel0_gpio);
|
||||
err_gpio0:
|
||||
regmap_exit(tps->regmap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -417,7 +428,6 @@ static int __devexit tps62360_remove(struct i2c_client *client)
|
|||
gpio_free(tps->vsel0_gpio);
|
||||
|
||||
regulator_unregister(tps->rdev);
|
||||
regmap_exit(tps->regmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -439,6 +449,8 @@ static void tps62360_shutdown(struct i2c_client *client)
|
|||
static const struct i2c_device_id tps62360_id[] = {
|
||||
{.name = "tps62360", .driver_data = TPS62360},
|
||||
{.name = "tps62361", .driver_data = TPS62361},
|
||||
{.name = "tps62362", .driver_data = TPS62362},
|
||||
{.name = "tps62363", .driver_data = TPS62363},
|
||||
{},
|
||||
};
|
||||
|
||||
|
@ -468,5 +480,5 @@ static void __exit tps62360_cleanup(void)
|
|||
module_exit(tps62360_cleanup);
|
||||
|
||||
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
|
||||
MODULE_DESCRIPTION("TPS62360 voltage regulator driver");
|
||||
MODULE_DESCRIPTION("TPS6236x voltage regulator driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
/* LDO_CTRL bitfields */
|
||||
#define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4)
|
||||
#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0xF0 >> ((ldo_id)*4))
|
||||
#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x0F << ((ldo_id)*4))
|
||||
|
||||
/* Number of step-down converters available */
|
||||
#define TPS65023_NUM_DCDC 3
|
||||
|
@ -139,7 +139,6 @@ struct tps_info {
|
|||
/* PMIC details */
|
||||
struct tps_pmic {
|
||||
struct regulator_desc desc[TPS65023_NUM_REGULATOR];
|
||||
struct i2c_client *client;
|
||||
struct regulator_dev *rdev[TPS65023_NUM_REGULATOR];
|
||||
const struct tps_info *info[TPS65023_NUM_REGULATOR];
|
||||
struct regmap *regmap;
|
||||
|
@ -152,96 +151,6 @@ struct tps_driver_data {
|
|||
u8 core_regulator;
|
||||
};
|
||||
|
||||
static int tps65023_dcdc_is_enabled(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps_pmic *tps = rdev_get_drvdata(dev);
|
||||
int data, dcdc = rdev_get_id(dev);
|
||||
int ret;
|
||||
u8 shift;
|
||||
|
||||
if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
|
||||
return -EINVAL;
|
||||
|
||||
shift = TPS65023_NUM_REGULATOR - dcdc;
|
||||
ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
else
|
||||
return (data & 1<<shift) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int tps65023_ldo_is_enabled(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps_pmic *tps = rdev_get_drvdata(dev);
|
||||
int data, ldo = rdev_get_id(dev);
|
||||
int ret;
|
||||
u8 shift;
|
||||
|
||||
if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
|
||||
return -EINVAL;
|
||||
|
||||
shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
|
||||
ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
else
|
||||
return (data & 1<<shift) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int tps65023_dcdc_enable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps_pmic *tps = rdev_get_drvdata(dev);
|
||||
int dcdc = rdev_get_id(dev);
|
||||
u8 shift;
|
||||
|
||||
if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
|
||||
return -EINVAL;
|
||||
|
||||
shift = TPS65023_NUM_REGULATOR - dcdc;
|
||||
return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
|
||||
}
|
||||
|
||||
static int tps65023_dcdc_disable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps_pmic *tps = rdev_get_drvdata(dev);
|
||||
int dcdc = rdev_get_id(dev);
|
||||
u8 shift;
|
||||
|
||||
if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
|
||||
return -EINVAL;
|
||||
|
||||
shift = TPS65023_NUM_REGULATOR - dcdc;
|
||||
return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0);
|
||||
}
|
||||
|
||||
static int tps65023_ldo_enable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps_pmic *tps = rdev_get_drvdata(dev);
|
||||
int ldo = rdev_get_id(dev);
|
||||
u8 shift;
|
||||
|
||||
if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
|
||||
return -EINVAL;
|
||||
|
||||
shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
|
||||
return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
|
||||
}
|
||||
|
||||
static int tps65023_ldo_disable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps_pmic *tps = rdev_get_drvdata(dev);
|
||||
int ldo = rdev_get_id(dev);
|
||||
u8 shift;
|
||||
|
||||
if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
|
||||
return -EINVAL;
|
||||
|
||||
shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
|
||||
return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0);
|
||||
}
|
||||
|
||||
static int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps_pmic *tps = rdev_get_drvdata(dev);
|
||||
|
@ -261,50 +170,28 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
|
|||
return tps->info[dcdc]->min_uV;
|
||||
}
|
||||
|
||||
static int tps65023_dcdc_set_voltage(struct regulator_dev *dev,
|
||||
int min_uV, int max_uV,
|
||||
unsigned *selector)
|
||||
static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct tps_pmic *tps = rdev_get_drvdata(dev);
|
||||
int dcdc = rdev_get_id(dev);
|
||||
int vsel;
|
||||
int ret;
|
||||
|
||||
if (dcdc != tps->core_regulator)
|
||||
return -EINVAL;
|
||||
if (min_uV < tps->info[dcdc]->min_uV
|
||||
|| min_uV > tps->info[dcdc]->max_uV)
|
||||
return -EINVAL;
|
||||
if (max_uV < tps->info[dcdc]->min_uV
|
||||
|| max_uV > tps->info[dcdc]->max_uV)
|
||||
return -EINVAL;
|
||||
|
||||
for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) {
|
||||
int mV = tps->info[dcdc]->table[vsel];
|
||||
int uV = mV * 1000;
|
||||
|
||||
/* Break at the first in-range value */
|
||||
if (min_uV <= uV && uV <= max_uV)
|
||||
break;
|
||||
}
|
||||
|
||||
*selector = vsel;
|
||||
|
||||
if (vsel == tps->info[dcdc]->table_len)
|
||||
goto failed;
|
||||
|
||||
ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, vsel);
|
||||
ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, selector);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* Tell the chip that we have changed the value in DEFCORE
|
||||
* and its time to update the core voltage
|
||||
*/
|
||||
regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
|
||||
TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
|
||||
ret = regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
|
||||
TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
failed:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int tps65023_ldo_get_voltage(struct regulator_dev *dev)
|
||||
|
@ -325,42 +212,15 @@ static int tps65023_ldo_get_voltage(struct regulator_dev *dev)
|
|||
return tps->info[ldo]->table[data] * 1000;
|
||||
}
|
||||
|
||||
static int tps65023_ldo_set_voltage(struct regulator_dev *dev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct tps_pmic *tps = rdev_get_drvdata(dev);
|
||||
int data, vsel, ldo = rdev_get_id(dev);
|
||||
int ret;
|
||||
int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1;
|
||||
|
||||
if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
|
||||
return -EINVAL;
|
||||
|
||||
if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV)
|
||||
return -EINVAL;
|
||||
if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV)
|
||||
return -EINVAL;
|
||||
|
||||
for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) {
|
||||
int mV = tps->info[ldo]->table[vsel];
|
||||
int uV = mV * 1000;
|
||||
|
||||
/* Break at the first in-range value */
|
||||
if (min_uV <= uV && uV <= max_uV)
|
||||
break;
|
||||
}
|
||||
|
||||
if (vsel == tps->info[ldo]->table_len)
|
||||
return -EINVAL;
|
||||
|
||||
*selector = vsel;
|
||||
|
||||
ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
data &= TPS65023_LDO_CTRL_LDOx_MASK(ldo - TPS65023_LDO_1);
|
||||
data |= (vsel << (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)));
|
||||
return regmap_write(tps->regmap, TPS65023_REG_LDO_CTRL, data);
|
||||
return regmap_update_bits(tps->regmap, TPS65023_REG_LDO_CTRL,
|
||||
TPS65023_LDO_CTRL_LDOx_MASK(ldo_index),
|
||||
selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index));
|
||||
}
|
||||
|
||||
static int tps65023_dcdc_list_voltage(struct regulator_dev *dev,
|
||||
|
@ -398,21 +258,21 @@ static int tps65023_ldo_list_voltage(struct regulator_dev *dev,
|
|||
|
||||
/* Operations permitted on VDCDCx */
|
||||
static struct regulator_ops tps65023_dcdc_ops = {
|
||||
.is_enabled = tps65023_dcdc_is_enabled,
|
||||
.enable = tps65023_dcdc_enable,
|
||||
.disable = tps65023_dcdc_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage = tps65023_dcdc_get_voltage,
|
||||
.set_voltage = tps65023_dcdc_set_voltage,
|
||||
.set_voltage_sel = tps65023_dcdc_set_voltage_sel,
|
||||
.list_voltage = tps65023_dcdc_list_voltage,
|
||||
};
|
||||
|
||||
/* Operations permitted on LDOx */
|
||||
static struct regulator_ops tps65023_ldo_ops = {
|
||||
.is_enabled = tps65023_ldo_is_enabled,
|
||||
.enable = tps65023_ldo_enable,
|
||||
.disable = tps65023_ldo_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage = tps65023_ldo_get_voltage,
|
||||
.set_voltage = tps65023_ldo_set_voltage,
|
||||
.set_voltage_sel = tps65023_ldo_set_voltage_sel,
|
||||
.list_voltage = tps65023_ldo_list_voltage,
|
||||
};
|
||||
|
||||
|
@ -426,6 +286,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
|
|||
{
|
||||
const struct tps_driver_data *drv_data = (void *)id->driver_data;
|
||||
const struct tps_info *info = drv_data->info;
|
||||
struct regulator_config config = { };
|
||||
struct regulator_init_data *init_data;
|
||||
struct regulator_dev *rdev;
|
||||
struct tps_pmic *tps;
|
||||
|
@ -443,20 +304,19 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
|
|||
if (!init_data)
|
||||
return -EIO;
|
||||
|
||||
tps = kzalloc(sizeof(*tps), GFP_KERNEL);
|
||||
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
|
||||
if (!tps)
|
||||
return -ENOMEM;
|
||||
|
||||
tps->regmap = regmap_init_i2c(client, &tps65023_regmap_config);
|
||||
tps->regmap = devm_regmap_init_i2c(client, &tps65023_regmap_config);
|
||||
if (IS_ERR(tps->regmap)) {
|
||||
error = PTR_ERR(tps->regmap);
|
||||
dev_err(&client->dev, "Failed to allocate register map: %d\n",
|
||||
error);
|
||||
goto fail_alloc;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* common for all regulators */
|
||||
tps->client = client;
|
||||
tps->core_regulator = drv_data->core_regulator;
|
||||
|
||||
for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) {
|
||||
|
@ -471,9 +331,22 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
|
|||
tps->desc[i].type = REGULATOR_VOLTAGE;
|
||||
tps->desc[i].owner = THIS_MODULE;
|
||||
|
||||
tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL;
|
||||
if (i == TPS65023_LDO_1)
|
||||
tps->desc[i].enable_mask = 1 << 1;
|
||||
else if (i == TPS65023_LDO_2)
|
||||
tps->desc[i].enable_mask = 1 << 2;
|
||||
else /* DCDCx */
|
||||
tps->desc[i].enable_mask =
|
||||
1 << (TPS65023_NUM_REGULATOR - i);
|
||||
|
||||
config.dev = &client->dev;
|
||||
config.init_data = init_data;
|
||||
config.driver_data = tps;
|
||||
config.regmap = tps->regmap;
|
||||
|
||||
/* Register the regulators */
|
||||
rdev = regulator_register(&tps->desc[i], &client->dev,
|
||||
init_data, tps, NULL);
|
||||
rdev = regulator_register(&tps->desc[i], &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&client->dev, "failed to register %s\n",
|
||||
id->name);
|
||||
|
@ -496,19 +369,9 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
|
|||
fail:
|
||||
while (--i >= 0)
|
||||
regulator_unregister(tps->rdev[i]);
|
||||
|
||||
regmap_exit(tps->regmap);
|
||||
fail_alloc:
|
||||
kfree(tps);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* tps_65023_remove - TPS65023 driver i2c remove handler
|
||||
* @client: i2c driver client device structure
|
||||
*
|
||||
* Unregister TPS driver as an i2c client device driver
|
||||
*/
|
||||
static int __devexit tps_65023_remove(struct i2c_client *client)
|
||||
{
|
||||
struct tps_pmic *tps = i2c_get_clientdata(client);
|
||||
|
@ -516,10 +379,6 @@ static int __devexit tps_65023_remove(struct i2c_client *client)
|
|||
|
||||
for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
|
||||
regulator_unregister(tps->rdev[i]);
|
||||
|
||||
regmap_exit(tps->regmap);
|
||||
kfree(tps);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -638,13 +497,13 @@ static struct tps_driver_data tps65020_drv_data = {
|
|||
};
|
||||
|
||||
static struct tps_driver_data tps65021_drv_data = {
|
||||
.info = tps65021_regs,
|
||||
.core_regulator = TPS65023_DCDC_3,
|
||||
.info = tps65021_regs,
|
||||
.core_regulator = TPS65023_DCDC_3,
|
||||
};
|
||||
|
||||
static struct tps_driver_data tps65023_drv_data = {
|
||||
.info = tps65023_regs,
|
||||
.core_regulator = TPS65023_DCDC_1,
|
||||
.info = tps65023_regs,
|
||||
.core_regulator = TPS65023_DCDC_1,
|
||||
};
|
||||
|
||||
static const struct i2c_device_id tps_65023_id[] = {
|
||||
|
@ -669,22 +528,12 @@ static struct i2c_driver tps_65023_i2c_driver = {
|
|||
.id_table = tps_65023_id,
|
||||
};
|
||||
|
||||
/**
|
||||
* tps_65023_init
|
||||
*
|
||||
* Module init function
|
||||
*/
|
||||
static int __init tps_65023_init(void)
|
||||
{
|
||||
return i2c_add_driver(&tps_65023_i2c_driver);
|
||||
}
|
||||
subsys_initcall(tps_65023_init);
|
||||
|
||||
/**
|
||||
* tps_65023_cleanup
|
||||
*
|
||||
* Module exit function
|
||||
*/
|
||||
static void __exit tps_65023_cleanup(void)
|
||||
{
|
||||
i2c_del_driver(&tps_65023_i2c_driver);
|
||||
|
|
|
@ -404,6 +404,7 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct tps_info *info = &tps6507x_pmic_regs[0];
|
||||
struct regulator_config config = { };
|
||||
struct regulator_init_data *init_data;
|
||||
struct regulator_dev *rdev;
|
||||
struct tps6507x_pmic *tps;
|
||||
|
@ -428,7 +429,7 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
|
|||
if (!init_data)
|
||||
return -EINVAL;
|
||||
|
||||
tps = kzalloc(sizeof(*tps), GFP_KERNEL);
|
||||
tps = devm_kzalloc(&pdev->dev, sizeof(*tps), GFP_KERNEL);
|
||||
if (!tps)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -453,8 +454,11 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
|
|||
tps->desc[i].type = REGULATOR_VOLTAGE;
|
||||
tps->desc[i].owner = THIS_MODULE;
|
||||
|
||||
rdev = regulator_register(&tps->desc[i],
|
||||
tps6507x_dev->dev, init_data, tps, NULL);
|
||||
config.dev = tps6507x_dev->dev;
|
||||
config.init_data = init_data;
|
||||
config.driver_data = tps;
|
||||
|
||||
rdev = regulator_register(&tps->desc[i], &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(tps6507x_dev->dev,
|
||||
"failed to register %s regulator\n",
|
||||
|
@ -475,8 +479,6 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
|
|||
fail:
|
||||
while (--i >= 0)
|
||||
regulator_unregister(tps->rdev[i]);
|
||||
|
||||
kfree(tps);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -488,9 +490,6 @@ static int __devexit tps6507x_pmic_remove(struct platform_device *pdev)
|
|||
|
||||
for (i = 0; i < TPS6507X_NUM_REGULATOR; i++)
|
||||
regulator_unregister(tps->rdev[i]);
|
||||
|
||||
kfree(tps);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Regulator driver for tps65090 power management chip.
|
||||
*
|
||||
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/mfd/tps65090.h>
|
||||
#include <linux/regulator/tps65090-regulator.h>
|
||||
|
||||
struct tps65090_regulator {
|
||||
int id;
|
||||
/* used by regulator core */
|
||||
struct regulator_desc desc;
|
||||
|
||||
/* Device */
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
static struct regulator_ops tps65090_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
#define tps65090_REG(_id) \
|
||||
{ \
|
||||
.id = TPS65090_ID_##_id, \
|
||||
.desc = { \
|
||||
.name = tps65090_rails(_id), \
|
||||
.id = TPS65090_ID_##_id, \
|
||||
.ops = &tps65090_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.enable_reg = (TPS65090_ID_##_id) + 12, \
|
||||
.enable_mask = BIT(0), \
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct tps65090_regulator TPS65090_regulator[] = {
|
||||
tps65090_REG(DCDC1),
|
||||
tps65090_REG(DCDC2),
|
||||
tps65090_REG(DCDC3),
|
||||
tps65090_REG(FET1),
|
||||
tps65090_REG(FET2),
|
||||
tps65090_REG(FET3),
|
||||
tps65090_REG(FET4),
|
||||
tps65090_REG(FET5),
|
||||
tps65090_REG(FET6),
|
||||
tps65090_REG(FET7),
|
||||
};
|
||||
|
||||
static inline struct tps65090_regulator *find_regulator_info(int id)
|
||||
{
|
||||
struct tps65090_regulator *ri;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(TPS65090_regulator); i++) {
|
||||
ri = &TPS65090_regulator[i];
|
||||
if (ri->desc.id == id)
|
||||
return ri;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __devinit tps65090_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent);
|
||||
struct tps65090_regulator *ri = NULL;
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
struct tps65090_regulator_platform_data *tps_pdata;
|
||||
int id = pdev->id;
|
||||
|
||||
dev_dbg(&pdev->dev, "Probing regulator %d\n", id);
|
||||
|
||||
ri = find_regulator_info(id);
|
||||
if (ri == NULL) {
|
||||
dev_err(&pdev->dev, "invalid regulator ID specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
tps_pdata = pdev->dev.platform_data;
|
||||
ri->dev = &pdev->dev;
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = &tps_pdata->regulator;
|
||||
config.driver_data = ri;
|
||||
config.regmap = tps65090_mfd->rmap;
|
||||
|
||||
rdev = regulator_register(&ri->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
ri->desc.name);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, rdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit tps65090_regulator_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_dev *rdev = platform_get_drvdata(pdev);
|
||||
|
||||
regulator_unregister(rdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver tps65090_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "tps65090-regulator",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = tps65090_regulator_probe,
|
||||
.remove = __devexit_p(tps65090_regulator_remove),
|
||||
};
|
||||
|
||||
static int __init tps65090_regulator_init(void)
|
||||
{
|
||||
return platform_driver_register(&tps65090_regulator_driver);
|
||||
}
|
||||
subsys_initcall(tps65090_regulator_init);
|
||||
|
||||
static void __exit tps65090_regulator_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&tps65090_regulator_driver);
|
||||
}
|
||||
module_exit(tps65090_regulator_exit);
|
||||
|
||||
MODULE_DESCRIPTION("tps65090 regulator driver");
|
||||
MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -312,7 +312,7 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = {
|
|||
.list_voltage = tps65217_pmic_list_voltage,
|
||||
};
|
||||
|
||||
static struct regulator_desc regulators[] = {
|
||||
static const struct regulator_desc regulators[] = {
|
||||
TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64),
|
||||
TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64),
|
||||
TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64),
|
||||
|
@ -327,13 +327,17 @@ static int __devinit tps65217_regulator_probe(struct platform_device *pdev)
|
|||
struct regulator_dev *rdev;
|
||||
struct tps65217 *tps;
|
||||
struct tps_info *info = &tps65217_pmic_regs[pdev->id];
|
||||
struct regulator_config config = { };
|
||||
|
||||
/* Already set by core driver */
|
||||
tps = dev_to_tps65217(pdev->dev.parent);
|
||||
tps->info[pdev->id] = info;
|
||||
|
||||
rdev = regulator_register(®ulators[pdev->id], &pdev->dev,
|
||||
pdev->dev.platform_data, tps, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdev->dev.platform_data;
|
||||
config.driver_data = tps;
|
||||
|
||||
rdev = regulator_register(®ulators[pdev->id], &config);
|
||||
if (IS_ERR(rdev))
|
||||
return PTR_ERR(rdev);
|
||||
|
||||
|
|
|
@ -458,12 +458,10 @@ static int list_voltage(struct regulator_dev *rdev, unsigned selector)
|
|||
info->voltages[selector] : -EINVAL);
|
||||
}
|
||||
|
||||
static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
||||
unsigned *selector)
|
||||
static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
|
||||
{
|
||||
const struct supply_info *info;
|
||||
struct tps6524x *hw;
|
||||
unsigned i;
|
||||
|
||||
hw = rdev_get_drvdata(rdev);
|
||||
info = &supply_info[rdev_get_id(rdev)];
|
||||
|
@ -471,20 +469,10 @@ static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
if (info->flags & FIXED_VOLTAGE)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < info->n_voltages; i++)
|
||||
if (min_uV <= info->voltages[i] &&
|
||||
max_uV >= info->voltages[i])
|
||||
break;
|
||||
|
||||
if (i >= info->n_voltages)
|
||||
i = info->n_voltages - 1;
|
||||
|
||||
*selector = i;
|
||||
|
||||
return write_field(hw, &info->voltage, i);
|
||||
return write_field(hw, &info->voltage, selector);
|
||||
}
|
||||
|
||||
static int get_voltage(struct regulator_dev *rdev)
|
||||
static int get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
const struct supply_info *info;
|
||||
struct tps6524x *hw;
|
||||
|
@ -502,7 +490,7 @@ static int get_voltage(struct regulator_dev *rdev)
|
|||
if (WARN_ON(ret >= info->n_voltages))
|
||||
return -EIO;
|
||||
|
||||
return info->voltages[ret];
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_current_limit(struct regulator_dev *rdev, int min_uA,
|
||||
|
@ -587,8 +575,8 @@ static struct regulator_ops regulator_ops = {
|
|||
.is_enabled = is_supply_enabled,
|
||||
.enable = enable_supply,
|
||||
.disable = disable_supply,
|
||||
.get_voltage = get_voltage,
|
||||
.set_voltage = set_voltage,
|
||||
.get_voltage_sel = get_voltage_sel,
|
||||
.set_voltage_sel = set_voltage_sel,
|
||||
.list_voltage = list_voltage,
|
||||
.set_current_limit = set_current_limit,
|
||||
.get_current_limit = get_current_limit,
|
||||
|
@ -607,7 +595,6 @@ static int pmic_remove(struct spi_device *spi)
|
|||
hw->rdev[i] = NULL;
|
||||
}
|
||||
spi_set_drvdata(spi, NULL);
|
||||
kfree(hw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -617,6 +604,7 @@ static int __devinit pmic_probe(struct spi_device *spi)
|
|||
struct device *dev = &spi->dev;
|
||||
const struct supply_info *info = supply_info;
|
||||
struct regulator_init_data *init_data;
|
||||
struct regulator_config config = { };
|
||||
int ret = 0, i;
|
||||
|
||||
init_data = dev->platform_data;
|
||||
|
@ -625,7 +613,7 @@ static int __devinit pmic_probe(struct spi_device *spi)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
hw = kzalloc(sizeof(struct tps6524x), GFP_KERNEL);
|
||||
hw = devm_kzalloc(&spi->dev, sizeof(struct tps6524x), GFP_KERNEL);
|
||||
if (!hw) {
|
||||
dev_err(dev, "cannot allocate regulator private data\n");
|
||||
return -ENOMEM;
|
||||
|
@ -648,8 +636,11 @@ static int __devinit pmic_probe(struct spi_device *spi)
|
|||
if (info->flags & FIXED_VOLTAGE)
|
||||
hw->desc[i].n_voltages = 1;
|
||||
|
||||
hw->rdev[i] = regulator_register(&hw->desc[i], dev,
|
||||
init_data, hw, NULL);
|
||||
config.dev = dev;
|
||||
config.init_data = init_data;
|
||||
config.driver_data = hw;
|
||||
|
||||
hw->rdev[i] = regulator_register(&hw->desc[i], &config);
|
||||
if (IS_ERR(hw->rdev[i])) {
|
||||
ret = PTR_ERR(hw->rdev[i]);
|
||||
hw->rdev[i] = NULL;
|
||||
|
@ -673,17 +664,7 @@ static struct spi_driver pmic_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init pmic_driver_init(void)
|
||||
{
|
||||
return spi_register_driver(&pmic_driver);
|
||||
}
|
||||
module_init(pmic_driver_init);
|
||||
|
||||
static void __exit pmic_driver_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&pmic_driver);
|
||||
}
|
||||
module_exit(pmic_driver_exit);
|
||||
module_spi_driver(pmic_driver);
|
||||
|
||||
MODULE_DESCRIPTION("TPS6524X PMIC Driver");
|
||||
MODULE_AUTHOR("Cyril Chemparathy");
|
||||
|
|
|
@ -75,8 +75,7 @@ static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev)
|
|||
return rdev_get_dev(rdev)->parent->parent;
|
||||
}
|
||||
|
||||
static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
static int tps6586x_list_voltage(struct regulator_dev *rdev, unsigned selector)
|
||||
{
|
||||
struct tps6586x_regulator *info = rdev_get_drvdata(rdev);
|
||||
int rid = rdev_get_id(rdev);
|
||||
|
@ -89,47 +88,34 @@ static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev,
|
|||
}
|
||||
|
||||
|
||||
static int __tps6586x_ldo_set_voltage(struct device *parent,
|
||||
struct tps6586x_regulator *ri,
|
||||
int min_uV, int max_uV,
|
||||
unsigned *selector)
|
||||
{
|
||||
int val, uV;
|
||||
uint8_t mask;
|
||||
|
||||
for (val = 0; val < ri->desc.n_voltages; val++) {
|
||||
uV = ri->voltages[val] * 1000;
|
||||
|
||||
/* LDO0 has minimal voltage 1.2 rather than 1.25 */
|
||||
if (ri->desc.id == TPS6586X_ID_LDO_0 && val == 0)
|
||||
uV -= 50 * 1000;
|
||||
|
||||
/* use the first in-range value */
|
||||
if (min_uV <= uV && uV <= max_uV) {
|
||||
|
||||
*selector = val;
|
||||
|
||||
val <<= ri->volt_shift;
|
||||
mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
|
||||
|
||||
return tps6586x_update(parent, ri->volt_reg, val, mask);
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int tps6586x_ldo_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
static int tps6586x_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
|
||||
struct device *parent = to_tps6586x_dev(rdev);
|
||||
int ret, val, rid = rdev_get_id(rdev);
|
||||
uint8_t mask;
|
||||
|
||||
return __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV,
|
||||
selector);
|
||||
val = selector << ri->volt_shift;
|
||||
mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
|
||||
|
||||
ret = tps6586x_update(parent, ri->volt_reg, val, mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Update go bit for DVM regulators */
|
||||
switch (rid) {
|
||||
case TPS6586X_ID_LDO_2:
|
||||
case TPS6586X_ID_LDO_4:
|
||||
case TPS6586X_ID_SM_0:
|
||||
case TPS6586X_ID_SM_1:
|
||||
ret = tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev)
|
||||
static int tps6586x_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
|
||||
struct device *parent = to_tps6586x_dev(rdev);
|
||||
|
@ -146,22 +132,7 @@ static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev)
|
|||
if (val >= ri->desc.n_voltages)
|
||||
BUG();
|
||||
|
||||
return ri->voltages[val] * 1000;
|
||||
}
|
||||
|
||||
static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
{
|
||||
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
|
||||
struct device *parent = to_tps6586x_dev(rdev);
|
||||
int ret;
|
||||
|
||||
ret = __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV,
|
||||
selector);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
|
||||
return val;
|
||||
}
|
||||
|
||||
static int tps6586x_regulator_enable(struct regulator_dev *rdev)
|
||||
|
@ -196,20 +167,10 @@ static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev)
|
|||
return !!(reg_val & (1 << ri->enable_bit[0]));
|
||||
}
|
||||
|
||||
static struct regulator_ops tps6586x_regulator_ldo_ops = {
|
||||
.list_voltage = tps6586x_ldo_list_voltage,
|
||||
.get_voltage = tps6586x_ldo_get_voltage,
|
||||
.set_voltage = tps6586x_ldo_set_voltage,
|
||||
|
||||
.is_enabled = tps6586x_regulator_is_enabled,
|
||||
.enable = tps6586x_regulator_enable,
|
||||
.disable = tps6586x_regulator_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops tps6586x_regulator_dvm_ops = {
|
||||
.list_voltage = tps6586x_ldo_list_voltage,
|
||||
.get_voltage = tps6586x_ldo_get_voltage,
|
||||
.set_voltage = tps6586x_dvm_set_voltage,
|
||||
static struct regulator_ops tps6586x_regulator_ops = {
|
||||
.list_voltage = tps6586x_list_voltage,
|
||||
.get_voltage_sel = tps6586x_get_voltage_sel,
|
||||
.set_voltage_sel = tps6586x_set_voltage_sel,
|
||||
|
||||
.is_enabled = tps6586x_regulator_is_enabled,
|
||||
.enable = tps6586x_regulator_enable,
|
||||
|
@ -241,11 +202,11 @@ static int tps6586x_dvm_voltages[] = {
|
|||
1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500,
|
||||
};
|
||||
|
||||
#define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \
|
||||
#define TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \
|
||||
ereg0, ebit0, ereg1, ebit1) \
|
||||
.desc = { \
|
||||
.name = "REG-" #_id, \
|
||||
.ops = &tps6586x_regulator_##_ops, \
|
||||
.ops = &tps6586x_regulator_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = TPS6586X_ID_##_id, \
|
||||
.n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \
|
||||
|
@ -267,14 +228,14 @@ static int tps6586x_dvm_voltages[] = {
|
|||
#define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \
|
||||
ereg0, ebit0, ereg1, ebit1) \
|
||||
{ \
|
||||
TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \
|
||||
TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \
|
||||
ereg0, ebit0, ereg1, ebit1) \
|
||||
}
|
||||
|
||||
#define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \
|
||||
ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
|
||||
{ \
|
||||
TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \
|
||||
TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \
|
||||
ereg0, ebit0, ereg1, ebit1) \
|
||||
TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
|
||||
}
|
||||
|
@ -384,6 +345,7 @@ static inline struct tps6586x_regulator *find_regulator_info(int id)
|
|||
static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps6586x_regulator *ri = NULL;
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
int id = pdev->id;
|
||||
int err;
|
||||
|
@ -400,8 +362,11 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
rdev = regulator_register(&ri->desc, &pdev->dev,
|
||||
pdev->dev.platform_data, ri, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdev->dev.platform_data;
|
||||
config.driver_data = ri;
|
||||
|
||||
rdev = regulator_register(&ri->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
ri->desc.name);
|
||||
|
|
|
@ -467,48 +467,6 @@ static int tps65911_get_ctrl_register(int id)
|
|||
}
|
||||
}
|
||||
|
||||
static int tps65910_is_enabled(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
|
||||
int reg, value, id = rdev_get_id(dev);
|
||||
|
||||
reg = pmic->get_ctrl_reg(id);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
value = tps65910_reg_read(pmic, reg);
|
||||
if (value < 0)
|
||||
return value;
|
||||
|
||||
return value & TPS65910_SUPPLY_STATE_ENABLED;
|
||||
}
|
||||
|
||||
static int tps65910_enable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
|
||||
struct tps65910 *mfd = pmic->mfd;
|
||||
int reg, id = rdev_get_id(dev);
|
||||
|
||||
reg = pmic->get_ctrl_reg(id);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
|
||||
}
|
||||
|
||||
static int tps65910_disable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
|
||||
struct tps65910 *mfd = pmic->mfd;
|
||||
int reg, id = rdev_get_id(dev);
|
||||
|
||||
reg = pmic->get_ctrl_reg(id);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
|
||||
}
|
||||
|
||||
static int tps65910_enable_time(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
|
||||
|
@ -914,9 +872,9 @@ static int tps65910_set_voltage_dcdc_time_sel(struct regulator_dev *dev,
|
|||
|
||||
/* Regulator ops (except VRTC) */
|
||||
static struct regulator_ops tps65910_ops_dcdc = {
|
||||
.is_enabled = tps65910_is_enabled,
|
||||
.enable = tps65910_enable,
|
||||
.disable = tps65910_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.enable_time = tps65910_enable_time,
|
||||
.set_mode = tps65910_set_mode,
|
||||
.get_mode = tps65910_get_mode,
|
||||
|
@ -927,9 +885,9 @@ static struct regulator_ops tps65910_ops_dcdc = {
|
|||
};
|
||||
|
||||
static struct regulator_ops tps65910_ops_vdd3 = {
|
||||
.is_enabled = tps65910_is_enabled,
|
||||
.enable = tps65910_enable,
|
||||
.disable = tps65910_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.enable_time = tps65910_enable_time,
|
||||
.set_mode = tps65910_set_mode,
|
||||
.get_mode = tps65910_get_mode,
|
||||
|
@ -938,9 +896,9 @@ static struct regulator_ops tps65910_ops_vdd3 = {
|
|||
};
|
||||
|
||||
static struct regulator_ops tps65910_ops = {
|
||||
.is_enabled = tps65910_is_enabled,
|
||||
.enable = tps65910_enable,
|
||||
.disable = tps65910_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.enable_time = tps65910_enable_time,
|
||||
.set_mode = tps65910_set_mode,
|
||||
.get_mode = tps65910_get_mode,
|
||||
|
@ -950,9 +908,9 @@ static struct regulator_ops tps65910_ops = {
|
|||
};
|
||||
|
||||
static struct regulator_ops tps65911_ops = {
|
||||
.is_enabled = tps65910_is_enabled,
|
||||
.enable = tps65910_enable,
|
||||
.disable = tps65910_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.enable_time = tps65910_enable_time,
|
||||
.set_mode = tps65910_set_mode,
|
||||
.get_mode = tps65910_get_mode,
|
||||
|
@ -1097,6 +1055,7 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
|
|||
static __devinit int tps65910_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_config config = { };
|
||||
struct tps_info *info;
|
||||
struct regulator_init_data *reg_data;
|
||||
struct regulator_dev *rdev;
|
||||
|
@ -1108,7 +1067,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
|
|||
if (!pmic_plat_data)
|
||||
return -EINVAL;
|
||||
|
||||
pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
|
||||
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
|
||||
if (!pmic)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1135,7 +1094,6 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
|
|||
break;
|
||||
default:
|
||||
pr_err("Invalid tps chip version\n");
|
||||
kfree(pmic);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -1143,7 +1101,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
|
|||
sizeof(struct regulator_desc), GFP_KERNEL);
|
||||
if (!pmic->desc) {
|
||||
err = -ENOMEM;
|
||||
goto err_free_pmic;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
pmic->info = kcalloc(pmic->num_regulators,
|
||||
|
@ -1205,9 +1163,15 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
|
|||
|
||||
pmic->desc[i].type = REGULATOR_VOLTAGE;
|
||||
pmic->desc[i].owner = THIS_MODULE;
|
||||
pmic->desc[i].enable_reg = pmic->get_ctrl_reg(i);
|
||||
pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED;
|
||||
|
||||
rdev = regulator_register(&pmic->desc[i],
|
||||
tps65910->dev, reg_data, pmic, NULL);
|
||||
config.dev = tps65910->dev;
|
||||
config.init_data = reg_data;
|
||||
config.driver_data = pmic;
|
||||
config.regmap = tps65910->regmap;
|
||||
|
||||
rdev = regulator_register(&pmic->desc[i], &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(tps65910->dev,
|
||||
"failed to register %s regulator\n",
|
||||
|
@ -1229,8 +1193,7 @@ err_free_info:
|
|||
kfree(pmic->info);
|
||||
err_free_desc:
|
||||
kfree(pmic->desc);
|
||||
err_free_pmic:
|
||||
kfree(pmic);
|
||||
err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1245,7 +1208,6 @@ static int __devexit tps65910_remove(struct platform_device *pdev)
|
|||
kfree(pmic->rdev);
|
||||
kfree(pmic->info);
|
||||
kfree(pmic->desc);
|
||||
kfree(pmic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -372,12 +372,14 @@ static unsigned int tps65912_get_mode(struct regulator_dev *dev)
|
|||
return mode;
|
||||
}
|
||||
|
||||
static int tps65912_list_voltage_dcdc(struct regulator_dev *dev,
|
||||
unsigned selector)
|
||||
static int tps65912_list_voltage(struct regulator_dev *dev, unsigned selector)
|
||||
{
|
||||
struct tps65912_reg *pmic = rdev_get_drvdata(dev);
|
||||
int range, voltage = 0, id = rdev_get_id(dev);
|
||||
|
||||
if (id >= TPS65912_REG_LDO1 && id <= TPS65912_REG_LDO10)
|
||||
return tps65912_vsel_to_uv_ldo(selector);
|
||||
|
||||
if (id > TPS65912_REG_DCDC4)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -404,7 +406,7 @@ static int tps65912_list_voltage_dcdc(struct regulator_dev *dev,
|
|||
return voltage;
|
||||
}
|
||||
|
||||
static int tps65912_get_voltage_dcdc(struct regulator_dev *dev)
|
||||
static int tps65912_get_voltage(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65912_reg *pmic = rdev_get_drvdata(dev);
|
||||
struct tps65912 *mfd = pmic->mfd;
|
||||
|
@ -418,7 +420,7 @@ static int tps65912_get_voltage_dcdc(struct regulator_dev *dev)
|
|||
vsel = tps65912_reg_read(mfd, reg);
|
||||
vsel &= 0x3F;
|
||||
|
||||
return tps65912_list_voltage_dcdc(dev, vsel);
|
||||
return tps65912_list_voltage(dev, vsel);
|
||||
}
|
||||
|
||||
static int tps65912_set_voltage_sel(struct regulator_dev *dev,
|
||||
|
@ -436,32 +438,6 @@ static int tps65912_set_voltage_sel(struct regulator_dev *dev,
|
|||
return tps65912_reg_write(mfd, reg, selector | value);
|
||||
}
|
||||
|
||||
static int tps65912_get_voltage_ldo(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65912_reg *pmic = rdev_get_drvdata(dev);
|
||||
struct tps65912 *mfd = pmic->mfd;
|
||||
int id = rdev_get_id(dev);
|
||||
int vsel = 0;
|
||||
u8 reg;
|
||||
|
||||
reg = tps65912_get_sel_register(pmic, id);
|
||||
vsel = tps65912_reg_read(mfd, reg);
|
||||
vsel &= 0x3F;
|
||||
|
||||
return tps65912_vsel_to_uv_ldo(vsel);
|
||||
}
|
||||
|
||||
static int tps65912_list_voltage_ldo(struct regulator_dev *dev,
|
||||
unsigned selector)
|
||||
{
|
||||
int ldo = rdev_get_id(dev);
|
||||
|
||||
if (ldo < TPS65912_REG_LDO1 || ldo > TPS65912_REG_LDO10)
|
||||
return -EINVAL;
|
||||
|
||||
return tps65912_vsel_to_uv_ldo(selector);
|
||||
}
|
||||
|
||||
/* Operations permitted on DCDCx */
|
||||
static struct regulator_ops tps65912_ops_dcdc = {
|
||||
.is_enabled = tps65912_reg_is_enabled,
|
||||
|
@ -469,9 +445,9 @@ static struct regulator_ops tps65912_ops_dcdc = {
|
|||
.disable = tps65912_reg_disable,
|
||||
.set_mode = tps65912_set_mode,
|
||||
.get_mode = tps65912_get_mode,
|
||||
.get_voltage = tps65912_get_voltage_dcdc,
|
||||
.get_voltage = tps65912_get_voltage,
|
||||
.set_voltage_sel = tps65912_set_voltage_sel,
|
||||
.list_voltage = tps65912_list_voltage_dcdc,
|
||||
.list_voltage = tps65912_list_voltage,
|
||||
};
|
||||
|
||||
/* Operations permitted on LDOx */
|
||||
|
@ -479,14 +455,15 @@ static struct regulator_ops tps65912_ops_ldo = {
|
|||
.is_enabled = tps65912_reg_is_enabled,
|
||||
.enable = tps65912_reg_enable,
|
||||
.disable = tps65912_reg_disable,
|
||||
.get_voltage = tps65912_get_voltage_ldo,
|
||||
.get_voltage = tps65912_get_voltage,
|
||||
.set_voltage_sel = tps65912_set_voltage_sel,
|
||||
.list_voltage = tps65912_list_voltage_ldo,
|
||||
.list_voltage = tps65912_list_voltage,
|
||||
};
|
||||
|
||||
static __devinit int tps65912_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_config config = { };
|
||||
struct tps_info *info;
|
||||
struct regulator_init_data *reg_data;
|
||||
struct regulator_dev *rdev;
|
||||
|
@ -500,7 +477,7 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
|
|||
|
||||
reg_data = pmic_plat_data->tps65912_pmic_init_data;
|
||||
|
||||
pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
|
||||
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
|
||||
if (!pmic)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -524,8 +501,12 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
|
|||
pmic->desc[i].type = REGULATOR_VOLTAGE;
|
||||
pmic->desc[i].owner = THIS_MODULE;
|
||||
range = tps65912_get_range(pmic, i);
|
||||
rdev = regulator_register(&pmic->desc[i],
|
||||
tps65912->dev, reg_data, pmic, NULL);
|
||||
|
||||
config.dev = tps65912->dev;
|
||||
config.init_data = reg_data;
|
||||
config.driver_data = pmic;
|
||||
|
||||
rdev = regulator_register(&pmic->desc[i], &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(tps65912->dev,
|
||||
"failed to register %s regulator\n",
|
||||
|
@ -542,8 +523,6 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
|
|||
err:
|
||||
while (--i >= 0)
|
||||
regulator_unregister(pmic->rdev[i]);
|
||||
|
||||
kfree(pmic);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -554,8 +533,6 @@ static int __devexit tps65912_remove(struct platform_device *pdev)
|
|||
|
||||
for (i = 0; i < TPS65912_NUM_REGULATOR; i++)
|
||||
regulator_unregister(tps65912_reg->rdev[i]);
|
||||
|
||||
kfree(tps65912_reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -175,15 +175,14 @@ static int twl6030reg_is_enabled(struct regulator_dev *rdev)
|
|||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int grp = 0, val;
|
||||
|
||||
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
|
||||
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
|
||||
if (grp < 0)
|
||||
return grp;
|
||||
|
||||
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
|
||||
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) {
|
||||
grp = twlreg_grp(rdev);
|
||||
if (grp < 0)
|
||||
return grp;
|
||||
grp &= P1_GRP_6030;
|
||||
else
|
||||
} else {
|
||||
grp = 1;
|
||||
}
|
||||
|
||||
val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
|
||||
val = TWL6030_CFG_STATE_APP(val);
|
||||
|
@ -197,7 +196,7 @@ static int twl4030reg_enable(struct regulator_dev *rdev)
|
|||
int grp;
|
||||
int ret;
|
||||
|
||||
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
|
||||
grp = twlreg_grp(rdev);
|
||||
if (grp < 0)
|
||||
return grp;
|
||||
|
||||
|
@ -205,8 +204,6 @@ static int twl4030reg_enable(struct regulator_dev *rdev)
|
|||
|
||||
ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
|
||||
|
||||
udelay(info->delay);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -217,26 +214,37 @@ static int twl6030reg_enable(struct regulator_dev *rdev)
|
|||
int ret;
|
||||
|
||||
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
|
||||
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
|
||||
grp = twlreg_grp(rdev);
|
||||
if (grp < 0)
|
||||
return grp;
|
||||
|
||||
ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
|
||||
grp << TWL6030_CFG_STATE_GRP_SHIFT |
|
||||
TWL6030_CFG_STATE_ON);
|
||||
|
||||
udelay(info->delay);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int twl4030reg_enable_time(struct regulator_dev *rdev)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
return info->delay;
|
||||
}
|
||||
|
||||
static int twl6030reg_enable_time(struct regulator_dev *rdev)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
return info->delay;
|
||||
}
|
||||
|
||||
static int twl4030reg_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int grp;
|
||||
int ret;
|
||||
|
||||
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
|
||||
grp = twlreg_grp(rdev);
|
||||
if (grp < 0)
|
||||
return grp;
|
||||
|
||||
|
@ -348,7 +356,7 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
|
|||
int val;
|
||||
|
||||
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
|
||||
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
|
||||
grp = twlreg_grp(rdev);
|
||||
|
||||
if (grp < 0)
|
||||
return grp;
|
||||
|
@ -473,31 +481,12 @@ static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
|
|||
}
|
||||
|
||||
static int
|
||||
twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
||||
unsigned *selector)
|
||||
twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int vsel;
|
||||
|
||||
for (vsel = 0; vsel < info->table_len; vsel++) {
|
||||
int mV = info->table[vsel];
|
||||
int uV;
|
||||
|
||||
if (IS_UNSUP(mV))
|
||||
continue;
|
||||
uV = LDO_MV(mV) * 1000;
|
||||
|
||||
/* REVISIT for VAUX2, first match may not be best/lowest */
|
||||
|
||||
/* use the first in-range value */
|
||||
if (min_uV <= uV && uV <= max_uV) {
|
||||
*selector = vsel;
|
||||
return twlreg_write(info, TWL_MODULE_PM_RECEIVER,
|
||||
VREG_VOLTAGE, vsel);
|
||||
}
|
||||
}
|
||||
|
||||
return -EDOM;
|
||||
return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE,
|
||||
selector);
|
||||
}
|
||||
|
||||
static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
|
||||
|
@ -516,12 +505,13 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
|
|||
static struct regulator_ops twl4030ldo_ops = {
|
||||
.list_voltage = twl4030ldo_list_voltage,
|
||||
|
||||
.set_voltage = twl4030ldo_set_voltage,
|
||||
.set_voltage_sel = twl4030ldo_set_voltage_sel,
|
||||
.get_voltage = twl4030ldo_get_voltage,
|
||||
|
||||
.enable = twl4030reg_enable,
|
||||
.disable = twl4030reg_disable,
|
||||
.is_enabled = twl4030reg_is_enabled,
|
||||
.enable_time = twl4030reg_enable_time,
|
||||
|
||||
.set_mode = twl4030reg_set_mode,
|
||||
|
||||
|
@ -642,6 +632,7 @@ static struct regulator_ops twl6030ldo_ops = {
|
|||
.enable = twl6030reg_enable,
|
||||
.disable = twl6030reg_disable,
|
||||
.is_enabled = twl6030reg_is_enabled,
|
||||
.enable_time = twl6030reg_enable_time,
|
||||
|
||||
.set_mode = twl6030reg_set_mode,
|
||||
|
||||
|
@ -675,6 +666,7 @@ static struct regulator_ops twl4030fixed_ops = {
|
|||
.enable = twl4030reg_enable,
|
||||
.disable = twl4030reg_disable,
|
||||
.is_enabled = twl4030reg_is_enabled,
|
||||
.enable_time = twl4030reg_enable_time,
|
||||
|
||||
.set_mode = twl4030reg_set_mode,
|
||||
|
||||
|
@ -689,6 +681,7 @@ static struct regulator_ops twl6030fixed_ops = {
|
|||
.enable = twl6030reg_enable,
|
||||
.disable = twl6030reg_disable,
|
||||
.is_enabled = twl6030reg_is_enabled,
|
||||
.enable_time = twl6030reg_enable_time,
|
||||
|
||||
.set_mode = twl6030reg_set_mode,
|
||||
|
||||
|
@ -699,6 +692,7 @@ static struct regulator_ops twl6030_fixed_resource = {
|
|||
.enable = twl6030reg_enable,
|
||||
.disable = twl6030reg_disable,
|
||||
.is_enabled = twl6030reg_is_enabled,
|
||||
.enable_time = twl6030reg_enable_time,
|
||||
.get_status = twl6030reg_get_status,
|
||||
};
|
||||
|
||||
|
@ -806,10 +800,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
vsel = 0;
|
||||
else if ((min_uV >= 600000) && (min_uV <= 1300000)) {
|
||||
int calc_uV;
|
||||
vsel = (min_uV - 600000) / 125;
|
||||
if (vsel % 100)
|
||||
vsel += 100;
|
||||
vsel /= 100;
|
||||
vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
|
||||
vsel++;
|
||||
calc_uV = twl6030smps_list_voltage(rdev, vsel);
|
||||
if (calc_uV > max_uV)
|
||||
|
@ -836,10 +827,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
vsel = 0;
|
||||
else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
|
||||
int calc_uV;
|
||||
vsel = (min_uV - 700000) / 125;
|
||||
if (vsel % 100)
|
||||
vsel += 100;
|
||||
vsel /= 100;
|
||||
vsel = DIV_ROUND_UP(min_uV - 700000, 12500);
|
||||
vsel++;
|
||||
calc_uV = twl6030smps_list_voltage(rdev, vsel);
|
||||
if (calc_uV > max_uV)
|
||||
|
@ -862,24 +850,18 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
return -EINVAL;
|
||||
break;
|
||||
case SMPS_EXTENDED_EN:
|
||||
if (min_uV == 0)
|
||||
if (min_uV == 0) {
|
||||
vsel = 0;
|
||||
else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
|
||||
vsel = (min_uV - 1852000) / 386;
|
||||
if (vsel % 100)
|
||||
vsel += 100;
|
||||
vsel /= 100;
|
||||
} else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
|
||||
vsel = DIV_ROUND_UP(min_uV - 1852000, 38600);
|
||||
vsel++;
|
||||
}
|
||||
break;
|
||||
case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
|
||||
if (min_uV == 0)
|
||||
if (min_uV == 0) {
|
||||
vsel = 0;
|
||||
else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
|
||||
vsel = (min_uV - 2161000) / 386;
|
||||
if (vsel % 100)
|
||||
vsel += 100;
|
||||
vsel /= 100;
|
||||
} else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
|
||||
vsel = DIV_ROUND_UP(min_uV - 2161000, 38600);
|
||||
vsel++;
|
||||
}
|
||||
break;
|
||||
|
@ -907,6 +889,7 @@ static struct regulator_ops twlsmps_ops = {
|
|||
.enable = twl6030reg_enable,
|
||||
.disable = twl6030reg_disable,
|
||||
.is_enabled = twl6030reg_is_enabled,
|
||||
.enable_time = twl6030reg_enable_time,
|
||||
|
||||
.set_mode = twl6030reg_set_mode,
|
||||
|
||||
|
@ -1194,6 +1177,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
struct regulator_dev *rdev;
|
||||
struct twl_regulator_driver_data *drvdata;
|
||||
const struct of_device_id *match;
|
||||
struct regulator_config config = { };
|
||||
|
||||
match = of_match_device(twl_of_match, &pdev->dev);
|
||||
if (match) {
|
||||
|
@ -1207,10 +1191,12 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
initdata = pdev->dev.platform_data;
|
||||
for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
|
||||
info = twl_of_match[i].data;
|
||||
if (!info || info->desc.id != id)
|
||||
continue;
|
||||
break;
|
||||
if (info && info->desc.id == id)
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(twl_of_match))
|
||||
return -ENODEV;
|
||||
|
||||
drvdata = initdata->driver_data;
|
||||
if (!drvdata)
|
||||
return -EINVAL;
|
||||
|
@ -1273,8 +1259,12 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
break;
|
||||
}
|
||||
|
||||
rdev = regulator_register(&info->desc, &pdev->dev, initdata, info,
|
||||
pdev->dev.of_node);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = initdata;
|
||||
config.driver_data = info;
|
||||
config.of_node = pdev->dev.of_node;
|
||||
|
||||
rdev = regulator_register(&info->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "can't register %s, %ld\n",
|
||||
info->desc.name, PTR_ERR(rdev));
|
||||
|
|
|
@ -60,41 +60,6 @@ struct wm831x_dcdc {
|
|||
int dvs_vsel;
|
||||
};
|
||||
|
||||
static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = dcdc->wm831x;
|
||||
int mask = 1 << rdev_get_id(rdev);
|
||||
int reg;
|
||||
|
||||
reg = wm831x_reg_read(wm831x, WM831X_DCDC_ENABLE);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
if (reg & mask)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm831x_dcdc_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = dcdc->wm831x;
|
||||
int mask = 1 << rdev_get_id(rdev);
|
||||
|
||||
return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, mask);
|
||||
}
|
||||
|
||||
static int wm831x_dcdc_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = dcdc->wm831x;
|
||||
int mask = 1 << rdev_get_id(rdev);
|
||||
|
||||
return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, 0);
|
||||
}
|
||||
|
||||
static unsigned int wm831x_dcdc_get_mode(struct regulator_dev *rdev)
|
||||
|
||||
{
|
||||
|
@ -414,9 +379,9 @@ static struct regulator_ops wm831x_buckv_ops = {
|
|||
.set_current_limit = wm831x_buckv_set_current_limit,
|
||||
.get_current_limit = wm831x_buckv_get_current_limit,
|
||||
|
||||
.is_enabled = wm831x_dcdc_is_enabled,
|
||||
.enable = wm831x_dcdc_enable,
|
||||
.disable = wm831x_dcdc_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_status = wm831x_dcdc_get_status,
|
||||
.get_mode = wm831x_dcdc_get_mode,
|
||||
.set_mode = wm831x_dcdc_set_mode,
|
||||
|
@ -498,6 +463,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
|
||||
struct regulator_config config = { };
|
||||
int id;
|
||||
struct wm831x_dcdc *dcdc;
|
||||
struct resource *res;
|
||||
|
@ -511,9 +477,6 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
|
|||
|
||||
dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
|
||||
|
||||
if (pdata == NULL || pdata->dcdc[id] == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc),
|
||||
GFP_KERNEL);
|
||||
if (dcdc == NULL) {
|
||||
|
@ -538,6 +501,8 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
|
|||
dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1;
|
||||
dcdc->desc.ops = &wm831x_buckv_ops;
|
||||
dcdc->desc.owner = THIS_MODULE;
|
||||
dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
|
||||
dcdc->desc.enable_mask = 1 << id;
|
||||
|
||||
ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
|
||||
if (ret < 0) {
|
||||
|
@ -556,8 +521,13 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
|
|||
if (pdata->dcdc[id])
|
||||
wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data);
|
||||
|
||||
dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
|
||||
pdata->dcdc[id], dcdc, NULL);
|
||||
config.dev = pdev->dev.parent;
|
||||
if (pdata)
|
||||
config.init_data = pdata->dcdc[id];
|
||||
config.driver_data = dcdc;
|
||||
config.regmap = wm831x->regmap;
|
||||
|
||||
dcdc->regulator = regulator_register(&dcdc->desc, &config);
|
||||
if (IS_ERR(dcdc->regulator)) {
|
||||
ret = PTR_ERR(dcdc->regulator);
|
||||
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
|
||||
|
@ -675,29 +645,15 @@ static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev,
|
|||
return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV, &selector);
|
||||
}
|
||||
|
||||
static int wm831x_buckp_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = dcdc->wm831x;
|
||||
u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
|
||||
int val;
|
||||
|
||||
val = wm831x_reg_read(wm831x, reg);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
return val & WM831X_DC3_ON_VSEL_MASK;
|
||||
}
|
||||
|
||||
static struct regulator_ops wm831x_buckp_ops = {
|
||||
.set_voltage = wm831x_buckp_set_voltage,
|
||||
.get_voltage_sel = wm831x_buckp_get_voltage_sel,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = wm831x_buckp_list_voltage,
|
||||
.set_suspend_voltage = wm831x_buckp_set_suspend_voltage,
|
||||
|
||||
.is_enabled = wm831x_dcdc_is_enabled,
|
||||
.enable = wm831x_dcdc_enable,
|
||||
.disable = wm831x_dcdc_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_status = wm831x_dcdc_get_status,
|
||||
.get_mode = wm831x_dcdc_get_mode,
|
||||
.set_mode = wm831x_dcdc_set_mode,
|
||||
|
@ -708,6 +664,7 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
|
||||
struct regulator_config config = { };
|
||||
int id;
|
||||
struct wm831x_dcdc *dcdc;
|
||||
struct resource *res;
|
||||
|
@ -721,9 +678,6 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
|
|||
|
||||
dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
|
||||
|
||||
if (pdata == NULL || pdata->dcdc[id] == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc),
|
||||
GFP_KERNEL);
|
||||
if (dcdc == NULL) {
|
||||
|
@ -748,9 +702,18 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
|
|||
dcdc->desc.n_voltages = WM831X_BUCKP_MAX_SELECTOR + 1;
|
||||
dcdc->desc.ops = &wm831x_buckp_ops;
|
||||
dcdc->desc.owner = THIS_MODULE;
|
||||
dcdc->desc.vsel_reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
|
||||
dcdc->desc.vsel_mask = WM831X_DC3_ON_VSEL_MASK;
|
||||
dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
|
||||
dcdc->desc.enable_mask = 1 << id;
|
||||
|
||||
dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
|
||||
pdata->dcdc[id], dcdc, NULL);
|
||||
config.dev = pdev->dev.parent;
|
||||
if (pdata)
|
||||
config.init_data = pdata->dcdc[id];
|
||||
config.driver_data = dcdc;
|
||||
config.regmap = wm831x->regmap;
|
||||
|
||||
dcdc->regulator = regulator_register(&dcdc->desc, &config);
|
||||
if (IS_ERR(dcdc->regulator)) {
|
||||
ret = PTR_ERR(dcdc->regulator);
|
||||
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
|
||||
|
@ -832,15 +795,16 @@ static int wm831x_boostp_get_status(struct regulator_dev *rdev)
|
|||
static struct regulator_ops wm831x_boostp_ops = {
|
||||
.get_status = wm831x_boostp_get_status,
|
||||
|
||||
.is_enabled = wm831x_dcdc_is_enabled,
|
||||
.enable = wm831x_dcdc_enable,
|
||||
.disable = wm831x_dcdc_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
};
|
||||
|
||||
static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
|
||||
struct regulator_config config = { };
|
||||
int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
|
||||
struct wm831x_dcdc *dcdc;
|
||||
struct resource *res;
|
||||
|
@ -851,7 +815,7 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
|
|||
if (pdata == NULL || pdata->dcdc[id] == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
|
||||
dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL);
|
||||
if (dcdc == NULL) {
|
||||
dev_err(&pdev->dev, "Unable to allocate private data\n");
|
||||
return -ENOMEM;
|
||||
|
@ -873,9 +837,15 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
|
|||
dcdc->desc.type = REGULATOR_VOLTAGE;
|
||||
dcdc->desc.ops = &wm831x_boostp_ops;
|
||||
dcdc->desc.owner = THIS_MODULE;
|
||||
dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
|
||||
dcdc->desc.enable_mask = 1 << id;
|
||||
|
||||
dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
|
||||
pdata->dcdc[id], dcdc, NULL);
|
||||
config.dev = pdev->dev.parent;
|
||||
config.init_data = pdata->dcdc[id];
|
||||
config.driver_data = dcdc;
|
||||
config.regmap = wm831x->regmap;
|
||||
|
||||
dcdc->regulator = regulator_register(&dcdc->desc, &config);
|
||||
if (IS_ERR(dcdc->regulator)) {
|
||||
ret = PTR_ERR(dcdc->regulator);
|
||||
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
|
||||
|
@ -900,7 +870,6 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
|
|||
err_regulator:
|
||||
regulator_unregister(dcdc->regulator);
|
||||
err:
|
||||
kfree(dcdc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -912,7 +881,6 @@ static __devexit int wm831x_boostp_remove(struct platform_device *pdev)
|
|||
|
||||
free_irq(platform_get_irq_byname(pdev, "UV"), dcdc);
|
||||
regulator_unregister(dcdc->regulator);
|
||||
kfree(dcdc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -936,9 +904,9 @@ static struct platform_driver wm831x_boostp_driver = {
|
|||
#define WM831X_EPE_BASE 6
|
||||
|
||||
static struct regulator_ops wm831x_epe_ops = {
|
||||
.is_enabled = wm831x_dcdc_is_enabled,
|
||||
.enable = wm831x_dcdc_enable,
|
||||
.disable = wm831x_dcdc_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_status = wm831x_dcdc_get_status,
|
||||
};
|
||||
|
||||
|
@ -946,16 +914,14 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
|
||||
struct regulator_config config = { };
|
||||
int id = pdev->id % ARRAY_SIZE(pdata->epe);
|
||||
struct wm831x_dcdc *dcdc;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1);
|
||||
|
||||
if (pdata == NULL || pdata->epe[id] == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
|
||||
dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL);
|
||||
if (dcdc == NULL) {
|
||||
dev_err(&pdev->dev, "Unable to allocate private data\n");
|
||||
return -ENOMEM;
|
||||
|
@ -972,9 +938,16 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
|
|||
dcdc->desc.ops = &wm831x_epe_ops;
|
||||
dcdc->desc.type = REGULATOR_VOLTAGE;
|
||||
dcdc->desc.owner = THIS_MODULE;
|
||||
dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
|
||||
dcdc->desc.enable_mask = 1 << dcdc->desc.id;
|
||||
|
||||
dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
|
||||
pdata->epe[id], dcdc, NULL);
|
||||
config.dev = pdev->dev.parent;
|
||||
if (pdata)
|
||||
config.init_data = pdata->epe[id];
|
||||
config.driver_data = dcdc;
|
||||
config.regmap = wm831x->regmap;
|
||||
|
||||
dcdc->regulator = regulator_register(&dcdc->desc, &config);
|
||||
if (IS_ERR(dcdc->regulator)) {
|
||||
ret = PTR_ERR(dcdc->regulator);
|
||||
dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
|
||||
|
@ -987,7 +960,6 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
err:
|
||||
kfree(dcdc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -996,9 +968,7 @@ static __devexit 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);
|
||||
kfree(dcdc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -154,6 +154,7 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
|
|||
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
|
||||
struct wm831x_isink *isink;
|
||||
int id = pdev->id % ARRAY_SIZE(pdata->isink);
|
||||
struct regulator_config config = { };
|
||||
struct resource *res;
|
||||
int ret, irq;
|
||||
|
||||
|
@ -189,8 +190,11 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
|
|||
isink->desc.type = REGULATOR_CURRENT;
|
||||
isink->desc.owner = THIS_MODULE;
|
||||
|
||||
isink->regulator = regulator_register(&isink->desc, &pdev->dev,
|
||||
pdata->isink[id], isink, NULL);
|
||||
config.dev = pdev->dev.parent;
|
||||
config.init_data = pdata->isink[id];
|
||||
config.driver_data = isink;
|
||||
|
||||
isink->regulator = regulator_register(&isink->desc, &config);
|
||||
if (IS_ERR(isink->regulator)) {
|
||||
ret = PTR_ERR(isink->regulator);
|
||||
dev_err(wm831x->dev, "Failed to register ISINK%d: %d\n",
|
||||
|
|
|
@ -46,41 +46,6 @@ struct wm831x_ldo {
|
|||
* Shared
|
||||
*/
|
||||
|
||||
static int wm831x_ldo_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = ldo->wm831x;
|
||||
int mask = 1 << rdev_get_id(rdev);
|
||||
int reg;
|
||||
|
||||
reg = wm831x_reg_read(wm831x, WM831X_LDO_ENABLE);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
if (reg & mask)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm831x_ldo_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = ldo->wm831x;
|
||||
int mask = 1 << rdev_get_id(rdev);
|
||||
|
||||
return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, mask);
|
||||
}
|
||||
|
||||
static int wm831x_ldo_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = ldo->wm831x;
|
||||
int mask = 1 << rdev_get_id(rdev);
|
||||
|
||||
return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, 0);
|
||||
}
|
||||
|
||||
static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
|
||||
{
|
||||
struct wm831x_ldo *ldo = data;
|
||||
|
@ -105,7 +70,7 @@ static int wm831x_gp_ldo_list_voltage(struct regulator_dev *rdev,
|
|||
/* 0.9-1.6V in 50mV steps */
|
||||
if (selector <= WM831X_GP_LDO_SELECTOR_LOW)
|
||||
return 900000 + (selector * 50000);
|
||||
/* 1.7-3.3V in 50mV steps */
|
||||
/* 1.7-3.3V in 100mV steps */
|
||||
if (selector <= WM831X_GP_LDO_MAX_SELECTOR)
|
||||
return 1600000 + ((selector - WM831X_GP_LDO_SELECTOR_LOW)
|
||||
* 100000);
|
||||
|
@ -160,22 +125,6 @@ static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev,
|
|||
return wm831x_gp_ldo_set_voltage_int(rdev, reg, uV, uV, &selector);
|
||||
}
|
||||
|
||||
static int wm831x_gp_ldo_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = ldo->wm831x;
|
||||
int reg = ldo->base + WM831X_LDO_ON_CONTROL;
|
||||
int ret;
|
||||
|
||||
ret = wm831x_reg_read(wm831x, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret &= WM831X_LDO1_ON_VSEL_MASK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
|
@ -293,7 +242,7 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev,
|
|||
|
||||
static struct regulator_ops wm831x_gp_ldo_ops = {
|
||||
.list_voltage = wm831x_gp_ldo_list_voltage,
|
||||
.get_voltage_sel = wm831x_gp_ldo_get_voltage_sel,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage = wm831x_gp_ldo_set_voltage,
|
||||
.set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage,
|
||||
.get_mode = wm831x_gp_ldo_get_mode,
|
||||
|
@ -301,15 +250,16 @@ static struct regulator_ops wm831x_gp_ldo_ops = {
|
|||
.get_status = wm831x_gp_ldo_get_status,
|
||||
.get_optimum_mode = wm831x_gp_ldo_get_optimum_mode,
|
||||
|
||||
.is_enabled = wm831x_ldo_is_enabled,
|
||||
.enable = wm831x_ldo_enable,
|
||||
.disable = wm831x_ldo_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
};
|
||||
|
||||
static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
|
||||
struct regulator_config config = { };
|
||||
int id;
|
||||
struct wm831x_ldo *ldo;
|
||||
struct resource *res;
|
||||
|
@ -323,9 +273,6 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
|
|||
|
||||
dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
|
||||
|
||||
if (pdata == NULL || pdata->ldo[id] == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
|
||||
if (ldo == NULL) {
|
||||
dev_err(&pdev->dev, "Unable to allocate private data\n");
|
||||
|
@ -349,9 +296,18 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
|
|||
ldo->desc.n_voltages = WM831X_GP_LDO_MAX_SELECTOR + 1;
|
||||
ldo->desc.ops = &wm831x_gp_ldo_ops;
|
||||
ldo->desc.owner = THIS_MODULE;
|
||||
ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
|
||||
ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK;
|
||||
ldo->desc.enable_reg = WM831X_LDO_ENABLE;
|
||||
ldo->desc.enable_mask = 1 << id;
|
||||
|
||||
ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
|
||||
pdata->ldo[id], ldo, NULL);
|
||||
config.dev = pdev->dev.parent;
|
||||
if (pdata)
|
||||
config.init_data = pdata->ldo[id];
|
||||
config.driver_data = ldo;
|
||||
config.regmap = wm831x->regmap;
|
||||
|
||||
ldo->regulator = regulator_register(&ldo->desc, &config);
|
||||
if (IS_ERR(ldo->regulator)) {
|
||||
ret = PTR_ERR(ldo->regulator);
|
||||
dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
|
||||
|
@ -414,7 +370,7 @@ static int wm831x_aldo_list_voltage(struct regulator_dev *rdev,
|
|||
/* 1-1.6V in 50mV steps */
|
||||
if (selector <= WM831X_ALDO_SELECTOR_LOW)
|
||||
return 1000000 + (selector * 50000);
|
||||
/* 1.7-3.5V in 50mV steps */
|
||||
/* 1.7-3.5V in 100mV steps */
|
||||
if (selector <= WM831X_ALDO_MAX_SELECTOR)
|
||||
return 1600000 + ((selector - WM831X_ALDO_SELECTOR_LOW)
|
||||
* 100000);
|
||||
|
@ -468,22 +424,6 @@ static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev,
|
|||
return wm831x_aldo_set_voltage_int(rdev, reg, uV, uV, &selector);
|
||||
}
|
||||
|
||||
static int wm831x_aldo_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = ldo->wm831x;
|
||||
int reg = ldo->base + WM831X_LDO_ON_CONTROL;
|
||||
int ret;
|
||||
|
||||
ret = wm831x_reg_read(wm831x, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret &= WM831X_LDO7_ON_VSEL_MASK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
|
@ -559,22 +499,23 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev)
|
|||
|
||||
static struct regulator_ops wm831x_aldo_ops = {
|
||||
.list_voltage = wm831x_aldo_list_voltage,
|
||||
.get_voltage_sel = wm831x_aldo_get_voltage_sel,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage = wm831x_aldo_set_voltage,
|
||||
.set_suspend_voltage = wm831x_aldo_set_suspend_voltage,
|
||||
.get_mode = wm831x_aldo_get_mode,
|
||||
.set_mode = wm831x_aldo_set_mode,
|
||||
.get_status = wm831x_aldo_get_status,
|
||||
|
||||
.is_enabled = wm831x_ldo_is_enabled,
|
||||
.enable = wm831x_ldo_enable,
|
||||
.disable = wm831x_ldo_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
};
|
||||
|
||||
static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
|
||||
struct regulator_config config = { };
|
||||
int id;
|
||||
struct wm831x_ldo *ldo;
|
||||
struct resource *res;
|
||||
|
@ -588,9 +529,6 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
|
|||
|
||||
dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
|
||||
|
||||
if (pdata == NULL || pdata->ldo[id] == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
|
||||
if (ldo == NULL) {
|
||||
dev_err(&pdev->dev, "Unable to allocate private data\n");
|
||||
|
@ -614,9 +552,18 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
|
|||
ldo->desc.n_voltages = WM831X_ALDO_MAX_SELECTOR + 1;
|
||||
ldo->desc.ops = &wm831x_aldo_ops;
|
||||
ldo->desc.owner = THIS_MODULE;
|
||||
ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
|
||||
ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK;
|
||||
ldo->desc.enable_reg = WM831X_LDO_ENABLE;
|
||||
ldo->desc.enable_mask = 1 << id;
|
||||
|
||||
ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
|
||||
pdata->ldo[id], ldo, NULL);
|
||||
config.dev = pdev->dev.parent;
|
||||
if (pdata)
|
||||
config.init_data = pdata->ldo[id];
|
||||
config.driver_data = ldo;
|
||||
config.regmap = wm831x->regmap;
|
||||
|
||||
ldo->regulator = regulator_register(&ldo->desc, &config);
|
||||
if (IS_ERR(ldo->regulator)) {
|
||||
ret = PTR_ERR(ldo->regulator);
|
||||
dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
|
||||
|
@ -720,22 +667,6 @@ static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev,
|
|||
return wm831x_alive_ldo_set_voltage_int(rdev, reg, uV, uV, &selector);
|
||||
}
|
||||
|
||||
static int wm831x_alive_ldo_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = ldo->wm831x;
|
||||
int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL;
|
||||
int ret;
|
||||
|
||||
ret = wm831x_reg_read(wm831x, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret &= WM831X_LDO11_ON_VSEL_MASK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
|
@ -755,20 +686,21 @@ static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev)
|
|||
|
||||
static struct regulator_ops wm831x_alive_ldo_ops = {
|
||||
.list_voltage = wm831x_alive_ldo_list_voltage,
|
||||
.get_voltage_sel = wm831x_alive_ldo_get_voltage_sel,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage = wm831x_alive_ldo_set_voltage,
|
||||
.set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage,
|
||||
.get_status = wm831x_alive_ldo_get_status,
|
||||
|
||||
.is_enabled = wm831x_ldo_is_enabled,
|
||||
.enable = wm831x_ldo_enable,
|
||||
.disable = wm831x_ldo_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
};
|
||||
|
||||
static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
|
||||
struct regulator_config config = { };
|
||||
int id;
|
||||
struct wm831x_ldo *ldo;
|
||||
struct resource *res;
|
||||
|
@ -783,9 +715,6 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
|
|||
|
||||
dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
|
||||
|
||||
if (pdata == NULL || pdata->ldo[id] == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
|
||||
if (ldo == NULL) {
|
||||
dev_err(&pdev->dev, "Unable to allocate private data\n");
|
||||
|
@ -809,9 +738,18 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
|
|||
ldo->desc.n_voltages = WM831X_ALIVE_LDO_MAX_SELECTOR + 1;
|
||||
ldo->desc.ops = &wm831x_alive_ldo_ops;
|
||||
ldo->desc.owner = THIS_MODULE;
|
||||
ldo->desc.vsel_reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL;
|
||||
ldo->desc.vsel_mask = WM831X_LDO11_ON_VSEL_MASK;
|
||||
ldo->desc.enable_reg = WM831X_LDO_ENABLE;
|
||||
ldo->desc.enable_mask = 1 << id;
|
||||
|
||||
ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
|
||||
pdata->ldo[id], ldo, NULL);
|
||||
config.dev = pdev->dev.parent;
|
||||
if (pdata)
|
||||
config.init_data = pdata->ldo[id];
|
||||
config.driver_data = ldo;
|
||||
config.regmap = wm831x->regmap;
|
||||
|
||||
ldo->regulator = regulator_register(&ldo->desc, &config);
|
||||
if (IS_ERR(ldo->regulator)) {
|
||||
ret = PTR_ERR(ldo->regulator);
|
||||
dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
|
||||
|
|
|
@ -1269,7 +1269,7 @@ static struct regulator_ops wm8350_isink_ops = {
|
|||
.enable_time = wm8350_isink_enable_time,
|
||||
};
|
||||
|
||||
static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
|
||||
static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
|
||||
{
|
||||
.name = "DCDC1",
|
||||
.id = WM8350_DCDC_1,
|
||||
|
@ -1398,6 +1398,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
|
|||
static int wm8350_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
int ret;
|
||||
u16 val;
|
||||
|
@ -1425,10 +1426,12 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
|
|||
break;
|
||||
}
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdev->dev.platform_data;
|
||||
config.driver_data = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
/* register regulator */
|
||||
rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
|
||||
pdev->dev.platform_data,
|
||||
dev_get_drvdata(&pdev->dev), NULL);
|
||||
rdev = regulator_register(&wm8350_reg[pdev->id], &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "failed to register %s\n",
|
||||
wm8350_reg[pdev->id].name);
|
||||
|
|
|
@ -323,11 +323,14 @@ static struct regulator_desc regulators[] = {
|
|||
static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
|
||||
rdev = regulator_register(®ulators[pdev->id], &pdev->dev,
|
||||
pdev->dev.platform_data, wm8400, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdev->dev.platform_data;
|
||||
config.driver_data = wm8400;
|
||||
|
||||
rdev = regulator_register(®ulators[pdev->id], &config);
|
||||
if (IS_ERR(rdev))
|
||||
return PTR_ERR(rdev);
|
||||
|
||||
|
|
|
@ -86,36 +86,6 @@ static int wm8994_ldo1_list_voltage(struct regulator_dev *rdev,
|
|||
return (selector * 100000) + 2400000;
|
||||
}
|
||||
|
||||
static int wm8994_ldo1_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
int val;
|
||||
|
||||
val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_1);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
return (val & WM8994_LDO1_VSEL_MASK) >> WM8994_LDO1_VSEL_SHIFT;
|
||||
}
|
||||
|
||||
static int wm8994_ldo1_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *s)
|
||||
{
|
||||
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
int selector, v;
|
||||
|
||||
selector = (min_uV - 2400000) / 100000;
|
||||
v = wm8994_ldo1_list_voltage(rdev, selector);
|
||||
if (v < 0 || v > max_uV)
|
||||
return -EINVAL;
|
||||
|
||||
*s = selector;
|
||||
selector <<= WM8994_LDO1_VSEL_SHIFT;
|
||||
|
||||
return wm8994_set_bits(ldo->wm8994, WM8994_LDO_1,
|
||||
WM8994_LDO1_VSEL_MASK, selector);
|
||||
}
|
||||
|
||||
static struct regulator_ops wm8994_ldo1_ops = {
|
||||
.enable = wm8994_ldo_enable,
|
||||
.disable = wm8994_ldo_disable,
|
||||
|
@ -123,8 +93,8 @@ static struct regulator_ops wm8994_ldo1_ops = {
|
|||
.enable_time = wm8994_ldo_enable_time,
|
||||
|
||||
.list_voltage = wm8994_ldo1_list_voltage,
|
||||
.get_voltage_sel = wm8994_ldo1_get_voltage_sel,
|
||||
.set_voltage = wm8994_ldo1_set_voltage,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
|
||||
|
@ -153,51 +123,6 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
|
|||
}
|
||||
}
|
||||
|
||||
static int wm8994_ldo2_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
int val;
|
||||
|
||||
val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_2);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
return (val & WM8994_LDO2_VSEL_MASK) >> WM8994_LDO2_VSEL_SHIFT;
|
||||
}
|
||||
|
||||
static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *s)
|
||||
{
|
||||
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
|
||||
int selector, v;
|
||||
|
||||
switch (ldo->wm8994->type) {
|
||||
case WM8994:
|
||||
selector = (min_uV - 900000) / 100000;
|
||||
break;
|
||||
case WM8958:
|
||||
selector = (min_uV - 1000000) / 100000;
|
||||
break;
|
||||
case WM1811:
|
||||
selector = (min_uV - 950000) / 100000;
|
||||
if (selector == 0)
|
||||
selector = 1;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
v = wm8994_ldo2_list_voltage(rdev, selector);
|
||||
if (v < 0 || v > max_uV)
|
||||
return -EINVAL;
|
||||
|
||||
*s = selector;
|
||||
selector <<= WM8994_LDO2_VSEL_SHIFT;
|
||||
|
||||
return wm8994_set_bits(ldo->wm8994, WM8994_LDO_2,
|
||||
WM8994_LDO2_VSEL_MASK, selector);
|
||||
}
|
||||
|
||||
static struct regulator_ops wm8994_ldo2_ops = {
|
||||
.enable = wm8994_ldo_enable,
|
||||
.disable = wm8994_ldo_disable,
|
||||
|
@ -205,16 +130,18 @@ static struct regulator_ops wm8994_ldo2_ops = {
|
|||
.enable_time = wm8994_ldo_enable_time,
|
||||
|
||||
.list_voltage = wm8994_ldo2_list_voltage,
|
||||
.get_voltage_sel = wm8994_ldo2_get_voltage_sel,
|
||||
.set_voltage = wm8994_ldo2_set_voltage,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_desc wm8994_ldo_desc[] = {
|
||||
static const struct regulator_desc wm8994_ldo_desc[] = {
|
||||
{
|
||||
.name = "LDO1",
|
||||
.id = 1,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = WM8994_LDO1_MAX_SELECTOR + 1,
|
||||
.vsel_reg = WM8994_LDO_1,
|
||||
.vsel_mask = WM8994_LDO1_VSEL_MASK,
|
||||
.ops = &wm8994_ldo1_ops,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
@ -223,6 +150,8 @@ static struct regulator_desc wm8994_ldo_desc[] = {
|
|||
.id = 2,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = WM8994_LDO2_MAX_SELECTOR + 1,
|
||||
.vsel_reg = WM8994_LDO_2,
|
||||
.vsel_mask = WM8994_LDO2_VSEL_MASK,
|
||||
.ops = &wm8994_ldo2_ops,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
@ -233,6 +162,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
|
|||
struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm8994_pdata *pdata = wm8994->dev->platform_data;
|
||||
int id = pdev->id % ARRAY_SIZE(pdata->ldo);
|
||||
struct regulator_config config = { };
|
||||
struct wm8994_ldo *ldo;
|
||||
int ret;
|
||||
|
||||
|
@ -268,8 +198,12 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
|
|||
} else
|
||||
ldo->is_enabled = true;
|
||||
|
||||
ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev,
|
||||
pdata->ldo[id].init_data, ldo, NULL);
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = pdata->ldo[id].init_data;
|
||||
config.driver_data = ldo;
|
||||
config.regmap = wm8994->regmap;
|
||||
|
||||
ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &config);
|
||||
if (IS_ERR(ldo->regulator)) {
|
||||
ret = PTR_ERR(ldo->regulator);
|
||||
dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",
|
||||
|
|
|
@ -250,6 +250,26 @@ enum {
|
|||
RC5T583_EXT_PWRREQ2_CONTROL = 0x2,
|
||||
};
|
||||
|
||||
enum {
|
||||
RC5T583_REGULATOR_DC0,
|
||||
RC5T583_REGULATOR_DC1,
|
||||
RC5T583_REGULATOR_DC2,
|
||||
RC5T583_REGULATOR_DC3,
|
||||
RC5T583_REGULATOR_LDO0,
|
||||
RC5T583_REGULATOR_LDO1,
|
||||
RC5T583_REGULATOR_LDO2,
|
||||
RC5T583_REGULATOR_LDO3,
|
||||
RC5T583_REGULATOR_LDO4,
|
||||
RC5T583_REGULATOR_LDO5,
|
||||
RC5T583_REGULATOR_LDO6,
|
||||
RC5T583_REGULATOR_LDO7,
|
||||
RC5T583_REGULATOR_LDO8,
|
||||
RC5T583_REGULATOR_LDO9,
|
||||
|
||||
/* Should be last entry */
|
||||
RC5T583_REGULATOR_MAX,
|
||||
};
|
||||
|
||||
struct rc5t583 {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
|
@ -273,11 +293,20 @@ struct rc5t583 {
|
|||
* The board specific data is provided through this structure.
|
||||
* @irq_base: Irq base number on which this device registers their interrupts.
|
||||
* @enable_shutdown: Enable shutdown through the input pin "shutdown".
|
||||
* @regulator_deepsleep_slot: The slot number on which device goes to sleep
|
||||
* in device sleep mode.
|
||||
* @regulator_ext_pwr_control: External power request regulator control. The
|
||||
* regulator output enable/disable is controlled by the external
|
||||
* power request input state.
|
||||
* @reg_init_data: Regulator init data.
|
||||
*/
|
||||
|
||||
struct rc5t583_platform_data {
|
||||
int irq_base;
|
||||
bool enable_shutdown;
|
||||
int regulator_deepsleep_slot[RC5T583_REGULATOR_MAX];
|
||||
unsigned long regulator_ext_pwr_control[RC5T583_REGULATOR_MAX];
|
||||
struct regulator_init_data *reg_init_data[RC5T583_REGULATOR_MAX];
|
||||
};
|
||||
|
||||
static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
|
||||
|
|
|
@ -335,6 +335,7 @@ extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask);
|
|||
|
||||
struct s5m_platform_data {
|
||||
struct s5m_regulator_data *regulators;
|
||||
struct s5m_opmode_data *opmode;
|
||||
int device_type;
|
||||
int num_regulators;
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ enum s5m8767_regulators {
|
|||
S5M8767_REG_MAX,
|
||||
};
|
||||
|
||||
#define S5M8767_ENCTRL_SHIFT 6
|
||||
|
||||
/* S5M8763 regulator ids */
|
||||
enum s5m8763_regulators {
|
||||
S5M8763_LDO1,
|
||||
|
@ -97,4 +99,31 @@ struct s5m_regulator_data {
|
|||
struct regulator_init_data *initdata;
|
||||
};
|
||||
|
||||
/*
|
||||
* s5m_opmode_data - regulator operation mode data
|
||||
* @id: regulator id
|
||||
* @mode: regulator operation mode
|
||||
*/
|
||||
struct s5m_opmode_data {
|
||||
int id;
|
||||
int mode;
|
||||
};
|
||||
|
||||
/*
|
||||
* s5m regulator operation mode
|
||||
* S5M_OPMODE_OFF Regulator always OFF
|
||||
* S5M_OPMODE_ON Regulator always ON
|
||||
* S5M_OPMODE_LOWPOWER Regulator is on in low-power mode
|
||||
* S5M_OPMODE_SUSPEND Regulator is changed by PWREN pin
|
||||
* If PWREN is high, regulator is on
|
||||
* If PWREN is low, regulator is off
|
||||
*/
|
||||
|
||||
enum s5m_opmode {
|
||||
S5M_OPMODE_OFF,
|
||||
S5M_OPMODE_ON,
|
||||
S5M_OPMODE_LOWPOWER,
|
||||
S5M_OPMODE_SUSPEND,
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MFD_S5M_PMIC_H */
|
||||
|
|
|
@ -22,6 +22,19 @@
|
|||
#ifndef __LINUX_MFD_TPS65090_H
|
||||
#define __LINUX_MFD_TPS65090_H
|
||||
|
||||
#include <linux/irq.h>
|
||||
|
||||
struct tps65090 {
|
||||
struct mutex lock;
|
||||
struct device *dev;
|
||||
struct i2c_client *client;
|
||||
struct regmap *rmap;
|
||||
struct irq_chip irq_chip;
|
||||
struct mutex irq_lock;
|
||||
int irq_base;
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
struct tps65090_subdev_info {
|
||||
int id;
|
||||
const char *name;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/notifier.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
struct regmap;
|
||||
struct regulator_dev;
|
||||
struct regulator_init_data;
|
||||
|
||||
|
@ -148,10 +149,12 @@ enum regulator_type {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct regulator_desc - Regulator descriptor
|
||||
* struct regulator_desc - Static regulator descriptor
|
||||
*
|
||||
* Each regulator registered with the core is described with a structure of
|
||||
* this type.
|
||||
* Each regulator registered with the core is described with a
|
||||
* structure of this type and a struct regulator_config. This
|
||||
* structure contains the non-varying parts of the regulator
|
||||
* description.
|
||||
*
|
||||
* @name: Identifying name for the regulator.
|
||||
* @supply_name: Identifying the regulator supply
|
||||
|
@ -161,6 +164,11 @@ enum regulator_type {
|
|||
* @irq: Interrupt number for the regulator.
|
||||
* @type: Indicates if the regulator is a voltage or current regulator.
|
||||
* @owner: Module providing the regulator, used for refcounting.
|
||||
|
||||
* @vsel_reg: Register for selector when using regulator_regmap_X_voltage_
|
||||
* @vsel_mask: Mask for register bitfield used for selector
|
||||
* @enable_reg: Register for control when using regmap enable/disable ops
|
||||
* @enable_mask: Mask for control when using regmap enable/disable ops
|
||||
*/
|
||||
struct regulator_desc {
|
||||
const char *name;
|
||||
|
@ -171,6 +179,33 @@ struct regulator_desc {
|
|||
int irq;
|
||||
enum regulator_type type;
|
||||
struct module *owner;
|
||||
|
||||
unsigned int vsel_reg;
|
||||
unsigned int vsel_mask;
|
||||
unsigned int enable_reg;
|
||||
unsigned int enable_mask;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct regulator_config - Dynamic regulator descriptor
|
||||
*
|
||||
* Each regulator registered with the core is described with a
|
||||
* structure of this type and a struct regulator_desc. This structure
|
||||
* contains the runtime variable parts of the regulator description.
|
||||
*
|
||||
* @dev: struct device for the regulator
|
||||
* @init_data: platform provided init data, passed through by driver
|
||||
* @driver_data: private regulator data
|
||||
* @of_node: OpenFirmware node to parse for device tree bindings (may be
|
||||
* NULL).
|
||||
* @regmap: regmap to use for core regmap helpers
|
||||
*/
|
||||
struct regulator_config {
|
||||
struct device *dev;
|
||||
const struct regulator_init_data *init_data;
|
||||
void *driver_data;
|
||||
struct device_node *of_node;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -184,7 +219,7 @@ struct regulator_desc {
|
|||
* no other direct access).
|
||||
*/
|
||||
struct regulator_dev {
|
||||
struct regulator_desc *desc;
|
||||
const struct regulator_desc *desc;
|
||||
int exclusive;
|
||||
u32 use_count;
|
||||
u32 open_count;
|
||||
|
@ -201,6 +236,7 @@ struct regulator_dev {
|
|||
struct device dev;
|
||||
struct regulation_constraints *constraints;
|
||||
struct regulator *supply; /* for tree */
|
||||
struct regmap *regmap;
|
||||
|
||||
struct delayed_work disable_work;
|
||||
int deferred_disables;
|
||||
|
@ -210,9 +246,9 @@ struct regulator_dev {
|
|||
struct dentry *debugfs;
|
||||
};
|
||||
|
||||
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
||||
struct device *dev, const struct regulator_init_data *init_data,
|
||||
void *driver_data, struct device_node *of_node);
|
||||
struct regulator_dev *
|
||||
regulator_register(const struct regulator_desc *regulator_desc,
|
||||
const struct regulator_config *config);
|
||||
void regulator_unregister(struct regulator_dev *rdev);
|
||||
|
||||
int regulator_notifier_call_chain(struct regulator_dev *rdev,
|
||||
|
@ -224,6 +260,12 @@ int rdev_get_id(struct regulator_dev *rdev);
|
|||
|
||||
int regulator_mode_to_status(unsigned int);
|
||||
|
||||
int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev);
|
||||
int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel);
|
||||
int regulator_is_enabled_regmap(struct regulator_dev *rdev);
|
||||
int regulator_enable_regmap(struct regulator_dev *rdev);
|
||||
int regulator_disable_regmap(struct regulator_dev *rdev);
|
||||
|
||||
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,12 @@ struct regulator_init_data;
|
|||
* @gpio: GPIO to use for enable control
|
||||
* set to -EINVAL if not used
|
||||
* @startup_delay: Start-up time in microseconds
|
||||
* @gpio_is_open_drain: Gpio pin is open drain or normal type.
|
||||
* If it is open drain type then HIGH will be set
|
||||
* through PULL-UP with setting gpio as input
|
||||
* and low will be set as gpio-output with driven
|
||||
* to low. For non-open-drain case, the gpio will
|
||||
* will be in output and drive to low/high accordingly.
|
||||
* @enable_high: Polarity of enable GPIO
|
||||
* 1 = Active high, 0 = Active low
|
||||
* @enabled_at_boot: Whether regulator has been enabled at
|
||||
|
@ -43,6 +49,7 @@ struct fixed_voltage_config {
|
|||
int microvolts;
|
||||
int gpio;
|
||||
unsigned startup_delay;
|
||||
unsigned gpio_is_open_drain:1;
|
||||
unsigned enable_high:1;
|
||||
unsigned enabled_at_boot:1;
|
||||
struct regulator_init_data *init_data;
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Regulator driver interface for TI TPS65090 PMIC family
|
||||
*
|
||||
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __REGULATOR_TPS65090_H
|
||||
#define __REGULATOR_TPS65090_H
|
||||
|
||||
#include <linux/regulator/machine.h>
|
||||
|
||||
#define tps65090_rails(_name) "tps65090_"#_name
|
||||
|
||||
enum {
|
||||
TPS65090_ID_DCDC1,
|
||||
TPS65090_ID_DCDC2,
|
||||
TPS65090_ID_DCDC3,
|
||||
TPS65090_ID_FET1,
|
||||
TPS65090_ID_FET2,
|
||||
TPS65090_ID_FET3,
|
||||
TPS65090_ID_FET4,
|
||||
TPS65090_ID_FET5,
|
||||
TPS65090_ID_FET6,
|
||||
TPS65090_ID_FET7,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct tps65090_regulator_platform_data
|
||||
*
|
||||
* @regulator: The regulator init data.
|
||||
* @slew_rate_uV_per_us: Slew rate microvolt per microsec.
|
||||
*/
|
||||
|
||||
struct tps65090_regulator_platform_data {
|
||||
struct regulator_init_data regulator;
|
||||
};
|
||||
|
||||
#endif /* __REGULATOR_TPS65090_H */
|
|
@ -809,6 +809,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
|
|||
{
|
||||
struct ldo_regulator *ldo;
|
||||
struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
|
||||
struct regulator_config config = { };
|
||||
|
||||
ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
|
||||
|
||||
|
@ -832,8 +833,11 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
|
|||
ldo->codec_data = codec;
|
||||
ldo->voltage = voltage;
|
||||
|
||||
ldo->dev = regulator_register(&ldo->desc, codec->dev,
|
||||
init_data, ldo, NULL);
|
||||
config.dev = codec->dev;
|
||||
config.driver_data = ldo;
|
||||
config.init_data = init_data;
|
||||
|
||||
ldo->dev = regulator_register(&ldo->desc, &config);
|
||||
if (IS_ERR(ldo->dev)) {
|
||||
int ret = PTR_ERR(ldo->dev);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче