improve spi_i2c by using wait_event_timeout function
authorluowei <lw@rock-chips.com>
Fri, 27 Aug 2010 12:51:08 +0000 (20:51 +0800)
committerluowei <lw@rock-chips.com>
Fri, 27 Aug 2010 12:51:08 +0000 (20:51 +0800)
arch/arm/mach-rk2818/include/mach/spi_fpga.h
drivers/fpga/spi_i2c.c

index 31376de88e863d194e9efeed0297109c24ec826f..f507f83118044a65af51be805fd2cc714bebaff8 100755 (executable)
@@ -13,7 +13,8 @@ defines of FPGA chip ICE65L08's register
 #define SPI_FPGA_STANDBY_PIN RK2818_PIN_PH7\r
 #define SPI_FPGA_RST_PIN RK2818_PIN_PF4\r
 \r
-#define SPI_FPGA_POLL_WAIT     1\r
+#define SPI_FPGA_I2C_EVENT     1\r
+#define SPI_FPGA_POLL_WAIT     0\r
 #define SPI_FPGA_TRANS_WORK    0\r
 #define SPI_FPGA_TEST_DEBUG    0\r
 #if SPI_FPGA_TEST_DEBUG\r
@@ -94,6 +95,9 @@ struct spi_i2c
        unsigned char interrupt;\r
        unsigned char i2c_data_width[2];\r
        unsigned int  speed[2];\r
+       #if SPI_FPGA_I2C_EVENT\r
+       wait_queue_head_t wait_w,wait_r;\r
+       #endif\r
 };\r
 \r
 struct spi_dpram\r
index 35f81509acbac7826b1915dcf8cac35d5ea0830d..3c7b67d701ccc19fbe1839b03500326c49292bdd 100755 (executable)
@@ -39,6 +39,7 @@
 #define I2C_COUNT       20\r
 #define DRV_NAME    "spi_i2c"\r
 #define SPI_I2C_TEST 0\r
+\r
 #if SPI_I2C_TEST\r
 struct i2c_adapter *adap;\r
 #endif\r
@@ -56,13 +57,24 @@ int spi_i2c_handle_irq(struct spi_fpga_port *port,unsigned char channel)
        ret = spi_in(port,reg,SEL_I2C);\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
+       {\r
+\r
+               port->i2c.interrupt = INT_I2C_READ_ACK; \r
+       #if SPI_FPGA_I2C_EVENT\r
+               wake_up(&port->i2c.wait_r);\r
+       #endif\r
+       }\r
        else if(INT_I2C_READ_NACK ==(ret & 0x07))\r
        {\r
                printk("Error::read no ack!!check the I2C slave device ret=%d \n",ret);\r
        }\r
        else if(INT_I2C_WRITE_ACK == (ret & 0x07))\r
+       {\r
                port->i2c.interrupt = INT_I2C_WRITE_ACK;\r
+               #if SPI_FPGA_I2C_EVENT\r
+               wake_up(&port->i2c.wait_w);\r
+               #endif\r
+       }\r
        else if(INT_I2C_WRITE_NACK == (ret & 0x07))\r
        {\r
                printk("Error::write no ack!!check the I2C slave device ret=%d \n",ret);\r
@@ -139,7 +151,20 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
        //len;\r
        reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_STOP;\r
        spi_out(port,reg,len,SEL_I2C);\r
-       \r
+\r
+#if SPI_FPGA_I2C_EVENT\r
+       wait_event_timeout(port->i2c.wait_r, port->i2c.interrupt == INT_I2C_READ_ACK, msecs_to_jiffies(30));    \r
+       for(i = 0;i<len;i++)\r
+       {\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
+       ret = pmsg->len;\r
+#else\r
        j = I2C_COUNT;\r
        while(j--)\r
 \r
@@ -162,6 +187,8 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
                else\r
                        msleep(2);\r
        }\r
+       \r
+#endif\r
        //for(i = 0;i<len;i++)\r
                //printk("pmsg->buf[%d] = 0x%x \n",i,pmsg->buf[i]);     \r
        return ret>0 ? ret:-1;\r
@@ -210,7 +237,13 @@ int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
                {\r
                reg = channel|ICE_SEL_I2C_STOP;\r
                spi_out(port,reg,pmsg->buf[i],SEL_I2C);\r
-       \r
+       #if SPI_FPGA_I2C_EVENT\r
+               wait_event_timeout(port->i2c.wait_w, port->i2c.interrupt == INT_I2C_WRITE_ACK, msecs_to_jiffies(30));\r
+               spin_lock(&port->i2c.i2c_lock);\r
+               port->i2c.interrupt &= INT_I2C_WRITE_MASK;\r
+               spin_unlock(&port->i2c.i2c_lock);\r
+               ret =  pmsg->len;\r
+       #else\r
                j = I2C_COUNT;  \r
                while(j--)\r
                {               \r
@@ -226,7 +259,7 @@ int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
                        else\r
                                msleep(2);\r
                }\r
-       \r
+       #endif\r
                }\r
                else if(i==len-1 &&  pmsg->read_type == I2C_NO_STOP)\r
                {                                       \r
@@ -509,6 +542,11 @@ int spi_i2c_register(struct spi_fpga_port *port,int num)
        \r
 #endif\r
 \r
+#if SPI_FPGA_I2C_EVENT\r
+       init_waitqueue_head(&port->i2c.wait_w);\r
+       init_waitqueue_head(&port->i2c.wait_r);\r
+#endif\r
+\r
        return 0;       \r
        \r
 }\r