diff options
Diffstat (limited to 'drivers/mfd/wm8994-core.c')
-rw-r--r-- | drivers/mfd/wm8994-core.c | 77 |
1 files changed, 56 insertions, 21 deletions
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index f4016a075fd6..e198d40292e7 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -40,10 +40,8 @@ static int wm8994_read(struct wm8994 *wm8994, unsigned short reg, | |||
40 | return ret; | 40 | return ret; |
41 | 41 | ||
42 | for (i = 0; i < bytes / 2; i++) { | 42 | for (i = 0; i < bytes / 2; i++) { |
43 | buf[i] = be16_to_cpu(buf[i]); | ||
44 | |||
45 | dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n", | 43 | dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n", |
46 | buf[i], reg + i, reg + i); | 44 | be16_to_cpu(buf[i]), reg + i, reg + i); |
47 | } | 45 | } |
48 | 46 | ||
49 | return 0; | 47 | return 0; |
@@ -69,7 +67,7 @@ int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg) | |||
69 | if (ret < 0) | 67 | if (ret < 0) |
70 | return ret; | 68 | return ret; |
71 | else | 69 | else |
72 | return val; | 70 | return be16_to_cpu(val); |
73 | } | 71 | } |
74 | EXPORT_SYMBOL_GPL(wm8994_reg_read); | 72 | EXPORT_SYMBOL_GPL(wm8994_reg_read); |
75 | 73 | ||
@@ -79,7 +77,7 @@ EXPORT_SYMBOL_GPL(wm8994_reg_read); | |||
79 | * @wm8994: Device to read from | 77 | * @wm8994: Device to read from |
80 | * @reg: First register | 78 | * @reg: First register |
81 | * @count: Number of registers | 79 | * @count: Number of registers |
82 | * @buf: Buffer to fill. | 80 | * @buf: Buffer to fill. The data will be returned big endian. |
83 | */ | 81 | */ |
84 | int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, | 82 | int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, |
85 | int count, u16 *buf) | 83 | int count, u16 *buf) |
@@ -97,9 +95,9 @@ int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, | |||
97 | EXPORT_SYMBOL_GPL(wm8994_bulk_read); | 95 | EXPORT_SYMBOL_GPL(wm8994_bulk_read); |
98 | 96 | ||
99 | static int wm8994_write(struct wm8994 *wm8994, unsigned short reg, | 97 | static int wm8994_write(struct wm8994 *wm8994, unsigned short reg, |
100 | int bytes, void *src) | 98 | int bytes, const void *src) |
101 | { | 99 | { |
102 | u16 *buf = src; | 100 | const u16 *buf = src; |
103 | int i; | 101 | int i; |
104 | 102 | ||
105 | BUG_ON(bytes % 2); | 103 | BUG_ON(bytes % 2); |
@@ -107,9 +105,7 @@ static int wm8994_write(struct wm8994 *wm8994, unsigned short reg, | |||
107 | 105 | ||
108 | for (i = 0; i < bytes / 2; i++) { | 106 | for (i = 0; i < bytes / 2; i++) { |
109 | dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n", | 107 | dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n", |
110 | buf[i], reg + i, reg + i); | 108 | be16_to_cpu(buf[i]), reg + i, reg + i); |
111 | |||
112 | buf[i] = cpu_to_be16(buf[i]); | ||
113 | } | 109 | } |
114 | 110 | ||
115 | return wm8994->write_dev(wm8994, reg, bytes, src); | 111 | return wm8994->write_dev(wm8994, reg, bytes, src); |
@@ -127,6 +123,8 @@ int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, | |||
127 | { | 123 | { |
128 | int ret; | 124 | int ret; |
129 | 125 | ||
126 | val = cpu_to_be16(val); | ||
127 | |||
130 | mutex_lock(&wm8994->io_lock); | 128 | mutex_lock(&wm8994->io_lock); |
131 | 129 | ||
132 | ret = wm8994_write(wm8994, reg, 2, &val); | 130 | ret = wm8994_write(wm8994, reg, 2, &val); |
@@ -138,6 +136,29 @@ int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, | |||
138 | EXPORT_SYMBOL_GPL(wm8994_reg_write); | 136 | EXPORT_SYMBOL_GPL(wm8994_reg_write); |
139 | 137 | ||
140 | /** | 138 | /** |
139 | * wm8994_bulk_write: Write multiple WM8994 registers | ||
140 | * | ||
141 | * @wm8994: Device to write to | ||
142 | * @reg: First register | ||
143 | * @count: Number of registers | ||
144 | * @buf: Buffer to write from. Data must be big-endian formatted. | ||
145 | */ | ||
146 | int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg, | ||
147 | int count, const u16 *buf) | ||
148 | { | ||
149 | int ret; | ||
150 | |||
151 | mutex_lock(&wm8994->io_lock); | ||
152 | |||
153 | ret = wm8994_write(wm8994, reg, count * 2, buf); | ||
154 | |||
155 | mutex_unlock(&wm8994->io_lock); | ||
156 | |||
157 | return ret; | ||
158 | } | ||
159 | EXPORT_SYMBOL_GPL(wm8994_bulk_write); | ||
160 | |||
161 | /** | ||
141 | * wm8994_set_bits: Set the value of a bitfield in a WM8994 register | 162 | * wm8994_set_bits: Set the value of a bitfield in a WM8994 register |
142 | * | 163 | * |
143 | * @wm8994: Device to write to. | 164 | * @wm8994: Device to write to. |
@@ -157,9 +178,13 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, | |||
157 | if (ret < 0) | 178 | if (ret < 0) |
158 | goto out; | 179 | goto out; |
159 | 180 | ||
181 | r = be16_to_cpu(r); | ||
182 | |||
160 | r &= ~mask; | 183 | r &= ~mask; |
161 | r |= val; | 184 | r |= val; |
162 | 185 | ||
186 | r = cpu_to_be16(r); | ||
187 | |||
163 | ret = wm8994_write(wm8994, reg, 2, &r); | 188 | ret = wm8994_write(wm8994, reg, 2, &r); |
164 | 189 | ||
165 | out: | 190 | out: |
@@ -271,6 +296,11 @@ static int wm8994_suspend(struct device *dev) | |||
271 | if (ret < 0) | 296 | if (ret < 0) |
272 | dev_err(dev, "Failed to save LDO registers: %d\n", ret); | 297 | dev_err(dev, "Failed to save LDO registers: %d\n", ret); |
273 | 298 | ||
299 | /* Explicitly put the device into reset in case regulators | ||
300 | * don't get disabled in order to ensure consistent restart. | ||
301 | */ | ||
302 | wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, 0x8994); | ||
303 | |||
274 | wm8994->suspended = true; | 304 | wm8994->suspended = true; |
275 | 305 | ||
276 | ret = regulator_bulk_disable(wm8994->num_supplies, | 306 | ret = regulator_bulk_disable(wm8994->num_supplies, |
@@ -552,25 +582,29 @@ static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg, | |||
552 | return 0; | 582 | return 0; |
553 | } | 583 | } |
554 | 584 | ||
555 | /* Currently we allocate the write buffer on the stack; this is OK for | ||
556 | * small writes - if we need to do large writes this will need to be | ||
557 | * revised. | ||
558 | */ | ||
559 | static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg, | 585 | static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg, |
560 | int bytes, void *src) | 586 | int bytes, const void *src) |
561 | { | 587 | { |
562 | struct i2c_client *i2c = wm8994->control_data; | 588 | struct i2c_client *i2c = wm8994->control_data; |
563 | unsigned char msg[bytes + 2]; | 589 | struct i2c_msg xfer[2]; |
564 | int ret; | 590 | int ret; |
565 | 591 | ||
566 | reg = cpu_to_be16(reg); | 592 | reg = cpu_to_be16(reg); |
567 | memcpy(&msg[0], ®, 2); | ||
568 | memcpy(&msg[2], src, bytes); | ||
569 | 593 | ||
570 | ret = i2c_master_send(i2c, msg, bytes + 2); | 594 | xfer[0].addr = i2c->addr; |
595 | xfer[0].flags = 0; | ||
596 | xfer[0].len = 2; | ||
597 | xfer[0].buf = (char *)® | ||
598 | |||
599 | xfer[1].addr = i2c->addr; | ||
600 | xfer[1].flags = I2C_M_NOSTART; | ||
601 | xfer[1].len = bytes; | ||
602 | xfer[1].buf = (char *)src; | ||
603 | |||
604 | ret = i2c_transfer(i2c->adapter, xfer, 2); | ||
571 | if (ret < 0) | 605 | if (ret < 0) |
572 | return ret; | 606 | return ret; |
573 | if (ret < bytes + 2) | 607 | if (ret != 2) |
574 | return -EIO; | 608 | return -EIO; |
575 | 609 | ||
576 | return 0; | 610 | return 0; |
@@ -612,7 +646,8 @@ static const struct i2c_device_id wm8994_i2c_id[] = { | |||
612 | }; | 646 | }; |
613 | MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); | 647 | MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); |
614 | 648 | ||
615 | UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, NULL); | 649 | static UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, |
650 | NULL); | ||
616 | 651 | ||
617 | static struct i2c_driver wm8994_i2c_driver = { | 652 | static struct i2c_driver wm8994_i2c_driver = { |
618 | .driver = { | 653 | .driver = { |