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 num_consumers, unsigned long features)
|
||||||
{
|
{
|
||||||
unsigned sub_chip_id;
|
unsigned sub_chip_id;
|
||||||
|
struct twl_regulator_driver_data drv_data;
|
||||||
|
|
||||||
/* regulator framework demands init_data ... */
|
/* regulator framework demands init_data ... */
|
||||||
if (!pdata)
|
if (!pdata)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -628,7 +630,19 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
|
||||||
pdata->num_consumer_supplies = num_consumers;
|
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 */
|
/* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */
|
||||||
sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
|
sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
|
||||||
|
|
|
@ -58,6 +58,16 @@ struct twlreg_info {
|
||||||
|
|
||||||
/* chip specific features */
|
/* chip specific features */
|
||||||
unsigned long 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);
|
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||||
int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
|
int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
|
||||||
|
|
||||||
twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030,
|
if (info->set_voltage) {
|
||||||
vsel);
|
return info->set_voltage(info->data, min_uV);
|
||||||
|
} else {
|
||||||
|
twlreg_write(info, TWL_MODULE_PM_RECEIVER,
|
||||||
|
VREG_VOLTAGE_SMPS_4030, vsel);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int twl4030smps_get_voltage(struct regulator_dev *rdev)
|
static int twl4030smps_get_voltage(struct regulator_dev *rdev)
|
||||||
{
|
{
|
||||||
struct twlreg_info *info = rdev_get_drvdata(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);
|
VREG_VOLTAGE_SMPS_4030);
|
||||||
|
|
||||||
return vsel * 12500 + 600000;
|
return vsel * 12500 + 600000;
|
||||||
|
@ -1060,6 +1080,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
||||||
struct regulator_init_data *initdata;
|
struct regulator_init_data *initdata;
|
||||||
struct regulation_constraints *c;
|
struct regulation_constraints *c;
|
||||||
struct regulator_dev *rdev;
|
struct regulator_dev *rdev;
|
||||||
|
struct twl_regulator_driver_data *drvdata;
|
||||||
|
|
||||||
for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
|
for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
|
||||||
if (twl_regs[i].desc.id != pdev->id)
|
if (twl_regs[i].desc.id != pdev->id)
|
||||||
|
@ -1074,8 +1095,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
||||||
if (!initdata)
|
if (!initdata)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* copy the features into regulator data */
|
drvdata = initdata->driver_data;
|
||||||
info->features = (unsigned long)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
|
/* Constrain board-specific capabilities according to what
|
||||||
* this driver and the chip itself can actually do.
|
* this driver and the chip itself can actually do.
|
||||||
|
|
|
@ -749,6 +749,13 @@ struct twl4030_platform_data {
|
||||||
struct regulator_init_data *vio6025;
|
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);
|
int twl4030_sih_setup(int module);
|
||||||
|
|
Loading…
Reference in New Issue