[linux-dvb] Linux support for the DigiTV PCI remote controller
Mark Weaver
mark-clist at npsl.co.uk
Sun Sep 18 07:30:07 CEST 2005
With a friend, we did some poking and proding with a multimeter, and it
looks like the IR input (we think it's a photo-transistor as it has a
biasing circuit, didn't have the box to hand) is connected to the
flip-flop's clock. The flip-flop ^S reset is connected to GPIO4 (and it
looks like the ^Q output is connected to GPIO5). The flip-flop appears
to be in there to hold the edge from the photo-transistor, and you then
toggle the reset to get it ready to go again.
I then went at it from the other end, disassembling the Nebula driver.
This, plus some hints from their 'SDK', indicates that INT_VPRES has
somehow been co-opted into triggering when GPIO5 becomes set. Does that
sound feasible? I couldn't really figure it out from the bt878 datasheet.
The interrupt handler then uses the timing to work out which 'bit' we
had and ends up with a 28-bit code (so I guess it's RC5 without decoding
the bi-phase). That code looks like what the windows software uses
internally (i.e. they don't bother to decode it).
The mess below is what I ended up with after reading the disassembly for
a while. It's probably feasible to turn that mess into a remote control
driver, although it looks like bttv-driver.c would have to be hacked up
a bit to punt the VPRES irq on to a sub-driver. If anyone has any
implementation advice, I'd be grateful.
It certainly seems like this card was built with saving cash in mind.
Ta,
Mark
int last_code; // last good code
int last_bit; // last code bit seen
int code; // code under construction
int base_time; // 100ns units
int remote_gap; // 6,000 for nebula remote/8,850 for the other one ?
int wait_30ms;
void int_remote()
{
unsigned int gpio;
int gap;
int time;
// read gpio port
gpio = read_gpio();
// get time of code
time = get_time_100ns();
gap = time - base_time;
if (gap > 2000000) // 200ms timeout
code = 0;
if (gap > 30000) // wait up to 30ms for entire code
wait_30ms = 0;
if (!wait_30ms) {
if (last_bit < 20) { // Short code??
last_code = 0;
} else { // Good code
last_code = code;
}
// Reset for next code
base_time = time;
code = 0;
last_bit = 0;
wait_30ms = 1;
} else if (last_bit < 28) {
// need to be at least 1/2 gap into next interval?
last_bit = (gap - remote_gap / 2) / remote_gap;
code |= 1<<last_bit;
}
// set bit 4 low
write_gpio(gpio & ~(1 << 4));
// set bit 4 high
read_gpio(gpio | (1 << 4));
}
More information about the linux-dvb
mailing list