regulator: ab8500: Add new operations for Vaux3

In former functions, only can set Vaux3 to 2.91V, because the
highest bit of Vaux3 register is put into another register. So
add new expanded functions for Vaux3's operation.

Signed-off-by: zhang xiaomei <xiaomei.zhang@stericsson.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
Lee Jones 2013-04-02 13:24:11 +01:00 committed by Mark Brown
parent bd44e2cb4a
commit d7607baf32
1 changed files with 128 additions and 1 deletions

View File

@ -63,6 +63,13 @@ struct ab8500_regulator_info {
u8 voltage_reg;
u8 voltage_mask;
u8 voltage_shift;
struct {
u8 voltage_limit;
u8 voltage_bank;
u8 voltage_reg;
u8 voltage_mask;
u8 voltage_shift;
} expand_register;
};
/* voltage tables for the vauxn/vintcore supplies */
@ -396,6 +403,57 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
return val >> info->voltage_shift;
}
static int ab8540_aux3_regulator_get_voltage_sel(struct regulator_dev *rdev)
{
int ret, val;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
u8 regval, regval_expand;
if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
return -EINVAL;
}
ret = abx500_get_register_interruptible(info->dev,
info->voltage_bank, info->voltage_reg, &regval);
if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"couldn't read voltage reg for regulator\n");
return ret;
}
ret = abx500_get_register_interruptible(info->dev,
info->expand_register.voltage_bank,
info->expand_register.voltage_reg, &regval_expand);
if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"couldn't read voltage reg for regulator\n");
return ret;
}
dev_vdbg(rdev_get_dev(rdev),
"%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
" 0x%x\n",
info->desc.name, info->voltage_bank, info->voltage_reg,
info->voltage_mask, regval);
dev_vdbg(rdev_get_dev(rdev),
"%s-get_voltage expand (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
" 0x%x\n",
info->desc.name, info->expand_register.voltage_bank,
info->expand_register.voltage_reg,
info->expand_register.voltage_mask, regval_expand);
if (regval_expand&(info->expand_register.voltage_mask))
/* Vaux3 has a different layout */
val = info->expand_register.voltage_limit;
else
val = (regval & info->voltage_mask) >> info->voltage_shift;
return val;
}
static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
unsigned selector)
{
@ -426,6 +484,55 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
return ret;
}
static int ab8540_aux3_regulator_set_voltage_sel(struct regulator_dev *rdev,
unsigned selector)
{
int ret;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
u8 regval;
if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
return -EINVAL;
}
if (selector >= info->expand_register.voltage_limit) {
/* Vaux3 bit4 has different layout */
regval = (u8)selector << info->expand_register.voltage_shift;
ret = abx500_mask_and_set_register_interruptible(info->dev,
info->expand_register.voltage_bank,
info->expand_register.voltage_reg,
info->expand_register.voltage_mask,
regval);
} else {
/* set the registers for the request */
regval = (u8)selector << info->voltage_shift;
ret = abx500_mask_and_set_register_interruptible(info->dev,
info->voltage_bank, info->voltage_reg,
info->voltage_mask, regval);
}
if (ret < 0)
dev_err(rdev_get_dev(rdev),
"couldn't set voltage reg for regulator\n");
dev_vdbg(rdev_get_dev(rdev),
"%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
" 0x%x\n",
info->desc.name, info->voltage_bank, info->voltage_reg,
info->voltage_mask, regval);
return ret;
}
static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
unsigned int old_sel,
unsigned int new_sel)
{
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
return info->delay;
}
static struct regulator_ops ab8500_regulator_volt_mode_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
@ -438,6 +545,19 @@ static struct regulator_ops ab8500_regulator_volt_mode_ops = {
.list_voltage = regulator_list_voltage_table,
};
static struct regulator_ops ab8540_aux3_regulator_volt_mode_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
.get_optimum_mode = ab8500_regulator_get_optimum_mode,
.set_mode = ab8500_regulator_set_mode,
.get_mode = ab8500_regulator_get_mode,
.is_enabled = ab8500_regulator_is_enabled,
.get_voltage_sel = ab8540_aux3_regulator_get_voltage_sel,
.set_voltage_sel = ab8540_aux3_regulator_set_voltage_sel,
.list_voltage = regulator_list_voltage_table,
.set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
};
static struct regulator_ops ab8500_regulator_volt_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
@ -1271,7 +1391,7 @@ static struct ab8500_regulator_info
[AB8540_LDO_AUX3] = {
.desc = {
.name = "LDO-AUX3",
.ops = &ab8500_regulator_volt_mode_ops,
.ops = &ab8540_aux3_regulator_volt_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8540_LDO_AUX3,
.owner = THIS_MODULE,
@ -1288,6 +1408,13 @@ static struct ab8500_regulator_info
.voltage_bank = 0x04,
.voltage_reg = 0x21,
.voltage_mask = 0x07,
.expand_register = {
.voltage_limit = 8,
.voltage_bank = 0x04,
.voltage_reg = 0x01,
.voltage_mask = 0x10,
.voltage_shift = 1,
}
},
[AB8540_LDO_AUX4] = {
.desc = {