diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-21 00:16:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-21 00:16:27 -0400 |
commit | ae0645a451b02ad35c520b01177b70ebd59c91ab (patch) | |
tree | cd120ec609f8cad914f0b5b967d358d0d104d8bd | |
parent | f894d18380e7e7ff05f6622ccb75d2881922c6e9 (diff) | |
parent | 99cdb0c8c5e0e43652d25951a85bac82a1231591 (diff) |
Merge branch 'for-linus' of git://git.o-hand.com/linux-mfd
* 'for-linus' of git://git.o-hand.com/linux-mfd:
mfd: let asic3 use mem resource instead of bus_shift
mfd: remove DS1WM register definitions from asic3.h
mfd: add ASIC3_CONFIG_GPIO templates
mfd: fix the asic3 irq demux code
mfd: asic3 should depend on gpiolib
mfd: fix asic3 config array initialisation
mfd: move asic3 probe functions into __init section
mfd: Use uppercase only for asic3 macros and defines
mfd: use dev_* macros for asic3 debugging
mfd: New asic3 gpio configuration code
mfd: asic3 children platform data removal
mfd: asic3 gpiolib support
-rw-r--r-- | drivers/mfd/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mfd/asic3.c | 388 | ||||
-rw-r--r-- | include/linux/mfd/asic3.h | 185 |
3 files changed, 319 insertions, 256 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index ae96bd6242f2..260bade0a5ec 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -17,7 +17,7 @@ config MFD_SM501 | |||
17 | 17 | ||
18 | config MFD_ASIC3 | 18 | config MFD_ASIC3 |
19 | bool "Support for Compaq ASIC3" | 19 | bool "Support for Compaq ASIC3" |
20 | depends on GENERIC_HARDIRQS && ARM | 20 | depends on GENERIC_HARDIRQS && HAVE_GPIO_LIB && ARM |
21 | ---help--- | 21 | ---help--- |
22 | This driver supports the ASIC3 multifunction chip found on many | 22 | This driver supports the ASIC3 multifunction chip found on many |
23 | PDAs (mainly iPAQ and HTC based ones) | 23 | PDAs (mainly iPAQ and HTC based ones) |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index ef8a492766a7..3b870e7fb3e1 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * Copyright 2001 Compaq Computer Corporation. | 10 | * Copyright 2001 Compaq Computer Corporation. |
11 | * Copyright 2004-2005 Phil Blundell | 11 | * Copyright 2004-2005 Phil Blundell |
12 | * Copyright 2007 OpenedHand Ltd. | 12 | * Copyright 2007-2008 OpenedHand Ltd. |
13 | * | 13 | * |
14 | * Authors: Phil Blundell <pb@handhelds.org>, | 14 | * Authors: Phil Blundell <pb@handhelds.org>, |
15 | * Samuel Ortiz <sameo@openedhand.com> | 15 | * Samuel Ortiz <sameo@openedhand.com> |
@@ -19,12 +19,26 @@ | |||
19 | #include <linux/version.h> | 19 | #include <linux/version.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/gpio.h> | ||
22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
23 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
24 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
25 | 26 | ||
26 | #include <linux/mfd/asic3.h> | 27 | #include <linux/mfd/asic3.h> |
27 | 28 | ||
29 | struct asic3 { | ||
30 | void __iomem *mapping; | ||
31 | unsigned int bus_shift; | ||
32 | unsigned int irq_nr; | ||
33 | unsigned int irq_base; | ||
34 | spinlock_t lock; | ||
35 | u16 irq_bothedge[4]; | ||
36 | struct gpio_chip gpio; | ||
37 | struct device *dev; | ||
38 | }; | ||
39 | |||
40 | static int asic3_gpio_get(struct gpio_chip *chip, unsigned offset); | ||
41 | |||
28 | static inline void asic3_write_register(struct asic3 *asic, | 42 | static inline void asic3_write_register(struct asic3 *asic, |
29 | unsigned int reg, u32 value) | 43 | unsigned int reg, u32 value) |
30 | { | 44 | { |
@@ -41,8 +55,8 @@ static inline u32 asic3_read_register(struct asic3 *asic, | |||
41 | 55 | ||
42 | /* IRQs */ | 56 | /* IRQs */ |
43 | #define MAX_ASIC_ISR_LOOPS 20 | 57 | #define MAX_ASIC_ISR_LOOPS 20 |
44 | #define ASIC3_GPIO_Base_INCR \ | 58 | #define ASIC3_GPIO_BASE_INCR \ |
45 | (ASIC3_GPIO_B_Base - ASIC3_GPIO_A_Base) | 59 | (ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE) |
46 | 60 | ||
47 | static void asic3_irq_flip_edge(struct asic3 *asic, | 61 | static void asic3_irq_flip_edge(struct asic3 *asic, |
48 | u32 base, int bit) | 62 | u32 base, int bit) |
@@ -52,10 +66,10 @@ static void asic3_irq_flip_edge(struct asic3 *asic, | |||
52 | 66 | ||
53 | spin_lock_irqsave(&asic->lock, flags); | 67 | spin_lock_irqsave(&asic->lock, flags); |
54 | edge = asic3_read_register(asic, | 68 | edge = asic3_read_register(asic, |
55 | base + ASIC3_GPIO_EdgeTrigger); | 69 | base + ASIC3_GPIO_EDGE_TRIGGER); |
56 | edge ^= bit; | 70 | edge ^= bit; |
57 | asic3_write_register(asic, | 71 | asic3_write_register(asic, |
58 | base + ASIC3_GPIO_EdgeTrigger, edge); | 72 | base + ASIC3_GPIO_EDGE_TRIGGER, edge); |
59 | spin_unlock_irqrestore(&asic->lock, flags); | 73 | spin_unlock_irqrestore(&asic->lock, flags); |
60 | } | 74 | } |
61 | 75 | ||
@@ -75,7 +89,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
75 | 89 | ||
76 | spin_lock_irqsave(&asic->lock, flags); | 90 | spin_lock_irqsave(&asic->lock, flags); |
77 | status = asic3_read_register(asic, | 91 | status = asic3_read_register(asic, |
78 | ASIC3_OFFSET(INTR, PIntStat)); | 92 | ASIC3_OFFSET(INTR, P_INT_STAT)); |
79 | spin_unlock_irqrestore(&asic->lock, flags); | 93 | spin_unlock_irqrestore(&asic->lock, flags); |
80 | 94 | ||
81 | /* Check all ten register bits */ | 95 | /* Check all ten register bits */ |
@@ -87,17 +101,17 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
87 | if (status & (1 << bank)) { | 101 | if (status & (1 << bank)) { |
88 | unsigned long base, istat; | 102 | unsigned long base, istat; |
89 | 103 | ||
90 | base = ASIC3_GPIO_A_Base | 104 | base = ASIC3_GPIO_A_BASE |
91 | + bank * ASIC3_GPIO_Base_INCR; | 105 | + bank * ASIC3_GPIO_BASE_INCR; |
92 | 106 | ||
93 | spin_lock_irqsave(&asic->lock, flags); | 107 | spin_lock_irqsave(&asic->lock, flags); |
94 | istat = asic3_read_register(asic, | 108 | istat = asic3_read_register(asic, |
95 | base + | 109 | base + |
96 | ASIC3_GPIO_IntStatus); | 110 | ASIC3_GPIO_INT_STATUS); |
97 | /* Clearing IntStatus */ | 111 | /* Clearing IntStatus */ |
98 | asic3_write_register(asic, | 112 | asic3_write_register(asic, |
99 | base + | 113 | base + |
100 | ASIC3_GPIO_IntStatus, 0); | 114 | ASIC3_GPIO_INT_STATUS, 0); |
101 | spin_unlock_irqrestore(&asic->lock, flags); | 115 | spin_unlock_irqrestore(&asic->lock, flags); |
102 | 116 | ||
103 | for (i = 0; i < ASIC3_GPIOS_PER_BANK; i++) { | 117 | for (i = 0; i < ASIC3_GPIOS_PER_BANK; i++) { |
@@ -123,7 +137,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
123 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { | 137 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { |
124 | /* They start at bit 4 and go up */ | 138 | /* They start at bit 4 and go up */ |
125 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { | 139 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { |
126 | desc = irq_desc + + i; | 140 | desc = irq_desc + asic->irq_base + i; |
127 | desc->handle_irq(asic->irq_base + i, | 141 | desc->handle_irq(asic->irq_base + i, |
128 | desc); | 142 | desc); |
129 | } | 143 | } |
@@ -131,8 +145,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
131 | } | 145 | } |
132 | 146 | ||
133 | if (iter >= MAX_ASIC_ISR_LOOPS) | 147 | if (iter >= MAX_ASIC_ISR_LOOPS) |
134 | printk(KERN_ERR "%s: interrupt processing overrun\n", | 148 | dev_err(asic->dev, "interrupt processing overrun\n"); |
135 | __func__); | ||
136 | } | 149 | } |
137 | 150 | ||
138 | static inline int asic3_irq_to_bank(struct asic3 *asic, int irq) | 151 | static inline int asic3_irq_to_bank(struct asic3 *asic, int irq) |
@@ -141,7 +154,7 @@ static inline int asic3_irq_to_bank(struct asic3 *asic, int irq) | |||
141 | 154 | ||
142 | n = (irq - asic->irq_base) >> 4; | 155 | n = (irq - asic->irq_base) >> 4; |
143 | 156 | ||
144 | return (n * (ASIC3_GPIO_B_Base - ASIC3_GPIO_A_Base)); | 157 | return (n * (ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE)); |
145 | } | 158 | } |
146 | 159 | ||
147 | static inline int asic3_irq_to_index(struct asic3 *asic, int irq) | 160 | static inline int asic3_irq_to_index(struct asic3 *asic, int irq) |
@@ -159,9 +172,9 @@ static void asic3_mask_gpio_irq(unsigned int irq) | |||
159 | index = asic3_irq_to_index(asic, irq); | 172 | index = asic3_irq_to_index(asic, irq); |
160 | 173 | ||
161 | spin_lock_irqsave(&asic->lock, flags); | 174 | spin_lock_irqsave(&asic->lock, flags); |
162 | val = asic3_read_register(asic, bank + ASIC3_GPIO_Mask); | 175 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); |
163 | val |= 1 << index; | 176 | val |= 1 << index; |
164 | asic3_write_register(asic, bank + ASIC3_GPIO_Mask, val); | 177 | asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val); |
165 | spin_unlock_irqrestore(&asic->lock, flags); | 178 | spin_unlock_irqrestore(&asic->lock, flags); |
166 | } | 179 | } |
167 | 180 | ||
@@ -173,15 +186,15 @@ static void asic3_mask_irq(unsigned int irq) | |||
173 | 186 | ||
174 | spin_lock_irqsave(&asic->lock, flags); | 187 | spin_lock_irqsave(&asic->lock, flags); |
175 | regval = asic3_read_register(asic, | 188 | regval = asic3_read_register(asic, |
176 | ASIC3_INTR_Base + | 189 | ASIC3_INTR_BASE + |
177 | ASIC3_INTR_IntMask); | 190 | ASIC3_INTR_INT_MASK); |
178 | 191 | ||
179 | regval &= ~(ASIC3_INTMASK_MASK0 << | 192 | regval &= ~(ASIC3_INTMASK_MASK0 << |
180 | (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); | 193 | (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); |
181 | 194 | ||
182 | asic3_write_register(asic, | 195 | asic3_write_register(asic, |
183 | ASIC3_INTR_Base + | 196 | ASIC3_INTR_BASE + |
184 | ASIC3_INTR_IntMask, | 197 | ASIC3_INTR_INT_MASK, |
185 | regval); | 198 | regval); |
186 | spin_unlock_irqrestore(&asic->lock, flags); | 199 | spin_unlock_irqrestore(&asic->lock, flags); |
187 | } | 200 | } |
@@ -196,9 +209,9 @@ static void asic3_unmask_gpio_irq(unsigned int irq) | |||
196 | index = asic3_irq_to_index(asic, irq); | 209 | index = asic3_irq_to_index(asic, irq); |
197 | 210 | ||
198 | spin_lock_irqsave(&asic->lock, flags); | 211 | spin_lock_irqsave(&asic->lock, flags); |
199 | val = asic3_read_register(asic, bank + ASIC3_GPIO_Mask); | 212 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); |
200 | val &= ~(1 << index); | 213 | val &= ~(1 << index); |
201 | asic3_write_register(asic, bank + ASIC3_GPIO_Mask, val); | 214 | asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val); |
202 | spin_unlock_irqrestore(&asic->lock, flags); | 215 | spin_unlock_irqrestore(&asic->lock, flags); |
203 | } | 216 | } |
204 | 217 | ||
@@ -210,15 +223,15 @@ static void asic3_unmask_irq(unsigned int irq) | |||
210 | 223 | ||
211 | spin_lock_irqsave(&asic->lock, flags); | 224 | spin_lock_irqsave(&asic->lock, flags); |
212 | regval = asic3_read_register(asic, | 225 | regval = asic3_read_register(asic, |
213 | ASIC3_INTR_Base + | 226 | ASIC3_INTR_BASE + |
214 | ASIC3_INTR_IntMask); | 227 | ASIC3_INTR_INT_MASK); |
215 | 228 | ||
216 | regval |= (ASIC3_INTMASK_MASK0 << | 229 | regval |= (ASIC3_INTMASK_MASK0 << |
217 | (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); | 230 | (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); |
218 | 231 | ||
219 | asic3_write_register(asic, | 232 | asic3_write_register(asic, |
220 | ASIC3_INTR_Base + | 233 | ASIC3_INTR_BASE + |
221 | ASIC3_INTR_IntMask, | 234 | ASIC3_INTR_INT_MASK, |
222 | regval); | 235 | regval); |
223 | spin_unlock_irqrestore(&asic->lock, flags); | 236 | spin_unlock_irqrestore(&asic->lock, flags); |
224 | } | 237 | } |
@@ -236,11 +249,11 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | |||
236 | 249 | ||
237 | spin_lock_irqsave(&asic->lock, flags); | 250 | spin_lock_irqsave(&asic->lock, flags); |
238 | level = asic3_read_register(asic, | 251 | level = asic3_read_register(asic, |
239 | bank + ASIC3_GPIO_LevelTrigger); | 252 | bank + ASIC3_GPIO_LEVEL_TRIGGER); |
240 | edge = asic3_read_register(asic, | 253 | edge = asic3_read_register(asic, |
241 | bank + ASIC3_GPIO_EdgeTrigger); | 254 | bank + ASIC3_GPIO_EDGE_TRIGGER); |
242 | trigger = asic3_read_register(asic, | 255 | trigger = asic3_read_register(asic, |
243 | bank + ASIC3_GPIO_TriggerType); | 256 | bank + ASIC3_GPIO_TRIGGER_TYPE); |
244 | asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit; | 257 | asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit; |
245 | 258 | ||
246 | if (type == IRQT_RISING) { | 259 | if (type == IRQT_RISING) { |
@@ -251,7 +264,7 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | |||
251 | edge &= ~bit; | 264 | edge &= ~bit; |
252 | } else if (type == IRQT_BOTHEDGE) { | 265 | } else if (type == IRQT_BOTHEDGE) { |
253 | trigger |= bit; | 266 | trigger |= bit; |
254 | if (asic3_gpio_get_value(asic, irq - asic->irq_base)) | 267 | if (asic3_gpio_get(&asic->gpio, irq - asic->irq_base)) |
255 | edge &= ~bit; | 268 | edge &= ~bit; |
256 | else | 269 | else |
257 | edge |= bit; | 270 | edge |= bit; |
@@ -268,13 +281,13 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | |||
268 | * be careful to not unmask them if mask was also called. | 281 | * be careful to not unmask them if mask was also called. |
269 | * Probably need internal state for mask. | 282 | * Probably need internal state for mask. |
270 | */ | 283 | */ |
271 | printk(KERN_NOTICE "asic3: irq type not changed.\n"); | 284 | dev_notice(asic->dev, "irq type not changed\n"); |
272 | } | 285 | } |
273 | asic3_write_register(asic, bank + ASIC3_GPIO_LevelTrigger, | 286 | asic3_write_register(asic, bank + ASIC3_GPIO_LEVEL_TRIGGER, |
274 | level); | 287 | level); |
275 | asic3_write_register(asic, bank + ASIC3_GPIO_EdgeTrigger, | 288 | asic3_write_register(asic, bank + ASIC3_GPIO_EDGE_TRIGGER, |
276 | edge); | 289 | edge); |
277 | asic3_write_register(asic, bank + ASIC3_GPIO_TriggerType, | 290 | asic3_write_register(asic, bank + ASIC3_GPIO_TRIGGER_TYPE, |
278 | trigger); | 291 | trigger); |
279 | spin_unlock_irqrestore(&asic->lock, flags); | 292 | spin_unlock_irqrestore(&asic->lock, flags); |
280 | return 0; | 293 | return 0; |
@@ -295,11 +308,12 @@ static struct irq_chip asic3_irq_chip = { | |||
295 | .unmask = asic3_unmask_irq, | 308 | .unmask = asic3_unmask_irq, |
296 | }; | 309 | }; |
297 | 310 | ||
298 | static int asic3_irq_probe(struct platform_device *pdev) | 311 | static int __init asic3_irq_probe(struct platform_device *pdev) |
299 | { | 312 | { |
300 | struct asic3 *asic = platform_get_drvdata(pdev); | 313 | struct asic3 *asic = platform_get_drvdata(pdev); |
301 | unsigned long clksel = 0; | 314 | unsigned long clksel = 0; |
302 | unsigned int irq, irq_base; | 315 | unsigned int irq, irq_base; |
316 | int map_size; | ||
303 | 317 | ||
304 | asic->irq_nr = platform_get_irq(pdev, 0); | 318 | asic->irq_nr = platform_get_irq(pdev, 0); |
305 | if (asic->irq_nr < 0) | 319 | if (asic->irq_nr < 0) |
@@ -323,7 +337,7 @@ static int asic3_irq_probe(struct platform_device *pdev) | |||
323 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 337 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
324 | } | 338 | } |
325 | 339 | ||
326 | asic3_write_register(asic, ASIC3_OFFSET(INTR, IntMask), | 340 | asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK), |
327 | ASIC3_INTMASK_GINTMASK); | 341 | ASIC3_INTMASK_GINTMASK); |
328 | 342 | ||
329 | set_irq_chained_handler(asic->irq_nr, asic3_irq_demux); | 343 | set_irq_chained_handler(asic->irq_nr, asic3_irq_demux); |
@@ -350,149 +364,182 @@ static void asic3_irq_remove(struct platform_device *pdev) | |||
350 | } | 364 | } |
351 | 365 | ||
352 | /* GPIOs */ | 366 | /* GPIOs */ |
353 | static inline u32 asic3_get_gpio(struct asic3 *asic, unsigned int base, | 367 | static int asic3_gpio_direction(struct gpio_chip *chip, |
354 | unsigned int function) | 368 | unsigned offset, int out) |
355 | { | ||
356 | return asic3_read_register(asic, base + function); | ||
357 | } | ||
358 | |||
359 | static void asic3_set_gpio(struct asic3 *asic, unsigned int base, | ||
360 | unsigned int function, u32 bits, u32 val) | ||
361 | { | 369 | { |
370 | u32 mask = ASIC3_GPIO_TO_MASK(offset), out_reg; | ||
371 | unsigned int gpio_base; | ||
362 | unsigned long flags; | 372 | unsigned long flags; |
373 | struct asic3 *asic; | ||
374 | |||
375 | asic = container_of(chip, struct asic3, gpio); | ||
376 | gpio_base = ASIC3_GPIO_TO_BASE(offset); | ||
377 | |||
378 | if (gpio_base > ASIC3_GPIO_D_BASE) { | ||
379 | dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n", | ||
380 | gpio_base, offset); | ||
381 | return -EINVAL; | ||
382 | } | ||
363 | 383 | ||
364 | spin_lock_irqsave(&asic->lock, flags); | 384 | spin_lock_irqsave(&asic->lock, flags); |
365 | val |= (asic3_read_register(asic, base + function) & ~bits); | ||
366 | 385 | ||
367 | asic3_write_register(asic, base + function, val); | 386 | out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_DIRECTION); |
387 | |||
388 | /* Input is 0, Output is 1 */ | ||
389 | if (out) | ||
390 | out_reg |= mask; | ||
391 | else | ||
392 | out_reg &= ~mask; | ||
393 | |||
394 | asic3_write_register(asic, gpio_base + ASIC3_GPIO_DIRECTION, out_reg); | ||
395 | |||
368 | spin_unlock_irqrestore(&asic->lock, flags); | 396 | spin_unlock_irqrestore(&asic->lock, flags); |
397 | |||
398 | return 0; | ||
399 | |||
400 | } | ||
401 | |||
402 | static int asic3_gpio_direction_input(struct gpio_chip *chip, | ||
403 | unsigned offset) | ||
404 | { | ||
405 | return asic3_gpio_direction(chip, offset, 0); | ||
406 | } | ||
407 | |||
408 | static int asic3_gpio_direction_output(struct gpio_chip *chip, | ||
409 | unsigned offset, int value) | ||
410 | { | ||
411 | return asic3_gpio_direction(chip, offset, 1); | ||
369 | } | 412 | } |
370 | 413 | ||
371 | #define asic3_get_gpio_a(asic, fn) \ | 414 | static int asic3_gpio_get(struct gpio_chip *chip, |
372 | asic3_get_gpio(asic, ASIC3_GPIO_A_Base, ASIC3_GPIO_##fn) | 415 | unsigned offset) |
373 | #define asic3_get_gpio_b(asic, fn) \ | ||
374 | asic3_get_gpio(asic, ASIC3_GPIO_B_Base, ASIC3_GPIO_##fn) | ||
375 | #define asic3_get_gpio_c(asic, fn) \ | ||
376 | asic3_get_gpio(asic, ASIC3_GPIO_C_Base, ASIC3_GPIO_##fn) | ||
377 | #define asic3_get_gpio_d(asic, fn) \ | ||
378 | asic3_get_gpio(asic, ASIC3_GPIO_D_Base, ASIC3_GPIO_##fn) | ||
379 | |||
380 | #define asic3_set_gpio_a(asic, fn, bits, val) \ | ||
381 | asic3_set_gpio(asic, ASIC3_GPIO_A_Base, ASIC3_GPIO_##fn, bits, val) | ||
382 | #define asic3_set_gpio_b(asic, fn, bits, val) \ | ||
383 | asic3_set_gpio(asic, ASIC3_GPIO_B_Base, ASIC3_GPIO_##fn, bits, val) | ||
384 | #define asic3_set_gpio_c(asic, fn, bits, val) \ | ||
385 | asic3_set_gpio(asic, ASIC3_GPIO_C_Base, ASIC3_GPIO_##fn, bits, val) | ||
386 | #define asic3_set_gpio_d(asic, fn, bits, val) \ | ||
387 | asic3_set_gpio(asic, ASIC3_GPIO_D_Base, ASIC3_GPIO_##fn, bits, val) | ||
388 | |||
389 | #define asic3_set_gpio_banks(asic, fn, bits, pdata, field) \ | ||
390 | do { \ | ||
391 | asic3_set_gpio_a((asic), fn, (bits), (pdata)->gpio_a.field); \ | ||
392 | asic3_set_gpio_b((asic), fn, (bits), (pdata)->gpio_b.field); \ | ||
393 | asic3_set_gpio_c((asic), fn, (bits), (pdata)->gpio_c.field); \ | ||
394 | asic3_set_gpio_d((asic), fn, (bits), (pdata)->gpio_d.field); \ | ||
395 | } while (0) | ||
396 | |||
397 | int asic3_gpio_get_value(struct asic3 *asic, unsigned gpio) | ||
398 | { | 416 | { |
399 | u32 mask = ASIC3_GPIO_bit(gpio); | 417 | unsigned int gpio_base; |
400 | 418 | u32 mask = ASIC3_GPIO_TO_MASK(offset); | |
401 | switch (gpio >> 4) { | 419 | struct asic3 *asic; |
402 | case ASIC3_GPIO_BANK_A: | 420 | |
403 | return asic3_get_gpio_a(asic, Status) & mask; | 421 | asic = container_of(chip, struct asic3, gpio); |
404 | case ASIC3_GPIO_BANK_B: | 422 | gpio_base = ASIC3_GPIO_TO_BASE(offset); |
405 | return asic3_get_gpio_b(asic, Status) & mask; | 423 | |
406 | case ASIC3_GPIO_BANK_C: | 424 | if (gpio_base > ASIC3_GPIO_D_BASE) { |
407 | return asic3_get_gpio_c(asic, Status) & mask; | 425 | dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n", |
408 | case ASIC3_GPIO_BANK_D: | 426 | gpio_base, offset); |
409 | return asic3_get_gpio_d(asic, Status) & mask; | ||
410 | default: | ||
411 | printk(KERN_ERR "%s: invalid GPIO value 0x%x", | ||
412 | __func__, gpio); | ||
413 | return -EINVAL; | 427 | return -EINVAL; |
414 | } | 428 | } |
429 | |||
430 | return asic3_read_register(asic, gpio_base + ASIC3_GPIO_STATUS) & mask; | ||
415 | } | 431 | } |
416 | EXPORT_SYMBOL(asic3_gpio_get_value); | ||
417 | 432 | ||
418 | void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val) | 433 | static void asic3_gpio_set(struct gpio_chip *chip, |
434 | unsigned offset, int value) | ||
419 | { | 435 | { |
420 | u32 mask = ASIC3_GPIO_bit(gpio); | 436 | u32 mask, out_reg; |
421 | u32 bitval = 0; | 437 | unsigned int gpio_base; |
422 | if (val) | 438 | unsigned long flags; |
423 | bitval = mask; | 439 | struct asic3 *asic; |
424 | 440 | ||
425 | switch (gpio >> 4) { | 441 | asic = container_of(chip, struct asic3, gpio); |
426 | case ASIC3_GPIO_BANK_A: | 442 | gpio_base = ASIC3_GPIO_TO_BASE(offset); |
427 | asic3_set_gpio_a(asic, Out, mask, bitval); | 443 | |
428 | return; | 444 | if (gpio_base > ASIC3_GPIO_D_BASE) { |
429 | case ASIC3_GPIO_BANK_B: | 445 | dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n", |
430 | asic3_set_gpio_b(asic, Out, mask, bitval); | 446 | gpio_base, offset); |
431 | return; | ||
432 | case ASIC3_GPIO_BANK_C: | ||
433 | asic3_set_gpio_c(asic, Out, mask, bitval); | ||
434 | return; | ||
435 | case ASIC3_GPIO_BANK_D: | ||
436 | asic3_set_gpio_d(asic, Out, mask, bitval); | ||
437 | return; | ||
438 | default: | ||
439 | printk(KERN_ERR "%s: invalid GPIO value 0x%x", | ||
440 | __func__, gpio); | ||
441 | return; | 447 | return; |
442 | } | 448 | } |
449 | |||
450 | mask = ASIC3_GPIO_TO_MASK(offset); | ||
451 | |||
452 | spin_lock_irqsave(&asic->lock, flags); | ||
453 | |||
454 | out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_OUT); | ||
455 | |||
456 | if (value) | ||
457 | out_reg |= mask; | ||
458 | else | ||
459 | out_reg &= ~mask; | ||
460 | |||
461 | asic3_write_register(asic, gpio_base + ASIC3_GPIO_OUT, out_reg); | ||
462 | |||
463 | spin_unlock_irqrestore(&asic->lock, flags); | ||
464 | |||
465 | return; | ||
443 | } | 466 | } |
444 | EXPORT_SYMBOL(asic3_gpio_set_value); | ||
445 | 467 | ||
446 | static int asic3_gpio_probe(struct platform_device *pdev) | 468 | static __init int asic3_gpio_probe(struct platform_device *pdev, |
469 | u16 *gpio_config, int num) | ||
447 | { | 470 | { |
448 | struct asic3_platform_data *pdata = pdev->dev.platform_data; | ||
449 | struct asic3 *asic = platform_get_drvdata(pdev); | 471 | struct asic3 *asic = platform_get_drvdata(pdev); |
472 | u16 alt_reg[ASIC3_NUM_GPIO_BANKS]; | ||
473 | u16 out_reg[ASIC3_NUM_GPIO_BANKS]; | ||
474 | u16 dir_reg[ASIC3_NUM_GPIO_BANKS]; | ||
475 | int i; | ||
476 | |||
477 | memzero(alt_reg, ASIC3_NUM_GPIO_BANKS * sizeof(u16)); | ||
478 | memzero(out_reg, ASIC3_NUM_GPIO_BANKS * sizeof(u16)); | ||
479 | memzero(dir_reg, ASIC3_NUM_GPIO_BANKS * sizeof(u16)); | ||
480 | |||
481 | /* Enable all GPIOs */ | ||
482 | asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, MASK), 0xffff); | ||
483 | asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, MASK), 0xffff); | ||
484 | asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, MASK), 0xffff); | ||
485 | asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, MASK), 0xffff); | ||
486 | |||
487 | for (i = 0; i < num; i++) { | ||
488 | u8 alt, pin, dir, init, bank_num, bit_num; | ||
489 | u16 config = gpio_config[i]; | ||
490 | |||
491 | pin = ASIC3_CONFIG_GPIO_PIN(config); | ||
492 | alt = ASIC3_CONFIG_GPIO_ALT(config); | ||
493 | dir = ASIC3_CONFIG_GPIO_DIR(config); | ||
494 | init = ASIC3_CONFIG_GPIO_INIT(config); | ||
495 | |||
496 | bank_num = ASIC3_GPIO_TO_BANK(pin); | ||
497 | bit_num = ASIC3_GPIO_TO_BIT(pin); | ||
498 | |||
499 | alt_reg[bank_num] |= (alt << bit_num); | ||
500 | out_reg[bank_num] |= (init << bit_num); | ||
501 | dir_reg[bank_num] |= (dir << bit_num); | ||
502 | } | ||
450 | 503 | ||
451 | asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, Mask), 0xffff); | 504 | for (i = 0; i < ASIC3_NUM_GPIO_BANKS; i++) { |
452 | asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, Mask), 0xffff); | 505 | asic3_write_register(asic, |
453 | asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, Mask), 0xffff); | 506 | ASIC3_BANK_TO_BASE(i) + |
454 | asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, Mask), 0xffff); | 507 | ASIC3_GPIO_DIRECTION, |
455 | 508 | dir_reg[i]); | |
456 | asic3_set_gpio_a(asic, SleepMask, 0xffff, 0xffff); | 509 | asic3_write_register(asic, |
457 | asic3_set_gpio_b(asic, SleepMask, 0xffff, 0xffff); | 510 | ASIC3_BANK_TO_BASE(i) + ASIC3_GPIO_OUT, |
458 | asic3_set_gpio_c(asic, SleepMask, 0xffff, 0xffff); | 511 | out_reg[i]); |
459 | asic3_set_gpio_d(asic, SleepMask, 0xffff, 0xffff); | 512 | asic3_write_register(asic, |
460 | 513 | ASIC3_BANK_TO_BASE(i) + | |
461 | if (pdata) { | 514 | ASIC3_GPIO_ALT_FUNCTION, |
462 | asic3_set_gpio_banks(asic, Out, 0xffff, pdata, init); | 515 | alt_reg[i]); |
463 | asic3_set_gpio_banks(asic, Direction, 0xffff, pdata, dir); | ||
464 | asic3_set_gpio_banks(asic, SleepMask, 0xffff, pdata, | ||
465 | sleep_mask); | ||
466 | asic3_set_gpio_banks(asic, SleepOut, 0xffff, pdata, sleep_out); | ||
467 | asic3_set_gpio_banks(asic, BattFaultOut, 0xffff, pdata, | ||
468 | batt_fault_out); | ||
469 | asic3_set_gpio_banks(asic, SleepConf, 0xffff, pdata, | ||
470 | sleep_conf); | ||
471 | asic3_set_gpio_banks(asic, AltFunction, 0xffff, pdata, | ||
472 | alt_function); | ||
473 | } | 516 | } |
474 | 517 | ||
475 | return 0; | 518 | return gpiochip_add(&asic->gpio); |
476 | } | 519 | } |
477 | 520 | ||
478 | static void asic3_gpio_remove(struct platform_device *pdev) | 521 | static int asic3_gpio_remove(struct platform_device *pdev) |
479 | { | 522 | { |
480 | return; | 523 | struct asic3 *asic = platform_get_drvdata(pdev); |
524 | |||
525 | return gpiochip_remove(&asic->gpio); | ||
481 | } | 526 | } |
482 | 527 | ||
483 | 528 | ||
484 | /* Core */ | 529 | /* Core */ |
485 | static int asic3_probe(struct platform_device *pdev) | 530 | static int __init asic3_probe(struct platform_device *pdev) |
486 | { | 531 | { |
487 | struct asic3_platform_data *pdata = pdev->dev.platform_data; | 532 | struct asic3_platform_data *pdata = pdev->dev.platform_data; |
488 | struct asic3 *asic; | 533 | struct asic3 *asic; |
489 | struct resource *mem; | 534 | struct resource *mem; |
490 | unsigned long clksel; | 535 | unsigned long clksel; |
491 | int ret; | 536 | int ret = 0; |
492 | 537 | ||
493 | asic = kzalloc(sizeof(struct asic3), GFP_KERNEL); | 538 | asic = kzalloc(sizeof(struct asic3), GFP_KERNEL); |
494 | if (!asic) | 539 | if (asic == NULL) { |
540 | printk(KERN_ERR "kzalloc failed\n"); | ||
495 | return -ENOMEM; | 541 | return -ENOMEM; |
542 | } | ||
496 | 543 | ||
497 | spin_lock_init(&asic->lock); | 544 | spin_lock_init(&asic->lock); |
498 | platform_set_drvdata(pdev, asic); | 545 | platform_set_drvdata(pdev, asic); |
@@ -501,49 +548,58 @@ static int asic3_probe(struct platform_device *pdev) | |||
501 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 548 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
502 | if (!mem) { | 549 | if (!mem) { |
503 | ret = -ENOMEM; | 550 | ret = -ENOMEM; |
504 | printk(KERN_ERR "asic3: no MEM resource\n"); | 551 | dev_err(asic->dev, "no MEM resource\n"); |
505 | goto err_out_1; | 552 | goto out_free; |
506 | } | 553 | } |
507 | 554 | ||
508 | asic->mapping = ioremap(mem->start, PAGE_SIZE); | 555 | map_size = mem->end - mem->start + 1; |
556 | asic->mapping = ioremap(mem->start, map_size); | ||
509 | if (!asic->mapping) { | 557 | if (!asic->mapping) { |
510 | ret = -ENOMEM; | 558 | ret = -ENOMEM; |
511 | printk(KERN_ERR "asic3: couldn't ioremap\n"); | 559 | dev_err(asic->dev, "Couldn't ioremap\n"); |
512 | goto err_out_1; | 560 | goto out_free; |
513 | } | 561 | } |
514 | 562 | ||
515 | asic->irq_base = pdata->irq_base; | 563 | asic->irq_base = pdata->irq_base; |
516 | 564 | ||
517 | if (pdata && pdata->bus_shift) | 565 | /* calculate bus shift from mem resource */ |
518 | asic->bus_shift = 2 - pdata->bus_shift; | 566 | asic->bus_shift = 2 - (map_size >> 12); |
519 | else | ||
520 | asic->bus_shift = 0; | ||
521 | 567 | ||
522 | clksel = 0; | 568 | clksel = 0; |
523 | asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), clksel); | 569 | asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), clksel); |
524 | 570 | ||
525 | ret = asic3_irq_probe(pdev); | 571 | ret = asic3_irq_probe(pdev); |
526 | if (ret < 0) { | 572 | if (ret < 0) { |
527 | printk(KERN_ERR "asic3: couldn't probe IRQs\n"); | 573 | dev_err(asic->dev, "Couldn't probe IRQs\n"); |
528 | goto err_out_2; | 574 | goto out_unmap; |
529 | } | 575 | } |
530 | asic3_gpio_probe(pdev); | ||
531 | 576 | ||
532 | if (pdata->children) { | 577 | asic->gpio.base = pdata->gpio_base; |
533 | int i; | 578 | asic->gpio.ngpio = ASIC3_NUM_GPIOS; |
534 | for (i = 0; i < pdata->n_children; i++) { | 579 | asic->gpio.get = asic3_gpio_get; |
535 | pdata->children[i]->dev.parent = &pdev->dev; | 580 | asic->gpio.set = asic3_gpio_set; |
536 | platform_device_register(pdata->children[i]); | 581 | asic->gpio.direction_input = asic3_gpio_direction_input; |
537 | } | 582 | asic->gpio.direction_output = asic3_gpio_direction_output; |
583 | |||
584 | ret = asic3_gpio_probe(pdev, | ||
585 | pdata->gpio_config, | ||
586 | pdata->gpio_config_num); | ||
587 | if (ret < 0) { | ||
588 | dev_err(asic->dev, "GPIO probe failed\n"); | ||
589 | goto out_irq; | ||
538 | } | 590 | } |
539 | 591 | ||
540 | printk(KERN_INFO "ASIC3 Core driver\n"); | 592 | dev_info(asic->dev, "ASIC3 Core driver\n"); |
541 | 593 | ||
542 | return 0; | 594 | return 0; |
543 | 595 | ||
544 | err_out_2: | 596 | out_irq: |
597 | asic3_irq_remove(pdev); | ||
598 | |||
599 | out_unmap: | ||
545 | iounmap(asic->mapping); | 600 | iounmap(asic->mapping); |
546 | err_out_1: | 601 | |
602 | out_free: | ||
547 | kfree(asic); | 603 | kfree(asic); |
548 | 604 | ||
549 | return ret; | 605 | return ret; |
@@ -551,9 +607,12 @@ static int asic3_probe(struct platform_device *pdev) | |||
551 | 607 | ||
552 | static int asic3_remove(struct platform_device *pdev) | 608 | static int asic3_remove(struct platform_device *pdev) |
553 | { | 609 | { |
610 | int ret; | ||
554 | struct asic3 *asic = platform_get_drvdata(pdev); | 611 | struct asic3 *asic = platform_get_drvdata(pdev); |
555 | 612 | ||
556 | asic3_gpio_remove(pdev); | 613 | ret = asic3_gpio_remove(pdev); |
614 | if (ret < 0) | ||
615 | return ret; | ||
557 | asic3_irq_remove(pdev); | 616 | asic3_irq_remove(pdev); |
558 | 617 | ||
559 | asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), 0); | 618 | asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), 0); |
@@ -573,7 +632,6 @@ static struct platform_driver asic3_device_driver = { | |||
573 | .driver = { | 632 | .driver = { |
574 | .name = "asic3", | 633 | .name = "asic3", |
575 | }, | 634 | }, |
576 | .probe = asic3_probe, | ||
577 | .remove = __devexit_p(asic3_remove), | 635 | .remove = __devexit_p(asic3_remove), |
578 | .shutdown = asic3_shutdown, | 636 | .shutdown = asic3_shutdown, |
579 | }; | 637 | }; |
@@ -581,7 +639,7 @@ static struct platform_driver asic3_device_driver = { | |||
581 | static int __init asic3_init(void) | 639 | static int __init asic3_init(void) |
582 | { | 640 | { |
583 | int retval = 0; | 641 | int retval = 0; |
584 | retval = platform_driver_register(&asic3_device_driver); | 642 | retval = platform_driver_probe(&asic3_device_driver, asic3_probe); |
585 | return retval; | 643 | return retval; |
586 | } | 644 | } |
587 | 645 | ||
diff --git a/include/linux/mfd/asic3.h b/include/linux/mfd/asic3.h index 4ab2162db13b..322cd6deb9f0 100644 --- a/include/linux/mfd/asic3.h +++ b/include/linux/mfd/asic3.h | |||
@@ -8,7 +8,7 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * Copyright 2001 Compaq Computer Corporation. | 10 | * Copyright 2001 Compaq Computer Corporation. |
11 | * Copyright 2007 OpendHand. | 11 | * Copyright 2007-2008 OpenedHand Ltd. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #ifndef __ASIC3_H__ | 14 | #ifndef __ASIC3_H__ |
@@ -16,43 +16,22 @@ | |||
16 | 16 | ||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | 18 | ||
19 | struct asic3 { | ||
20 | void __iomem *mapping; | ||
21 | unsigned int bus_shift; | ||
22 | unsigned int irq_nr; | ||
23 | unsigned int irq_base; | ||
24 | spinlock_t lock; | ||
25 | u16 irq_bothedge[4]; | ||
26 | struct device *dev; | ||
27 | }; | ||
28 | |||
29 | struct asic3_platform_data { | 19 | struct asic3_platform_data { |
30 | struct { | 20 | u16 *gpio_config; |
31 | u32 dir; | 21 | unsigned int gpio_config_num; |
32 | u32 init; | ||
33 | u32 sleep_mask; | ||
34 | u32 sleep_out; | ||
35 | u32 batt_fault_out; | ||
36 | u32 sleep_conf; | ||
37 | u32 alt_function; | ||
38 | } gpio_a, gpio_b, gpio_c, gpio_d; | ||
39 | |||
40 | unsigned int bus_shift; | ||
41 | 22 | ||
42 | unsigned int irq_base; | 23 | unsigned int irq_base; |
43 | 24 | ||
44 | struct platform_device **children; | 25 | unsigned int gpio_base; |
45 | unsigned int n_children; | ||
46 | }; | 26 | }; |
47 | 27 | ||
48 | int asic3_gpio_get_value(struct asic3 *asic, unsigned gpio); | ||
49 | void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val); | ||
50 | |||
51 | #define ASIC3_NUM_GPIO_BANKS 4 | 28 | #define ASIC3_NUM_GPIO_BANKS 4 |
52 | #define ASIC3_GPIOS_PER_BANK 16 | 29 | #define ASIC3_GPIOS_PER_BANK 16 |
53 | #define ASIC3_NUM_GPIOS 64 | 30 | #define ASIC3_NUM_GPIOS 64 |
54 | #define ASIC3_NR_IRQS ASIC3_NUM_GPIOS + 6 | 31 | #define ASIC3_NR_IRQS ASIC3_NUM_GPIOS + 6 |
55 | 32 | ||
33 | #define ASIC3_TO_GPIO(gpio) (NR_BUILTIN_GPIO + (gpio)) | ||
34 | |||
56 | #define ASIC3_GPIO_BANK_A 0 | 35 | #define ASIC3_GPIO_BANK_A 0 |
57 | #define ASIC3_GPIO_BANK_B 1 | 36 | #define ASIC3_GPIO_BANK_B 1 |
58 | #define ASIC3_GPIO_BANK_C 2 | 37 | #define ASIC3_GPIO_BANK_C 2 |
@@ -64,32 +43,89 @@ void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val); | |||
64 | /* All offsets below are specified with this address bus shift */ | 43 | /* All offsets below are specified with this address bus shift */ |
65 | #define ASIC3_DEFAULT_ADDR_SHIFT 2 | 44 | #define ASIC3_DEFAULT_ADDR_SHIFT 2 |
66 | 45 | ||
67 | #define ASIC3_OFFSET(base, reg) (ASIC3_##base##_Base + ASIC3_##base##_##reg) | 46 | #define ASIC3_OFFSET(base, reg) (ASIC3_##base##_BASE + ASIC3_##base##_##reg) |
68 | #define ASIC3_GPIO_OFFSET(base, reg) \ | 47 | #define ASIC3_GPIO_OFFSET(base, reg) \ |
69 | (ASIC3_GPIO_##base##_Base + ASIC3_GPIO_##reg) | 48 | (ASIC3_GPIO_##base##_BASE + ASIC3_GPIO_##reg) |
70 | 49 | ||
71 | #define ASIC3_GPIO_A_Base 0x0000 | 50 | #define ASIC3_GPIO_A_BASE 0x0000 |
72 | #define ASIC3_GPIO_B_Base 0x0100 | 51 | #define ASIC3_GPIO_B_BASE 0x0100 |
73 | #define ASIC3_GPIO_C_Base 0x0200 | 52 | #define ASIC3_GPIO_C_BASE 0x0200 |
74 | #define ASIC3_GPIO_D_Base 0x0300 | 53 | #define ASIC3_GPIO_D_BASE 0x0300 |
75 | 54 | ||
76 | #define ASIC3_GPIO_Mask 0x00 /* R/W 0:don't mask */ | 55 | #define ASIC3_GPIO_TO_BANK(gpio) ((gpio) >> 4) |
77 | #define ASIC3_GPIO_Direction 0x04 /* R/W 0:input */ | 56 | #define ASIC3_GPIO_TO_BIT(gpio) ((gpio) - \ |
78 | #define ASIC3_GPIO_Out 0x08 /* R/W 0:output low */ | 57 | (ASIC3_GPIOS_PER_BANK * ((gpio) >> 4))) |
79 | #define ASIC3_GPIO_TriggerType 0x0c /* R/W 0:level */ | 58 | #define ASIC3_GPIO_TO_MASK(gpio) (1 << ASIC3_GPIO_TO_BIT(gpio)) |
80 | #define ASIC3_GPIO_EdgeTrigger 0x10 /* R/W 0:falling */ | 59 | #define ASIC3_GPIO_TO_BASE(gpio) (ASIC3_GPIO_A_BASE + (((gpio) >> 4) * 0x0100)) |
81 | #define ASIC3_GPIO_LevelTrigger 0x14 /* R/W 0:low level detect */ | 60 | #define ASIC3_BANK_TO_BASE(bank) (ASIC3_GPIO_A_BASE + ((bank) * 0x100)) |
82 | #define ASIC3_GPIO_SleepMask 0x18 /* R/W 0:don't mask in sleep mode */ | 61 | |
83 | #define ASIC3_GPIO_SleepOut 0x1c /* R/W level 0:low in sleep mode */ | 62 | #define ASIC3_GPIO_MASK 0x00 /* R/W 0:don't mask */ |
84 | #define ASIC3_GPIO_BattFaultOut 0x20 /* R/W level 0:low in batt_fault */ | 63 | #define ASIC3_GPIO_DIRECTION 0x04 /* R/W 0:input */ |
85 | #define ASIC3_GPIO_IntStatus 0x24 /* R/W 0:none, 1:detect */ | 64 | #define ASIC3_GPIO_OUT 0x08 /* R/W 0:output low */ |
86 | #define ASIC3_GPIO_AltFunction 0x28 /* R/W 1:LED register control */ | 65 | #define ASIC3_GPIO_TRIGGER_TYPE 0x0c /* R/W 0:level */ |
87 | #define ASIC3_GPIO_SleepConf 0x2c /* | 66 | #define ASIC3_GPIO_EDGE_TRIGGER 0x10 /* R/W 0:falling */ |
67 | #define ASIC3_GPIO_LEVEL_TRIGGER 0x14 /* R/W 0:low level detect */ | ||
68 | #define ASIC3_GPIO_SLEEP_MASK 0x18 /* R/W 0:don't mask in sleep mode */ | ||
69 | #define ASIC3_GPIO_SLEEP_OUT 0x1c /* R/W level 0:low in sleep mode */ | ||
70 | #define ASIC3_GPIO_BAT_FAULT_OUT 0x20 /* R/W level 0:low in batt_fault */ | ||
71 | #define ASIC3_GPIO_INT_STATUS 0x24 /* R/W 0:none, 1:detect */ | ||
72 | #define ASIC3_GPIO_ALT_FUNCTION 0x28 /* R/W 1:LED register control */ | ||
73 | #define ASIC3_GPIO_SLEEP_CONF 0x2c /* | ||
88 | * R/W bit 1: autosleep | 74 | * R/W bit 1: autosleep |
89 | * 0: disable gposlpout in normal mode, | 75 | * 0: disable gposlpout in normal mode, |
90 | * enable gposlpout in sleep mode. | 76 | * enable gposlpout in sleep mode. |
91 | */ | 77 | */ |
92 | #define ASIC3_GPIO_Status 0x30 /* R Pin status */ | 78 | #define ASIC3_GPIO_STATUS 0x30 /* R Pin status */ |
79 | |||
80 | /* | ||
81 | * ASIC3 GPIO config | ||
82 | * | ||
83 | * Bits 0..6 gpio number | ||
84 | * Bits 7..13 Alternate function | ||
85 | * Bit 14 Direction | ||
86 | * Bit 15 Initial value | ||
87 | * | ||
88 | */ | ||
89 | #define ASIC3_CONFIG_GPIO_PIN(config) ((config) & 0x7f) | ||
90 | #define ASIC3_CONFIG_GPIO_ALT(config) (((config) & (0x7f << 7)) >> 7) | ||
91 | #define ASIC3_CONFIG_GPIO_DIR(config) ((config & (1 << 14)) >> 14) | ||
92 | #define ASIC3_CONFIG_GPIO_INIT(config) ((config & (1 << 15)) >> 15) | ||
93 | #define ASIC3_CONFIG_GPIO(gpio, alt, dir, init) (((gpio) & 0x7f) \ | ||
94 | | (((alt) & 0x7f) << 7) | (((dir) & 0x1) << 14) \ | ||
95 | | (((init) & 0x1) << 15)) | ||
96 | #define ASIC3_CONFIG_GPIO_DEFAULT(gpio, dir, init) \ | ||
97 | ASIC3_CONFIG_GPIO((gpio), 0, (dir), (init)) | ||
98 | #define ASIC3_CONFIG_GPIO_DEFAULT_OUT(gpio, init) \ | ||
99 | ASIC3_CONFIG_GPIO((gpio), 0, 1, (init)) | ||
100 | |||
101 | /* | ||
102 | * Alternate functions | ||
103 | */ | ||
104 | #define ASIC3_GPIOA11_PWM0 ASIC3_CONFIG_GPIO(11, 1, 1, 0) | ||
105 | #define ASIC3_GPIOA12_PWM1 ASIC3_CONFIG_GPIO(12, 1, 1, 0) | ||
106 | #define ASIC3_GPIOA15_CONTROL_CX ASIC3_CONFIG_GPIO(15, 1, 1, 0) | ||
107 | #define ASIC3_GPIOC0_LED0 ASIC3_CONFIG_GPIO(32, 1, 1, 0) | ||
108 | #define ASIC3_GPIOC1_LED1 ASIC3_CONFIG_GPIO(33, 1, 1, 0) | ||
109 | #define ASIC3_GPIOC2_LED2 ASIC3_CONFIG_GPIO(34, 1, 1, 0) | ||
110 | #define ASIC3_GPIOC3_SPI_RXD ASIC3_CONFIG_GPIO(35, 1, 0, 0) | ||
111 | #define ASIC3_GPIOC4_CF_nCD ASIC3_CONFIG_GPIO(36, 1, 0, 0) | ||
112 | #define ASIC3_GPIOC4_SPI_TXD ASIC3_CONFIG_GPIO(36, 1, 1, 0) | ||
113 | #define ASIC3_GPIOC5_SPI_CLK ASIC3_CONFIG_GPIO(37, 1, 1, 0) | ||
114 | #define ASIC3_GPIOC5_nCIOW ASIC3_CONFIG_GPIO(37, 1, 1, 0) | ||
115 | #define ASIC3_GPIOC6_nCIOR ASIC3_CONFIG_GPIO(38, 1, 1, 0) | ||
116 | #define ASIC3_GPIOC7_nPCE_1 ASIC3_CONFIG_GPIO(39, 1, 0, 0) | ||
117 | #define ASIC3_GPIOC8_nPCE_2 ASIC3_CONFIG_GPIO(40, 1, 0, 0) | ||
118 | #define ASIC3_GPIOC9_nPOE ASIC3_CONFIG_GPIO(41, 1, 0, 0) | ||
119 | #define ASIC3_GPIOC10_nPWE ASIC3_CONFIG_GPIO(42, 1, 0, 0) | ||
120 | #define ASIC3_GPIOC11_PSKTSEL ASIC3_CONFIG_GPIO(43, 1, 0, 0) | ||
121 | #define ASIC3_GPIOC12_nPREG ASIC3_CONFIG_GPIO(44, 1, 0, 0) | ||
122 | #define ASIC3_GPIOC13_nPWAIT ASIC3_CONFIG_GPIO(45, 1, 1, 0) | ||
123 | #define ASIC3_GPIOC14_nPIOIS16 ASIC3_CONFIG_GPIO(46, 1, 1, 0) | ||
124 | #define ASIC3_GPIOC15_nPIOR ASIC3_CONFIG_GPIO(47, 1, 0, 0) | ||
125 | #define ASIC3_GPIOD11_nCIOIS16 ASIC3_CONFIG_GPIO(59, 1, 0, 0) | ||
126 | #define ASIC3_GPIOD12_nCWAIT ASIC3_CONFIG_GPIO(60, 1, 0, 0) | ||
127 | #define ASIC3_GPIOD15_nPIOW ASIC3_CONFIG_GPIO(63, 1, 0, 0) | ||
128 | |||
93 | 129 | ||
94 | #define ASIC3_SPI_Base 0x0400 | 130 | #define ASIC3_SPI_Base 0x0400 |
95 | #define ASIC3_SPI_Control 0x0000 | 131 | #define ASIC3_SPI_Control 0x0000 |
@@ -128,7 +164,7 @@ void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val); | |||
128 | #define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop 0:disable, 1:enable */ | 164 | #define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop 0:disable, 1:enable */ |
129 | #define LED_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */ | 165 | #define LED_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */ |
130 | 166 | ||
131 | #define ASIC3_CLOCK_Base 0x0A00 | 167 | #define ASIC3_CLOCK_BASE 0x0A00 |
132 | #define ASIC3_CLOCK_CDEX 0x00 | 168 | #define ASIC3_CLOCK_CDEX 0x00 |
133 | #define ASIC3_CLOCK_SEL 0x04 | 169 | #define ASIC3_CLOCK_SEL 0x04 |
134 | 170 | ||
@@ -159,12 +195,12 @@ void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val); | |||
159 | #define CLOCK_SEL_CX (1 << 2) | 195 | #define CLOCK_SEL_CX (1 << 2) |
160 | 196 | ||
161 | 197 | ||
162 | #define ASIC3_INTR_Base 0x0B00 | 198 | #define ASIC3_INTR_BASE 0x0B00 |
163 | 199 | ||
164 | #define ASIC3_INTR_IntMask 0x00 /* Interrupt mask control */ | 200 | #define ASIC3_INTR_INT_MASK 0x00 /* Interrupt mask control */ |
165 | #define ASIC3_INTR_PIntStat 0x04 /* Peripheral interrupt status */ | 201 | #define ASIC3_INTR_P_INT_STAT 0x04 /* Peripheral interrupt status */ |
166 | #define ASIC3_INTR_IntCPS 0x08 /* Interrupt timer clock pre-scale */ | 202 | #define ASIC3_INTR_INT_CPS 0x08 /* Interrupt timer clock pre-scale */ |
167 | #define ASIC3_INTR_IntTBS 0x0c /* Interrupt timer set */ | 203 | #define ASIC3_INTR_INT_TBS 0x0c /* Interrupt timer set */ |
168 | 204 | ||
169 | #define ASIC3_INTMASK_GINTMASK (1 << 0) /* Global INTs mask 1:enable */ | 205 | #define ASIC3_INTMASK_GINTMASK (1 << 0) /* Global INTs mask 1:enable */ |
170 | #define ASIC3_INTMASK_GINTEL (1 << 1) /* 1: rising edge, 0: hi level */ | 206 | #define ASIC3_INTMASK_GINTEL (1 << 1) /* 1: rising edge, 0: hi level */ |
@@ -227,44 +263,12 @@ void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val); | |||
227 | #define ASIC3_EXTCF_CF_SLEEP (1 << 15) /* CF sleep mode control */ | 263 | #define ASIC3_EXTCF_CF_SLEEP (1 << 15) /* CF sleep mode control */ |
228 | 264 | ||
229 | /********************************************* | 265 | /********************************************* |
230 | * The Onewire interface registers | 266 | * The Onewire interface (DS1WM) is handled |
231 | * | 267 | * by the ds1wm driver. |
232 | * OWM_CMD | ||
233 | * OWM_DAT | ||
234 | * OWM_INTR | ||
235 | * OWM_INTEN | ||
236 | * OWM_CLKDIV | ||
237 | * | 268 | * |
238 | *********************************************/ | 269 | *********************************************/ |
239 | 270 | ||
240 | #define ASIC3_OWM_Base 0xC00 | 271 | #define ASIC3_OWM_BASE 0xC00 |
241 | |||
242 | #define ASIC3_OWM_CMD 0x00 | ||
243 | #define ASIC3_OWM_DAT 0x04 | ||
244 | #define ASIC3_OWM_INTR 0x08 | ||
245 | #define ASIC3_OWM_INTEN 0x0C | ||
246 | #define ASIC3_OWM_CLKDIV 0x10 | ||
247 | |||
248 | #define ASIC3_OWM_CMD_ONEWR (1 << 0) | ||
249 | #define ASIC3_OWM_CMD_SRA (1 << 1) | ||
250 | #define ASIC3_OWM_CMD_DQO (1 << 2) | ||
251 | #define ASIC3_OWM_CMD_DQI (1 << 3) | ||
252 | |||
253 | #define ASIC3_OWM_INTR_PD (1 << 0) | ||
254 | #define ASIC3_OWM_INTR_PDR (1 << 1) | ||
255 | #define ASIC3_OWM_INTR_TBE (1 << 2) | ||
256 | #define ASIC3_OWM_INTR_TEMP (1 << 3) | ||
257 | #define ASIC3_OWM_INTR_RBF (1 << 4) | ||
258 | |||
259 | #define ASIC3_OWM_INTEN_EPD (1 << 0) | ||
260 | #define ASIC3_OWM_INTEN_IAS (1 << 1) | ||
261 | #define ASIC3_OWM_INTEN_ETBE (1 << 2) | ||
262 | #define ASIC3_OWM_INTEN_ETMT (1 << 3) | ||
263 | #define ASIC3_OWM_INTEN_ERBF (1 << 4) | ||
264 | |||
265 | #define ASIC3_OWM_CLKDIV_PRE (3 << 0) /* two bits wide at bit 0 */ | ||
266 | #define ASIC3_OWM_CLKDIV_DIV (7 << 2) /* 3 bits wide at bit 2 */ | ||
267 | |||
268 | 272 | ||
269 | /***************************************************************************** | 273 | /***************************************************************************** |
270 | * The SD configuration registers are at a completely different location | 274 | * The SD configuration registers are at a completely different location |
@@ -492,6 +496,7 @@ void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val); | |||
492 | #define ASIC3_SDIO_CTRL_LEDCtrl 0x7C | 496 | #define ASIC3_SDIO_CTRL_LEDCtrl 0x7C |
493 | #define ASIC3_SDIO_CTRL_SoftwareReset 0x1C0 | 497 | #define ASIC3_SDIO_CTRL_SoftwareReset 0x1C0 |
494 | 498 | ||
495 | #define ASIC3_MAP_SIZE 0x2000 | 499 | #define ASIC3_MAP_SIZE_32BIT 0x2000 |
500 | #define ASIC3_MAP_SIZE_16BIT 0x1000 | ||
496 | 501 | ||
497 | #endif /* __ASIC3_H__ */ | 502 | #endif /* __ASIC3_H__ */ |