From: Jean Delvare Date: Tue, 1 May 2007 21:26:29 +0000 (+0200) Subject: i2c-algo-bit: Emulate SMBus block read X-Git-Tag: v2.6.22-rc1~1081^2~35 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c4bb241d34ee3d9ab87aad265734885385f179b;p=linux-2.6 i2c-algo-bit: Emulate SMBus block read Now that i2c-core lets the i2c bus drivers emulate the SMBus block read and SMBus block process call transaction types, let's implement that in the popular i2c bit-banging driver. This will also act as a reference implementation for other bus drivers which want to do the same. Signed-off-by: Jean Delvare --- diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 28b7e25ca7..fcef6ff3d2 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -391,6 +391,21 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) }; scllo(adap); sdahi(adap); + + /* Some SMBus transactions require that we receive the + transaction length as the first read byte. */ + if (rdcount == 1 && (msg->flags & I2C_M_RECV_LEN)) { + if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { + printk(KERN_ERR "i2c-algo-bit: readbytes: " + "invalid block length (%d)\n", inval); + return -EREMOTEIO; + } + /* The original count value accounts for the extra + bytes, that is, either 1 for a regular transaction, + or 2 for a PEC transaction. */ + count += inval; + msg->len += inval; + } } return rdcount; } @@ -509,6 +524,8 @@ bailout: static u32 bit_func(struct i2c_adapter *adap) { return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_SMBUS_READ_BLOCK_DATA | + I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; }