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)); }