[lkml]   [2006]   [Jun]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
SubjectRe: [PATCH] I2C block read
On Wed, 7 Jun 2006 20:50:25 +0200
Jean Delvare wrote:

> As for the problem you encounter, it looks like a bug in the
> scx200_acb driver to me. It advertises the I2C_FUNC_SMBUS_BLOCK_DATA
> functionality, but due to its implementation it can only support SMBus
> block writes and not SMBus block reads. I see no reason why the chip
> itself couldn't do it, but right now the driver can't. The state
> machine the driver is based on would need some rework before the
> functionality can be added. In the meantime, the quickest fix is to

OK, i got it now. Untested patch that should do it.
> May I ask for what slave SMBus chip you need the SMBus block read
> transaction? It's only rarely used, so it could be that it's not what
> you need after all.

It's custom developed board with using some motorola processor,
and the implementation there is buggy doesn't send the lenght but
this is fixable. So i'll have to fix the state machine after that.
Guy who is developing the board says that he doesn't get the ACK
after the last byte is read too - one more thing to investigate.

Also i use some pc engines board which has geode cpu on it
and have two access busses one is at 0x820 and the second is at 0x810
but the second is not in the list of probed devices, can it be added?

> The scx200_acb code would probably benefit from a general review. It
> looks to me like quick command with data bit == 1 would fail, for
> example. It's not a very popular transaction either, but i2c bus
> drivers should handle all transactions they advertise as supported.

have fun,

--- drivers/i2c/busses/scx200_acb.c.orig 2006-06-08 15:57:38.000000000 +0300
+++ drivers/i2c/busses/scx200_acb.c 2006-06-08 16:24:32.000000000 +0300
@@ -175,12 +175,22 @@
iface->state = state_read;
} else {
outb(iface->address_byte, ACBSDA);
iface->state = state_write;

case state_read:
+ if (iface->len == 42) {
+ outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
+ iface->len = inb(ACBSDA);
+ if (iface->len > 31) {
+ dev_dbg(&iface->, "Invalid read lenght %d in state %s\n",
+ iface->len, scx200_acb_state_name[iface->state]);
+ errmsg = "Invalid read lenght";
+ goto error;
+ }
+ break;
+ }
/* Set ACK if receiving the last byte */
if (iface->len == 1)
outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
@@ -305,7 +315,11 @@

- len = data->block[0];
+ /* 42 is invalid lenght max 32, use it to get real lenght from data */
+ if (rw == I2C_SMBUS_READ)
+ len = 42;
+ else
+ len = data->block[0];
buffer = &data->block[1];

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at
Please read the FAQ at
 \ /
  Last update: 2006-06-08 15:32    [W:0.040 / U:7.116 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site