aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMattias Wallin <mattias.wallin@stericsson.com>2010-09-10 11:47:56 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2010-10-28 18:29:19 -0400
commit47c1697508f2ec9f6b31ce6c825fe1017871dea6 (patch)
treee22afa146c3232802abf482caa167e0e2444093b /drivers/mfd
parentf4ebcab36088d45a5e8889e9b63d77e01c808076 (diff)
mfd: Align ab8500 with the abx500 interface
This patch makes the ab8500 mixed signal chip expose the same interface for register access as the ab3100, ab3550 and ab5500 chip. The ab8500_read() and ab8500_write() is removed and replaced with abx500_get_register_interruptible() and abx500_set_register_interruptible(). Signed-off-by: Mattias Wallin <mattias.wallin@stericsson.com> Acked-by: Linus Walleij <linus.walleij@stericsson.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig4
-rw-r--r--drivers/mfd/ab8500-core.c281
2 files changed, 168 insertions, 117 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8a463e6c22a0..ec0af47a9058 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -434,7 +434,7 @@ config PCF50633_GPIO
434 434
435config ABX500_CORE 435config ABX500_CORE
436 bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions" 436 bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
437 default y if ARCH_U300 437 default y if ARCH_U300 || ARCH_U8500
438 help 438 help
439 Say yes here if you have the ABX500 Mixed Signal IC family 439 Say yes here if you have the ABX500 Mixed Signal IC family
440 chips. This core driver expose register access functions. 440 chips. This core driver expose register access functions.
@@ -475,7 +475,7 @@ config EZX_PCAP
475 475
476config AB8500_CORE 476config AB8500_CORE
477 bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" 477 bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
478 depends on SPI=y && GENERIC_HARDIRQS 478 depends on SPI=y && GENERIC_HARDIRQS && ABX500_CORE
479 select MFD_CORE 479 select MFD_CORE
480 help 480 help
481 Select this option to enable access to AB8500 power management 481 Select this option to enable access to AB8500 power management
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index b8c4b80e4c43..373783146b5e 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -4,6 +4,7 @@
4 * License Terms: GNU General Public License v2 4 * License Terms: GNU General Public License v2
5 * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> 5 * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
6 * Author: Rabin Vincent <rabin.vincent@stericsson.com> 6 * Author: Rabin Vincent <rabin.vincent@stericsson.com>
7 * Changes: Mattias Wallin <mattias.wallin@stericsson.com>
7 */ 8 */
8 9
9#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -15,6 +16,7 @@
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/mfd/core.h> 18#include <linux/mfd/core.h>
19#include <linux/mfd/abx500.h>
18#include <linux/mfd/ab8500.h> 20#include <linux/mfd/ab8500.h>
19#include <linux/regulator/ab8500.h> 21#include <linux/regulator/ab8500.h>
20 22
@@ -22,71 +24,71 @@
22 * Interrupt register offsets 24 * Interrupt register offsets
23 * Bank : 0x0E 25 * Bank : 0x0E
24 */ 26 */
25#define AB8500_IT_SOURCE1_REG 0x0E00 27#define AB8500_IT_SOURCE1_REG 0x00
26#define AB8500_IT_SOURCE2_REG 0x0E01 28#define AB8500_IT_SOURCE2_REG 0x01
27#define AB8500_IT_SOURCE3_REG 0x0E02 29#define AB8500_IT_SOURCE3_REG 0x02
28#define AB8500_IT_SOURCE4_REG 0x0E03 30#define AB8500_IT_SOURCE4_REG 0x03
29#define AB8500_IT_SOURCE5_REG 0x0E04 31#define AB8500_IT_SOURCE5_REG 0x04
30#define AB8500_IT_SOURCE6_REG 0x0E05 32#define AB8500_IT_SOURCE6_REG 0x05
31#define AB8500_IT_SOURCE7_REG 0x0E06 33#define AB8500_IT_SOURCE7_REG 0x06
32#define AB8500_IT_SOURCE8_REG 0x0E07 34#define AB8500_IT_SOURCE8_REG 0x07
33#define AB8500_IT_SOURCE19_REG 0x0E12 35#define AB8500_IT_SOURCE19_REG 0x12
34#define AB8500_IT_SOURCE20_REG 0x0E13 36#define AB8500_IT_SOURCE20_REG 0x13
35#define AB8500_IT_SOURCE21_REG 0x0E14 37#define AB8500_IT_SOURCE21_REG 0x14
36#define AB8500_IT_SOURCE22_REG 0x0E15 38#define AB8500_IT_SOURCE22_REG 0x15
37#define AB8500_IT_SOURCE23_REG 0x0E16 39#define AB8500_IT_SOURCE23_REG 0x16
38#define AB8500_IT_SOURCE24_REG 0x0E17 40#define AB8500_IT_SOURCE24_REG 0x17
39 41
40/* 42/*
41 * latch registers 43 * latch registers
42 */ 44 */
43#define AB8500_IT_LATCH1_REG 0x0E20 45#define AB8500_IT_LATCH1_REG 0x20
44#define AB8500_IT_LATCH2_REG 0x0E21 46#define AB8500_IT_LATCH2_REG 0x21
45#define AB8500_IT_LATCH3_REG 0x0E22 47#define AB8500_IT_LATCH3_REG 0x22
46#define AB8500_IT_LATCH4_REG 0x0E23 48#define AB8500_IT_LATCH4_REG 0x23
47#define AB8500_IT_LATCH5_REG 0x0E24 49#define AB8500_IT_LATCH5_REG 0x24
48#define AB8500_IT_LATCH6_REG 0x0E25 50#define AB8500_IT_LATCH6_REG 0x25
49#define AB8500_IT_LATCH7_REG 0x0E26 51#define AB8500_IT_LATCH7_REG 0x26
50#define AB8500_IT_LATCH8_REG 0x0E27 52#define AB8500_IT_LATCH8_REG 0x27
51#define AB8500_IT_LATCH9_REG 0x0E28 53#define AB8500_IT_LATCH9_REG 0x28
52#define AB8500_IT_LATCH10_REG 0x0E29 54#define AB8500_IT_LATCH10_REG 0x29
53#define AB8500_IT_LATCH19_REG 0x0E32 55#define AB8500_IT_LATCH19_REG 0x32
54#define AB8500_IT_LATCH20_REG 0x0E33 56#define AB8500_IT_LATCH20_REG 0x33
55#define AB8500_IT_LATCH21_REG 0x0E34 57#define AB8500_IT_LATCH21_REG 0x34
56#define AB8500_IT_LATCH22_REG 0x0E35 58#define AB8500_IT_LATCH22_REG 0x35
57#define AB8500_IT_LATCH23_REG 0x0E36 59#define AB8500_IT_LATCH23_REG 0x36
58#define AB8500_IT_LATCH24_REG 0x0E37 60#define AB8500_IT_LATCH24_REG 0x37
59 61
60/* 62/*
61 * mask registers 63 * mask registers
62 */ 64 */
63 65
64#define AB8500_IT_MASK1_REG 0x0E40 66#define AB8500_IT_MASK1_REG 0x40
65#define AB8500_IT_MASK2_REG 0x0E41 67#define AB8500_IT_MASK2_REG 0x41
66#define AB8500_IT_MASK3_REG 0x0E42 68#define AB8500_IT_MASK3_REG 0x42
67#define AB8500_IT_MASK4_REG 0x0E43 69#define AB8500_IT_MASK4_REG 0x43
68#define AB8500_IT_MASK5_REG 0x0E44 70#define AB8500_IT_MASK5_REG 0x44
69#define AB8500_IT_MASK6_REG 0x0E45 71#define AB8500_IT_MASK6_REG 0x45
70#define AB8500_IT_MASK7_REG 0x0E46 72#define AB8500_IT_MASK7_REG 0x46
71#define AB8500_IT_MASK8_REG 0x0E47 73#define AB8500_IT_MASK8_REG 0x47
72#define AB8500_IT_MASK9_REG 0x0E48 74#define AB8500_IT_MASK9_REG 0x48
73#define AB8500_IT_MASK10_REG 0x0E49 75#define AB8500_IT_MASK10_REG 0x49
74#define AB8500_IT_MASK11_REG 0x0E4A 76#define AB8500_IT_MASK11_REG 0x4A
75#define AB8500_IT_MASK12_REG 0x0E4B 77#define AB8500_IT_MASK12_REG 0x4B
76#define AB8500_IT_MASK13_REG 0x0E4C 78#define AB8500_IT_MASK13_REG 0x4C
77#define AB8500_IT_MASK14_REG 0x0E4D 79#define AB8500_IT_MASK14_REG 0x4D
78#define AB8500_IT_MASK15_REG 0x0E4E 80#define AB8500_IT_MASK15_REG 0x4E
79#define AB8500_IT_MASK16_REG 0x0E4F 81#define AB8500_IT_MASK16_REG 0x4F
80#define AB8500_IT_MASK17_REG 0x0E50 82#define AB8500_IT_MASK17_REG 0x50
81#define AB8500_IT_MASK18_REG 0x0E51 83#define AB8500_IT_MASK18_REG 0x51
82#define AB8500_IT_MASK19_REG 0x0E52 84#define AB8500_IT_MASK19_REG 0x52
83#define AB8500_IT_MASK20_REG 0x0E53 85#define AB8500_IT_MASK20_REG 0x53
84#define AB8500_IT_MASK21_REG 0x0E54 86#define AB8500_IT_MASK21_REG 0x54
85#define AB8500_IT_MASK22_REG 0x0E55 87#define AB8500_IT_MASK22_REG 0x55
86#define AB8500_IT_MASK23_REG 0x0E56 88#define AB8500_IT_MASK23_REG 0x56
87#define AB8500_IT_MASK24_REG 0x0E57 89#define AB8500_IT_MASK24_REG 0x57
88 90
89#define AB8500_REV_REG 0x1080 91#define AB8500_REV_REG 0x80
90 92
91/* 93/*
92 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt 94 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
@@ -99,96 +101,132 @@ static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = {
99 0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21, 101 0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21,
100}; 102};
101 103
102static int __ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data) 104static int ab8500_get_chip_id(struct device *dev)
105{
106 struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
107 return (int)ab8500->chip_id;
108}
109
110static int set_register_interruptible(struct ab8500 *ab8500, u8 bank,
111 u8 reg, u8 data)
103{ 112{
104 int ret; 113 int ret;
114 /*
115 * Put the u8 bank and u8 register together into a an u16.
116 * The bank on higher 8 bits and register in lower 8 bits.
117 * */
118 u16 addr = ((u16)bank) << 8 | reg;
105 119
106 dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data); 120 dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data);
107 121
122 ret = mutex_lock_interruptible(&ab8500->lock);
123 if (ret)
124 return ret;
125
108 ret = ab8500->write(ab8500, addr, data); 126 ret = ab8500->write(ab8500, addr, data);
109 if (ret < 0) 127 if (ret < 0)
110 dev_err(ab8500->dev, "failed to write reg %#x: %d\n", 128 dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
111 addr, ret); 129 addr, ret);
130 mutex_unlock(&ab8500->lock);
112 131
113 return ret; 132 return ret;
114} 133}
115 134
116/** 135static int ab8500_set_register(struct device *dev, u8 bank,
117 * ab8500_write() - write an AB8500 register 136 u8 reg, u8 value)
118 * @ab8500: device to write to
119 * @addr: address of the register
120 * @data: value to write
121 */
122int ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data)
123{ 137{
124 int ret; 138 struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
125
126 mutex_lock(&ab8500->lock);
127 ret = __ab8500_write(ab8500, addr, data);
128 mutex_unlock(&ab8500->lock);
129 139
130 return ret; 140 return set_register_interruptible(ab8500, bank, reg, value);
131} 141}
132EXPORT_SYMBOL_GPL(ab8500_write);
133 142
134static int __ab8500_read(struct ab8500 *ab8500, u16 addr) 143static int get_register_interruptible(struct ab8500 *ab8500, u8 bank,
144 u8 reg, u8 *value)
135{ 145{
136 int ret; 146 int ret;
147 /* put the u8 bank and u8 reg together into a an u16.
148 * bank on higher 8 bits and reg in lower */
149 u16 addr = ((u16)bank) << 8 | reg;
150
151 ret = mutex_lock_interruptible(&ab8500->lock);
152 if (ret)
153 return ret;
137 154
138 ret = ab8500->read(ab8500, addr); 155 ret = ab8500->read(ab8500, addr);
139 if (ret < 0) 156 if (ret < 0)
140 dev_err(ab8500->dev, "failed to read reg %#x: %d\n", 157 dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
141 addr, ret); 158 addr, ret);
159 else
160 *value = ret;
142 161
162 mutex_unlock(&ab8500->lock);
143 dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret); 163 dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret);
144 164
145 return ret; 165 return ret;
146} 166}
147 167
148/** 168static int ab8500_get_register(struct device *dev, u8 bank,
149 * ab8500_read() - read an AB8500 register 169 u8 reg, u8 *value)
150 * @ab8500: device to read from
151 * @addr: address of the register
152 */
153int ab8500_read(struct ab8500 *ab8500, u16 addr)
154{ 170{
155 int ret; 171 struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
156
157 mutex_lock(&ab8500->lock);
158 ret = __ab8500_read(ab8500, addr);
159 mutex_unlock(&ab8500->lock);
160 172
161 return ret; 173 return get_register_interruptible(ab8500, bank, reg, value);
162} 174}
163EXPORT_SYMBOL_GPL(ab8500_read); 175
164 176static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank,
165/** 177 u8 reg, u8 bitmask, u8 bitvalues)
166 * ab8500_set_bits() - set a bitfield in an AB8500 register
167 * @ab8500: device to read from
168 * @addr: address of the register
169 * @mask: mask of the bitfield to modify
170 * @data: value to set to the bitfield
171 */
172int ab8500_set_bits(struct ab8500 *ab8500, u16 addr, u8 mask, u8 data)
173{ 178{
174 int ret; 179 int ret;
180 u8 data;
181 /* put the u8 bank and u8 reg together into a an u16.
182 * bank on higher 8 bits and reg in lower */
183 u16 addr = ((u16)bank) << 8 | reg;
175 184
176 mutex_lock(&ab8500->lock); 185 ret = mutex_lock_interruptible(&ab8500->lock);
186 if (ret)
187 return ret;
177 188
178 ret = __ab8500_read(ab8500, addr); 189 ret = ab8500->read(ab8500, addr);
179 if (ret < 0) 190 if (ret < 0) {
191 dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
192 addr, ret);
180 goto out; 193 goto out;
194 }
181 195
182 ret &= ~mask; 196 data = (u8)ret;
183 ret |= data; 197 data = (~bitmask & data) | (bitmask & bitvalues);
184 198
185 ret = __ab8500_write(ab8500, addr, ret); 199 ret = ab8500->write(ab8500, addr, data);
200 if (ret < 0)
201 dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
202 addr, ret);
186 203
204 dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr, data);
187out: 205out:
188 mutex_unlock(&ab8500->lock); 206 mutex_unlock(&ab8500->lock);
189 return ret; 207 return ret;
190} 208}
191EXPORT_SYMBOL_GPL(ab8500_set_bits); 209
210static int ab8500_mask_and_set_register(struct device *dev,
211 u8 bank, u8 reg, u8 bitmask, u8 bitvalues)
212{
213 struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
214
215 return mask_and_set_register_interruptible(ab8500, bank, reg,
216 bitmask, bitvalues);
217
218}
219
220static struct abx500_ops ab8500_ops = {
221 .get_chip_id = ab8500_get_chip_id,
222 .get_register = ab8500_get_register,
223 .set_register = ab8500_set_register,
224 .get_register_page = NULL,
225 .set_register_page = NULL,
226 .mask_and_set_register = ab8500_mask_and_set_register,
227 .event_registers_startup_state_get = NULL,
228 .startup_irq_enabled = NULL,
229};
192 230
193static void ab8500_irq_lock(unsigned int irq) 231static void ab8500_irq_lock(unsigned int irq)
194{ 232{
@@ -213,7 +251,7 @@ static void ab8500_irq_sync_unlock(unsigned int irq)
213 ab8500->oldmask[i] = new; 251 ab8500->oldmask[i] = new;
214 252
215 reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; 253 reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i];
216 ab8500_write(ab8500, reg, new); 254 set_register_interruptible(ab8500, AB8500_INTERRUPT, reg, new);
217 } 255 }
218 256
219 mutex_unlock(&ab8500->irq_lock); 257 mutex_unlock(&ab8500->irq_lock);
@@ -257,9 +295,11 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
257 for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { 295 for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) {
258 int regoffset = ab8500_irq_regoffset[i]; 296 int regoffset = ab8500_irq_regoffset[i];
259 int status; 297 int status;
298 u8 value;
260 299
261 status = ab8500_read(ab8500, AB8500_IT_LATCH1_REG + regoffset); 300 status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
262 if (status <= 0) 301 AB8500_IT_LATCH1_REG + regoffset, &value);
302 if (status < 0 || value == 0)
263 continue; 303 continue;
264 304
265 do { 305 do {
@@ -267,8 +307,8 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
267 int line = i * 8 + bit; 307 int line = i * 8 + bit;
268 308
269 handle_nested_irq(ab8500->irq_base + line); 309 handle_nested_irq(ab8500->irq_base + line);
270 status &= ~(1 << bit); 310 value &= ~(1 << bit);
271 } while (status); 311 } while (value);
272 } 312 }
273 313
274 return IRQ_HANDLED; 314 return IRQ_HANDLED;
@@ -381,6 +421,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
381 struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); 421 struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev);
382 int ret; 422 int ret;
383 int i; 423 int i;
424 u8 value;
384 425
385 if (plat) 426 if (plat)
386 ab8500->irq_base = plat->irq_base; 427 ab8500->irq_base = plat->irq_base;
@@ -388,7 +429,8 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
388 mutex_init(&ab8500->lock); 429 mutex_init(&ab8500->lock);
389 mutex_init(&ab8500->irq_lock); 430 mutex_init(&ab8500->irq_lock);
390 431
391 ret = ab8500_read(ab8500, AB8500_REV_REG); 432 ret = get_register_interruptible(ab8500, AB8500_MISC,
433 AB8500_REV_REG, &value);
392 if (ret < 0) 434 if (ret < 0)
393 return ret; 435 return ret;
394 436
@@ -397,28 +439,37 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
397 * 0x10 - Cut 1.0 439 * 0x10 - Cut 1.0
398 * 0x11 - Cut 1.1 440 * 0x11 - Cut 1.1
399 */ 441 */
400 if (ret == 0x0 || ret == 0x10 || ret == 0x11) { 442 if (value == 0x0 || value == 0x10 || value == 0x11) {
401 ab8500->revision = ret; 443 ab8500->revision = value;
402 dev_info(ab8500->dev, "detected chip, revision: %#x\n", ret); 444 dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
403 } else { 445 } else {
404 dev_err(ab8500->dev, "unknown chip, revision: %#x\n", ret); 446 dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value);
405 return -EINVAL; 447 return -EINVAL;
406 } 448 }
449 ab8500->chip_id = value;
407 450
408 if (plat && plat->init) 451 if (plat && plat->init)
409 plat->init(ab8500); 452 plat->init(ab8500);
410 453
411 /* Clear and mask all interrupts */ 454 /* Clear and mask all interrupts */
412 for (i = 0; i < 10; i++) { 455 for (i = 0; i < 10; i++) {
413 ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i); 456 get_register_interruptible(ab8500, AB8500_INTERRUPT,
414 ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff); 457 AB8500_IT_LATCH1_REG + i, &value);
458 set_register_interruptible(ab8500, AB8500_INTERRUPT,
459 AB8500_IT_MASK1_REG + i, 0xff);
415 } 460 }
416 461
417 for (i = 18; i < 24; i++) { 462 for (i = 18; i < 24; i++) {
418 ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i); 463 get_register_interruptible(ab8500, AB8500_INTERRUPT,
419 ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff); 464 AB8500_IT_LATCH1_REG + i, &value);
465 set_register_interruptible(ab8500, AB8500_INTERRUPT,
466 AB8500_IT_MASK1_REG + i, 0xff);
420 } 467 }
421 468
469 ret = abx500_register_ops(ab8500->dev, &ab8500_ops);
470 if (ret)
471 return ret;
472
422 for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) 473 for (i = 0; i < AB8500_NUM_IRQ_REGS; i++)
423 ab8500->mask[i] = ab8500->oldmask[i] = 0xff; 474 ab8500->mask[i] = ab8500->oldmask[i] = 0xff;
424 475