mfd: Convert pcf50633 to use new register map API

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Tested-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Mark Brown 2011-08-08 17:04:40 +09:00 committed by Samuel Ortiz
parent d036c96e70
commit 6e3ad11804
3 changed files with 38 additions and 80 deletions

View File

@ -500,6 +500,7 @@ config MFD_WM8994
config MFD_PCF50633 config MFD_PCF50633
tristate "Support for NXP PCF50633" tristate "Support for NXP PCF50633"
depends on I2C depends on I2C
select REGMAP_I2C
help help
Say yes here if you have NXP PCF50633 chip on your board. Say yes here if you have NXP PCF50633 chip on your board.
This core driver provides register access and IRQ handling This core driver provides register access and IRQ handling

View File

@ -23,45 +23,22 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/err.h>
#include <linux/mfd/pcf50633/core.h> #include <linux/mfd/pcf50633/core.h>
static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
{
int ret;
ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client, reg,
num, data);
if (ret < 0)
dev_err(pcf->dev, "Error reading %d regs at %d\n", num, reg);
return ret;
}
static int __pcf50633_write(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
{
int ret;
ret = i2c_smbus_write_i2c_block_data(pcf->i2c_client, reg,
num, data);
if (ret < 0)
dev_err(pcf->dev, "Error writing %d regs at %d\n", num, reg);
return ret;
}
/* Read a block of up to 32 regs */ /* Read a block of up to 32 regs */
int pcf50633_read_block(struct pcf50633 *pcf, u8 reg, int pcf50633_read_block(struct pcf50633 *pcf, u8 reg,
int nr_regs, u8 *data) int nr_regs, u8 *data)
{ {
int ret; int ret;
mutex_lock(&pcf->lock); ret = regmap_raw_read(pcf->regmap, reg, data, nr_regs);
ret = __pcf50633_read(pcf, reg, nr_regs, data); if (ret != 0)
mutex_unlock(&pcf->lock); return ret;
return ret; return nr_regs;
} }
EXPORT_SYMBOL_GPL(pcf50633_read_block); EXPORT_SYMBOL_GPL(pcf50633_read_block);
@ -71,21 +48,22 @@ int pcf50633_write_block(struct pcf50633 *pcf , u8 reg,
{ {
int ret; int ret;
mutex_lock(&pcf->lock); ret = regmap_raw_write(pcf->regmap, reg, data, nr_regs);
ret = __pcf50633_write(pcf, reg, nr_regs, data); if (ret != 0)
mutex_unlock(&pcf->lock); return ret;
return ret; return nr_regs;
} }
EXPORT_SYMBOL_GPL(pcf50633_write_block); EXPORT_SYMBOL_GPL(pcf50633_write_block);
u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg) u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg)
{ {
u8 val; unsigned int val;
int ret;
mutex_lock(&pcf->lock); ret = regmap_read(pcf->regmap, reg, &val);
__pcf50633_read(pcf, reg, 1, &val); if (ret < 0)
mutex_unlock(&pcf->lock); return -1;
return val; return val;
} }
@ -93,56 +71,19 @@ EXPORT_SYMBOL_GPL(pcf50633_reg_read);
int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val) int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val)
{ {
int ret; return regmap_write(pcf->regmap, reg, val);
mutex_lock(&pcf->lock);
ret = __pcf50633_write(pcf, reg, 1, &val);
mutex_unlock(&pcf->lock);
return ret;
} }
EXPORT_SYMBOL_GPL(pcf50633_reg_write); EXPORT_SYMBOL_GPL(pcf50633_reg_write);
int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val) int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val)
{ {
int ret; return regmap_update_bits(pcf->regmap, reg, mask, val);
u8 tmp;
val &= mask;
mutex_lock(&pcf->lock);
ret = __pcf50633_read(pcf, reg, 1, &tmp);
if (ret < 0)
goto out;
tmp &= ~mask;
tmp |= val;
ret = __pcf50633_write(pcf, reg, 1, &tmp);
out:
mutex_unlock(&pcf->lock);
return ret;
} }
EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask); EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask);
int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val) int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val)
{ {
int ret; return regmap_update_bits(pcf->regmap, reg, val, 0);
u8 tmp;
mutex_lock(&pcf->lock);
ret = __pcf50633_read(pcf, reg, 1, &tmp);
if (ret < 0)
goto out;
tmp &= ~val;
ret = __pcf50633_write(pcf, reg, 1, &tmp);
out:
mutex_unlock(&pcf->lock);
return ret;
} }
EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits); EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits);
@ -251,6 +192,11 @@ static int pcf50633_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume); static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
static struct regmap_config pcf50633_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static int __devinit pcf50633_probe(struct i2c_client *client, static int __devinit pcf50633_probe(struct i2c_client *client,
const struct i2c_device_id *ids) const struct i2c_device_id *ids)
{ {
@ -272,16 +218,23 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
mutex_init(&pcf->lock); mutex_init(&pcf->lock);
pcf->regmap = regmap_init_i2c(client, &pcf50633_regmap_config);
if (IS_ERR(pcf->regmap)) {
ret = PTR_ERR(pcf->regmap);
dev_err(pcf->dev, "Failed to allocate register map: %d\n",
ret);
goto err_free;
}
i2c_set_clientdata(client, pcf); i2c_set_clientdata(client, pcf);
pcf->dev = &client->dev; pcf->dev = &client->dev;
pcf->i2c_client = client;
version = pcf50633_reg_read(pcf, 0); version = pcf50633_reg_read(pcf, 0);
variant = pcf50633_reg_read(pcf, 1); variant = pcf50633_reg_read(pcf, 1);
if (version < 0 || variant < 0) { if (version < 0 || variant < 0) {
dev_err(pcf->dev, "Unable to probe pcf50633\n"); dev_err(pcf->dev, "Unable to probe pcf50633\n");
ret = -ENODEV; ret = -ENODEV;
goto err_free; goto err_regmap;
} }
dev_info(pcf->dev, "Probed device version %d variant %d\n", dev_info(pcf->dev, "Probed device version %d variant %d\n",
@ -328,6 +281,8 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
return 0; return 0;
err_regmap:
regmap_exit(pcf->regmap);
err_free: err_free:
kfree(pcf); kfree(pcf);
@ -351,6 +306,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
for (i = 0; i < PCF50633_NUM_REGULATORS; i++) for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
platform_device_unregister(pcf->regulator_pdev[i]); platform_device_unregister(pcf->regulator_pdev[i]);
regmap_exit(pcf->regmap);
kfree(pcf); kfree(pcf);
return 0; return 0;

View File

@ -21,6 +21,7 @@
#include <linux/mfd/pcf50633/backlight.h> #include <linux/mfd/pcf50633/backlight.h>
struct pcf50633; struct pcf50633;
struct regmap;
#define PCF50633_NUM_REGULATORS 11 #define PCF50633_NUM_REGULATORS 11
@ -134,7 +135,7 @@ enum {
struct pcf50633 { struct pcf50633 {
struct device *dev; struct device *dev;
struct i2c_client *i2c_client; struct regmap *regmap;
struct pcf50633_platform_data *pdata; struct pcf50633_platform_data *pdata;
int irq; int irq;