diff options
| -rw-r--r-- | drivers/mfd/ab8500-core.c | 37 | ||||
| -rw-r--r-- | drivers/mfd/ab8500-i2c.c | 15 | ||||
| -rw-r--r-- | include/linux/mfd/abx500/ab8500.h | 6 |
3 files changed, 41 insertions, 17 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 | ||
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h index 78ed95bb47c3..3b551a1783ac 100644 --- a/include/linux/mfd/abx500/ab8500.h +++ b/include/linux/mfd/abx500/ab8500.h | |||
| @@ -217,6 +217,7 @@ enum ab8500_version { | |||
| 217 | * @version: chip version id (e.g. ab8500 or ab9540) | 217 | * @version: chip version id (e.g. ab8500 or ab9540) |
| 218 | * @chip_id: chip revision id | 218 | * @chip_id: chip revision id |
| 219 | * @write: register write | 219 | * @write: register write |
| 220 | * @write_masked: masked register write | ||
| 220 | * @read: register read | 221 | * @read: register read |
| 221 | * @rx_buf: rx buf for SPI | 222 | * @rx_buf: rx buf for SPI |
| 222 | * @tx_buf: tx buf for SPI | 223 | * @tx_buf: tx buf for SPI |
| @@ -236,8 +237,9 @@ struct ab8500 { | |||
| 236 | enum ab8500_version version; | 237 | enum ab8500_version version; |
| 237 | u8 chip_id; | 238 | u8 chip_id; |
| 238 | 239 | ||
| 239 | int (*write) (struct ab8500 *a8500, u16 addr, u8 data); | 240 | int (*write)(struct ab8500 *ab8500, u16 addr, u8 data); |
| 240 | int (*read) (struct ab8500 *a8500, u16 addr); | 241 | int (*write_masked)(struct ab8500 *ab8500, u16 addr, u8 mask, u8 data); |
| 242 | int (*read)(struct ab8500 *ab8500, u16 addr); | ||
| 241 | 243 | ||
| 242 | unsigned long tx_buf[4]; | 244 | unsigned long tx_buf[4]; |
| 243 | unsigned long rx_buf[4]; | 245 | unsigned long rx_buf[4]; |
