aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2009-09-18 16:45:43 -0400
committerJean Delvare <khali@linux-fr.org>2009-09-18 16:45:43 -0400
commit27693ce5f372c0af3b0730f5152b35432afa0fd7 (patch)
treee408ab73b8f1815a89a935992bec4332f0ff116a /drivers/i2c
parent6a891a3111fe701517bb31c2204304724c7299c8 (diff)
i2c-taos-evm: Switch echo off to improve performance
When echo is on, we waste time reading back our orders. Switching echo off makes performance much better: SMBus byte data transactions are 47% faster and byte transactions are 24% faster. Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-taos-evm.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c
index 224aa12ee7c8..dd39c1eb03ed 100644
--- a/drivers/i2c/busses/i2c-taos-evm.c
+++ b/drivers/i2c/busses/i2c-taos-evm.c
@@ -32,10 +32,12 @@
32 32
33#define TAOS_STATE_INIT 0 33#define TAOS_STATE_INIT 0
34#define TAOS_STATE_IDLE 1 34#define TAOS_STATE_IDLE 1
35#define TAOS_STATE_SEND 2 35#define TAOS_STATE_EOFF 2
36#define TAOS_STATE_RECV 3 36#define TAOS_STATE_RECV 3
37 37
38#define TAOS_CMD_RESET 0x12 38#define TAOS_CMD_RESET 0x12
39#define TAOS_CMD_ECHO_ON '+'
40#define TAOS_CMD_ECHO_OFF '-'
39 41
40static DECLARE_WAIT_QUEUE_HEAD(wq); 42static DECLARE_WAIT_QUEUE_HEAD(wq);
41 43
@@ -102,17 +104,9 @@ static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
102 104
103 /* Send the transaction to the TAOS EVM */ 105 /* Send the transaction to the TAOS EVM */
104 dev_dbg(&adapter->dev, "Command buffer: %s\n", taos->buffer); 106 dev_dbg(&adapter->dev, "Command buffer: %s\n", taos->buffer);
105 taos->pos = 0; 107 for (p = taos->buffer; *p; p++)
106 taos->state = TAOS_STATE_SEND; 108 serio_write(serio, *p);
107 serio_write(serio, taos->buffer[0]); 109
108 wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
109 msecs_to_jiffies(250));
110 if (taos->state != TAOS_STATE_IDLE) {
111 dev_err(&adapter->dev, "Transaction failed "
112 "(state=%d, pos=%d)\n", taos->state, taos->pos);
113 taos->addr = 0;
114 return -EIO;
115 }
116 taos->addr = addr; 110 taos->addr = addr;
117 111
118 /* Start the transaction and read the answer */ 112 /* Start the transaction and read the answer */
@@ -122,7 +116,7 @@ static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
122 wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE, 116 wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
123 msecs_to_jiffies(150)); 117 msecs_to_jiffies(150));
124 if (taos->state != TAOS_STATE_IDLE 118 if (taos->state != TAOS_STATE_IDLE
125 || taos->pos != 6) { 119 || taos->pos != 5) {
126 dev_err(&adapter->dev, "Transaction timeout (pos=%d)\n", 120 dev_err(&adapter->dev, "Transaction timeout (pos=%d)\n",
127 taos->pos); 121 taos->pos);
128 return -EIO; 122 return -EIO;
@@ -130,7 +124,7 @@ static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
130 dev_dbg(&adapter->dev, "Answer buffer: %s\n", taos->buffer); 124 dev_dbg(&adapter->dev, "Answer buffer: %s\n", taos->buffer);
131 125
132 /* Interpret the returned string */ 126 /* Interpret the returned string */
133 p = taos->buffer + 2; 127 p = taos->buffer + 1;
134 p[3] = '\0'; 128 p[3] = '\0';
135 if (!strcmp(p, "NAK")) 129 if (!strcmp(p, "NAK"))
136 return -ENODEV; 130 return -ENODEV;
@@ -173,13 +167,9 @@ static irqreturn_t taos_interrupt(struct serio *serio, unsigned char data,
173 wake_up_interruptible(&wq); 167 wake_up_interruptible(&wq);
174 } 168 }
175 break; 169 break;
176 case TAOS_STATE_SEND: 170 case TAOS_STATE_EOFF:
177 if (taos->buffer[++taos->pos]) 171 taos->state = TAOS_STATE_IDLE;
178 serio_write(serio, taos->buffer[taos->pos]); 172 wake_up_interruptible(&wq);
179 else {
180 taos->state = TAOS_STATE_IDLE;
181 wake_up_interruptible(&wq);
182 }
183 break; 173 break;
184 case TAOS_STATE_RECV: 174 case TAOS_STATE_RECV:
185 taos->buffer[taos->pos++] = data; 175 taos->buffer[taos->pos++] = data;
@@ -257,6 +247,19 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv)
257 } 247 }
258 strlcpy(adapter->name, name, sizeof(adapter->name)); 248 strlcpy(adapter->name, name, sizeof(adapter->name));
259 249
250 /* Turn echo off for better performance */
251 taos->state = TAOS_STATE_EOFF;
252 serio_write(serio, TAOS_CMD_ECHO_OFF);
253
254 wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
255 msecs_to_jiffies(250));
256 if (taos->state != TAOS_STATE_IDLE) {
257 err = -ENODEV;
258 dev_err(&adapter->dev, "Echo off failed "
259 "(state=%d)\n", taos->state);
260 goto exit_close;
261 }
262
260 err = i2c_add_adapter(adapter); 263 err = i2c_add_adapter(adapter);
261 if (err) 264 if (err)
262 goto exit_close; 265 goto exit_close;