fpga driver update
authorroot <root@lw-desktop.(none)>
Mon, 26 Jul 2010 08:46:48 +0000 (16:46 +0800)
committerroot <root@lw-desktop.(none)>
Mon, 26 Jul 2010 08:49:45 +0000 (16:49 +0800)
12 files changed:
arch/arm/mach-rk2818/board-midsdk.c
arch/arm/mach-rk2818/board-phonesdk.c
arch/arm/mach-rk2818/board-raho.c
arch/arm/mach-rk2818/devices.h
arch/arm/mach-rk2818/include/mach/board.h
drivers/fpga/spi_dpram.c
drivers/fpga/spi_fpga.h
drivers/fpga/spi_fpga_init.c
drivers/fpga/spi_gpio.c
drivers/fpga/spi_i2c.c
drivers/fpga/spi_uart.c
include/linux/i2c.h

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