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