Path: blob/master/drivers/media/rc/ir-rc5-sz-decoder.c
15111 views
/* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol1*2* Copyright (C) 2010 by Mauro Carvalho Chehab <[email protected]>3* Copyright (C) 2010 by Jarod Wilson <[email protected]>4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation version 2 of the License.8*9* This program is distributed in the hope that it will be useful,10* but WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12* GNU General Public License for more details.13*/1415/*16* This code handles the 15 bit RC5-ish protocol used by the Streamzap17* PC Remote.18* It considers a carrier of 36 kHz, with a total of 15 bits, where19* the first two bits are start bits, and a third one is a filing bit20*/2122#include "rc-core-priv.h"2324#define RC5_SZ_NBITS 1525#define RC5_UNIT 888888 /* ns */26#define RC5_BIT_START (1 * RC5_UNIT)27#define RC5_BIT_END (1 * RC5_UNIT)2829enum rc5_sz_state {30STATE_INACTIVE,31STATE_BIT_START,32STATE_BIT_END,33STATE_FINISHED,34};3536/**37* ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space38* @dev: the struct rc_dev descriptor of the device39* @ev: the struct ir_raw_event descriptor of the pulse/space40*41* This function returns -EINVAL if the pulse violates the state machine42*/43static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev)44{45struct rc5_sz_dec *data = &dev->raw->rc5_sz;46u8 toggle, command, system;47u32 scancode;4849if (!(dev->raw->enabled_protocols & RC_TYPE_RC5_SZ))50return 0;5152if (!is_timing_event(ev)) {53if (ev.reset)54data->state = STATE_INACTIVE;55return 0;56}5758if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))59goto out;6061again:62IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n",63data->state, TO_US(ev.duration), TO_STR(ev.pulse));6465if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))66return 0;6768switch (data->state) {6970case STATE_INACTIVE:71if (!ev.pulse)72break;7374data->state = STATE_BIT_START;75data->count = 1;76data->wanted_bits = RC5_SZ_NBITS;77decrease_duration(&ev, RC5_BIT_START);78goto again;7980case STATE_BIT_START:81if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))82break;8384data->bits <<= 1;85if (!ev.pulse)86data->bits |= 1;87data->count++;88data->state = STATE_BIT_END;89return 0;9091case STATE_BIT_END:92if (!is_transition(&ev, &dev->raw->prev_ev))93break;9495if (data->count == data->wanted_bits)96data->state = STATE_FINISHED;97else98data->state = STATE_BIT_START;99100decrease_duration(&ev, RC5_BIT_END);101goto again;102103case STATE_FINISHED:104if (ev.pulse)105break;106107/* RC5-sz */108command = (data->bits & 0x0003F) >> 0;109system = (data->bits & 0x02FC0) >> 6;110toggle = (data->bits & 0x01000) ? 1 : 0;111scancode = system << 6 | command;112113IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",114scancode, toggle);115116rc_keydown(dev, scancode, toggle);117data->state = STATE_INACTIVE;118return 0;119}120121out:122IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n",123data->state, TO_US(ev.duration), TO_STR(ev.pulse));124data->state = STATE_INACTIVE;125return -EINVAL;126}127128static struct ir_raw_handler rc5_sz_handler = {129.protocols = RC_TYPE_RC5_SZ,130.decode = ir_rc5_sz_decode,131};132133static int __init ir_rc5_sz_decode_init(void)134{135ir_raw_handler_register(&rc5_sz_handler);136137printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n");138return 0;139}140141static void __exit ir_rc5_sz_decode_exit(void)142{143ir_raw_handler_unregister(&rc5_sz_handler);144}145146module_init(ir_rc5_sz_decode_init);147module_exit(ir_rc5_sz_decode_exit);148149MODULE_LICENSE("GPL");150MODULE_AUTHOR("Jarod Wilson <[email protected]>");151MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");152MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder");153154155