diff options
author | Mattias Nilsson <mattias.i.nilsson@stericsson.com> | 2012-03-05 16:52:14 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@linaro.org> | 2012-04-06 09:39:36 +0200 |
commit | 7b3b0c2093f8c1ef3e1e6c965f4c79e33a883f42 (patch) | |
tree | 9670b3d078fa8cbb94b8b6041a685139e4b4b610 | |
parent | a8fb4849d086e1b4c3185dc9e8cd042c5ed66298 (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.c | 37 | ||||
-rw-r--r-- | drivers/mfd/ab8500-i2c.c | 13 | ||||
-rw-r--r-- | include/linux/mfd/abx500/ab8500.h | 6 |
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]; |