diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-taos-evm.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-taos-evm.c | 57 |
1 files changed, 29 insertions, 28 deletions
diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c index 224aa12ee7c..05760268355 100644 --- a/drivers/i2c/busses/i2c-taos-evm.c +++ b/drivers/i2c/busses/i2c-taos-evm.c @@ -3,7 +3,7 @@ * These devices include an I2C master which can be controlled over the * serial port. * - * Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2007 Jean Delvare <jdelvare@suse.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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); @@ -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 */ @@ -122,7 +116,7 @@ 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; @@ -130,7 +124,7 @@ static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr, 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; @@ -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; @@ -244,7 +234,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv) if (taos->state != TAOS_STATE_IDLE) { err = -ENODEV; - dev_dbg(&serio->dev, "TAOS EVM reset failed (state=%d, " + dev_err(&serio->dev, "TAOS EVM reset failed (state=%d, " "pos=%d)\n", taos->state, taos->pos); goto exit_close; } @@ -257,10 +247,23 @@ 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(&serio->dev, "TAOS EVM echo off failed " + "(state=%d)\n", taos->state); + goto exit_close; + } + err = i2c_add_adapter(adapter); if (err) goto exit_close; - dev_dbg(&serio->dev, "Connected to TAOS EVM\n"); + dev_info(&serio->dev, "Connected to TAOS EVM\n"); taos->client = taos_instantiate_device(adapter); return 0; @@ -268,7 +271,6 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv) exit_close: serio_close(serio); exit_kfree: - serio_set_drvdata(serio, NULL); kfree(taos); exit: return err; @@ -282,10 +284,9 @@ static void taos_disconnect(struct serio *serio) i2c_unregister_device(taos->client); i2c_del_adapter(&taos->adapter); serio_close(serio); - serio_set_drvdata(serio, NULL); kfree(taos); - dev_dbg(&serio->dev, "Disconnected from TAOS EVM\n"); + dev_info(&serio->dev, "Disconnected from TAOS EVM\n"); } static struct serio_device_id taos_serio_ids[] = { @@ -320,7 +321,7 @@ static void __exit taos_exit(void) serio_unregister_driver(&taos_drv); } -MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); +MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>"); MODULE_DESCRIPTION("TAOS evaluation module driver"); MODULE_LICENSE("GPL"); |
