[linux-dvb] cx24110 driver question/problem

Johannes Stezenbach js at linuxtv.org
Tue Jul 19 22:41:01 CEST 2005

Peter Hettkamp wrote:
> On Sun, Jul 17, 2005 at 10:49:57PM +0200, Johannes Stezenbach wrote:
> > On Sun, Jul 17, 2005 Andreas Oberritter wrote:
> > > On Sun, 2005-07-17 at 16:03 +0200, Peter Hettkamp wrote:
> > > > - The best solution might be to only store the requested burst command on a
> > > > call to send_burst, and include the correct burst bit in the start_diseqc
> > > > sequence in send_msg. This would, however, require applications that want to
> > > > send bursts do do so before calling send_msg,
> > 
> > That's not good, because the DiSEqC spec requires the burst to be
> > sent after the DiSEqC message, so usually apps do it that way
> > (in VDR one can configure it, though).
> Ok, then it has to be done the other way round... store the message from
> send_msg, then send both the (stored) message ant the burst on the call to
> send_burst. Will send_burst be called by every application?

Nope. VDR lets you configure it away so if you don't have legacy
equipment which needs the burst you can save a few milliseconds
tuning time.
There could also be more than one DiSEqC message, e.g. if you have
multiple, cascaded switches.

> With the cx24110, hardware can handle both the sending of DiSEqC 1.1 and the
> tone burst. The voltage and continuous tone can be set at any time. When the
> DiSEqC handling circuitry is started, it does all of these things:
> 1.) The continuous tone is stopped (if present) and the voltage is switched
> if necessary (*)
> 2.) After 15ms of silence, the DiSEqC message is sent (unless suppressed by
> setting bit 2 of 0x77...). Possibly, more than one message or messages
> longer than 6 bytes can be sent (will need additional code though).
> 3.) After another 15ms of silence, a 12.5ms tone burst, either modulated or
> unmodulated, then again 15 ms of silence, then the continuous tone is
> switched on again.
> This basically means that when this sequence is triggered, ALL the
> information needs to be present.
> So, WHEN do I start the output of the DiSEqC sequence? On a call to
> send_msg, to send_burst, both, or on some other ioctl?

I think if the approach you implented so for could be made to
work it would be the best. From the description you gave so far
it sounds like that it should work.

> > That sounds a bit ugly. I cleaner solution would be to
> > go a few years back and add something like SEC_SEND_SEQUENCE from
> > http://linuxtv.org/cgi-bin/viewcvs.cgi/DVB/ost/include/ost/Attic/sec.h?rev=1.3&hideattic=0&view=auto
> I would hate to change the existing API (there probably WAS a good reason to
> discard SEC_SEND_SEQUENCE in favor of the separate ioctls, wasn't it?), but
> I am somewhat at a loss how to do it correctly with the current API.

Yeah, I wasn't serious about this, only that retrospectively it
would've been better to keep that API and not mess with it.
(The old API also took care of proper timing, currently it's
the task of the application to insert the proper sleeps as
required by the DiSEqC spec.)

> If the lines are left in, the line in send_msg will have to be changed to
> &~0x04 in any case.
> IF applications always call send_msg first and send_burst second, or not at
> all, AND messages are always less than 7 bytes long, removing both sets of
> lines will actually bring on a correct result:
> - on the call to send_msg all registers except the type of burst to be sent
> will be set up correctly and should be left behind in a correct state for
> re-sending the same message again.
> - on the call to send_burst, the burst bit will be set to the correct value
> and the whole sequence will be repeated. As Adam's experience shows, this
> seems to output the complete message again
> - if DiSEqC messages of seven or more bytes need to be sent, the current code
> cannot handle it anyways.
> Therefore, if nobody objects to it, please remove the lines (or enclose
> them with #if 0) and we shall see what happens next.

Isn't there a bit in reg 0x77 to suppress the burst?

In any rate I would keep the rv | 0x04 in cx24110_diseqc_send_burst
to NOT send a DiSEqC message, but just the burst. With
rv & ~0x04 in cx24110_send_diseqc_msg() the DiSEqC message
will be sent (followed by a bogus burst, but wtf), which should
fix the problem for Adam.


BTW, the loop:
	for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; )
		; /* wait for LNB ready */

hammers mercilessly on the i2c bus, it might be worth to
add an msleep(1) and descrease i to 13 resp. 100 (burst
lenght is 12.5ms, DiSEqC msg is 54ms typically but depends on the
message), or not?

Index: drivers/media/dvb/frontends/cx24110.c
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/cx24110.c,v
retrieving revision 1.26
diff -u -p -r1.26 cx24110.c
--- drivers/media/dvb/frontends/cx24110.c	17 Jul 2005 20:56:25 -0000	1.26
+++ drivers/media/dvb/frontends/cx24110.c	19 Jul 2005 20:27:48 -0000
@@ -398,7 +398,7 @@ static int cx24110_diseqc_send_burst(str
 		return -EINVAL;
 	rv = cx24110_readreg(state, 0x77);
-	cx24110_writereg(state, 0x77, rv|0x04);
+	cx24110_writereg(state, 0x77, rv | 0x04);	// suppress DiSEqC msg
 	rv = cx24110_readreg(state, 0x76);
 	cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
@@ -418,7 +418,7 @@ static int cx24110_send_diseqc_msg(struc
 		cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
 	rv = cx24110_readreg(state, 0x77);
-	cx24110_writereg(state, 0x77, rv|0x04);
+	cx24110_writereg(state, 0x77, rv & ~0x04);	// enable DiSEqC msg
 	rv = cx24110_readreg(state, 0x76);


More information about the linux-dvb mailing list