gpio-iop.c revision f6ffa5ee039cd0168d82e3edd712ebbb1de93a00
172edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek/* 272edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek * arch/arm/plat-iop/gpio.c 372edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek * GPIO handling for Intel IOP3xx processors. 472edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek * 572edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> 672edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek * 772edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek * This program is free software; you can redistribute it and/or modify 872edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek * it under the terms of the GNU General Public License as published by 972edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek * the Free Software Foundation; either version 2 of the License, or (at 1072edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek * your option) any later version. 1172edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek */ 1272edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek 1372edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek#include <linux/device.h> 1463f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard#include <linux/init.h> 1563f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard#include <linux/types.h> 1663f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard#include <linux/errno.h> 1763f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard#include <linux/gpio.h> 18dc28094b905a872f8884f1f1c48ca86b3b78583aPaul Gortmaker#include <linux/export.h> 19f6ffa5ee039cd0168d82e3edd712ebbb1de93a00Linus Walleij 20f6ffa5ee039cd0168d82e3edd712ebbb1de93a00Linus Walleij#define IOP3XX_N_GPIOS 8 2172edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek 2272edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhekvoid gpio_line_config(int line, int direction) 2372edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek{ 2472edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek unsigned long flags; 2572edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek 2672edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek local_irq_save(flags); 2772edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek if (direction == GPIO_IN) { 2872edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek *IOP3XX_GPOE |= 1 << line; 2972edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek } else if (direction == GPIO_OUT) { 3072edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek *IOP3XX_GPOE &= ~(1 << line); 3172edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek } 3272edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek local_irq_restore(flags); 3372edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek} 3472edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert BuytenhekEXPORT_SYMBOL(gpio_line_config); 3572edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek 3672edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhekint gpio_line_get(int line) 3772edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek{ 3872edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek return !!(*IOP3XX_GPID & (1 << line)); 3972edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek} 4072edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert BuytenhekEXPORT_SYMBOL(gpio_line_get); 4172edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek 4272edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhekvoid gpio_line_set(int line, int value) 4372edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek{ 4472edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek unsigned long flags; 4572edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek 4672edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek local_irq_save(flags); 4772edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek if (value == GPIO_LOW) { 4872edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek *IOP3XX_GPOD &= ~(1 << line); 4972edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek } else if (value == GPIO_HIGH) { 5072edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek *IOP3XX_GPOD |= 1 << line; 5172edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek } 5272edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek local_irq_restore(flags); 5372edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert Buytenhek} 5472edd84a6b2db1a21d1ed07929cae560e276a0a6Lennert BuytenhekEXPORT_SYMBOL(gpio_line_set); 5563f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard 5663f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patardstatic int iop3xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) 5763f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard{ 5863f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard gpio_line_config(gpio, GPIO_IN); 5963f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard return 0; 6063f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard} 6163f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard 6263f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patardstatic int iop3xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level) 6363f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard{ 6463f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard gpio_line_set(gpio, level); 6563f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard gpio_line_config(gpio, GPIO_OUT); 6663f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard return 0; 6763f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard} 6863f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard 6963f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patardstatic int iop3xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) 7063f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard{ 7163f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard return gpio_line_get(gpio); 7263f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard} 7363f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard 7463f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patardstatic void iop3xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) 7563f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard{ 7663f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard gpio_line_set(gpio, value); 7763f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard} 7863f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard 7963f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patardstatic struct gpio_chip iop3xx_chip = { 8063f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard .label = "iop3xx", 8163f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard .direction_input = iop3xx_gpio_direction_input, 8263f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard .get = iop3xx_gpio_get_value, 8363f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard .direction_output = iop3xx_gpio_direction_output, 8463f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard .set = iop3xx_gpio_set_value, 8563f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard .base = 0, 8663f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard .ngpio = IOP3XX_N_GPIOS, 8763f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard}; 8863f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard 8963f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patardstatic int __init iop3xx_gpio_setup(void) 9063f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard{ 9163f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard return gpiochip_add(&iop3xx_chip); 9263f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patard} 9363f385cd1f649b3f4f2d59fc609e051981215fd7Arnaud Patardarch_initcall(iop3xx_gpio_setup); 94