[MIPS] rbtx4938: Add generic GPIO support
GPIO 0..15 are for TX4938 PIO pins, GPIO 16..18 are for FPGA-driven chipselect signals for SPI devices. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
06cf5583fd
commit
3896b05418
|
@ -660,6 +660,7 @@ config TOSHIBA_RBTX4938
|
|||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
select SYS_SUPPORTS_KGDB
|
||||
select GENERIC_HARDIRQS_NO__DO_IRQ
|
||||
select GENERIC_GPIO
|
||||
help
|
||||
This Toshiba board is based on the TX4938 processor. Say Y here to
|
||||
support this machine type
|
||||
|
|
|
@ -80,6 +80,7 @@ CONFIG_DMA_NONCOHERENT=y
|
|||
CONFIG_DMA_NEED_PCI_MAP_STATE=y
|
||||
CONFIG_GENERIC_ISA_DMA=y
|
||||
CONFIG_I8259=y
|
||||
CONFIG_GENERIC_GPIO=y
|
||||
# CONFIG_CPU_BIG_ENDIAN is not set
|
||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/tx4938/rbtx4938.h>
|
||||
#ifdef CONFIG_SERIAL_TXX9
|
||||
#include <linux/tty.h>
|
||||
|
@ -1057,3 +1058,106 @@ static int __init rbtx4938_ne_init(void)
|
|||
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
|
||||
}
|
||||
device_initcall(rbtx4938_ne_init);
|
||||
|
||||
/* GPIO support */
|
||||
|
||||
static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
|
||||
|
||||
static void rbtx4938_spi_gpio_set(unsigned gpio, int value)
|
||||
{
|
||||
u8 val;
|
||||
unsigned long flags;
|
||||
gpio -= 16;
|
||||
spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
|
||||
val = *rbtx4938_spics_ptr;
|
||||
if (value)
|
||||
val |= 1 << gpio;
|
||||
else
|
||||
val &= ~(1 << gpio);
|
||||
*rbtx4938_spics_ptr = val;
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
|
||||
}
|
||||
|
||||
static int rbtx4938_spi_gpio_dir_out(unsigned gpio, int value)
|
||||
{
|
||||
rbtx4938_spi_gpio_set(gpio, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(tx4938_gpio_lock);
|
||||
|
||||
static int tx4938_gpio_get(unsigned gpio)
|
||||
{
|
||||
return tx4938_pioptr->din & (1 << gpio);
|
||||
}
|
||||
|
||||
static void tx4938_gpio_set_raw(unsigned gpio, int value)
|
||||
{
|
||||
u32 val;
|
||||
val = tx4938_pioptr->dout;
|
||||
if (value)
|
||||
val |= 1 << gpio;
|
||||
else
|
||||
val &= ~(1 << gpio);
|
||||
tx4938_pioptr->dout = val;
|
||||
}
|
||||
|
||||
static void tx4938_gpio_set(unsigned gpio, int value)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&tx4938_gpio_lock, flags);
|
||||
tx4938_gpio_set_raw(gpio, value);
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&tx4938_gpio_lock, flags);
|
||||
}
|
||||
|
||||
static int tx4938_gpio_dir_in(unsigned gpio)
|
||||
{
|
||||
spin_lock_irq(&tx4938_gpio_lock);
|
||||
tx4938_pioptr->dir &= ~(1 << gpio);
|
||||
mmiowb();
|
||||
spin_unlock_irq(&tx4938_gpio_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tx4938_gpio_dir_out(unsigned int gpio, int value)
|
||||
{
|
||||
spin_lock_irq(&tx4938_gpio_lock);
|
||||
tx4938_gpio_set_raw(gpio, value);
|
||||
tx4938_pioptr->dir |= 1 << gpio;
|
||||
mmiowb();
|
||||
spin_unlock_irq(&tx4938_gpio_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_direction_input(unsigned gpio)
|
||||
{
|
||||
if (gpio < 16)
|
||||
return tx4938_gpio_dir_in(gpio);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int gpio_direction_output(unsigned gpio, int value)
|
||||
{
|
||||
if (gpio < 16)
|
||||
return tx4938_gpio_dir_out(gpio, value);
|
||||
if (gpio < 16 + 3)
|
||||
return rbtx4938_spi_gpio_dir_out(gpio, value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int gpio_get_value(unsigned gpio)
|
||||
{
|
||||
if (gpio < 16)
|
||||
return tx4938_gpio_get(gpio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_set_value(unsigned gpio, int value)
|
||||
{
|
||||
if (gpio < 16)
|
||||
tx4938_gpio_set(gpio, value);
|
||||
else
|
||||
rbtx4938_spi_gpio_set(gpio, value);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue