From e87b540be2dd02552fb9244d50ae8b4e4619a34b Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Thu, 3 Apr 2014 20:32:31 -0300 Subject: [media] rc-core: merge rc5 and streamzap decoders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the protocol is part of the scancode, it is pretty easy to merge the rc5 and streamzap decoders. An additional advantage is that the decoder is now stricter as it waits for the trailing silence before determining that a command is a valid rc5/streamzap command (which avoids collisions that I've seen with e.g. Sony protocols). Signed-off-by: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-rc5-decoder.c | 72 ++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 31 deletions(-) (limited to 'drivers/media/rc/ir-rc5-decoder.c') diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 04ce42fa9eec..93168daf82eb 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -1,6 +1,7 @@ -/* ir-rc5-decoder.c - handle RC5(x) IR Pulse/Space protocol +/* ir-rc5-decoder.c - decoder for RC5(x) and StreamZap protocols * * Copyright (C) 2010 by Mauro Carvalho Chehab + * Copyright (C) 2010 by Jarod Wilson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,23 +14,22 @@ */ /* - * This code handles 14 bits RC5 protocols and 20 bits RC5x protocols. - * There are other variants that use a different number of bits. - * This is currently unsupported. - * It considers a carrier of 36 kHz, with a total of 14/20 bits, where - * the first two bits are start bits, and a third one is a filing bit + * This decoder handles the 14 bit RC5 protocol, 15 bit "StreamZap" protocol + * and 20 bit RC5x protocol. */ #include "rc-core-priv.h" #include #define RC5_NBITS 14 +#define RC5_SZ_NBITS 15 #define RC5X_NBITS 20 #define CHECK_RC5X_NBITS 8 #define RC5_UNIT 888888 /* ns */ #define RC5_BIT_START (1 * RC5_UNIT) #define RC5_BIT_END (1 * RC5_UNIT) #define RC5X_SPACE (4 * RC5_UNIT) +#define RC5_TRAILER (10 * RC5_UNIT) /* In reality, approx 100 */ enum rc5_state { STATE_INACTIVE, @@ -66,7 +66,7 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) goto out; again: - IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n", + IR_dprintk(2, "RC5(x/sz) decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) @@ -80,12 +80,15 @@ again: data->state = STATE_BIT_START; data->count = 1; - /* We just need enough bits to get to STATE_CHECK_RC5X */ - data->wanted_bits = RC5X_NBITS; decrease_duration(&ev, RC5_BIT_START); goto again; case STATE_BIT_START: + if (!ev.pulse && geq_margin(ev.duration, RC5_TRAILER, RC5_UNIT / 2)) { + data->state = STATE_FINISHED; + goto again; + } + if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) break; @@ -100,9 +103,7 @@ again: if (!is_transition(&ev, &dev->raw->prev_ev)) break; - if (data->count == data->wanted_bits) - data->state = STATE_FINISHED; - else if (data->count == CHECK_RC5X_NBITS) + if (data->count == CHECK_RC5X_NBITS) data->state = STATE_CHECK_RC5X; else data->state = STATE_BIT_START; @@ -112,13 +113,10 @@ again: case STATE_CHECK_RC5X: if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) { - /* RC5X */ - data->wanted_bits = RC5X_NBITS; + data->is_rc5x = true; decrease_duration(&ev, RC5X_SPACE); - } else { - /* RC5 */ - data->wanted_bits = RC5_NBITS; - } + } else + data->is_rc5x = false; data->state = STATE_BIT_START; goto again; @@ -126,7 +124,7 @@ again: if (ev.pulse) break; - if (data->wanted_bits == RC5X_NBITS) { + if (data->is_rc5x && data->count == RC5X_NBITS) { /* RC5X */ u8 xdata, command, system; if (!(dev->enabled_protocols & RC_BIT_RC5X)) { @@ -141,10 +139,7 @@ again: scancode = system << 16 | command << 8 | xdata; protocol = RC_TYPE_RC5X; - IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n", - scancode, toggle); - - } else { + } else if (!data->is_rc5x && data->count == RC5_NBITS) { /* RC5 */ u8 command, system; if (!(dev->enabled_protocols & RC_BIT_RC5)) { @@ -158,9 +153,24 @@ again: scancode = system << 8 | command; protocol = RC_TYPE_RC5; - IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n", - scancode, toggle); - } + } else if (!data->is_rc5x && data->count == RC5_SZ_NBITS) { + /* RC5 StreamZap */ + u8 command, system; + if (!(dev->enabled_protocols & RC_BIT_RC5_SZ)) { + data->state = STATE_INACTIVE; + return 0; + } + command = (data->bits & 0x0003F) >> 0; + system = (data->bits & 0x02FC0) >> 6; + toggle = (data->bits & 0x01000) ? 1 : 0; + scancode = system << 6 | command; + protocol = RC_TYPE_RC5_SZ; + + } else + break; + + IR_dprintk(1, "RC5(x/sz) scancode 0x%06x (p: %u, t: %u)\n", + scancode, protocol, toggle); rc_keydown(dev, protocol, scancode, toggle); data->state = STATE_INACTIVE; @@ -168,14 +178,14 @@ again: } out: - IR_dprintk(1, "RC5(x) decode failed at state %i (%uus %s)\n", + IR_dprintk(1, "RC5(x/sz) decode failed at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } static struct ir_raw_handler rc5_handler = { - .protocols = RC_BIT_RC5 | RC_BIT_RC5X, + .protocols = RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ, .decode = ir_rc5_decode, }; @@ -183,7 +193,7 @@ static int __init ir_rc5_decode_init(void) { ir_raw_handler_register(&rc5_handler); - printk(KERN_INFO "IR RC5(x) protocol handler initialized\n"); + printk(KERN_INFO "IR RC5(x/sz) protocol handler initialized\n"); return 0; } @@ -196,6 +206,6 @@ module_init(ir_rc5_decode_init); module_exit(ir_rc5_decode_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab"); +MODULE_AUTHOR("Mauro Carvalho Chehab and Jarod Wilson"); MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); -MODULE_DESCRIPTION("RC5(x) IR protocol decoder"); +MODULE_DESCRIPTION("RC5(x/sz) IR protocol decoder"); -- cgit