diff options
Diffstat (limited to 'drivers/media/rc/rc-main.c')
-rw-r--r-- | drivers/media/rc/rc-main.c | 138 |
1 files changed, 65 insertions, 73 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 7aaf28bcb01e..f2d3cc450d08 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -30,8 +30,54 @@ #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); @@ -613,6 +659,7 @@ static void ir_timer_keyup(unsigned long cookie) 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); @@ -622,7 +669,7 @@ void rc_repeat(struct rc_dev *dev) 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: @@ -692,7 +739,8 @@ void rc_keydown(struct rc_dev *dev, enum rc_type protocol, u32 scancode, u8 togg 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); @@ -733,33 +781,14 @@ EXPORT_SYMBOL_GPL(rc_keydown_notimeout); 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) @@ -781,14 +810,13 @@ static int rc_validate_filter(struct rc_dev *dev, 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; @@ -1301,40 +1329,6 @@ unlock: 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 @@ -1369,14 +1363,12 @@ static ssize_t show_wakeup_protocols(struct device *device, 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); } } @@ -1418,15 +1410,15 @@ static ssize_t store_wakeup_protocols(struct device *device, 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; } |