1/* 2 * Driver for NEC VR4100 series General-purpose I/O Unit. 3 * 4 * Copyright (C) 2002 MontaVista Software Inc. 5 * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com> 6 * Copyright (C) 2003-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> 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 as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22#include <linux/errno.h> 23#include <linux/fs.h> 24#include <linux/init.h> 25#include <linux/interrupt.h> 26#include <linux/irq.h> 27#include <linux/kernel.h> 28#include <linux/module.h> 29#include <linux/platform_device.h> 30#include <linux/spinlock.h> 31#include <linux/types.h> 32 33#include <asm/io.h> 34#include <asm/vr41xx/giu.h> 35#include <asm/vr41xx/irq.h> 36#include <asm/vr41xx/vr41xx.h> 37 38MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); 39MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver"); 40MODULE_LICENSE("GPL"); 41 42static int major; /* default is dynamic major device number */ 43module_param(major, int, 0); 44MODULE_PARM_DESC(major, "Major device number"); 45 46#define GIUIOSELL 0x00 47#define GIUIOSELH 0x02 48#define GIUPIODL 0x04 49#define GIUPIODH 0x06 50#define GIUINTSTATL 0x08 51#define GIUINTSTATH 0x0a 52#define GIUINTENL 0x0c 53#define GIUINTENH 0x0e 54#define GIUINTTYPL 0x10 55#define GIUINTTYPH 0x12 56#define GIUINTALSELL 0x14 57#define GIUINTALSELH 0x16 58#define GIUINTHTSELL 0x18 59#define GIUINTHTSELH 0x1a 60#define GIUPODATL 0x1c 61#define GIUPODATEN 0x1c 62#define GIUPODATH 0x1e 63 #define PIOEN0 0x0100 64 #define PIOEN1 0x0200 65#define GIUPODAT 0x1e 66#define GIUFEDGEINHL 0x20 67#define GIUFEDGEINHH 0x22 68#define GIUREDGEINHL 0x24 69#define GIUREDGEINHH 0x26 70 71#define GIUUSEUPDN 0x1e0 72#define GIUTERMUPDN 0x1e2 73 74#define GPIO_HAS_PULLUPDOWN_IO 0x0001 75#define GPIO_HAS_OUTPUT_ENABLE 0x0002 76#define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 77 78static spinlock_t giu_lock; 79static unsigned long giu_flags; 80static unsigned int giu_nr_pins; 81 82static void __iomem *giu_base; 83 84#define giu_read(offset) readw(giu_base + (offset)) 85#define giu_write(offset, value) writew((value), giu_base + (offset)) 86 87#define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE) 88#define GIUINT_HIGH_OFFSET 16 89#define GIUINT_HIGH_MAX 32 90 91static inline uint16_t giu_set(uint16_t offset, uint16_t set) 92{ 93 uint16_t data; 94 95 data = giu_read(offset); 96 data |= set; 97 giu_write(offset, data); 98 99 return data; 100} 101 102static inline uint16_t giu_clear(uint16_t offset, uint16_t clear) 103{ 104 uint16_t data; 105 106 data = giu_read(offset); 107 data &= ~clear; 108 giu_write(offset, data); 109 110 return data; 111} 112 113static void ack_giuint_low(unsigned int irq) 114{ 115 giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); 116} 117 118static void mask_giuint_low(unsigned int irq) 119{ 120 giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); 121} 122 123static void mask_ack_giuint_low(unsigned int irq) 124{ 125 unsigned int pin; 126 127 pin = GPIO_PIN_OF_IRQ(irq); 128 giu_clear(GIUINTENL, 1 << pin); 129 giu_write(GIUINTSTATL, 1 << pin); 130} 131 132static void unmask_giuint_low(unsigned int irq) 133{ 134 giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); 135} 136 137static struct irq_chip giuint_low_irq_chip = { 138 .name = "GIUINTL", 139 .ack = ack_giuint_low, 140 .mask = mask_giuint_low, 141 .mask_ack = mask_ack_giuint_low, 142 .unmask = unmask_giuint_low, 143}; 144 145static void ack_giuint_high(unsigned int irq) 146{ 147 giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 148} 149 150static void mask_giuint_high(unsigned int irq) 151{ 152 giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 153} 154 155static void mask_ack_giuint_high(unsigned int irq) 156{ 157 unsigned int pin; 158 159 pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; 160 giu_clear(GIUINTENH, 1 << pin); 161 giu_write(GIUINTSTATH, 1 << pin); 162} 163 164static void unmask_giuint_high(unsigned int irq) 165{ 166 giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 167} 168 169static struct irq_chip giuint_high_irq_chip = { 170 .name = "GIUINTH", 171 .ack = ack_giuint_high, 172 .mask = mask_giuint_high, 173 .mask_ack = mask_ack_giuint_high, 174 .unmask = unmask_giuint_high, 175}; 176 177static int giu_get_irq(unsigned int irq) 178{ 179 uint16_t pendl, pendh, maskl, maskh; 180 int i; 181 182 pendl = giu_read(GIUINTSTATL); 183 pendh = giu_read(GIUINTSTATH); 184 maskl = giu_read(GIUINTENL); 185 maskh = giu_read(GIUINTENH); 186 187 maskl &= pendl; 188 maskh &= pendh; 189 190 if (maskl) { 191 for (i = 0; i < 16; i++) { 192 if (maskl & (1 << i)) 193 return GIU_IRQ(i); 194 } 195 } else if (maskh) { 196 for (i = 0; i < 16; i++) { 197 if (maskh & (1 << i)) 198 return GIU_IRQ(i + GIUINT_HIGH_OFFSET); 199 } 200 } 201 202 printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", 203 maskl, pendl, maskh, pendh); 204 205 atomic_inc(&irq_err_count); 206 207 return -EINVAL; 208} 209 210void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal) 211{ 212 uint16_t mask; 213 214 if (pin < GIUINT_HIGH_OFFSET) { 215 mask = 1 << pin; 216 if (trigger != IRQ_TRIGGER_LEVEL) { 217 giu_set(GIUINTTYPL, mask); 218 if (signal == IRQ_SIGNAL_HOLD) 219 giu_set(GIUINTHTSELL, mask); 220 else 221 giu_clear(GIUINTHTSELL, mask); 222 if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { 223 switch (trigger) { 224 case IRQ_TRIGGER_EDGE_FALLING: 225 giu_set(GIUFEDGEINHL, mask); 226 giu_clear(GIUREDGEINHL, mask); 227 break; 228 case IRQ_TRIGGER_EDGE_RISING: 229 giu_clear(GIUFEDGEINHL, mask); 230 giu_set(GIUREDGEINHL, mask); 231 break; 232 default: 233 giu_set(GIUFEDGEINHL, mask); 234 giu_set(GIUREDGEINHL, mask); 235 break; 236 } 237 } 238 set_irq_chip_and_handler(GIU_IRQ(pin), 239 &giuint_low_irq_chip, 240 handle_edge_irq); 241 } else { 242 giu_clear(GIUINTTYPL, mask); 243 giu_clear(GIUINTHTSELL, mask); 244 set_irq_chip_and_handler(GIU_IRQ(pin), 245 &giuint_low_irq_chip, 246 handle_level_irq); 247 } 248 giu_write(GIUINTSTATL, mask); 249 } else if (pin < GIUINT_HIGH_MAX) { 250 mask = 1 << (pin - GIUINT_HIGH_OFFSET); 251 if (trigger != IRQ_TRIGGER_LEVEL) { 252 giu_set(GIUINTTYPH, mask); 253 if (signal == IRQ_SIGNAL_HOLD) 254 giu_set(GIUINTHTSELH, mask); 255 else 256 giu_clear(GIUINTHTSELH, mask); 257 if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { 258 switch (trigger) { 259 case IRQ_TRIGGER_EDGE_FALLING: 260 giu_set(GIUFEDGEINHH, mask); 261 giu_clear(GIUREDGEINHH, mask); 262 break; 263 case IRQ_TRIGGER_EDGE_RISING: 264 giu_clear(GIUFEDGEINHH, mask); 265 giu_set(GIUREDGEINHH, mask); 266 break; 267 default: 268 giu_set(GIUFEDGEINHH, mask); 269 giu_set(GIUREDGEINHH, mask); 270 break; 271 } 272 } 273 set_irq_chip_and_handler(GIU_IRQ(pin), 274 &giuint_high_irq_chip, 275 handle_edge_irq); 276 } else { 277 giu_clear(GIUINTTYPH, mask); 278 giu_clear(GIUINTHTSELH, mask); 279 set_irq_chip_and_handler(GIU_IRQ(pin), 280 &giuint_high_irq_chip, 281 handle_level_irq); 282 } 283 giu_write(GIUINTSTATH, mask); 284 } 285} 286EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); 287 288void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) 289{ 290 uint16_t mask; 291 292 if (pin < GIUINT_HIGH_OFFSET) { 293 mask = 1 << pin; 294 if (level == IRQ_LEVEL_HIGH) 295 giu_set(GIUINTALSELL, mask); 296 else 297 giu_clear(GIUINTALSELL, mask); 298 giu_write(GIUINTSTATL, mask); 299 } else if (pin < GIUINT_HIGH_MAX) { 300 mask = 1 << (pin - GIUINT_HIGH_OFFSET); 301 if (level == IRQ_LEVEL_HIGH) 302 giu_set(GIUINTALSELH, mask); 303 else 304 giu_clear(GIUINTALSELH, mask); 305 giu_write(GIUINTSTATH, mask); 306 } 307} 308EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); 309 310gpio_data_t vr41xx_gpio_get_pin(unsigned int pin) 311{ 312 uint16_t reg, mask; 313 314 if (pin >= giu_nr_pins) 315 return GPIO_DATA_INVAL; 316 317 if (pin < 16) { 318 reg = giu_read(GIUPIODL); 319 mask = (uint16_t)1 << pin; 320 } else if (pin < 32) { 321 reg = giu_read(GIUPIODH); 322 mask = (uint16_t)1 << (pin - 16); 323 } else if (pin < 48) { 324 reg = giu_read(GIUPODATL); 325 mask = (uint16_t)1 << (pin - 32); 326 } else { 327 reg = giu_read(GIUPODATH); 328 mask = (uint16_t)1 << (pin - 48); 329 } 330 331 if (reg & mask) 332 return GPIO_DATA_HIGH; 333 334 return GPIO_DATA_LOW; 335} 336EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin); 337 338int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data) 339{ 340 uint16_t offset, mask, reg; 341 unsigned long flags; 342 343 if (pin >= giu_nr_pins) 344 return -EINVAL; 345 346 if (pin < 16) { 347 offset = GIUPIODL; 348 mask = (uint16_t)1 << pin; 349 } else if (pin < 32) { 350 offset = GIUPIODH; 351 mask = (uint16_t)1 << (pin - 16); 352 } else if (pin < 48) { 353 offset = GIUPODATL; 354 mask = (uint16_t)1 << (pin - 32); 355 } else { 356 offset = GIUPODATH; 357 mask = (uint16_t)1 << (pin - 48); 358 } 359 360 spin_lock_irqsave(&giu_lock, flags); 361 362 reg = giu_read(offset); 363 if (data == GPIO_DATA_HIGH) 364 reg |= mask; 365 else 366 reg &= ~mask; 367 giu_write(offset, reg); 368 369 spin_unlock_irqrestore(&giu_lock, flags); 370 371 return 0; 372} 373EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin); 374 375int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir) 376{ 377 uint16_t offset, mask, reg; 378 unsigned long flags; 379 380 if (pin >= giu_nr_pins) 381 return -EINVAL; 382 383 if (pin < 16) { 384 offset = GIUIOSELL; 385 mask = (uint16_t)1 << pin; 386 } else if (pin < 32) { 387 offset = GIUIOSELH; 388 mask = (uint16_t)1 << (pin - 16); 389 } else { 390 if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) { 391 offset = GIUPODATEN; 392 mask = (uint16_t)1 << (pin - 32); 393 } else { 394 switch (pin) { 395 case 48: 396 offset = GIUPODATH; 397 mask = PIOEN0; 398 break; 399 case 49: 400 offset = GIUPODATH; 401 mask = PIOEN1; 402 break; 403 default: 404 return -EINVAL; 405 } 406 } 407 } 408 409 spin_lock_irqsave(&giu_lock, flags); 410 411 reg = giu_read(offset); 412 if (dir == GPIO_OUTPUT) 413 reg |= mask; 414 else 415 reg &= ~mask; 416 giu_write(offset, reg); 417 418 spin_unlock_irqrestore(&giu_lock, flags); 419 420 return 0; 421} 422EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction); 423 424int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) 425{ 426 uint16_t reg, mask; 427 unsigned long flags; 428 429 if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO) 430 return -EPERM; 431 432 if (pin >= 15) 433 return -EINVAL; 434 435 mask = (uint16_t)1 << pin; 436 437 spin_lock_irqsave(&giu_lock, flags); 438 439 if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) { 440 reg = giu_read(GIUTERMUPDN); 441 if (pull == GPIO_PULL_UP) 442 reg |= mask; 443 else 444 reg &= ~mask; 445 giu_write(GIUTERMUPDN, reg); 446 447 reg = giu_read(GIUUSEUPDN); 448 reg |= mask; 449 giu_write(GIUUSEUPDN, reg); 450 } else { 451 reg = giu_read(GIUUSEUPDN); 452 reg &= ~mask; 453 giu_write(GIUUSEUPDN, reg); 454 } 455 456 spin_unlock_irqrestore(&giu_lock, flags); 457 458 return 0; 459} 460EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); 461 462static ssize_t gpio_read(struct file *file, char __user *buf, size_t len, 463 loff_t *ppos) 464{ 465 unsigned int pin; 466 char value = '0'; 467 468 pin = iminor(file->f_path.dentry->d_inode); 469 if (pin >= giu_nr_pins) 470 return -EBADF; 471 472 if (vr41xx_gpio_get_pin(pin) == GPIO_DATA_HIGH) 473 value = '1'; 474 475 if (len <= 0) 476 return -EFAULT; 477 478 if (put_user(value, buf)) 479 return -EFAULT; 480 481 return 1; 482} 483 484static ssize_t gpio_write(struct file *file, const char __user *data, 485 size_t len, loff_t *ppos) 486{ 487 unsigned int pin; 488 size_t i; 489 char c; 490 int retval = 0; 491 492 pin = iminor(file->f_path.dentry->d_inode); 493 if (pin >= giu_nr_pins) 494 return -EBADF; 495 496 for (i = 0; i < len; i++) { 497 if (get_user(c, data + i)) 498 return -EFAULT; 499 500 switch (c) { 501 case '0': 502 retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_LOW); 503 break; 504 case '1': 505 retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_HIGH); 506 break; 507 case 'D': 508 printk(KERN_INFO "GPIO%d: pull down\n", pin); 509 retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DOWN); 510 break; 511 case 'd': 512 printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); 513 retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); 514 break; 515 case 'I': 516 printk(KERN_INFO "GPIO%d: input\n", pin); 517 retval = vr41xx_gpio_set_direction(pin, GPIO_INPUT); 518 break; 519 case 'O': 520 printk(KERN_INFO "GPIO%d: output\n", pin); 521 retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT); 522 break; 523 case 'o': 524 printk(KERN_INFO "GPIO%d: output disable\n", pin); 525 retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT_DISABLE); 526 break; 527 case 'P': 528 printk(KERN_INFO "GPIO%d: pull up\n", pin); 529 retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_UP); 530 break; 531 case 'p': 532 printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); 533 retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); 534 break; 535 default: 536 break; 537 } 538 539 if (retval < 0) 540 break; 541 } 542 543 return i; 544} 545 546static int gpio_open(struct inode *inode, struct file *file) 547{ 548 unsigned int pin; 549 550 pin = iminor(inode); 551 if (pin >= giu_nr_pins) 552 return -EBADF; 553 554 return nonseekable_open(inode, file); 555} 556 557static int gpio_release(struct inode *inode, struct file *file) 558{ 559 unsigned int pin; 560 561 pin = iminor(inode); 562 if (pin >= giu_nr_pins) 563 return -EBADF; 564 565 return 0; 566} 567 568static const struct file_operations gpio_fops = { 569 .owner = THIS_MODULE, 570 .read = gpio_read, 571 .write = gpio_write, 572 .open = gpio_open, 573 .release = gpio_release, 574}; 575 576static int __devinit giu_probe(struct platform_device *dev) 577{ 578 struct resource *res; 579 unsigned int trigger, i, pin; 580 struct irq_chip *chip; 581 int irq, retval; 582 583 switch (dev->id) { 584 case GPIO_50PINS_PULLUPDOWN: 585 giu_flags = GPIO_HAS_PULLUPDOWN_IO; 586 giu_nr_pins = 50; 587 break; 588 case GPIO_36PINS: 589 giu_nr_pins = 36; 590 break; 591 case GPIO_48PINS_EDGE_SELECT: 592 giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; 593 giu_nr_pins = 48; 594 break; 595 default: 596 printk(KERN_ERR "GIU: unknown ID %d\n", dev->id); 597 return -ENODEV; 598 } 599 600 res = platform_get_resource(dev, IORESOURCE_MEM, 0); 601 if (!res) 602 return -EBUSY; 603 604 giu_base = ioremap(res->start, res->end - res->start + 1); 605 if (!giu_base) 606 return -ENOMEM; 607 608 retval = register_chrdev(major, "GIU", &gpio_fops); 609 if (retval < 0) { 610 iounmap(giu_base); 611 giu_base = NULL; 612 return retval; 613 } 614 615 if (major == 0) { 616 major = retval; 617 printk(KERN_INFO "GIU: major number %d\n", major); 618 } 619 620 spin_lock_init(&giu_lock); 621 622 giu_write(GIUINTENL, 0); 623 giu_write(GIUINTENH, 0); 624 625 trigger = giu_read(GIUINTTYPH) << 16; 626 trigger |= giu_read(GIUINTTYPL); 627 for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { 628 pin = GPIO_PIN_OF_IRQ(i); 629 if (pin < GIUINT_HIGH_OFFSET) 630 chip = &giuint_low_irq_chip; 631 else 632 chip = &giuint_high_irq_chip; 633 634 if (trigger & (1 << pin)) 635 set_irq_chip_and_handler(i, chip, handle_edge_irq); 636 else 637 set_irq_chip_and_handler(i, chip, handle_level_irq); 638 639 } 640 641 irq = platform_get_irq(dev, 0); 642 if (irq < 0 || irq >= NR_IRQS) 643 return -EBUSY; 644 645 return cascade_irq(irq, giu_get_irq); 646} 647 648static int __devexit giu_remove(struct platform_device *dev) 649{ 650 if (giu_base) { 651 iounmap(giu_base); 652 giu_base = NULL; 653 } 654 655 return 0; 656} 657 658static struct platform_driver giu_device_driver = { 659 .probe = giu_probe, 660 .remove = __devexit_p(giu_remove), 661 .driver = { 662 .name = "GIU", 663 .owner = THIS_MODULE, 664 }, 665}; 666 667static int __init vr41xx_giu_init(void) 668{ 669 return platform_driver_register(&giu_device_driver); 670} 671 672static void __exit vr41xx_giu_exit(void) 673{ 674 platform_driver_unregister(&giu_device_driver); 675} 676 677module_init(vr41xx_giu_init); 678module_exit(vr41xx_giu_exit); 679