#define IR_TAB_MAX_SIZE        8192
 #define RC_DEV_MAX     256
 
-/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
-#define IR_KEYPRESS_TIMEOUT 250
+static const struct {
+       const char *name;
+       unsigned int repeat_period;
+       unsigned int scancode_bits;
+} protocols[] = {
+       [RC_TYPE_UNKNOWN] = { .name = "unknown", .repeat_period = 250 },
+       [RC_TYPE_OTHER] = { .name = "other", .repeat_period = 250 },
+       [RC_TYPE_RC5] = { .name = "rc-5",
+               .scancode_bits = 0x1f7f, .repeat_period = 164 },
+       [RC_TYPE_RC5X_20] = { .name = "rc-5x-20",
+               .scancode_bits = 0x1f7f3f, .repeat_period = 164 },
+       [RC_TYPE_RC5_SZ] = { .name = "rc-5-sz",
+               .scancode_bits = 0x2fff, .repeat_period = 164 },
+       [RC_TYPE_JVC] = { .name = "jvc",
+               .scancode_bits = 0xffff, .repeat_period = 250 },
+       [RC_TYPE_SONY12] = { .name = "sony-12",
+               .scancode_bits = 0x1f007f, .repeat_period = 100 },
+       [RC_TYPE_SONY15] = { .name = "sony-15",
+               .scancode_bits = 0xff007f, .repeat_period = 100 },
+       [RC_TYPE_SONY20] = { .name = "sony-20",
+               .scancode_bits = 0x1fff7f, .repeat_period = 100 },
+       [RC_TYPE_NEC] = { .name = "nec",
+               .scancode_bits = 0xffff, .repeat_period = 160 },
+       [RC_TYPE_NECX] = { .name = "nec-x",
+               .scancode_bits = 0xffffff, .repeat_period = 160 },
+       [RC_TYPE_NEC32] = { .name = "nec-32",
+               .scancode_bits = 0xffffffff, .repeat_period = 160 },
+       [RC_TYPE_SANYO] = { .name = "sanyo",
+               .scancode_bits = 0x1fffff, .repeat_period = 250 },
+       [RC_TYPE_MCIR2_KBD] = { .name = "mcir2-kbd",
+               .scancode_bits = 0xffff, .repeat_period = 150 },
+       [RC_TYPE_MCIR2_MSE] = { .name = "mcir2-mse",
+               .scancode_bits = 0x1fffff, .repeat_period = 150 },
+       [RC_TYPE_RC6_0] = { .name = "rc-6-0",
+               .scancode_bits = 0xffff, .repeat_period = 164 },
+       [RC_TYPE_RC6_6A_20] = { .name = "rc-6-6a-20",
+               .scancode_bits = 0xfffff, .repeat_period = 164 },
+       [RC_TYPE_RC6_6A_24] = { .name = "rc-6-6a-24",
+               .scancode_bits = 0xffffff, .repeat_period = 164 },
+       [RC_TYPE_RC6_6A_32] = { .name = "rc-6-6a-32",
+               .scancode_bits = 0xffffffff, .repeat_period = 164 },
+       [RC_TYPE_RC6_MCE] = { .name = "rc-6-mce",
+               .scancode_bits = 0xffff7fff, .repeat_period = 164 },
+       [RC_TYPE_SHARP] = { .name = "sharp",
+               .scancode_bits = 0x1fff, .repeat_period = 250 },
+       [RC_TYPE_XMP] = { .name = "xmp", .repeat_period = 250 },
+       [RC_TYPE_CEC] = { .name = "cec", .repeat_period = 550 },
+};
 
 /* Used to keep track of known keymaps */
 static LIST_HEAD(rc_map_list);
 void rc_repeat(struct rc_dev *dev)
 {
        unsigned long flags;
+       unsigned int timeout = protocols[dev->last_protocol].repeat_period;
 
        spin_lock_irqsave(&dev->keylock, flags);
 
        input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
        input_sync(dev->input_dev);
 
-       dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
+       dev->keyup_jiffies = jiffies + msecs_to_jiffies(timeout);
        mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
 
 out:
        ir_do_keydown(dev, protocol, scancode, keycode, toggle);
 
        if (dev->keypressed) {
-               dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
+               dev->keyup_jiffies = jiffies +
+                       msecs_to_jiffies(protocols[protocol].repeat_period);
                mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
        }
        spin_unlock_irqrestore(&dev->keylock, flags);
 static int rc_validate_filter(struct rc_dev *dev,
                              struct rc_scancode_filter *filter)
 {
-       static const u32 masks[] = {
-               [RC_TYPE_RC5] = 0x1f7f,
-               [RC_TYPE_RC5X_20] = 0x1f7f3f,
-               [RC_TYPE_RC5_SZ] = 0x2fff,
-               [RC_TYPE_SONY12] = 0x1f007f,
-               [RC_TYPE_SONY15] = 0xff007f,
-               [RC_TYPE_SONY20] = 0x1fff7f,
-               [RC_TYPE_JVC] = 0xffff,
-               [RC_TYPE_NEC] = 0xffff,
-               [RC_TYPE_NECX] = 0xffffff,
-               [RC_TYPE_NEC32] = 0xffffffff,
-               [RC_TYPE_SANYO] = 0x1fffff,
-               [RC_TYPE_MCIR2_KBD] = 0xffff,
-               [RC_TYPE_MCIR2_MSE] = 0x1fffff,
-               [RC_TYPE_RC6_0] = 0xffff,
-               [RC_TYPE_RC6_6A_20] = 0xfffff,
-               [RC_TYPE_RC6_6A_24] = 0xffffff,
-               [RC_TYPE_RC6_6A_32] = 0xffffffff,
-               [RC_TYPE_RC6_MCE] = 0xffff7fff,
-               [RC_TYPE_SHARP] = 0x1fff,
-       };
-       u32 s = filter->data;
+       u32 mask, s = filter->data;
        enum rc_type protocol = dev->wakeup_protocol;
 
-       if (protocol >= ARRAY_SIZE(masks))
+       if (protocol >= ARRAY_SIZE(protocols))
                return -EINVAL;
 
+       mask = protocols[protocol].scancode_bits;
+
        switch (protocol) {
        case RC_TYPE_NECX:
                if ((((s >> 16) ^ ~(s >> 8)) & 0xff) == 0)
                break;
        }
 
-       filter->data &= masks[protocol];
-       filter->mask &= masks[protocol];
+       filter->data &= mask;
+       filter->mask &= mask;
 
        /*
         * If we have to raw encode the IR for wakeup, we cannot have a mask
         */
-       if (dev->encode_wakeup &&
-           filter->mask != 0 && filter->mask != masks[protocol])
+       if (dev->encode_wakeup && filter->mask != 0 && filter->mask != mask)
                return -EINVAL;
 
        return 0;
        return (ret < 0) ? ret : len;
 }
 
-/*
- * This is the list of all variants of all protocols, which is used by
- * the wakeup_protocols sysfs entry. In the protocols sysfs entry some
- * some protocols are grouped together (e.g. nec = nec + necx + nec32).
- *
- * For wakeup we need to know the exact protocol variant so the hardware
- * can be programmed exactly what to expect.
- */
-static const char * const proto_variant_names[] = {
-       [RC_TYPE_UNKNOWN] = "unknown",
-       [RC_TYPE_OTHER] = "other",
-       [RC_TYPE_RC5] = "rc-5",
-       [RC_TYPE_RC5X_20] = "rc-5x-20",
-       [RC_TYPE_RC5_SZ] = "rc-5-sz",
-       [RC_TYPE_JVC] = "jvc",
-       [RC_TYPE_SONY12] = "sony-12",
-       [RC_TYPE_SONY15] = "sony-15",
-       [RC_TYPE_SONY20] = "sony-20",
-       [RC_TYPE_NEC] = "nec",
-       [RC_TYPE_NECX] = "nec-x",
-       [RC_TYPE_NEC32] = "nec-32",
-       [RC_TYPE_SANYO] = "sanyo",
-       [RC_TYPE_MCIR2_KBD] = "mcir2-kbd",
-       [RC_TYPE_MCIR2_MSE] = "mcir2-mse",
-       [RC_TYPE_RC6_0] = "rc-6-0",
-       [RC_TYPE_RC6_6A_20] = "rc-6-6a-20",
-       [RC_TYPE_RC6_6A_24] = "rc-6-6a-24",
-       [RC_TYPE_RC6_6A_32] = "rc-6-6a-32",
-       [RC_TYPE_RC6_MCE] = "rc-6-mce",
-       [RC_TYPE_SHARP] = "sharp",
-       [RC_TYPE_XMP] = "xmp",
-       [RC_TYPE_CEC] = "cec",
-};
-
 /**
  * show_wakeup_protocols() - shows the wakeup IR protocol
  * @device:    the device descriptor
        IR_dprintk(1, "%s: allowed - 0x%llx, enabled - %d\n",
                   __func__, (long long)allowed, enabled);
 
-       for (i = 0; i < ARRAY_SIZE(proto_variant_names); i++) {
+       for (i = 0; i < ARRAY_SIZE(protocols); i++) {
                if (allowed & (1ULL << i)) {
                        if (i == enabled)
-                               tmp += sprintf(tmp, "[%s] ",
-                                               proto_variant_names[i]);
+                               tmp += sprintf(tmp, "[%s] ", protocols[i].name);
                        else
-                               tmp += sprintf(tmp, "%s ",
-                                               proto_variant_names[i]);
+                               tmp += sprintf(tmp, "%s ", protocols[i].name);
                }
        }
 
        if (sysfs_streq(buf, "none")) {
                protocol = RC_TYPE_UNKNOWN;
        } else {
-               for (i = 0; i < ARRAY_SIZE(proto_variant_names); i++) {
+               for (i = 0; i < ARRAY_SIZE(protocols); i++) {
                        if ((allowed & (1ULL << i)) &&
-                           sysfs_streq(buf, proto_variant_names[i])) {
+                           sysfs_streq(buf, protocols[i].name)) {
                                protocol = i;
                                break;
                        }
                }
 
-               if (i == ARRAY_SIZE(proto_variant_names)) {
+               if (i == ARRAY_SIZE(protocols)) {
                        rc = -EINVAL;
                        goto out;
                }