summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMattias Nilsson <mattias.i.nilsson@stericsson.com>2012-03-05 16:52:14 +0100
committerPhilippe Langlais <philippe.langlais@linaro.org>2012-04-06 09:39:36 +0200
commit7b3b0c2093f8c1ef3e1e6c965f4c79e33a883f42 (patch)
tree9670b3d078fa8cbb94b8b6041a685139e4b4b610
parenta8fb4849d086e1b4c3185dc9e8cd042c5ed66298 (diff)
mfd: ab8500: make use of the firmware read-modify-write service
This patch updates the AB8500 driver to make use of the I2C read-modify-write service in the PRCMU firmware. ST Ericsson ID: 354143 ST Ericsson FOSS-OUT ID: trivial Change-Id: Ic204b63b3a7546bbb7cf4966c973f9ec3662c328 Signed-off-by: Mattias Nilsson <mattias.i.nilsson@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/47195 Reviewed-by: QABUILD Reviewed-by: Mattias WALLIN <mattias.wallin@stericsson.com>
-rw-r--r--drivers/mfd/ab8500-core.c37
-rw-r--r--drivers/mfd/ab8500-i2c.c13
-rw-r--r--include/linux/mfd/abx500/ab8500.h6
3 files changed, 40 insertions, 16 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index bb220ca0176..ddbfcd5cc6d 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -204,29 +204,38 @@ static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank,
u8 reg, u8 bitmask, u8 bitvalues)
{
int ret;
- u8 data;
/* put the u8 bank and u8 reg together into a an u16.
* bank on higher 8 bits and reg in lower */
u16 addr = ((u16)bank) << 8 | reg;
mutex_lock(&ab8500->lock);
- ret = ab8500->read(ab8500, addr);
- if (ret < 0) {
- dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
- addr, ret);
- goto out;
- }
+ if (ab8500->write_masked == NULL) {
+ u8 data;
- data = (u8)ret;
- data = (~bitmask & data) | (bitmask & bitvalues);
+ ret = ab8500->read(ab8500, addr);
+ if (ret < 0) {
+ dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
+ addr, ret);
+ goto out;
+ }
- ret = ab8500->write(ab8500, addr, data);
- if (ret < 0)
- dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
- addr, ret);
+ data = (u8)ret;
+ data = (~bitmask & data) | (bitmask & bitvalues);
+
+ ret = ab8500->write(ab8500, addr, data);
+ if (ret < 0)
+ dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
+ addr, ret);
- dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr, data);
+ dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr,
+ data);
+ goto out;
+ }
+ ret = ab8500->write_masked(ab8500, addr, bitmask, bitvalues);
+ if (ret < 0)
+ dev_err(ab8500->dev, "failed to modify reg %#x: %d\n", addr,
+ ret);
out:
mutex_unlock(&ab8500->lock);
return ret;
diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c
index 1c0d1fbdb2a..15b837c70a1 100644
--- a/drivers/mfd/ab8500-i2c.c
+++ b/drivers/mfd/ab8500-i2c.c
@@ -24,6 +24,18 @@ static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
return ret;
}
+static int ab8500_i2c_write_masked(struct ab8500 *ab8500, u16 addr, u8 mask,
+ u8 data)
+{
+ int ret;
+
+ ret = prcmu_abb_write_masked((u8)(addr >> 8), (u8)(addr & 0xFF), &data,
+ &mask, 1);
+ if (ret < 0)
+ dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
+ return ret;
+}
+
static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr)
{
int ret;
@@ -60,6 +72,7 @@ static int __devinit ab8500_i2c_probe(struct platform_device *plf)
ab8500->read = ab8500_i2c_read;
ab8500->write = ab8500_i2c_write;
+ ab8500->write_masked = ab8500_i2c_write_masked;
platform_set_drvdata(plf, ab8500);
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h
index 8cba9684e4a..9612ebd6991 100644
--- a/include/linux/mfd/abx500/ab8500.h
+++ b/include/linux/mfd/abx500/ab8500.h
@@ -217,6 +217,7 @@ enum ab8500_version {
* @version: chip version id (e.g. ab8500 or ab9540)
* @chip_id: chip revision id
* @write: register write
+ * @write_masked: masked register write
* @read: register read
* @rx_buf: rx buf for SPI
* @tx_buf: tx buf for SPI
@@ -235,8 +236,9 @@ struct ab8500 {
enum ab8500_version version;
u8 chip_id;
- int (*write) (struct ab8500 *a8500, u16 addr, u8 data);
- int (*read) (struct ab8500 *a8500, u16 addr);
+ int (*write)(struct ab8500 *ab8500, u16 addr, u8 data);
+ int (*write_masked)(struct ab8500 *ab8500, u16 addr, u8 mask, u8 data);
+ int (*read)(struct ab8500 *ab8500, u16 addr);
unsigned long tx_buf[4];
unsigned long rx_buf[4];