diff options
Diffstat (limited to 'drivers/regulator/isl6271a-regulator.c')
| -rw-r--r-- | drivers/regulator/isl6271a-regulator.c | 120 |
1 files changed, 33 insertions, 87 deletions
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index b8cc6389a54..6e5da95fa02 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -22,7 +22,6 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/i2c.h> -#include <linux/delay.h> #include <linux/slab.h> #define ISL6271A_VOLTAGE_MIN 850000 @@ -36,51 +35,30 @@ struct isl_pmic { struct mutex mtx; }; -static int isl6271a_get_voltage(struct regulator_dev *dev) +static int isl6271a_get_voltage_sel(struct regulator_dev *dev) { struct isl_pmic *pmic = rdev_get_drvdata(dev); - int idx, data; + int idx; mutex_lock(&pmic->mtx); idx = i2c_smbus_read_byte(pmic->client); - if (idx < 0) { + if (idx < 0) dev_err(&pmic->client->dev, "Error getting voltage\n"); - data = idx; - goto out; - } - - /* Convert the data from chip to microvolts */ - data = ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * (idx & 0xf)); -out: mutex_unlock(&pmic->mtx); - return data; + return idx; } -static int isl6271a_set_voltage(struct regulator_dev *dev, int minuV, int maxuV) +static int isl6271a_set_voltage_sel(struct regulator_dev *dev, + unsigned selector) { struct isl_pmic *pmic = rdev_get_drvdata(dev); - int vsel, err, data; - - if (minuV < ISL6271A_VOLTAGE_MIN || minuV > ISL6271A_VOLTAGE_MAX) - return -EINVAL; - if (maxuV < ISL6271A_VOLTAGE_MIN || maxuV > ISL6271A_VOLTAGE_MAX) - return -EINVAL; - - /* Align to 50000 mV */ - vsel = minuV - (minuV % ISL6271A_VOLTAGE_STEP); - - /* If the result fell out of [minuV,maxuV] range, put it back */ - if (vsel < minuV) - vsel += ISL6271A_VOLTAGE_STEP; - - /* Convert the microvolts to data for the chip */ - data = (vsel - ISL6271A_VOLTAGE_MIN) / ISL6271A_VOLTAGE_STEP; + int err; mutex_lock(&pmic->mtx); - err = i2c_smbus_write_byte(pmic->client, data); + err = i2c_smbus_write_byte(pmic->client, selector); if (err < 0) dev_err(&pmic->client->dev, "Error setting voltage\n"); @@ -88,35 +66,18 @@ static int isl6271a_set_voltage(struct regulator_dev *dev, int minuV, int maxuV) return err; } -static int isl6271a_list_voltage(struct regulator_dev *dev, unsigned selector) -{ - return ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * selector); -} - static struct regulator_ops isl_core_ops = { - .get_voltage = isl6271a_get_voltage, - .set_voltage = isl6271a_set_voltage, - .list_voltage = isl6271a_list_voltage, + .get_voltage_sel = isl6271a_get_voltage_sel, + .set_voltage_sel = isl6271a_set_voltage_sel, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, }; -static int isl6271a_get_fixed_voltage(struct regulator_dev *dev) -{ - int id = rdev_get_id(dev); - return (id == 1) ? 1100000 : 1300000; -} - -static int isl6271a_list_fixed_voltage(struct regulator_dev *dev, unsigned selector) -{ - int id = rdev_get_id(dev); - return (id == 1) ? 1100000 : 1300000; -} - static struct regulator_ops isl_fixed_ops = { - .get_voltage = isl6271a_get_fixed_voltage, - .list_voltage = isl6271a_list_fixed_voltage, + .list_voltage = regulator_list_voltage_linear, }; -static struct regulator_desc isl_rd[] = { +static const struct regulator_desc isl_rd[] = { { .name = "Core Buck", .id = 0, @@ -124,6 +85,8 @@ static struct regulator_desc isl_rd[] = { .ops = &isl_core_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, + .min_uV = ISL6271A_VOLTAGE_MIN, + .uV_step = ISL6271A_VOLTAGE_STEP, }, { .name = "LDO1", .id = 1, @@ -131,6 +94,7 @@ static struct regulator_desc isl_rd[] = { .ops = &isl_fixed_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, + .min_uV = 1100000, }, { .name = "LDO2", .id = 2, @@ -138,25 +102,22 @@ static struct regulator_desc isl_rd[] = { .ops = &isl_fixed_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, + .min_uV = 1300000, }, }; -static int __devinit isl6271a_probe(struct i2c_client *i2c, +static int isl6271a_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct regulator_init_data *init_data = i2c->dev.platform_data; + struct regulator_config config = { }; + struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); struct isl_pmic *pmic; - int err, i; + int i; if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - if (!init_data) { - dev_err(&i2c->dev, "no platform data supplied\n"); - return -EIO; - } - - pmic = kzalloc(sizeof(struct isl_pmic), GFP_KERNEL); + pmic = devm_kzalloc(&i2c->dev, sizeof(struct isl_pmic), GFP_KERNEL); if (!pmic) return -ENOMEM; @@ -165,38 +126,24 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, mutex_init(&pmic->mtx); for (i = 0; i < 3; i++) { - pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev, - init_data, pmic); + config.dev = &i2c->dev; + if (i == 0) + config.init_data = init_data; + else + config.init_data = NULL; + config.driver_data = pmic; + + pmic->rdev[i] = devm_regulator_register(&i2c->dev, &isl_rd[i], + &config); if (IS_ERR(pmic->rdev[i])) { dev_err(&i2c->dev, "failed to register %s\n", id->name); - err = PTR_ERR(pmic->rdev); - goto error; + return PTR_ERR(pmic->rdev[i]); } } i2c_set_clientdata(i2c, pmic); return 0; - -error: - while (--i >= 0) - regulator_unregister(pmic->rdev[i]); - - kfree(pmic); - return err; -} - -static int __devexit isl6271a_remove(struct i2c_client *i2c) -{ - struct isl_pmic *pmic = i2c_get_clientdata(i2c); - int i; - - for (i = 0; i < 3; i++) - regulator_unregister(pmic->rdev[i]); - - kfree(pmic); - - return 0; } static const struct i2c_device_id isl6271a_id[] = { @@ -212,7 +159,6 @@ static struct i2c_driver isl6271a_i2c_driver = { .owner = THIS_MODULE, }, .probe = isl6271a_probe, - .remove = __devexit_p(isl6271a_remove), .id_table = isl6271a_id, }; |
