modify spi i2c
authorswj <swj@rock-chips.com>
Wed, 28 Jul 2010 13:17:27 +0000 (06:17 -0700)
committerswj <swj@rock-chips.com>
Wed, 28 Jul 2010 13:17:27 +0000 (06:17 -0700)
arch/arm/mach-rk2818/include/mach/spi_fpga.h [changed mode: 0644->0755]
drivers/fpga/spi_fpga_init.c [changed mode: 0644->0755]
drivers/fpga/spi_i2c.c [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index cd889b9..dfc5e60
@@ -61,7 +61,16 @@ struct spi_gpio
        struct timer_list       gpio_timer;\r
 \r
 };\r
-\r
+struct spi_i2c_data\r
+{\r
+       struct i2c_adapter     adapter;\r
+       struct i2c_client         *client;\r
+       struct spi_fpga_port   *port;\r
+       unsigned int                 speed;     \r
+       unsigned int                 mode;\r
+       unsigned int                    msg_idx;\r
+       unsigned int                    msg_num;\r
+};\r
 struct spi_i2c\r
 {\r
        struct workqueue_struct         *spi_i2c_workqueue;\r
@@ -206,15 +215,10 @@ typedef enum I2C_ch
 typedef enum eI2CReadMode\r
 {\r
        I2C_NORMAL,\r
-       I2C_NOREG\r
+       I2C_NO_REG,\r
+       I2C_NO_STOP\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
 #define ICE_SEL_I2C_RESTART        (2<<0)\r
old mode 100644 (file)
new mode 100755 (executable)
index 8195aa2..77da0b2
@@ -307,7 +307,7 @@ static int spi_open_sysclk(int set)
        return 0;\r
 }\r
 \r
-extern int spi_i2c_set_bt_power(void);\r
+\r
 static int __devinit spi_fpga_probe(struct spi_device * spi)\r
 {\r
        struct spi_fpga_port *port;\r
@@ -361,18 +361,18 @@ static int __devinit spi_fpga_probe(struct spi_device * spi)
 #endif\r
 #if defined(CONFIG_SPI_I2C)\r
 \r
-       printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
+       DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
        spin_lock_init(&port->i2c.i2c_lock);\r
        for (num= 2;num<4;num++)\r
        {\r
-               ret = spi_i2c_register(port,num);\r
-               printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
+               ret = spi_i2c_register(port,num);               \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
+               DBG("spi_i2c spi_i2c.%d: i2c-%d: spi_i2c I2C adapter\n",num,num);\r
        }\r
 #endif\r
 \r
old mode 100644 (file)
new mode 100755 (executable)
index 687023a..ea1261a
 #define DBG(x...)\r
 #endif\r
 \r
-#define MAXMSGLEN   8\r
-#define DRV_NAME    "fpga_i2c"\r
+#define MAXMSGLEN      8\r
+#define I2C_COUNT       20\r
+#define DRV_NAME    "spi_i2c"\r
 #define SPI_I2C_TEST 0\r
-struct spi_i2c_data {\r
-       struct device *dev;\r
-       struct i2c_adapter adapter;\r
-       unsigned long scl_rate;\r
-       spinlock_t i2c_lock;    \r
-};\r
-\r
-\r
+#if SPI_I2C_TEST\r
+struct i2c_adapter *adap;\r
+#endif\r
 int spi_i2c_handle_irq(struct spi_fpga_port *port,unsigned char channel)\r
 {\r
        int reg;\r
@@ -81,22 +77,23 @@ int spi_i2c_select_speed(int speed)
        int result = 0; \r
        switch(speed)\r
        {\r
-               case 10:\r
+               case 10*1000:\r
                        result = ICE_SET_10K_I2C_SPEED; \r
                        break;                  \r
-               case 100:\r
+               case 100*1000:\r
                        result = ICE_SET_100K_I2C_SPEED;                \r
                        break;                  \r
-               case 200:\r
+               case 200*1000:\r
                        result = ICE_SET_200K_I2C_SPEED;        \r
                        break;                  \r
-               case 300:                       \r
+               case 300*1000:                  \r
                       result = ICE_SET_300K_I2C_SPEED; \r
                        break;                  \r
-               case 400:                       \r
+               case 400*1000:                  \r
                        result = ICE_SET_400K_I2C_SPEED;        \r
                        break;                  \r
-               default:                        \r
+               default:        \r
+                       printk("not support this rate ,set spi i2c rate fail\n");\r
                        break;          \r
        }\r
        return result;\r
@@ -106,13 +103,13 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
 {\r
        \r
        unsigned int reg ;\r
-       unsigned int len,i;\r
+       unsigned int len,i,j;\r
        unsigned int slaveaddr;\r
        unsigned int speed;\r
        unsigned int channel = 0 ;\r
        unsigned int result;\r
        \r
-       slaveaddr = pmsg->addr;\r
+       slaveaddr = pmsg->addr<<1;\r
        len = pmsg->len;        \r
        speed = spi_i2c_select_speed(pmsg->scl_rate);\r
        \r
@@ -126,46 +123,13 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
                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 == I2C_NORMAL)\r
-       {\r
-               //slaveaddr ;\r
-               slaveaddr = slaveaddr<<1;\r
-               reg = channel |ICE_SEL_I2C_START;\r
-               spi_out(port,reg,slaveaddr,SEL_I2C);\r
-               //speed;\r
-               reg = channel |ICE_SEL_I2C_SPEED|ICE_SEL_I2C_TRANS;\r
-               spi_out(port,reg,speed,SEL_I2C);\r
-               //len;&&data\r
-               reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_TRANS;\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
-                       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
+       DBG("len = %d chan = %d read=%d\n",pmsg->len,ch,pmsg->read_type);       \r
 \r
        \r
-       //slaveaddr\r
        slaveaddr = slaveaddr|ICE_I2C_SLAVE_READ;\r
-       if(pmsg->read_type == 0)\r
+       if(pmsg->read_type == I2C_NORMAL  || pmsg->read_type == I2C_NO_STOP)\r
                reg = channel |ICE_SEL_I2C_RESTART;\r
-       else\r
+       else if(pmsg->read_type == I2C_NO_REG )\r
                reg = channel |ICE_SEL_I2C_START;\r
        spi_out(port,reg,slaveaddr,SEL_I2C);\r
        //speed;\r
@@ -175,8 +139,11 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
        reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_STOP;\r
        spi_out(port,reg,len,SEL_I2C);\r
        \r
-       msleep(100);    \r
-       if(port->i2c.interrupt == INT_I2C_READ_ACK)\r
+       j = I2C_COUNT;\r
+       while(j--)\r
+\r
+       {\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
@@ -188,7 +155,11 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
                        spin_lock(&port->i2c.i2c_lock);\r
                        port->i2c.interrupt &= INT_I2C_READ_MASK;\r
                        spin_unlock(&port->i2c.i2c_lock);\r
-               }       \r
+                       break;\r
+               }\r
+               else\r
+                       msleep(2);\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
@@ -199,7 +170,7 @@ int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
 {\r
        \r
        unsigned int reg ;\r
-       unsigned int len,i;\r
+       unsigned int len,i,j;\r
        unsigned int slaveaddr;\r
        unsigned int speed;\r
        unsigned int channel = 0;\r
@@ -217,7 +188,8 @@ int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
                printk("Error: try to write the error i2c channel\n");\r
                return 0;\r
        }\r
-       DBG("len = %d ch = %d\n",pmsg->len,ch);\r
+       DBG("len = %d chan = %d read=%d\n",pmsg->len,ch,pmsg->read_type);       \r
+\r
        //slaveaddr ;\r
        slaveaddr = slaveaddr<<1;\r
        reg = channel |ICE_SEL_I2C_START;\r
@@ -230,31 +202,98 @@ int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
        spi_out(port,reg,len,SEL_I2C);\r
        reg = channel  |ICE_SEL_I2C_TRANS;\r
        //data;\r
-       for(i = 0 ;i < len;i++)\r
-       {\r
-               if(i == len-1)\r
-                       reg = channel|ICE_SEL_I2C_STOP;\r
+       for(i = 0 ;i < len;i++){\r
+               if(i==len-1 &&  pmsg->read_type == I2C_NORMAL)\r
+               {\r
+               reg = channel|ICE_SEL_I2C_STOP;\r
                spi_out(port,reg,pmsg->buf[i],SEL_I2C);\r
-       }\r
-       msleep(25);\r
-       i = 50;\r
-       while(i--)\r
-       {               \r
-               if(port->i2c.interrupt  == INT_I2C_WRITE_ACK)\r
+       \r
+               j = I2C_COUNT;  \r
+               while(j--)\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
+                       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
+                       else\r
+                               msleep(2);\r
+               }\r
+       \r
+               }\r
+               else if(i==len-1 &&  pmsg->read_type == I2C_NO_STOP)\r
+               {                                       \r
+                       spi_out(port,reg,pmsg->buf[i],SEL_I2C);\r
+               }\r
+               else\r
+               {                       \r
+                       spi_out(port,reg,pmsg->buf[i],SEL_I2C);\r
+               }\r
+       }       \r
+       \r
        \r
        return pmsg->len;\r
        \r
        \r
 }\r
 \r
+static int spi_xfer_msg(struct i2c_adapter *adapter,\r
+                                               struct i2c_msg *msg,int stop)\r
+{\r
+       int ret;\r
+       struct spi_i2c_data *i2c = (struct spi_i2c_data *)adapter->algo_data;\r
+       struct spi_fpga_port *port = (struct spi_fpga_port *) i2c->port;        \r
+       //printk("%s:line=%d,channel = %d port= 0x%x\n",__FUNCTION__,__LINE__,adapter->nr,port);        \r
+\r
+       if(msg->len >MAXMSGLEN)\r
+               return EFBIG;\r
+       if(msg->flags & I2C_M_RD)       \r
+               ret = spi_i2c_readbuf(port,msg,adapter->nr);\r
+\r
+       else \r
+               ret = spi_i2c_writebuf(port,msg,adapter->nr);\r
+       return ret;\r
+}\r
+\r
+int spi_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)\r
+{\r
+       \r
+       int i;\r
+       int ret;\r
+       struct spi_i2c_data *i2c = (struct spi_i2c_data *)adapter->algo_data;\r
+       \r
+       if(adapter->nr != I2C_CH2 && adapter->nr != I2C_CH3)\r
+               return -EPERM;\r
+       \r
+       //i2c->msg_num = num;           \r
+       \r
+       for(i = 0;i<num;i++)\r
+       {\r
+               //i2c->msg_idx = i;\r
+               ret = spi_xfer_msg(adapter,&msgs[i],(i == (num - 1)));  \r
+               if(ret == 0)\r
+               {\r
+                       num = ret;\r
+                       printk("spi_xfer_msg error .ret = %d\n",ret);\r
+                       break;\r
+               }\r
+       }\r
+       return num;\r
+}\r
+\r
+\r
+static unsigned int spi_i2c_func(struct i2c_adapter *adapter)\r
+{\r
+       return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL);\r
+}\r
+                       \r
+static const struct i2c_algorithm spi_i2c_algorithm = {\r
+       .master_xfer            = spi_i2c_xfer,\r
+       .functionality          = spi_i2c_func,\r
+};\r
 \r
 #if SPI_I2C_TEST\r
 unsigned short rda5400[][2] = \r
@@ -300,9 +339,10 @@ int spi_i2c_16bit_test(struct spi_fpga_port *port)
        u8 i2c_buf[8];\r
        int len = 2;\r
        int i ;\r
+       struct i2c_adapter *adapter = adap;\r
        struct i2c_msg msg[1] = \r
        {\r
-               {0x16,0,len+2,i2c_buf,200,0,0}\r
+               {0x16,0,len+2,i2c_buf,200*1000,0,0}\r
        };\r
        \r
        for(i = 0;i < (sizeof(rda5400)/sizeof(rda5400[0]));i++)\r
@@ -328,11 +368,16 @@ int spi_i2c_8bit_test(struct spi_fpga_port *port)
        u8 i2c_buf[8];\r
        int len = 2;\r
        int i ;\r
+       struct i2c_adapter *adapter = adap;\r
        struct i2c_msg msg[1] = \r
        {\r
-               {0x16,0,len+1,i2c_buf,200,0,0}\r
+               {0x16,0,len+1,i2c_buf,200*1000,0,0}\r
+       };\r
+       struct i2c_msg msgs[2] = \r
+       {\r
+               {0x16,0,1,i2c_buf,200*1000,2,0},\r
+               {0x16,1,2,i2c_buf,200*1000,2,0},\r
        };\r
-       \r
        for(i = 0;i < (sizeof(rda5400)/sizeof(rda5400[0]));i++)\r
        {       \r
                printk("i=%d\n",i);\r
@@ -340,11 +385,14 @@ int spi_i2c_8bit_test(struct spi_fpga_port *port)
                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,3);\r
-               msg[0].len = 2;\r
+               //spi_i2c_writebuf(port, msg,3);\r
+               spi_i2c_xfer(adapter,msg,1);\r
+               \r
+               \r
                i2c_buf[1] = 0;\r
                i2c_buf[2] = 0;\r
-               spi_i2c_readbuf(port, msg,3);\r
+               spi_i2c_xfer(adapter,msgs,2);\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
@@ -358,8 +406,6 @@ int spi_i2c_test(void)
        spi_i2c_8bit_test(port);\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
@@ -381,7 +427,7 @@ static void spi_testi2c_timer(unsigned long data)
 #define BT_PWR_PIN     SPI_GPIO_P1_06\r
 int spi_i2c_set_bt_power(void)\r
 {\r
-#if 1\r
+#if 0\r
 \r
        spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_HIGH);\r
        spi_gpio_set_pindirection(BT_RST_PIN, SPI_GPIO_OUT);\r
@@ -405,80 +451,44 @@ int spi_i2c_set_bt_power(void)
        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
-{\r
-       //struct spi_fpga_port *port1 = pFpgaPort;      \r
-       struct spi_fpga_port *port = adapter->algo_data;\r
-       \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,adapter->nr);\r
-               //spi_i2c_readbuf(port,pmsg,adapter->nr,num);\r
-       else\r
-               spi_i2c_writebuf(port,pmsg,adapter->nr);\r
-\r
-       return pmsg->len;       \r
-\r
-       return 0;\r
-}\r
-\r
-static unsigned int spi_i2c_func(struct i2c_adapter *adapter)\r
-{\r
-       return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL);\r
-}\r
-                       \r
-static const struct i2c_algorithm spi_i2c_algorithm = {\r
-       .master_xfer            = spi_i2c_xfer,\r
-       .functionality          = spi_i2c_func,\r
-};\r
-#if 1\r
 int spi_i2c_register(struct spi_fpga_port *port,int num)\r
 {\r
        int ret;\r
-       struct i2c_adapter *adapter;\r
+       struct spi_i2c_data *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
+       i2c = kzalloc(sizeof(struct spi_i2c_data),GFP_KERNEL);\r
+       if(i2c == NULL)\r
+       {       \r
+               printk("%s:no memory for state \n",__FUNCTION__);\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
+       }\r
+       i2c->port = port;\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
+       //lock  \r
+       i2c->adapter.nr = num;\r
+       i2c->adapter.algo_data = i2c;\r
+       ret = i2c_add_numbered_adapter(&i2c->adapter);\r
        if(ret)\r
        {\r
                printk(KERN_INFO "SPI2I2C: Failed to add bus\n");\r
-               kfree(adapter);\r
+               kfree(i2c);\r
                \r
                return ret;\r
        }\r
-\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
+       adap = &i2c->adapter;\r
        port->i2c.spi_i2c_workqueue = create_freezeable_workqueue(b);\r
        if (!port->i2c.spi_i2c_workqueue) {\r
                printk("cannot create workqueue\n");\r
@@ -494,13 +504,14 @@ int spi_i2c_register(struct spi_fpga_port *port,int num)
        \r
 #endif\r
 \r
-       return 0;\r
+       return 0;       \r
+       \r
 }\r
 \r
-#endif\r
-\r
-\r
-\r
+int spi_i2c_unregister(struct spi_fpga_port *port)\r
+{\r
+       return 0;\r
+}\r
 \r
 \r
 MODULE_DESCRIPTION("Driver for spi2i2c.");\r