diff options
| -rw-r--r-- | drivers/regulator/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/regulator/tps65023-regulator.c | 97 |
2 files changed, 28 insertions, 70 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index d7ed20f293d7..118eb213eb3a 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
| @@ -235,6 +235,7 @@ config REGULATOR_TPS6105X | |||
| 235 | config REGULATOR_TPS65023 | 235 | config REGULATOR_TPS65023 |
| 236 | tristate "TI TPS65023 Power regulators" | 236 | tristate "TI TPS65023 Power regulators" |
| 237 | depends on I2C | 237 | depends on I2C |
| 238 | select REGMAP_I2C | ||
| 238 | help | 239 | help |
| 239 | This driver supports TPS65023 voltage regulator chips. TPS65023 provides | 240 | This driver supports TPS65023 voltage regulator chips. TPS65023 provides |
| 240 | three step-down converters and two general-purpose LDO voltage regulators. | 241 | three step-down converters and two general-purpose LDO voltage regulators. |
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index fbddc15e1811..701a5900f83f 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
| 26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
| 27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
| 28 | #include <linux/regmap.h> | ||
| 28 | 29 | ||
| 29 | /* Register definitions */ | 30 | /* Register definitions */ |
| 30 | #define TPS65023_REG_VERSION 0 | 31 | #define TPS65023_REG_VERSION 0 |
| @@ -125,93 +126,35 @@ struct tps_pmic { | |||
| 125 | struct i2c_client *client; | 126 | struct i2c_client *client; |
| 126 | struct regulator_dev *rdev[TPS65023_NUM_REGULATOR]; | 127 | struct regulator_dev *rdev[TPS65023_NUM_REGULATOR]; |
| 127 | const struct tps_info *info[TPS65023_NUM_REGULATOR]; | 128 | const struct tps_info *info[TPS65023_NUM_REGULATOR]; |
| 128 | struct mutex io_lock; | 129 | struct regmap *regmap; |
| 129 | }; | 130 | }; |
| 130 | 131 | ||
| 131 | static inline int tps_65023_read(struct tps_pmic *tps, u8 reg) | ||
| 132 | { | ||
| 133 | return i2c_smbus_read_byte_data(tps->client, reg); | ||
| 134 | } | ||
| 135 | |||
| 136 | static inline int tps_65023_write(struct tps_pmic *tps, u8 reg, u8 val) | ||
| 137 | { | ||
| 138 | return i2c_smbus_write_byte_data(tps->client, reg, val); | ||
| 139 | } | ||
| 140 | |||
| 141 | static int tps_65023_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) | 132 | static int tps_65023_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) |
| 142 | { | 133 | { |
| 143 | int err, data; | 134 | return regmap_update_bits(tps->regmap, reg, mask, mask); |
| 144 | |||
| 145 | mutex_lock(&tps->io_lock); | ||
| 146 | |||
| 147 | data = tps_65023_read(tps, reg); | ||
| 148 | if (data < 0) { | ||
| 149 | dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); | ||
| 150 | err = data; | ||
| 151 | goto out; | ||
| 152 | } | ||
| 153 | |||
| 154 | data |= mask; | ||
| 155 | err = tps_65023_write(tps, reg, data); | ||
| 156 | if (err) | ||
| 157 | dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); | ||
| 158 | |||
| 159 | out: | ||
| 160 | mutex_unlock(&tps->io_lock); | ||
| 161 | return err; | ||
| 162 | } | 135 | } |
| 163 | 136 | ||
| 164 | static int tps_65023_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) | 137 | static int tps_65023_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) |
| 165 | { | 138 | { |
| 166 | int err, data; | 139 | return regmap_update_bits(tps->regmap, reg, mask, 0); |
| 167 | |||
| 168 | mutex_lock(&tps->io_lock); | ||
| 169 | |||
| 170 | data = tps_65023_read(tps, reg); | ||
| 171 | if (data < 0) { | ||
| 172 | dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); | ||
| 173 | err = data; | ||
| 174 | goto out; | ||
| 175 | } | ||
| 176 | |||
| 177 | data &= ~mask; | ||
| 178 | |||
| 179 | err = tps_65023_write(tps, reg, data); | ||
| 180 | if (err) | ||
| 181 | dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); | ||
| 182 | |||
| 183 | out: | ||
| 184 | mutex_unlock(&tps->io_lock); | ||
| 185 | return err; | ||
| 186 | |||
| 187 | } | 140 | } |
| 188 | 141 | ||
| 189 | static int tps_65023_reg_read(struct tps_pmic *tps, u8 reg) | 142 | static int tps_65023_reg_read(struct tps_pmic *tps, u8 reg) |
| 190 | { | 143 | { |
| 191 | int data; | 144 | unsigned int val; |
| 145 | int ret; | ||
| 192 | 146 | ||
| 193 | mutex_lock(&tps->io_lock); | 147 | ret = regmap_read(tps->regmap, reg, &val); |
| 194 | 148 | ||
| 195 | data = tps_65023_read(tps, reg); | 149 | if (ret != 0) |
| 196 | if (data < 0) | 150 | return ret; |
| 197 | dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); | 151 | else |
| 198 | 152 | return val; | |
| 199 | mutex_unlock(&tps->io_lock); | ||
| 200 | return data; | ||
| 201 | } | 153 | } |
| 202 | 154 | ||
| 203 | static int tps_65023_reg_write(struct tps_pmic *tps, u8 reg, u8 val) | 155 | static int tps_65023_reg_write(struct tps_pmic *tps, u8 reg, u8 val) |
| 204 | { | 156 | { |
| 205 | int err; | 157 | return regmap_write(tps->regmap, reg, val); |
| 206 | |||
| 207 | mutex_lock(&tps->io_lock); | ||
| 208 | |||
| 209 | err = tps_65023_write(tps, reg, val); | ||
| 210 | if (err < 0) | ||
| 211 | dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); | ||
| 212 | |||
| 213 | mutex_unlock(&tps->io_lock); | ||
| 214 | return err; | ||
| 215 | } | 158 | } |
| 216 | 159 | ||
| 217 | static int tps65023_dcdc_is_enabled(struct regulator_dev *dev) | 160 | static int tps65023_dcdc_is_enabled(struct regulator_dev *dev) |
| @@ -463,6 +406,11 @@ static struct regulator_ops tps65023_ldo_ops = { | |||
| 463 | .list_voltage = tps65023_ldo_list_voltage, | 406 | .list_voltage = tps65023_ldo_list_voltage, |
| 464 | }; | 407 | }; |
| 465 | 408 | ||
| 409 | static struct regmap_config tps65023_regmap_config = { | ||
| 410 | .reg_bits = 8, | ||
| 411 | .val_bits = 8, | ||
| 412 | }; | ||
| 413 | |||
| 466 | static int __devinit tps_65023_probe(struct i2c_client *client, | 414 | static int __devinit tps_65023_probe(struct i2c_client *client, |
| 467 | const struct i2c_device_id *id) | 415 | const struct i2c_device_id *id) |
| 468 | { | 416 | { |
| @@ -488,7 +436,13 @@ static int __devinit tps_65023_probe(struct i2c_client *client, | |||
| 488 | if (!tps) | 436 | if (!tps) |
| 489 | return -ENOMEM; | 437 | return -ENOMEM; |
| 490 | 438 | ||
| 491 | mutex_init(&tps->io_lock); | 439 | tps->regmap = regmap_init_i2c(client, &tps65023_regmap_config); |
| 440 | if (IS_ERR(tps->regmap)) { | ||
| 441 | error = PTR_ERR(tps->regmap); | ||
| 442 | dev_err(&client->dev, "Failed to allocate register map: %d\n", | ||
| 443 | error); | ||
| 444 | goto fail_alloc; | ||
| 445 | } | ||
| 492 | 446 | ||
| 493 | /* common for all regulators */ | 447 | /* common for all regulators */ |
| 494 | tps->client = client; | 448 | tps->client = client; |
| @@ -527,6 +481,8 @@ static int __devinit tps_65023_probe(struct i2c_client *client, | |||
| 527 | while (--i >= 0) | 481 | while (--i >= 0) |
| 528 | regulator_unregister(tps->rdev[i]); | 482 | regulator_unregister(tps->rdev[i]); |
| 529 | 483 | ||
| 484 | regmap_exit(tps->regmap); | ||
| 485 | fail_alloc: | ||
| 530 | kfree(tps); | 486 | kfree(tps); |
| 531 | return error; | 487 | return error; |
| 532 | } | 488 | } |
| @@ -545,6 +501,7 @@ static int __devexit tps_65023_remove(struct i2c_client *client) | |||
| 545 | for (i = 0; i < TPS65023_NUM_REGULATOR; i++) | 501 | for (i = 0; i < TPS65023_NUM_REGULATOR; i++) |
| 546 | regulator_unregister(tps->rdev[i]); | 502 | regulator_unregister(tps->rdev[i]); |
| 547 | 503 | ||
| 504 | regmap_exit(tps->regmap); | ||
| 548 | kfree(tps); | 505 | kfree(tps); |
| 549 | 506 | ||
| 550 | return 0; | 507 | return 0; |
