[linux-dvb] Ticlkess Mantis remote control implementation

Marko Ristola marko.ristola at kolumbus.fi
Tue Jun 24 21:50:51 CEST 2008


Hi,

I have still my own version of Manu's jusst.de/mantis driver that is 
based on v4l-dvb-linuxtv main branch,
mainly because I use so new Linux kernels.
I have done the following improvement lately:

I implemented a remote control patch, that doesn't poll the remote 
control all the time.
It polls the remote control only if you press the button (a tickless 
version, you know).
It surprised me, that the actual implementation was really small, it 
took very few lines of code.


The idea is, that the remote control informs (thrue irq) 
mantis_query_rc() to be active.
mantis_query_rc takes care that it will reactivate itself after 250ms, 
until remote control
hasn't sent any "user is still pressing a button" messages.

POLL_FREQ (HZ/4) time (250ms) must be more than the remote control 
message interval (230ms).
This way we can ensure that the remote control sends at least one 
message per POLL_FREQ tick.
If on the last POLL_FREQ tick no button is pressed (-1), 
mantis_query_rc() doesn't activate the POLL_FREQ tick
anymore, just informs via ir_input_nokey() that the remote control user 
doesn't press any buttons.

So in this way the remote control works with Twinhan 2033 better than 
ever (the hand experience is good also).
+ Initial key press is delivered instantly.
+ No CPU consumption while the remote control isn't used.
Could possibly be improved with a tasklet, if the instant response 
experience would be that important.
Can be used from 1 to 4 key repeats per second (230ms remote control 
limit is the lower bound, we must be safely above).

Interrupt handler on mantis_pci.c:
        if (stat & MANTIS_INT_IRQ1) {
                mantis->ir.ir_last_code = mmread(0xe8);
                dprintk(verbose, MANTIS_DEBUG, 0, "* INT IRQ-1 *");
                schedule_delayed_work(&mantis->ir.rc_query_work, 0);
        }
 


mantis_rc.c:
#define POLL_FREQ (HZ/4)

void mantis_query_rc(struct work_struct *work)
{
        struct mantis_pci *mantis =
                container_of(work, struct mantis_pci, 
ir.rc_query_work.work);
        struct ir_input_state *ir = &mantis->ir.ir;

        u32 lastkey = mantis->ir.ir_last_code;

        ir_input_nokey(mantis->ir.rc_dev, ir);

        if (lastkey != -1) {
                ir_input_keydown(mantis->ir.rc_dev, ir, lastkey, 0);
                mantis->ir.ir_last_code = -1;
                schedule_delayed_work(&mantis->ir.rc_query_work, POLL_FREQ);
        }
}

int mantis_rc_init(struct mantis_pci *mantis):
        mantis->ir.ir_last_code = -1; /* key presses disabled here. */
        INIT_DELAYED_WORK(&mir->rc_query_work, mantis_query_rc);

int mantis_rc_exit(struct mantis_pci *mantis):

        mmwrite(mmread(MANTIS_INT_MASK) & (~MANTIS_INT_IRQ1), 
MANTIS_INT_MASK);
        mantis->ir.ir_last_code = -1; /* key presses disabled here. */
        cancel_delayed_work_sync(&mantis->ir.rc_query_work); /* not my 
idea */




More information about the linux-dvb mailing list