|
@@ -25,6 +25,7 @@
|
|
|
#include <linux/i2c.h>
|
|
|
#include <linux/delay.h>
|
|
|
#include <linux/slab.h>
|
|
|
+#include <linux/regmap.h>
|
|
|
|
|
|
/* Register definitions */
|
|
|
#define TPS65023_REG_VERSION 0
|
|
@@ -125,93 +126,35 @@ struct tps_pmic {
|
|
|
struct i2c_client *client;
|
|
|
struct regulator_dev *rdev[TPS65023_NUM_REGULATOR];
|
|
|
const struct tps_info *info[TPS65023_NUM_REGULATOR];
|
|
|
- struct mutex io_lock;
|
|
|
+ struct regmap *regmap;
|
|
|
};
|
|
|
|
|
|
-static inline int tps_65023_read(struct tps_pmic *tps, u8 reg)
|
|
|
-{
|
|
|
- return i2c_smbus_read_byte_data(tps->client, reg);
|
|
|
-}
|
|
|
-
|
|
|
-static inline int tps_65023_write(struct tps_pmic *tps, u8 reg, u8 val)
|
|
|
-{
|
|
|
- return i2c_smbus_write_byte_data(tps->client, reg, val);
|
|
|
-}
|
|
|
-
|
|
|
static int tps_65023_set_bits(struct tps_pmic *tps, u8 reg, u8 mask)
|
|
|
{
|
|
|
- int err, data;
|
|
|
-
|
|
|
- mutex_lock(&tps->io_lock);
|
|
|
-
|
|
|
- data = tps_65023_read(tps, reg);
|
|
|
- if (data < 0) {
|
|
|
- dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg);
|
|
|
- err = data;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- data |= mask;
|
|
|
- err = tps_65023_write(tps, reg, data);
|
|
|
- if (err)
|
|
|
- dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg);
|
|
|
-
|
|
|
-out:
|
|
|
- mutex_unlock(&tps->io_lock);
|
|
|
- return err;
|
|
|
+ return regmap_update_bits(tps->regmap, reg, mask, mask);
|
|
|
}
|
|
|
|
|
|
static int tps_65023_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask)
|
|
|
{
|
|
|
- int err, data;
|
|
|
-
|
|
|
- mutex_lock(&tps->io_lock);
|
|
|
-
|
|
|
- data = tps_65023_read(tps, reg);
|
|
|
- if (data < 0) {
|
|
|
- dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg);
|
|
|
- err = data;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- data &= ~mask;
|
|
|
-
|
|
|
- err = tps_65023_write(tps, reg, data);
|
|
|
- if (err)
|
|
|
- dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg);
|
|
|
-
|
|
|
-out:
|
|
|
- mutex_unlock(&tps->io_lock);
|
|
|
- return err;
|
|
|
-
|
|
|
+ return regmap_update_bits(tps->regmap, reg, mask, 0);
|
|
|
}
|
|
|
|
|
|
static int tps_65023_reg_read(struct tps_pmic *tps, u8 reg)
|
|
|
{
|
|
|
- int data;
|
|
|
+ unsigned int val;
|
|
|
+ int ret;
|
|
|
|
|
|
- mutex_lock(&tps->io_lock);
|
|
|
+ ret = regmap_read(tps->regmap, reg, &val);
|
|
|
|
|
|
- data = tps_65023_read(tps, reg);
|
|
|
- if (data < 0)
|
|
|
- dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg);
|
|
|
-
|
|
|
- mutex_unlock(&tps->io_lock);
|
|
|
- return data;
|
|
|
+ if (ret != 0)
|
|
|
+ return ret;
|
|
|
+ else
|
|
|
+ return val;
|
|
|
}
|
|
|
|
|
|
static int tps_65023_reg_write(struct tps_pmic *tps, u8 reg, u8 val)
|
|
|
{
|
|
|
- int err;
|
|
|
-
|
|
|
- mutex_lock(&tps->io_lock);
|
|
|
-
|
|
|
- err = tps_65023_write(tps, reg, val);
|
|
|
- if (err < 0)
|
|
|
- dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg);
|
|
|
-
|
|
|
- mutex_unlock(&tps->io_lock);
|
|
|
- return err;
|
|
|
+ return regmap_write(tps->regmap, reg, val);
|
|
|
}
|
|
|
|
|
|
static int tps65023_dcdc_is_enabled(struct regulator_dev *dev)
|
|
@@ -463,6 +406,11 @@ static struct regulator_ops tps65023_ldo_ops = {
|
|
|
.list_voltage = tps65023_ldo_list_voltage,
|
|
|
};
|
|
|
|
|
|
+static struct regmap_config tps65023_regmap_config = {
|
|
|
+ .reg_bits = 8,
|
|
|
+ .val_bits = 8,
|
|
|
+};
|
|
|
+
|
|
|
static int __devinit tps_65023_probe(struct i2c_client *client,
|
|
|
const struct i2c_device_id *id)
|
|
|
{
|
|
@@ -488,7 +436,13 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
|
|
|
if (!tps)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- mutex_init(&tps->io_lock);
|
|
|
+ tps->regmap = regmap_init_i2c(client, &tps65023_regmap_config);
|
|
|
+ if (IS_ERR(tps->regmap)) {
|
|
|
+ error = PTR_ERR(tps->regmap);
|
|
|
+ dev_err(&client->dev, "Failed to allocate register map: %d\n",
|
|
|
+ error);
|
|
|
+ goto fail_alloc;
|
|
|
+ }
|
|
|
|
|
|
/* common for all regulators */
|
|
|
tps->client = client;
|
|
@@ -527,6 +481,8 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
|
|
|
while (--i >= 0)
|
|
|
regulator_unregister(tps->rdev[i]);
|
|
|
|
|
|
+ regmap_exit(tps->regmap);
|
|
|
+ fail_alloc:
|
|
|
kfree(tps);
|
|
|
return error;
|
|
|
}
|
|
@@ -545,6 +501,7 @@ static int __devexit tps_65023_remove(struct i2c_client *client)
|
|
|
for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
|
|
|
regulator_unregister(tps->rdev[i]);
|
|
|
|
|
|
+ regmap_exit(tps->regmap);
|
|
|
kfree(tps);
|
|
|
|
|
|
return 0;
|