Merge branch 'topic/hda' into for-linus
[pandora-kernel.git] / arch / xtensa / variants / s6000 / gpio.c
1 /*
2  * s6000 gpio driver
3  *
4  * Copyright (c) 2009 emlix GmbH
5  * Authors:     Oskar Schirmer <os@emlix.com>
6  *              Johannes Weiner <jw@emlix.com>
7  */
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/io.h>
12 #include <linux/gpio.h>
13
14 #include <variant/hardware.h>
15
16 #define S6_GPIO_DATA            0x000
17 #define S6_GPIO_IS              0x404
18 #define S6_GPIO_IBE             0x408
19 #define S6_GPIO_IEV             0x40C
20 #define S6_GPIO_IE              0x410
21 #define S6_GPIO_RIS             0x414
22 #define S6_GPIO_MIS             0x418
23 #define S6_GPIO_IC              0x41C
24 #define S6_GPIO_AFSEL           0x420
25 #define S6_GPIO_DIR             0x800
26 #define S6_GPIO_BANK(nr)        ((nr) * 0x1000)
27 #define S6_GPIO_MASK(nr)        (4 << (nr))
28 #define S6_GPIO_OFFSET(nr) \
29                 (S6_GPIO_BANK((nr) >> 3) + S6_GPIO_MASK((nr) & 7))
30
31 static int direction_input(struct gpio_chip *chip, unsigned int off)
32 {
33         writeb(0, S6_REG_GPIO + S6_GPIO_DIR + S6_GPIO_OFFSET(off));
34         return 0;
35 }
36
37 static int get(struct gpio_chip *chip, unsigned int off)
38 {
39         return readb(S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
40 }
41
42 static int direction_output(struct gpio_chip *chip, unsigned int off, int val)
43 {
44         unsigned rel = S6_GPIO_OFFSET(off);
45         writeb(~0, S6_REG_GPIO + S6_GPIO_DIR + rel);
46         writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + rel);
47         return 0;
48 }
49
50 static void set(struct gpio_chip *chip, unsigned int off, int val)
51 {
52         writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
53 }
54
55 static struct gpio_chip gpiochip = {
56         .owner = THIS_MODULE,
57         .direction_input = direction_input,
58         .get = get,
59         .direction_output = direction_output,
60         .set = set,
61         .base = 0,
62         .ngpio = 24,
63         .can_sleep = 0, /* no blocking io needed */
64         .exported = 0, /* no exporting to userspace */
65 };
66
67 int s6_gpio_init(void)
68 {
69         return gpiochip_add(&gpiochip);
70 }