From: root Date: Mon, 26 Jul 2010 08:46:48 +0000 (+0800) Subject: fpga driver update X-Git-Tag: firefly_0821_release~11343 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6ccd5e75a3d609e440edf3deb47cb9aa5fd0ad20;p=firefly-linux-kernel-4.4.55.git fpga driver update --- diff --git a/arch/arm/mach-rk2818/board-midsdk.c b/arch/arm/mach-rk2818/board-midsdk.c index 1d68487a1a1d..6e0236b7cd8c 100644 --- a/arch/arm/mach-rk2818/board-midsdk.c +++ b/arch/arm/mach-rk2818/board-midsdk.c @@ -287,14 +287,14 @@ struct rk2818_i2c_platform_data default_i2c1_data = { .cfg_gpio = rk2818_i2c1_cfg_gpio, }; -struct rk2818_i2c_platform_data default_i2c2_data = { +struct rk2818_i2c_spi_data default_i2c2_data = { .bus_num = 2, .flags = 0, .slave_addr = 0xff, .scl_rate = 400*1000, }; -struct rk2818_i2c_platform_data default_i2c3_data = { +struct rk2818_i2c_spi_data default_i2c3_data = { .bus_num = 3, .flags = 0, @@ -454,12 +454,6 @@ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_I2C1_RK2818 &rk2818_device_i2c1, #endif -#ifdef CONFIG_SPI_I2C - &rk2818_device_i2c2, -#endif -#ifdef CONFIG_SPI_I2C - &rk2818_device_i2c3, -#endif #ifdef CONFIG_SDMMC0_RK2818 &rk2818_device_sdmmc0, #endif diff --git a/arch/arm/mach-rk2818/board-phonesdk.c b/arch/arm/mach-rk2818/board-phonesdk.c index c65f56144f88..1690ebd58c45 100755 --- a/arch/arm/mach-rk2818/board-phonesdk.c +++ b/arch/arm/mach-rk2818/board-phonesdk.c @@ -285,14 +285,14 @@ struct rk2818_i2c_platform_data default_i2c1_data = { .cfg_gpio = rk2818_i2c1_cfg_gpio, }; -struct rk2818_i2c_platform_data default_i2c2_data = { +struct rk2818_i2c_spi_data default_i2c2_data = { .bus_num = 2, .flags = 0, .slave_addr = 0xff, .scl_rate = 400*1000, }; -struct rk2818_i2c_platform_data default_i2c3_data = { +struct rk2818_i2c_spi_data default_i2c3_data = { .bus_num = 3, .flags = 0, @@ -460,12 +460,6 @@ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_I2C1_RK2818 &rk2818_device_i2c1, #endif -#ifdef CONFIG_SPI_I2C - &rk2818_device_i2c2, -#endif -#ifdef CONFIG_SPI_I2C - &rk2818_device_i2c3, -#endif #ifdef CONFIG_SDMMC0_RK2818 &rk2818_device_sdmmc0, #endif diff --git a/arch/arm/mach-rk2818/board-raho.c b/arch/arm/mach-rk2818/board-raho.c index 8319ebcb35fa..97a5c18f4d53 100644 --- a/arch/arm/mach-rk2818/board-raho.c +++ b/arch/arm/mach-rk2818/board-raho.c @@ -287,14 +287,14 @@ struct rk2818_i2c_platform_data default_i2c1_data = { .cfg_gpio = rk2818_i2c1_cfg_gpio, }; -struct rk2818_i2c_platform_data default_i2c2_data = { +struct rk2818_i2c_spi_data default_i2c2_data = { .bus_num = 2, .flags = 0, .slave_addr = 0xff, .scl_rate = 400*1000, }; -struct rk2818_i2c_platform_data default_i2c3_data = { +struct rk2818_i2c_spi_data default_i2c3_data = { .bus_num = 3, .flags = 0, @@ -463,12 +463,6 @@ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_I2C1_RK2818 &rk2818_device_i2c1, #endif -#ifdef CONFIG_SPI_I2C - &rk2818_device_i2c2, -#endif -#ifdef CONFIG_SPI_I2C - &rk2818_device_i2c3, -#endif #ifdef CONFIG_SDMMC0_RK2818 &rk2818_device_sdmmc0, #endif diff --git a/arch/arm/mach-rk2818/devices.h b/arch/arm/mach-rk2818/devices.h index 7a8263bebe82..631eb18b28fe 100644 --- a/arch/arm/mach-rk2818/devices.h +++ b/arch/arm/mach-rk2818/devices.h @@ -27,8 +27,8 @@ extern struct platform_device rk2818_device_i2c2; extern struct platform_device rk2818_device_i2c3; extern struct rk2818_i2c_platform_data default_i2c0_data; extern struct rk2818_i2c_platform_data default_i2c1_data; -extern struct rk2818_i2c_platform_data default_i2c2_data; -extern struct rk2818_i2c_platform_data default_i2c3_data; +extern struct rk2818_i2c_spi_data default_i2c2_data; +extern struct rk2818_i2c_spi_data default_i2c3_data; extern struct platform_device rk2818_device_sdmmc0; extern struct platform_device rk2818_device_sdmmc1; diff --git a/arch/arm/mach-rk2818/include/mach/board.h b/arch/arm/mach-rk2818/include/mach/board.h index 0de9068242b5..8b8d379cedba 100644 --- a/arch/arm/mach-rk2818/include/mach/board.h +++ b/arch/arm/mach-rk2818/include/mach/board.h @@ -32,6 +32,12 @@ struct rk2818_sdmmc_platform_data { void (*cfg_gpio)(struct platform_device *dev); }; +struct rk2818_i2c_spi_data { + int bus_num; + unsigned int flags; + unsigned int slave_addr; + unsigned long scl_rate; +}; struct rk2818_i2c_platform_data { int bus_num; unsigned int flags; diff --git a/drivers/fpga/spi_dpram.c b/drivers/fpga/spi_dpram.c index f0e112d3534b..5e2551bcdae5 100644 --- a/drivers/fpga/spi_dpram.c +++ b/drivers/fpga/spi_dpram.c @@ -27,7 +27,7 @@ #include #include -#include "spi_fpga.h" +#include #if defined(CONFIG_SPI_DPRAM_DEBUG) #define DBG(x...) printk(x) @@ -117,12 +117,13 @@ static int spi_dpram_read_buf(struct spi_dpram *dpram, unsigned short int addr, { struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram); unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL & ICE_SEL_DPRAM_READ)); - unsigned char tx_buf[3]; + unsigned char tx_buf[4]; unsigned char stat; tx_buf[0] = opt; tx_buf[1] = ((addr << 1) >> 8) & 0xff; tx_buf[2] = ((addr << 1) & 0xff); + tx_buf[3] = 0;//give fpga 8 clks for reading data stat = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), buf, len); if(stat) @@ -172,11 +173,12 @@ int spi_dpram_read_ptr(struct spi_dpram *dpram, unsigned short int addr) int ret; struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram); unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL & ICE_SEL_DPRAM_READ)); - unsigned char tx_buf[3],rx_buf[2]; + unsigned char tx_buf[4],rx_buf[2]; tx_buf[0] = opt; tx_buf[1] = ((addr << 1) >> 8) & 0xff; tx_buf[2] = ((addr << 1) & 0xff); + tx_buf[3] = 0;//give fpga 8 clks for reading data ret = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), rx_buf, sizeof(rx_buf)); if(ret) @@ -221,11 +223,12 @@ int spi_dpram_read_mailbox(struct spi_dpram *dpram) int ret; struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram); unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL & ICE_SEL_DPRAM_READ)); - unsigned char tx_buf[3],rx_buf[2]; + unsigned char tx_buf[4],rx_buf[2]; tx_buf[0] = opt; tx_buf[1] = ((SPI_DPRAM_MAILBOX_BPWRITE << 1) >> 8) & 0xff; tx_buf[2] = ((SPI_DPRAM_MAILBOX_BPWRITE << 1) & 0xff); + tx_buf[3] = 0;//give fpga 8 clks for reading data ret = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), rx_buf, sizeof(rx_buf)); if(ret) @@ -271,80 +274,82 @@ static irqreturn_t spi_dpram_busy_irq(int irq, void *dev_id) } #if SPI_DPRAM_TEST -#define DPRAM_TEST_LEN 512 //8bit +#define SEL_RAM0 0 +#define SEL_RAM1 1 +#define SEL_RAM2 2 +#define SEL_RAM3 3 +#define SEL_REG 4 +#define SEL_RAM SEL_RAM2 +#define DPRAM_TEST_LEN 16 //8bit unsigned char buf_test_dpram[DPRAM_TEST_LEN]; void spi_dpram_work_handler(struct work_struct *work) { - int i; + int i,j; int ret; struct spi_fpga_port *port = container_of(work, struct spi_fpga_port, dpram.spi_dpram_work); printk("*************test spi_dpram now***************\n"); - - for(i=0; i<(DPRAM_TEST_LEN>>1); i++) - { - buf_test_dpram[2*i] = (0xa000+i)>>8; - buf_test_dpram[2*i+1] = (0xa000+i)&0xff; - } -#if 0 + +#if(SEL_RAM == SEL_RAM0) //RAM0 for(i=0;i<(SPI_DPRAM_BPWRITE_SIZE/(DPRAM_TEST_LEN>>1));i++) { - spi_dpram_read_buf(&port->dpram, SPI_DPRAM_BPWRITE_START+(i*DPRAM_TEST_LEN>>1), port->dpram.prx, DPRAM_TEST_LEN); + port->dpram.read_dpram(&port->dpram, SPI_DPRAM_BPWRITE_START+(i*DPRAM_TEST_LEN>>1), port->dpram.prx+i*DPRAM_TEST_LEN, DPRAM_TEST_LEN); } - for(i=0;idpram.prx+2*i)<<8) | (*(port->dpram.prx+2*i+1)); if(ret != 0xa000+i) printk("prx[%d]=0x%x ram[%d]=0x%x\n",i,ret&0xffff,i,0xa000+i); } -#endif - -#if 0 +#elif(SEL_RAM == SEL_RAM1) //RAM1 for(i=0;i<(SPI_DPRAM_APWRITE_SIZE/(DPRAM_TEST_LEN>>1));i++) { + for(j=(i*(DPRAM_TEST_LEN>>1)); j<((i+1)*(DPRAM_TEST_LEN>>1)); j++) + { + buf_test_dpram[2*(j-(i*(DPRAM_TEST_LEN>>1)))] = (0xa000+j)>>8; + buf_test_dpram[2*(j-(i*(DPRAM_TEST_LEN>>1)))+1] = (0xa000+j)&0xff; + printk("buf_test_dpram[%d]=0x%x\n",j,buf_test_dpram[(j-(i*(DPRAM_TEST_LEN>>1)))]); + } + port->dpram.write_dpram(&port->dpram, ((DPRAM_TEST_LEN*i)>>1)+SPI_DPRAM_APWRITE_START, buf_test_dpram, sizeof(buf_test_dpram)); mdelay(1); } - - for(i=0;i>1));i++) { - spi_dpram_read_buf(&port->dpram, SPI_DPRAM_LOG_BPWRITE_START+(i*DPRAM_TEST_LEN>>1), port->dpram.prx, DPRAM_TEST_LEN); + port->dpram.read_dpram(&port->dpram, SPI_DPRAM_LOG_BPWRITE_START+(i*DPRAM_TEST_LEN>>1), port->dpram.prx+i*DPRAM_TEST_LEN, DPRAM_TEST_LEN); } - for(i=0;idpram.prx+2*i)<<8) | (*(port->dpram.prx+2*i+1)); if(ret != 0xc000+i) printk("prx[%d]=0x%x ram[%d]=0x%x\n",i,ret&0xffff,i,0xc000+i); } -#endif - -#if 0 + +#elif(SEL_RAM == SEL_RAM3) //RAM3 for(i=0;i<(SPI_DPRAM_LOG_APWRITE_SIZE/(DPRAM_TEST_LEN>>1));i++) { - spi_dpram_write_buf(&port->dpram, ((DPRAM_TEST_LEN*i)>>1)+SPI_DPRAM_LOG_APWRITE_START, buf_test_dpram, sizeof(buf_test_dpram)); + for(j=(i*(DPRAM_TEST_LEN>>1)); j<((i+1)*(DPRAM_TEST_LEN>>1)); j++) + { + buf_test_dpram[2*(j-(i*(DPRAM_TEST_LEN>>1)))] = (0xa000+j)>>8; + buf_test_dpram[2*(j-(i*(DPRAM_TEST_LEN>>1)))+1] = (0xa000+j)&0xff; + printk("buf_test_dpram[%d]=0x%x\n",j,buf_test_dpram[(j-(i*(DPRAM_TEST_LEN>>1)))]); + } + + port->dpram.write_dpram(&port->dpram, ((DPRAM_TEST_LEN*i)>>1)+SPI_DPRAM_LOG_APWRITE_START, buf_test_dpram, sizeof(buf_test_dpram)); mdelay(1); } - for(i=0;idpram.write_ptr(&port->dpram, SPI_DPRAM_PTR0_APWRITE_BPREAD, SPI_DPRAM_PTR0_APWRITE_BPREAD); port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, SPI_DPRAM_PTR1_APWRITE_BPREAD); port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR2_APWRITE_BPREAD, SPI_DPRAM_PTR2_APWRITE_BPREAD); @@ -353,46 +358,24 @@ void spi_dpram_work_handler(struct work_struct *work) ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR0_BPWRITE_APREAD); if(ret != SPI_DPRAM_PTR0_BPWRITE_APREAD) - { - //ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR0_BPWRITE_APREAD); - //if(ret != SPI_DPRAM_PTR0_BPWRITE_APREAD) - printk("SPI_DPRAM_PTR0_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR0_BPWRITE_APREAD,ret); - } + printk("SPI_DPRAM_PTR0_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR0_BPWRITE_APREAD,ret); ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR1_BPWRITE_APREAD); if(ret != SPI_DPRAM_PTR1_BPWRITE_APREAD) - { - //ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR1_BPWRITE_APREAD); - //if(ret != SPI_DPRAM_PTR1_BPWRITE_APREAD) - printk("SPI_DPRAM_PTR1_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR1_BPWRITE_APREAD,ret); - } - + printk("SPI_DPRAM_PTR1_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR1_BPWRITE_APREAD,ret); + ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR2_BPWRITE_APREAD); if(ret != SPI_DPRAM_PTR2_BPWRITE_APREAD) - { - //ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR2_BPWRITE_APREAD); - //if(ret != SPI_DPRAM_PTR2_BPWRITE_APREAD) - printk("SPI_DPRAM_PTR2_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR2_BPWRITE_APREAD,ret); - } - + printk("SPI_DPRAM_PTR2_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR2_BPWRITE_APREAD,ret); ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR3_BPWRITE_APREAD); if(ret != SPI_DPRAM_PTR3_BPWRITE_APREAD) - { - //ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR3_BPWRITE_APREAD); - //if(ret != SPI_DPRAM_PTR3_BPWRITE_APREAD) - printk("SPI_DPRAM_PTR3_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR3_BPWRITE_APREAD,ret); - - } - mdelay(10); + printk("SPI_DPRAM_PTR3_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR3_BPWRITE_APREAD,ret); ret = port->dpram.read_mailbox(&port->dpram); if(ret != SPI_DPRAM_MAILBOX_BPWRITE) - { - //ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_MAILBOX_BPWRITE); - //if(ret != SPI_DPRAM_MAILBOX_BPWRITE) - printk("SPI_DPRAM_MAILBOX_BPWRITE(0x%x)=0x%x\n",SPI_DPRAM_MAILBOX_BPWRITE,ret); - } + printk("SPI_DPRAM_MAILBOX_BPWRITE(0x%x)=0x%x\n",SPI_DPRAM_MAILBOX_BPWRITE,ret); + #endif @@ -414,10 +397,9 @@ static void spi_testdpram_timer(unsigned long data) int spi_dpram_handle_irq(struct spi_device *spi) { struct spi_fpga_port *port = spi_get_drvdata(spi); - DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); -#if 0 unsigned char mbox = port->dpram.read_mailbox(&port->dpram); unsigned int len; + DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); switch(mbox) { case MAILBOX_BPWRITE_DATA: @@ -431,7 +413,7 @@ int spi_dpram_handle_irq(struct spi_device *spi) default: break; } -#endif + return 0; } @@ -451,8 +433,8 @@ static int dpr_open(struct inode *inode, struct file *filp) static int dpr_close(struct inode *inode, struct file *filp) { - struct spi_fpga_port *port = pFpgaPort; - DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); + //struct spi_fpga_port *port = pFpgaPort; + DBG("%s:line=%d\n",__FUNCTION__,__LINE__); filp->private_data = NULL; return 0; } @@ -528,9 +510,9 @@ static ssize_t dpr_write (struct file *filp, const char __user *buffer, size_t c unsigned int dpr_poll(struct file *filp, struct poll_table_struct * wait) { unsigned int mask = 0; - struct spi_fpga_port *port = filp->private_data; - - DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); + struct spi_fpga_port *port; + port = filp->private_data; + DBG("%s:line=%d\n",__FUNCTION__,__LINE__); return mask; } diff --git a/drivers/fpga/spi_fpga.h b/drivers/fpga/spi_fpga.h index 91b34d0742e4..cd889b929dcd 100644 --- a/drivers/fpga/spi_fpga.h +++ b/drivers/fpga/spi_fpga.h @@ -9,6 +9,12 @@ defines of FPGA chip ICE65L08's register #define SPI_DPRAM_BUSY_PIN RK2818_PIN_PA2 #define SPI_FPGA_STANDBY_PIN RK2818_PIN_PH7 +#define SPI_FPGA_TEST_DEBUG 0 +#if SPI_FPGA_TEST_DEBUG +#define SPI_FPGA_TEST_DEBUG_PIN RK2818_PIN_PE0 +extern int spi_test_wrong_handle(void); +#endif + struct uart_icount { __u32 cts; __u32 dsr; @@ -132,6 +138,7 @@ struct spi_fpga_port { #define SEL_GPIO 1 #define SEL_I2C 2 #define SEL_DPRAM 3 +#define READ_TOP_INT 4 /* CMD */ #define ICE_SEL_UART (SEL_UART<<6) @@ -196,6 +203,17 @@ typedef enum I2C_ch I2C_CH2, I2C_CH3 }eI2C_ch_t; +typedef enum eI2CReadMode +{ + I2C_NORMAL, + I2C_NOREG +}eI2ReadMode_t; + +typedef enum eI2RegType +{ + I2C_8_BIT, + I2C_16_BIT +}eI2RegType_t; #define ICE_SEL_I2C_START (0<<0) #define ICE_SEL_I2C_STOP (1<<0) @@ -298,6 +316,7 @@ typedef enum eSpiGpioPinDirection { SPI_GPIO_IN = 0, SPI_GPIO_OUT, + SPI_GPIO_DIR_ERR, }eSpiGpioPinDirection_t; @@ -483,7 +502,7 @@ extern int spi_gpio_unregister(struct spi_fpga_port *port); #endif #if defined(CONFIG_SPI_I2C) extern int spi_i2c_handle_irq(struct spi_fpga_port *port,unsigned char channel); -extern int spi_i2c_register(struct spi_fpga_port *port); +extern int spi_i2c_register(struct spi_fpga_port *port,int num); extern int spi_i2c_unregister(struct spi_fpga_port *port); #endif #if defined(CONFIG_SPI_DPRAM) diff --git a/drivers/fpga/spi_fpga_init.c b/drivers/fpga/spi_fpga_init.c index b5bea0afb764..8195aa288156 100644 --- a/drivers/fpga/spi_fpga_init.c +++ b/drivers/fpga/spi_fpga_init.c @@ -44,20 +44,21 @@ #include #include -#include "spi_fpga.h" +#include #if defined(CONFIG_SPI_FPGA_INIT_DEBUG) #define DBG(x...) printk(x) #else #define DBG(x...) #endif + struct spi_fpga_port *pFpgaPort; /*------------------------spi¶ÁдµÄ»ù±¾º¯Êý-----------------------*/ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type) { unsigned char index = 0; - unsigned char tx_buf[1], rx_buf[2], n_rx=2, stat=0; + unsigned char tx_buf[2], rx_buf[2], n_rx=2, stat=0; unsigned int result=0; //printk("index1=%d\n",index); @@ -68,10 +69,11 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type) index = port->uart.index; reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ | ICE_SEL_UART_CH(index)); tx_buf[0] = reg & 0xff; + tx_buf[1] = 0; rx_buf[0] = 0; rx_buf[1] = 0; - stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx); - result = rx_buf[1]; + stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx); + result = (rx_buf[0] << 8) | rx_buf[1]; DBG("%s,SEL_UART reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff); break; #endif @@ -80,6 +82,7 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type) case SEL_GPIO: reg = (((reg) | ICE_SEL_GPIO) | ICE_SEL_READ ); tx_buf[0] = reg & 0xff; + tx_buf[1] = 0;//give fpga 8 clks for reading data rx_buf[0] = 0; rx_buf[1] = 0; stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx); @@ -90,13 +93,14 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type) #if defined(CONFIG_SPI_I2C) case SEL_I2C: - reg = (((reg) | ICE_SEL_I2C) & ICE_SEL_READ ); + reg = (((reg) | ICE_SEL_I2C) | ICE_SEL_READ ); tx_buf[0] = reg & 0xff; + tx_buf[1] = 0; rx_buf[0] = 0; rx_buf[1] = 0; - stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx); - result = (rx_buf[0] << 8) | rx_buf[1]; - DBG("%s,SEL_I2C reg=0x%x,result=0x%x [0x%x] [0x%x]\n",__FUNCTION__,reg&0xff,result&0xffff,rx_buf[0],rx_buf[1]); + stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx); + result = rx_buf[1]; + DBG("%s,SEL_I2C reg=0x%x,result=0x%x \n",__FUNCTION__,reg&0xff,result&0xffff); break; #endif @@ -104,6 +108,7 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type) case SEL_DPRAM: reg = (((reg) | ICE_SEL_DPRAM) & ICE_SEL_DPRAM_READ ); tx_buf[0] = reg & 0xff; + tx_buf[1] = 0;//give fpga 8 clks for reading data rx_buf[0] = 0; rx_buf[1] = 0; stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx); @@ -111,8 +116,18 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type) DBG("%s,SEL_GPIO reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xffff); break; #endif + case READ_TOP_INT: + reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ); + tx_buf[0] = reg & 0xff; + tx_buf[1] = 0; + rx_buf[0] = 0; + rx_buf[1] = 0; + stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx); + result = rx_buf[1]; + DBG("%s,SEL_INT reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff); + break; default: - printk("Can not support this type!\n"); + printk("%s err: Can not support this type!\n",__FUNCTION__); break; } @@ -150,7 +165,6 @@ void spi_out(struct spi_fpga_port *port, int reg, int value, int type) #endif #if defined(CONFIG_SPI_I2C) - case SEL_I2C: reg = (((reg) | ICE_SEL_I2C) & ICE_SEL_WRITE); tx_buf[0] = reg & 0xff; @@ -173,61 +187,87 @@ void spi_out(struct spi_fpga_port *port, int reg, int value, int type) #endif default: - printk("Can not support this type!\n"); + printk("%s err: Can not support this type!\n",__FUNCTION__); break; } } +#if SPI_FPGA_TEST_DEBUG +int spi_test_wrong_handle(void) +{ + gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,0); + udelay(2); + gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,1); + printk("%s:give one trailing edge!\n",__FUNCTION__); + return 0; +} + +static int spi_test_request_gpio(int set) +{ + int ret; + rk2818_mux_api_set(GPIOE0_VIPDATA0_SEL_NAME,0); + ret = gpio_request(SPI_FPGA_TEST_DEBUG_PIN, NULL); + if (ret) { + printk("%s:failed to request SPI_FPGA_TEST_DEBUG_PIN pin\n",__FUNCTION__); + return ret; + } + gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,set); + + return 0; +} + +#endif static void spi_fpga_irq_work_handler(struct work_struct *work) { struct spi_fpga_port *port = container_of(work, struct spi_fpga_port, fpga_irq_work); struct spi_device *spi = port->spi; - int ret,uart_ch,gpio_ch; + int ret,uart_ch=0; DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__); - ret = spi_in(port, ICE_SEL_READ_INT_TYPE, SEL_UART); + ret = spi_in(port, ICE_SEL_READ_INT_TYPE, READ_TOP_INT); if((ret | ICE_INT_TYPE_UART0) == ICE_INT_TYPE_UART0) { #if defined(CONFIG_SPI_UART) - uart_ch = 0; - printk("Enter::%s,LINE=%d,uart_ch=%d,uart.index=%d\n",__FUNCTION__,__LINE__,uart_ch,port->uart.index); + DBG("%s:ICE_INT_TYPE_UART0 ret=0x%x\n",__FUNCTION__,ret); port->uart.index = uart_ch; spi_uart_handle_irq(spi); #endif } else if((ret | ICE_INT_TYPE_GPIO) == ICE_INT_TYPE_GPIO) { - gpio_ch = 0; - printk("Enter::%s,LINE=%d,gpio_ch=%d\n",__FUNCTION__,__LINE__,gpio_ch); #if defined(CONFIG_SPI_GPIO) + printk("%s:ICE_INT_TYPE_GPIO ret=0x%x\n",__FUNCTION__,ret); spi_gpio_handle_irq(spi); #endif } else if((ret | ICE_INT_TYPE_I2C2) == ICE_INT_TYPE_I2C2) { #if defined(CONFIG_SPI_I2C) - spi_i2c_handle_irq(port,0); + DBG("%s:ICE_INT_TYPE_I2C2 ret=0x%x\n",__FUNCTION__,ret); + spi_i2c_handle_irq(port,I2C_CH2); #endif } else if((ret | ICE_INT_TYPE_I2C3) == ICE_INT_TYPE_I2C3) { #if defined(CONFIG_SPI_I2C) - spi_i2c_handle_irq(port,1); + DBG("%s:ICE_INT_TYPE_I2C3 ret=0x%x\n",__FUNCTION__,ret); + spi_i2c_handle_irq(port,I2C_CH3); #endif } else if((ret | ICE_INT_TYPE_DPRAM) == ICE_INT_TYPE_DPRAM) { #if defined(CONFIG_SPI_DPRAM) + DBG("%s:ICE_INT_TYPE_DPRAM ret=0x%x\n",__FUNCTION__,ret); spi_dpram_handle_irq(spi); #endif } else { - printk("%s:NO such INT TYPE\n",__FUNCTION__); + printk("%s:NO such INT TYPE,ret=0x%x\n",__FUNCTION__,ret); } DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__); @@ -267,12 +307,13 @@ static int spi_open_sysclk(int set) return 0; } - +extern int spi_i2c_set_bt_power(void); static int __devinit spi_fpga_probe(struct spi_device * spi) { struct spi_fpga_port *port; int ret; char b[12]; + int num; DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__); /* * bits_per_word cannot be configured in platform data @@ -318,18 +359,23 @@ static int __devinit spi_fpga_probe(struct spi_device * spi) return ret; } #endif -#if 0 //defined(CONFIG_SPI_I2C) +#if defined(CONFIG_SPI_I2C) printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); - ret = spi_i2c_register(port); - printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); - if(ret) + spin_lock_init(&port->i2c.i2c_lock); + for (num= 2;num<4;num++) { - spi_i2c_unregister(port); - printk("%s:ret=%d,fail to spi_i2c_register\n",__FUNCTION__,ret); - return ret; + ret = spi_i2c_register(port,num); + printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); + if(ret) + { + spi_i2c_unregister(port); + printk("%s:ret=%d,fail to spi_i2c_register\n",__FUNCTION__,ret); + return ret; + } } #endif + #if defined(CONFIG_SPI_DPRAM) ret = spi_dpram_register(port); if(ret) @@ -362,6 +408,10 @@ static int __devinit spi_fpga_probe(struct spi_device * spi) spi_gpio_init(); #endif +#if SPI_FPGA_TEST_DEBUG + spi_test_request_gpio(GPIO_HIGH); +#endif + return 0; err2: diff --git a/drivers/fpga/spi_gpio.c b/drivers/fpga/spi_gpio.c index 5dc3dca5f376..2c0821f7bb26 100644 --- a/drivers/fpga/spi_gpio.c +++ b/drivers/fpga/spi_gpio.c @@ -27,7 +27,7 @@ #include #include -#include "spi_fpga.h" +#include #if defined(CONFIG_SPI_GPIO_DEBUG) #define DBG(x...) printk(x) @@ -52,15 +52,14 @@ static void spi_gpio_write_reg(int reg, int PinNum, int set) unsigned int new_set; struct spi_fpga_port *port = pFpgaPort; PinNum = PinNum % 16; - //mutex_lock(&port->spi_lock); + old_set= spi_in(port, reg, SEL_GPIO); + if(1 == set) new_set = old_set | (1 << PinNum ); else new_set = old_set & (~(1 << PinNum )); - spi_out(port, reg, new_set, SEL_GPIO); - //mutex_unlock(&port->spi_lock); - + spi_out(port, reg, new_set, SEL_GPIO); } static int spi_gpio_read_reg(int reg) @@ -68,9 +67,7 @@ static int spi_gpio_read_reg(int reg) int ret = 0; struct spi_fpga_port *port = pFpgaPort; - //mutex_lock(&port->spi_lock); ret = spi_in(port, reg, SEL_GPIO); - //mutex_unlock(&port->spi_lock); return ret; } @@ -125,10 +122,8 @@ int spi_gpio_int_sel(eSpiGpioPinNum_t PinNum,eSpiGpioTypeSel_t type) gGpio0State &= (~(1 << PinNum )); spin_unlock(&gpio_state_lock); DBG("%s,PinNum=%d,GPIO[%d]:type=%d\n",__FUNCTION__,PinNum,PinNum/16,type); - //mutex_lock(&port->spi_lock); - spi_gpio_write_reg(reg, PinNum, type); - //mutex_unlock(&port->spi_lock); + spi_gpio_write_reg(reg, PinNum, type); return 0; } else @@ -144,6 +139,10 @@ int spi_gpio_set_pindirection(eSpiGpioPinNum_t PinNum,eSpiGpioPinDirection_t dir { int reg = get_gpio_addr(PinNum); //struct spi_fpga_port *port = pFpgaPort; + int state; + spin_lock(&gpio_state_lock); + state = gGpio0State; + spin_unlock(&gpio_state_lock); if(reg == -1) { @@ -154,34 +153,76 @@ int spi_gpio_set_pindirection(eSpiGpioPinNum_t PinNum,eSpiGpioPinDirection_t dir if(ICE_SEL_GPIO0 == reg) { reg |= ICE_SEL_GPIO0_DIR; - spin_lock(&gpio_state_lock); - if((gGpio0State & (1 << PinNum )) != 0) + if((state & (1 << PinNum )) != 0) { printk("Fail to set direction because it is int pin!\n"); return -1; } - spin_unlock(&gpio_state_lock); - DBG("%s,PinNum=%d,direction=%d,GPIO[%d]:PinNum/16=%d\n",__FUNCTION__,PinNum,direction,PinNum/16,PinNum%16); - //mutex_lock(&port->spi_lock); - spi_gpio_write_reg(reg, PinNum, direction); - //mutex_unlock(&port->spi_lock); + DBG("%s,PinNum=%d,direction=%d,GPIO[%d]:PinNum/16=%d\n",__FUNCTION__,PinNum,direction,PinNum/16,PinNum%16); + spi_gpio_write_reg(reg, PinNum, direction); } else { reg |= ICE_SEL_GPIO_DIR; - DBG("%s,PinNum=%d,direction=%d,GPIO[%d]:PinNum/16=%d\n",__FUNCTION__,PinNum,direction,PinNum/16,PinNum%16); - //mutex_lock(&port->spi_lock); - spi_gpio_write_reg(reg, PinNum, direction); - //mutex_unlock(&port->spi_lock); + DBG("%s,PinNum=%d,direction=%d,GPIO[%d]:PinNum/16=%d\n",__FUNCTION__,PinNum,direction,PinNum/16,PinNum%16); + spi_gpio_write_reg(reg, PinNum, direction); } return 0; } +eSpiGpioPinDirection_t spi_gpio_get_pindirection(eSpiGpioPinNum_t PinNum) +{ + int ret = 0; + int reg = get_gpio_addr(PinNum); + int dir = 0; + //struct spi_fpga_port *port = pFpgaPort; + int state; + spin_lock(&gpio_state_lock); + state = gGpio0State; + spin_unlock(&gpio_state_lock); + + if(reg == -1) + { + printk("%s:error\n",__FUNCTION__); + return SPI_GPIO_DIR_ERR; + } + + if(ICE_SEL_GPIO0 == reg) + { + reg |= ICE_SEL_GPIO0_DIR; + if((state & (1 << PinNum )) != 0) + { + printk("Fail to get pindirection because it is int pin!\n"); + return SPI_GPIO_DIR_ERR; + } + ret = spi_gpio_read_reg(reg); + } + else + { + reg |= ICE_SEL_GPIO_DIR; + ret = spi_gpio_read_reg(reg); + } + + if((ret & (1 << (PinNum%16) )) == 0) + dir = SPI_GPIO_IN; + else + dir = SPI_GPIO_OUT; + + DBG("%s,PinNum=%d,ret=0x%x,GPIO[%d]:PinNum/16=%d,pindirection=%d\n\n",__FUNCTION__,PinNum,ret,PinNum/16,PinNum%16,dir); + + return dir; + +} + int spi_gpio_set_pinlevel(eSpiGpioPinNum_t PinNum, eSpiGpioPinLevel_t PinLevel) { int reg = get_gpio_addr(PinNum); //struct spi_fpga_port *port = pFpgaPort; + int state; + spin_lock(&gpio_state_lock); + state = gGpio0State; + spin_unlock(&gpio_state_lock); if(reg == -1) { @@ -192,26 +233,20 @@ int spi_gpio_set_pinlevel(eSpiGpioPinNum_t PinNum, eSpiGpioPinLevel_t PinLevel) if(ICE_SEL_GPIO0 == reg) { reg |= ICE_SEL_GPIO0_DATA; - spin_lock(&gpio_state_lock); - if((gGpio0State & (1 << PinNum )) != 0) + if((state & (1 << PinNum )) != 0) { printk("Fail to set PinLevel because PinNum=%d is int pin!\n",PinNum); return -1; } - spin_unlock(&gpio_state_lock); - DBG("%s,PinNum=%d,GPIO[%d]:PinNum/16=%d,PinLevel=%d\n",__FUNCTION__,PinNum,PinNum/16,PinNum%16,PinLevel); - //mutex_lock(&port->spi_lock); - spi_gpio_write_reg(reg, PinNum, PinLevel); - //mutex_unlock(&port->spi_lock); + DBG("%s,PinNum=%d,GPIO[%d]:PinNum/16=%d,PinLevel=%d\n",__FUNCTION__,PinNum,PinNum/16,PinNum%16,PinLevel); + spi_gpio_write_reg(reg, PinNum, PinLevel); } else { reg |= ICE_SEL_GPIO_DATA; - DBG("%s,PinNum=%d,GPIO[%d]:PinNum/16=%d,PinLevel=%d\n",__FUNCTION__,PinNum,PinNum/16,PinNum%16,PinLevel); - //mutex_lock(&port->spi_lock); - spi_gpio_write_reg(reg, PinNum, PinLevel); - //mutex_unlock(&port->spi_lock); + DBG("%s,PinNum=%d,GPIO[%d]:PinNum/16=%d,PinLevel=%d\n",__FUNCTION__,PinNum,PinNum/16,PinNum%16,PinLevel); + spi_gpio_write_reg(reg, PinNum, PinLevel); } return 0; @@ -225,6 +260,10 @@ eSpiGpioPinLevel_t spi_gpio_get_pinlevel(eSpiGpioPinNum_t PinNum) int reg = get_gpio_addr(PinNum); int level = 0; //struct spi_fpga_port *port = pFpgaPort; + int state; + spin_lock(&gpio_state_lock); + state = gGpio0State; + spin_unlock(&gpio_state_lock); if(reg == -1) { @@ -235,25 +274,19 @@ eSpiGpioPinLevel_t spi_gpio_get_pinlevel(eSpiGpioPinNum_t PinNum) if(ICE_SEL_GPIO0 == reg) { reg |= ICE_SEL_GPIO0_DATA; - spin_lock(&gpio_state_lock); - if((gGpio0State & (1 << PinNum )) != 0) + if((state & (1 << PinNum )) != 0) { printk("Fail to get PinLevel because it is int pin!\n"); return SPI_GPIO_LEVEL_ERR; - } - spin_unlock(&gpio_state_lock); - //mutex_lock(&port->spi_lock); - ret = spi_gpio_read_reg(reg); - //mutex_unlock(&port->spi_lock); + } + ret = spi_gpio_read_reg(reg); } else { - reg |= ICE_SEL_GPIO_DATA; - //mutex_lock(&port->spi_lock); - ret = spi_gpio_read_reg(reg); - //mutex_unlock(&port->spi_lock); + reg |= ICE_SEL_GPIO_DATA; + ret = spi_gpio_read_reg(reg); } - + if((ret & (1 << (PinNum%16) )) == 0) level = SPI_GPIO_LOW; else @@ -270,21 +303,21 @@ int spi_gpio_enable_int(eSpiGpioPinNum_t PinNum) { int reg = get_gpio_addr(PinNum); //struct spi_fpga_port *port = pFpgaPort; + int state; + spin_lock(&gpio_state_lock); + state = gGpio0State; + spin_unlock(&gpio_state_lock); if(ICE_SEL_GPIO0 == reg) { reg |= ICE_SEL_GPIO0_INT_EN; - spin_lock(&gpio_state_lock); - if((gGpio0State & (1 << PinNum )) == 0) + if((state & (1 << PinNum )) == 0) { printk("Fail to enable int because it is gpio pin!\n"); return -1; } - spin_unlock(&gpio_state_lock); - DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_ENABLE); - //mutex_lock(&port->spi_lock); - spi_gpio_write_reg(reg, PinNum, SPI_GPIO_INT_ENABLE); - //mutex_unlock(&port->spi_lock); + DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_ENABLE); + spi_gpio_write_reg(reg, PinNum, SPI_GPIO_INT_ENABLE); } else { @@ -300,21 +333,23 @@ int spi_gpio_disable_int(eSpiGpioPinNum_t PinNum) { int reg = get_gpio_addr(PinNum); //struct spi_fpga_port *port = pFpgaPort; + int state; + spin_lock(&gpio_state_lock); + state = gGpio0State; + spin_unlock(&gpio_state_lock); if(ICE_SEL_GPIO0 == reg) { reg |= ICE_SEL_GPIO0_INT_EN; - spin_lock(&gpio_state_lock); - if((gGpio0State & (1 << PinNum )) == 0) + + if((state & (1 << PinNum )) == 0) { printk("Fail to enable int because it is gpio pin!\n"); return -1; } - spin_unlock(&gpio_state_lock); - DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_DISABLE); - //mutex_lock(&port->spi_lock); - spi_gpio_write_reg(reg, PinNum, SPI_GPIO_INT_DISABLE); - //mutex_unlock(&port->spi_lock); + + DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_DISABLE); + spi_gpio_write_reg(reg, PinNum, SPI_GPIO_INT_DISABLE); } else { @@ -330,21 +365,25 @@ int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntType_t IntType) { int reg = get_gpio_addr(PinNum); //struct spi_fpga_port *port = pFpgaPort; + int state; + spin_lock(&gpio_state_lock); + state = gGpio0State; + spin_unlock(&gpio_state_lock); if(ICE_SEL_GPIO0 == reg) { reg |= ICE_SEL_GPIO0_INT_TRI; - spin_lock(&gpio_state_lock); - if((gGpio0State & (1 << PinNum )) == 0) + + if((state & (1 << PinNum )) == 0) { printk("Fail to enable int because it is gpio pin!\n"); return -1; } - spin_unlock(&gpio_state_lock); + DBG("%s,PinNum=%d,IntType=%d\n",__FUNCTION__,PinNum,IntType); - //mutex_lock(&port->spi_lock); + spi_gpio_write_reg(reg, PinNum, IntType); - //mutex_unlock(&port->spi_lock); + } else { @@ -372,17 +411,30 @@ int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiGpioIntT return -1; DBG("Enter::%s,LINE=%d,PinNum=%d\n",__FUNCTION__,__LINE__,PinNum); if(spi_gpio_int_sel(PinNum,SPI_GPIO0_IS_INT)) + { + printk("%s err:fail to enable select intterupt when PinNum=%d\n",__FUNCTION__,PinNum); return -1; + } if(spi_gpio_set_int_trigger(PinNum,IntType)) + { + printk("%s err:fail to enable set intterrupt trigger when PinNum=%d\n",__FUNCTION__,PinNum); return -1; - spin_lock(&gpio_irq_lock); + } + if(g_spiGpioVectorTable[PinNum].gpio_vector) - return -1; + { + printk("%s err:fail to enable g_spiGpioVectorTable[%d] have been used\n",__FUNCTION__,PinNum); + return -1; + } + spin_lock(&gpio_irq_lock); g_spiGpioVectorTable[PinNum].gpio_vector = (pSpiFuncIntr)Routine; g_spiGpioVectorTable[PinNum].gpio_devid= dev_id; spin_unlock(&gpio_irq_lock); if(spi_gpio_enable_int(PinNum)) + { + printk("%s err:fail to enable gpio intterupt when PinNum=%d\n",__FUNCTION__,PinNum); return -1; + } return 0; } @@ -402,31 +454,117 @@ int spi_free_gpio_irq(eSpiGpioPinNum_t PinNum) int spi_gpio_handle_irq(struct spi_device *spi) { int gpio_iir, i; + int state; + spin_lock(&gpio_state_lock); + state = gGpio0State; + spin_unlock(&gpio_state_lock); -#if 1 gpio_iir = spi_gpio_read_iir() & 0xffff; if(gpio_iir == 0xffff) return -1; - //spin_lock(&gpio_state_lock); + DBG("gpio_iir=0x%x\n",gpio_iir); for(i=0; igpio.gpio_timer.expires = jiffies + msecs_to_jiffies(2000); + add_timer(&port->gpio.gpio_timer); + //schedule_work(&port->gpio.spi_gpio_work); + queue_work(port->gpio.spi_gpio_workqueue, &port->gpio.spi_gpio_work); +} + +#endif + int spi_gpio_init(void) { int i,ret; @@ -443,6 +581,7 @@ int spi_gpio_init(void) } #endif + #if (FPGA_TYPE == ICE_CC72) for(i=0; i<16; i++) { @@ -471,34 +610,6 @@ int spi_gpio_init(void) #elif (FPGA_TYPE == ICE_CC196) -#if 0 - for(i=0;i<82;i++) - { - if(i<16) - spi_gpio_int_sel(i,SPI_GPIO0_IS_GPIO); - spi_gpio_set_pindirection(i, SPI_GPIO_OUT); - } - - while(1) - { - if(TestGpioPinLevel == 0) - TestGpioPinLevel = 1; - else - TestGpioPinLevel = 0; - for(i=0;i<82;i++) - { - spi_gpio_set_pinlevel(i, TestGpioPinLevel); - ret = spi_gpio_get_pinlevel(i); - if(ret != TestGpioPinLevel) - DBG("PinNum=%d,set_pinlevel=%d,get_pinlevel=%d\n\n",i,TestGpioPinLevel,ret); - } - mdelay(10); - - DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__); - } - -#endif - #if 0 DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__); spi_out(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO0_TYPE), 0x0000, SEL_GPIO); @@ -565,12 +676,11 @@ int spi_gpio_init(void) ret = spi_in(port, (ICE_SEL_GPIO5 | ICE_SEL_GPIO_DIR), SEL_GPIO) & 0xffff; if(ret != 0xffff) DBG("%s:Line=%d,set=0xffff,ret=0x%x\n",__FUNCTION__,__LINE__,ret); - - + #else - spi_gpio_set_pinlevel(SPI_GPIO_P1_00, SPI_GPIO_LOW); //LCD_ON output + spi_gpio_set_pinlevel(SPI_GPIO_P1_00, SPI_GPIO_HIGH); //LCD_ON output// spi_gpio_set_pindirection(SPI_GPIO_P1_00, SPI_GPIO_OUT); - spi_gpio_set_pinlevel(SPI_GPIO_P1_01, SPI_GPIO_LOW); //LCD_PWR_CTRL output + spi_gpio_set_pinlevel(SPI_GPIO_P1_01, SPI_GPIO_HIGH); //LCD_PWR_CTRL output spi_gpio_set_pindirection(SPI_GPIO_P1_01, SPI_GPIO_OUT); spi_gpio_set_pinlevel(SPI_GPIO_P1_02, SPI_GPIO_HIGH); //SD_POW_ON output spi_gpio_set_pindirection(SPI_GPIO_P1_02, SPI_GPIO_OUT); @@ -587,7 +697,7 @@ int spi_gpio_init(void) spi_gpio_set_pinlevel(SPI_GPIO_P1_08, SPI_GPIO_LOW); //BT_WAKE_B output spi_gpio_set_pindirection(SPI_GPIO_P1_08, SPI_GPIO_OUT); - spi_gpio_set_pinlevel(SPI_GPIO_P1_09, SPI_GPIO_HIGH); //LCD_DISP_ON output + spi_gpio_set_pinlevel(SPI_GPIO_P1_09, SPI_GPIO_LOW); //LCD_DISP_ON output spi_gpio_set_pindirection(SPI_GPIO_P1_09, SPI_GPIO_OUT); spi_gpio_set_pinlevel(SPI_GPIO_P1_10, SPI_GPIO_LOW); //WM_PWR_EN output spi_gpio_set_pindirection(SPI_GPIO_P1_10, SPI_GPIO_OUT); @@ -623,87 +733,73 @@ int spi_gpio_init(void) spi_gpio_set_pindirection(SPI_GPIO_P2_10, SPI_GPIO_IN); //X-XL input spi_gpio_set_pindirection(SPI_GPIO_P2_11, SPI_GPIO_IN); //X+XR input - spi_gpio_set_pinlevel(SPI_GPIO_P2_12, SPI_GPIO_LOW); //LCD_RESET output + spi_gpio_set_pinlevel(SPI_GPIO_P2_12, SPI_GPIO_HIGH); //LCD_RESET output// spi_gpio_set_pindirection(SPI_GPIO_P2_12, SPI_GPIO_OUT); spi_gpio_set_pinlevel(SPI_GPIO_P2_13, SPI_GPIO_HIGH); //USB_PWR_EN output spi_gpio_set_pindirection(SPI_GPIO_P2_13, SPI_GPIO_OUT); spi_gpio_set_pinlevel(SPI_GPIO_P2_14, SPI_GPIO_LOW); //WL_HOST_WAKE_B output spi_gpio_set_pindirection(SPI_GPIO_P2_14, SPI_GPIO_OUT); - spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_LOW); //TOUCH_SCREEN_RST output + spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_HIGH); //TOUCH_SCREEN_RST output// spi_gpio_set_pindirection(SPI_GPIO_P2_15, SPI_GPIO_OUT); spi_gpio_set_pindirection(SPI_GPIO_P4_06, SPI_GPIO_IN); //CHARGER_INT_END input - spi_gpio_set_pinlevel(SPI_GPIO_P4_07, SPI_GPIO_LOW); //TOUCH_SCREEN_RST output + spi_gpio_set_pinlevel(SPI_GPIO_P4_07, SPI_GPIO_LOW); //CM3605_PWD output spi_gpio_set_pindirection(SPI_GPIO_P4_07, SPI_GPIO_OUT); spi_gpio_set_pinlevel(SPI_GPIO_P4_08, SPI_GPIO_LOW); //CM3605_PS_SHUTDOWN spi_gpio_set_pindirection(SPI_GPIO_P4_08, SPI_GPIO_OUT); #endif -#endif - return 0; - -} - - #if SPI_GPIO_TEST -volatile int TestGpioPinLevel = 0; -void spi_gpio_work_handler(struct work_struct *work) -{ - struct spi_fpga_port *port = - container_of(work, struct spi_fpga_port, gpio.spi_gpio_work); - int i,ret; - printk("*************test spi_gpio now***************\n"); - - if(TestGpioPinLevel == 0) - TestGpioPinLevel = 1; - else - TestGpioPinLevel = 0; - -#if (FPGA_TYPE == ICE_CC72) - for(i=0;i<32;i++) - { - spi_gpio_set_pinlevel(i, TestGpioPinLevel); - ret = spi_gpio_get_pinlevel(i); - if(ret != TestGpioPinLevel) - DBG("PinNum=%d,set_pinlevel=%d,get_pinlevel=%d\n",i,TestGpioPinLevel,ret); - //spi_gpio_set_pindirection(i, SPI_GPIO_OUT); - } -#elif (FPGA_TYPE == ICE_CC196) - for(i=0;i<16;i++) - { - if(i<16) - spi_gpio_int_sel(i,SPI_GPIO0_IS_GPIO); - spi_gpio_set_pindirection(i, SPI_GPIO_OUT); - } - for(i=0;i<81;i++) { - spi_gpio_set_pinlevel(i, TestGpioPinLevel); - ret = spi_gpio_get_pinlevel(i); - if(ret != TestGpioPinLevel) - printk("err:PinNum=%d,set_pinlevel=%d but get_pinlevel=%d\n\n",i,TestGpioPinLevel,ret); - } - - DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__); + if(i<4) + { + switch(i) + { + case 0: + spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_0, SPI_GPIO_EDGE_FALLING, port); + break; + case 1: + spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_1, SPI_GPIO_EDGE_FALLING, port); + break; + case 2: + spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_2, SPI_GPIO_EDGE_FALLING, port); + break; + case 3: + spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_3, SPI_GPIO_EDGE_FALLING, port); + break; + + default: + break; + } + + } + else + { + //if(i<16) + //spi_gpio_int_sel(i,SPI_GPIO0_IS_GPIO); + spi_gpio_set_pindirection(i, SPI_GPIO_OUT); + ret = spi_gpio_get_pindirection(i); + if(ret != SPI_GPIO_OUT) + { + #if SPI_FPGA_TEST_DEBUG + spi_test_wrong_handle(); + #endif + printk("err:PinNum=%d,set_pindirection=%d but get_pindirection=%d\n",i,SPI_GPIO_OUT,ret); + } + } + } #endif -} - -static void spi_testgpio_timer(unsigned long data) -{ - struct spi_fpga_port *port = (struct spi_fpga_port *)data; - port->gpio.gpio_timer.expires = jiffies + msecs_to_jiffies(1000); - add_timer(&port->gpio.gpio_timer); - //schedule_work(&port->gpio.spi_gpio_work); - queue_work(port->gpio.spi_gpio_workqueue, &port->gpio.spi_gpio_work); -} #endif + return 0; +} int spi_gpio_register(struct spi_fpga_port *port) { @@ -728,6 +824,7 @@ int spi_gpio_register(struct spi_fpga_port *port) DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); return 0; } + int spi_gpio_unregister(struct spi_fpga_port *port) { return 0; diff --git a/drivers/fpga/spi_i2c.c b/drivers/fpga/spi_i2c.c index 9500583582d1..687023aeaed4 100644 --- a/drivers/fpga/spi_i2c.c +++ b/drivers/fpga/spi_i2c.c @@ -27,7 +27,7 @@ #include #include -#include "spi_fpga.h" +#include #if defined(CONFIG_SPI_I2C_DEBUG) #define DBG(x...) printk(x) @@ -35,12 +35,9 @@ #define DBG(x...) #endif -#define SPI_I2C_TEST 0 - -#define MAXMSGLEN 16 +#define MAXMSGLEN 8 #define DRV_NAME "fpga_i2c" - - +#define SPI_I2C_TEST 0 struct spi_i2c_data { struct device *dev; struct i2c_adapter adapter; @@ -53,28 +50,29 @@ int spi_i2c_handle_irq(struct spi_fpga_port *port,unsigned char channel) { int reg; int ret; - - if(channel == 0) + + if(channel == I2C_CH2) reg = ICE_SEL_I2C_INT|ICE_SEL_I2C_CH2; else reg = ICE_SEL_I2C_INT|ICE_SEL_I2C_CH3; port->i2c.interrupt = 0; ret = spi_in(port,reg,SEL_I2C); - if(ret == INT_I2C_READ_ACK) + DBG("Enter::%s,LINE=%d ret = [%d]\n",__FUNCTION__,__LINE__,ret); + if(INT_I2C_READ_ACK == (ret & 0x07)) port->i2c.interrupt = INT_I2C_READ_ACK; - else if(ret == INT_I2C_READ_NACK) + else if(INT_I2C_READ_NACK ==(ret & 0x07)) { - printk("Error::read no ack!!check the I2C slave device \n"); + printk("Error::read no ack!!check the I2C slave device ret=%d \n",ret); } - else if(ret == INT_I2C_WRITE_ACK) + else if(INT_I2C_WRITE_ACK == (ret & 0x07)) port->i2c.interrupt = INT_I2C_WRITE_ACK; - else if(ret == INT_I2C_WRITE_NACK) + else if(INT_I2C_WRITE_NACK == (ret & 0x07)) { - printk("Error::write no ack!!check the I2C slave device \n"); + printk("Error::write no ack!!check the I2C slave device ret=%d \n",ret); } else - printk("Error:ack value error!!check the I2C slave device \n"); + printk("Error:ack value error!!check the I2C slave device ret=%d \n",ret); return port->i2c.interrupt; } @@ -104,7 +102,7 @@ int spi_i2c_select_speed(int speed) return result; } -int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg) +int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch) { unsigned int reg ; @@ -118,17 +116,19 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg) len = pmsg->len; speed = spi_i2c_select_speed(pmsg->scl_rate); - if(pmsg->channel == I2C_CH2) + if(ch == I2C_CH2) channel = ICE_SEL_I2C_CH2; - else if(pmsg->channel == I2C_CH3) + else if(ch == I2C_CH3) channel = ICE_SEL_I2C_CH3; else { printk("Error:try to read form error i2c channel\n"); return 0; } + + //printk("len = %d chan = %d read=%d,reg=%d\n",pmsg->len,ch,pmsg->read_type,pmsg->reg_type); - if(pmsg->read_type == 0) + if(pmsg->read_type == I2C_NORMAL) { //slaveaddr ; slaveaddr = slaveaddr<<1; @@ -137,19 +137,30 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg) //speed; reg = channel |ICE_SEL_I2C_SPEED|ICE_SEL_I2C_TRANS; spi_out(port,reg,speed,SEL_I2C); - //len; + //len;&&data reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_TRANS; - spi_out(port,reg,len,SEL_I2C); - reg = channel |ICE_SEL_I2C_TRANS; - //data; - for(i = 0 ;i < len;i++) + if(pmsg->reg_type == I2C_8_BIT) + { + spi_out(port,reg,1,SEL_I2C); + reg = channel |ICE_SEL_I2C_TRANS; + spi_out(port,reg,pmsg->buf[0],SEL_I2C); + } + else if(pmsg->reg_type == I2C_16_BIT) { - if(i == len-1) - reg = channel |ICE_SEL_I2C_STOP; - spi_out(port,reg,pmsg->buf[i],SEL_I2C); - } - + spi_out(port,reg,2,SEL_I2C); + reg = channel |ICE_SEL_I2C_TRANS; + spi_out(port,reg,pmsg->buf[0],SEL_I2C); + spi_out(port,reg,pmsg->buf[1],SEL_I2C); + } } + + //handle irq after send stop cmd + + + + + + //slaveaddr slaveaddr = slaveaddr|ICE_I2C_SLAVE_READ; if(pmsg->read_type == 0) @@ -161,30 +172,30 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg) reg = channel |ICE_SEL_I2C_SPEED|ICE_SEL_I2C_TRANS; spi_out(port,reg,speed,SEL_I2C); //len; - reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_TRANS; + reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_STOP; spi_out(port,reg,len,SEL_I2C); - i=50; - while(i--) - { - if(port->i2c.interrupt == INT_I2C_READ_ACK) + msleep(100); + if(port->i2c.interrupt == INT_I2C_READ_ACK) { + //printk("%s:line=%d\n",__FUNCTION__,__LINE__); for(i = 0;ibuf[i] = result & 0xFF; + result = spi_in(port,channel,SEL_I2C); + pmsg->buf[i] = 0; + pmsg->buf[i] = result & 0xff ; } spin_lock(&port->i2c.i2c_lock); port->i2c.interrupt &= INT_I2C_READ_MASK; spin_unlock(&port->i2c.i2c_lock); - break; - } - } - for(i = 0;ibuf[%d] = 0x%x \n",i,pmsg->buf[i]); + } + //for(i = 0;ibuf[%d] = 0x%x \n",i,pmsg->buf[i]); return pmsg->len; + } -int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg) + +int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch) { unsigned int reg ; @@ -197,16 +208,16 @@ int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg) len = pmsg->len; speed = spi_i2c_select_speed(pmsg->scl_rate); - if(pmsg->channel == I2C_CH2) + if(ch == I2C_CH2) channel = ICE_SEL_I2C_CH2; - else if(pmsg->channel == I2C_CH3) + else if(ch == I2C_CH3) channel = ICE_SEL_I2C_CH3; else { printk("Error: try to write the error i2c channel\n"); return 0; } - + DBG("len = %d ch = %d\n",pmsg->len,ch); //slaveaddr ; slaveaddr = slaveaddr<<1; reg = channel |ICE_SEL_I2C_START; @@ -225,24 +236,27 @@ int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg) reg = channel|ICE_SEL_I2C_STOP; spi_out(port,reg,pmsg->buf[i],SEL_I2C); } - + msleep(25); i = 50; while(i--) { if(port->i2c.interrupt == INT_I2C_WRITE_ACK) { + //printk("wait num= %d,port->i2c.interrupt = 0x%x\n",i,port->i2c.interrupt); spin_lock(&port->i2c.i2c_lock); port->i2c.interrupt &= INT_I2C_WRITE_MASK; spin_unlock(&port->i2c.i2c_lock); break; } } - DBG("wait num= %d,port->i2c.interrupt = 0x%x\n",i,port->i2c.interrupt); + return pmsg->len; } -#if defined(CONFIG_SPI_I2C_DEBUG) + + +#if SPI_I2C_TEST unsigned short rda5400[][2] = { {0x3f,0x0000},//page 0 @@ -288,18 +302,22 @@ int spi_i2c_16bit_test(struct spi_fpga_port *port) int i ; struct i2c_msg msg[1] = { - {0x16,0,len+2,i2c_buf,200,3,0} + {0x16,0,len+2,i2c_buf,200,0,0} }; for(i = 0;i < (sizeof(rda5400)/sizeof(rda5400[0]));i++) { i2c_buf[0] = 0x22; i2c_buf[1] = rda5400[i][0]; - i2c_buf[1] = rda5400[i][1]>>8; - i2c_buf[2] = rda5400[i][1]&0xFF; - spi_i2c_writebuf(port, msg); + i2c_buf[2] = rda5400[i][1]>>8; + i2c_buf[3] = rda5400[i][1]&0xFF; + printk("i = %d\n",i); + spi_i2c_writebuf(port, msg,3); msg[0].len = 2; - spi_i2c_readbuf(port, msg); + + spi_i2c_readbuf(port, msg,3); + if(msg->buf[0] != i2c_buf[2] ||msg->buf[1] != i2c_buf[3] ) + printk("i=%d,msg[0]=%d,msg[1]=%d\n",i,msg->buf[0],msg->buf[1]); } return 0; @@ -312,48 +330,110 @@ int spi_i2c_8bit_test(struct spi_fpga_port *port) int i ; struct i2c_msg msg[1] = { - {0x16,0,len+1,i2c_buf,200,2,0} + {0x16,0,len+1,i2c_buf,200,0,0} }; for(i = 0;i < (sizeof(rda5400)/sizeof(rda5400[0]));i++) { + printk("i=%d\n",i); + msg[0].len = 3; i2c_buf[0] = rda5400[i][0]; i2c_buf[1] = rda5400[i][1]>>8; i2c_buf[2] = rda5400[i][1]&0xFF; - spi_i2c_writebuf(port, msg); - msg[0].len = 1; - spi_i2c_readbuf(port, msg); + spi_i2c_writebuf(port, msg,3); + msg[0].len = 2; + i2c_buf[1] = 0; + i2c_buf[2] = 0; + spi_i2c_readbuf(port, msg,3); + if(msg->buf[0] != (rda5400[i][1]>>8) ||msg->buf[1] != (rda5400[i][1]&0xff) ) + printk("i=%d,msg[0]=0x%x,msg[1]=0x%x\n",i,msg->buf[0],msg->buf[1]); } return 0; } - int spi_i2c_test(void ) + +int spi_i2c_test(void) { struct spi_fpga_port *port = pFpgaPort; - printk("IN::************spi_i2c_test********\r\n"); spi_i2c_8bit_test(port); - spi_i2c_16bit_test(port); - - printk("OUT::************spi_i2c_test********\r\n"); return 0; +} + +//EXPORT_SYMBOL(spi_i2c_test); +void spi_i2c_work_handler(struct work_struct *work) +{ + struct spi_fpga_port *port = + container_of(work, struct spi_fpga_port, i2c.spi_i2c_work); + + printk("*************test spi_i2c now***************\n"); + spi_i2c_8bit_test(port); + +} + +static void spi_testi2c_timer(unsigned long data) +{ + struct spi_fpga_port *port = (struct spi_fpga_port *)data; + port->i2c.i2c_timer.expires = jiffies + msecs_to_jiffies(2000); + add_timer(&port->i2c.i2c_timer); + queue_work(port->i2c.spi_i2c_workqueue, &port->i2c.spi_i2c_work); +} +#define BT_RST_PIN SPI_GPIO_P1_07 +#define BT_PWR_PIN SPI_GPIO_P1_06 +int spi_i2c_set_bt_power(void) +{ +#if 1 + + spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_HIGH); + spi_gpio_set_pindirection(BT_RST_PIN, SPI_GPIO_OUT); + spi_gpio_set_pinlevel(BT_PWR_PIN, SPI_GPIO_HIGH); + spi_gpio_set_pindirection(BT_PWR_PIN, SPI_GPIO_OUT); + +#else + spi_gpio_set_pinlevel(BT_PWR_PIN, SPI_GPIO_LOW); + spi_gpio_set_pindirection(BT_PWR_PIN, SPI_GPIO_OUT); + mdelay(2); + spi_gpio_set_pinlevel(BT_PWR_PIN, SPI_GPIO_HIGH); + spi_gpio_set_pindirection(BT_PWR_PIN, SPI_GPIO_OUT); + mdelay(2); + spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_LOW); + spi_gpio_set_pindirection(BT_RST_PIN, SPI_GPIO_OUT); + mdelay(20); + /*µÈ´ý10msÒÔÉÏ£¬µÈ´ý26M XTALÎȶ¨£¬È»ºóÀ­¸ßRESETN*/ + spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_HIGH); +#endif + return 0; } +#endif +#if 0 +int spi_i2c_register(struct spi_fpga_port *port,int num) +{ + spin_lock_init(&port->i2c.i2c_lock); + return 0; +} #endif +int spi_i2c_unregister(struct spi_fpga_port *port) +{ + return 0; +} - int spi_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *pmsg, int num) +int spi_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *pmsg, int num) { + //struct spi_fpga_port *port1 = pFpgaPort; + struct spi_fpga_port *port = adapter->algo_data; - struct spi_fpga_port *port = pFpgaPort; - - printk("%s:line=%d,channel = %d\n",__FUNCTION__,__LINE__,adapter->nr); + DBG("%s:line=%d,channel = %d\n",__FUNCTION__,__LINE__,adapter->nr); if(pmsg->len > MAXMSGLEN) return 0; + if(adapter->nr != I2C_CH2 && adapter->nr != I2C_CH3) + return 0; if(pmsg->flags) - spi_i2c_readbuf(port,pmsg); + spi_i2c_readbuf(port,pmsg,adapter->nr); + //spi_i2c_readbuf(port,pmsg,adapter->nr,num); else - spi_i2c_writebuf(port,pmsg); + spi_i2c_writebuf(port,pmsg,adapter->nr); return pmsg->len; @@ -369,74 +449,59 @@ static const struct i2c_algorithm spi_i2c_algorithm = { .master_xfer = spi_i2c_xfer, .functionality = spi_i2c_func, }; - -static int spi_i2c_probe(struct platform_device *pdev) +#if 1 +int spi_i2c_register(struct spi_fpga_port *port,int num) { int ret; - struct spi_i2c_data *i2c; - struct rk2818_i2c_platform_data *pdata; - DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__); - pdata = pdev->dev.platform_data; - if(!pdata) - { - dev_err(&pdev->dev,"no platform data\n"); - return -EINVAL; - } - i2c = kzalloc(sizeof(struct spi_i2c_data),GFP_KERNEL); - if(!i2c) + struct i2c_adapter *adapter; + DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); + //spi_i2c_add_bus(port); + adapter = kzalloc(sizeof(struct i2c_adapter),GFP_KERNEL); + if(adapter == NULL) + return -ENOMEM; + sprintf(adapter->name,"spi_i2c"); + adapter->algo = &spi_i2c_algorithm; + adapter->class = I2C_CLASS_HWMON; + adapter->nr = num; + adapter->algo_data = port; + ret = i2c_add_numbered_adapter(adapter); + if(ret) { - dev_err(&pdev->dev,"no memory for state\n"); - return -ENOMEM; - } - strlcpy(i2c->adapter.name,DRV_NAME,sizeof(i2c->adapter.name)); - i2c->adapter.owner = THIS_MODULE; - i2c->adapter.algo = &spi_i2c_algorithm; - i2c->adapter.class = I2C_CLASS_HWMON; - - i2c->dev = &pdev->dev; - i2c->adapter.algo_data = i2c; - i2c->adapter.dev.parent = &pdev->dev; - i2c->adapter.nr = pdata->bus_num; - ret = i2c_add_numbered_adapter(&i2c->adapter); - if(ret < 0){ - dev_err(&pdev->dev,"fail to add bus to i2c core fpga\n"); - kfree(i2c); + printk(KERN_INFO "SPI2I2C: Failed to add bus\n"); + kfree(adapter); + return ret; } - platform_set_drvdata(pdev,i2c); - printk("Enter::%s,LINE=%d i2c->adap.nr = %d ************************\n",__FUNCTION__,__LINE__,i2c->adapter.nr); - #if defined(CONFIG_SPI_I2C_DEBUG) + +#if SPI_I2C_TEST + char b[20]; + if(num != 3) + return 0; + sprintf(b, "spi_i2c_workqueue"); + DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); + port->i2c.spi_i2c_workqueue = create_freezeable_workqueue(b); + if (!port->i2c.spi_i2c_workqueue) { + printk("cannot create workqueue\n"); + return -EBUSY; + } + + INIT_WORK(&port->i2c.spi_i2c_work, spi_i2c_work_handler); + + setup_timer(&port->i2c.i2c_timer, spi_testi2c_timer, (unsigned long)port); + port->i2c.i2c_timer.expires = jiffies+2000;//>1000ms + add_timer(&port->i2c.i2c_timer); + printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port); - #endif - return 0; -} +#endif -static int spi_i2c_remove(struct platform_device *pdev) -{ - return 0; + return 0; } -static struct platform_driver spi_i2c_driver = { - .probe = spi_i2c_probe, - .remove = spi_i2c_remove, - .driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - }, -}; +#endif + + -static int __init spi_i2c_adap_init(void) -{ - printk(" *************Enter::%s,LINE=%d ************\n",__FUNCTION__,__LINE__); - return platform_driver_register(&spi_i2c_driver); -} -static void __exit spi_i2c_adap_exit(void) -{ - platform_driver_unregister(&spi_i2c_driver); -} -subsys_initcall(spi_i2c_adap_init); -module_exit(spi_i2c_adap_exit); MODULE_DESCRIPTION("Driver for spi2i2c."); MODULE_AUTHOR("swj "); diff --git a/drivers/fpga/spi_uart.c b/drivers/fpga/spi_uart.c index b6b6072a0517..f13ea0041241 100644 --- a/drivers/fpga/spi_uart.c +++ b/drivers/fpga/spi_uart.c @@ -27,7 +27,7 @@ #include #include -#include "spi_fpga.h" +#include #if defined(CONFIG_SPI_UART_DEBUG) #define DBG(x...) printk(x) @@ -37,6 +37,9 @@ #define SPI_UART_TEST 0 +#define SPI_UART_FIFO_LEN 32 +#define SPI_UART_TXRX_BUF 0 //send or recieve several bytes one time + static struct tty_driver *spi_uart_tty_driver; /*------------------------ÒÔÏÂÊÇspi2uart±äÁ¿-----------------------*/ @@ -60,6 +63,41 @@ static struct tty_driver *spi_uart_tty_driver; static struct spi_uart *spi_uart_table[UART_NR]; static DEFINE_SPINLOCK(spi_uart_table_lock); +#if SPI_UART_TXRX_BUF +static int spi_uart_write_buf(struct spi_uart *uart, unsigned char *buf, int len) +{ + struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart); + int index = port->uart.index; + int reg = 0; + unsigned char tx_buf[SPI_UART_TXRX_BUF+2];//uart's tx fifo max lenth + 1 + + reg = ((((reg) | ICE_SEL_UART) & ICE_SEL_WRITE) | ICE_SEL_UART_CH(index)); + tx_buf[0] = reg & 0xff; + tx_buf[1] = 0; + memcpy(tx_buf+2, buf, len); + spi_write(port->spi, (const u8 *)&tx_buf, len+2); + DBG("%s,buf=0x%x,len=0x%x\n",__FUNCTION__,reg&0xff,(int)tx_buf,len); + return 0; +} + + +static int spi_uart_read_buf(struct spi_uart *uart, unsigned char *buf, int len) +{ + struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart); + int index = port->uart.index; + int reg = 0,stat = 0; + unsigned char tx_buf[1],rx_buf[SPI_UART_FIFO_LEN+1]; + + reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ | ICE_SEL_UART_CH(index)); + tx_buf[0] = reg & 0xff; + //give fpga 8 clks for reading data + stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, 1, rx_buf, len+1); + memcpy(buf, rx_buf+1, len); + DBG("%s,buf=0x%x,len=0x%x\n",__FUNCTION__,reg&0xff,(int)buf,len); + return stat; +} + +#endif static int spi_uart_add_port(struct spi_uart *uart) { @@ -359,9 +397,38 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status) { struct tty_struct *tty = uart->tty; struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart); - unsigned int ch, flag; - int max_count = 1024; + int max_count = 1024; + +#if SPI_UART_TXRX_BUF + int ret,count,stat = 0,num = 0; + unsigned char buf[SPI_UART_FIFO_LEN]; + max_count = 512; + while (max_count >0 ) + { + ret = spi_in(port, UART_RX, SEL_UART); + count = (ret >> 8) & 0xff; + if(count == 0) + break; + buf[0] = ret & 0xff; + if(count > 1) + { + stat = spi_uart_read_buf(uart,buf+1,count-1); + if(stat) + printk("err:%s:stat=%d,fail to read uart data because of spi bus error!\n",__FUNCTION__,stat); + } + max_count -= count; + while (count-- >0 ) + { + flag = TTY_NORMAL; + ch = buf[num++]; + tty_insert_flip_char(tty, ch, flag); + } + + tty_flip_buffer_push(tty); + } + printk("r%d\n",1024-max_count); +#else //printk("rx:"); while (--max_count >0 ) { @@ -370,7 +437,6 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status) flag = TTY_NORMAL; uart->icount.rx++; //--max_count; -#if 1 if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | UART_LSR_FE | UART_LSR_OE))) { /* @@ -397,7 +463,7 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status) else if (*status & UART_LSR_FE) flag = TTY_FRAME; } -#endif + if ((*status & uart->ignore_status_mask & ~UART_LSR_OE) == 0) tty_insert_flip_char(tty, ch, flag); @@ -415,6 +481,8 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status) DBG("Enter::%s,LINE=%d,rx_count=%d********\n",__FUNCTION__,__LINE__,(1024-max_count)); printk("r%d\n",1024-max_count); tty_flip_buffer_push(tty); + +#endif } @@ -422,6 +490,9 @@ static void spi_uart_transmit_chars(struct spi_uart *uart) { struct circ_buf *xmit = &uart->xmit; int count; +#if SPI_UART_TXRX_BUF + unsigned char buf[SPI_UART_FIFO_LEN]; +#endif struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart); if (uart->x_char) { @@ -438,7 +509,23 @@ static void spi_uart_transmit_chars(struct spi_uart *uart) return; } //printk("tx:"); - count = 32;// + +#if SPI_UART_TXRX_BUF + //send several bytes one time + count = 0; + while(count < SPI_UART_FIFO_LEN) + { + buf[count] = xmit->buf[xmit->tail]; + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + uart->icount.tx++; + count++; + if (circ_empty(xmit)) + break; + } + spi_uart_write_buf(uart,buf,count); +#else + //send one byte one time + count = SPI_UART_FIFO_LEN;// while(count > 0) { spi_out(port, UART_TX, xmit->buf[xmit->tail], SEL_UART); @@ -449,7 +536,7 @@ static void spi_uart_transmit_chars(struct spi_uart *uart) if (circ_empty(xmit)) break; } - +#endif //printk("\n"); DBG("Enter::%s,LINE=%d,tx_count=%d\n",__FUNCTION__,__LINE__,(32-count)); if (circ_chars_pending(xmit) < WAKEUP_CHARS) @@ -515,41 +602,61 @@ static void spi_uart_check_modem_status(struct spi_uart *uart) #if SPI_UART_TEST #define UART_TEST_LEN 16 //8bit unsigned char buf_test_uart[UART_TEST_LEN]; -unsigned int ice65l08_init_para[]= + +void spi_uart_test_init(struct spi_fpga_port *port) { - 0x030083, - 0x010000, - 0x000034, // (0100XYH) ÉèÖ÷ÖƵϵÊý£ºXY = MCLK / (4*²¨ÌØÂÊ)£» - 0x030003, // ÉèÖÃ×Ö½ÚÓÐЧ³¤¶È£º 8 bits£» - 0x01000f, // TX RX ÖÐ¶Ï - 0x020080, // ÉèÖô¥·¢µÈ¼¶ ½ÓÊÜFIFOΪ 16bytes ²úÉúÖжϣ» -}; + unsigned char cval, fcr = 0; + unsigned int baud, quot; + unsigned char mcr = 0; + int ret; + + DBG("Enter::%s,LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr); + spi_out(port, UART_MCR, mcr, SEL_UART); + baud = 1500000; + cval = UART_LCR_WLEN8; + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10; + quot = 6000000 / baud; + mcr |= UART_MCR_RTS; + mcr |= UART_MCR_AFE; + + spi_out(port, UART_FCR, UART_FCR_ENABLE_FIFO, SEL_UART); + spi_out(port, UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, SEL_UART); + spi_out(port, UART_FCR, 0, SEL_UART); + spi_out(port, UART_LCR, UART_LCR_WLEN8, SEL_UART); + spi_out(port, UART_LCR, cval | UART_LCR_DLAB, SEL_UART); + spi_out(port, UART_DLL, quot & 0xff, SEL_UART); + ret = spi_in(port, UART_DLL, SEL_UART)&0xff; + printk("%s:quot=0x%x,UART_DLL=0x%x\n",__FUNCTION__,quot,ret); + spi_out(port, UART_DLM, quot >> 8, SEL_UART); + spi_out(port, UART_LCR, cval, SEL_UART); + spi_out(port, UART_FCR, fcr, SEL_UART); + spi_out(port, UART_MCR, mcr, SEL_UART); + + +} void spi_uart_work_handler(struct work_struct *work) { int i; - int ret,count; - int offset,value; + int count; struct spi_fpga_port *port = container_of(work, struct spi_fpga_port, uart.spi_uart_work); printk("*************test spi_uart now***************\n"); - + spi_uart_test_init(port); for(i=0;i> 16) & 0xff; - value = ice65l08_init_para[i] & 0xffff; - spi_out(port, offset, value, SEL_UART); - } - + buf_test_uart[i] = '0'+i; count = UART_TEST_LEN; +#if SPI_UART_TXRX_BUF + spi_uart_write_buf(&port->uart, buf_test_uart, count); +#else while(count > 0) { spi_out(port, UART_TX, buf_test_uart[UART_TEST_LEN-count], SEL_UART); --count; } +#endif + } static void spi_testuart_timer(unsigned long data) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a31b2ee47103..bf44183cbb60 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -514,6 +514,7 @@ struct i2c_msg { __u32 scl_rate; __u16 channel; __u16 read_type; + __u16 reg_type; }; /* To determine what functionality is present */