123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- /*
- * arch/arm/mach-pnx4008/gpio.c
- *
- * PNX4008 GPIO driver
- *
- * Author: Dmitry Chigirev <source@mvista.com>
- *
- * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
- * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
- *
- * 2005 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/io.h>
- #include <mach/hardware.h>
- #include <mach/platform.h>
- #include <mach/gpio.h>
- /* register definitions */
- #define PIO_VA_BASE IO_ADDRESS(PNX4008_PIO_BASE)
- #define PIO_INP_STATE (0x00U)
- #define PIO_OUTP_SET (0x04U)
- #define PIO_OUTP_CLR (0x08U)
- #define PIO_OUTP_STATE (0x0CU)
- #define PIO_DRV_SET (0x10U)
- #define PIO_DRV_CLR (0x14U)
- #define PIO_DRV_STATE (0x18U)
- #define PIO_SDINP_STATE (0x1CU)
- #define PIO_SDOUTP_SET (0x20U)
- #define PIO_SDOUTP_CLR (0x24U)
- #define PIO_MUX_SET (0x28U)
- #define PIO_MUX_CLR (0x2CU)
- #define PIO_MUX_STATE (0x30U)
- static inline void gpio_lock(void)
- {
- local_irq_disable();
- }
- static inline void gpio_unlock(void)
- {
- local_irq_enable();
- }
- /* Inline functions */
- static inline int gpio_read_bit(u32 reg, int gpio)
- {
- u32 bit, val;
- int ret = -EFAULT;
- if (gpio < 0)
- goto out;
- bit = GPIO_BIT(gpio);
- if (bit) {
- val = __raw_readl(PIO_VA_BASE + reg);
- ret = (val & bit) ? 1 : 0;
- }
- out:
- return ret;
- }
- static inline int gpio_set_bit(u32 reg, int gpio)
- {
- u32 bit, val;
- int ret = -EFAULT;
- if (gpio < 0)
- goto out;
- bit = GPIO_BIT(gpio);
- if (bit) {
- val = __raw_readl(PIO_VA_BASE + reg);
- val |= bit;
- __raw_writel(val, PIO_VA_BASE + reg);
- ret = 0;
- }
- out:
- return ret;
- }
- /* Very simple access control, bitmap for allocated/free */
- static unsigned long access_map[4];
- #define INP_INDEX 0
- #define OUTP_INDEX 1
- #define GPIO_INDEX 2
- #define MUX_INDEX 3
- /*GPIO to Input Mapping */
- static short gpio_to_inp_map[32] = {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 24, -1
- };
- /*GPIO to Mux Mapping */
- static short gpio_to_mux_map[32] = {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 0, 1, 4, 5, -1
- };
- /*Output to Mux Mapping */
- static short outp_to_mux_map[32] = {
- -1, -1, -1, 6, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 2, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1
- };
- int pnx4008_gpio_register_pin(unsigned short pin)
- {
- unsigned long bit = GPIO_BIT(pin);
- int ret = -EBUSY; /* Already in use */
- gpio_lock();
- if (GPIO_ISBID(pin)) {
- if (access_map[GPIO_INDEX] & bit)
- goto out;
- access_map[GPIO_INDEX] |= bit;
- } else if (GPIO_ISRAM(pin)) {
- if (access_map[GPIO_INDEX] & bit)
- goto out;
- access_map[GPIO_INDEX] |= bit;
- } else if (GPIO_ISMUX(pin)) {
- if (access_map[MUX_INDEX] & bit)
- goto out;
- access_map[MUX_INDEX] |= bit;
- } else if (GPIO_ISOUT(pin)) {
- if (access_map[OUTP_INDEX] & bit)
- goto out;
- access_map[OUTP_INDEX] |= bit;
- } else if (GPIO_ISIN(pin)) {
- if (access_map[INP_INDEX] & bit)
- goto out;
- access_map[INP_INDEX] |= bit;
- } else
- goto out;
- ret = 0;
- out:
- gpio_unlock();
- return ret;
- }
- EXPORT_SYMBOL(pnx4008_gpio_register_pin);
- int pnx4008_gpio_unregister_pin(unsigned short pin)
- {
- unsigned long bit = GPIO_BIT(pin);
- int ret = -EFAULT; /* Not registered */
- gpio_lock();
- if (GPIO_ISBID(pin)) {
- if (~access_map[GPIO_INDEX] & bit)
- goto out;
- access_map[GPIO_INDEX] &= ~bit;
- } else if (GPIO_ISRAM(pin)) {
- if (~access_map[GPIO_INDEX] & bit)
- goto out;
- access_map[GPIO_INDEX] &= ~bit;
- } else if (GPIO_ISMUX(pin)) {
- if (~access_map[MUX_INDEX] & bit)
- goto out;
- access_map[MUX_INDEX] &= ~bit;
- } else if (GPIO_ISOUT(pin)) {
- if (~access_map[OUTP_INDEX] & bit)
- goto out;
- access_map[OUTP_INDEX] &= ~bit;
- } else if (GPIO_ISIN(pin)) {
- if (~access_map[INP_INDEX] & bit)
- goto out;
- access_map[INP_INDEX] &= ~bit;
- } else
- goto out;
- ret = 0;
- out:
- gpio_unlock();
- return ret;
- }
- EXPORT_SYMBOL(pnx4008_gpio_unregister_pin);
- unsigned long pnx4008_gpio_read_pin(unsigned short pin)
- {
- unsigned long ret = -EFAULT;
- int gpio = GPIO_BIT_MASK(pin);
- gpio_lock();
- if (GPIO_ISOUT(pin)) {
- ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
- } else if (GPIO_ISRAM(pin)) {
- if (gpio_read_bit(PIO_DRV_STATE, gpio) == 0) {
- ret = gpio_read_bit(PIO_SDINP_STATE, gpio);
- }
- } else if (GPIO_ISBID(pin)) {
- ret = gpio_read_bit(PIO_DRV_STATE, gpio);
- if (ret > 0)
- ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
- else if (ret == 0)
- ret =
- gpio_read_bit(PIO_INP_STATE, gpio_to_inp_map[gpio]);
- } else if (GPIO_ISIN(pin)) {
- ret = gpio_read_bit(PIO_INP_STATE, gpio);
- }
- gpio_unlock();
- return ret;
- }
- EXPORT_SYMBOL(pnx4008_gpio_read_pin);
- /* Write Value to output */
- int pnx4008_gpio_write_pin(unsigned short pin, int output)
- {
- int gpio = GPIO_BIT_MASK(pin);
- int ret = -EFAULT;
- gpio_lock();
- if (GPIO_ISOUT(pin)) {
- printk( "writing '%x' to '%x'\n",
- gpio, output ? PIO_OUTP_SET : PIO_OUTP_CLR );
- ret = gpio_set_bit(output ? PIO_OUTP_SET : PIO_OUTP_CLR, gpio);
- } else if (GPIO_ISRAM(pin)) {
- if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
- ret = gpio_set_bit(output ? PIO_SDOUTP_SET :
- PIO_SDOUTP_CLR, gpio);
- } else if (GPIO_ISBID(pin)) {
- if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
- ret = gpio_set_bit(output ? PIO_OUTP_SET :
- PIO_OUTP_CLR, gpio);
- }
- gpio_unlock();
- return ret;
- }
- EXPORT_SYMBOL(pnx4008_gpio_write_pin);
- /* Value = 1 : Set GPIO pin as output */
- /* Value = 0 : Set GPIO pin as input */
- int pnx4008_gpio_set_pin_direction(unsigned short pin, int output)
- {
- int gpio = GPIO_BIT_MASK(pin);
- int ret = -EFAULT;
- gpio_lock();
- if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
- ret = gpio_set_bit(output ? PIO_DRV_SET : PIO_DRV_CLR, gpio);
- }
- gpio_unlock();
- return ret;
- }
- EXPORT_SYMBOL(pnx4008_gpio_set_pin_direction);
- /* Read GPIO pin direction: 0= pin used as input, 1= pin used as output*/
- int pnx4008_gpio_read_pin_direction(unsigned short pin)
- {
- int gpio = GPIO_BIT_MASK(pin);
- int ret = -EFAULT;
- gpio_lock();
- if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
- ret = gpio_read_bit(PIO_DRV_STATE, gpio);
- }
- gpio_unlock();
- return ret;
- }
- EXPORT_SYMBOL(pnx4008_gpio_read_pin_direction);
- /* Value = 1 : Set pin to muxed function */
- /* Value = 0 : Set pin as GPIO */
- int pnx4008_gpio_set_pin_mux(unsigned short pin, int output)
- {
- int gpio = GPIO_BIT_MASK(pin);
- int ret = -EFAULT;
- gpio_lock();
- if (GPIO_ISBID(pin)) {
- ret =
- gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
- gpio_to_mux_map[gpio]);
- } else if (GPIO_ISOUT(pin)) {
- ret =
- gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
- outp_to_mux_map[gpio]);
- } else if (GPIO_ISMUX(pin)) {
- ret = gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR, gpio);
- }
- gpio_unlock();
- return ret;
- }
- EXPORT_SYMBOL(pnx4008_gpio_set_pin_mux);
- /* Read pin mux function: 0= pin used as GPIO, 1= pin used for muxed function*/
- int pnx4008_gpio_read_pin_mux(unsigned short pin)
- {
- int gpio = GPIO_BIT_MASK(pin);
- int ret = -EFAULT;
- gpio_lock();
- if (GPIO_ISBID(pin)) {
- ret = gpio_read_bit(PIO_MUX_STATE, gpio_to_mux_map[gpio]);
- } else if (GPIO_ISOUT(pin)) {
- ret = gpio_read_bit(PIO_MUX_STATE, outp_to_mux_map[gpio]);
- } else if (GPIO_ISMUX(pin)) {
- ret = gpio_read_bit(PIO_MUX_STATE, gpio);
- }
- gpio_unlock();
- return ret;
- }
- EXPORT_SYMBOL(pnx4008_gpio_read_pin_mux);
|