summaryrefslogtreecommitdiff
path: root/drivers/i2c/busses/scx200_acb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/scx200_acb.c')
-rw-r--r--drivers/i2c/busses/scx200_acb.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 22a3eda0416..ced309ff056 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -184,21 +184,21 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
break;
case state_read:
- /* Set ACK if receiving the last byte */
- if (iface->len == 1)
+ /* Set ACK if _next_ byte will be the last one */
+ if (iface->len == 2)
outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
else
outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
- *iface->ptr++ = inb(ACBSDA);
- --iface->len;
-
- if (iface->len == 0) {
+ if (iface->len == 1) {
iface->result = 0;
iface->state = state_idle;
outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
}
+ *iface->ptr++ = inb(ACBSDA);
+ --iface->len;
+
break;
case state_write:
@@ -307,8 +307,12 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
buffer = (u8 *)&cur_word;
break;
- case I2C_SMBUS_BLOCK_DATA:
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ if (rw == I2C_SMBUS_READ)
+ data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */
len = data->block[0];
+ if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
+ return -EINVAL;
buffer = &data->block[1];
break;
@@ -372,7 +376,7 @@ static u32 scx200_acb_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA;
+ I2C_FUNC_SMBUS_I2C_BLOCK;
}
/* For now, we only handle combined mode (smbus) */