mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 08:44:21 +08:00
regulator: twl4030: add support for external voltage get/set
This is needed for SMPS regulators, which use the OMAP voltage processor for voltage get/set functions instead of the normal I2C channel. For this purpose, regulator_init_data->driver_data contents are expanded, it is now a struct which contains function pointers for the set/get voltage operations, a data pointer for these, and the previously used features bitmask. Signed-off-by: Tero Kristo <t-kristo@ti.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com> [for the MFD part] Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
a33b6e5a8f
commit
63bfff4e20
@ -619,6 +619,8 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
|
||||
unsigned num_consumers, unsigned long features)
|
||||
{
|
||||
unsigned sub_chip_id;
|
||||
struct twl_regulator_driver_data drv_data;
|
||||
|
||||
/* regulator framework demands init_data ... */
|
||||
if (!pdata)
|
||||
return NULL;
|
||||
@ -628,7 +630,19 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
|
||||
pdata->num_consumer_supplies = num_consumers;
|
||||
}
|
||||
|
||||
pdata->driver_data = (void *)features;
|
||||
if (pdata->driver_data) {
|
||||
/* If we have existing drv_data, just add the flags */
|
||||
struct twl_regulator_driver_data *tmp;
|
||||
tmp = pdata->driver_data;
|
||||
tmp->features |= features;
|
||||
} else {
|
||||
/* add new driver data struct, used only during init */
|
||||
drv_data.features = features;
|
||||
drv_data.set_voltage = NULL;
|
||||
drv_data.get_voltage = NULL;
|
||||
drv_data.data = NULL;
|
||||
pdata->driver_data = &drv_data;
|
||||
}
|
||||
|
||||
/* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */
|
||||
sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
|
||||
|
@ -58,6 +58,16 @@ struct twlreg_info {
|
||||
|
||||
/* chip specific features */
|
||||
unsigned long features;
|
||||
|
||||
/*
|
||||
* optional override functions for voltage set/get
|
||||
* these are currently only used for SMPS regulators
|
||||
*/
|
||||
int (*get_voltage)(void *data);
|
||||
int (*set_voltage)(void *data, int target_uV);
|
||||
|
||||
/* data passed from board for external get/set voltage */
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
@ -522,15 +532,25 @@ twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
|
||||
|
||||
twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030,
|
||||
vsel);
|
||||
if (info->set_voltage) {
|
||||
return info->set_voltage(info->data, min_uV);
|
||||
} else {
|
||||
twlreg_write(info, TWL_MODULE_PM_RECEIVER,
|
||||
VREG_VOLTAGE_SMPS_4030, vsel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int twl4030smps_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
|
||||
int vsel;
|
||||
|
||||
if (info->get_voltage)
|
||||
return info->get_voltage(info->data);
|
||||
|
||||
vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
|
||||
VREG_VOLTAGE_SMPS_4030);
|
||||
|
||||
return vsel * 12500 + 600000;
|
||||
@ -1060,6 +1080,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
||||
struct regulator_init_data *initdata;
|
||||
struct regulation_constraints *c;
|
||||
struct regulator_dev *rdev;
|
||||
struct twl_regulator_driver_data *drvdata;
|
||||
|
||||
for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
|
||||
if (twl_regs[i].desc.id != pdev->id)
|
||||
@ -1074,8 +1095,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
||||
if (!initdata)
|
||||
return -EINVAL;
|
||||
|
||||
/* copy the features into regulator data */
|
||||
info->features = (unsigned long)initdata->driver_data;
|
||||
drvdata = initdata->driver_data;
|
||||
|
||||
if (!drvdata)
|
||||
return -EINVAL;
|
||||
|
||||
/* copy the driver data into regulator data */
|
||||
info->features = drvdata->features;
|
||||
info->data = drvdata->data;
|
||||
info->set_voltage = drvdata->set_voltage;
|
||||
info->get_voltage = drvdata->get_voltage;
|
||||
|
||||
/* Constrain board-specific capabilities according to what
|
||||
* this driver and the chip itself can actually do.
|
||||
|
@ -749,6 +749,13 @@ struct twl4030_platform_data {
|
||||
struct regulator_init_data *vio6025;
|
||||
};
|
||||
|
||||
struct twl_regulator_driver_data {
|
||||
int (*set_voltage)(void *data, int target_uV);
|
||||
int (*get_voltage)(void *data);
|
||||
void *data;
|
||||
unsigned long features;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
int twl4030_sih_setup(int module);
|
||||
|
Loading…
Reference in New Issue
Block a user