1/* 2 * Driver for NEC VR4100 series General-purpose I/O Unit. 3 * 4 * Copyright (C) 2002 MontaVista Software Inc. 5 * Author: Yoichi Yuasa <source@mvista.com> 6 * Copyright (C) 2003-2009 Yoichi Yuasa <yuasa@linux-mips.org> 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/gpio.h> 25#include <linux/init.h> 26#include <linux/interrupt.h> 27#include <linux/io.h> 28#include <linux/irq.h> 29#include <linux/kernel.h> 30#include <linux/module.h> 31#include <linux/platform_device.h> 32#include <linux/spinlock.h> 33#include <linux/types.h> 34 35#include <asm/vr41xx/giu.h> 36#include <asm/vr41xx/irq.h> 37#include <asm/vr41xx/vr41xx.h> 38 39MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>"); 40MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver"); 41MODULE_LICENSE("GPL"); 42 43#define GIUIOSELL 0x00 44#define GIUIOSELH 0x02 45#define GIUPIODL 0x04 46#define GIUPIODH 0x06 47#define GIUINTSTATL 0x08 48#define GIUINTSTATH 0x0a 49#define GIUINTENL 0x0c 50#define GIUINTENH 0x0e 51#define GIUINTTYPL 0x10 52#define GIUINTTYPH 0x12 53#define GIUINTALSELL 0x14 54#define GIUINTALSELH 0x16 55#define GIUINTHTSELL 0x18 56#define GIUINTHTSELH 0x1a 57#define GIUPODATL 0x1c 58#define GIUPODATEN 0x1c 59#define GIUPODATH 0x1e 60 #define PIOEN0 0x0100 61 #define PIOEN1 0x0200 62#define GIUPODAT 0x1e 63#define GIUFEDGEINHL 0x20 64#define GIUFEDGEINHH 0x22 65#define GIUREDGEINHL 0x24 66#define GIUREDGEINHH 0x26 67 68#define GIUUSEUPDN 0x1e0 69#define GIUTERMUPDN 0x1e2 70 71#define GPIO_HAS_PULLUPDOWN_IO 0x0001 72#define GPIO_HAS_OUTPUT_ENABLE 0x0002 73#define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 74 75enum { 76 GPIO_INPUT, 77 GPIO_OUTPUT, 78}; 79 80static DEFINE_SPINLOCK(giu_lock); 81static unsigned long giu_flags; 82 83static void __iomem *giu_base; 84 85#define giu_read(offset) readw(giu_base + (offset)) 86#define giu_write(offset, value) writew((value), giu_base + (offset)) 87 88#define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE) 89#define GIUINT_HIGH_OFFSET 16 90#define GIUINT_HIGH_MAX 32 91 92static inline u16 giu_set(u16 offset, u16 set) 93{ 94 u16 data; 95 96 data = giu_read(offset); 97 data |= set; 98 giu_write(offset, data); 99 100 return data; 101} 102 103static inline u16 giu_clear(u16 offset, u16 clear) 104{ 105 u16 data; 106 107 data = giu_read(offset); 108 data &= ~clear; 109 giu_write(offset, data); 110 111 return data; 112} 113 114static void ack_giuint_low(unsigned int irq) 115{ 116 giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); 117} 118 119static void mask_giuint_low(unsigned int irq) 120{ 121 giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); 122} 123 124static void mask_ack_giuint_low(unsigned int irq) 125{ 126 unsigned int pin; 127 128 pin = GPIO_PIN_OF_IRQ(irq); 129 giu_clear(GIUINTENL, 1 << pin); 130 giu_write(GIUINTSTATL, 1 << pin); 131} 132 133static void unmask_giuint_low(unsigned int irq) 134{ 135 giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); 136} 137 138static struct irq_chip giuint_low_irq_chip = { 139 .name = "GIUINTL", 140 .ack = ack_giuint_low, 141 .mask = mask_giuint_low, 142 .mask_ack = mask_ack_giuint_low, 143 .unmask = unmask_giuint_low, 144}; 145 146static void ack_giuint_high(unsigned int irq) 147{ 148 giu_write(GIUINTSTATH, 149 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 150} 151 152static void mask_giuint_high(unsigned int irq) 153{ 154 giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 155} 156 157static void mask_ack_giuint_high(unsigned int irq) 158{ 159 unsigned int pin; 160 161 pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; 162 giu_clear(GIUINTENH, 1 << pin); 163 giu_write(GIUINTSTATH, 1 << pin); 164} 165 166static void unmask_giuint_high(unsigned int irq) 167{ 168 giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 169} 170 171static struct irq_chip giuint_high_irq_chip = { 172 .name = "GIUINTH", 173 .ack = ack_giuint_high, 174 .mask = mask_giuint_high, 175 .mask_ack = mask_ack_giuint_high, 176 .unmask = unmask_giuint_high, 177}; 178 179static int giu_get_irq(unsigned int irq) 180{ 181 u16 pendl, pendh, maskl, maskh; 182 int i; 183 184 pendl = giu_read(GIUINTSTATL); 185 pendh = giu_read(GIUINTSTATH); 186 maskl = giu_read(GIUINTENL); 187 maskh = giu_read(GIUINTENH); 188 189 maskl &= pendl; 190 maskh &= pendh; 191 192 if (maskl) { 193 for (i = 0; i < 16; i++) { 194 if (maskl & (1 << i)) 195 return GIU_IRQ(i); 196 } 197 } else if (maskh) { 198 for (i = 0; i < 16; i++) { 199 if (maskh & (1 << i)) 200 return GIU_IRQ(i + GIUINT_HIGH_OFFSET); 201 } 202 } 203 204 printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", 205 maskl, pendl, maskh, pendh); 206 207 atomic_inc(&irq_err_count); 208 209 return -EINVAL; 210} 211 212void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, 213 irq_signal_t signal) 214{ 215 u16 mask; 216 217 if (pin < GIUINT_HIGH_OFFSET) { 218 mask = 1 << pin; 219 if (trigger != IRQ_TRIGGER_LEVEL) { 220 giu_set(GIUINTTYPL, mask); 221 if (signal == IRQ_SIGNAL_HOLD) 222 giu_set(GIUINTHTSELL, mask); 223 else 224 giu_clear(GIUINTHTSELL, mask); 225 if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { 226 switch (trigger) { 227 case IRQ_TRIGGER_EDGE_FALLING: 228 giu_set(GIUFEDGEINHL, mask); 229 giu_clear(GIUREDGEINHL, mask); 230 break; 231 case IRQ_TRIGGER_EDGE_RISING: 232 giu_clear(GIUFEDGEINHL, mask); 233 giu_set(GIUREDGEINHL, mask); 234 break; 235 default: 236 giu_set(GIUFEDGEINHL, mask); 237 giu_set(GIUREDGEINHL, mask); 238 break; 239 } 240 } 241 set_irq_chip_and_handler(GIU_IRQ(pin), 242 &giuint_low_irq_chip, 243 handle_edge_irq); 244 } else { 245 giu_clear(GIUINTTYPL, mask); 246 giu_clear(GIUINTHTSELL, mask); 247 set_irq_chip_and_handler(GIU_IRQ(pin), 248 &giuint_low_irq_chip, 249 handle_level_irq); 250 } 251 giu_write(GIUINTSTATL, mask); 252 } else if (pin < GIUINT_HIGH_MAX) { 253 mask = 1 << (pin - GIUINT_HIGH_OFFSET); 254 if (trigger != IRQ_TRIGGER_LEVEL) { 255 giu_set(GIUINTTYPH, mask); 256 if (signal == IRQ_SIGNAL_HOLD) 257 giu_set(GIUINTHTSELH, mask); 258 else 259 giu_clear(GIUINTHTSELH, mask); 260 if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { 261 switch (trigger) { 262 case IRQ_TRIGGER_EDGE_FALLING: 263 giu_set(GIUFEDGEINHH, mask); 264 giu_clear(GIUREDGEINHH, mask); 265 break; 266 case IRQ_TRIGGER_EDGE_RISING: 267 giu_clear(GIUFEDGEINHH, mask); 268 giu_set(GIUREDGEINHH, mask); 269 break; 270 default: 271 giu_set(GIUFEDGEINHH, mask); 272 giu_set(GIUREDGEINHH, mask); 273 break; 274 } 275 } 276 set_irq_chip_and_handler(GIU_IRQ(pin), 277 &giuint_high_irq_chip, 278 handle_edge_irq); 279 } else { 280 giu_clear(GIUINTTYPH, mask); 281 giu_clear(GIUINTHTSELH, mask); 282 set_irq_chip_and_handler(GIU_IRQ(pin), 283 &giuint_high_irq_chip, 284 handle_level_irq); 285 } 286 giu_write(GIUINTSTATH, mask); 287 } 288} 289EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); 290 291void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) 292{ 293 u16 mask; 294 295 if (pin < GIUINT_HIGH_OFFSET) { 296 mask = 1 << pin; 297 if (level == IRQ_LEVEL_HIGH) 298 giu_set(GIUINTALSELL, mask); 299 else 300 giu_clear(GIUINTALSELL, mask); 301 giu_write(GIUINTSTATL, mask); 302 } else if (pin < GIUINT_HIGH_MAX) { 303 mask = 1 << (pin - GIUINT_HIGH_OFFSET); 304 if (level == IRQ_LEVEL_HIGH) 305 giu_set(GIUINTALSELH, mask); 306 else 307 giu_clear(GIUINTALSELH, mask); 308 giu_write(GIUINTSTATH, mask); 309 } 310} 311EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); 312 313static int giu_set_direction(struct gpio_chip *chip, unsigned pin, int dir) 314{ 315 u16 offset, mask, reg; 316 unsigned long flags; 317 318 if (pin >= chip->ngpio) 319 return -EINVAL; 320 321 if (pin < 16) { 322 offset = GIUIOSELL; 323 mask = 1 << pin; 324 } else if (pin < 32) { 325 offset = GIUIOSELH; 326 mask = 1 << (pin - 16); 327 } else { 328 if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) { 329 offset = GIUPODATEN; 330 mask = 1 << (pin - 32); 331 } else { 332 switch (pin) { 333 case 48: 334 offset = GIUPODATH; 335 mask = PIOEN0; 336 break; 337 case 49: 338 offset = GIUPODATH; 339 mask = PIOEN1; 340 break; 341 default: 342 return -EINVAL; 343 } 344 } 345 } 346 347 spin_lock_irqsave(&giu_lock, flags); 348 349 reg = giu_read(offset); 350 if (dir == GPIO_OUTPUT) 351 reg |= mask; 352 else 353 reg &= ~mask; 354 giu_write(offset, reg); 355 356 spin_unlock_irqrestore(&giu_lock, flags); 357 358 return 0; 359} 360 361int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) 362{ 363 u16 reg, mask; 364 unsigned long flags; 365 366 if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO) 367 return -EPERM; 368 369 if (pin >= 15) 370 return -EINVAL; 371 372 mask = 1 << pin; 373 374 spin_lock_irqsave(&giu_lock, flags); 375 376 if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) { 377 reg = giu_read(GIUTERMUPDN); 378 if (pull == GPIO_PULL_UP) 379 reg |= mask; 380 else 381 reg &= ~mask; 382 giu_write(GIUTERMUPDN, reg); 383 384 reg = giu_read(GIUUSEUPDN); 385 reg |= mask; 386 giu_write(GIUUSEUPDN, reg); 387 } else { 388 reg = giu_read(GIUUSEUPDN); 389 reg &= ~mask; 390 giu_write(GIUUSEUPDN, reg); 391 } 392 393 spin_unlock_irqrestore(&giu_lock, flags); 394 395 return 0; 396} 397EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); 398 399static int vr41xx_gpio_get(struct gpio_chip *chip, unsigned pin) 400{ 401 u16 reg, mask; 402 403 if (pin >= chip->ngpio) 404 return -EINVAL; 405 406 if (pin < 16) { 407 reg = giu_read(GIUPIODL); 408 mask = 1 << pin; 409 } else if (pin < 32) { 410 reg = giu_read(GIUPIODH); 411 mask = 1 << (pin - 16); 412 } else if (pin < 48) { 413 reg = giu_read(GIUPODATL); 414 mask = 1 << (pin - 32); 415 } else { 416 reg = giu_read(GIUPODATH); 417 mask = 1 << (pin - 48); 418 } 419 420 if (reg & mask) 421 return 1; 422 423 return 0; 424} 425 426static void vr41xx_gpio_set(struct gpio_chip *chip, unsigned pin, 427 int value) 428{ 429 u16 offset, mask, reg; 430 unsigned long flags; 431 432 if (pin >= chip->ngpio) 433 return; 434 435 if (pin < 16) { 436 offset = GIUPIODL; 437 mask = 1 << pin; 438 } else if (pin < 32) { 439 offset = GIUPIODH; 440 mask = 1 << (pin - 16); 441 } else if (pin < 48) { 442 offset = GIUPODATL; 443 mask = 1 << (pin - 32); 444 } else { 445 offset = GIUPODATH; 446 mask = 1 << (pin - 48); 447 } 448 449 spin_lock_irqsave(&giu_lock, flags); 450 451 reg = giu_read(offset); 452 if (value) 453 reg |= mask; 454 else 455 reg &= ~mask; 456 giu_write(offset, reg); 457 458 spin_unlock_irqrestore(&giu_lock, flags); 459} 460 461 462static int vr41xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 463{ 464 return giu_set_direction(chip, offset, GPIO_INPUT); 465} 466 467static int vr41xx_gpio_direction_output(struct gpio_chip *chip, unsigned offset, 468 int value) 469{ 470 vr41xx_gpio_set(chip, offset, value); 471 472 return giu_set_direction(chip, offset, GPIO_OUTPUT); 473} 474 475static int vr41xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 476{ 477 if (offset >= chip->ngpio) 478 return -EINVAL; 479 480 return GIU_IRQ_BASE + offset; 481} 482 483static struct gpio_chip vr41xx_gpio_chip = { 484 .label = "vr41xx", 485 .owner = THIS_MODULE, 486 .direction_input = vr41xx_gpio_direction_input, 487 .get = vr41xx_gpio_get, 488 .direction_output = vr41xx_gpio_direction_output, 489 .set = vr41xx_gpio_set, 490 .to_irq = vr41xx_gpio_to_irq, 491}; 492 493static int __devinit giu_probe(struct platform_device *pdev) 494{ 495 struct resource *res; 496 unsigned int trigger, i, pin; 497 struct irq_chip *chip; 498 int irq, retval; 499 500 switch (pdev->id) { 501 case GPIO_50PINS_PULLUPDOWN: 502 giu_flags = GPIO_HAS_PULLUPDOWN_IO; 503 vr41xx_gpio_chip.ngpio = 50; 504 break; 505 case GPIO_36PINS: 506 vr41xx_gpio_chip.ngpio = 36; 507 break; 508 case GPIO_48PINS_EDGE_SELECT: 509 giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; 510 vr41xx_gpio_chip.ngpio = 48; 511 break; 512 default: 513 dev_err(&pdev->dev, "GIU: unknown ID %d\n", pdev->id); 514 return -ENODEV; 515 } 516 517 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 518 if (!res) 519 return -EBUSY; 520 521 giu_base = ioremap(res->start, res->end - res->start + 1); 522 if (!giu_base) 523 return -ENOMEM; 524 525 vr41xx_gpio_chip.dev = &pdev->dev; 526 527 retval = gpiochip_add(&vr41xx_gpio_chip); 528 529 giu_write(GIUINTENL, 0); 530 giu_write(GIUINTENH, 0); 531 532 trigger = giu_read(GIUINTTYPH) << 16; 533 trigger |= giu_read(GIUINTTYPL); 534 for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { 535 pin = GPIO_PIN_OF_IRQ(i); 536 if (pin < GIUINT_HIGH_OFFSET) 537 chip = &giuint_low_irq_chip; 538 else 539 chip = &giuint_high_irq_chip; 540 541 if (trigger & (1 << pin)) 542 set_irq_chip_and_handler(i, chip, handle_edge_irq); 543 else 544 set_irq_chip_and_handler(i, chip, handle_level_irq); 545 546 } 547 548 irq = platform_get_irq(pdev, 0); 549 if (irq < 0 || irq >= nr_irqs) 550 return -EBUSY; 551 552 return cascade_irq(irq, giu_get_irq); 553} 554 555static int __devexit giu_remove(struct platform_device *pdev) 556{ 557 if (giu_base) { 558 iounmap(giu_base); 559 giu_base = NULL; 560 } 561 562 return 0; 563} 564 565static struct platform_driver giu_device_driver = { 566 .probe = giu_probe, 567 .remove = __devexit_p(giu_remove), 568 .driver = { 569 .name = "GIU", 570 .owner = THIS_MODULE, 571 }, 572}; 573 574static int __init vr41xx_giu_init(void) 575{ 576 return platform_driver_register(&giu_device_driver); 577} 578 579static void __exit vr41xx_giu_exit(void) 580{ 581 platform_driver_unregister(&giu_device_driver); 582} 583 584module_init(vr41xx_giu_init); 585module_exit(vr41xx_giu_exit); 586