[linux-dvb] SAA7146 short delay flag and budget cards

hunold at linuxtv.org hunold at linuxtv.org
Mon Sep 26 12:25:58 CEST 2005

Hello Johannes, 

Johannes Stezenbach writes:
> syrius.ml at no-log.org wrote:
>> (someone broke quoting so we don't know who wrote this:)
>> >> After a long and painful search, I found out that the delay
>> >> happened in I2C comms. I noticed that, in av7110.c, a flag was set,
>> >> called SAA7146_I2C_SHORT_DELAY, in the saa7146_extension
>> >> structure. So, I applied the following simple patch:
>> >> 
>> >> --- budget.c~   2005-09-04 14:58:21.000000000 +0200
>> >> +++ budget.c    2005-09-17 23:28:14.000000000 +0200
>> >> @@ -740,7 +740,7 @@
>> >> 
>> >>  static struct saa7146_extension budget_extension = {
>> >>         .name           = "budget dvb\0",
>> >> -       .flags          = 0,
>> >> +       .flags          = SAA7146_I2C_SHORT_DELAY,
>> >> 
>> >>         .module         = THIS_MODULE,
>> >>         .pci_tbl        = pci_tbl,
>> >> 
>> >> Well, the card now reacts *very* quickly, and I do not notice any side
>> >> effects. 
>> >> 
>> >> Is there any reason why this flag is not set? 
>> Same here !
>> my 1131:7146 tt budget card (without ci) now works correctly with this
>> correction to budget-ci.c and recent kernels (2.6.14-rc2-git5 + cvs
>> dvb-kernel)
>> without this, the budget card only tune to some channels
>> (if i recall correctly, only low band horizontal polarity ones)
> It looks to me like SAA7146_I2C_SHORT_DELAY should be safe
> for all cards? Looking at saa7146_i2c.c it seems the worst
> which could happen is that with some slow i2c devices it
> would wast some CPU? Why does SAA7146_I2C_SHORT_DELAY
> exist in the first place? Why does the short_delay flag
> depend on the result of saa7146_i2c_msg_prepare()?

First of all, I did not add "short_delay" to that code. ;-) 

In theory, i2c transfers with the saa7146 can be interrupt-driven. The 
transfer is started, the caller goes to sleep, remaining transfers are 
continued from the interrupt handler. After the last transfer, the caller 
wakes up, ok. 

This does not work with DVB cards because i2c interrupts seem to screw up 
GPIO and/or DEBI interrupts, I don't remember which exactly. 

So DVB cards use polling. The saa7146 transfers 3 bytes of i2c data at a 
time. It seems that if one i2c transfer would take more than 9 bytes to 
transfer ("count" * 3 bytes), then short_delay is set. 

After a chunk of 3 bytes has been written to the saa7146 i2c transfer 
engine, the device must be polled in order to see if the next chunk can be 
written. If short_delay is *not* set, it will uses a msleep(1) to do this 
waiting. The problem is that reading out the status after the transfer has 
just been started always gives "busy". In theory you can calculate the time 
needed to wait by looking at the i2c transmission rate selected. Because you 
usually send only a handful of bytes, this is usually overkill. 

IIRC short_delay was introduced to speed up firmware uploads via i2c. There, 
waiting for 1ms after every 3 bytes will slow down your firmware upload 

> Comments?

Setting SAA7146_I2C_SHORT_DELAY should be ok for every card that uses 
polling. It will only take effect, if more than 9 bytes of i2c data are 
transferred though. I don't know why this limit was chosen. 

> Johannes


More information about the linux-dvb mailing list