From 7a32b589a9c856493bccb02db55047edc04eee7b Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Fri, 11 Mar 2011 10:13:59 +0900 Subject: Regulator: add suspend-finish API for regulator core. The regulator core had suspend-prepare that turns off the regulators when entering a system-wide suspend. However, it did not have suspend-finish that pairs with suspend-prepare and the regulator core has assumed that the regulator devices and their drivers support autonomous recover at resume. This patch adds regulator_suspend_finish that pairs with the previously-existed regulator_suspend_prepare. The function regulator_suspend_finish turns on the regulators that have always_on set or positive use_count so that we can reset the regulator states appropriately at resume. In regulator_suspend_finish, if has_full_constraints, it disables unnecessary regulators. Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park Acked-by: Mark Brown -- Updates v3 comments corrected (Thanks to Igor) v2 disable unnecessary regulators (Thanks to Mark) Signed-off-by: Liam Girdwood --- include/linux/regulator/machine.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 761c745b9c24..c4c4fc45f856 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -186,6 +186,7 @@ struct regulator_init_data { }; int regulator_suspend_prepare(suspend_state_t state); +int regulator_suspend_finish(void); #ifdef CONFIG_REGULATOR void regulator_has_full_constraints(void); -- cgit v1.2.3 From ea05ef31f2aa98b25d14222300dc9c1d1eb59e41 Mon Sep 17 00:00:00 2001 From: Bengt Jonsson Date: Thu, 10 Mar 2011 14:43:31 +0100 Subject: regulator: add support for USB voltage regulator Signed-off-by: Bengt Jonsson Signed-off-by: Linus Walleij Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/ab8500.c | 17 ++++++++++++++++- include/linux/regulator/ab8500.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index d9a052c53aec..5a77630095d9 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -9,7 +9,7 @@ * AB8500 peripheral regulators * * AB8500 supports the following regulators: - * VAUX1/2/3, VINTCORE, VTVOUT, VAUDIO, VAMIC1/2, VDMIC, VANA + * VAUX1/2/3, VINTCORE, VTVOUT, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA */ #include #include @@ -432,6 +432,21 @@ static struct ab8500_regulator_info .update_mask = 0x82, .update_val_enable = 0x02, }, + [AB8500_LDO_USB] = { + .desc = { + .name = "LDO-USB", + .ops = &ab8500_regulator_fixed_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_USB, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 3300000, + .update_bank = 0x03, + .update_reg = 0x82, + .update_mask = 0x03, + .update_val_enable = 0x01, + }, [AB8500_LDO_AUDIO] = { .desc = { .name = "LDO-AUDIO", diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 6a210f1511fc..d4eacdef2017 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -17,6 +17,7 @@ enum ab8500_regulator_id { AB8500_LDO_AUX3, AB8500_LDO_INTCORE, AB8500_LDO_TVOUT, + AB8500_LDO_USB, AB8500_LDO_AUDIO, AB8500_LDO_ANAMIC1, AB8500_LDO_ANAMIC2, -- cgit v1.2.3 From 79568b941277b5986a8a7f0fb8578b2ccfc3e87e Mon Sep 17 00:00:00 2001 From: Bengt Jonsson Date: Fri, 11 Mar 2011 11:54:46 +0100 Subject: regulator: initialization for ab8500 regulators The regulators on the AB8500 have a lot of custom hardware control settings pertaining to 8 external signals, settings which are board-specific and need be provided from the platform at startup. Initialization added for regulators Vana, VextSupply1, VextSupply2, VextSupply3, Vaux1, Vaux2, Vaux3, VTVout, Vintcore12, Vaudio, Vdmic, Vamic1, Vamic2, VrefDDR. Signed-off-by: Bengt Jonsson Reviewed-by: Rickard Andersson Reviewed-by: Jonas Aberg Signed-off-by: Linus Walleij Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- arch/arm/mach-ux500/board-mop500-regulators.h | 2 + arch/arm/mach-ux500/board-mop500.c | 1 + drivers/regulator/ab8500.c | 223 +++++++++++++++++++++++++- include/linux/mfd/ab8500.h | 6 + include/linux/regulator/ab8500.h | 50 +++++- 5 files changed, 279 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h index 2675fae52537..f979b892e4fa 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/arch/arm/mach-ux500/board-mop500-regulators.h @@ -14,6 +14,8 @@ #include #include +extern struct ab8500_regulator_reg_init +ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS]; extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; #endif diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 8790d984cac8..d0076453d7ff 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 5a77630095d9..d157146c8655 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -526,6 +526,186 @@ static struct ab8500_regulator_info }; +struct ab8500_reg_init { + u8 bank; + u8 addr; + u8 mask; +}; + +#define REG_INIT(_id, _bank, _addr, _mask) \ + [_id] = { \ + .bank = _bank, \ + .addr = _addr, \ + .mask = _mask, \ + } + +static struct ab8500_reg_init ab8500_reg_init[] = { + /* + * 0x30, VanaRequestCtrl + * 0x0C, VpllRequestCtrl + * 0xc0, VextSupply1RequestCtrl + */ + REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc), + /* + * 0x03, VextSupply2RequestCtrl + * 0x0c, VextSupply3RequestCtrl + * 0x30, Vaux1RequestCtrl + * 0xc0, Vaux2RequestCtrl + */ + REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff), + /* + * 0x03, Vaux3RequestCtrl + * 0x04, SwHPReq + */ + REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07), + /* + * 0x08, VanaSysClkReq1HPValid + * 0x20, Vaux1SysClkReq1HPValid + * 0x40, Vaux2SysClkReq1HPValid + * 0x80, Vaux3SysClkReq1HPValid + */ + REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8), + /* + * 0x10, VextSupply1SysClkReq1HPValid + * 0x20, VextSupply2SysClkReq1HPValid + * 0x40, VextSupply3SysClkReq1HPValid + */ + REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70), + /* + * 0x08, VanaHwHPReq1Valid + * 0x20, Vaux1HwHPReq1Valid + * 0x40, Vaux2HwHPReq1Valid + * 0x80, Vaux3HwHPReq1Valid + */ + REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8), + /* + * 0x01, VextSupply1HwHPReq1Valid + * 0x02, VextSupply2HwHPReq1Valid + * 0x04, VextSupply3HwHPReq1Valid + */ + REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07), + /* + * 0x08, VanaHwHPReq2Valid + * 0x20, Vaux1HwHPReq2Valid + * 0x40, Vaux2HwHPReq2Valid + * 0x80, Vaux3HwHPReq2Valid + */ + REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8), + /* + * 0x01, VextSupply1HwHPReq2Valid + * 0x02, VextSupply2HwHPReq2Valid + * 0x04, VextSupply3HwHPReq2Valid + */ + REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07), + /* + * 0x20, VanaSwHPReqValid + * 0x80, Vaux1SwHPReqValid + */ + REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0), + /* + * 0x01, Vaux2SwHPReqValid + * 0x02, Vaux3SwHPReqValid + * 0x04, VextSupply1SwHPReqValid + * 0x08, VextSupply2SwHPReqValid + * 0x10, VextSupply3SwHPReqValid + */ + REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f), + /* + * 0x02, SysClkReq2Valid1 + * ... + * 0x80, SysClkReq8Valid1 + */ + REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe), + /* + * 0x02, SysClkReq2Valid2 + * ... + * 0x80, SysClkReq8Valid2 + */ + REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe), + /* + * 0x02, VTVoutEna + * 0x04, Vintcore12Ena + * 0x38, Vintcore12Sel + * 0x40, Vintcore12LP + * 0x80, VTVoutLP + */ + REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe), + /* + * 0x02, VaudioEna + * 0x04, VdmicEna + * 0x08, Vamic1Ena + * 0x10, Vamic2Ena + */ + REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e), + /* + * 0x01, Vamic1_dzout + * 0x02, Vamic2_dzout + */ + REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03), + /* + * 0x0c, VanaRegu + * 0x03, VpllRegu + */ + REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f), + /* + * 0x01, VrefDDREna + * 0x02, VrefDDRSleepMode + */ + REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03), + /* + * 0x03, VextSupply1Regu + * 0x0c, VextSupply2Regu + * 0x30, VextSupply3Regu + * 0x40, ExtSupply2Bypass + * 0x80, ExtSupply3Bypass + */ + REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff), + /* + * 0x03, Vaux1Regu + * 0x0c, Vaux2Regu + */ + REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f), + /* + * 0x03, Vaux3Regu + */ + REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03), + /* + * 0x3f, Vsmps1Sel1 + */ + REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f), + /* + * 0x0f, Vaux1Sel + */ + REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f), + /* + * 0x0f, Vaux2Sel + */ + REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f), + /* + * 0x07, Vaux3Sel + */ + REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07), + /* + * 0x01, VextSupply12LP + */ + REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01), + /* + * 0x04, Vaux1Disch + * 0x08, Vaux2Disch + * 0x10, Vaux3Disch + * 0x20, Vintcore12Disch + * 0x40, VTVoutDisch + * 0x80, VaudioDisch + */ + REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc), + /* + * 0x02, VanaDisch + * 0x04, VdmicPullDownEna + * 0x10, VdmicDisch + */ + REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), +}; + static __devinit int ab8500_regulator_probe(struct platform_device *pdev) { struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); @@ -544,10 +724,51 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) /* make sure the platform data has the correct size */ if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) { - dev_err(&pdev->dev, "platform configuration error\n"); + dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); return -EINVAL; } + /* initialize registers */ + for (i = 0; i < pdata->num_regulator_reg_init; i++) { + int id; + u8 value; + + id = pdata->regulator_reg_init[i].id; + value = pdata->regulator_reg_init[i].value; + + /* check for configuration errors */ + if (id >= AB8500_NUM_REGULATOR_REGISTERS) { + dev_err(&pdev->dev, + "Configuration error: id outside range.\n"); + return -EINVAL; + } + if (value & ~ab8500_reg_init[id].mask) { + dev_err(&pdev->dev, + "Configuration error: value outside mask.\n"); + return -EINVAL; + } + + /* initialize register */ + err = abx500_mask_and_set_register_interruptible(&pdev->dev, + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr, + ab8500_reg_init[id].mask, + value); + if (err < 0) { + dev_err(&pdev->dev, + "Failed to initialize 0x%02x, 0x%02x.\n", + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr); + return err; + } + dev_vdbg(&pdev->dev, + " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr, + ab8500_reg_init[id].mask, + value); + } + /* register all regulators */ for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { struct ab8500_regulator_info *info = NULL; diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h index 56f8dea72152..6e4f77ef4d20 100644 --- a/include/linux/mfd/ab8500.h +++ b/include/linux/mfd/ab8500.h @@ -139,17 +139,23 @@ struct ab8500 { u8 oldmask[AB8500_NUM_IRQ_REGS]; }; +struct regulator_reg_init; struct regulator_init_data; /** * struct ab8500_platform_data - AB8500 platform data * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used * @init: board-specific initialization after detection of ab8500 + * @num_regulator_reg_init: number of regulator init registers + * @regulator_reg_init: regulator init registers + * @num_regulator: number of regulators * @regulator: machine-specific constraints for regulators */ struct ab8500_platform_data { int irq_base; void (*init) (struct ab8500 *); + int num_regulator_reg_init; + struct ab8500_regulator_reg_init *regulator_reg_init; int num_regulator; struct regulator_init_data *regulator; }; diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index d4eacdef2017..76579f964a29 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -3,8 +3,8 @@ * * License Terms: GNU General Public License v2 * - * Author: Sundar Iyer for ST-Ericsson - * + * Authors: Sundar Iyer for ST-Ericsson + * Bengt Jonsson for ST-Ericsson */ #ifndef __LINUX_MFD_AB8500_REGULATOR_H @@ -25,4 +25,50 @@ enum ab8500_regulator_id { AB8500_LDO_ANA, AB8500_NUM_REGULATORS, }; + +/* AB8500 register initialization */ +struct ab8500_regulator_reg_init { + int id; + u8 value; +}; + +#define INIT_REGULATOR_REGISTER(_id, _value) \ + { \ + .id = _id, \ + .value = _value, \ + } + +/* AB8500 registers */ +enum ab8500_regulator_reg { + AB8500_REGUREQUESTCTRL2, + AB8500_REGUREQUESTCTRL3, + AB8500_REGUREQUESTCTRL4, + AB8500_REGUSYSCLKREQ1HPVALID1, + AB8500_REGUSYSCLKREQ1HPVALID2, + AB8500_REGUHWHPREQ1VALID1, + AB8500_REGUHWHPREQ1VALID2, + AB8500_REGUHWHPREQ2VALID1, + AB8500_REGUHWHPREQ2VALID2, + AB8500_REGUSWHPREQVALID1, + AB8500_REGUSWHPREQVALID2, + AB8500_REGUSYSCLKREQVALID1, + AB8500_REGUSYSCLKREQVALID2, + AB8500_REGUMISC1, + AB8500_VAUDIOSUPPLY, + AB8500_REGUCTRL1VAMIC, + AB8500_VPLLVANAREGU, + AB8500_VREFDDR, + AB8500_EXTSUPPLYREGU, + AB8500_VAUX12REGU, + AB8500_VRF1VAUX3REGU, + AB8500_VAUX1SEL, + AB8500_VAUX2SEL, + AB8500_VRF1VAUX3SEL, + AB8500_REGUCTRL2SPARE, + AB8500_REGUCTRLDISCH, + AB8500_REGUCTRLDISCH2, + AB8500_VSMPS1SEL1, + AB8500_NUM_REGULATOR_REGISTERS, +}; + #endif -- cgit v1.2.3 From 77af1b2641faf45788a0d480db94082ebee931dc Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 17 Mar 2011 13:24:36 +0100 Subject: regulator: add set_voltage_time_sel infrastructure This makes it possible to set the stabilization time for voltage regulators in the same manner as enable_time(). The interface only supports regulators that implements fixed selectors. Cc: Bengt Jonsson Signed-off-by: Linus Walleij Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 25 +++++++++++++++++++++++++ include/linux/regulator/driver.h | 11 +++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e611f6797e6a..e7e4460dcb92 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1629,6 +1629,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { int ret; + int delay = 0; unsigned int selector; trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); @@ -1662,6 +1663,22 @@ 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; + delay = rdev->desc->ops->set_voltage_time_sel(rdev, + old_selector, selector); + } + if (best_val != INT_MAX) { ret = rdev->desc->ops->set_voltage_sel(rdev, selector); selector = best_val; @@ -1672,6 +1689,14 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ret = -EINVAL; } + /* Insert any necessary delays */ + if (delay >= 1000) { + mdelay(delay / 1000); + udelay(delay % 1000); + } else if (delay) { + udelay(delay); + } + if (ret == 0) _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL); diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index b8ed16a33c47..6c433b89c80d 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -63,7 +63,11 @@ enum regulator_status { * when running with the specified parameters. * * @enable_time: Time taken for the regulator voltage output voltage to - * stabalise after being enabled, in microseconds. + * stabilise after being enabled, in microseconds. + * @set_voltage_time_sel: Time taken for the regulator voltage output voltage + * to stabilise after being set to a new value, in microseconds. + * The function provides the from and to voltage selector, the + * function should return the worst case. * * @set_suspend_voltage: Set the voltage for the regulator when the system * is suspended. @@ -103,8 +107,11 @@ struct regulator_ops { int (*set_mode) (struct regulator_dev *, unsigned int mode); unsigned int (*get_mode) (struct regulator_dev *); - /* Time taken to enable the regulator */ + /* Time taken to enable or set voltage on the regulator */ int (*enable_time) (struct regulator_dev *); + int (*set_voltage_time_sel) (struct regulator_dev *, + unsigned int old_selector, + unsigned int new_selector); /* report regulator status ... most other accessors report * control inputs, this reports results of combining inputs -- cgit v1.2.3 From 88cd222b259d62148ab8c82398498b1a01314476 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 17 Mar 2011 13:24:52 +0100 Subject: regulator: provide consumer interface for fall/rise time This exposes the functionality for rise/fall fime when setting voltage to the consumers. Cc: Bengt Jonsson Signed-off-by: Linus Walleij Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 45 ++++++++++++++++++++++++++++++++++++++ include/linux/regulator/consumer.h | 2 ++ 2 files changed, 47 insertions(+) (limited to 'include') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e7e4460dcb92..3ffc6979d164 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1764,6 +1764,51 @@ out: } EXPORT_SYMBOL_GPL(regulator_set_voltage); +/** + * regulator_set_voltage_time - get raise/fall time + * @regulator: regulator source + * @old_uV: starting voltage in microvolts + * @new_uV: target voltage in microvolts + * + * Provided with the starting and ending voltage, this function attempts to + * calculate the time in microseconds required to rise or fall to this new + * voltage. + */ +int regulator_set_voltage_time(struct regulator *regulator, + int old_uV, int new_uV) +{ + struct regulator_dev *rdev = regulator->rdev; + struct regulator_ops *ops = rdev->desc->ops; + int old_sel = -1; + int new_sel = -1; + int voltage; + int i; + + /* Currently requires operations to do this */ + if (!ops->list_voltage || !ops->set_voltage_time_sel + || !rdev->desc->n_voltages) + return -EINVAL; + + for (i = 0; i < rdev->desc->n_voltages; i++) { + /* We only look for exact voltage matches here */ + voltage = regulator_list_voltage(regulator, i); + if (voltage < 0) + return -EINVAL; + if (voltage == 0) + continue; + if (voltage == old_uV) + old_sel = i; + if (voltage == new_uV) + new_sel = i; + } + + if (old_sel < 0 || new_sel < 0) + return -EINVAL; + + return ops->set_voltage_time_sel(rdev, old_sel, new_sel); +} +EXPORT_SYMBOL_GPL(regulator_set_voltage_time); + /** * regulator_sync_voltage - re-apply last regulator output voltage * @regulator: regulator source diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 7954f6bd7edb..9e87c1cb7270 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -153,6 +153,8 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector); int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV); int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); +int regulator_set_voltage_time(struct regulator *regulator, + int old_uV, int new_uV); int regulator_get_voltage(struct regulator *regulator); int regulator_sync_voltage(struct regulator *regulator); int regulator_set_current_limit(struct regulator *regulator, -- cgit v1.2.3