Set the EV_REP bit, so reported key repeats actually make their
way out to userspace, and fix up the handling of repeats a bit,
routines for which are shamelessly heisted from ati_remote2.c.

Signed-off-by: Jarod Wilson <ja...@redhat.com>
---
 drivers/media/IR/imon.c |   38 +++++++++++++++++++++++++++++++-------
 1 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
index b65c31a..16e2e7f 100644
--- a/drivers/media/IR/imon.c
+++ b/drivers/media/IR/imon.c
@@ -130,6 +130,7 @@ struct imon_context {
        u64 ir_type;                    /* iMON or MCE (RC6) IR protocol? */
        u8 mce_toggle_bit;              /* last mce toggle bit */
        bool release_code;              /* some keys send a release code */
+       unsigned long jiffies;          /* repeat timer */
 
        u8 display_type;                /* store the display type */
        bool pad_mouse;                 /* toggle kbd(0)/mouse(1) mode */
@@ -146,7 +147,6 @@ struct imon_context {
 };
 
 #define TOUCH_TIMEOUT  (HZ/30)
-#define MCE_TIMEOUT_MS 200
 
 /* vfd character device file operations */
 static const struct file_operations vfd_fops = {
@@ -1394,6 +1394,8 @@ static int imon_parse_press_type(struct imon_context 
*ictx,
                                 unsigned char *buf, u8 ktype)
 {
        int press_type = 0;
+       int rep_delay = ictx->idev->rep[REP_DELAY];
+       int rep_period = ictx->idev->rep[REP_PERIOD];
 
        /* key release of 0x02XXXXXX key */
        if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00)
@@ -1418,12 +1420,12 @@ static int imon_parse_press_type(struct imon_context 
*ictx,
                        ictx->mce_toggle_bit = buf[2];
                        press_type = 1;
                        mod_timer(&ictx->itimer,
-                                 jiffies + msecs_to_jiffies(MCE_TIMEOUT_MS));
+                                 jiffies + msecs_to_jiffies(rep_delay));
                /* repeat */
                } else {
                        press_type = 2;
                        mod_timer(&ictx->itimer,
-                                 jiffies + msecs_to_jiffies(MCE_TIMEOUT_MS));
+                                 jiffies + msecs_to_jiffies(rep_period));
                }
 
        /* incoherent or irrelevant data */
@@ -1458,12 +1460,14 @@ static void imon_incoming_packet(struct imon_context 
*ictx,
        u32 remote_key = 0;
        struct input_dev *idev = NULL;
        int press_type = 0;
-       int msec;
+       int msec, rep_delay, rep_period;
        struct timeval t;
        static struct timeval prev_time = { 0, 0 };
        u8 ktype = IMON_KEY_IMON;
 
        idev = ictx->idev;
+       rep_delay = idev->rep[REP_DELAY];
+       rep_period = idev->rep[REP_PERIOD];
 
        /* filter out junk data on the older 0xffdc imon devices */
        if ((buf[0] == 0xff) && (buf[7] == 0xff))
@@ -1529,8 +1533,28 @@ static void imon_incoming_packet(struct imon_context 
*ictx,
        }
 
        press_type = imon_parse_press_type(ictx, buf, ktype);
-       if (press_type < 0)
+
+       switch (press_type) {
+       /* release */
+       case 0:
+               break;
+       /* press */
+       case 1:
+               ictx->jiffies = jiffies + msecs_to_jiffies(rep_delay);
+               break;
+       /* repeat */
+       case 2:
+               /* don't repeat too fast */
+               if (!time_after_eq(jiffies, ictx->jiffies))
+                       return;
+
+               ictx->jiffies = jiffies + msecs_to_jiffies(rep_period);
+               break;
+       case -EINVAL:
+       default:
                goto not_input_data;
+               break;
+       }
 
        if (ictx->kc == KEY_UNKNOWN)
                goto unknown_key;
@@ -1541,7 +1565,7 @@ static void imon_incoming_packet(struct imon_context 
*ictx,
                do_gettimeofday(&t);
                msec = tv2int(&t, &prev_time);
                prev_time = t;
-               if (msec < 200)
+               if (msec < rep_delay)
                        return;
        }
 
@@ -1686,7 +1710,7 @@ static struct input_dev *imon_init_idev(struct 
imon_context *ictx)
        strlcat(ictx->phys_idev, "/input0", sizeof(ictx->phys_idev));
        idev->phys = ictx->phys_idev;
 
-       idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);
 
        idev->keybit[BIT_WORD(BTN_MOUSE)] =
                BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);

-- 
Jarod Wilson
ja...@redhat.com

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to