[i2c] i2c-dev i2c_smbus_read_i2c_block_data update
Jean Delvare
khali at linux-fr.org
Tue May 15 14:48:07 CEST 2007
On Sat, 12 May 2007 12:32:49 +0200, Jean Delvare wrote:
> Here comes the user-space patch completing the
> i2c_smbus_read_i2c_block_data kernel patch I sent yesterday. It finally
> makes it possible to do I2C block reads from user-space with size less
> than 32 bytes.
>
> I'm not too sure about the python changes, I'm not even sure the
> original code was correct and I can't test it. Mark, can you please
> take a look and comment?
Here is an updated version that matches the kernel patch update I just
posted. Note that "i2cdump i" would then only work with kernels >=
2.6.23, which is not very wise, so maybe we want to delay this change
(after all, the new kernel patch guarantees binary compatibility) or do
it differently, maybe falling back to the old block read if the new one
fails? Opinions welcome.
Index: kernel/include/i2c-dev.h
===================================================================
--- kernel/include/i2c-dev.h (revision 4403)
+++ kernel/include/i2c-dev.h (working copy)
@@ -106,8 +106,9 @@
#define I2C_SMBUS_WORD_DATA 3
#define I2C_SMBUS_PROC_CALL 4
#define I2C_SMBUS_BLOCK_DATA 5
-#define I2C_SMBUS_I2C_BLOCK_DATA 6
+#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
+#define I2C_SMBUS_I2C_BLOCK_DATA 8
/* ----- commands for the ioctl like i2c_command call:
@@ -271,11 +272,16 @@
}
/* Returns the number of read bytes */
+/* Note: only works since kernel 2.6.23 */
static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
- __u8 *values)
+ __u8 length, __u8 *values)
{
union i2c_smbus_data data;
int i;
+
+ if (length > 32)
+ length = 32;
+ data.block[0] = length;
if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
I2C_SMBUS_I2C_BLOCK_DATA,&data))
return -1;
@@ -297,7 +303,7 @@
data.block[i] = values[i-1];
data.block[0] = length;
return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
- I2C_SMBUS_I2C_BLOCK_DATA, &data);
+ I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
}
/* Returns the number of read bytes */
Index: prog/py-smbus/smbusmodule.c
===================================================================
--- prog/py-smbus/smbusmodule.c (revision 4403)
+++ prog/py-smbus/smbusmodule.c (working copy)
@@ -486,20 +486,22 @@
}
PyDoc_STRVAR(SMBus_read_i2c_block_data_doc,
- "read_i2c_block_data(addr, cmd) -> results\n\n"
+ "read_i2c_block_data(addr, cmd, len) -> results\n\n"
"Perform I2C Block Read transaction.\n");
static PyObject *
SMBus_read_i2c_block_data(SMBus *self, PyObject *args)
{
- int addr, cmd;
+ int addr, cmd, len;
union i2c_smbus_data data;
- if (!PyArg_ParseTuple(args, "ii:read_i2c_block_data", &addr, &cmd))
+ if (!PyArg_ParseTuple(args, "iii:read_i2c_block_data", &addr, &cmd,
+ &len))
return NULL;
SMBus_SET_ADDR(self, addr);
+ data.block[0] = len;
/* save a bit of code by calling the access function directly */
if (i2c_smbus_access(self->fd, I2C_SMBUS_READ, (__u8)cmd,
I2C_SMBUS_I2C_BLOCK_DATA, &data)) {
@@ -529,7 +531,7 @@
/* save a bit of code by calling the access function directly */
if (i2c_smbus_access(self->fd, I2C_SMBUS_WRITE, (__u8)cmd,
- I2C_SMBUS_I2C_BLOCK_DATA, &data)) {
+ I2C_SMBUS_I2C_BLOCK_BROKEN, &data)) {
PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
Index: prog/dump/i2cdump.c
===================================================================
--- prog/dump/i2cdump.c (revision 4403)
+++ prog/dump/i2cdump.c (working copy)
@@ -316,7 +316,7 @@
} else {
for (res = 0; res < 256; res += i) {
i = i2c_smbus_read_i2c_block_data(file,
- res, cblock + res);
+ res, 32, cblock + res);
if (i <= 0)
break;
}
--
Jean Delvare
More information about the i2c
mailing list