Mailing List archive

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

[linux-dvb] Re: CX88 i2c issue w/ DVB tuners



Andrew de Quincey wrote:
On Friday 10 Sep 2004 11:02, John Dalgliesh wrote:

On Fri, 10 Sep 2004, Andrew de Quincey wrote:

On Thursday 09 Sep 2004 23:41, Gerd Knorr wrote:

Just hope there isn't a card out there with both DVB AND analogue
tuners on it....
class isn't a value but a bitmask, so you can actually say the card
can do both analog and digital tv ...
Ah right cool. Eurgh, nasty problem waiting down the line when those
cards Holger mentioned appear.
I don't think I understand the condition you are worried about. Do you
mean that the card has to have two separate (i2c-addressable) tuners, one
for analogue and one for digital? Or would a card that has one tuner that
does both like <http://www.dvico.com/products_mul_hd3.html> be a worry?

Just wondering :)

If the card is marked as both analogue and digital, and happens to use one of the i2c addresses which several devices use, you could end up with the wrong i2c device associated with the wrong device - e.g. the tda9987 (analogue tuner) driver was being used incorrectly as the driver for the cx22702 (digtial demodulator) because they both commonly reside at the same i2c address. And theres no way to detect the tda9887 more specifically.

Gah, if only Philips had mandated that all i2c devices must have a unique 32 bit identifier!
The i2c bus is well-designed for this particular purpose, it is the API that does not matches the reality.

i2c devices are usually dumb tiny special chips that do a very special job, which heavily depend on the hardware around them and how everything is wired together. Not really the environment where autoprobing is a good idea.

And there is no urge doing anything so complicated at all: all infrastructure we need are two simple functions for every card's i2c/SPI/8bit-parallel/whatever uC bus:

int card->uC_write(u8 addr, const u8 *buf, int len);
int card->uC_read(u8 addr, u8 *buf, int len);

This is enough to implement the access functions for a particular device:

#define DEVICE_ADDR XXX

static
int device_writereg (u8 reg, u8 val)
{
u8 buf [] = { reg, val };
return card->uC_write(DEVICE_ADDR, buf, sizeof(buf));
}

static
int device_readreg (u8 reg, u8 *val)
{
u8 buf [] = { reg };
int ret;
if ((ret = card->uC_write(DEVICE_ADDR, buf, sizeof(buf))))
return ret;
return card->uC_read(DEVICE_ADDR, val, 1);
}

These function pointers are passed to the frontend_spec struct (e.g. mt312_cardspec) and from there together with the card-specific constants and initialisation tables to the "frontend library" functions.

that's all we need...

Holger




Home | Main Index | Thread Index