aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2014-02-28 18:17:06 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-11 12:29:52 -0400
commit6bea25af147fcddcd8fd4557f4184c847c5c6ffd (patch)
tree8f8e23c1620078ced4c1e7e9d87fac7a035ff700 /drivers/media/rc
parentab88c66deace78989aa71cb139284cf7fb227ba4 (diff)
[media] rc-main: automatically refresh filter on protocol change
When either of the normal or wakeup filter protocols are changed, refresh the corresponding scancode filter, i.e. try and set the same scancode filter with the new protocol. If that fails clear the filter instead. If no protocol was selected the filter is just cleared, and if no s_filter callback exists the filter is left unmodified. Similarly clear the filter mask when the filter is set if no protocol is currently selected. This simplifies driver code which no longer has to explicitly worry about modifying the filter on a protocol change. This also allows the change_wakeup_protocol callback to be omitted entirely if there is only a single available wakeup protocol at a time, since selecting no protocol will automatically clear the wakeup filter, disabling wakeup. 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.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index e6e3ec7141bf..b1a690054834 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -918,11 +918,12 @@ static ssize_t store_protocols(struct device *device,
918 struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); 918 struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr);
919 bool enable, disable; 919 bool enable, disable;
920 const char *tmp; 920 const char *tmp;
921 u64 type; 921 u64 old_type, type;
922 u64 mask; 922 u64 mask;
923 int rc, i, count = 0; 923 int rc, i, count = 0;
924 ssize_t ret; 924 ssize_t ret;
925 int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); 925 int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
926 struct rc_scancode_filter local_filter, *filter;
926 927
927 /* Device is being removed */ 928 /* Device is being removed */
928 if (!dev) 929 if (!dev)
@@ -935,7 +936,8 @@ static ssize_t store_protocols(struct device *device,
935 ret = -EINVAL; 936 ret = -EINVAL;
936 goto out; 937 goto out;
937 } 938 }
938 type = dev->enabled_protocols[fattr->type]; 939 old_type = dev->enabled_protocols[fattr->type];
940 type = old_type;
939 941
940 while ((tmp = strsep((char **) &data, " \n")) != NULL) { 942 while ((tmp = strsep((char **) &data, " \n")) != NULL) {
941 if (!*tmp) 943 if (!*tmp)
@@ -999,6 +1001,36 @@ static ssize_t store_protocols(struct device *device,
999 IR_dprintk(1, "Current protocol(s): 0x%llx\n", 1001 IR_dprintk(1, "Current protocol(s): 0x%llx\n",
1000 (long long)type); 1002 (long long)type);
1001 1003
1004 /*
1005 * If the protocol is changed the filter needs updating.
1006 * Try setting the same filter with the new protocol (if any).
1007 * Fall back to clearing the filter.
1008 */
1009 filter = &dev->scancode_filters[fattr->type];
1010 if (old_type != type && filter->mask) {
1011 local_filter = *filter;
1012 if (!type) {
1013 /* no protocol => clear filter */
1014 ret = -1;
1015 } else if (!dev->s_filter) {
1016 /* generic filtering => accept any filter */
1017 ret = 0;
1018 } else {
1019 /* hardware filtering => try setting, otherwise clear */
1020 ret = dev->s_filter(dev, fattr->type, &local_filter);
1021 }
1022 if (ret < 0) {
1023 /* clear the filter */
1024 local_filter.data = 0;
1025 local_filter.mask = 0;
1026 if (dev->s_filter)
1027 dev->s_filter(dev, fattr->type, &local_filter);
1028 }
1029
1030 /* commit the new filter */
1031 *filter = local_filter;
1032 }
1033
1002 ret = len; 1034 ret = len;
1003 1035
1004out: 1036out:
@@ -1096,6 +1128,11 @@ static ssize_t store_filter(struct device *device,
1096 local_filter.mask = val; 1128 local_filter.mask = val;
1097 else 1129 else
1098 local_filter.data = val; 1130 local_filter.data = val;
1131 if (!dev->enabled_protocols[fattr->type] && local_filter.mask) {
1132 /* refuse to set a filter unless a protocol is enabled */
1133 ret = -EINVAL;
1134 goto unlock;
1135 }
1099 if (dev->s_filter) { 1136 if (dev->s_filter) {
1100 ret = dev->s_filter(dev, fattr->type, &local_filter); 1137 ret = dev->s_filter(dev, fattr->type, &local_filter);
1101 if (ret < 0) 1138 if (ret < 0)