regulator: Rework s5m8767_set_voltage to support both LDOs and BUCKs
s5m8767_set_voltage not only implement set_voltage callbacks for LDOs, but also for BUCKs when s5m8767->buck_gpioindex is not set. s5m8767_set_voltage_buck actually only for buck[2|3|4] when s5m8767->buck_gpioindex is set. Conditionally calling s5m8767_set_voltage in s5m8767_set_voltage_buck makes the code hard to read. I think merging s5m8767_set_voltage_buck and s5m8767_set_voltage actually simplifies things. It's easy to use buck234_vol pointer to differentiate if we need to control voltage for buck[2|3|4] by DVS GPIOs. This patch reworks s5m8767_set_voltage to support both LDOx and BUCKx in all cases. Signed-off-by: Axel Lin <axel.lin@gmail.com> Acked-by: Sangbeom Kim <sbkim73@samsung.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
Родитель
b920eb41a8
Коммит
321d2abaca
|
@ -355,51 +355,6 @@ static int s5m8767_convert_voltage_to_sel(
|
||||||
return selector;
|
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)
|
static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
|
||||||
{
|
{
|
||||||
int temp_index = s5m8767->buck_gpioindex;
|
int temp_index = s5m8767->buck_gpioindex;
|
||||||
|
@ -418,70 +373,70 @@ static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
|
||||||
gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
|
gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s5m8767_set_voltage_buck(struct regulator_dev *rdev,
|
static int s5m8767_set_voltage(struct regulator_dev *rdev,
|
||||||
int min_uV, int max_uV, unsigned *selector)
|
int min_uV, int max_uV, unsigned *selector)
|
||||||
{
|
{
|
||||||
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
||||||
int reg_id = rdev_get_id(rdev);
|
|
||||||
const struct s5m_voltage_desc *desc;
|
const struct s5m_voltage_desc *desc;
|
||||||
int new_val, old_val, i = 0;
|
int reg_id = rdev_get_id(rdev);
|
||||||
|
int sel, reg, mask, ret = 0, old_index, index = 0;
|
||||||
if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6)
|
u8 val;
|
||||||
return -EINVAL;
|
u8 *buck234_vol = NULL;
|
||||||
|
|
||||||
switch (reg_id) {
|
switch (reg_id) {
|
||||||
case S5M8767_BUCK1:
|
case S5M8767_LDO1 ... S5M8767_LDO28:
|
||||||
return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
|
mask = 0x3f;
|
||||||
case S5M8767_BUCK2 ... S5M8767_BUCK4:
|
|
||||||
break;
|
break;
|
||||||
case S5M8767_BUCK5 ... S5M8767_BUCK6:
|
case S5M8767_BUCK1 ... S5M8767_BUCK6:
|
||||||
return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
|
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:
|
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];
|
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) {
|
sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
|
||||||
case S5M8767_BUCK2:
|
if (sel < 0)
|
||||||
if (s5m8767->buck2_gpiodvs) {
|
return sel;
|
||||||
while (s5m8767->buck2_vol[i] != new_val)
|
|
||||||
i++;
|
/* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */
|
||||||
} else
|
if (buck234_vol) {
|
||||||
return s5m8767_set_voltage(rdev, min_uV,
|
while (*buck234_vol != sel) {
|
||||||
max_uV, selector);
|
buck234_vol++;
|
||||||
break;
|
index++;
|
||||||
case S5M8767_BUCK3:
|
}
|
||||||
if (s5m8767->buck3_gpiodvs) {
|
old_index = s5m8767->buck_gpioindex;
|
||||||
while (s5m8767->buck3_vol[i] != new_val)
|
s5m8767->buck_gpioindex = index;
|
||||||
i++;
|
|
||||||
} else
|
if (index > old_index)
|
||||||
return s5m8767_set_voltage(rdev, min_uV,
|
s5m8767_set_high(s5m8767);
|
||||||
max_uV, selector);
|
else
|
||||||
break;
|
s5m8767_set_low(s5m8767);
|
||||||
case S5M8767_BUCK4:
|
} else {
|
||||||
if (s5m8767->buck3_gpiodvs) {
|
ret = s5m8767_get_voltage_register(rdev, ®);
|
||||||
while (s5m8767->buck4_vol[i] != new_val)
|
if (ret)
|
||||||
i++;
|
return ret;
|
||||||
} else
|
|
||||||
return s5m8767_set_voltage(rdev, min_uV,
|
s5m_reg_read(s5m8767->iodev, reg, &val);
|
||||||
max_uV, selector);
|
val = (val & ~mask) | sel;
|
||||||
break;
|
|
||||||
|
ret = s5m_reg_write(s5m8767->iodev, reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
old_val = s5m8767->buck_gpioindex;
|
*selector = sel;
|
||||||
s5m8767->buck_gpioindex = i;
|
return ret;
|
||||||
|
|
||||||
if (i > old_val)
|
|
||||||
s5m8767_set_high(s5m8767);
|
|
||||||
else
|
|
||||||
s5m8767_set_low(s5m8767);
|
|
||||||
|
|
||||||
*selector = new_val;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
|
static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||||
|
@ -516,7 +471,7 @@ static struct regulator_ops s5m8767_buck_ops = {
|
||||||
.enable = s5m8767_reg_enable,
|
.enable = s5m8767_reg_enable,
|
||||||
.disable = s5m8767_reg_disable,
|
.disable = s5m8767_reg_disable,
|
||||||
.get_voltage_sel = s5m8767_get_voltage_sel,
|
.get_voltage_sel = s5m8767_get_voltage_sel,
|
||||||
.set_voltage = s5m8767_set_voltage_buck,
|
.set_voltage = s5m8767_set_voltage,
|
||||||
.set_voltage_time_sel = s5m8767_set_voltage_time_sel,
|
.set_voltage_time_sel = s5m8767_set_voltage_time_sel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче