diff options
author | Mattias Nilsson <mattias.i.nilsson@stericsson.com> | 2012-03-08 08:02:20 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-03-16 14:45:33 -0400 |
commit | bc628fd19d2d1d053b88fa225bb599be026c048b (patch) | |
tree | d314ae4ddcb2804f68179c98a17581b33356fe96 /drivers/mfd | |
parent | 3c3e489831b601e566f6bc47e711f5847fb93dff (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.c | 37 | ||||
-rw-r--r-- | drivers/mfd/ab8500-i2c.c | 15 |
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); | ||
227 | out: | 236 | out: |
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 | ||
16 | static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) | 16 | static 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 | ||
26 | static 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 | |||
26 | static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr) | 38 | static 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 | ||