Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.18-rc6 419 lines 10 kB view raw
1/* 2 * FILE NAME ite_gpio.c 3 * 4 * BRIEF MODULE DESCRIPTION 5 * API for ITE GPIO device. 6 * Driver for ITE GPIO device. 7 * 8 * Author: MontaVista Software, Inc. <source@mvista.com> 9 * Hai-Pao Fan <haipao@mvista.com> 10 * 11 * Copyright 2001 MontaVista Software Inc. 12 * 13 * This program is free software; you can redistribute it and/or modify it 14 * under the terms of the GNU General Public License as published by the 15 * Free Software Foundation; either version 2 of the License, or (at your 16 * option) any later version. 17 * 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * You should have received a copy of the GNU General Public License along 30 * with this program; if not, write to the Free Software Foundation, Inc., 31 * 675 Mass Ave, Cambridge, MA 02139, USA. 32 */ 33#include <linux/module.h> 34#include <linux/types.h> 35#include <linux/kernel.h> 36#include <linux/miscdevice.h> 37#include <linux/init.h> 38#include <linux/ioport.h> 39#include <asm/uaccess.h> 40#include <asm/addrspace.h> 41#include <asm/it8172/it8172_int.h> 42#include <linux/sched.h> 43#include <linux/ite_gpio.h> 44 45#define ite_gpio_base 0x14013800 46 47#define ITE_GPADR (*(volatile __u8 *)(0x14013800 + KSEG1)) 48#define ITE_GPBDR (*(volatile __u8 *)(0x14013808 + KSEG1)) 49#define ITE_GPCDR (*(volatile __u8 *)(0x14013810 + KSEG1)) 50#define ITE_GPACR (*(volatile __u16 *)(0x14013802 + KSEG1)) 51#define ITE_GPBCR (*(volatile __u16 *)(0x1401380a + KSEG1)) 52#define ITE_GPCCR (*(volatile __u16 *)(0x14013812 + KSEG1)) 53#define ITE_GPAICR (*(volatile __u16 *)(0x14013804 + KSEG1)) 54#define ITE_GPBICR (*(volatile __u16 *)(0x1401380c + KSEG1)) 55#define ITE_GPCICR (*(volatile __u16 *)(0x14013814 + KSEG1)) 56#define ITE_GPAISR (*(volatile __u8 *)(0x14013806 + KSEG1)) 57#define ITE_GPBISR (*(volatile __u8 *)(0x1401380e + KSEG1)) 58#define ITE_GPCISR (*(volatile __u8 *)(0x14013816 + KSEG1)) 59#define ITE_GCR (*(volatile __u8 *)(0x14013818 + KSEG1)) 60 61#define MAX_GPIO_LINE 21 62static int ite_gpio_irq=IT8172_GPIO_IRQ; 63 64static long ite_irq_counter[MAX_GPIO_LINE]; 65wait_queue_head_t ite_gpio_wait[MAX_GPIO_LINE]; 66static int ite_gpio_irq_pending[MAX_GPIO_LINE]; 67 68static int ite_gpio_debug=0; 69#define DEB(x) if (ite_gpio_debug>=1) x 70 71int ite_gpio_in(__u32 device, __u32 mask, volatile __u32 *data) 72{ 73 DEB(printk("ite_gpio_in mask=0x%x\n",mask)); 74 75 switch (device) { 76 case ITE_GPIO_PORTA: 77 ITE_GPACR = (__u16)mask; /* 0xffff */ 78 *data = ITE_GPADR; 79 break; 80 case ITE_GPIO_PORTB: 81 ITE_GPBCR = (__u16)mask; /* 0xffff */ 82 *data = ITE_GPBDR; 83 break; 84 case ITE_GPIO_PORTC: 85 ITE_GPCCR = (__u16)mask; /* 0x03ff */ 86 *data = ITE_GPCDR; 87 break; 88 default: 89 return -EFAULT; 90 } 91 92 return 0; 93} 94 95 96int ite_gpio_out(__u32 device, __u32 mask, __u32 data) 97{ 98 switch (device) { 99 case ITE_GPIO_PORTA: 100 ITE_GPACR = (__u16)mask; /* 0x5555 */ 101 ITE_GPADR = (__u8)data; 102 break; 103 case ITE_GPIO_PORTB: 104 ITE_GPBCR = (__u16)mask; /* 0x5555 */ 105 ITE_GPBDR = (__u8)data; 106 break; 107 case ITE_GPIO_PORTC: 108 ITE_GPCCR = (__u16)mask; /* 0x0155 */ 109 ITE_GPCDR = (__u8)data; 110 break; 111 default: 112 return -EFAULT; 113 } 114 115 return 0; 116} 117 118int ite_gpio_int_ctrl(__u32 device, __u32 mask, __u32 data) 119{ 120 switch (device) { 121 case ITE_GPIO_PORTA: 122 ITE_GPAICR = (ITE_GPAICR & ~mask) | (data & mask); 123 break; 124 case ITE_GPIO_PORTB: 125 ITE_GPBICR = (ITE_GPBICR & ~mask) | (data & mask); 126 break; 127 case ITE_GPIO_PORTC: 128 ITE_GPCICR = (ITE_GPCICR & ~mask) | (data & mask); 129 break; 130 default: 131 return -EFAULT; 132 } 133 134 return 0; 135} 136 137int ite_gpio_in_status(__u32 device, __u32 mask, volatile __u32 *data) 138{ 139 int ret=-1; 140 141 if ((MAX_GPIO_LINE > *data) && (*data >= 0)) 142 ret=ite_gpio_irq_pending[*data]; 143 144 DEB(printk("ite_gpio_in_status %d ret=%d\n",*data, ret)); 145 146 switch (device) { 147 case ITE_GPIO_PORTA: 148 *data = ITE_GPAISR & mask; 149 break; 150 case ITE_GPIO_PORTB: 151 *data = ITE_GPBISR & mask; 152 break; 153 case ITE_GPIO_PORTC: 154 *data = ITE_GPCISR & mask; 155 break; 156 default: 157 return -EFAULT; 158 } 159 160 return ret; 161} 162 163int ite_gpio_out_status(__u32 device, __u32 mask, __u32 data) 164{ 165 switch (device) { 166 case ITE_GPIO_PORTA: 167 ITE_GPAISR = (ITE_GPAISR & ~mask) | (data & mask); 168 break; 169 case ITE_GPIO_PORTB: 170 ITE_GPBISR = (ITE_GPBISR & ~mask) | (data & mask); 171 break; 172 case ITE_GPIO_PORTC: 173 ITE_GPCISR = (ITE_GPCISR & ~mask) | (data & mask); 174 break; 175 default: 176 return -EFAULT; 177 } 178 179 return 0; 180} 181 182int ite_gpio_gen_ctrl(__u32 device, __u32 mask, __u32 data) 183{ 184 ITE_GCR = (ITE_GCR & ~mask) | (data & mask); 185 186 return 0; 187} 188 189int ite_gpio_int_wait (__u32 device, __u32 mask, __u32 data) 190{ 191 int i,line=0, ret=0; 192 unsigned long flags; 193 194 switch (device) { 195 case ITE_GPIO_PORTA: 196 line = data & mask; 197 break; 198 case ITE_GPIO_PORTB: 199 line = (data & mask) <<8; 200 break; 201 case ITE_GPIO_PORTC: 202 line = (data & mask) <<16; 203 break; 204 } 205 for (i=MAX_GPIO_LINE-1; i >= 0; i--) { 206 if ( (line) & (1 << i)) 207 break; 208 } 209 210 DEB(printk("wait device=0x%d mask=0x%x data=0x%x index %d\n", 211 device, mask, data, i)); 212 213 if (line & ~(1<<i)) 214 return -EFAULT; 215 216 if (ite_gpio_irq_pending[i]==1) 217 return -EFAULT; 218 219 save_flags (flags); 220 cli(); 221 ite_gpio_irq_pending[i] = 1; 222 ret = interruptible_sleep_on_timeout(&ite_gpio_wait[i], 3*HZ); 223 restore_flags (flags); 224 ite_gpio_irq_pending[i] = 0; 225 226 return ret; 227} 228 229EXPORT_SYMBOL(ite_gpio_in); 230EXPORT_SYMBOL(ite_gpio_out); 231EXPORT_SYMBOL(ite_gpio_int_ctrl); 232EXPORT_SYMBOL(ite_gpio_in_status); 233EXPORT_SYMBOL(ite_gpio_out_status); 234EXPORT_SYMBOL(ite_gpio_gen_ctrl); 235EXPORT_SYMBOL(ite_gpio_int_wait); 236 237static int ite_gpio_open(struct inode *inode, struct file *file) 238{ 239 return 0; 240} 241 242 243static int ite_gpio_release(struct inode *inode, struct file *file) 244{ 245 return 0; 246} 247 248 249static int ite_gpio_ioctl(struct inode *inode, struct file *file, 250 unsigned int cmd, unsigned long arg) 251{ 252 static struct ite_gpio_ioctl_data ioctl_data; 253 254 if (copy_from_user(&ioctl_data, (struct ite_gpio_ioctl_data *)arg, 255 sizeof(ioctl_data))) 256 return -EFAULT; 257 if ((ioctl_data.device < ITE_GPIO_PORTA) || 258 (ioctl_data.device > ITE_GPIO_PORTC) ) 259 return -EFAULT; 260 261 switch(cmd) { 262 case ITE_GPIO_IN: 263 if (ite_gpio_in(ioctl_data.device, ioctl_data.mask, 264 &ioctl_data.data)) 265 return -EFAULT; 266 267 if (copy_to_user((struct ite_gpio_ioctl_data *)arg, 268 &ioctl_data, sizeof(ioctl_data))) 269 return -EFAULT; 270 break; 271 272 case ITE_GPIO_OUT: 273 return ite_gpio_out(ioctl_data.device, 274 ioctl_data.mask, ioctl_data.data); 275 break; 276 277 case ITE_GPIO_INT_CTRL: 278 return ite_gpio_int_ctrl(ioctl_data.device, 279 ioctl_data.mask, ioctl_data.data); 280 break; 281 282 case ITE_GPIO_IN_STATUS: 283 if (ite_gpio_in_status(ioctl_data.device, ioctl_data.mask, 284 &ioctl_data.data)) 285 return -EFAULT; 286 if (copy_to_user((struct ite_gpio_ioctl_data *)arg, 287 &ioctl_data, sizeof(ioctl_data))) 288 return -EFAULT; 289 break; 290 291 case ITE_GPIO_OUT_STATUS: 292 return ite_gpio_out_status(ioctl_data.device, 293 ioctl_data.mask, ioctl_data.data); 294 break; 295 296 case ITE_GPIO_GEN_CTRL: 297 return ite_gpio_gen_ctrl(ioctl_data.device, 298 ioctl_data.mask, ioctl_data.data); 299 break; 300 301 case ITE_GPIO_INT_WAIT: 302 return ite_gpio_int_wait(ioctl_data.device, 303 ioctl_data.mask, ioctl_data.data); 304 break; 305 306 default: 307 return -ENOIOCTLCMD; 308 309 } 310 311 return 0; 312} 313 314static void ite_gpio_irq_handler(int this_irq, void *dev_id, 315 struct pt_regs *regs) 316{ 317 int i,line; 318 319 line = ITE_GPCISR & 0x1f; 320 for (i=4; i >=0; i--) { 321 if ( line & (1 << i)) { 322 ++ite_irq_counter[i+16]; 323 ite_gpio_irq_pending[i+16] = 2; 324 wake_up_interruptible(&ite_gpio_wait[i+16]); 325 326DEB(printk("interrupt 0x%x %d\n", &ite_gpio_wait[i+16], i+16)); 327 328 ITE_GPCISR = ITE_GPCISR & (1<<i); 329 return; 330 } 331 } 332 line = ITE_GPBISR; 333 for (i=7; i >= 0; i--) { 334 if ( line & (1 << i)) { 335 ++ite_irq_counter[i+8]; 336 ite_gpio_irq_pending[i+8] = 2; 337 wake_up_interruptible(&ite_gpio_wait[i+8]); 338 339DEB(printk("interrupt 0x%x %d\n",ITE_GPBISR, i+8)); 340 341 ITE_GPBISR = ITE_GPBISR & (1<<i); 342 return; 343 } 344 } 345 line = ITE_GPAISR; 346 for (i=7; i >= 0; i--) { 347 if ( line & (1 << i)) { 348 ++ite_irq_counter[i]; 349 ite_gpio_irq_pending[i] = 2; 350 wake_up_interruptible(&ite_gpio_wait[i]); 351 352DEB(printk("interrupt 0x%x %d\n",ITE_GPAISR, i)); 353 354 ITE_GPAISR = ITE_GPAISR & (1<<i); 355 return; 356 } 357 } 358} 359 360static const struct file_operations ite_gpio_fops = { 361 .owner = THIS_MODULE, 362 .ioctl = ite_gpio_ioctl, 363 .open = ite_gpio_open, 364 .release = ite_gpio_release, 365}; 366 367static struct miscdevice ite_gpio_miscdev = { 368 MISC_DYNAMIC_MINOR, 369 "ite_gpio", 370 &ite_gpio_fops 371}; 372 373int __init ite_gpio_init(void) 374{ 375 int i; 376 377 if (misc_register(&ite_gpio_miscdev)) 378 return -ENODEV; 379 380 if (!request_region(ite_gpio_base, 0x1c, "ITE GPIO")) 381 { 382 misc_deregister(&ite_gpio_miscdev); 383 return -EIO; 384 } 385 386 /* initialize registers */ 387 ITE_GPACR = 0xffff; 388 ITE_GPBCR = 0xffff; 389 ITE_GPCCR = 0xffff; 390 ITE_GPAICR = 0x00ff; 391 ITE_GPBICR = 0x00ff; 392 ITE_GPCICR = 0x00ff; 393 ITE_GCR = 0; 394 395 for (i = 0; i < MAX_GPIO_LINE; i++) { 396 ite_gpio_irq_pending[i]=0; 397 init_waitqueue_head(&ite_gpio_wait[i]); 398 } 399 400 if (request_irq(ite_gpio_irq, ite_gpio_irq_handler, IRQF_SHARED, "gpio", 0) < 0) { 401 misc_deregister(&ite_gpio_miscdev); 402 release_region(ite_gpio_base, 0x1c); 403 return 0; 404 } 405 406 printk("GPIO at 0x%x (irq = %d)\n", ite_gpio_base, ite_gpio_irq); 407 408 return 0; 409} 410 411static void __exit ite_gpio_exit(void) 412{ 413 misc_deregister(&ite_gpio_miscdev); 414} 415 416module_init(ite_gpio_init); 417module_exit(ite_gpio_exit); 418 419MODULE_LICENSE("GPL");