aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMattias Nilsson <mattias.i.nilsson@stericsson.com>2012-03-08 08:02:20 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2012-03-16 14:45:33 -0400
commitbc628fd19d2d1d053b88fa225bb599be026c048b (patch)
treed314ae4ddcb2804f68179c98a17581b33356fe96 /drivers/mfd
parent3c3e489831b601e566f6bc47e711f5847fb93dff (diff)
mfd: Make use of the ab8500 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. Signed-off-by: Mattias Nilsson <mattias.i.nilsson@stericsson.com> Reviewed-by: Mattias Wallin <mattias.wallin@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/ab8500-core.c37
-rw-r--r--drivers/mfd/ab8500-i2c.c15
2 files changed, 37 insertions, 15 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index c637c8d2e7de..1f08704f7ae8 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -201,29 +201,38 @@ static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank,
201 u8 reg, u8 bitmask, u8 bitvalues) 201 u8 reg, u8 bitmask, u8 bitvalues)
202{ 202{
203 int ret; 203 int ret;
204 u8 data;
205 /* put the u8 bank and u8 reg together into a an u16. 204 /* put the u8 bank and u8 reg together into a an u16.
206 * bank on higher 8 bits and reg in lower */ 205 * bank on higher 8 bits and reg in lower */
207 u16 addr = ((u16)bank) << 8 | reg; 206 u16 addr = ((u16)bank) << 8 | reg;
208 207
209 mutex_lock(&ab8500->lock); 208 mutex_lock(&ab8500->lock);
210 209
211 ret = ab8500->read(ab8500, addr); 210 if (ab8500->write_masked == NULL) {
212 if (ret < 0) { 211 u8 data;
213 dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
214 addr, ret);
215 goto out;
216 }
217 212
218 data = (u8)ret; 213 ret = ab8500->read(ab8500, addr);
219 data = (~bitmask & data) | (bitmask & bitvalues); 214 if (ret < 0) {
215 dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
216 addr, ret);
217 goto out;
218 }
220 219
221 ret = ab8500->write(ab8500, addr, data); 220 data = (u8)ret;
222 if (ret < 0) 221 data = (~bitmask & data) | (bitmask & bitvalues);
223 dev_err(ab8500->dev, "failed to write reg %#x: %d\n", 222
224 addr, ret); 223 ret = ab8500->write(ab8500, addr, data);
224 if (ret < 0)
225 dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
226 addr, ret);
225 227
226 dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr, data); 228 dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr,
229 data);
230 goto out;
231 }
232 ret = ab8500->write_masked(ab8500, addr, bitmask, bitvalues);
233 if (ret < 0)
234 dev_err(ab8500->dev, "failed to modify reg %#x: %d\n", addr,
235 ret);
227out: 236out:
228 mutex_unlock(&ab8500->lock); 237 mutex_unlock(&ab8500->lock);
229 return ret; 238 return ret;
diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c
index 70a16ae856a2..b83045f102be 100644
--- a/drivers/mfd/ab8500-i2c.c
+++ b/drivers/mfd/ab8500-i2c.c
@@ -11,7 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/mfd/abx500/ab8500.h> 13#include <linux/mfd/abx500/ab8500.h>
14#include <linux/mfd/db8500-prcmu.h> 14#include <linux/mfd/dbx500-prcmu.h>
15 15
16static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) 16static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
17{ 17{
@@ -23,6 +23,18 @@ static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
23 return ret; 23 return ret;
24} 24}
25 25
26static int ab8500_i2c_write_masked(struct ab8500 *ab8500, u16 addr, u8 mask,
27 u8 data)
28{
29 int ret;
30
31 ret = prcmu_abb_write_masked((u8)(addr >> 8), (u8)(addr & 0xFF), &data,
32 &mask, 1);
33 if (ret < 0)
34 dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
35 return ret;
36}
37
26static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr) 38static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr)
27{ 39{
28 int ret; 40 int ret;
@@ -59,6 +71,7 @@ static int __devinit ab8500_i2c_probe(struct platform_device *plf)
59 71
60 ab8500->read = ab8500_i2c_read; 72 ab8500->read = ab8500_i2c_read;
61 ab8500->write = ab8500_i2c_write; 73 ab8500->write = ab8500_i2c_write;
74 ab8500->write_masked = ab8500_i2c_write_masked;
62 75
63 platform_set_drvdata(plf, ab8500); 76 platform_set_drvdata(plf, ab8500);
64 77