#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
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
{\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
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
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
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
{\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
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
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
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
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
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
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
#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
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
\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