4 * Copyright (c) 2009 emlix GmbH
5 * Authors: Oskar Schirmer <os@emlix.com>
6 * Johannes Weiner <jw@emlix.com>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
12 #include <linux/gpio.h>
14 #include <variant/hardware.h>
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))
31 static int direction_input(struct gpio_chip
*chip
, unsigned int off
)
33 writeb(0, S6_REG_GPIO
+ S6_GPIO_DIR
+ S6_GPIO_OFFSET(off
));
37 static int get(struct gpio_chip
*chip
, unsigned int off
)
39 return readb(S6_REG_GPIO
+ S6_GPIO_DATA
+ S6_GPIO_OFFSET(off
));
42 static int direction_output(struct gpio_chip
*chip
, unsigned int off
, int val
)
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
);
50 static void set(struct gpio_chip
*chip
, unsigned int off
, int val
)
52 writeb(val
? ~0 : 0, S6_REG_GPIO
+ S6_GPIO_DATA
+ S6_GPIO_OFFSET(off
));
55 static struct gpio_chip gpiochip
= {
57 .direction_input
= direction_input
,
59 .direction_output
= direction_output
,
63 .can_sleep
= 0, /* no blocking io needed */
64 .exported
= 0, /* no exporting to userspace */
67 int s6_gpio_init(void)
69 return gpiochip_add(&gpiochip
);