From c2f8efd7641b1b10b73ffa6f216a45209a5705dd Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 18 Jan 2012 20:46:56 +0530 Subject: regulator: tps65910: Add regulator info for RTC rail Adding missing regulator info for VRTC rail for device tps65911. The regulator voltage rail index start from VRTC which is defined as 0. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 5c15ba01e9c7..67424185b365 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -174,6 +174,9 @@ static struct tps_info tps65910_regs[] = { }; static struct tps_info tps65911_regs[] = { + { + .name = "VRTC", + }, { .name = "VIO", .min_uV = 1500000, -- cgit v1.2.3 From 51ced5e288b4381705df173fb05f561dea35bfac Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 18 Jan 2012 20:47:16 +0530 Subject: regulator: tps65910: Initialize n_voltages for rails. Initializing the number of voltages supported by different rails of pmic device tps65911. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 67424185b365..3ac5f91a4f7d 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -188,56 +188,67 @@ static struct tps_info tps65911_regs[] = { .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, + .table_len = 73, }, { .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, + .table_len = 73, }, { .name = "VDDCTRL", .min_uV = 600000, .max_uV = 1400000, + .table_len = 65, }, { .name = "LDO1", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 47, }, { .name = "LDO2", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 47, }, { .name = "LDO3", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO4", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 47, }, { .name = "LDO5", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO6", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO7", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO8", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, }; -- cgit v1.2.3 From 7d38a3cb9b9f6a6d31b1d19e4f07a7c0b71407d5 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 20 Jan 2012 16:36:22 +0530 Subject: regulator: tps65910: use appropriate variable names. Renaming the variables "table" to "voltage_table" and "table_len" to "n_voltages" of regulator information to have more meaningful. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 82 +++++++++++++++++----------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 3ac5f91a4f7d..1d13cf997afb 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -83,8 +83,8 @@ struct tps_info { const char *name; unsigned min_uV; unsigned max_uV; - u8 table_len; - const u16 *table; + u8 n_voltages; + const u16 *voltage_table; }; static struct tps_info tps65910_regs[] = { @@ -95,8 +95,8 @@ static struct tps_info tps65910_regs[] = { .name = "VIO", .min_uV = 1500000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VIO_VSEL_table), - .table = VIO_VSEL_table, + .n_voltages = ARRAY_SIZE(VIO_VSEL_table), + .voltage_table = VIO_VSEL_table, }, { .name = "VDD1", @@ -112,64 +112,64 @@ static struct tps_info tps65910_regs[] = { .name = "VDD3", .min_uV = 5000000, .max_uV = 5000000, - .table_len = ARRAY_SIZE(VDD3_VSEL_table), - .table = VDD3_VSEL_table, + .n_voltages = ARRAY_SIZE(VDD3_VSEL_table), + .voltage_table = VDD3_VSEL_table, }, { .name = "VDIG1", .min_uV = 1200000, .max_uV = 2700000, - .table_len = ARRAY_SIZE(VDIG1_VSEL_table), - .table = VDIG1_VSEL_table, + .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), + .voltage_table = VDIG1_VSEL_table, }, { .name = "VDIG2", .min_uV = 1000000, .max_uV = 1800000, - .table_len = ARRAY_SIZE(VDIG2_VSEL_table), - .table = VDIG2_VSEL_table, + .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), + .voltage_table = VDIG2_VSEL_table, }, { .name = "VPLL", .min_uV = 1000000, .max_uV = 2500000, - .table_len = ARRAY_SIZE(VPLL_VSEL_table), - .table = VPLL_VSEL_table, + .n_voltages = ARRAY_SIZE(VPLL_VSEL_table), + .voltage_table = VPLL_VSEL_table, }, { .name = "VDAC", .min_uV = 1800000, .max_uV = 2850000, - .table_len = ARRAY_SIZE(VDAC_VSEL_table), - .table = VDAC_VSEL_table, + .n_voltages = ARRAY_SIZE(VDAC_VSEL_table), + .voltage_table = VDAC_VSEL_table, }, { .name = "VAUX1", .min_uV = 1800000, .max_uV = 2850000, - .table_len = ARRAY_SIZE(VAUX1_VSEL_table), - .table = VAUX1_VSEL_table, + .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), + .voltage_table = VAUX1_VSEL_table, }, { .name = "VAUX2", .min_uV = 1800000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VAUX2_VSEL_table), - .table = VAUX2_VSEL_table, + .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), + .voltage_table = VAUX2_VSEL_table, }, { .name = "VAUX33", .min_uV = 1800000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VAUX33_VSEL_table), - .table = VAUX33_VSEL_table, + .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), + .voltage_table = VAUX33_VSEL_table, }, { .name = "VMMC", .min_uV = 1800000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VMMC_VSEL_table), - .table = VMMC_VSEL_table, + .n_voltages = ARRAY_SIZE(VMMC_VSEL_table), + .voltage_table = VMMC_VSEL_table, }, }; @@ -181,74 +181,74 @@ static struct tps_info tps65911_regs[] = { .name = "VIO", .min_uV = 1500000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VIO_VSEL_table), - .table = VIO_VSEL_table, + .n_voltages = ARRAY_SIZE(VIO_VSEL_table), + .voltage_table = VIO_VSEL_table, }, { .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, - .table_len = 73, + .n_voltages = 73, }, { .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, - .table_len = 73, + .n_voltages = 73, }, { .name = "VDDCTRL", .min_uV = 600000, .max_uV = 1400000, - .table_len = 65, + .n_voltages = 65, }, { .name = "LDO1", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 47, + .n_voltages = 47, }, { .name = "LDO2", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 47, + .n_voltages = 47, }, { .name = "LDO3", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO4", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 47, + .n_voltages = 47, }, { .name = "LDO5", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO6", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO7", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO8", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, }; @@ -586,7 +586,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev) return -EINVAL; } - voltage = pmic->info[id]->table[value] * 1000; + voltage = pmic->info[id]->voltage_table[value] * 1000; return voltage; } @@ -636,7 +636,7 @@ static int tps65911_get_voltage(struct regulator_dev *dev) step_mv = 100; break; case TPS65910_REG_VIO: - return pmic->info[id]->table[value] * 1000; + return pmic->info[id]->voltage_table[value] * 1000; break; default: return -EINVAL; @@ -770,10 +770,10 @@ static int tps65910_list_voltage(struct regulator_dev *dev, if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) return -EINVAL; - if (selector >= pmic->info[id]->table_len) + if (selector >= pmic->info[id]->n_voltages) return -EINVAL; else - voltage = pmic->info[id]->table[selector] * 1000; + voltage = pmic->info[id]->voltage_table[selector] * 1000; return voltage; } @@ -809,7 +809,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) step_mv = 100; break; case TPS65910_REG_VIO: - return pmic->info[id]->table[selector] * 1000; + return pmic->info[id]->voltage_table[selector] * 1000; default: return -EINVAL; } @@ -940,7 +940,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].name = info->name; pmic->desc[i].id = i; - pmic->desc[i].n_voltages = info->table_len; + pmic->desc[i].n_voltages = info->n_voltages; if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { pmic->desc[i].ops = &tps65910_ops_dcdc; -- cgit v1.2.3 From 1e0c66f49762fa1866ab20b1feb6e86a9aa4838f Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Sat, 28 Jan 2012 15:07:57 +0530 Subject: regulator: tps65910: Sleep control through external inputs Add support for sleep controls of different regulator through external inputs EN1, EN2 or EN3. Each regulator's output will be active when its external input is high and turns to OFF/Low power mode when its external input is low. The configuration parameters for sleep control is provided through board specific platform data. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 206 +++++++++++++++++++++++++++++++++ include/linux/mfd/tps65910.h | 8 ++ 2 files changed, 214 insertions(+) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 1d13cf997afb..9092b7f998c1 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -26,6 +26,9 @@ #include #define TPS65910_SUPPLY_STATE_ENABLED 0x1 +#define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \ + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \ + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) /* supported VIO voltages in milivolts */ static const u16 VIO_VSEL_table[] = { @@ -252,6 +255,39 @@ static struct tps_info tps65911_regs[] = { }, }; +#define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits)) +static unsigned int tps65910_ext_sleep_control[] = { + 0, + EXT_CONTROL_REG_BITS(VIO, 1, 0), + EXT_CONTROL_REG_BITS(VDD1, 1, 1), + EXT_CONTROL_REG_BITS(VDD2, 1, 2), + EXT_CONTROL_REG_BITS(VDD3, 1, 3), + EXT_CONTROL_REG_BITS(VDIG1, 0, 1), + EXT_CONTROL_REG_BITS(VDIG2, 0, 2), + EXT_CONTROL_REG_BITS(VPLL, 0, 6), + EXT_CONTROL_REG_BITS(VDAC, 0, 7), + EXT_CONTROL_REG_BITS(VAUX1, 0, 3), + EXT_CONTROL_REG_BITS(VAUX2, 0, 4), + EXT_CONTROL_REG_BITS(VAUX33, 0, 5), + EXT_CONTROL_REG_BITS(VMMC, 0, 0), +}; + +static unsigned int tps65911_ext_sleep_control[] = { + 0, + EXT_CONTROL_REG_BITS(VIO, 1, 0), + EXT_CONTROL_REG_BITS(VDD1, 1, 1), + EXT_CONTROL_REG_BITS(VDD2, 1, 2), + EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3), + EXT_CONTROL_REG_BITS(LDO1, 0, 1), + EXT_CONTROL_REG_BITS(LDO2, 0, 2), + EXT_CONTROL_REG_BITS(LDO3, 0, 7), + EXT_CONTROL_REG_BITS(LDO4, 0, 6), + EXT_CONTROL_REG_BITS(LDO5, 0, 3), + EXT_CONTROL_REG_BITS(LDO6, 0, 0), + EXT_CONTROL_REG_BITS(LDO7, 0, 5), + EXT_CONTROL_REG_BITS(LDO8, 0, 4), +}; + struct tps65910_reg { struct regulator_desc *desc; struct tps65910 *mfd; @@ -261,6 +297,8 @@ struct tps65910_reg { int num_regulators; int mode; int (*get_ctrl_reg)(int); + unsigned int *ext_sleep_control; + unsigned int board_ext_control[TPS65910_NUM_REGS]; }; static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) @@ -861,6 +899,131 @@ static struct regulator_ops tps65911_ops = { .list_voltage = tps65911_list_voltage, }; +static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, + int id, int ext_sleep_config) +{ + struct tps65910 *mfd = pmic->mfd; + u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF; + u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF); + int ret; + + /* + * Regulator can not be control from multiple external input EN1, EN2 + * and EN3 together. + */ + if (ext_sleep_config & EXT_SLEEP_CONTROL) { + int en_count; + en_count = ((ext_sleep_config & + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0); + en_count += ((ext_sleep_config & + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0); + en_count += ((ext_sleep_config & + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0); + if (en_count > 1) { + dev_err(mfd->dev, + "External sleep control flag is not proper\n"); + return -EINVAL; + } + } + + pmic->board_ext_control[id] = ext_sleep_config; + + /* External EN1 control */ + if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) + ret = tps65910_set_bits(mfd, + TPS65910_EN1_LDO_ASS + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_EN1_LDO_ASS + regoffs, bit_pos); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring external control EN1\n"); + return ret; + } + + /* External EN2 control */ + if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) + ret = tps65910_set_bits(mfd, + TPS65910_EN2_LDO_ASS + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_EN2_LDO_ASS + regoffs, bit_pos); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring external control EN2\n"); + return ret; + } + + /* External EN3 control for TPS65910 LDO only */ + if ((tps65910_chip_id(mfd) == TPS65910) && + (id >= TPS65910_REG_VDIG1)) { + if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) + ret = tps65910_set_bits(mfd, + TPS65910_EN3_LDO_ASS + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_EN3_LDO_ASS + regoffs, bit_pos); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring external control EN3\n"); + return ret; + } + } + + /* Return if no external control is selected */ + if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) { + /* Clear all sleep controls */ + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); + if (!ret) + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); + if (ret < 0) + dev_err(mfd->dev, + "Error in configuring SLEEP register\n"); + return ret; + } + + /* + * For regulator that has separate operational and sleep register make + * sure that operational is used and clear sleep register to turn + * regulator off when external control is inactive + */ + if ((id == TPS65910_REG_VDD1) || + (id == TPS65910_REG_VDD2) || + ((id == TPS65911_REG_VDDCTRL) && + (tps65910_chip_id(mfd) == TPS65911))) { + int op_reg_add = pmic->get_ctrl_reg(id) + 1; + int sr_reg_add = pmic->get_ctrl_reg(id) + 2; + int opvsel = tps65910_reg_read(pmic, op_reg_add); + int srvsel = tps65910_reg_read(pmic, sr_reg_add); + if (opvsel & VDD1_OP_CMD_MASK) { + u8 reg_val = srvsel & VDD1_OP_SEL_MASK; + ret = tps65910_reg_write(pmic, op_reg_add, reg_val); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring op register\n"); + return ret; + } + } + ret = tps65910_reg_write(pmic, sr_reg_add, 0); + if (ret < 0) { + dev_err(mfd->dev, "Error in settting sr register\n"); + return ret; + } + } + + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); + if (!ret) + ret = tps65910_set_bits(mfd, + TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); + if (ret < 0) + dev_err(mfd->dev, + "Error in configuring SLEEP register\n"); + return ret; +} + static __devinit int tps65910_probe(struct platform_device *pdev) { struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); @@ -891,11 +1054,13 @@ static __devinit int tps65910_probe(struct platform_device *pdev) case TPS65910: pmic->get_ctrl_reg = &tps65910_get_ctrl_register; pmic->num_regulators = ARRAY_SIZE(tps65910_regs); + pmic->ext_sleep_control = tps65910_ext_sleep_control; info = tps65910_regs; break; case TPS65911: pmic->get_ctrl_reg = &tps65911_get_ctrl_register; pmic->num_regulators = ARRAY_SIZE(tps65911_regs); + pmic->ext_sleep_control = tps65911_ext_sleep_control; info = tps65911_regs; break; default: @@ -958,6 +1123,16 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].ops = &tps65911_ops; } + err = tps65910_set_ext_sleep_config(pmic, i, + pmic_plat_data->regulator_ext_sleep_control[i]); + /* + * Failing on regulator for configuring externally control + * is not a serious issue, just throw warning. + */ + if (err < 0) + dev_warn(tps65910->dev, + "Failed to initialise ext control config\n"); + pmic->desc[i].type = REGULATOR_VOLTAGE; pmic->desc[i].owner = THIS_MODULE; @@ -1004,6 +1179,36 @@ static int __devexit tps65910_remove(struct platform_device *pdev) return 0; } +static void tps65910_shutdown(struct platform_device *pdev) +{ + struct tps65910_reg *pmic = platform_get_drvdata(pdev); + int i; + + /* + * Before bootloader jumps to kernel, it makes sure that required + * external control signals are in desired state so that given rails + * can be configure accordingly. + * If rails are configured to be controlled from external control + * then before shutting down/rebooting the system, the external + * control configuration need to be remove from the rails so that + * its output will be available as per register programming even + * if external controls are removed. This is require when the POR + * value of the control signals are not in active state and before + * bootloader initializes it, the system requires the rail output + * to be active for booting. + */ + for (i = 0; i < pmic->num_regulators; i++) { + int err; + if (!pmic->rdev[i]) + continue; + + err = tps65910_set_ext_sleep_config(pmic, i, 0); + if (err < 0) + dev_err(&pdev->dev, + "Error in clearing external control\n"); + } +} + static struct platform_driver tps65910_driver = { .driver = { .name = "tps65910-pmic", @@ -1011,6 +1216,7 @@ static struct platform_driver tps65910_driver = { }, .probe = tps65910_probe, .remove = __devexit_p(tps65910_remove), + .shutdown = tps65910_shutdown, }; static int __init tps65910_init(void) diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index d0cb12eba402..fa6c6bf7a54d 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -768,6 +768,13 @@ /* Max number of TPS65910/11 regulators */ #define TPS65910_NUM_REGS 13 +/* External sleep controls through EN1/EN2/EN3 inputs*/ +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 0x1 +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 0x2 +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 0x4 +/* TPS65911 names the EN3 signal as SLEEP */ +#define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP 0x4 + /** * struct tps65910_board * Board platform data may be used to initialize regulators. @@ -779,6 +786,7 @@ struct tps65910_board { int irq_base; int vmbch_threshold; int vmbch2_threshold; + unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS]; struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS]; }; -- cgit v1.2.3 From e882eae80f37fac922c6faa25e5ba535f29f2d38 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 17 Feb 2012 18:56:11 +0530 Subject: regulator: tps65910: Correct VIO voltage configuration The VIO regulator register specify the voltage configuration on bit3:2 of its register. And hence only these bits should be modified when setting voltage and used when reading voltage from register setting. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 9092b7f998c1..a9bb6d45ceff 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -674,8 +674,9 @@ static int tps65911_get_voltage(struct regulator_dev *dev) step_mv = 100; break; case TPS65910_REG_VIO: + value &= LDO_SEL_MASK; + value >>= LDO_SEL_SHIFT; return pmic->info[id]->voltage_table[value] * 1000; - break; default: return -EINVAL; } @@ -767,9 +768,11 @@ static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector) case TPS65911_REG_LDO6: case TPS65911_REG_LDO7: case TPS65911_REG_LDO8: - case TPS65910_REG_VIO: return tps65910_modify_bits(pmic, reg, (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK); + case TPS65910_REG_VIO: + return tps65910_modify_bits(pmic, reg, + (selector << LDO_SEL_SHIFT), LDO_SEL_MASK); } return -EINVAL; -- cgit v1.2.3 From ae0e6544347d6e114b6fa7eea66ebd062e4d8858 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 21 Feb 2012 10:14:55 +0800 Subject: regulator: Fix module desciption for tps65910 regulator Fix the module desciption and also update Kconfig to include supporting tps65911 chip. Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 4 ++-- drivers/regulator/tps65910-regulator.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 376824b865a4..edcd9e259368 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -344,10 +344,10 @@ config REGULATOR_TPS6524X port controller. config REGULATOR_TPS65910 - tristate "TI TPS65910 Power Regulator" + tristate "TI TPS65910/TPS65911 Power Regulators" depends on MFD_TPS65910 help - This driver supports TPS65910 voltage regulator chips. + This driver supports TPS65910/TPS65911 voltage regulator chips. config REGULATOR_TPS62360 tristate "TI TPS62360 Power Regulator" diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index a9bb6d45ceff..15b5f1ec17b7 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1235,6 +1235,6 @@ static void __exit tps65910_cleanup(void) module_exit(tps65910_cleanup); MODULE_AUTHOR("Graeme Gregory "); -MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); +MODULE_DESCRIPTION("TPS65910/TPS65911 voltage regulator driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:tps65910-pmic"); -- cgit v1.2.3 From f30b0716feaedc0cf432ed8eca82c46104d64c0d Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 7 Mar 2012 18:21:49 +0530 Subject: regulator: tps65910: Sleep off rails when ext sleep configured Keep the rails OFF in sleep mode only when the rails are controlled by external sleep control. The devices tps65910 and tps65911, both has the sleep input. The tps65911's sleep input is not same as tps65910's EN3 and hence taking care of SLEEP input as separate external sleep control input. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 17 +++++++++++++---- include/linux/mfd/tps65910.h | 5 ++--- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 15b5f1ec17b7..b0533c111571 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -28,7 +28,8 @@ #define TPS65910_SUPPLY_STATE_ENABLED 0x1 #define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \ TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \ - TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 | \ + TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) /* supported VIO voltages in milivolts */ static const u16 VIO_VSEL_table[] = { @@ -922,6 +923,8 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0); en_count += ((ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0); + en_count += ((ext_sleep_config & + TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) != 0); if (en_count > 1) { dev_err(mfd->dev, "External sleep control flag is not proper\n"); @@ -1018,12 +1021,18 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, ret = tps65910_clear_bits(mfd, TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); - if (!ret) - ret = tps65910_set_bits(mfd, - TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); + if (!ret) { + if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) + ret = tps65910_set_bits(mfd, + TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); + } if (ret < 0) dev_err(mfd->dev, "Error in configuring SLEEP register\n"); + return ret; } diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index fa6c6bf7a54d..76700b5eee92 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -768,12 +768,11 @@ /* Max number of TPS65910/11 regulators */ #define TPS65910_NUM_REGS 13 -/* External sleep controls through EN1/EN2/EN3 inputs*/ +/* External sleep controls through EN1/EN2/EN3/SLEEP inputs */ #define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 0x1 #define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 0x2 #define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 0x4 -/* TPS65911 names the EN3 signal as SLEEP */ -#define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP 0x4 +#define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP 0x8 /** * struct tps65910_board -- cgit v1.2.3 From 94732b97c39859427cf99c34fc9de9750be7e5a5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 9 Mar 2012 10:22:20 +0800 Subject: regulator: Rename set_voltage_sel callback function name to *_sel This change improves readability. Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 16 +++++++++------- drivers/regulator/tps65912-regulator.c | 12 ++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index b0533c111571..4ac0058dbf82 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -685,8 +685,8 @@ static int tps65911_get_voltage(struct regulator_dev *dev) return (LDO_MIN_VOLT + value * step_mv) * 1000; } -static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, - unsigned selector) +static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, + unsigned selector) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); int id = rdev_get_id(dev), vsel; @@ -723,7 +723,8 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, return 0; } -static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) +static int tps65910_set_voltage_sel(struct regulator_dev *dev, + unsigned selector) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); int reg, id = rdev_get_id(dev); @@ -749,7 +750,8 @@ static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) return -EINVAL; } -static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector) +static int tps65911_set_voltage_sel(struct regulator_dev *dev, + unsigned selector) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); int reg, id = rdev_get_id(dev); @@ -867,7 +869,7 @@ static struct regulator_ops tps65910_ops_dcdc = { .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65910_get_voltage_dcdc, - .set_voltage_sel = tps65910_set_voltage_dcdc, + .set_voltage_sel = tps65910_set_voltage_dcdc_sel, .list_voltage = tps65910_list_voltage_dcdc, }; @@ -888,7 +890,7 @@ static struct regulator_ops tps65910_ops = { .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65910_get_voltage, - .set_voltage_sel = tps65910_set_voltage, + .set_voltage_sel = tps65910_set_voltage_sel, .list_voltage = tps65910_list_voltage, }; @@ -899,7 +901,7 @@ static struct regulator_ops tps65911_ops = { .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65911_get_voltage, - .set_voltage_sel = tps65911_set_voltage, + .set_voltage_sel = tps65911_set_voltage_sel, .list_voltage = tps65911_list_voltage, }; diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index b685757a2b8e..679709536408 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -588,8 +588,8 @@ static int tps65912_get_voltage_dcdc(struct regulator_dev *dev) return tps65912_list_voltage_dcdc(dev, vsel); } -static int tps65912_set_voltage_dcdc(struct regulator_dev *dev, - unsigned selector) +static int tps65912_set_voltage_dcdc_sel(struct regulator_dev *dev, + unsigned selector) { struct tps65912_reg *pmic = rdev_get_drvdata(dev); struct tps65912 *mfd = pmic->mfd; @@ -618,8 +618,8 @@ static int tps65912_get_voltage_ldo(struct regulator_dev *dev) return tps65912_vsel_to_uv_ldo(vsel); } -static int tps65912_set_voltage_ldo(struct regulator_dev *dev, - unsigned selector) +static int tps65912_set_voltage_ldo_sel(struct regulator_dev *dev, + unsigned selector) { struct tps65912_reg *pmic = rdev_get_drvdata(dev); struct tps65912 *mfd = pmic->mfd; @@ -650,7 +650,7 @@ static struct regulator_ops tps65912_ops_dcdc = { .set_mode = tps65912_set_mode, .get_mode = tps65912_get_mode, .get_voltage = tps65912_get_voltage_dcdc, - .set_voltage_sel = tps65912_set_voltage_dcdc, + .set_voltage_sel = tps65912_set_voltage_dcdc_sel, .list_voltage = tps65912_list_voltage_dcdc, }; @@ -660,7 +660,7 @@ static struct regulator_ops tps65912_ops_ldo = { .enable = tps65912_reg_enable, .disable = tps65912_reg_disable, .get_voltage = tps65912_get_voltage_ldo, - .set_voltage_sel = tps65912_set_voltage_ldo, + .set_voltage_sel = tps65912_set_voltage_ldo_sel, .list_voltage = tps65912_list_voltage_ldo, }; -- cgit v1.2.3 From 585993932ccc44ab6a8c6dc590a2f3d6b2facb41 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 13 Mar 2012 07:15:27 +0800 Subject: regulator: Fix the logic of tps65910_get_mode We actually clear LDO_ST_ON_BIT for standby mode in tps65910_set_mode. Fix the logic in tps65910_get_mode. Supply state (EEPROM bits): ST[1:0] = 00 : Off ST[1:0] = 01 : On high power (ACTIVE) ST[1:0] = 10 : Off ST[1:0] = 11 : On low power (SLEEP) Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 4ac0058dbf82..aa11ce86ec64 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -520,7 +520,7 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) if (value < 0) return value; - if (value & LDO_ST_ON_BIT) + if (!(value & LDO_ST_ON_BIT)) return REGULATOR_MODE_STANDBY; else if (value & LDO_ST_MODE_BIT) return REGULATOR_MODE_IDLE; -- cgit v1.2.3 From 0651eed5e094a079a0a9fccd80a41cb3e7f2aa99 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 13 Mar 2012 11:35:20 +0530 Subject: regulator: tps65910: Provide settling time for enabling rails There is settling time for each rails when it is switched to ON. Implementing enable time for returning proper settling time of regulator rails when it is enabled. Filling the on-time for each rail as per tps65910/tps65911 datasheets. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index aa11ce86ec64..f28f41aec284 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -89,11 +89,13 @@ struct tps_info { unsigned max_uV; u8 n_voltages; const u16 *voltage_table; + int enable_time_us; }; static struct tps_info tps65910_regs[] = { { .name = "VRTC", + .enable_time_us = 2200, }, { .name = "VIO", @@ -101,16 +103,19 @@ static struct tps_info tps65910_regs[] = { .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VIO_VSEL_table), .voltage_table = VIO_VSEL_table, + .enable_time_us = 350, }, { .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, + .enable_time_us = 350, }, { .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, + .enable_time_us = 350, }, { .name = "VDD3", @@ -118,6 +123,7 @@ static struct tps_info tps65910_regs[] = { .max_uV = 5000000, .n_voltages = ARRAY_SIZE(VDD3_VSEL_table), .voltage_table = VDD3_VSEL_table, + .enable_time_us = 200, }, { .name = "VDIG1", @@ -125,6 +131,7 @@ static struct tps_info tps65910_regs[] = { .max_uV = 2700000, .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), .voltage_table = VDIG1_VSEL_table, + .enable_time_us = 100, }, { .name = "VDIG2", @@ -132,6 +139,7 @@ static struct tps_info tps65910_regs[] = { .max_uV = 1800000, .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), .voltage_table = VDIG2_VSEL_table, + .enable_time_us = 100, }, { .name = "VPLL", @@ -139,6 +147,7 @@ static struct tps_info tps65910_regs[] = { .max_uV = 2500000, .n_voltages = ARRAY_SIZE(VPLL_VSEL_table), .voltage_table = VPLL_VSEL_table, + .enable_time_us = 100, }, { .name = "VDAC", @@ -146,6 +155,7 @@ static struct tps_info tps65910_regs[] = { .max_uV = 2850000, .n_voltages = ARRAY_SIZE(VDAC_VSEL_table), .voltage_table = VDAC_VSEL_table, + .enable_time_us = 100, }, { .name = "VAUX1", @@ -153,6 +163,7 @@ static struct tps_info tps65910_regs[] = { .max_uV = 2850000, .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), .voltage_table = VAUX1_VSEL_table, + .enable_time_us = 100, }, { .name = "VAUX2", @@ -160,6 +171,7 @@ static struct tps_info tps65910_regs[] = { .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), .voltage_table = VAUX2_VSEL_table, + .enable_time_us = 100, }, { .name = "VAUX33", @@ -167,6 +179,7 @@ static struct tps_info tps65910_regs[] = { .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), .voltage_table = VAUX33_VSEL_table, + .enable_time_us = 100, }, { .name = "VMMC", @@ -174,12 +187,14 @@ static struct tps_info tps65910_regs[] = { .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VMMC_VSEL_table), .voltage_table = VMMC_VSEL_table, + .enable_time_us = 100, }, }; static struct tps_info tps65911_regs[] = { { .name = "VRTC", + .enable_time_us = 2200, }, { .name = "VIO", @@ -187,72 +202,84 @@ static struct tps_info tps65911_regs[] = { .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VIO_VSEL_table), .voltage_table = VIO_VSEL_table, + .enable_time_us = 350, }, { .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, .n_voltages = 73, + .enable_time_us = 350, }, { .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, .n_voltages = 73, + .enable_time_us = 350, }, { .name = "VDDCTRL", .min_uV = 600000, .max_uV = 1400000, .n_voltages = 65, + .enable_time_us = 900, }, { .name = "LDO1", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 47, + .enable_time_us = 420, }, { .name = "LDO2", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 47, + .enable_time_us = 420, }, { .name = "LDO3", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, + .enable_time_us = 230, }, { .name = "LDO4", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 47, + .enable_time_us = 230, }, { .name = "LDO5", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, + .enable_time_us = 230, }, { .name = "LDO6", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, + .enable_time_us = 230, }, { .name = "LDO7", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, + .enable_time_us = 230, }, { .name = "LDO8", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, + .enable_time_us = 230, }, }; @@ -482,6 +509,12 @@ static int tps65910_disable(struct regulator_dev *dev) 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); + int id = rdev_get_id(dev); + return pmic->info[id]->enable_time_us; +} static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) { @@ -866,6 +899,7 @@ static struct regulator_ops tps65910_ops_dcdc = { .is_enabled = tps65910_is_enabled, .enable = tps65910_enable, .disable = tps65910_disable, + .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65910_get_voltage_dcdc, @@ -877,6 +911,7 @@ static struct regulator_ops tps65910_ops_vdd3 = { .is_enabled = tps65910_is_enabled, .enable = tps65910_enable, .disable = tps65910_disable, + .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65910_get_voltage_vdd3, @@ -887,6 +922,7 @@ static struct regulator_ops tps65910_ops = { .is_enabled = tps65910_is_enabled, .enable = tps65910_enable, .disable = tps65910_disable, + .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65910_get_voltage, @@ -898,6 +934,7 @@ static struct regulator_ops tps65911_ops = { .is_enabled = tps65910_is_enabled, .enable = tps65910_enable, .disable = tps65910_disable, + .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65911_get_voltage, -- cgit v1.2.3 From 18039e0f16d50c8243fe0388a587c25a3b155ece Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 14 Mar 2012 13:00:58 +0530 Subject: regulator: tps65910: Provide settling time for DCDC voltage change Settling time is require when there is dcdc rail's voltage change. Returning proper delay time for dcdc voltage change to settle down the output voltage to new value. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 45 ++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 13 deletions(-) (limited to 'drivers/regulator/tps65910-regulator.c') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index f28f41aec284..3d1370f9bc7f 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -561,10 +561,10 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) return REGULATOR_MODE_NORMAL; } -static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) +static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev), voltage = 0; + int id = rdev_get_id(dev); int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; switch (id) { @@ -608,9 +608,7 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) srvsel = 3; if (srvsel > vselmax) srvsel = vselmax; - srvsel -= 3; - - voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; + return srvsel - 3; } else { /* normalise to valid range*/ @@ -618,14 +616,9 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) opvsel = 3; if (opvsel > vselmax) opvsel = vselmax; - opvsel -= 3; - - voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; + return opvsel - 3; } - - voltage *= mult; - - return voltage; + return -EINVAL; } static int tps65910_get_voltage(struct regulator_dev *dev) @@ -894,6 +887,31 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) return (LDO_MIN_VOLT + selector * step_mv) * 1000; } +static int tps65910_set_voltage_dcdc_time_sel(struct regulator_dev *dev, + unsigned int old_selector, unsigned int new_selector) +{ + int id = rdev_get_id(dev); + int old_volt, new_volt; + + old_volt = tps65910_list_voltage_dcdc(dev, old_selector); + if (old_volt < 0) + return old_volt; + + new_volt = tps65910_list_voltage_dcdc(dev, new_selector); + if (new_volt < 0) + return new_volt; + + /* VDD1 and VDD2 are 12.5mV/us, VDDCTRL is 100mV/20us */ + switch (id) { + case TPS65910_REG_VDD1: + case TPS65910_REG_VDD2: + return DIV_ROUND_UP(abs(old_volt - new_volt), 12500); + case TPS65911_REG_VDDCTRL: + return DIV_ROUND_UP(abs(old_volt - new_volt), 5000); + } + return -EINVAL; +} + /* Regulator ops (except VRTC) */ static struct regulator_ops tps65910_ops_dcdc = { .is_enabled = tps65910_is_enabled, @@ -902,8 +920,9 @@ static struct regulator_ops tps65910_ops_dcdc = { .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, - .get_voltage = tps65910_get_voltage_dcdc, + .get_voltage_sel = tps65910_get_voltage_dcdc_sel, .set_voltage_sel = tps65910_set_voltage_dcdc_sel, + .set_voltage_time_sel = tps65910_set_voltage_dcdc_time_sel, .list_voltage = tps65910_list_voltage_dcdc, }; -- cgit v1.2.3