From de8592bd539b2bb8da2b55b1007562eb1abd1fe6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jun 2010 13:52:07 -0300 Subject: [PATCH] V4L/DVB: ir-core: allow specifying multiple protocols at one open/write With this change, it is now possible to do something like: su -c 'echo "none +rc-5 +nec" > /sys/class/rc/rc1/protocols' This prevents the need of multiple opens, one for each protocol change, and makes userspace application easier. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-sysfs.c | 92 ++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index e84f9783b8c2..f176fbff9488 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c @@ -117,62 +117,63 @@ static ssize_t store_protocols(struct device *d, const char *tmp; u64 type; u64 mask; - int rc, i; + int rc, i, count = 0; unsigned long flags; - tmp = skip_spaces(data); - if (*tmp == '\0') { - IR_dprintk(1, "Protocol not specified\n"); - return -EINVAL; - } else if (*tmp == '+') { - enable = true; - disable = false; - tmp++; - } else if (*tmp == '-') { - enable = false; - disable = true; - tmp++; - } else { - enable = false; - disable = false; - } + if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) + type = ir_dev->rc_tab.ir_type; + else + type = ir_dev->raw->enabled_protocols; + while ((tmp = strsep((char **) &data, " \n")) != NULL) { + if (!*tmp) + break; + + if (*tmp == '+') { + enable = true; + disable = false; + tmp++; + } else if (*tmp == '-') { + enable = false; + disable = true; + tmp++; + } else { + enable = false; + disable = false; + } - if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) { - mask = 0; - tmp += sizeof(PROTO_NONE); - } else { - for (i = 0; i < ARRAY_SIZE(proto_names); i++) { - if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) { - tmp += strlen(proto_names[i].name); - mask = proto_names[i].type; - break; + if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) { + tmp += sizeof(PROTO_NONE); + mask = 0; + count++; + } else { + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) { + tmp += strlen(proto_names[i].name); + mask = proto_names[i].type; + break; + } } + if (i == ARRAY_SIZE(proto_names)) { + IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); + return -EINVAL; + } + count++; } - if (i == ARRAY_SIZE(proto_names)) { - IR_dprintk(1, "Unknown protocol\n"); - return -EINVAL; - } + + if (enable) + type |= mask; + else if (disable) + type &= ~mask; + else + type = mask; } - tmp = skip_spaces(tmp); - if (*tmp != '\0') { - IR_dprintk(1, "Invalid trailing characters\n"); + if (!count) { + IR_dprintk(1, "Protocol not specified\n"); return -EINVAL; } - if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) - type = ir_dev->rc_tab.ir_type; - else - type = ir_dev->raw->enabled_protocols; - - if (enable) - type |= mask; - else if (disable) - type &= ~mask; - else - type = mask; - if (ir_dev->props && ir_dev->props->change_protocol) { rc = ir_dev->props->change_protocol(ir_dev->props->priv, type); @@ -191,7 +192,6 @@ static ssize_t store_protocols(struct device *d, ir_dev->raw->enabled_protocols = type; } - IR_dprintk(1, "Current protocol(s): 0x%llx\n", (long long)type); -- 2.34.1