diff options
| -rw-r--r-- | drivers/media/rc/rc-main.c | 88 | ||||
| -rw-r--r-- | include/media/rc-core.h | 2 |
2 files changed, 55 insertions, 35 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index ecbc20c4252e..970b93d6f399 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c | |||
| @@ -633,19 +633,13 @@ EXPORT_SYMBOL_GPL(rc_repeat); | |||
| 633 | static void ir_do_keydown(struct rc_dev *dev, int scancode, | 633 | static void ir_do_keydown(struct rc_dev *dev, int scancode, |
| 634 | u32 keycode, u8 toggle) | 634 | u32 keycode, u8 toggle) |
| 635 | { | 635 | { |
| 636 | struct rc_scancode_filter *filter; | 636 | bool new_event = (!dev->keypressed || |
| 637 | bool new_event = !dev->keypressed || | 637 | dev->last_scancode != scancode || |
| 638 | dev->last_scancode != scancode || | 638 | dev->last_toggle != toggle); |
| 639 | dev->last_toggle != toggle; | ||
| 640 | 639 | ||
| 641 | if (new_event && dev->keypressed) | 640 | if (new_event && dev->keypressed) |
| 642 | ir_do_keyup(dev, false); | 641 | ir_do_keyup(dev, false); |
| 643 | 642 | ||
| 644 | /* Generic scancode filtering */ | ||
| 645 | filter = &dev->scancode_filters[RC_FILTER_NORMAL]; | ||
| 646 | if (filter->mask && ((scancode ^ filter->data) & filter->mask)) | ||
| 647 | return; | ||
| 648 | |||
| 649 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); | 643 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); |
| 650 | 644 | ||
| 651 | if (new_event && keycode != KEY_RESERVED) { | 645 | if (new_event && keycode != KEY_RESERVED) { |
| @@ -1011,14 +1005,11 @@ static ssize_t store_protocols(struct device *device, | |||
| 1011 | set_filter = (fattr->type == RC_FILTER_NORMAL) | 1005 | set_filter = (fattr->type == RC_FILTER_NORMAL) |
| 1012 | ? dev->s_filter : dev->s_wakeup_filter; | 1006 | ? dev->s_filter : dev->s_wakeup_filter; |
| 1013 | 1007 | ||
| 1014 | if (old_type != type && filter->mask) { | 1008 | if (set_filter && old_type != type && filter->mask) { |
| 1015 | local_filter = *filter; | 1009 | local_filter = *filter; |
| 1016 | if (!type) { | 1010 | if (!type) { |
| 1017 | /* no protocol => clear filter */ | 1011 | /* no protocol => clear filter */ |
| 1018 | ret = -1; | 1012 | ret = -1; |
| 1019 | } else if (!set_filter) { | ||
| 1020 | /* generic filtering => accept any filter */ | ||
| 1021 | ret = 0; | ||
| 1022 | } else { | 1013 | } else { |
| 1023 | /* hardware filtering => try setting, otherwise clear */ | 1014 | /* hardware filtering => try setting, otherwise clear */ |
| 1024 | ret = set_filter(dev, &local_filter); | 1015 | ret = set_filter(dev, &local_filter); |
| @@ -1027,8 +1018,7 @@ static ssize_t store_protocols(struct device *device, | |||
| 1027 | /* clear the filter */ | 1018 | /* clear the filter */ |
| 1028 | local_filter.data = 0; | 1019 | local_filter.data = 0; |
| 1029 | local_filter.mask = 0; | 1020 | local_filter.mask = 0; |
| 1030 | if (set_filter) | 1021 | set_filter(dev, &local_filter); |
| 1031 | set_filter(dev, &local_filter); | ||
| 1032 | } | 1022 | } |
| 1033 | 1023 | ||
| 1034 | /* commit the new filter */ | 1024 | /* commit the new filter */ |
| @@ -1072,7 +1062,10 @@ static ssize_t show_filter(struct device *device, | |||
| 1072 | return -EINVAL; | 1062 | return -EINVAL; |
| 1073 | 1063 | ||
| 1074 | mutex_lock(&dev->lock); | 1064 | mutex_lock(&dev->lock); |
| 1075 | if (fattr->mask) | 1065 | if ((fattr->type == RC_FILTER_NORMAL && !dev->s_filter) || |
| 1066 | (fattr->type == RC_FILTER_WAKEUP && !dev->s_wakeup_filter)) | ||
| 1067 | val = 0; | ||
| 1068 | else if (fattr->mask) | ||
| 1076 | val = dev->scancode_filters[fattr->type].mask; | 1069 | val = dev->scancode_filters[fattr->type].mask; |
| 1077 | else | 1070 | else |
| 1078 | val = dev->scancode_filters[fattr->type].data; | 1071 | val = dev->scancode_filters[fattr->type].data; |
| @@ -1120,12 +1113,11 @@ static ssize_t store_filter(struct device *device, | |||
| 1120 | if (ret < 0) | 1113 | if (ret < 0) |
| 1121 | return ret; | 1114 | return ret; |
| 1122 | 1115 | ||
| 1116 | /* Can the scancode filter be set? */ | ||
| 1123 | set_filter = (fattr->type == RC_FILTER_NORMAL) ? dev->s_filter : | 1117 | set_filter = (fattr->type == RC_FILTER_NORMAL) ? dev->s_filter : |
| 1124 | dev->s_wakeup_filter; | 1118 | dev->s_wakeup_filter; |
| 1125 | 1119 | if (!set_filter) | |
| 1126 | /* Scancode filter not supported (but still accept 0) */ | 1120 | return -EINVAL; |
| 1127 | if (!set_filter && fattr->type == RC_FILTER_WAKEUP) | ||
| 1128 | return val ? -EINVAL : count; | ||
| 1129 | 1121 | ||
| 1130 | mutex_lock(&dev->lock); | 1122 | mutex_lock(&dev->lock); |
| 1131 | 1123 | ||
| @@ -1143,11 +1135,9 @@ static ssize_t store_filter(struct device *device, | |||
| 1143 | goto unlock; | 1135 | goto unlock; |
| 1144 | } | 1136 | } |
| 1145 | 1137 | ||
| 1146 | if (set_filter) { | 1138 | ret = set_filter(dev, &local_filter); |
| 1147 | ret = set_filter(dev, &local_filter); | 1139 | if (ret < 0) |
| 1148 | if (ret < 0) | 1140 | goto unlock; |
| 1149 | goto unlock; | ||
| 1150 | } | ||
| 1151 | 1141 | ||
| 1152 | /* Success, commit the new filter */ | 1142 | /* Success, commit the new filter */ |
| 1153 | *filter = local_filter; | 1143 | *filter = local_filter; |
| @@ -1199,27 +1189,45 @@ static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR, | |||
| 1199 | static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, | 1189 | static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, |
| 1200 | show_filter, store_filter, RC_FILTER_WAKEUP, true); | 1190 | show_filter, store_filter, RC_FILTER_WAKEUP, true); |
| 1201 | 1191 | ||
| 1202 | static struct attribute *rc_dev_attrs[] = { | 1192 | static struct attribute *rc_dev_protocol_attrs[] = { |
| 1203 | &dev_attr_protocols.attr.attr, | 1193 | &dev_attr_protocols.attr.attr, |
| 1194 | NULL, | ||
| 1195 | }; | ||
| 1196 | |||
| 1197 | static struct attribute_group rc_dev_protocol_attr_grp = { | ||
| 1198 | .attrs = rc_dev_protocol_attrs, | ||
| 1199 | }; | ||
| 1200 | |||
| 1201 | static struct attribute *rc_dev_wakeup_protocol_attrs[] = { | ||
| 1204 | &dev_attr_wakeup_protocols.attr.attr, | 1202 | &dev_attr_wakeup_protocols.attr.attr, |
| 1203 | NULL, | ||
| 1204 | }; | ||
| 1205 | |||
| 1206 | static struct attribute_group rc_dev_wakeup_protocol_attr_grp = { | ||
| 1207 | .attrs = rc_dev_wakeup_protocol_attrs, | ||
| 1208 | }; | ||
| 1209 | |||
| 1210 | static struct attribute *rc_dev_filter_attrs[] = { | ||
| 1205 | &dev_attr_filter.attr.attr, | 1211 | &dev_attr_filter.attr.attr, |
| 1206 | &dev_attr_filter_mask.attr.attr, | 1212 | &dev_attr_filter_mask.attr.attr, |
| 1207 | &dev_attr_wakeup_filter.attr.attr, | ||
| 1208 | &dev_attr_wakeup_filter_mask.attr.attr, | ||
| 1209 | NULL, | 1213 | NULL, |
| 1210 | }; | 1214 | }; |
| 1211 | 1215 | ||
| 1212 | static struct attribute_group rc_dev_attr_grp = { | 1216 | static struct attribute_group rc_dev_filter_attr_grp = { |
| 1213 | .attrs = rc_dev_attrs, | 1217 | .attrs = rc_dev_filter_attrs, |
| 1214 | }; | 1218 | }; |
| 1215 | 1219 | ||
| 1216 | static const struct attribute_group *rc_dev_attr_groups[] = { | 1220 | static struct attribute *rc_dev_wakeup_filter_attrs[] = { |
| 1217 | &rc_dev_attr_grp, | 1221 | &dev_attr_wakeup_filter.attr.attr, |
| 1218 | NULL | 1222 | &dev_attr_wakeup_filter_mask.attr.attr, |
| 1223 | NULL, | ||
| 1224 | }; | ||
| 1225 | |||
| 1226 | static struct attribute_group rc_dev_wakeup_filter_attr_grp = { | ||
| 1227 | .attrs = rc_dev_wakeup_filter_attrs, | ||
| 1219 | }; | 1228 | }; |
| 1220 | 1229 | ||
| 1221 | static struct device_type rc_dev_type = { | 1230 | static struct device_type rc_dev_type = { |
| 1222 | .groups = rc_dev_attr_groups, | ||
| 1223 | .release = rc_dev_release, | 1231 | .release = rc_dev_release, |
| 1224 | .uevent = rc_dev_uevent, | 1232 | .uevent = rc_dev_uevent, |
| 1225 | }; | 1233 | }; |
| @@ -1276,7 +1284,7 @@ int rc_register_device(struct rc_dev *dev) | |||
| 1276 | static bool raw_init = false; /* raw decoders loaded? */ | 1284 | static bool raw_init = false; /* raw decoders loaded? */ |
| 1277 | struct rc_map *rc_map; | 1285 | struct rc_map *rc_map; |
| 1278 | const char *path; | 1286 | const char *path; |
| 1279 | int rc, devno; | 1287 | int rc, devno, attr = 0; |
| 1280 | 1288 | ||
| 1281 | if (!dev || !dev->map_name) | 1289 | if (!dev || !dev->map_name) |
| 1282 | return -EINVAL; | 1290 | return -EINVAL; |
| @@ -1304,6 +1312,16 @@ int rc_register_device(struct rc_dev *dev) | |||
| 1304 | return -ENOMEM; | 1312 | return -ENOMEM; |
| 1305 | } while (test_and_set_bit(devno, ir_core_dev_number)); | 1313 | } while (test_and_set_bit(devno, ir_core_dev_number)); |
| 1306 | 1314 | ||
| 1315 | dev->dev.groups = dev->sysfs_groups; | ||
| 1316 | dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp; | ||
| 1317 | if (dev->s_filter) | ||
| 1318 | dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp; | ||
| 1319 | if (dev->s_wakeup_filter) | ||
| 1320 | dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp; | ||
| 1321 | if (dev->change_wakeup_protocol) | ||
