Skip to content

Commit

Permalink
i2c-taos-evm: Switch echo off to improve performance
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jean Delvare committed Sep 18, 2009
1 parent 6a891a3 commit 27693ce
Showing 1 changed file with 24 additions and 21 deletions.
45 changes: 24 additions & 21 deletions drivers/i2c/busses/i2c-taos-evm.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@

#define TAOS_STATE_INIT 0
#define TAOS_STATE_IDLE 1
#define TAOS_STATE_SEND 2
#define TAOS_STATE_EOFF 2
#define TAOS_STATE_RECV 3

#define TAOS_CMD_RESET 0x12
#define TAOS_CMD_ECHO_ON '+'
#define TAOS_CMD_ECHO_OFF '-'

static DECLARE_WAIT_QUEUE_HEAD(wq);

Expand Down Expand Up @@ -102,17 +104,9 @@ static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,

/* Send the transaction to the TAOS EVM */
dev_dbg(&adapter->dev, "Command buffer: %s\n", taos->buffer);
taos->pos = 0;
taos->state = TAOS_STATE_SEND;
serio_write(serio, taos->buffer[0]);
wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
msecs_to_jiffies(250));
if (taos->state != TAOS_STATE_IDLE) {
dev_err(&adapter->dev, "Transaction failed "
"(state=%d, pos=%d)\n", taos->state, taos->pos);
taos->addr = 0;
return -EIO;
}
for (p = taos->buffer; *p; p++)
serio_write(serio, *p);

taos->addr = addr;

/* Start the transaction and read the answer */
Expand All @@ -122,15 +116,15 @@ static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
msecs_to_jiffies(150));
if (taos->state != TAOS_STATE_IDLE
|| taos->pos != 6) {
|| taos->pos != 5) {
dev_err(&adapter->dev, "Transaction timeout (pos=%d)\n",
taos->pos);
return -EIO;
}
dev_dbg(&adapter->dev, "Answer buffer: %s\n", taos->buffer);

/* Interpret the returned string */
p = taos->buffer + 2;
p = taos->buffer + 1;
p[3] = '\0';
if (!strcmp(p, "NAK"))
return -ENODEV;
Expand Down Expand Up @@ -173,13 +167,9 @@ static irqreturn_t taos_interrupt(struct serio *serio, unsigned char data,
wake_up_interruptible(&wq);
}
break;
case TAOS_STATE_SEND:
if (taos->buffer[++taos->pos])
serio_write(serio, taos->buffer[taos->pos]);
else {
taos->state = TAOS_STATE_IDLE;
wake_up_interruptible(&wq);
}
case TAOS_STATE_EOFF:
taos->state = TAOS_STATE_IDLE;
wake_up_interruptible(&wq);
break;
case TAOS_STATE_RECV:
taos->buffer[taos->pos++] = data;
Expand Down Expand Up @@ -257,6 +247,19 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv)
}
strlcpy(adapter->name, name, sizeof(adapter->name));

/* Turn echo off for better performance */
taos->state = TAOS_STATE_EOFF;
serio_write(serio, TAOS_CMD_ECHO_OFF);

wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
msecs_to_jiffies(250));
if (taos->state != TAOS_STATE_IDLE) {
err = -ENODEV;
dev_err(&adapter->dev, "Echo off failed "
"(state=%d)\n", taos->state);
goto exit_close;
}

err = i2c_add_adapter(adapter);
if (err)
goto exit_close;
Expand Down

0 comments on commit 27693ce

Please sign in to comment.