* [PATCH] i2c: i2c-au1550: properly terminate zero-byte transfers
@ 2008-01-14 8:46 Manuel Lauss
[not found] ` <20080114084652.GA15392-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org>
0 siblings, 1 reply; 4+ messages in thread
From: Manuel Lauss @ 2008-01-14 8:46 UTC (permalink / raw)
To: khali-PUYAD+kWke1g9hUCZPvPmw
Cc: i2c-GZX6beZjE8VD60Wz+7aTrA, cd-8pe3aW1LYQvVtiohHAVwjA
Hi Jean,
Here is my third try to fix the corrupted RTC minute register
on my board in conjunction with the i2c-au1550 driver.
Here's a trace of the controller accessing the RTC (0xA2):
http://mlau.at/files/i2c-au1550-original_behav.png
Notice the missing stop condition after the quick probe.
Here's a trace with the patch applied:
http://mlau.at/files/i2c-au1550-misbehavior-patch-behav.png
Please apply!
---
>From 443520b88bda030ba304dcbbbf14f977abad5ff5 Mon Sep 17 00:00:00 2001
From: Manuel Lauss <mano-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org>
Date: Mon, 14 Jan 2008 09:28:11 +0100
Subject: [PATCH] i2c: i2c-au1550: properly terminate zero-byte transfers
Zero-bytes transfers would leave the bus transaction unfinished
(no i2c stop is sent), with the following transfer actually
sending the slave address to the previously addressed device,
resulting in weird device failures (e.g. reset minute register
values in my RTC).
This patch instructs the controller to send an I2C STOP right after
the slave address in case of a zero-byte transfer.
Signed-off-by: Manuel Lauss <mano-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org>
---
drivers/i2c/busses/i2c-au1550.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
index 2f68416..7d51a43 100644
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -105,7 +105,7 @@ wait_master_done(struct i2c_au1550_data *adap)
}
static int
-do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd)
+do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q)
{
volatile psc_smb_t *sp;
u32 stat;
@@ -134,6 +134,10 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd)
if (rd)
addr |= 1;
+ /* zero-byte xfers stop immediately */
+ if (q)
+ addr |= PSC_SMBTXRX_STP;
+
/* Put byte into fifo, start up master.
*/
sp->psc_smbtxrx = addr;
@@ -142,7 +146,7 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd)
au_sync();
if (wait_ack(adap))
return -EIO;
- return 0;
+ return (q) ? wait_master_done(adap) : 0;
}
static u32
@@ -262,7 +266,8 @@ au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
for (i = 0; !err && i < num; i++) {
p = &msgs[i];
- err = do_address(adap, p->addr, p->flags & I2C_M_RD);
+ err = do_address(adap, p->addr, p->flags & I2C_M_RD,
+ (p->len == 0));
if (err || !p->len)
continue;
if (p->flags & I2C_M_RD)
--
1.5.3.7
_______________________________________________
i2c mailing list
i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
http://lists.lm-sensors.org/mailman/listinfo/i2c
^ permalink raw reply related [flat|nested] 4+ messages in thread[parent not found: <20080114084652.GA15392-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org>]
* Re: [PATCH] i2c: i2c-au1550: properly terminate zero-byte transfers [not found] ` <20080114084652.GA15392-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org> @ 2008-01-17 15:52 ` Jean Delvare [not found] ` <20080117165230.711e87bf-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org> 0 siblings, 1 reply; 4+ messages in thread From: Jean Delvare @ 2008-01-17 15:52 UTC (permalink / raw) To: Manuel Lauss; +Cc: i2c-GZX6beZjE8VD60Wz+7aTrA, cd-8pe3aW1LYQvVtiohHAVwjA Hi Manuel, On Mon, 14 Jan 2008 09:46:52 +0100, Manuel Lauss wrote: > Here is my third try to fix the corrupted RTC minute register > on my board in conjunction with the i2c-au1550 driver. > > Here's a trace of the controller accessing the RTC (0xA2): > http://mlau.at/files/i2c-au1550-original_behav.png > > Notice the missing stop condition after the quick probe. > > Here's a trace with the patch applied: > http://mlau.at/files/i2c-au1550-misbehavior-patch-behav.png > > Please apply! Nice pictures, it's really helpful to be able to visualize what's happening on the I2C bus. > > --- > From 443520b88bda030ba304dcbbbf14f977abad5ff5 Mon Sep 17 00:00:00 2001 > From: Manuel Lauss <mano-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org> > Date: Mon, 14 Jan 2008 09:28:11 +0100 > Subject: [PATCH] i2c: i2c-au1550: properly terminate zero-byte transfers > > Zero-bytes transfers would leave the bus transaction unfinished > (no i2c stop is sent), with the following transfer actually > sending the slave address to the previously addressed device, > resulting in weird device failures (e.g. reset minute register > values in my RTC). > This patch instructs the controller to send an I2C STOP right after > the slave address in case of a zero-byte transfer. > > Signed-off-by: Manuel Lauss <mano-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org> > --- > drivers/i2c/busses/i2c-au1550.c | 11 ++++++++--- > 1 files changed, 8 insertions(+), 3 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c > index 2f68416..7d51a43 100644 > --- a/drivers/i2c/busses/i2c-au1550.c > +++ b/drivers/i2c/busses/i2c-au1550.c > @@ -105,7 +105,7 @@ wait_master_done(struct i2c_au1550_data *adap) > } > > static int > -do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd) > +do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q) > { > volatile psc_smb_t *sp; > u32 stat; > @@ -134,6 +134,10 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd) > if (rd) > addr |= 1; > > + /* zero-byte xfers stop immediately */ > + if (q) > + addr |= PSC_SMBTXRX_STP; > + > /* Put byte into fifo, start up master. > */ > sp->psc_smbtxrx = addr; > @@ -142,7 +146,7 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd) > au_sync(); > if (wait_ack(adap)) > return -EIO; > - return 0; > + return (q) ? wait_master_done(adap) : 0; > } > > static u32 > @@ -262,7 +266,8 @@ au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) > > for (i = 0; !err && i < num; i++) { > p = &msgs[i]; > - err = do_address(adap, p->addr, p->flags & I2C_M_RD); > + err = do_address(adap, p->addr, p->flags & I2C_M_RD, > + (p->len == 0)); > if (err || !p->len) > continue; > if (p->flags & I2C_M_RD) This approach looks much nicer than your previous proposal. I like it. Applied, thanks! -- Jean Delvare _______________________________________________ i2c mailing list i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org http://lists.lm-sensors.org/mailman/listinfo/i2c ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <20080117165230.711e87bf-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>]
* Re: [PATCH] i2c: i2c-au1550: properly terminate zero-byte transfers [not found] ` <20080117165230.711e87bf-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org> @ 2008-01-17 16:37 ` Manuel Lauss [not found] ` <20080117163733.GA13110-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org> 0 siblings, 1 reply; 4+ messages in thread From: Manuel Lauss @ 2008-01-17 16:37 UTC (permalink / raw) To: Jean Delvare; +Cc: i2c-GZX6beZjE8VD60Wz+7aTrA, cd-8pe3aW1LYQvVtiohHAVwjA On Thu, Jan 17, 2008 at 04:52:30PM +0100, Jean Delvare wrote: > Hi Manuel, > > This approach looks much nicer than your previous proposal. I like it. > Applied, thanks! Thank you, however there's still the problem with unterminated bus xfers after receiving a NAK. I've only seen them with a PCA9539 if one's trying to access a non-existant register. However it can't be solved to everyones satisfaction I'm afraid... (see http://mlau.at/files/i2c-au1550-stopfix-1-behav_2.png ) -- Manuel Lauss _______________________________________________ i2c mailing list i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org http://lists.lm-sensors.org/mailman/listinfo/i2c ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <20080117163733.GA13110-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org>]
* Re: [PATCH] i2c: i2c-au1550: properly terminate zero-byte transfers [not found] ` <20080117163733.GA13110-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org> @ 2008-01-18 7:33 ` Jean Delvare 0 siblings, 0 replies; 4+ messages in thread From: Jean Delvare @ 2008-01-18 7:33 UTC (permalink / raw) To: Manuel Lauss; +Cc: i2c-GZX6beZjE8VD60Wz+7aTrA, cd-8pe3aW1LYQvVtiohHAVwjA Hi Manuel, On Thu, 17 Jan 2008 17:37:33 +0100, Manuel Lauss wrote: > On Thu, Jan 17, 2008 at 04:52:30PM +0100, Jean Delvare wrote: > > Hi Manuel, > > > > This approach looks much nicer than your previous proposal. I like it. > > Applied, thanks! > > Thank you, however there's still the problem with unterminated bus xfers > after receiving a NAK. I've only seen them with a PCA9539 if one's trying > to access a non-existant register. However it can't be solved to everyones > satisfaction I'm afraid... > (see http://mlau.at/files/i2c-au1550-stopfix-1-behav_2.png ) Indeed. As I understand it, the hardware simply offers no clean solution to this problem, as you have to ask for the stop condition before you send an address or data byte. As you can't foresee transaction failures, you just can't ask for the stop condition before the failure (or simply nack) happens. Which means that you either don't send a stop condition at all (what the driver does now) or you send an extra byte before the stop condition (slightly better but still not perfect.) Or maybe you have to read the datasheet in details to find out how to do the right thing, some chips can be very tricky in this respect. Anyway, I will take whatever patch you think will improve the situation on this platform. -- Jean Delvare _______________________________________________ i2c mailing list i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org http://lists.lm-sensors.org/mailman/listinfo/i2c ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-01-18 7:33 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-14 8:46 [PATCH] i2c: i2c-au1550: properly terminate zero-byte transfers Manuel Lauss
[not found] ` <20080114084652.GA15392-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org>
2008-01-17 15:52 ` Jean Delvare
[not found] ` <20080117165230.711e87bf-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-17 16:37 ` Manuel Lauss
[not found] ` <20080117163733.GA13110-nEyxjcs6f3Vin2gBucwGBecsttgLyre6@public.gmane.org>
2008-01-18 7:33 ` Jean Delvare
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox