[ARM] 5501/1: Freescale STMP: fix compilation warning
[safe/jmp/linux-2.6] / arch / arm / plat-stmp3xxx / pinmux.c
1 /*
2  * Freescale STMP378X/STMP378X Pin Multiplexing
3  *
4  * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
5  *
6  * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
7  * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
8  */
9
10 /*
11  * The code contained herein is licensed under the GNU General Public
12  * License. You may obtain a copy of the GNU General Public License
13  * Version 2 or later at the following locations:
14  *
15  * http://www.opensource.org/licenses/gpl-license.html
16  * http://www.gnu.org/copyleft/gpl.html
17  */
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/sysdev.h>
22 #include <linux/string.h>
23 #include <linux/bitops.h>
24 #include <linux/sysdev.h>
25 #include <linux/irq.h>
26
27 #include <mach/hardware.h>
28 #include <mach/regs-pinctrl.h>
29 #include <mach/pins.h>
30 #include <mach/pinmux.h>
31
32 #define NR_BANKS ARRAY_SIZE(pinmux_banks)
33 static struct stmp3xxx_pinmux_bank pinmux_banks[] = {
34         [0] = {
35                 .hw_muxsel = {
36                         HW_PINCTRL_MUXSEL0_ADDR,
37                         HW_PINCTRL_MUXSEL1_ADDR
38                 },
39                 .hw_drive = {
40                         HW_PINCTRL_DRIVE0_ADDR,
41                         HW_PINCTRL_DRIVE1_ADDR,
42                         HW_PINCTRL_DRIVE2_ADDR,
43                         HW_PINCTRL_DRIVE3_ADDR
44                 },
45                 .hw_pull = HW_PINCTRL_PULL0_ADDR,
46                 .functions = { 0x0, 0x1, 0x2, 0x3 },
47                 .strengths = { 0x0, 0x1, 0x2, 0x3, 0xff },
48
49                 .hw_gpio_read = HW_PINCTRL_DIN0_ADDR,
50                 .hw_gpio_set = HW_PINCTRL_DOUT0_ADDR + HW_STMP3xxx_SET,
51                 .hw_gpio_clr = HW_PINCTRL_DOUT0_ADDR + HW_STMP3xxx_CLR,
52                 .hw_gpio_doe = HW_PINCTRL_DOE0_ADDR,
53                 .irq = IRQ_GPIO0,
54
55                 .pin2irq = HW_PINCTRL_PIN2IRQ0_ADDR,
56                 .irqstat = HW_PINCTRL_IRQSTAT0_ADDR,
57                 .irqlevel = HW_PINCTRL_IRQLEVEL0_ADDR,
58                 .irqpolarity = HW_PINCTRL_IRQPOL0_ADDR,
59                 .irqen = HW_PINCTRL_IRQEN0_ADDR,
60         },
61         [1] = {
62                 .hw_muxsel = {
63                         HW_PINCTRL_MUXSEL2_ADDR,
64                         HW_PINCTRL_MUXSEL3_ADDR
65                 },
66                 .hw_drive = {
67                         HW_PINCTRL_DRIVE4_ADDR,
68                         HW_PINCTRL_DRIVE5_ADDR,
69                         HW_PINCTRL_DRIVE6_ADDR,
70                         HW_PINCTRL_DRIVE7_ADDR
71                 },
72                 .hw_pull = HW_PINCTRL_PULL1_ADDR,
73                 .functions = { 0x0, 0x1, 0x2, 0x3 },
74                 .strengths = { 0x0, 0x1, 0x2, 0x3, 0xff },
75
76                 .hw_gpio_read = HW_PINCTRL_DIN1_ADDR,
77                 .hw_gpio_set = HW_PINCTRL_DOUT1_ADDR + HW_STMP3xxx_SET,
78                 .hw_gpio_clr = HW_PINCTRL_DOUT1_ADDR + HW_STMP3xxx_CLR,
79                 .hw_gpio_doe = HW_PINCTRL_DOE1_ADDR,
80                 .irq = IRQ_GPIO1,
81
82                 .pin2irq = HW_PINCTRL_PIN2IRQ1_ADDR,
83                 .irqstat = HW_PINCTRL_IRQSTAT1_ADDR,
84                 .irqlevel = HW_PINCTRL_IRQLEVEL1_ADDR,
85                 .irqpolarity = HW_PINCTRL_IRQPOL1_ADDR,
86                 .irqen = HW_PINCTRL_IRQEN1_ADDR,
87         },
88         [2] = {
89                .hw_muxsel = {
90                         HW_PINCTRL_MUXSEL4_ADDR,
91                         HW_PINCTRL_MUXSEL5_ADDR,
92                 },
93                 .hw_drive = {
94                         HW_PINCTRL_DRIVE8_ADDR,
95                         HW_PINCTRL_DRIVE9_ADDR,
96                         HW_PINCTRL_DRIVE10_ADDR,
97                         HW_PINCTRL_DRIVE11_ADDR,
98                 },
99                 .hw_pull = HW_PINCTRL_PULL2_ADDR,
100                 .functions = { 0x0, 0x1, 0x2, 0x3 },
101                 .strengths = { 0x0, 0x1, 0x2, 0x1, 0x2 },
102
103                 .hw_gpio_read = HW_PINCTRL_DIN2_ADDR,
104                 .hw_gpio_set = HW_PINCTRL_DOUT2_ADDR + HW_STMP3xxx_SET,
105                 .hw_gpio_clr = HW_PINCTRL_DOUT2_ADDR + HW_STMP3xxx_CLR,
106                 .hw_gpio_doe = HW_PINCTRL_DOE2_ADDR,
107                 .irq = IRQ_GPIO2,
108
109                 .pin2irq = HW_PINCTRL_PIN2IRQ2_ADDR,
110                 .irqstat = HW_PINCTRL_IRQSTAT2_ADDR,
111                 .irqlevel = HW_PINCTRL_IRQLEVEL2_ADDR,
112                 .irqpolarity = HW_PINCTRL_IRQPOL2_ADDR,
113                 .irqen = HW_PINCTRL_IRQEN2_ADDR,
114         },
115         [3] = {
116                .hw_muxsel = {
117                        HW_PINCTRL_MUXSEL6_ADDR,
118                        HW_PINCTRL_MUXSEL7_ADDR,
119                },
120                .hw_drive = {
121                         HW_PINCTRL_DRIVE12_ADDR,
122                         HW_PINCTRL_DRIVE13_ADDR,
123                         HW_PINCTRL_DRIVE14_ADDR,
124                         NULL,
125                },
126                .hw_pull = HW_PINCTRL_PULL3_ADDR,
127                .functions = {0x0, 0x1, 0x2, 0x3},
128                .strengths = {0x0, 0x1, 0x2, 0x3, 0xff},
129         },
130 };
131
132 static inline struct stmp3xxx_pinmux_bank *
133 stmp3xxx_pinmux_bank(unsigned id, unsigned *bank, unsigned *pin)
134 {
135         unsigned b, p;
136
137         b = STMP3XXX_PINID_TO_BANK(id);
138         p = STMP3XXX_PINID_TO_PINNUM(id);
139         BUG_ON(b >= NR_BANKS);
140         if (bank)
141                 *bank = b;
142         if (pin)
143                 *pin = p;
144         return &pinmux_banks[b];
145 }
146
147 /* Check if requested pin is owned by caller */
148 static int stmp3xxx_check_pin(unsigned id, const char *label)
149 {
150         unsigned pin;
151         struct stmp3xxx_pinmux_bank *pm = stmp3xxx_pinmux_bank(id, NULL, &pin);
152
153         if (!test_bit(pin, &pm->pin_map)) {
154                 printk(KERN_WARNING
155                        "%s: Accessing free pin %x, caller %s\n",
156                        __func__, id, label);
157
158                 return -EINVAL;
159         }
160
161         if (label && pm->pin_labels[pin] &&
162             strcmp(label, pm->pin_labels[pin])) {
163                 printk(KERN_WARNING
164                        "%s: Wrong pin owner %x, caller %s owner %s\n",
165                        __func__, id, label, pm->pin_labels[pin]);
166
167                 return -EINVAL;
168         }
169         return 0;
170 }
171
172 void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength,
173                 const char *label)
174 {
175         struct stmp3xxx_pinmux_bank *pbank;
176         void __iomem *hwdrive;
177         u32 shift, val;
178         u32 bank, pin;
179
180         pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
181         pr_debug("%s: label %s bank %d pin %d strength %d\n", __func__, label,
182                  bank, pin, strength);
183
184         hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
185         shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;
186         val = pbank->strengths[strength];
187         if (val == 0xff) {
188                 printk(KERN_WARNING
189                        "%s: strength is not supported for bank %d, caller %s",
190                        __func__, bank, label);
191                 return;
192         }
193
194         if (stmp3xxx_check_pin(id, label))
195                 return;
196
197         pr_debug("%s: writing 0x%x to 0x%p register\n", __func__,
198                         val << shift, hwdrive);
199         __raw_writel(HW_DRIVE_PINDRV_MASK << shift, hwdrive + HW_STMP3xxx_CLR);
200         __raw_writel(val << shift, hwdrive + HW_STMP3xxx_SET);
201 }
202
203 void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage,
204                           const char *label)
205 {
206         struct stmp3xxx_pinmux_bank *pbank;
207         void __iomem *hwdrive;
208         u32 shift;
209         u32 bank, pin;
210
211         pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
212         pr_debug("%s: label %s bank %d pin %d voltage %d\n", __func__, label,
213                  bank, pin, voltage);
214
215         hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
216         shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;
217
218         if (stmp3xxx_check_pin(id, label))
219                 return;
220
221         pr_debug("%s: changing 0x%x bit in 0x%p register\n",
222                         __func__, HW_DRIVE_PINV_MASK << shift, hwdrive);
223         if (voltage == PIN_1_8V)
224                 __raw_writel(HW_DRIVE_PINV_MASK << shift,
225                              hwdrive + HW_STMP3xxx_CLR);
226         else
227                 __raw_writel(HW_DRIVE_PINV_MASK << shift,
228                              hwdrive + HW_STMP3xxx_SET);
229 }
230
231 void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label)
232 {
233         struct stmp3xxx_pinmux_bank *pbank;
234         void __iomem *hwpull;
235         u32 bank, pin;
236
237         pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
238         pr_debug("%s: label %s bank %d pin %d enable %d\n", __func__, label,
239                  bank, pin, enable);
240
241         hwpull = pbank->hw_pull;
242
243         if (stmp3xxx_check_pin(id, label))
244                 return;
245
246         pr_debug("%s: changing 0x%x bit in 0x%p register\n",
247                         __func__, 1 << pin, hwpull);
248         __raw_writel(1 << pin,
249                      hwpull + (enable ? HW_STMP3xxx_SET : HW_STMP3xxx_CLR));
250 }
251
252 int stmp3xxx_request_pin(unsigned id, enum pin_fun fun, const char *label)
253 {
254         struct stmp3xxx_pinmux_bank *pbank;
255         u32 bank, pin;
256         int ret = 0;
257
258         pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
259         pr_debug("%s: label %s bank %d pin %d fun %d\n", __func__, label,
260                  bank, pin, fun);
261
262         if (test_bit(pin, &pbank->pin_map)) {
263                 printk(KERN_WARNING
264                        "%s: CONFLICT DETECTED pin %d:%d caller %s owner %s\n",
265                        __func__, bank, pin, label, pbank->pin_labels[pin]);
266                 return -EBUSY;
267         }
268
269         set_bit(pin, &pbank->pin_map);
270         pbank->pin_labels[pin] = label;
271
272         stmp3xxx_set_pin_type(id, fun);
273
274         return ret;
275 }
276
277 void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun)
278 {
279         struct stmp3xxx_pinmux_bank *pbank;
280         void __iomem *hwmux;
281         u32 shift, val;
282         u32 bank, pin;
283
284         pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
285
286         hwmux = pbank->hw_muxsel[pin / HW_MUXSEL_PIN_NUM];
287         shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;
288
289         val = pbank->functions[fun];
290         shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;
291         pr_debug("%s: writing 0x%x to 0x%p register\n",
292                         __func__, val << shift, hwmux);
293         __raw_writel(HW_MUXSEL_PINFUN_MASK << shift, hwmux + HW_STMP3xxx_CLR);
294         __raw_writel(val << shift, hwmux + HW_STMP3xxx_SET);
295 }
296
297 void stmp3xxx_release_pin(unsigned id, const char *label)
298 {
299         struct stmp3xxx_pinmux_bank *pbank;
300         u32 bank, pin;
301
302         pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
303         pr_debug("%s: label %s bank %d pin %d\n", __func__, label, bank, pin);
304
305         if (stmp3xxx_check_pin(id, label))
306                 return;
307
308         clear_bit(pin, &pbank->pin_map);
309         pbank->pin_labels[pin] = NULL;
310 }
311
312 int stmp3xxx_request_pin_group(struct pin_group *pin_group, const char *label)
313 {
314         struct pin_desc *pin;
315         int p;
316         int err = 0;
317
318         /* Allocate and configure pins */
319         for (p = 0; p < pin_group->nr_pins; p++) {
320                 pr_debug("%s: #%d\n", __func__, p);
321                 pin = &pin_group->pins[p];
322
323                 err = stmp3xxx_request_pin(pin->id, pin->fun, label);
324                 if (err)
325                         goto out_err;
326
327                 stmp3xxx_pin_strength(pin->id, pin->strength, label);
328                 stmp3xxx_pin_voltage(pin->id, pin->voltage, label);
329                 stmp3xxx_pin_pullup(pin->id, pin->pullup, label);
330         }
331
332         return 0;
333
334 out_err:
335         /* Release allocated pins in case of error */
336         while (--p >= 0) {
337                 pr_debug("%s: releasing #%d\n", __func__, p);
338                 stmp3xxx_release_pin(pin_group->pins[p].id, label);
339         }
340         return err;
341 }
342 EXPORT_SYMBOL(stmp3xxx_request_pin_group);
343
344 void stmp3xxx_release_pin_group(struct pin_group *pin_group, const char *label)
345 {
346         struct pin_desc *pin;
347         int p;
348
349         for (p = 0; p < pin_group->nr_pins; p++) {
350                 pin = &pin_group->pins[p];
351                 stmp3xxx_release_pin(pin->id, label);
352         }
353 }
354 EXPORT_SYMBOL(stmp3xxx_release_pin_group);
355
356 static int stmp3xxx_irq_to_gpio(int irq,
357         struct stmp3xxx_pinmux_bank **bank, unsigned *gpio)
358 {
359         struct stmp3xxx_pinmux_bank *pm;
360
361         for (pm = pinmux_banks; pm < pinmux_banks + NR_BANKS; pm++)
362                 if (pm->virq <= irq && irq < pm->virq + 32) {
363                         *bank = pm;
364                         *gpio = irq - pm->virq;
365                         return 0;
366                 }
367         return -ENOENT;
368 }
369
370 static int stmp3xxx_set_irqtype(unsigned irq, unsigned type)
371 {
372         struct stmp3xxx_pinmux_bank *pm;
373         unsigned gpio;
374         int l, p;
375
376         stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
377         switch (type) {
378         case IRQ_TYPE_EDGE_RISING:
379                 l = 0; p = 1; break;
380         case IRQ_TYPE_EDGE_FALLING:
381                 l = 0; p = 0; break;
382         case IRQ_TYPE_LEVEL_HIGH:
383                 l = 1; p = 1; break;
384         case IRQ_TYPE_LEVEL_LOW:
385                 l = 1; p = 0; break;
386         default:
387                 pr_debug("%s: Incorrect GPIO interrupt type 0x%x\n",
388                                 __func__, type);
389                 return -ENXIO;
390         }
391         __raw_writel(1 << gpio,
392                 pm->irqlevel + (l ? HW_STMP3xxx_SET : HW_STMP3xxx_CLR));
393         __raw_writel(1 << gpio,
394                 pm->irqpolarity + (p ? HW_STMP3xxx_SET : HW_STMP3xxx_CLR));
395         return 0;
396 }
397
398 static void stmp3xxx_pin_ack_irq(unsigned irq)
399 {
400         u32 stat;
401         struct stmp3xxx_pinmux_bank *pm;
402         unsigned gpio;
403
404         stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
405         stat = __raw_readl(pm->irqstat) & (1<<gpio);
406         __raw_writel(stat, pm->irqstat + HW_STMP3xxx_CLR);
407 }
408
409 static void stmp3xxx_pin_mask_irq(unsigned irq)
410 {
411         struct stmp3xxx_pinmux_bank *pm;
412         unsigned gpio;
413
414         stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
415         __raw_writel(1 << gpio, pm->irqen + HW_STMP3xxx_CLR);
416         __raw_writel(1 << gpio, pm->pin2irq + HW_STMP3xxx_CLR);
417 }
418
419 static void stmp3xxx_pin_unmask_irq(unsigned irq)
420 {
421         struct stmp3xxx_pinmux_bank *pm;
422         unsigned gpio;
423
424         stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
425         __raw_writel(1 << gpio, pm->irqen + HW_STMP3xxx_SET);
426         __raw_writel(1 << gpio, pm->pin2irq + HW_STMP3xxx_SET);
427 }
428
429 static inline
430 struct stmp3xxx_pinmux_bank *to_pinmux_bank(struct gpio_chip *chip)
431 {
432         return container_of(chip, struct stmp3xxx_pinmux_bank, chip);
433 }
434
435 static int stmp3xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
436 {
437         struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
438         return pm->virq + offset;
439 }
440
441 static int stmp3xxx_gpio_get(struct gpio_chip *chip, unsigned offset)
442 {
443         struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
444         unsigned v;
445
446         v = __raw_readl(pm->hw_gpio_read) & (1 << offset);
447         return v ? 1 : 0;
448 }
449
450 static void stmp3xxx_gpio_set(struct gpio_chip *chip, unsigned offset, int v)
451 {
452         struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
453
454         __raw_writel(1 << offset, v ? pm->hw_gpio_set : pm->hw_gpio_clr);
455 }
456
457 static int stmp3xxx_gpio_output(struct gpio_chip *chip, unsigned offset, int v)
458 {
459         struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
460
461         __raw_writel(1 << offset, pm->hw_gpio_doe + HW_STMP3xxx_SET);
462         stmp3xxx_gpio_set(chip, offset, v);
463         return 0;
464 }
465
466 static int stmp3xxx_gpio_input(struct gpio_chip *chip, unsigned offset)
467 {
468         struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
469
470         __raw_writel(1 << offset, pm->hw_gpio_doe + HW_STMP3xxx_CLR);
471         return 0;
472 }
473
474 static int stmp3xxx_gpio_request(struct gpio_chip *chip, unsigned offset)
475 {
476         return stmp3xxx_request_pin(chip->base + offset, PIN_GPIO, "gpio");
477 }
478
479 static void stmp3xxx_gpio_free(struct gpio_chip *chip, unsigned offset)
480 {
481         stmp3xxx_release_pin(chip->base + offset, "gpio");
482 }
483
484 static void stmp3xxx_gpio_irq(u32 irq, struct irq_desc *desc)
485 {
486         struct stmp3xxx_pinmux_bank *pm = get_irq_data(irq);
487         int gpio_irq = pm->virq;
488         u32 stat = __raw_readl(pm->irqstat);
489
490         while (stat) {
491                 if (stat & 1)
492                         irq_desc[gpio_irq].handle_irq(gpio_irq,
493                                 &irq_desc[gpio_irq]);
494                 gpio_irq++;
495                 stat >>= 1;
496         }
497 }
498
499 static struct irq_chip gpio_irq_chip = {
500         .ack    = stmp3xxx_pin_ack_irq,
501         .mask   = stmp3xxx_pin_mask_irq,
502         .unmask = stmp3xxx_pin_unmask_irq,
503         .set_type = stmp3xxx_set_irqtype,
504 };
505
506 int __init stmp3xxx_pinmux_init(int virtual_irq_start)
507 {
508         int b, r = 0;
509         struct stmp3xxx_pinmux_bank *pm;
510         int virq;
511
512         for (b = 0; b < 3; b++) {
513                 /* only banks 0,1,2 are allowed to GPIO */
514                 pm = pinmux_banks + b;
515                 pm->chip.base = 32 * b;
516                 pm->chip.ngpio = 32;
517                 pm->chip.owner = THIS_MODULE;
518                 pm->chip.can_sleep = 1;
519                 pm->chip.exported = 1;
520                 pm->chip.to_irq = stmp3xxx_gpio_to_irq;
521                 pm->chip.direction_input = stmp3xxx_gpio_input;
522                 pm->chip.direction_output = stmp3xxx_gpio_output;
523                 pm->chip.get = stmp3xxx_gpio_get;
524                 pm->chip.set = stmp3xxx_gpio_set;
525                 pm->chip.request = stmp3xxx_gpio_request;
526                 pm->chip.free = stmp3xxx_gpio_free;
527                 pm->virq = virtual_irq_start + b * 32;
528
529                 for (virq = pm->virq; virq < pm->virq; virq++) {
530                         gpio_irq_chip.mask(virq);
531                         set_irq_chip(virq, &gpio_irq_chip);
532                         set_irq_handler(virq, handle_level_irq);
533                         set_irq_flags(virq, IRQF_VALID);
534                 }
535                 r = gpiochip_add(&pm->chip);
536                 if (r < 0)
537                         break;
538                 set_irq_chained_handler(pm->irq, stmp3xxx_gpio_irq);
539                 set_irq_data(pm->irq, pm);
540         }
541         return r;
542 }
543
544 MODULE_AUTHOR("Vladislav Buzov");
545 MODULE_LICENSE("GPL");