Blame view
drivers/gpio/gpio-ks8695.c
7.16 KB
8a87a996e [ARM] 4377/1: KS8... |
1 2 3 4 |
/* * arch/arm/mach-ks8695/gpio.c * * Copyright (C) 2006 Andrew Victor |
72880ad86 [ARM] KS8695: Fix... |
5 6 |
* Updated to GPIOLIB, Copyright 2008 Simtec Electronics * Daniel Silverstone <dsilvers@simtec.co.uk> |
8a87a996e [ARM] 4377/1: KS8... |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
2f8163baa ARM: gpio: conver... |
21 |
#include <linux/gpio.h> |
8a87a996e [ARM] 4377/1: KS8... |
22 23 24 |
#include <linux/kernel.h> #include <linux/mm.h> #include <linux/init.h> |
20118ff97 [ARM] 4603/1: KS8... |
25 26 |
#include <linux/debugfs.h> #include <linux/seq_file.h> |
8a87a996e [ARM] 4377/1: KS8... |
27 |
#include <linux/module.h> |
fced80c73 [ARM] Convert asm... |
28 |
#include <linux/io.h> |
8a87a996e [ARM] 4377/1: KS8... |
29 |
|
a09e64fbc [ARM] Move includ... |
30 |
#include <mach/hardware.h> |
8a87a996e [ARM] 4377/1: KS8... |
31 |
#include <asm/mach/irq.h> |
a09e64fbc [ARM] Move includ... |
32 |
#include <mach/regs-gpio.h> |
e24e4498c ARM: 7036/1: mach... |
33 |
#include <mach/gpio-ks8695.h> |
8a87a996e [ARM] 4377/1: KS8... |
34 35 36 37 38 |
/* * Configure a GPIO line for either GPIO function, or its internal * function (Interrupt, Timer, etc). */ |
72880ad86 [ARM] KS8695: Fix... |
39 |
static void ks8695_gpio_mode(unsigned int pin, short gpio) |
8a87a996e [ARM] 4377/1: KS8... |
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
{ unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN }; unsigned long x, flags; if (pin > KS8695_GPIO_5) /* only GPIO 0..5 have internal functions */ return; local_irq_save(flags); x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC); if (gpio) /* GPIO: set bit to 0 */ x &= ~enable[pin]; else /* Internal function: set bit to 1 */ x |= enable[pin]; __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPC); local_irq_restore(flags); } static unsigned short gpio_irq[] = { KS8695_IRQ_EXTERN0, KS8695_IRQ_EXTERN1, KS8695_IRQ_EXTERN2, KS8695_IRQ_EXTERN3 }; /* * Configure GPIO pin as external interrupt source. */ |
72880ad86 [ARM] KS8695: Fix... |
65 |
int ks8695_gpio_interrupt(unsigned int pin, unsigned int type) |
8a87a996e [ARM] 4377/1: KS8... |
66 67 68 69 70 71 72 73 74 75 |
{ unsigned long x, flags; if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */ return -EINVAL; local_irq_save(flags); /* set pin as input */ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); |
8d163b3fa [ARM] 5296/1: [KS... |
76 |
x &= ~IOPM(pin); |
8a87a996e [ARM] 4377/1: KS8... |
77 78 79 80 81 |
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM); local_irq_restore(flags); /* Set IRQ triggering type */ |
6845664a6 arm: Cleanup the ... |
82 |
irq_set_irq_type(gpio_irq[pin], type); |
8a87a996e [ARM] 4377/1: KS8... |
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
/* enable interrupt mode */ ks8695_gpio_mode(pin, 0); return 0; } EXPORT_SYMBOL(ks8695_gpio_interrupt); /* .... Generic GPIO interface .............................................. */ /* * Configure the GPIO line as an input. */ |
72880ad86 [ARM] KS8695: Fix... |
98 |
static int ks8695_gpio_direction_input(struct gpio_chip *gc, unsigned int pin) |
8a87a996e [ARM] 4377/1: KS8... |
99 100 101 102 103 104 105 106 107 108 109 110 111 |
{ unsigned long x, flags; if (pin > KS8695_GPIO_15) return -EINVAL; /* set pin to GPIO mode */ ks8695_gpio_mode(pin, 1); local_irq_save(flags); /* set pin as input */ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); |
8d163b3fa [ARM] 5296/1: [KS... |
112 |
x &= ~IOPM(pin); |
8a87a996e [ARM] 4377/1: KS8... |
113 114 115 116 117 118 |
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM); local_irq_restore(flags); return 0; } |
8a87a996e [ARM] 4377/1: KS8... |
119 120 121 122 123 |
/* * Configure the GPIO line as an output, with default state. */ |
72880ad86 [ARM] KS8695: Fix... |
124 125 |
static int ks8695_gpio_direction_output(struct gpio_chip *gc, unsigned int pin, int state) |
8a87a996e [ARM] 4377/1: KS8... |
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
{ unsigned long x, flags; if (pin > KS8695_GPIO_15) return -EINVAL; /* set pin to GPIO mode */ ks8695_gpio_mode(pin, 1); local_irq_save(flags); /* set line state */ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); if (state) |
8d163b3fa [ARM] 5296/1: [KS... |
140 |
x |= IOPD(pin); |
8a87a996e [ARM] 4377/1: KS8... |
141 |
else |
8d163b3fa [ARM] 5296/1: [KS... |
142 |
x &= ~IOPD(pin); |
8a87a996e [ARM] 4377/1: KS8... |
143 144 145 146 |
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD); /* set pin as output */ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); |
8d163b3fa [ARM] 5296/1: [KS... |
147 |
x |= IOPM(pin); |
8a87a996e [ARM] 4377/1: KS8... |
148 149 150 151 152 153 |
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM); local_irq_restore(flags); return 0; } |
8a87a996e [ARM] 4377/1: KS8... |
154 155 156 157 158 |
/* * Set the state of an output GPIO line. */ |
72880ad86 [ARM] KS8695: Fix... |
159 160 |
static void ks8695_gpio_set_value(struct gpio_chip *gc, unsigned int pin, int state) |
8a87a996e [ARM] 4377/1: KS8... |
161 162 163 164 165 166 167 168 169 170 171 |
{ unsigned long x, flags; if (pin > KS8695_GPIO_15) return; local_irq_save(flags); /* set output line state */ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); if (state) |
8d163b3fa [ARM] 5296/1: [KS... |
172 |
x |= IOPD(pin); |
8a87a996e [ARM] 4377/1: KS8... |
173 |
else |
8d163b3fa [ARM] 5296/1: [KS... |
174 |
x &= ~IOPD(pin); |
8a87a996e [ARM] 4377/1: KS8... |
175 176 177 178 |
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD); local_irq_restore(flags); } |
8a87a996e [ARM] 4377/1: KS8... |
179 180 181 182 183 |
/* * Read the state of a GPIO line. */ |
72880ad86 [ARM] KS8695: Fix... |
184 |
static int ks8695_gpio_get_value(struct gpio_chip *gc, unsigned int pin) |
8a87a996e [ARM] 4377/1: KS8... |
185 186 187 188 189 190 191 |
{ unsigned long x; if (pin > KS8695_GPIO_15) return -EINVAL; x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); |
8d163b3fa [ARM] 5296/1: [KS... |
192 |
return (x & IOPD(pin)) != 0; |
8a87a996e [ARM] 4377/1: KS8... |
193 |
} |
8a87a996e [ARM] 4377/1: KS8... |
194 195 196 197 198 |
/* * Map GPIO line to IRQ number. */ |
7ef71320e [ARM] KS8695: Add... |
199 |
static int ks8695_gpio_to_irq(struct gpio_chip *gc, unsigned int pin) |
8a87a996e [ARM] 4377/1: KS8... |
200 201 202 203 204 205 |
{ if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */ return -EINVAL; return gpio_irq[pin]; } |
8a87a996e [ARM] 4377/1: KS8... |
206 |
|
72880ad86 [ARM] KS8695: Fix... |
207 208 209 210 211 212 213 214 |
/* GPIOLIB interface */ static struct gpio_chip ks8695_gpio_chip = { .label = "KS8695", .direction_input = ks8695_gpio_direction_input, .direction_output = ks8695_gpio_direction_output, .get = ks8695_gpio_get_value, .set = ks8695_gpio_set_value, |
7ef71320e [ARM] KS8695: Add... |
215 |
.to_irq = ks8695_gpio_to_irq, |
72880ad86 [ARM] KS8695: Fix... |
216 217 |
.base = 0, .ngpio = 16, |
9fb1f39eb gpio/pinctrl: mak... |
218 |
.can_sleep = false, |
72880ad86 [ARM] KS8695: Fix... |
219 220 221 222 223 |
}; /* Register the GPIOs */ void ks8695_register_gpios(void) { |
4eab22e74 gpio: convert rem... |
224 |
if (gpiochip_add_data(&ks8695_gpio_chip, NULL)) |
72880ad86 [ARM] KS8695: Fix... |
225 226 227 |
printk(KERN_ERR "Unable to register core GPIOs "); } |
20118ff97 [ARM] 4603/1: KS8... |
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
/* .... Debug interface ..................................................... */ #ifdef CONFIG_DEBUG_FS static int ks8695_gpio_show(struct seq_file *s, void *unused) { unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN }; unsigned int intmask[] = { IOPC_IOEINT0TM, IOPC_IOEINT1TM, IOPC_IOEINT2TM, IOPC_IOEINT3TM }; unsigned long mode, ctrl, data; int i; mode = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC); data = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); seq_printf(s, "Pin\tI/O\tFunction\tState "); for (i = KS8695_GPIO_0; i <= KS8695_GPIO_15 ; i++) { seq_printf(s, "%i:\t", i); |
8d163b3fa [ARM] 5296/1: [KS... |
250 |
seq_printf(s, "%s\t", (mode & IOPM(i)) ? "Output" : "Input"); |
20118ff97 [ARM] 4603/1: KS8... |
251 252 253 254 255 256 |
if (i <= KS8695_GPIO_3) { if (ctrl & enable[i]) { seq_printf(s, "EXT%i ", i); switch ((ctrl & intmask[i]) >> (4 * i)) { |
0397375dc gpio: ks8695: fix... |
257 258 259 260 261 262 263 264 265 266 |
case IOPC_TM_LOW: seq_printf(s, "(Low)"); break; case IOPC_TM_HIGH: seq_printf(s, "(High)"); break; case IOPC_TM_RISING: seq_printf(s, "(Rising)"); break; case IOPC_TM_FALLING: seq_printf(s, "(Falling)"); break; case IOPC_TM_EDGE: seq_printf(s, "(Edges)"); break; |
20118ff97 [ARM] 4603/1: KS8... |
267 |
} |
36905a33d gpio: ks8695: fix... |
268 |
} else |
20118ff97 [ARM] 4603/1: KS8... |
269 |
seq_printf(s, "GPIO\t"); |
36905a33d gpio: ks8695: fix... |
270 |
} else if (i <= KS8695_GPIO_5) { |
20118ff97 [ARM] 4603/1: KS8... |
271 272 273 274 |
if (ctrl & enable[i]) seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4); else seq_printf(s, "GPIO\t"); |
36905a33d gpio: ks8695: fix... |
275 |
} else { |
20118ff97 [ARM] 4603/1: KS8... |
276 |
seq_printf(s, "GPIO\t"); |
36905a33d gpio: ks8695: fix... |
277 |
} |
20118ff97 [ARM] 4603/1: KS8... |
278 279 |
seq_printf(s, "\t"); |
8d163b3fa [ARM] 5296/1: [KS... |
280 281 |
seq_printf(s, "%i ", (data & IOPD(i)) ? 1 : 0); |
20118ff97 [ARM] 4603/1: KS8... |
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
} return 0; } static int ks8695_gpio_open(struct inode *inode, struct file *file) { return single_open(file, ks8695_gpio_show, NULL); } static const struct file_operations ks8695_gpio_operations = { .open = ks8695_gpio_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static int __init ks8695_gpio_debugfs_init(void) { /* /sys/kernel/debug/ks8695_gpio */ (void) debugfs_create_file("ks8695_gpio", S_IFREG | S_IRUGO, NULL, NULL, &ks8695_gpio_operations); return 0; } postcore_initcall(ks8695_gpio_debugfs_init); #endif |