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