Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: Fix to the jerking problem with tda10045h



Andrew de Quincey wrote:
Hi, the jerking was caused by the i2c busyloop delays chewing too much CPU. The attached patch should fix it.
Basically, I've made the i2c code use the busy-waiting-low-latency mdelay()/my_delay() combination if there is lots of data being transferred. Otherwise it just uses the high latency my_delay() code as previously.

Now for some soak testing.
applied, please report if there're problems.

Holger


------------------------------------------------------------------------

Index: linux/drivers/media/common/saa7146_i2c.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/common/saa7146_i2c.c,v
retrieving revision 1.19
diff -u -p -r1.19 saa7146_i2c.c
--- linux/drivers/media/common/saa7146_i2c.c 14 Jun 2003 20:06:03 -0000 1.19
+++ linux/drivers/media/common/saa7146_i2c.c 16 Jun 2003 10:37:18 -0000
@@ -187,7 +187,7 @@ int saa7146_i2c_reset(struct saa7146_dev
it returns 0 if ok, -1 if the transfer failed, -2 if the transfer
failed badly (e.g. address error) */
static
-int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword)
+int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_delay)
{
u32 status = 0, mc2 = 0;
int trial = 0;
@@ -245,7 +245,7 @@ int saa7146_i2c_writeout(struct saa7146_
DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
return -EIO;
}
- if (++trial < 10)
+ if ((++trial < 20) && short_delay)
udelay(10);
else
my_wait(dev,1);
@@ -290,6 +290,7 @@ int saa7146_i2c_transfer(struct saa7146_
u32* buffer = dev->d_i2c.cpu_addr;
int err = 0;
int address_err = 0;
+ int short_delay = 0;

if (down_interruptible (&dev->i2c_lock))
return -ERESTARTSYS;
@@ -305,6 +306,8 @@ int saa7146_i2c_transfer(struct saa7146_
goto out;
}
+ if (count > 3) short_delay = 1;
+ do {
/* reset the i2c-device if necessary */
err = saa7146_i2c_reset(dev);
@@ -315,7 +318,7 @@ int saa7146_i2c_transfer(struct saa7146_
/* write out the u32s one after another */
for(i = 0; i < count; i++) {
- err = saa7146_i2c_writeout(dev, &buffer[i] );
+ err = saa7146_i2c_writeout(dev, &buffer[i], short_delay);
if ( 0 != err) {
/* this one is unsatisfying: some i2c slaves on some
dvb cards don't acknowledge correctly, so the saa7146
@@ -370,7 +373,7 @@ out:
if( 0 == dev->revision ) {
u32 zero = 0;
saa7146_i2c_reset(dev);
- if( 0 != saa7146_i2c_writeout(dev, &zero)) {
+ if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) {
INFO(("revision 0 error. this should never happen.\n"));
}
}


--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe linux-dvb" as subject.



Home | Main Index | Thread Index