|
@@ -633,19 +633,13 @@ EXPORT_SYMBOL_GPL(rc_repeat);
|
|
|
static void ir_do_keydown(struct rc_dev *dev, int scancode,
|
|
|
u32 keycode, u8 toggle)
|
|
|
{
|
|
|
- struct rc_scancode_filter *filter;
|
|
|
- bool new_event = !dev->keypressed ||
|
|
|
- dev->last_scancode != scancode ||
|
|
|
- dev->last_toggle != toggle;
|
|
|
+ bool new_event = (!dev->keypressed ||
|
|
|
+ dev->last_scancode != scancode ||
|
|
|
+ dev->last_toggle != toggle);
|
|
|
|
|
|
if (new_event && dev->keypressed)
|
|
|
ir_do_keyup(dev, false);
|
|
|
|
|
|
- /* Generic scancode filtering */
|
|
|
- filter = &dev->scancode_filters[RC_FILTER_NORMAL];
|
|
|
- if (filter->mask && ((scancode ^ filter->data) & filter->mask))
|
|
|
- return;
|
|
|
-
|
|
|
input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
|
|
|
|
|
|
if (new_event && keycode != KEY_RESERVED) {
|
|
@@ -1011,14 +1005,11 @@ static ssize_t store_protocols(struct device *device,
|
|
|
set_filter = (fattr->type == RC_FILTER_NORMAL)
|
|
|
? dev->s_filter : dev->s_wakeup_filter;
|
|
|
|
|
|
- if (old_type != type && filter->mask) {
|
|
|
+ if (set_filter && old_type != type && filter->mask) {
|
|
|
local_filter = *filter;
|
|
|
if (!type) {
|
|
|
/* no protocol => clear filter */
|
|
|
ret = -1;
|
|
|
- } else if (!set_filter) {
|
|
|
- /* generic filtering => accept any filter */
|
|
|
- ret = 0;
|
|
|
} else {
|
|
|
/* hardware filtering => try setting, otherwise clear */
|
|
|
ret = set_filter(dev, &local_filter);
|
|
@@ -1027,8 +1018,7 @@ static ssize_t store_protocols(struct device *device,
|
|
|
/* clear the filter */
|
|
|
local_filter.data = 0;
|
|
|
local_filter.mask = 0;
|
|
|
- if (set_filter)
|
|
|
- set_filter(dev, &local_filter);
|
|
|
+ set_filter(dev, &local_filter);
|
|
|
}
|
|
|
|
|
|
/* commit the new filter */
|
|
@@ -1072,7 +1062,10 @@ static ssize_t show_filter(struct device *device,
|
|
|
return -EINVAL;
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
- if (fattr->mask)
|
|
|
+ if ((fattr->type == RC_FILTER_NORMAL && !dev->s_filter) ||
|
|
|
+ (fattr->type == RC_FILTER_WAKEUP && !dev->s_wakeup_filter))
|
|
|
+ val = 0;
|
|
|
+ else if (fattr->mask)
|
|
|
val = dev->scancode_filters[fattr->type].mask;
|
|
|
else
|
|
|
val = dev->scancode_filters[fattr->type].data;
|
|
@@ -1120,12 +1113,11 @@ static ssize_t store_filter(struct device *device,
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
|
|
|
+ /* Can the scancode filter be set? */
|
|
|
set_filter = (fattr->type == RC_FILTER_NORMAL) ? dev->s_filter :
|
|
|
dev->s_wakeup_filter;
|
|
|
-
|
|
|
- /* Scancode filter not supported (but still accept 0) */
|
|
|
- if (!set_filter && fattr->type == RC_FILTER_WAKEUP)
|
|
|
- return val ? -EINVAL : count;
|
|
|
+ if (!set_filter)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
@@ -1143,11 +1135,9 @@ static ssize_t store_filter(struct device *device,
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
- if (set_filter) {
|
|
|
- ret = set_filter(dev, &local_filter);
|
|
|
- if (ret < 0)
|
|
|
- goto unlock;
|
|
|
- }
|
|
|
+ ret = set_filter(dev, &local_filter);
|
|
|
+ if (ret < 0)
|
|
|
+ goto unlock;
|
|
|
|
|
|
/* Success, commit the new filter */
|
|
|
*filter = local_filter;
|
|
@@ -1199,27 +1189,45 @@ static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR,
|
|
|
static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR,
|
|
|
show_filter, store_filter, RC_FILTER_WAKEUP, true);
|
|
|
|
|
|
-static struct attribute *rc_dev_attrs[] = {
|
|
|
+static struct attribute *rc_dev_protocol_attrs[] = {
|
|
|
&dev_attr_protocols.attr.attr,
|
|
|
+ NULL,
|
|
|
+};
|
|
|
+
|
|
|
+static struct attribute_group rc_dev_protocol_attr_grp = {
|
|
|
+ .attrs = rc_dev_protocol_attrs,
|
|
|
+};
|
|
|
+
|
|
|
+static struct attribute *rc_dev_wakeup_protocol_attrs[] = {
|
|
|
&dev_attr_wakeup_protocols.attr.attr,
|
|
|
+ NULL,
|
|
|
+};
|
|
|
+
|
|
|
+static struct attribute_group rc_dev_wakeup_protocol_attr_grp = {
|
|
|
+ .attrs = rc_dev_wakeup_protocol_attrs,
|
|
|
+};
|
|
|
+
|
|
|
+static struct attribute *rc_dev_filter_attrs[] = {
|
|
|
&dev_attr_filter.attr.attr,
|
|
|
&dev_attr_filter_mask.attr.attr,
|
|
|
- &dev_attr_wakeup_filter.attr.attr,
|
|
|
- &dev_attr_wakeup_filter_mask.attr.attr,
|
|
|
NULL,
|
|
|
};
|
|
|
|
|
|
-static struct attribute_group rc_dev_attr_grp = {
|
|
|
- .attrs = rc_dev_attrs,
|
|
|
+static struct attribute_group rc_dev_filter_attr_grp = {
|
|
|
+ .attrs = rc_dev_filter_attrs,
|
|
|
};
|
|
|
|
|
|
-static const struct attribute_group *rc_dev_attr_groups[] = {
|
|
|
- &rc_dev_attr_grp,
|
|
|
- NULL
|
|
|
+static struct attribute *rc_dev_wakeup_filter_attrs[] = {
|
|
|
+ &dev_attr_wakeup_filter.attr.attr,
|
|
|
+ &dev_attr_wakeup_filter_mask.attr.attr,
|
|
|
+ NULL,
|
|
|
+};
|
|
|
+
|
|
|
+static struct attribute_group rc_dev_wakeup_filter_attr_grp = {
|
|
|
+ .attrs = rc_dev_wakeup_filter_attrs,
|
|
|
};
|
|
|
|
|
|
static struct device_type rc_dev_type = {
|
|
|
- .groups = rc_dev_attr_groups,
|
|
|
.release = rc_dev_release,
|
|
|
.uevent = rc_dev_uevent,
|
|
|
};
|
|
@@ -1276,7 +1284,7 @@ int rc_register_device(struct rc_dev *dev)
|
|
|
static bool raw_init = false; /* raw decoders loaded? */
|
|
|
struct rc_map *rc_map;
|
|
|
const char *path;
|
|
|
- int rc, devno;
|
|
|
+ int rc, devno, attr = 0;
|
|
|
|
|
|
if (!dev || !dev->map_name)
|
|
|
return -EINVAL;
|
|
@@ -1304,6 +1312,16 @@ int rc_register_device(struct rc_dev *dev)
|
|
|
return -ENOMEM;
|
|
|
} while (test_and_set_bit(devno, ir_core_dev_number));
|
|
|
|
|
|
+ dev->dev.groups = dev->sysfs_groups;
|
|
|
+ dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp;
|
|
|
+ if (dev->s_filter)
|
|
|
+ dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp;
|
|
|
+ if (dev->s_wakeup_filter)
|
|
|
+ dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp;
|
|
|
+ if (dev->change_wakeup_protocol)
|
|
|
+ dev->sysfs_groups[attr++] = &rc_dev_wakeup_protocol_attr_grp;
|
|
|
+ dev->sysfs_groups[attr++] = NULL;
|
|
|
+
|
|
|
/*
|
|
|
* Take the lock here, as the device sysfs node will appear
|
|
|
* when device_add() is called, which may trigger an ir-keytable udev
|