summaryrefslogtreecommitdiff
path: root/drivers/regulator/max8660.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/max8660.c')
-rw-r--r--drivers/regulator/max8660.c165
1 files changed, 55 insertions, 110 deletions
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c
index 4c5b05311f47..8d531742f593 100644
--- a/drivers/regulator/max8660.c
+++ b/drivers/regulator/max8660.c
@@ -126,42 +126,22 @@ static int max8660_dcdc_disable(struct regulator_dev *rdev)
return max8660_write(max8660, MAX8660_OVER1, mask, 0);
}
-static int max8660_dcdc_list(struct regulator_dev *rdev, unsigned selector)
-{
- if (selector > MAX8660_DCDC_MAX_SEL)
- return -EINVAL;
- return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP;
-}
-
-static int max8660_dcdc_get(struct regulator_dev *rdev)
+static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev)
{
struct max8660 *max8660 = rdev_get_drvdata(rdev);
+
u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2;
u8 selector = max8660->shadow_regs[reg];
- return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP;
+ return selector;
}
-static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV,
- unsigned int *s)
+static int max8660_dcdc_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned int selector)
{
struct max8660 *max8660 = rdev_get_drvdata(rdev);
- u8 reg, selector, bits;
+ u8 reg, bits;
int ret;
- if (min_uV < MAX8660_DCDC_MIN_UV || min_uV > MAX8660_DCDC_MAX_UV)
- return -EINVAL;
- if (max_uV < MAX8660_DCDC_MIN_UV || max_uV > MAX8660_DCDC_MAX_UV)
- return -EINVAL;
-
- selector = DIV_ROUND_UP(min_uV - MAX8660_DCDC_MIN_UV,
- MAX8660_DCDC_STEP);
-
- ret = max8660_dcdc_list(rdev, selector);
- if (ret < 0 || ret > max_uV)
- return -EINVAL;
-
- *s = selector;
-
reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2;
ret = max8660_write(max8660, reg, 0, selector);
if (ret)
@@ -174,9 +154,10 @@ static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV,
static struct regulator_ops max8660_dcdc_ops = {
.is_enabled = max8660_dcdc_is_enabled,
- .list_voltage = max8660_dcdc_list,
- .set_voltage = max8660_dcdc_set,
- .get_voltage = max8660_dcdc_get,
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .set_voltage_sel = max8660_dcdc_set_voltage_sel,
+ .get_voltage_sel = max8660_dcdc_get_voltage_sel,
};
@@ -184,42 +165,20 @@ static struct regulator_ops max8660_dcdc_ops = {
* LDO5 functions
*/
-static int max8660_ldo5_list(struct regulator_dev *rdev, unsigned selector)
-{
- if (selector > MAX8660_LDO5_MAX_SEL)
- return -EINVAL;
- return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP;
-}
-
-static int max8660_ldo5_get(struct regulator_dev *rdev)
+static int max8660_ldo5_get_voltage_sel(struct regulator_dev *rdev)
{
struct max8660 *max8660 = rdev_get_drvdata(rdev);
- u8 selector = max8660->shadow_regs[MAX8660_MDTV2];
- return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP;
+ u8 selector = max8660->shadow_regs[MAX8660_MDTV2];
+ return selector;
}
-static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV,
- unsigned int *s)
+static int max8660_ldo5_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned int selector)
{
struct max8660 *max8660 = rdev_get_drvdata(rdev);
- u8 selector;
int ret;
- if (min_uV < MAX8660_LDO5_MIN_UV || min_uV > MAX8660_LDO5_MAX_UV)
- return -EINVAL;
- if (max_uV < MAX8660_LDO5_MIN_UV || max_uV > MAX8660_LDO5_MAX_UV)
- return -EINVAL;
-
- selector = DIV_ROUND_UP(min_uV - MAX8660_LDO5_MIN_UV,
- MAX8660_LDO5_STEP);
-
- ret = max8660_ldo5_list(rdev, selector);
- if (ret < 0 || ret > max_uV)
- return -EINVAL;
-
- *s = selector;
-
ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector);
if (ret)
return ret;
@@ -229,9 +188,10 @@ static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV,
}
static struct regulator_ops max8660_ldo5_ops = {
- .list_voltage = max8660_ldo5_list,
- .set_voltage = max8660_ldo5_set,
- .get_voltage = max8660_ldo5_get,
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .set_voltage_sel = max8660_ldo5_set_voltage_sel,
+ .get_voltage_sel = max8660_ldo5_get_voltage_sel,
};
@@ -261,59 +221,38 @@ static int max8660_ldo67_disable(struct regulator_dev *rdev)
return max8660_write(max8660, MAX8660_OVER2, mask, 0);
}
-static int max8660_ldo67_list(struct regulator_dev *rdev, unsigned selector)
-{
- if (selector > MAX8660_LDO67_MAX_SEL)
- return -EINVAL;
- return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP;
-}
-
-static int max8660_ldo67_get(struct regulator_dev *rdev)
+static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev)
{
struct max8660 *max8660 = rdev_get_drvdata(rdev);
+
u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4;
u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf;
-
- return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP;
+ return selector;
}
-static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV,
- int max_uV, unsigned int *s)
+static int max8660_ldo67_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned int selector)
{
struct max8660 *max8660 = rdev_get_drvdata(rdev);
- u8 selector;
- int ret;
-
- if (min_uV < MAX8660_LDO67_MIN_UV || min_uV > MAX8660_LDO67_MAX_UV)
- return -EINVAL;
- if (max_uV < MAX8660_LDO67_MIN_UV || max_uV > MAX8660_LDO67_MAX_UV)
- return -EINVAL;
-
- selector = DIV_ROUND_UP(min_uV - MAX8660_LDO67_MIN_UV,
- MAX8660_LDO67_STEP);
-
- ret = max8660_ldo67_list(rdev, selector);
- if (ret < 0 || ret > max_uV)
- return -EINVAL;
-
- *s = selector;
if (rdev_get_id(rdev) == MAX8660_V6)
return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector);
else
- return max8660_write(max8660, MAX8660_L12VCR, 0x0f, selector << 4);
+ return max8660_write(max8660, MAX8660_L12VCR, 0x0f,
+ selector << 4);
}
static struct regulator_ops max8660_ldo67_ops = {
.is_enabled = max8660_ldo67_is_enabled,
.enable = max8660_ldo67_enable,
.disable = max8660_ldo67_disable,
- .list_voltage = max8660_ldo67_list,
- .get_voltage = max8660_ldo67_get,
- .set_voltage = max8660_ldo67_set,
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .get_voltage_sel = max8660_ldo67_get_voltage_sel,
+ .set_voltage_sel = max8660_ldo67_set_voltage_sel,
};
-static struct regulator_desc max8660_reg[] = {
+static const struct regulator_desc max8660_reg[] = {
{
.name = "V3(DCDC)",
.id = MAX8660_V3,
@@ -321,6 +260,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_DCDC_MAX_SEL + 1,
.owner = THIS_MODULE,
+ .min_uV = MAX8660_DCDC_MIN_UV,
+ .uV_step = MAX8660_DCDC_STEP,
},
{
.name = "V4(DCDC)",
@@ -329,6 +270,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_DCDC_MAX_SEL + 1,
.owner = THIS_MODULE,
+ .min_uV = MAX8660_DCDC_MIN_UV,
+ .uV_step = MAX8660_DCDC_STEP,
},
{
.name = "V5(LDO)",
@@ -337,6 +280,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_LDO5_MAX_SEL + 1,
.owner = THIS_MODULE,
+ .min_uV = MAX8660_LDO5_MIN_UV,
+ .uV_step = MAX8660_LDO5_STEP,
},
{
.name = "V6(LDO)",
@@ -345,6 +290,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_LDO67_MAX_SEL + 1,
.owner = THIS_MODULE,
+ .min_uV = MAX8660_LDO67_MIN_UV,
+ .uV_step = MAX8660_LDO67_STEP,
},
{
.name = "V7(LDO)",
@@ -353,6 +300,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_LDO67_MAX_SEL + 1,
.owner = THIS_MODULE,
+ .min_uV = MAX8660_LDO67_MIN_UV,
+ .uV_step = MAX8660_LDO67_STEP,
},
};
@@ -361,21 +310,20 @@ static int __devinit max8660_probe(struct i2c_client *client,
{
struct regulator_dev **rdev;
struct max8660_platform_data *pdata = client->dev.platform_data;
+ struct regulator_config config = { };
struct max8660 *max8660;
int boot_on, i, id, ret = -EINVAL;
if (pdata->num_subdevs > MAX8660_V_END) {
dev_err(&client->dev, "Too many regulators found!\n");
- goto out;
+ return -EINVAL;
}
- max8660 = kzalloc(sizeof(struct max8660) +
+ max8660 = devm_kzalloc(&client->dev, sizeof(struct max8660) +
sizeof(struct regulator_dev *) * MAX8660_V_END,
GFP_KERNEL);
- if (!max8660) {
- ret = -ENOMEM;
- goto out;
- }
+ if (!max8660)
+ return -ENOMEM;
max8660->client = client;
rdev = max8660->rdev;
@@ -404,7 +352,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
for (i = 0; i < pdata->num_subdevs; i++) {
if (!pdata->subdevs[i].platform_data)
- goto err_free;
+ goto err_out;
boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
@@ -430,7 +378,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
case MAX8660_V7:
if (!strcmp(i2c_id->name, "max8661")) {
dev_err(&client->dev, "Regulator not on this chip!\n");
- goto err_free;
+ goto err_out;
}
if (boot_on)
@@ -440,7 +388,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
default:
dev_err(&client->dev, "invalid regulator %s\n",
pdata->subdevs[i].name);
- goto err_free;
+ goto err_out;
}
}
@@ -449,9 +397,11 @@ static int __devinit max8660_probe(struct i2c_client *client,
id = pdata->subdevs[i].id;
- rdev[i] = regulator_register(&max8660_reg[id], &client->dev,
- pdata->subdevs[i].platform_data,
- max8660, NULL);
+ config.dev = &client->dev;
+ config.init_data = pdata->subdevs[i].platform_data;
+ config.driver_data = max8660;
+
+ rdev[i] = regulator_register(&max8660_reg[id], &config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(&client->dev, "failed to register %s\n",
@@ -461,15 +411,12 @@ static int __devinit max8660_probe(struct i2c_client *client,
}
i2c_set_clientdata(client, max8660);
- dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n");
return 0;
err_unregister:
while (--i >= 0)
regulator_unregister(rdev[i]);
-err_free:
- kfree(max8660);
-out:
+err_out:
return ret;
}
@@ -481,8 +428,6 @@ static int __devexit max8660_remove(struct i2c_client *client)
for (i = 0; i < MAX8660_V_END; i++)
if (max8660->rdev[i])
regulator_unregister(max8660->rdev[i]);
- kfree(max8660);
-
return 0;
}