From 00607823bb9cf191f644cf3135065caae403e670 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 Jul 2010 14:05:17 +0800 Subject: [PATCH] add linux interface for spi_gpio.c --- arch/arm/mach-rk2818/include/mach/gpio.h | 124 +++++- arch/arm/mach-rk2818/include/mach/spi_fpga.h | 1 + drivers/fpga/spi_gpio.c | 393 ++++++++++++++++++- 3 files changed, 492 insertions(+), 26 deletions(-) mode change 100644 => 100755 drivers/fpga/spi_gpio.c diff --git a/arch/arm/mach-rk2818/include/mach/gpio.h b/arch/arm/mach-rk2818/include/mach/gpio.h index fba5bf1165e5..e75f459ed582 100755 --- a/arch/arm/mach-rk2818/include/mach/gpio.h +++ b/arch/arm/mach-rk2818/include/mach/gpio.h @@ -168,14 +168,116 @@ struct rk2818_gpio_bank { #define RK2818_PIN_PH6 (PIN_BASE + 7*NUM_GROUP + 6) #define RK2818_PIN_PH7 (PIN_BASE + 7*NUM_GROUP + 7) /***********************define extern gpio pin num******************************/ -#define RK2818_PIN_PI0 (GPIOS_EXPANDER_BASE + 0) -#define RK2818_PIN_PI1 (GPIOS_EXPANDER_BASE +1) -#define RK2818_PIN_PI2 (GPIOS_EXPANDER_BASE +2) -#define RK2818_PIN_PI3 (GPIOS_EXPANDER_BASE +3) -#define RK2818_PIN_PI4 (GPIOS_EXPANDER_BASE +4) -#define RK2818_PIN_PI5 (GPIOS_EXPANDER_BASE +5) -#define RK2818_PIN_PI6 (GPIOS_EXPANDER_BASE +6) -#define RK2818_PIN_PI7 (GPIOS_EXPANDER_BASE +7) +#if defined(CONFIG_SPI_GPIO) +#define FPGA_PIN_PA0 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 0) +#define FPGA_PIN_PA1 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 1) +#define FPGA_PIN_PA2 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 2) +#define FPGA_PIN_PA3 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 3) +#define FPGA_PIN_PA4 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 4) +#define FPGA_PIN_PA5 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 5) +#define FPGA_PIN_PA6 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 6) +#define FPGA_PIN_PA7 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 7) + +#define FPGA_PIN_PB0 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 0) +#define FPGA_PIN_PB1 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 1) +#define FPGA_PIN_PB2 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 2) +#define FPGA_PIN_PB3 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 3) +#define FPGA_PIN_PB4 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 4) +#define FPGA_PIN_PB5 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 5) +#define FPGA_PIN_PB6 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 6) +#define FPGA_PIN_PB7 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 7) + +#define FPGA_PIN_PC0 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 0) +#define FPGA_PIN_PC1 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 1) +#define FPGA_PIN_PC2 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 2) +#define FPGA_PIN_PC3 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 3) +#define FPGA_PIN_PC4 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 4) +#define FPGA_PIN_PC5 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 5) +#define FPGA_PIN_PC6 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 6) +#define FPGA_PIN_PC7 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 7) + +#define FPGA_PIN_PD0 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 0) +#define FPGA_PIN_PD1 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 1) +#define FPGA_PIN_PD2 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 2) +#define FPGA_PIN_PD3 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 3) +#define FPGA_PIN_PD4 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 4) +#define FPGA_PIN_PD5 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 5) +#define FPGA_PIN_PD6 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 6) +#define FPGA_PIN_PD7 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 7) + +#define FPGA_PIN_PE0 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 0) +#define FPGA_PIN_PE1 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 1) +#define FPGA_PIN_PE2 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 2) +#define FPGA_PIN_PE3 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 3) +#define FPGA_PIN_PE4 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 4) +#define FPGA_PIN_PE5 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 5) +#define FPGA_PIN_PE6 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 6) +#define FPGA_PIN_PE7 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 7) + +#define FPGA_PIN_PF0 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 0) +#define FPGA_PIN_PF1 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 1) +#define FPGA_PIN_PF2 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 2) +#define FPGA_PIN_PF3 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 3) +#define FPGA_PIN_PF4 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 4) +#define FPGA_PIN_PF5 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 5) +#define FPGA_PIN_PF6 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 6) +#define FPGA_PIN_PF7 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 7) + +#define FPGA_PIN_PG0 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 0) +#define FPGA_PIN_PG1 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 1) +#define FPGA_PIN_PG2 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 2) +#define FPGA_PIN_PG3 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 3) +#define FPGA_PIN_PG4 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 4) +#define FPGA_PIN_PG5 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 5) +#define FPGA_PIN_PG6 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 6) +#define FPGA_PIN_PG7 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 7) + +#define FPGA_PIN_PH0 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 0) +#define FPGA_PIN_PH1 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 1) +#define FPGA_PIN_PH2 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 2) +#define FPGA_PIN_PH3 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 3) +#define FPGA_PIN_PH4 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 4) +#define FPGA_PIN_PH5 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 5) +#define FPGA_PIN_PH6 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 6) +#define FPGA_PIN_PH7 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 7) + +#define FPGA_PIN_PI0 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 0) +#define FPGA_PIN_PI1 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 1) +#define FPGA_PIN_PI2 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 2) +#define FPGA_PIN_PI3 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 3) +#define FPGA_PIN_PI4 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 4) +#define FPGA_PIN_PI5 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 5) +#define FPGA_PIN_PI6 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 6) +#define FPGA_PIN_PI7 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 7) + +#define FPGA_PIN_PJ0 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 0) +#define FPGA_PIN_PJ1 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 1) +#define FPGA_PIN_PJ2 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 2) +#define FPGA_PIN_PJ3 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 3) +#define FPGA_PIN_PJ4 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 4) +#define FPGA_PIN_PJ5 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 5) +#define FPGA_PIN_PJ6 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 6) +#define FPGA_PIN_PJ7 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 7) + +#define FPGA_PIN_PK0 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 0) +#define FPGA_PIN_PK1 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 1) +#define FPGA_PIN_PK2 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 2) +#define FPGA_PIN_PK3 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 3) +#define FPGA_PIN_PK4 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 4) +#define FPGA_PIN_PK5 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 5) +#define FPGA_PIN_PK6 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 6) +#define FPGA_PIN_PK7 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 7) + +#define FPGA_PIN_PL0 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 0) +#define FPGA_PIN_PL1 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 1) +#define FPGA_PIN_PL2 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 2) +#define FPGA_PIN_PL3 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 3) +#define FPGA_PIN_PL4 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 4) +#define FPGA_PIN_PL5 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 5) +#define FPGA_PIN_PL6 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 6) +#define FPGA_PIN_PL7 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 7) + +#endif #ifndef __ASSEMBLY__ extern void __init rk2818_gpio_init(struct rk2818_gpio_bank *data, int nr_banks); extern void __init rk2818_gpio_irq_setup(void); @@ -211,10 +313,12 @@ static inline int irq_to_gpio(unsigned irq) { return (RK2818_PIN_PE0 + (irq - __gpio_to_irq(RK2818_PIN_PE0))); } - else if((irq - __gpio_to_irq(RK2818_PIN_PA0)) <3*NUM_GROUP) +#if defined(CONFIG_SPI_GPIO) + else if((irq - __gpio_to_irq(FPGA_PIN_PA0)) <2*NUM_GROUP) { - return (RK2818_PIN_PI0 + (irq - __gpio_to_irq(RK2818_PIN_PI0))); + return (FPGA_PIN_PA0 + (irq - __gpio_to_irq(FPGA_PIN_PA0))); } +#endif else { return -ENXIO; diff --git a/arch/arm/mach-rk2818/include/mach/spi_fpga.h b/arch/arm/mach-rk2818/include/mach/spi_fpga.h index dfc5e60c58a4..51a402bd0b33 100755 --- a/arch/arm/mach-rk2818/include/mach/spi_fpga.h +++ b/arch/arm/mach-rk2818/include/mach/spi_fpga.h @@ -501,6 +501,7 @@ extern int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiG extern int spi_free_gpio_irq(eSpiGpioPinNum_t PinNum); extern int spi_gpio_handle_irq(struct spi_device *spi); extern int spi_gpio_init(void); +extern void spi_gpio_irq_setup(void); extern int spi_gpio_register(struct spi_fpga_port *port); extern int spi_gpio_unregister(struct spi_fpga_port *port); #endif diff --git a/drivers/fpga/spi_gpio.c b/drivers/fpga/spi_gpio.c old mode 100644 new mode 100755 index 2c0821f7bb26..6c951950fdbe --- a/drivers/fpga/spi_gpio.c +++ b/drivers/fpga/spi_gpio.c @@ -26,7 +26,8 @@ #include #include #include - +#include +#include #include #if defined(CONFIG_SPI_GPIO_DEBUG) @@ -35,7 +36,7 @@ #define DBG(x...) #endif -#define SPI_GPIO_TEST 0 +#define SPI_GPIO_TEST 1 #define HIGH_SPI_TEST 1 spinlock_t gpio_lock; spinlock_t gpio_state_lock; @@ -45,6 +46,7 @@ static unsigned short int gGpio0State = 0; static SPI_GPIO_PDATA g_spiGpioVectorTable[SPI_GPIO_IRQ_NUM] = \ {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}; +/************FPGA ²Ù×÷GPIOµÄº¯ÊýʵÏÖ************************/ static void spi_gpio_write_reg(int reg, int PinNum, int set) { @@ -111,7 +113,7 @@ int spi_gpio_int_sel(eSpiGpioPinNum_t PinNum,eSpiGpioTypeSel_t type) { int reg = get_gpio_addr(PinNum); //struct spi_fpga_port *port = pFpgaPort; - + DBG("%s:PinNum=%d,type=%d\n",__FUNCTION__,PinNum,type); if(ICE_SEL_GPIO0 == reg) { reg |= ICE_SEL_GPIO0_TYPE; @@ -313,7 +315,7 @@ int spi_gpio_enable_int(eSpiGpioPinNum_t PinNum) reg |= ICE_SEL_GPIO0_INT_EN; if((state & (1 << PinNum )) == 0) { - printk("Fail to enable int because it is gpio pin!\n"); + printk("%s:Fail to enable int because it is gpio pin!\n",__FUNCTION__); return -1; } DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_ENABLE); @@ -344,7 +346,7 @@ int spi_gpio_disable_int(eSpiGpioPinNum_t PinNum) if((state & (1 << PinNum )) == 0) { - printk("Fail to enable int because it is gpio pin!\n"); + printk("%s:Fail to enable int because it is gpio pin!\n",__FUNCTION__); return -1; } @@ -376,7 +378,7 @@ int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntType_t IntType) if((state & (1 << PinNum )) == 0) { - printk("Fail to enable int because it is gpio pin!\n"); + printk("%s:Fail to enable int because it is gpio pin!\n",__FUNCTION__); return -1; } @@ -450,7 +452,7 @@ int spi_free_gpio_irq(eSpiGpioPinNum_t PinNum) return 0; } - +#if 0 int spi_gpio_handle_irq(struct spi_device *spi) { int gpio_iir, i; @@ -481,6 +483,35 @@ int spi_gpio_handle_irq(struct spi_device *spi) return 0; } +#else +int spi_gpio_handle_irq(struct spi_device *spi) +{ + int gpio_iir, i; + int state; + int irq; + spin_lock(&gpio_state_lock); + state = gGpio0State; + spin_unlock(&gpio_state_lock); + + gpio_iir = spi_gpio_read_iir() & 0xffff; + if(gpio_iir == 0xffff) + return -1; + + DBG("gpio_iir=0x%x\n",gpio_iir); + for(i=0; i"); -MODULE_LICENSE("GPL"); +#if 1 + +/************³éÏóGPIO½Ó¿Úº¯ÊýʵÏÖ²¿·Ö************************/ +static int spi_gpiolib_direction_input(struct gpio_chip *chip, unsigned offset) +{ + int pinnum = offset + chip->base -GPIOS_EXPANDER_BASE; + DBG("%s:pinnum=%d\n",__FUNCTION__,pinnum); + if(pinnum < 16) + spi_gpio_int_sel(pinnum,SPI_GPIO0_IS_GPIO); + return spi_gpio_set_pindirection(pinnum, SPI_GPIO_IN); +} + +static int spi_gpiolib_direction_output(struct gpio_chip *chip, unsigned offset, int val) +{ + int pinnum = offset + chip->base -GPIOS_EXPANDER_BASE; + if(pinnum < 16) + spi_gpio_int_sel(pinnum,SPI_GPIO0_IS_GPIO); + DBG("%s:pinnum=%d\n",__FUNCTION__,pinnum); + if(GPIO_HIGH == val) + spi_gpio_set_pinlevel(pinnum,SPI_GPIO_HIGH); + else + spi_gpio_set_pinlevel(pinnum,SPI_GPIO_LOW); + return spi_gpio_set_pindirection(pinnum, SPI_GPIO_OUT); +} + +static int spi_gpiolib_get_pinlevel(struct gpio_chip *chip, unsigned int offset) +{ + int pinnum = offset + chip->base -GPIOS_EXPANDER_BASE; + DBG("%s:pinnum=%d\n",__FUNCTION__,pinnum); + return spi_gpio_get_pinlevel(pinnum); +} + +static void spi_gpiolib_set_pinlevel(struct gpio_chip *chip, unsigned int offset, int val) +{ + int pinnum = offset + chip->base -GPIOS_EXPANDER_BASE; + DBG("%s:pinnum=%d\n",__FUNCTION__,pinnum); + if(GPIO_HIGH == val) + spi_gpio_set_pinlevel(pinnum,SPI_GPIO_HIGH); + else + spi_gpio_set_pinlevel(pinnum,SPI_GPIO_LOW); +} + +static int spi_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, unsigned val) +{ + return 0; //FPGA do not support pull up or down +} + +static void spi_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + //to do +} + +static int spi_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset) +{ + if(offset < CONFIG_EXPANDED_GPIO_IRQ_NUM) + return offset + NR_AIC_IRQS + CONFIG_RK28_GPIO_IRQ; + else + return -EINVAL; +} + +struct fpga_gpio_bank { + unsigned short id; //GPIO¼Ä´æÆ÷×éµÄIDʶ±ðºÅ + unsigned long offset; //GPIO0»òGPIO1µÄ»ùµØÖ· + struct clk *clock; /* associated clock */ +}; + +struct fpga_gpio_chip { + struct gpio_chip chip; + struct fpga_gpio_chip *next; /* Bank sharing same clock */ + struct fpga_gpio_bank *bank; /* Bank definition */ + void __iomem *regbase; /* Base of register bank */ +}; + +#define SPI_GPIO_CHIP_DEF(name, base_gpio, nr_gpio) \ + { \ + .chip = { \ + .label = name, \ + .direction_input = spi_gpiolib_direction_input, \ + .direction_output = spi_gpiolib_direction_output, \ + .get = spi_gpiolib_get_pinlevel, \ + .set = spi_gpiolib_set_pinlevel, \ + .pull_updown = spi_gpiolib_pull_updown, \ + .dbg_show = spi_gpiolib_dbg_show, \ + .to_irq = spi_gpiolib_to_irq, \ + .base = base_gpio, \ + .ngpio = nr_gpio, \ + }, \ + } +static struct fpga_gpio_chip spi_gpio_chip[] = { + SPI_GPIO_CHIP_DEF("PIO0", GPIOS_EXPANDER_BASE+0*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO0", GPIOS_EXPANDER_BASE+1*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO1", GPIOS_EXPANDER_BASE+2*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO1", GPIOS_EXPANDER_BASE+3*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO2", GPIOS_EXPANDER_BASE+4*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO2", GPIOS_EXPANDER_BASE+5*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO3", GPIOS_EXPANDER_BASE+6*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO3", GPIOS_EXPANDER_BASE+7*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO4", GPIOS_EXPANDER_BASE+8*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO4", GPIOS_EXPANDER_BASE+9*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO5", GPIOS_EXPANDER_BASE+10*NUM_GROUP, NUM_GROUP), + SPI_GPIO_CHIP_DEF("PIO5", GPIOS_EXPANDER_BASE+11*NUM_GROUP, NUM_GROUP), +}; + + +static void spi_gpio_irq_enable(unsigned irq) +{ + int gpio = irq_to_gpio(irq) - GPIOS_EXPANDER_BASE; + DBG("%s:line=%d,gpio=%d\n",__FUNCTION__,__LINE__,gpio); + if(gpio < 16) + spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT); + else + { + printk("err:%s:pin %d don't support gpio irq!\n",__FUNCTION__,gpio); + return; + } + spi_gpio_enable_int(gpio); +} +static void spi_gpio_irq_disable(unsigned irq) +{ + int gpio = irq_to_gpio(irq) - GPIOS_EXPANDER_BASE; + DBG("%s:line=%d,gpio=%d\n",__FUNCTION__,__LINE__,gpio); + if(gpio < 16) + spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT); + else + { + printk("err:%s:pin %d don't support gpio irq!\n",__FUNCTION__,gpio); + return; + } + spi_gpio_disable_int(gpio); + +} + + +static void spi_gpio_irq_mask(unsigned int irq) +{ + //FPGA do not support irq mask +} + +static void spi_gpio_irq_unmask(unsigned int irq) +{ + //FPGA do not support irq unmask +} + +static int spi_gpio_irq_set_type(unsigned int irq, unsigned int type) +{ + int gpio = irq_to_gpio(irq) - GPIOS_EXPANDER_BASE; + int int_type = 0; + DBG("%s:line=%d,type=%d\n",__FUNCTION__,__LINE__,type); + if(gpio < 16) + spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT); + else + { + printk("err:%s:pin %d don't support gpio irq!\n",__FUNCTION__,gpio); + return -1; + } + switch(type) + { + case GPIOEdgelFalling: + int_type = SPI_GPIO_EDGE_FALLING; + break; + case GPIOEdgelRising: + int_type = SPI_GPIO_EDGE_RISING; + break; + default: + printk("err:%s:FPGA don't support this intterupt type!\n",__FUNCTION__); + break; + } + spi_gpio_set_int_trigger(gpio, int_type); + return 0; +} + +static int spi_gpio_irq_set_wake(unsigned irq, unsigned state) +{ + //unsigned int pin = irq_to_gpio(irq); + set_irq_wake(irq, state); + return 0; +} + +static struct irq_chip spi_gpio_irq_chip = { + .name = "SPI_GPIO_IRQ", + .enable = spi_gpio_irq_enable, + .disable = spi_gpio_irq_disable, + .mask = spi_gpio_irq_mask, + .unmask = spi_gpio_irq_unmask, + .set_type = spi_gpio_irq_set_type, + .set_wake = spi_gpio_irq_set_wake, +}; + +void spi_gpio_test_gpio_irq_init(void) +{ +#if SPI_GPIO_TEST + struct spi_fpga_port *port = pFpgaPort; + int i,gpio,ret; + + for(i=0;i<81;i++) + { + gpio = FPGA_PIN_PA0+i; + ret = gpio_request(gpio, NULL); + if (ret) { + printk("%s:failed to request GPIO[%d]\n",__FUNCTION__,gpio); + } + } +#if 1 + for(i=0;i<4;i++) + { + gpio = FPGA_PIN_PA0+i; + + switch(i) + { + case 0: + ret = request_irq(gpio_to_irq(gpio),spi_gpio_int_test_0,IRQF_TRIGGER_FALLING,NULL,port); + if(ret) + { + printk("unable to request GPIO[%d] irq\n",gpio); + gpio_free(gpio); + } + break; + + case 1: + ret = request_irq(gpio_to_irq(gpio),spi_gpio_int_test_1,IRQF_TRIGGER_FALLING,NULL,port); + if(ret) + { + printk("unable to request GPIO[%d] irq\n",gpio); + gpio_free(gpio); + } + break; + + case 2: + ret = request_irq(gpio_to_irq(gpio),spi_gpio_int_test_2,IRQF_TRIGGER_FALLING,NULL,port); + if(ret) + { + printk("unable to request GPIO[%d] irq\n",gpio); + gpio_free(gpio); + } + break; + + case 3: + ret = request_irq(gpio_to_irq(gpio),spi_gpio_int_test_3,IRQF_TRIGGER_FALLING,NULL,port); + if(ret) + { + printk("unable to request GPIO[%d] irq\n",gpio); + gpio_free(gpio); + } + break; + + default: + break; + } + + } +#endif + +#endif + +} + +int spi_gpio_banks; +static struct lock_class_key gpio_lock_class; +int spi_gpio_init(void) +{ + unsigned i; + struct fpga_gpio_chip *fpga_gpio_chip; + spi_gpio_banks = 12; + spi_gpio_init_first(); + for (i = 0; i < 12; i++) + { + fpga_gpio_chip = &spi_gpio_chip[i]; + gpiochip_add(&fpga_gpio_chip->chip); + } + + return 0; +} + +/* + * Called from the processor-specific init to enable GPIO interrupt support. + */ +void spi_gpio_irq_setup(void) +{ + unsigned int i,j, pin; + struct fpga_gpio_chip *this; + + this = spi_gpio_chip; + pin = NR_AIC_IRQS + CONFIG_RK28_GPIO_IRQ; + + for(i=0;i<2;i++) + { + for (j = 0; j < 8; j++) + { + lockdep_set_class(&irq_desc[pin+j].lock, &gpio_lock_class); + /* + * Can use the "simple" and not "edge" handler since it's + * shorter, and the AIC handles interrupts sanely. + */ + set_irq_chip(pin+j, &spi_gpio_irq_chip); + set_irq_handler(pin+j, handle_simple_irq); + set_irq_flags(pin+j, IRQF_VALID); + //set_irq_chip_data(pin+j, this); + //set_irq_chained_handler(pin+j, spi_fpga_irq); + } + + this += 4; + pin += 8; + } + printk("%s: %d gpio irqs in %d banks\n", __FUNCTION__, pin-GPIOS_EXPANDER_BASE, spi_gpio_banks); +#if SPI_GPIO_TEST + spi_gpio_test_gpio_irq_init(); +#endif +} +#endif + +MODULE_DESCRIPTION("Driver for spi2gpio."); +MODULE_AUTHOR("luowei "); +MODULE_LICENSE("GPL"); \ No newline at end of file -- 2.34.1