diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-03 20:40:51 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-03 20:40:51 +0400 |
commit | a0a4194c943bc64dd7b6e26cccb036cb26b81363 (patch) | |
tree | 4282f0dd573344d10f69616eb05868b5cd563cc1 /drivers/mfd/pcf50633-core.c | |
parent | cf0223503e6198292cdcc864e01eeb5fe7490752 (diff) | |
parent | b958f7a7cbdfbf59ba61de7ebb9c59b0ee3a7967 (diff) | |
download | linux-a0a4194c943bc64dd7b6e26cccb036cb26b81363.tar.xz |
Merge branch 'for-next' of git://git.infradead.org/users/sameo/mfd-2.6
* 'for-next' of git://git.infradead.org/users/sameo/mfd-2.6: (80 commits)
mfd: Fix missing abx500 header file updates
mfd: Add missing <linux/io.h> include to intel_msic
x86, mrst: add platform support for MSIC MFD driver
mfd: Expose TurnOnStatus in ab8500 sysfs
mfd: Remove support for early drop ab8500 chip
mfd: Add support for ab8500 v3.3
mfd: Add ab8500 interrupt disable hook
mfd: Convert db8500-prcmu panic() into pr_crit()
mfd: Refactor db8500-prcmu request_clock() function
mfd: Rename db8500-prcmu init function
mfd: Fix db5500-prcmu defines
mfd: db8500-prcmu voltage domain consumers additions
mfd: db8500-prcmu reset code retrieval
mfd: db8500-prcmu tweak for modem wakeup
mfd: Add db8500-pcmu watchdog accessor functions for watchdog
mfd: hwacc power state db8500-prcmu accessor
mfd: Add db8500-prcmu accessors for PLL and SGA clock
mfd: Move to the new db500 PRCMU API
mfd: Create a common interface for dbx500 PRCMU drivers
mfd: Initialize DB8500 PRCMU regs
...
Fix up trivial conflicts in
arch/arm/mach-imx/mach-mx31moboard.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-u300/include/mach/irqs.h
drivers/mfd/wm831x-spi.c
Diffstat (limited to 'drivers/mfd/pcf50633-core.c')
-rw-r--r-- | drivers/mfd/pcf50633-core.c | 114 |
1 files changed, 35 insertions, 79 deletions
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 57868416c760..ff1a7e741ecd 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -23,45 +23,22 @@ #include <linux/i2c.h> #include <linux/pm.h> #include <linux/slab.h> +#include <linux/regmap.h> +#include <linux/err.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 */ int pcf50633_read_block(struct pcf50633 *pcf, u8 reg, int nr_regs, u8 *data) { int ret; - mutex_lock(&pcf->lock); - ret = __pcf50633_read(pcf, reg, nr_regs, data); - mutex_unlock(&pcf->lock); + ret = regmap_raw_read(pcf->regmap, reg, data, nr_regs); + if (ret != 0) + return ret; - return ret; + return nr_regs; } EXPORT_SYMBOL_GPL(pcf50633_read_block); @@ -71,21 +48,22 @@ int pcf50633_write_block(struct pcf50633 *pcf , u8 reg, { int ret; - mutex_lock(&pcf->lock); - ret = __pcf50633_write(pcf, reg, nr_regs, data); - mutex_unlock(&pcf->lock); + ret = regmap_raw_write(pcf->regmap, reg, data, nr_regs); + if (ret != 0) + return ret; - return ret; + return nr_regs; } EXPORT_SYMBOL_GPL(pcf50633_write_block); u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg) { - u8 val; + unsigned int val; + int ret; - mutex_lock(&pcf->lock); - __pcf50633_read(pcf, reg, 1, &val); - mutex_unlock(&pcf->lock); + ret = regmap_read(pcf->regmap, reg, &val); + if (ret < 0) + return -1; return val; } @@ -93,56 +71,19 @@ EXPORT_SYMBOL_GPL(pcf50633_reg_read); int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val) { - int ret; - - mutex_lock(&pcf->lock); - ret = __pcf50633_write(pcf, reg, 1, &val); - mutex_unlock(&pcf->lock); - - return ret; + return regmap_write(pcf->regmap, reg, val); } EXPORT_SYMBOL_GPL(pcf50633_reg_write); int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val) { - int ret; - 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; + return regmap_update_bits(pcf->regmap, reg, mask, val); } EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask); int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val) { - int ret; - 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; + return regmap_update_bits(pcf->regmap, reg, val, 0); } 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 struct regmap_config pcf50633_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + static int __devinit pcf50633_probe(struct i2c_client *client, const struct i2c_device_id *ids) { @@ -272,16 +218,23 @@ static int __devinit pcf50633_probe(struct i2c_client *client, 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); pcf->dev = &client->dev; - pcf->i2c_client = client; version = pcf50633_reg_read(pcf, 0); variant = pcf50633_reg_read(pcf, 1); if (version < 0 || variant < 0) { dev_err(pcf->dev, "Unable to probe pcf50633\n"); ret = -ENODEV; - goto err_free; + goto err_regmap; } 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; +err_regmap: + regmap_exit(pcf->regmap); err_free: kfree(pcf); @@ -351,6 +306,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client) for (i = 0; i < PCF50633_NUM_REGULATORS; i++) platform_device_unregister(pcf->regulator_pdev[i]); + regmap_exit(pcf->regmap); kfree(pcf); return 0; |