summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2014-03-01 03:17:02 +0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-11 20:21:40 +0400
commitb8c7d915087c97a21fa415fa0e860e59739da202 (patch)
tree912e3c9296f0ecd70ea024c3bd2ca7955f7af2e3 /drivers
parentc3c2077d9579472b07581ecdaf6cc5a60b1700bc (diff)
downloadlinux-b8c7d915087c97a21fa415fa0e860e59739da202.tar.xz
[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')
-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);
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;
@@ -640,6 +641,11 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode,
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) {
@@ -1019,9 +1025,7 @@ static ssize_t show_filter(struct device *device,
return -EINVAL;
mutex_lock(&dev->lock);
- if (!dev->s_filter)
- val = 0;
- else if (fattr->mask)
+ if (fattr->mask)
val = dev->scancode_filters[fattr->type].mask;
else
val = dev->scancode_filters[fattr->type].data;
@@ -1069,7 +1073,7 @@ static ssize_t store_filter(struct device *device,
return ret;
/* Scancode filter not supported (but still accept 0) */
- if (!dev->s_filter)
+ if (!dev->s_filter && fattr->type != RC_FILTER_NORMAL)
return val ? -EINVAL : count;
mutex_lock(&dev->lock);
@@ -1081,9 +1085,11 @@ static ssize_t store_filter(struct device *device,
local_filter.mask = val;
else
local_filter.data = val;
- ret = dev->s_filter(dev, fattr->type, &local_filter);
- if (ret < 0)
- goto unlock;
+ if (dev->s_filter) {
+ ret = dev->s_filter(dev, fattr->type, &local_filter);
+ if (ret < 0)
+ goto unlock;
+ }
/* Success, commit the new filter */
*filter = local_filter;