Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[ARM] 4377/1: KS8695: GPIO driver

Driver to control the GPIO pins on the KS8695 processor.
The driver natively supports the Generic GPIO interface.

Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Andrew Victor and committed by
Russell King
8a87a996 7dcca30a

+299 -1
+1
arch/arm/Kconfig
··· 308 308 309 309 config ARCH_KS8695 310 310 bool "Micrel/Kendin KS8695" 311 + select GENERIC_GPIO 311 312 help 312 313 Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based 313 314 System-on-Chip devices.
+1 -1
arch/arm/mach-ks8695/Makefile
··· 3 3 # Makefile for KS8695 architecture support 4 4 # 5 5 6 - obj-y := cpu.o irq.o time.o devices.o 6 + obj-y := cpu.o irq.o time.o gpio.o devices.o 7 7 obj-m := 8 8 obj-n := 9 9 obj- :=
+218
arch/arm/mach-ks8695/gpio.c
··· 1 + /* 2 + * arch/arm/mach-ks8695/gpio.c 3 + * 4 + * Copyright (C) 2006 Andrew Victor 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 + */ 19 + 20 + #include <linux/kernel.h> 21 + #include <linux/mm.h> 22 + #include <linux/init.h> 23 + #include <linux/module.h> 24 + 25 + #include <asm/io.h> 26 + #include <asm/hardware.h> 27 + #include <asm/mach/irq.h> 28 + 29 + #include <asm/arch/regs-gpio.h> 30 + #include <asm/arch/gpio.h> 31 + 32 + /* 33 + * Configure a GPIO line for either GPIO function, or its internal 34 + * function (Interrupt, Timer, etc). 35 + */ 36 + static void __init_or_module ks8695_gpio_mode(unsigned int pin, short gpio) 37 + { 38 + unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN }; 39 + unsigned long x, flags; 40 + 41 + if (pin > KS8695_GPIO_5) /* only GPIO 0..5 have internal functions */ 42 + return; 43 + 44 + local_irq_save(flags); 45 + 46 + x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC); 47 + if (gpio) /* GPIO: set bit to 0 */ 48 + x &= ~enable[pin]; 49 + else /* Internal function: set bit to 1 */ 50 + x |= enable[pin]; 51 + __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPC); 52 + 53 + local_irq_restore(flags); 54 + } 55 + 56 + 57 + static unsigned short gpio_irq[] = { KS8695_IRQ_EXTERN0, KS8695_IRQ_EXTERN1, KS8695_IRQ_EXTERN2, KS8695_IRQ_EXTERN3 }; 58 + 59 + /* 60 + * Configure GPIO pin as external interrupt source. 61 + */ 62 + int __init_or_module ks8695_gpio_interrupt(unsigned int pin, unsigned int type) 63 + { 64 + unsigned long x, flags; 65 + 66 + if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */ 67 + return -EINVAL; 68 + 69 + local_irq_save(flags); 70 + 71 + /* set pin as input */ 72 + x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); 73 + x &= ~IOPM_(pin); 74 + __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM); 75 + 76 + local_irq_restore(flags); 77 + 78 + /* Set IRQ triggering type */ 79 + set_irq_type(gpio_irq[pin], type); 80 + 81 + /* enable interrupt mode */ 82 + ks8695_gpio_mode(pin, 0); 83 + 84 + return 0; 85 + } 86 + EXPORT_SYMBOL(ks8695_gpio_interrupt); 87 + 88 + 89 + 90 + /* .... Generic GPIO interface .............................................. */ 91 + 92 + /* 93 + * Configure the GPIO line as an input. 94 + */ 95 + int __init_or_module gpio_direction_input(unsigned int pin) 96 + { 97 + unsigned long x, flags; 98 + 99 + if (pin > KS8695_GPIO_15) 100 + return -EINVAL; 101 + 102 + /* set pin to GPIO mode */ 103 + ks8695_gpio_mode(pin, 1); 104 + 105 + local_irq_save(flags); 106 + 107 + /* set pin as input */ 108 + x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); 109 + x &= ~IOPM_(pin); 110 + __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM); 111 + 112 + local_irq_restore(flags); 113 + 114 + return 0; 115 + } 116 + EXPORT_SYMBOL(gpio_direction_input); 117 + 118 + 119 + /* 120 + * Configure the GPIO line as an output, with default state. 121 + */ 122 + int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state) 123 + { 124 + unsigned long x, flags; 125 + 126 + if (pin > KS8695_GPIO_15) 127 + return -EINVAL; 128 + 129 + /* set pin to GPIO mode */ 130 + ks8695_gpio_mode(pin, 1); 131 + 132 + local_irq_save(flags); 133 + 134 + /* set line state */ 135 + x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); 136 + if (state) 137 + x |= (1 << pin); 138 + else 139 + x &= ~(1 << pin); 140 + __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD); 141 + 142 + /* set pin as output */ 143 + x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); 144 + x |= IOPM_(pin); 145 + __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM); 146 + 147 + local_irq_restore(flags); 148 + 149 + return 0; 150 + } 151 + EXPORT_SYMBOL(gpio_direction_output); 152 + 153 + 154 + /* 155 + * Set the state of an output GPIO line. 156 + */ 157 + void gpio_set_value(unsigned int pin, unsigned int state) 158 + { 159 + unsigned long x, flags; 160 + 161 + if (pin > KS8695_GPIO_15) 162 + return; 163 + 164 + local_irq_save(flags); 165 + 166 + /* set output line state */ 167 + x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); 168 + if (state) 169 + x |= (1 << pin); 170 + else 171 + x &= ~(1 << pin); 172 + __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD); 173 + 174 + local_irq_restore(flags); 175 + } 176 + EXPORT_SYMBOL(gpio_set_value); 177 + 178 + 179 + /* 180 + * Read the state of a GPIO line. 181 + */ 182 + int gpio_get_value(unsigned int pin) 183 + { 184 + unsigned long x; 185 + 186 + if (pin > KS8695_GPIO_15) 187 + return -EINVAL; 188 + 189 + x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); 190 + return (x & (1 << pin)) != 0; 191 + } 192 + EXPORT_SYMBOL(gpio_get_value); 193 + 194 + 195 + /* 196 + * Map GPIO line to IRQ number. 197 + */ 198 + int gpio_to_irq(unsigned int pin) 199 + { 200 + if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */ 201 + return -EINVAL; 202 + 203 + return gpio_irq[pin]; 204 + } 205 + EXPORT_SYMBOL(gpio_to_irq); 206 + 207 + 208 + /* 209 + * Map IRQ number to GPIO line. 210 + */ 211 + int 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 + } 218 + EXPORT_SYMBOL(irq_to_gpio);
+79
include/asm-arm/arch-ks8695/gpio.h
··· 1 + /* 2 + * include/asm-arm/arch-ks8695/gpio.h 3 + * 4 + * Copyright (C) 2006 Andrew Victor 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #ifndef __ASM_ARCH_GPIO_H_ 12 + #define __ASM_ARCH_GPIO_H_ 13 + 14 + #define KS8695_GPIO_0 0 15 + #define KS8695_GPIO_1 1 16 + #define KS8695_GPIO_2 2 17 + #define KS8695_GPIO_3 3 18 + #define KS8695_GPIO_4 4 19 + #define KS8695_GPIO_5 5 20 + #define KS8695_GPIO_6 6 21 + #define KS8695_GPIO_7 7 22 + #define KS8695_GPIO_8 8 23 + #define KS8695_GPIO_9 9 24 + #define KS8695_GPIO_10 10 25 + #define KS8695_GPIO_11 11 26 + #define KS8695_GPIO_12 12 27 + #define KS8695_GPIO_13 13 28 + #define KS8695_GPIO_14 14 29 + #define KS8695_GPIO_15 15 30 + 31 + 32 + /* 33 + * Configure GPIO pin as external interrupt source. 34 + */ 35 + int __init_or_module ks8695_gpio_interrupt(unsigned int pin, unsigned int type); 36 + 37 + /* 38 + * Configure the GPIO line as an input. 39 + */ 40 + int __init_or_module gpio_direction_input(unsigned int pin); 41 + 42 + /* 43 + * Configure the GPIO line as an output, with default state. 44 + */ 45 + int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state); 46 + 47 + /* 48 + * Set the state of an output GPIO line. 49 + */ 50 + void gpio_set_value(unsigned int pin, unsigned int state); 51 + 52 + /* 53 + * Read the state of a GPIO line. 54 + */ 55 + int gpio_get_value(unsigned int pin); 56 + 57 + /* 58 + * Map GPIO line to IRQ number. 59 + */ 60 + int gpio_to_irq(unsigned int pin); 61 + 62 + /* 63 + * Map IRQ number to GPIO line. 64 + */ 65 + int irq_to_gpio(unsigned int irq); 66 + 67 + 68 + #include <asm-generic/gpio.h> 69 + 70 + static inline int gpio_request(unsigned int pin, const char *label) 71 + { 72 + return 0; 73 + } 74 + 75 + static inline void gpio_free(unsigned int pin) 76 + { 77 + } 78 + 79 + #endif