aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2014-02-28 18:17:02 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-11 12:21:40 -0400
commitb8c7d915087c97a21fa415fa0e860e59739da202 (patch)
tree912e3c9296f0ecd70ea024c3bd2ca7955f7af2e3 /drivers/media/rc
parentc3c2077d9579472b07581ecdaf6cc5a60b1700bc (diff)
[media] rc-main: add generic scancode filtering
Add generic scancode filtering of RC input events, and fall back to permitting any RC_FILTER_NORMAL scancode filter to be set if no s_filter callback exists. This allows raw IR decoder events to be filtered, and potentially allows hardware decoders to set looser filters and rely on generic code to filter out the corner cases. Signed-off-by: James Hogan <james.hogan@imgtec.com> Reviewed-by: Antti Seppälä <a.seppala@gmail.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/rc')
-rw-r--r--drivers/media/rc/rc-main.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 64481289c98e..0a4f680f6f67 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -633,6 +633,7 @@ EXPORT_SYMBOL_GPL(rc_repeat);
633static void ir_do_keydown(struct rc_dev *dev, int scancode, 633static 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,6 +641,11 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode,
640 if (new_event && dev->keypressed) 641 if (new_event && dev->keypressed)
641 ir_do_keyup(dev, false); 642 ir_do_keyup(dev, false);
642 643
644 /* Generic scancode filtering */
645 filter = &dev->scancode_filters[RC_FILTER_NORMAL];
646 if (filter->mask && ((scancode ^ filter->data) & filter->mask))
647 return;
648
643 input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); 649 input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
644 650
645 if (new_event && keycode != KEY_RESERVED) { 651 if (new_event && keycode != KEY_RESERVED) {
@@ -1019,9 +1025,7 @@ static ssize_t show_filter(struct device *device,
1019 return -EINVAL; 1025 return -EINVAL;
1020 1026
1021 mutex_lock(&dev->lock); 1027 mutex_lock(&dev->lock);
1022 if (!dev->s_filter) 1028 if (fattr->mask)
1023 val = 0;
1024 else if (fattr->mask)
1025 val = dev->scancode_filters[fattr->type].mask; 1029 val = dev->scancode_filters[fattr->type].mask;
1026 else 1030 else
1027 val = dev->scancode_filters[fattr->type].data; 1031 val = dev->scancode_filters[fattr->type].data;
@@ -1069,7 +1073,7 @@ static ssize_t store_filter(struct device *device,
1069 return ret; 1073 return ret;
1070 1074
1071 /* Scancode filter not supported (but still accept 0) */ 1075 /* Scancode filter not supported (but still accept 0) */
1072 if (!dev->s_filter) 1076 if (!dev->s_filter && fattr->type != RC_FILTER_NORMAL)
1073 return val ? -EINVAL : count; 1077 return val ? -EINVAL : count;
1074 1078
1075 mutex_lock(&dev->lock); 1079 mutex_lock(&dev->lock);
@@ -1081,9 +1085,11 @@ static ssize_t store_filter(struct device *device,
1081 local_filter.mask = val; 1085 local_filter.mask = val;
1082 else 1086 else
1083 local_filter.data = val; 1087 local_filter.data = val;
1084 ret = dev->s_filter(dev, fattr->type, &local_filter); 1088 if (dev->s_filter) {
1085 if (ret < 0) 1089 ret = dev->s_filter(dev, fattr->type, &local_filter);
1086 goto unlock; 1090 if (ret < 0)
1091 goto unlock;
1092 }
1087 1093
1088 /* Success, commit the new filter */ 1094 /* Success, commit the new filter */
1089 *filter = local_filter; 1095 *filter = local_filter;