diff mbox

[U-Boot] drivers/i2c/fsl_i2c: modify i2c_read to handle multi-byte write

Message ID 1397205713-14076-1-git-send-email-shaveta@freescale.com
State Superseded
Delegated to: Heiko Schocher
Headers show

Commit Message

Shaveta Leekha April 11, 2014, 8:41 a.m. UTC
Most of the I2C slaves support accesses in the typical style
that is : read/write series of bytes at particular address offset.
These transactions look like:"
(1) START:Address:Tx:Offset:RESTART:Address[0..4]:Tx/Rx:data[0..n]:STOP"

However there are certain devices which support accesses in
terms of the transactions as follows:
(2) "START:Address:Tx:Txdata[0..n1]:Clock_stretching:
        RESTART:Address:Rx:data[0..n2]"
Here Txdata is typically a command and some associated data,
similarly Rxdata could be command status plus some data received
as a response to the command sent.

Type (1) transactions are currently supportd in the
i2c driver using i2c_read and i2c_write APIs. I2C EEPROMs,
RTC, etc fall in this category.

To handle type (2) along with type (1) transactions,
i2c_read() function has been modified.

Signed-off-by: Shaveta Leekha <shaveta@freescale.com>
Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
---
 drivers/i2c/fsl_i2c.c |   41 ++++++++++++++++++++++++++++++++++-------
 1 files changed, 34 insertions(+), 7 deletions(-)

Comments

Heiko Schocher April 11, 2014, 10:39 a.m. UTC | #1
Hello Shaveta Leekha,

Am 11.04.2014 10:41, schrieb Shaveta Leekha:
> Most of the I2C slaves support accesses in the typical style
> that is : read/write series of bytes at particular address offset.
> These transactions look like:"
> (1) START:Address:Tx:Offset:RESTART:Address[0..4]:Tx/Rx:data[0..n]:STOP"
>
> However there are certain devices which support accesses in
> terms of the transactions as follows:
> (2) "START:Address:Tx:Txdata[0..n1]:Clock_stretching:
>          RESTART:Address:Rx:data[0..n2]"
> Here Txdata is typically a command and some associated data,
> similarly Rxdata could be command status plus some data received
> as a response to the command sent.
>
> Type (1) transactions are currently supportd in the
> i2c driver using i2c_read and i2c_write APIs. I2C EEPROMs,
> RTC, etc fall in this category.
>
> To handle type (2) along with type (1) transactions,
> i2c_read() function has been modified.
>
> Signed-off-by: Shaveta Leekha<shaveta@freescale.com>
> Signed-off-by: Poonam Aggrwal<poonam.aggrwal@freescale.com>
> ---
>   drivers/i2c/fsl_i2c.c |   41 ++++++++++++++++++++++++++++++++++-------
>   1 files changed, 34 insertions(+), 7 deletions(-)

Hmm? Is this v2 of the following patch?:

[U-Boot] 2c: modify i2c_read API to handle multi-bytes writes
http://patchwork.ozlabs.org/patch/336911/

If so, please stick to the follow rules, for sending updated
patches:

http://www.denx.de/wiki/view/U-Boot/Patches#Sending_updated_patch_versions

Thanks!

bye,
Heiko
Shaveta Leekha April 21, 2014, 7:32 a.m. UTC | #2
Heiko Schocher <hs <at> denx.de> writes:


> 
> Hmm? Is this v2 of the following patch?:
> 
> [U-Boot] 2c: modify i2c_read API to handle multi-bytes writes
> http://patchwork.ozlabs.org/patch/336911/
> 
> If so, please stick to the follow rules, for sending updated
> patches:
> 
> http://www.denx.de/wiki/view/U-Boot/Patches#Sending_updated_patch_versions
> 
> Thanks!
> 
> bye,
> Heiko

Yes, this the the v2 of this patch. I missed adding the reference here.
I have rejected the older patch now, as the subject line was also little 
different.

Should I send the v2/v3 of this new patch " [U-Boot] [PATCH] 
drivers/i2c/fsl_i2c: modify i2c_read to handle multi-byte write"
now with the older references and changes mentioned?
Or this patch would work?

Regards,
Shaveta
diff mbox

Patch

diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index 291ad94..aa159f8 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -423,18 +423,45 @@  fsl_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, int alen, u8 *data,
 	struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
 	int i = -1; /* signal error */
 	u8 *a = (u8*)&addr;
+	int len = alen * -1;
 
 	if (i2c_wait4bus(adap) < 0)
 		return -1;
 
-	if ((!length || alen > 0)
-	    && i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0
-	    && __i2c_write(adap, &a[4 - alen], alen) == alen)
-		i = 0; /* No error so far */
+	/* To handle the need of I2C devices that require to write few bytes
+	 * (more than 4 bytes of address as in the case of else part)
+	 * of data before reading, Negative equivalent of length(bytes to write)
+	 * is passed, but used the +ve part of len for writing data
+	 */
+	if (alen < 0) {
+		/* Generate a START and send the Address and
+		 * the Tx Bytes to the slave.
+		 * "START: Address: Write bytes data[len]"
+		 * IF part supports writing any number of bytes in contrast
+		 * to the else part, which supports writing address offset
+		 * of upto 4 bytes only.
+		 * bytes that need to be written are passed in
+		 * "data", which will eventually keep the data READ,
+		 * after writing the len bytes out of it
+		 */
+		if (i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0)
+			i = __i2c_write(adap, data, len);
+
+		if (i != len)
+			return -1;
 
-	if (length &&
-	    i2c_write_addr(adap, dev, I2C_READ_BIT, alen ? 1 : 0) != 0)
-		i = __i2c_read(adap, data, length);
+		if (length && i2c_write_addr(adap, dev, I2C_READ_BIT, 1) != 0)
+			i = __i2c_read(adap, data, length);
+	} else {
+		if ((!length || alen > 0) &&
+		    i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0  &&
+		    __i2c_write(adap, &a[4 - alen], alen) == alen)
+			i = 0; /* No error so far */
+
+		if (length &&
+		    i2c_write_addr(adap, dev, I2C_READ_BIT, alen ? 1 : 0) != 0)
+			i = __i2c_read(adap, data, length);
+	}
 
 	writeb(I2C_CR_MEN, &device->cr);