--- /dev/null
+/* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol
+ *
+ * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
+ *
+ * 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
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This code handles the 15 bit RC5-ish protocol used by the Streamzap
+ * PC Remote.
+ * It considers a carrier of 36 kHz, with a total of 15 bits, where
+ * the first two bits are start bits, and a third one is a filing bit
+ */
+
+#include "ir-core-priv.h"
+
+#define RC5_SZ_NBITS 15
+#define RC5_UNIT 888888 /* ns */
+#define RC5_BIT_START (1 * RC5_UNIT)
+#define RC5_BIT_END (1 * RC5_UNIT)
+
+enum rc5_sz_state {
+ STATE_INACTIVE,
+ STATE_BIT_START,
+ STATE_BIT_END,
+ STATE_FINISHED,
+};
+
+/**
+ * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
+ * @input_dev: the struct input_dev descriptor of the device
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
+ *
+ * This function returns -EINVAL if the pulse violates the state machine
+ */
+static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+{
+ struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
+ u8 toggle, command, system;
+ u32 scancode;
+
+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
+ return 0;
+
+ if (IS_RESET(ev)) {
+ data->state = STATE_INACTIVE;
+ return 0;
+ }
+
+ if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
+ goto out;
+
+again:
+ IR_dprintk(2, "RC5-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))
+ return 0;
+
+ switch (data->state) {
+
+ case STATE_INACTIVE:
+ if (!ev.pulse)
+ break;
+
+ data->state = STATE_BIT_START;
+ data->count = 1;
+ data->wanted_bits = RC5_SZ_NBITS;
+ decrease_duration(&ev, RC5_BIT_START);
+ goto again;
+
+ case STATE_BIT_START:
+ if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
+ break;
+
+ data->bits <<= 1;
+ if (!ev.pulse)
+ data->bits |= 1;
+ data->count++;
+ data->state = STATE_BIT_END;
+ return 0;
+
+ case STATE_BIT_END:
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ break;
+
+ if (data->count == data->wanted_bits)
+ data->state = STATE_FINISHED;
+ else
+ data->state = STATE_BIT_START;
+
+ decrease_duration(&ev, RC5_BIT_END);
+ goto again;
+
+ case STATE_FINISHED:
+ if (ev.pulse)
+ break;
+
+ /* RC5-sz */
+ command = (data->bits & 0x0003F) >> 0;
+ system = (data->bits & 0x02FC0) >> 6;
+ toggle = (data->bits & 0x01000) ? 1 : 0;
+ scancode = system << 6 | command;
+
+ IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
+ scancode, toggle);
+
+ ir_keydown(input_dev, scancode, toggle);
+ data->state = STATE_INACTIVE;
+ return 0;
+ }
+
+out:
+ IR_dprintk(1, "RC5-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_sz_handler = {
+ .protocols = IR_TYPE_RC5_SZ,
+ .decode = ir_rc5_sz_decode,
+};
+
+static int __init ir_rc5_sz_decode_init(void)
+{
+ ir_raw_handler_register(&rc5_sz_handler);
+
+ printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n");
+ return 0;
+}
+
+static void __exit ir_rc5_sz_decode_exit(void)
+{
+ ir_raw_handler_unregister(&rc5_sz_handler);
+}
+
+module_init(ir_rc5_sz_decode_init);
+module_exit(ir_rc5_sz_decode_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
+MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
+MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder");
--- /dev/null
+/* rc-streamzap.c - Keytable for Streamzap PC Remote, for use
+ * with the Streamzap PC Remote IR Receiver.
+ *
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+
+static struct ir_scancode streamzap[] = {
+/*
+ * The Streamzap remote is almost, but not quite, RC-5, as it has an extra
+ * bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently,
+ * an additional RC-5-sz decoder is being deployed to support it, but it
+ * may be possible to merge it back with the standard RC-5 decoder.
+ */
+ { 0x28c0, KEY_NUMERIC_0 },
+ { 0x28c1, KEY_NUMERIC_1 },
+ { 0x28c2, KEY_NUMERIC_2 },
+ { 0x28c3, KEY_NUMERIC_3 },
+ { 0x28c4, KEY_NUMERIC_4 },
+ { 0x28c5, KEY_NUMERIC_5 },
+ { 0x28c6, KEY_NUMERIC_6 },
+ { 0x28c7, KEY_NUMERIC_7 },
+ { 0x28c8, KEY_NUMERIC_8 },
+ { 0x28c9, KEY_NUMERIC_9 },
+ { 0x28ca, KEY_POWER },
+ { 0x28cb, KEY_MUTE },
+ { 0x28cc, KEY_CHANNELUP },
+ { 0x28cd, KEY_VOLUMEUP },
+ { 0x28ce, KEY_CHANNELDOWN },
+ { 0x28cf, KEY_VOLUMEDOWN },
+ { 0x28d0, KEY_UP },
+ { 0x28d1, KEY_LEFT },
+ { 0x28d2, KEY_OK },
+ { 0x28d3, KEY_RIGHT },
+ { 0x28d4, KEY_DOWN },
+ { 0x28d5, KEY_MENU },
+ { 0x28d6, KEY_EXIT },
+ { 0x28d7, KEY_PLAY },
+ { 0x28d8, KEY_PAUSE },
+ { 0x28d9, KEY_STOP },
+ { 0x28da, KEY_BACK },
+ { 0x28db, KEY_FORWARD },
+ { 0x28dc, KEY_RECORD },
+ { 0x28dd, KEY_REWIND },
+ { 0x28de, KEY_FASTFORWARD },
+ { 0x28e0, KEY_RED },
+ { 0x28e1, KEY_GREEN },
+ { 0x28e2, KEY_YELLOW },
+ { 0x28e3, KEY_BLUE },
+
+};
+
+static struct rc_keymap streamzap_map = {
+ .map = {
+ .scan = streamzap,
+ .size = ARRAY_SIZE(streamzap),
+ .ir_type = IR_TYPE_RC5_SZ,
+ .name = RC_MAP_STREAMZAP,
+ }
+};
+
+static int __init init_rc_map_streamzap(void)
+{
+ return ir_register_map(&streamzap_map);
+}
+
+static void __exit exit_rc_map_streamzap(void)
+{
+ ir_unregister_map(&streamzap_map);
+}
+
+module_init(init_rc_map_streamzap)
+module_exit(exit_rc_map_streamzap)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
#include <linux/input.h>
#include <media/ir-core.h>
-#define DRIVER_VERSION "1.60"
+#define DRIVER_VERSION "1.61"
#define DRIVER_NAME "streamzap"
#define DRIVER_DESC "Streamzap Remote Control driver"
/* number of samples buffered */
#define SZ_BUF_LEN 128
+/* from ir-rc5-sz-decoder.c */
+#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
+#define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder")
+#else
+#define load_rc5_sz_decode() 0
+#endif
+
enum StreamzapDecoderState {
PulseSpace,
FullPulse,
/* ir-core */
struct ir_dev_props *props;
- struct ir_raw_event rawir;
/* core device info */
struct device *dev;
dma_addr_t dma_in;
unsigned int buf_in_len;
- /* timer used to support delay buffering */
- struct timer_list delay_timer;
- bool timer_running;
- spinlock_t timer_lock;
- struct timer_list flush_timer;
- bool flush;
-
- /* delay buffer */
- struct kfifo fifo;
- bool fifo_initialized;
-
/* track what state we're in */
enum StreamzapDecoderState decoder_state;
/* tracks whether we are currently receiving some signal */
/* start time of signal; necessary for gap tracking */
struct timeval signal_last;
struct timeval signal_start;
- /* bool timeout_enabled; */
+ bool timeout_enabled;
char name[128];
char phys[64];
.id_table = streamzap_table,
};
-static void streamzap_stop_timer(struct streamzap_ir *sz)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sz->timer_lock, flags);
- if (sz->timer_running) {
- sz->timer_running = false;
- spin_unlock_irqrestore(&sz->timer_lock, flags);
- del_timer_sync(&sz->delay_timer);
- } else {
- spin_unlock_irqrestore(&sz->timer_lock, flags);
- }
-}
-
-static void streamzap_flush_timeout(unsigned long arg)
-{
- struct streamzap_ir *sz = (struct streamzap_ir *)arg;
-
- dev_info(sz->dev, "%s: callback firing\n", __func__);
-
- /* finally start accepting data */
- sz->flush = false;
-}
-
-static void streamzap_delay_timeout(unsigned long arg)
-{
- struct streamzap_ir *sz = (struct streamzap_ir *)arg;
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
- unsigned long flags;
- int len, ret;
- static unsigned long delay;
- bool wake = false;
-
- /* deliver data every 10 ms */
- delay = msecs_to_jiffies(10);
-
- spin_lock_irqsave(&sz->timer_lock, flags);
-
- if (kfifo_len(&sz->fifo) > 0) {
- ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
- if (ret != sizeof(rawir))
- dev_err(sz->dev, "Problem w/kfifo_out...\n");
- ir_raw_event_store(sz->idev, &rawir);
- wake = true;
- }
-
- len = kfifo_len(&sz->fifo);
- if (len > 0) {
- while ((len < SZ_BUF_LEN / 2) &&
- (len < SZ_BUF_LEN * sizeof(int))) {
- ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
- if (ret != sizeof(rawir))
- dev_err(sz->dev, "Problem w/kfifo_out...\n");
- ir_raw_event_store(sz->idev, &rawir);
- wake = true;
- len = kfifo_len(&sz->fifo);
- }
- if (sz->timer_running)
- mod_timer(&sz->delay_timer, jiffies + delay);
-
- } else {
- sz->timer_running = false;
- }
-
- if (wake)
- ir_raw_event_handle(sz->idev);
-
- spin_unlock_irqrestore(&sz->timer_lock, flags);
-}
-
-static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
+static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
{
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
- bool wake = false;
- int ret;
-
- while (kfifo_len(&sz->fifo) > 0) {
- ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
- if (ret != sizeof(rawir))
- dev_err(sz->dev, "Problem w/kfifo_out...\n");
- ir_raw_event_store(sz->idev, &rawir);
- wake = true;
- }
-
- if (wake)
- ir_raw_event_handle(sz->idev);
-}
-
-static void sz_push(struct streamzap_ir *sz)
-{
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&sz->timer_lock, flags);
- if (kfifo_len(&sz->fifo) >= sizeof(int) * SZ_BUF_LEN) {
- ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
- if (ret != sizeof(rawir))
- dev_err(sz->dev, "Problem w/kfifo_out...\n");
- ir_raw_event_store(sz->idev, &rawir);
- }
-
- kfifo_in(&sz->fifo, &sz->rawir, sizeof(rawir));
-
- if (!sz->timer_running) {
- sz->delay_timer.expires = jiffies + (HZ / 10);
- add_timer(&sz->delay_timer);
- sz->timer_running = true;
- }
-
- spin_unlock_irqrestore(&sz->timer_lock, flags);
+ ir_raw_event_store(sz->idev, &rawir);
}
static void sz_push_full_pulse(struct streamzap_ir *sz,
unsigned char value)
{
+ struct ir_raw_event rawir;
+
if (sz->idle) {
long deltv;
do_gettimeofday(&sz->signal_start);
deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec;
- sz->rawir.pulse = false;
+ rawir.pulse = false;
if (deltv > 15) {
/* really long time */
- sz->rawir.duration = IR_MAX_DURATION;
+ rawir.duration = IR_MAX_DURATION;
} else {
- sz->rawir.duration = (int)(deltv * 1000000 +
+ rawir.duration = (int)(deltv * 1000000 +
sz->signal_start.tv_usec -
sz->signal_last.tv_usec);
- sz->rawir.duration -= sz->sum;
- sz->rawir.duration *= 1000;
- sz->rawir.duration &= IR_MAX_DURATION;
+ rawir.duration -= sz->sum;
+ rawir.duration *= 1000;
+ rawir.duration &= IR_MAX_DURATION;
}
- dev_dbg(sz->dev, "ls %u\n", sz->rawir.duration);
- sz_push(sz);
+ dev_dbg(sz->dev, "ls %u\n", rawir.duration);
+ sz_push(sz, rawir);
- sz->idle = 0;
+ sz->idle = false;
sz->sum = 0;
}
- sz->rawir.pulse = true;
- sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
- sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
- sz->sum += sz->rawir.duration;
- sz->rawir.duration *= 1000;
- sz->rawir.duration &= IR_MAX_DURATION;
- dev_dbg(sz->dev, "p %u\n", sz->rawir.duration);
- sz_push(sz);
+ rawir.pulse = true;
+ rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
+ rawir.duration += STREAMZAP_RESOLUTION / 2;
+ sz->sum += rawir.duration;
+ rawir.duration *= 1000;
+ rawir.duration &= IR_MAX_DURATION;
+ dev_dbg(sz->dev, "p %u\n", rawir.duration);
+ sz_push(sz, rawir);
}
static void sz_push_half_pulse(struct streamzap_ir *sz,
static void sz_push_full_space(struct streamzap_ir *sz,
unsigned char value)
{
- sz->rawir.pulse = false;
- sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
- sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
- sz->sum += sz->rawir.duration;
- sz->rawir.duration *= 1000;
- dev_dbg(sz->dev, "s %u\n", sz->rawir.duration);
- sz_push(sz);
+ struct ir_raw_event rawir;
+
+ rawir.pulse = false;
+ rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
+ rawir.duration += STREAMZAP_RESOLUTION / 2;
+ sz->sum += rawir.duration;
+ rawir.duration *= 1000;
+ dev_dbg(sz->dev, "s %u\n", rawir.duration);
+ sz_push(sz, rawir);
}
static void sz_push_half_space(struct streamzap_ir *sz,
struct streamzap_ir *sz;
unsigned int i;
int len;
- #if 0
static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) &
IR_MAX_DURATION) | 0x03000000);
- #endif
if (!urb)
return;
}
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
- if (!sz->flush) {
- for (i = 0; i < urb->actual_length; i++) {
- dev_dbg(sz->dev, "%d: %x\n", i,
- (unsigned char)sz->buf_in[i]);
- switch (sz->decoder_state) {
- case PulseSpace:
- if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
- STREAMZAP_PULSE_MASK) {
- sz->decoder_state = FullPulse;
- continue;
- } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
- == STREAMZAP_SPACE_MASK) {
- sz_push_half_pulse(sz, sz->buf_in[i]);
- sz->decoder_state = FullSpace;
- continue;
- } else {
- sz_push_half_pulse(sz, sz->buf_in[i]);
- sz_push_half_space(sz, sz->buf_in[i]);
- }
- break;
- case FullPulse:
- sz_push_full_pulse(sz, sz->buf_in[i]);
- sz->decoder_state = IgnorePulse;
- break;
- case FullSpace:
- if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
- sz->idle = 1;
- streamzap_stop_timer(sz);
- #if 0
- if (sz->timeout_enabled) {
- sz->rawir.pulse = false;
- sz->rawir.duration = timeout;
- sz->rawir.duration *= 1000;
- sz_push(sz);
- }
- #endif
- streamzap_flush_delay_buffer(sz);
- } else
- sz_push_full_space(sz, sz->buf_in[i]);
- sz->decoder_state = PulseSpace;
- break;
- case IgnorePulse:
- if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) ==
- STREAMZAP_SPACE_MASK) {
- sz->decoder_state = FullSpace;
- continue;
- }
+ for (i = 0; i < len; i++) {
+ dev_dbg(sz->dev, "sz idx %d: %x\n",
+ i, (unsigned char)sz->buf_in[i]);
+ switch (sz->decoder_state) {
+ case PulseSpace:
+ if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
+ STREAMZAP_PULSE_MASK) {
+ sz->decoder_state = FullPulse;
+ continue;
+ } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
+ == STREAMZAP_SPACE_MASK) {
+ sz_push_half_pulse(sz, sz->buf_in[i]);
+ sz->decoder_state = FullSpace;
+ continue;
+ } else {
+ sz_push_half_pulse(sz, sz->buf_in[i]);
sz_push_half_space(sz, sz->buf_in[i]);
- sz->decoder_state = PulseSpace;
- break;
}
+ break;
+ case FullPulse:
+ sz_push_full_pulse(sz, sz->buf_in[i]);
+ sz->decoder_state = IgnorePulse;
+ break;
+ case FullSpace:
+ if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
+ struct ir_raw_event rawir;
+
+ rawir.pulse = false;
+ rawir.duration = timeout * 1000;
+ sz->idle = true;
+ if (sz->timeout_enabled)
+ sz_push(sz, rawir);
+ ir_raw_event_handle(sz->idev);
+ } else {
+ sz_push_full_space(sz, sz->buf_in[i]);
+ }
+ sz->decoder_state = PulseSpace;
+ break;
+ case IgnorePulse:
+ if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK) ==
+ STREAMZAP_SPACE_MASK) {
+ sz->decoder_state = FullSpace;
+ continue;
+ }
+ sz_push_half_space(sz, sz->buf_in[i]);
+ sz->decoder_state = PulseSpace;
+ break;
}
}
props->priv = sz;
props->driver_type = RC_DRIVER_IR_RAW;
- /* FIXME: not sure about supported protocols, check on this */
- props->allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6;
+ props->allowed_protos = IR_TYPE_ALL;
sz->props = props;
- ret = ir_input_register(idev, RC_MAP_RC5_STREAMZAP, props, DRIVER_NAME);
+ ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
if (ret < 0) {
dev_err(dev, "remote input device register failed\n");
goto irdev_failed;
return NULL;
}
-static int streamzap_delay_buf_init(struct streamzap_ir *sz)
-{
- int ret;
-
- ret = kfifo_alloc(&sz->fifo, sizeof(int) * SZ_BUF_LEN,
- GFP_KERNEL);
- if (ret == 0)
- sz->fifo_initialized = 1;
-
- return ret;
-}
-
-static void streamzap_start_flush_timer(struct streamzap_ir *sz)
-{
- sz->flush_timer.expires = jiffies + HZ;
- sz->flush = true;
- add_timer(&sz->flush_timer);
-
- sz->urb_in->dev = sz->usbdev;
- if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
- dev_err(sz->dev, "urb submit failed\n");
-}
-
/**
* streamzap_probe
*
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
- retval = streamzap_delay_buf_init(sz);
- if (retval) {
- dev_err(&intf->dev, "%s: delay buffer init failed\n", __func__);
- goto free_urb_in;
- }
-
sz->idev = streamzap_init_input_dev(sz);
if (!sz->idev)
goto input_dev_fail;
sz->idle = true;
sz->decoder_state = PulseSpace;
+ /* FIXME: don't yet have a way to set this */
+ sz->timeout_enabled = true;
#if 0
/* not yet supported, depends on patches from maxim */
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
- sz->timeout_enabled = false;
sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
#endif
- init_timer(&sz->delay_timer);
- sz->delay_timer.function = streamzap_delay_timeout;
- sz->delay_timer.data = (unsigned long)sz;
- spin_lock_init(&sz->timer_lock);
-
- init_timer(&sz->flush_timer);
- sz->flush_timer.function = streamzap_flush_timeout;
- sz->flush_timer.data = (unsigned long)sz;
-
do_gettimeofday(&sz->signal_start);
/* Complete final initialisations */
usb_set_intfdata(intf, sz);
- streamzap_start_flush_timer(sz);
+ if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
+ dev_err(sz->dev, "urb submit failed\n");
dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
usbdev->bus->busnum, usbdev->devnum);
+ /* Load the streamzap not-quite-rc5 decoder too */
+ load_rc5_sz_decode();
+
return 0;
input_dev_fail:
- kfifo_free(&sz->fifo);
-free_urb_in:
usb_free_urb(sz->urb_in);
free_buf_in:
usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
if (!sz)
return;
- if (sz->flush) {
- sz->flush = false;
- del_timer_sync(&sz->flush_timer);
- }
-
- streamzap_stop_timer(sz);
-
sz->usbdev = NULL;
ir_input_unregister(sz->idev);
usb_kill_urb(sz->urb_in);
{
struct streamzap_ir *sz = usb_get_intfdata(intf);
- if (sz->flush) {
- sz->flush = false;
- del_timer_sync(&sz->flush_timer);
- }
-
- streamzap_stop_timer(sz);
-
usb_kill_urb(sz->urb_in);
return 0;
{
struct streamzap_ir *sz = usb_get_intfdata(intf);
- if (sz->fifo_initialized)
- kfifo_reset(&sz->fifo);
-
- sz->flush_timer.expires = jiffies + HZ;
- sz->flush = true;
- add_timer(&sz->flush_timer);
-
if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
dev_err(sz->dev, "Error sumbiting urb\n");
return -EIO;