Jarod Wilson b9878dc
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/ir-core-priv.h linux-2.6.35.x86_64/drivers/media/IR/ir-core-priv.h
Jarod Wilson b9878dc
--- linux-2.6.35.x86_64.orig/drivers/media/IR/ir-core-priv.h	2010-08-15 17:50:34.572382442 -0400
Jarod Wilson b9878dc
+++ linux-2.6.35.x86_64/drivers/media/IR/ir-core-priv.h	2010-08-16 00:11:42.756124321 -0400
Jarod Wilson b9878dc
@@ -73,6 +73,12 @@ struct ir_raw_event_ctrl {
Jarod Wilson b9878dc
 		bool first;
Jarod Wilson b9878dc
 		bool toggle;
Jarod Wilson b9878dc
 	} jvc;
Jarod Wilson b9878dc
+	struct rc5_sz_dec {
Jarod Wilson b9878dc
+		int state;
Jarod Wilson b9878dc
+		u32 bits;
Jarod Wilson b9878dc
+		unsigned count;
Jarod Wilson b9878dc
+		unsigned wanted_bits;
Jarod Wilson b9878dc
+	} rc5_sz;
Jarod Wilson b9878dc
 	struct lirc_codec {
Jarod Wilson b9878dc
 		struct ir_input_dev *ir_dev;
Jarod Wilson b9878dc
 		struct lirc_driver *drv;
Jarod Wilson b9878dc
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/ir-rc5-sz-decoder.c linux-2.6.35.x86_64/drivers/media/IR/ir-rc5-sz-decoder.c
Jarod Wilson b9878dc
--- linux-2.6.35.x86_64.orig/drivers/media/IR/ir-rc5-sz-decoder.c	1969-12-31 19:00:00.000000000 -0500
Jarod Wilson b9878dc
+++ linux-2.6.35.x86_64/drivers/media/IR/ir-rc5-sz-decoder.c	2010-08-16 00:07:19.962608685 -0400
Jarod Wilson b9878dc
@@ -0,0 +1,153 @@
Jarod Wilson b9878dc
+/* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
Jarod Wilson b9878dc
+ * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * This program is free software; you can redistribute it and/or modify
Jarod Wilson b9878dc
+ *  it under the terms of the GNU General Public License as published by
Jarod Wilson b9878dc
+ *  the Free Software Foundation version 2 of the License.
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ *  This program is distributed in the hope that it will be useful,
Jarod Wilson b9878dc
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Jarod Wilson b9878dc
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jarod Wilson b9878dc
+ *  GNU General Public License for more details.
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/*
Jarod Wilson b9878dc
+ * This code handles the 15 bit RC5-ish protocol used by the Streamzap
Jarod Wilson b9878dc
+ * PC Remote.
Jarod Wilson b9878dc
+ * It considers a carrier of 36 kHz, with a total of 15 bits, where
Jarod Wilson b9878dc
+ * the first two bits are start bits, and a third one is a filing bit
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+#include "ir-core-priv.h"
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+#define RC5_SZ_NBITS		15
Jarod Wilson b9878dc
+#define RC5_UNIT		888888 /* ns */
Jarod Wilson b9878dc
+#define RC5_BIT_START		(1 * RC5_UNIT)
Jarod Wilson b9878dc
+#define RC5_BIT_END		(1 * RC5_UNIT)
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+enum rc5_sz_state {
Jarod Wilson b9878dc
+	STATE_INACTIVE,
Jarod Wilson b9878dc
+	STATE_BIT_START,
Jarod Wilson b9878dc
+	STATE_BIT_END,
Jarod Wilson b9878dc
+	STATE_FINISHED,
Jarod Wilson b9878dc
+};
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/**
Jarod Wilson b9878dc
+ * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
Jarod Wilson b9878dc
+ * @input_dev:	the struct input_dev descriptor of the device
Jarod Wilson b9878dc
+ * @ev:		the struct ir_raw_event descriptor of the pulse/space
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * This function returns -EINVAL if the pulse violates the state machine
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jarod Wilson b9878dc
+	struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
Jarod Wilson b9878dc
+	u8 toggle, command, system;
Jarod Wilson b9878dc
+	u32 scancode;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+        if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
Jarod Wilson b9878dc
+                return 0;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (IS_RESET(ev)) {
Jarod Wilson b9878dc
+		data->state = STATE_INACTIVE;
Jarod Wilson b9878dc
+		return 0;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
Jarod Wilson b9878dc
+		goto out;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+again:
Jarod Wilson b9878dc
+	IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n",
Jarod Wilson b9878dc
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
Jarod Wilson b9878dc
+		return 0;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	switch (data->state) {
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	case STATE_INACTIVE:
Jarod Wilson b9878dc
+		if (!ev.pulse)
Jarod Wilson b9878dc
+			break;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		data->state = STATE_BIT_START;
Jarod Wilson b9878dc
+		data->count = 1;
Jarod Wilson b9878dc
+		data->wanted_bits = RC5_SZ_NBITS;
Jarod Wilson b9878dc
+		decrease_duration(&ev, RC5_BIT_START);
Jarod Wilson b9878dc
+		goto again;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	case STATE_BIT_START:
Jarod Wilson b9878dc
+		if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
Jarod Wilson b9878dc
+			break;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		data->bits <<= 1;
Jarod Wilson b9878dc
+		if (!ev.pulse)
Jarod Wilson b9878dc
+			data->bits |= 1;
Jarod Wilson b9878dc
+		data->count++;
Jarod Wilson b9878dc
+		data->state = STATE_BIT_END;
Jarod Wilson b9878dc
+		return 0;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	case STATE_BIT_END:
Jarod Wilson b9878dc
+		if (!is_transition(&ev, &ir_dev->raw->prev_ev))
Jarod Wilson b9878dc
+			break;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		if (data->count == data->wanted_bits)
Jarod Wilson b9878dc
+			data->state = STATE_FINISHED;
Jarod Wilson b9878dc
+		else
Jarod Wilson b9878dc
+			data->state = STATE_BIT_START;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		decrease_duration(&ev, RC5_BIT_END);
Jarod Wilson b9878dc
+		goto again;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	case STATE_FINISHED:
Jarod Wilson b9878dc
+		if (ev.pulse)
Jarod Wilson b9878dc
+			break;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		/* RC5-sz */
Jarod Wilson b9878dc
+		command  = (data->bits & 0x0003F) >> 0;
Jarod Wilson b9878dc
+		system   = (data->bits & 0x02FC0) >> 6;
Jarod Wilson b9878dc
+		toggle   = (data->bits & 0x01000) ? 1 : 0;
Jarod Wilson b9878dc
+		scancode = system << 6 | command;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
Jarod Wilson b9878dc
+			   scancode, toggle);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		ir_keydown(input_dev, scancode, toggle);
Jarod Wilson b9878dc
+		data->state = STATE_INACTIVE;
Jarod Wilson b9878dc
+		return 0;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+out:
Jarod Wilson b9878dc
+	IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n",
Jarod Wilson b9878dc
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
Jarod Wilson b9878dc
+	data->state = STATE_INACTIVE;
Jarod Wilson b9878dc
+	return -EINVAL;
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static struct ir_raw_handler rc5_sz_handler = {
Jarod Wilson b9878dc
+	.protocols	= IR_TYPE_RC5_SZ,
Jarod Wilson b9878dc
+	.decode		= ir_rc5_sz_decode,
Jarod Wilson b9878dc
+};
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static int __init ir_rc5_sz_decode_init(void)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	ir_raw_handler_register(&rc5_sz_handler);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n");
Jarod Wilson b9878dc
+	return 0;
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static void __exit ir_rc5_sz_decode_exit(void)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	ir_raw_handler_unregister(&rc5_sz_handler);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+module_init(ir_rc5_sz_decode_init);
Jarod Wilson b9878dc
+module_exit(ir_rc5_sz_decode_exit);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+MODULE_LICENSE("GPL");
Jarod Wilson b9878dc
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
Jarod Wilson b9878dc
+MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
Jarod Wilson b9878dc
+MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder");
Jarod Wilson b9878dc
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/ir-sysfs.c linux-2.6.35.x86_64/drivers/media/IR/ir-sysfs.c
Jarod Wilson b9878dc
--- linux-2.6.35.x86_64.orig/drivers/media/IR/ir-sysfs.c	2010-08-15 17:50:34.574380413 -0400
Jarod Wilson b9878dc
+++ linux-2.6.35.x86_64/drivers/media/IR/ir-sysfs.c	2010-08-16 00:23:24.893168856 -0400
Jarod Wilson b9878dc
@@ -93,6 +93,11 @@ static ssize_t show_protocols(struct dev
Jarod Wilson b9878dc
 	else if (allowed & IR_TYPE_SONY)
Jarod Wilson b9878dc
 		tmp += sprintf(tmp, "sony ");
Jarod Wilson b9878dc
 
Jarod Wilson b9878dc
+	if (allowed & enabled & IR_TYPE_RC5_SZ)
Jarod Wilson b9878dc
+		tmp += sprintf(tmp, "[rc5sz] ");
Jarod Wilson b9878dc
+	else if (allowed & IR_TYPE_RC5_SZ)
Jarod Wilson b9878dc
+		tmp += sprintf(tmp, "rc5sz ");
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
 	if (allowed & enabled & IR_TYPE_LIRC)
Jarod Wilson b9878dc
 		tmp += sprintf(tmp, "[lirc] ");
Jarod Wilson b9878dc
 	else if (allowed & IR_TYPE_LIRC)
Jarod Wilson b9878dc
@@ -165,6 +170,9 @@ static ssize_t store_protocols(struct de
Jarod Wilson b9878dc
 	} else if (!strncasecmp(tmp, "sony", 4)) {
Jarod Wilson b9878dc
 		tmp += 4;
Jarod Wilson b9878dc
 		mask = IR_TYPE_SONY;
Jarod Wilson b9878dc
+	} else if (!strncasecmp(tmp, "rc5sz", 5)) {
Jarod Wilson b9878dc
+		tmp += 5;
Jarod Wilson b9878dc
+		mask = IR_TYPE_RC5_SZ;
Jarod Wilson b9878dc
 	} else if (!strncasecmp(tmp, "lirc", 4)) {
Jarod Wilson b9878dc
 		tmp += 4;
Jarod Wilson b9878dc
 		mask = IR_TYPE_LIRC;
Jarod Wilson b9878dc
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/Kconfig linux-2.6.35.x86_64/drivers/media/IR/Kconfig
Jarod Wilson b9878dc
--- linux-2.6.35.x86_64.orig/drivers/media/IR/Kconfig	2010-08-15 17:50:34.571382513 -0400
Jarod Wilson b9878dc
+++ linux-2.6.35.x86_64/drivers/media/IR/Kconfig	2010-08-16 00:10:09.292873588 -0400
Jarod Wilson b9878dc
@@ -69,6 +69,16 @@ config IR_SONY_DECODER
Jarod Wilson b9878dc
 	   Enable this option if you have an infrared remote control which
Jarod Wilson b9878dc
 	   uses the Sony protocol, and you need software decoding support.
Jarod Wilson b9878dc
 
Jarod Wilson b9878dc
+config IR_RC5_SZ_DECODER
Jarod Wilson b9878dc
+	tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol"
Jarod Wilson b9878dc
+	depends on IR_CORE
Jarod Wilson b9878dc
+	select BITREVERSE
Jarod Wilson b9878dc
+	default y
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	---help---
Jarod Wilson b9878dc
+	   Enable this option if you have IR with RC-5 (streamzap) protocol,
Jarod Wilson b9878dc
+	   and if the IR is decoded in software.
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
 config IR_LIRC_CODEC
Jarod Wilson b9878dc
 	tristate "Enable IR to LIRC bridge"
Jarod Wilson b9878dc
 	depends on IR_CORE
Jarod Wilson b9878dc
@@ -102,3 +112,15 @@ config IR_MCEUSB
Jarod Wilson b9878dc
 
Jarod Wilson b9878dc
 	   To compile this driver as a module, choose M here: the
Jarod Wilson b9878dc
 	   module will be called mceusb.
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+config IR_STREAMZAP
Jarod Wilson b9878dc
+	tristate "Streamzap PC Remote IR Receiver"
Jarod Wilson b9878dc
+	depends on USB_ARCH_HAS_HCD
Jarod Wilson b9878dc
+	depends on IR_CORE
Jarod Wilson b9878dc
+	select USB
Jarod Wilson b9878dc
+	---help---
Jarod Wilson b9878dc
+	   Say Y here if you want to use a Streamzap PC Remote
Jarod Wilson b9878dc
+	   Infrared Receiver.
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	   To compile this driver as a module, choose M here: the
Jarod Wilson b9878dc
+	   module will be called streamzap.
Jarod Wilson b9878dc
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/keymaps/Makefile linux-2.6.35.x86_64/drivers/media/IR/keymaps/Makefile
Jarod Wilson b9878dc
--- linux-2.6.35.x86_64.orig/drivers/media/IR/keymaps/Makefile	2010-08-15 17:50:34.575383346 -0400
Jarod Wilson b9878dc
+++ linux-2.6.35.x86_64/drivers/media/IR/keymaps/Makefile	2010-08-16 00:05:47.400370419 -0400
Jarod Wilson b9878dc
@@ -60,6 +60,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t
Jarod Wilson b9878dc
 			rc-rc5-tv.o \
Jarod Wilson b9878dc
 			rc-rc6-mce.o \
Jarod Wilson b9878dc
 			rc-real-audio-220-32-keys.o \
Jarod Wilson b9878dc
+			rc-streamzap.o \
Jarod Wilson b9878dc
 			rc-tbs-nec.o \
Jarod Wilson b9878dc
 			rc-terratec-cinergy-xs.o \
Jarod Wilson b9878dc
 			rc-tevii-nec.o \
Jarod Wilson b9878dc
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/keymaps/rc-streamzap.c linux-2.6.35.x86_64/drivers/media/IR/keymaps/rc-streamzap.c
Jarod Wilson b9878dc
--- linux-2.6.35.x86_64.orig/drivers/media/IR/keymaps/rc-streamzap.c	1969-12-31 19:00:00.000000000 -0500
Jarod Wilson b9878dc
+++ linux-2.6.35.x86_64/drivers/media/IR/keymaps/rc-streamzap.c	2010-08-16 00:05:47.402370467 -0400
Jarod Wilson b9878dc
@@ -0,0 +1,82 @@
Jarod Wilson b9878dc
+/* rc-streamzap.c - Keytable for Streamzap PC Remote, for use
Jarod Wilson b9878dc
+ * with the Streamzap PC Remote IR Receiver.
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * This program is free software; you can redistribute it and/or modify
Jarod Wilson b9878dc
+ * it under the terms of the GNU General Public License as published by
Jarod Wilson b9878dc
+ * the Free Software Foundation; either version 2 of the License, or
Jarod Wilson b9878dc
+ * (at your option) any later version.
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+#include <media/rc-map.h>
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static struct ir_scancode streamzap[] = {
Jarod Wilson b9878dc
+/*
Jarod Wilson b9878dc
+ * The Streamzap remote is almost, but not quite, RC-5, as it has an extra
Jarod Wilson b9878dc
+ * bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently,
Jarod Wilson b9878dc
+ * an additional RC-5-sz decoder is being deployed to support it, but it
Jarod Wilson b9878dc
+ * may be possible to merge it back with the standard RC-5 decoder.
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+	{ 0x28c0, KEY_NUMERIC_0 },
Jarod Wilson b9878dc
+	{ 0x28c1, KEY_NUMERIC_1 },
Jarod Wilson b9878dc
+	{ 0x28c2, KEY_NUMERIC_2 },
Jarod Wilson b9878dc
+	{ 0x28c3, KEY_NUMERIC_3 },
Jarod Wilson b9878dc
+	{ 0x28c4, KEY_NUMERIC_4 },
Jarod Wilson b9878dc
+	{ 0x28c5, KEY_NUMERIC_5 },
Jarod Wilson b9878dc
+	{ 0x28c6, KEY_NUMERIC_6 },
Jarod Wilson b9878dc
+	{ 0x28c7, KEY_NUMERIC_7 },
Jarod Wilson b9878dc
+	{ 0x28c8, KEY_NUMERIC_8 },
Jarod Wilson b9878dc
+	{ 0x28c9, KEY_NUMERIC_9 },
Jarod Wilson b9878dc
+	{ 0x28ca, KEY_POWER },
Jarod Wilson b9878dc
+	{ 0x28cb, KEY_MUTE },
Jarod Wilson b9878dc
+	{ 0x28cc, KEY_CHANNELUP },
Jarod Wilson b9878dc
+	{ 0x28cd, KEY_VOLUMEUP },
Jarod Wilson b9878dc
+	{ 0x28ce, KEY_CHANNELDOWN },
Jarod Wilson b9878dc
+	{ 0x28cf, KEY_VOLUMEDOWN },
Jarod Wilson b9878dc
+	{ 0x28d0, KEY_UP },
Jarod Wilson b9878dc
+	{ 0x28d1, KEY_LEFT },
Jarod Wilson b9878dc
+	{ 0x28d2, KEY_OK },
Jarod Wilson b9878dc
+	{ 0x28d3, KEY_RIGHT },
Jarod Wilson b9878dc
+	{ 0x28d4, KEY_DOWN },
Jarod Wilson b9878dc
+	{ 0x28d5, KEY_MENU },
Jarod Wilson b9878dc
+	{ 0x28d6, KEY_EXIT },
Jarod Wilson b9878dc
+	{ 0x28d7, KEY_PLAY },
Jarod Wilson b9878dc
+	{ 0x28d8, KEY_PAUSE },
Jarod Wilson b9878dc
+	{ 0x28d9, KEY_STOP },
Jarod Wilson b9878dc
+	{ 0x28da, KEY_BACK },
Jarod Wilson b9878dc
+	{ 0x28db, KEY_FORWARD },
Jarod Wilson b9878dc
+	{ 0x28dc, KEY_RECORD },
Jarod Wilson b9878dc
+	{ 0x28dd, KEY_REWIND },
Jarod Wilson b9878dc
+	{ 0x28de, KEY_FASTFORWARD },
Jarod Wilson b9878dc
+	{ 0x28e0, KEY_RED },
Jarod Wilson b9878dc
+	{ 0x28e1, KEY_GREEN },
Jarod Wilson b9878dc
+	{ 0x28e2, KEY_YELLOW },
Jarod Wilson b9878dc
+	{ 0x28e3, KEY_BLUE },
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+};
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static struct rc_keymap streamzap_map = {
Jarod Wilson b9878dc
+	.map = {
Jarod Wilson b9878dc
+		.scan    = streamzap,
Jarod Wilson b9878dc
+		.size    = ARRAY_SIZE(streamzap),
Jarod Wilson b9878dc
+		.ir_type = IR_TYPE_RC5,
Jarod Wilson b9878dc
+		.name    = RC_MAP_STREAMZAP,
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+};
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static int __init init_rc_map_streamzap(void)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	return ir_register_map(&streamzap_map);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static void __exit exit_rc_map_streamzap(void)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	ir_unregister_map(&streamzap_map);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+module_init(init_rc_map_streamzap)
Jarod Wilson b9878dc
+module_exit(exit_rc_map_streamzap)
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+MODULE_LICENSE("GPL");
Jarod Wilson b9878dc
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
Jarod Wilson b9878dc
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/Makefile linux-2.6.35.x86_64/drivers/media/IR/Makefile
Jarod Wilson b9878dc
--- linux-2.6.35.x86_64.orig/drivers/media/IR/Makefile	2010-08-15 17:50:34.571382513 -0400
Jarod Wilson b9878dc
+++ linux-2.6.35.x86_64/drivers/media/IR/Makefile	2010-08-16 00:10:29.478144601 -0400
Jarod Wilson b9878dc
@@ -11,8 +11,10 @@ obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-d
Jarod Wilson b9878dc
 obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
Jarod Wilson b9878dc
 obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
Jarod Wilson b9878dc
 obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
Jarod Wilson b9878dc
+obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
Jarod Wilson b9878dc
 obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
Jarod Wilson b9878dc
 
Jarod Wilson b9878dc
 # stand-alone IR receivers/transmitters
Jarod Wilson b9878dc
 obj-$(CONFIG_IR_IMON) += imon.o
Jarod Wilson b9878dc
 obj-$(CONFIG_IR_MCEUSB) += mceusb.o
Jarod Wilson b9878dc
+obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
Jarod Wilson b9878dc
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/streamzap.c linux-2.6.35.x86_64/drivers/media/IR/streamzap.c
Jarod Wilson b9878dc
--- linux-2.6.35.x86_64.orig/drivers/media/IR/streamzap.c	1969-12-31 19:00:00.000000000 -0500
Jarod Wilson b9878dc
+++ linux-2.6.35.x86_64/drivers/media/IR/streamzap.c	2010-08-16 00:12:43.223932881 -0400
Jarod Wilson b9878dc
@@ -0,0 +1,569 @@
Jarod Wilson b9878dc
+/*
Jarod Wilson b9878dc
+ * Streamzap Remote Control driver
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * Copyright (c) 2005 Christoph Bartelmus <lirc@bartelmus.de>
Jarod Wilson b9878dc
+ * Copyright (c) 2010 Jarod Wilson <jarod@wilsonet.com>
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * This driver was based on the work of Greg Wickham and Adrian
Jarod Wilson b9878dc
+ * Dewhurst. It was substantially rewritten to support correct signal
Jarod Wilson b9878dc
+ * gaps and now maintains a delay buffer, which is used to present
Jarod Wilson b9878dc
+ * consistent timing behaviour to user space applications. Without the
Jarod Wilson b9878dc
+ * delay buffer an ugly hack would be required in lircd, which can
Jarod Wilson b9878dc
+ * cause sluggish signal decoding in certain situations.
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * Ported to in-kernel ir-core interface by Jarod Wilson
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * This driver is based on the USB skeleton driver packaged with the
Jarod Wilson b9878dc
+ * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ *  This program is free software; you can redistribute it and/or modify
Jarod Wilson b9878dc
+ *  it under the terms of the GNU General Public License as published by
Jarod Wilson b9878dc
+ *  the Free Software Foundation; either version 2 of the License, or
Jarod Wilson b9878dc
+ *  (at your option) any later version.
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ *  This program is distributed in the hope that it will be useful,
Jarod Wilson b9878dc
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Jarod Wilson b9878dc
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jarod Wilson b9878dc
+ *  GNU General Public License for more details.
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ *  You should have received a copy of the GNU General Public License
Jarod Wilson b9878dc
+ *  along with this program; if not, write to the Free Software
Jarod Wilson b9878dc
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+#include <linux/device.h>
Jarod Wilson b9878dc
+#include <linux/module.h>
Jarod Wilson b9878dc
+#include <linux/slab.h>
Jarod Wilson b9878dc
+#include <linux/usb.h>
Jarod Wilson b9878dc
+#include <linux/input.h>
Jarod Wilson b9878dc
+#include <media/ir-core.h>
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+#define DRIVER_VERSION	"1.61"
Jarod Wilson b9878dc
+#define DRIVER_NAME	"streamzap"
Jarod Wilson b9878dc
+#define DRIVER_DESC	"Streamzap Remote Control driver"
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+#ifdef CONFIG_USB_DEBUG
Jarod Wilson b9878dc
+static int debug = 1;
Jarod Wilson b9878dc
+#else
Jarod Wilson b9878dc
+static int debug;
Jarod Wilson b9878dc
+#endif
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+#define USB_STREAMZAP_VENDOR_ID		0x0e9c
Jarod Wilson b9878dc
+#define USB_STREAMZAP_PRODUCT_ID	0x0000
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/* table of devices that work with this driver */
Jarod Wilson b9878dc
+static struct usb_device_id streamzap_table[] = {
Jarod Wilson b9878dc
+	/* Streamzap Remote Control */
Jarod Wilson b9878dc
+	{ USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) },
Jarod Wilson b9878dc
+	/* Terminating entry */
Jarod Wilson b9878dc
+	{ }
Jarod Wilson b9878dc
+};
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+MODULE_DEVICE_TABLE(usb, streamzap_table);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+#define STREAMZAP_PULSE_MASK 0xf0
Jarod Wilson b9878dc
+#define STREAMZAP_SPACE_MASK 0x0f
Jarod Wilson b9878dc
+#define STREAMZAP_TIMEOUT    0xff
Jarod Wilson b9878dc
+#define STREAMZAP_RESOLUTION 256
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/* number of samples buffered */
Jarod Wilson b9878dc
+#define SZ_BUF_LEN 128
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/* from ir-rc5-sz-decoder.c */
Jarod Wilson b9878dc
+#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
Jarod Wilson b9878dc
+#define load_rc5_sz_decode()   request_module("ir-rc5-sz-decoder")
Jarod Wilson b9878dc
+#else
Jarod Wilson b9878dc
+#define load_rc5_sz_decode()   0
Jarod Wilson b9878dc
+#endif
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+enum StreamzapDecoderState {
Jarod Wilson b9878dc
+	PulseSpace,
Jarod Wilson b9878dc
+	FullPulse,
Jarod Wilson b9878dc
+	FullSpace,
Jarod Wilson b9878dc
+	IgnorePulse
Jarod Wilson b9878dc
+};
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/* structure to hold our device specific stuff */
Jarod Wilson b9878dc
+struct streamzap_ir {
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* ir-core */
Jarod Wilson b9878dc
+	struct ir_dev_props *props;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* core device info */
Jarod Wilson b9878dc
+	struct device *dev;
Jarod Wilson b9878dc
+	struct input_dev *idev;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* usb */
Jarod Wilson b9878dc
+	struct usb_device	*usbdev;
Jarod Wilson b9878dc
+	struct usb_interface	*interface;
Jarod Wilson b9878dc
+	struct usb_endpoint_descriptor *endpoint;
Jarod Wilson b9878dc
+	struct urb		*urb_in;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* buffer & dma */
Jarod Wilson b9878dc
+	unsigned char		*buf_in;
Jarod Wilson b9878dc
+	dma_addr_t		dma_in;
Jarod Wilson b9878dc
+	unsigned int		buf_in_len;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* track what state we're in */
Jarod Wilson b9878dc
+	enum StreamzapDecoderState decoder_state;
Jarod Wilson b9878dc
+	/* tracks whether we are currently receiving some signal */
Jarod Wilson b9878dc
+	bool			idle;
Jarod Wilson b9878dc
+	/* sum of signal lengths received since signal start */
Jarod Wilson b9878dc
+	unsigned long		sum;
Jarod Wilson b9878dc
+	/* start time of signal; necessary for gap tracking */
Jarod Wilson b9878dc
+	struct timeval		signal_last;
Jarod Wilson b9878dc
+	struct timeval		signal_start;
Jarod Wilson b9878dc
+	bool			timeout_enabled;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	char			name[128];
Jarod Wilson b9878dc
+	char			phys[64];
Jarod Wilson b9878dc
+};
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/* local function prototypes */
Jarod Wilson b9878dc
+static int streamzap_probe(struct usb_interface *interface,
Jarod Wilson b9878dc
+			   const struct usb_device_id *id);
Jarod Wilson b9878dc
+static void streamzap_disconnect(struct usb_interface *interface);
Jarod Wilson b9878dc
+static void streamzap_callback(struct urb *urb);
Jarod Wilson b9878dc
+static int streamzap_suspend(struct usb_interface *intf, pm_message_t message);
Jarod Wilson b9878dc
+static int streamzap_resume(struct usb_interface *intf);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/* usb specific object needed to register this driver with the usb subsystem */
Jarod Wilson b9878dc
+static struct usb_driver streamzap_driver = {
Jarod Wilson b9878dc
+	.name =		DRIVER_NAME,
Jarod Wilson b9878dc
+	.probe =	streamzap_probe,
Jarod Wilson b9878dc
+	.disconnect =	streamzap_disconnect,
Jarod Wilson b9878dc
+	.suspend =	streamzap_suspend,
Jarod Wilson b9878dc
+	.resume =	streamzap_resume,
Jarod Wilson b9878dc
+	.id_table =	streamzap_table,
Jarod Wilson b9878dc
+};
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	ir_raw_event_store(sz->idev, &rawir);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static void sz_push_full_pulse(struct streamzap_ir *sz,
Jarod Wilson b9878dc
+			       unsigned char value)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	struct ir_raw_event rawir;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (sz->idle) {
Jarod Wilson b9878dc
+		long deltv;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		sz->signal_last = sz->signal_start;
Jarod Wilson b9878dc
+		do_gettimeofday(&sz->signal_start);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec;
Jarod Wilson b9878dc
+		rawir.pulse = false;
Jarod Wilson b9878dc
+		if (deltv > 15) {
Jarod Wilson b9878dc
+			/* really long time */
Jarod Wilson b9878dc
+			rawir.duration = IR_MAX_DURATION;
Jarod Wilson b9878dc
+		} else {
Jarod Wilson b9878dc
+			rawir.duration = (int)(deltv * 1000000 +
Jarod Wilson b9878dc
+				sz->signal_start.tv_usec -
Jarod Wilson b9878dc
+				sz->signal_last.tv_usec);
Jarod Wilson b9878dc
+			rawir.duration -= sz->sum;
Jarod Wilson b9878dc
+			rawir.duration *= 1000;
Jarod Wilson b9878dc
+			rawir.duration &= IR_MAX_DURATION;
Jarod Wilson b9878dc
+		}
Jarod Wilson b9878dc
+		dev_dbg(sz->dev, "ls %u\n", rawir.duration);
Jarod Wilson b9878dc
+		sz_push(sz, rawir);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+		sz->idle = false;
Jarod Wilson b9878dc
+		sz->sum = 0;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	rawir.pulse = true;
Jarod Wilson b9878dc
+	rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
Jarod Wilson b9878dc
+	rawir.duration += STREAMZAP_RESOLUTION / 2;
Jarod Wilson b9878dc
+	sz->sum += rawir.duration;
Jarod Wilson b9878dc
+	rawir.duration *= 1000;
Jarod Wilson b9878dc
+	rawir.duration &= IR_MAX_DURATION;
Jarod Wilson b9878dc
+	dev_dbg(sz->dev, "p %u\n", rawir.duration);
Jarod Wilson b9878dc
+	sz_push(sz, rawir);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static void sz_push_half_pulse(struct streamzap_ir *sz,
Jarod Wilson b9878dc
+			       unsigned char value)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	sz_push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK) >> 4);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static void sz_push_full_space(struct streamzap_ir *sz,
Jarod Wilson b9878dc
+			       unsigned char value)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	struct ir_raw_event rawir;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	rawir.pulse = false;
Jarod Wilson b9878dc
+	rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
Jarod Wilson b9878dc
+	rawir.duration += STREAMZAP_RESOLUTION / 2;
Jarod Wilson b9878dc
+	sz->sum += rawir.duration;
Jarod Wilson b9878dc
+	rawir.duration *= 1000;
Jarod Wilson b9878dc
+	dev_dbg(sz->dev, "s %u\n", rawir.duration);
Jarod Wilson b9878dc
+	sz_push(sz, rawir);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static void sz_push_half_space(struct streamzap_ir *sz,
Jarod Wilson b9878dc
+			       unsigned long value)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	sz_push_full_space(sz, value & STREAMZAP_SPACE_MASK);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/**
Jarod Wilson b9878dc
+ * streamzap_callback - usb IRQ handler callback
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * This procedure is invoked on reception of data from
Jarod Wilson b9878dc
+ * the usb remote.
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+static void streamzap_callback(struct urb *urb)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	struct streamzap_ir *sz;
Jarod Wilson b9878dc
+	unsigned int i;
Jarod Wilson b9878dc
+	int len;
Jarod Wilson b9878dc
+	static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) &
Jarod Wilson b9878dc
+				IR_MAX_DURATION) | 0x03000000);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (!urb)
Jarod Wilson b9878dc
+		return;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	sz = urb->context;
Jarod Wilson b9878dc
+	len = urb->actual_length;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	switch (urb->status) {
Jarod Wilson b9878dc
+	case -ECONNRESET:
Jarod Wilson b9878dc
+	case -ENOENT:
Jarod Wilson b9878dc
+	case -ESHUTDOWN:
Jarod Wilson b9878dc
+		/*
Jarod Wilson b9878dc
+		 * this urb is terminated, clean up.
Jarod Wilson b9878dc
+		 * sz might already be invalid at this point
Jarod Wilson b9878dc
+		 */
Jarod Wilson b9878dc
+		dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
Jarod Wilson b9878dc
+		return;
Jarod Wilson b9878dc
+	default:
Jarod Wilson b9878dc
+		break;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	dev_info(sz->dev, "%s: received urb, len %d\n", __func__, len);
Jarod Wilson b9878dc
+	for (i = 0; i < len; i++) {
Jarod Wilson b9878dc
+		dev_info(sz->dev, "sz idx %d: %x\n",
Jarod Wilson b9878dc
+			i, (unsigned char)sz->buf_in[i]);
Jarod Wilson b9878dc
+		switch (sz->decoder_state) {
Jarod Wilson b9878dc
+		case PulseSpace:
Jarod Wilson b9878dc
+			if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
Jarod Wilson b9878dc
+				STREAMZAP_PULSE_MASK) {
Jarod Wilson b9878dc
+				sz->decoder_state = FullPulse;
Jarod Wilson b9878dc
+				continue;
Jarod Wilson b9878dc
+			} else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
Jarod Wilson b9878dc
+					== STREAMZAP_SPACE_MASK) {
Jarod Wilson b9878dc
+				sz_push_half_pulse(sz, sz->buf_in[i]);
Jarod Wilson b9878dc
+				sz->decoder_state = FullSpace;
Jarod Wilson b9878dc
+				continue;
Jarod Wilson b9878dc
+			} else {
Jarod Wilson b9878dc
+				sz_push_half_pulse(sz, sz->buf_in[i]);
Jarod Wilson b9878dc
+				sz_push_half_space(sz, sz->buf_in[i]);
Jarod Wilson b9878dc
+			}
Jarod Wilson b9878dc
+			break;
Jarod Wilson b9878dc
+		case FullPulse:
Jarod Wilson b9878dc
+			sz_push_full_pulse(sz, sz->buf_in[i]);
Jarod Wilson b9878dc
+			sz->decoder_state = IgnorePulse;
Jarod Wilson b9878dc
+			break;
Jarod Wilson b9878dc
+		case FullSpace:
Jarod Wilson b9878dc
+			if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
Jarod Wilson b9878dc
+				struct ir_raw_event rawir;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+				rawir.pulse = false;
Jarod Wilson b9878dc
+				rawir.duration = timeout * 1000;
Jarod Wilson b9878dc
+				sz->idle = true;
Jarod Wilson b9878dc
+				if (sz->timeout_enabled)
Jarod Wilson b9878dc
+					sz_push(sz, rawir);
Jarod Wilson b9878dc
+				ir_raw_event_handle(sz->idev);
Jarod Wilson b9878dc
+			} else {
Jarod Wilson b9878dc
+				sz_push_full_space(sz, sz->buf_in[i]);
Jarod Wilson b9878dc
+			}
Jarod Wilson b9878dc
+			sz->decoder_state = PulseSpace;
Jarod Wilson b9878dc
+			break;
Jarod Wilson b9878dc
+		case IgnorePulse:
Jarod Wilson b9878dc
+			if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK) ==
Jarod Wilson b9878dc
+				STREAMZAP_SPACE_MASK) {
Jarod Wilson b9878dc
+				sz->decoder_state = FullSpace;
Jarod Wilson b9878dc
+				continue;
Jarod Wilson b9878dc
+			}
Jarod Wilson b9878dc
+			sz_push_half_space(sz, sz->buf_in[i]);
Jarod Wilson b9878dc
+			sz->decoder_state = PulseSpace;
Jarod Wilson b9878dc
+			break;
Jarod Wilson b9878dc
+		}
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	usb_submit_urb(urb, GFP_ATOMIC);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	return;
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	struct input_dev *idev;
Jarod Wilson b9878dc
+	struct ir_dev_props *props;
Jarod Wilson b9878dc
+	struct device *dev = sz->dev;
Jarod Wilson b9878dc
+	int ret;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	idev = input_allocate_device();
Jarod Wilson b9878dc
+	if (!idev) {
Jarod Wilson b9878dc
+		dev_err(dev, "remote input dev allocation failed\n");
Jarod Wilson b9878dc
+		goto idev_alloc_failed;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
Jarod Wilson b9878dc
+	if (!props) {
Jarod Wilson b9878dc
+		dev_err(dev, "remote ir dev props allocation failed\n");
Jarod Wilson b9878dc
+		goto props_alloc_failed;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared "
Jarod Wilson b9878dc
+		 "Receiver (%04x:%04x)",
Jarod Wilson b9878dc
+		 le16_to_cpu(sz->usbdev->descriptor.idVendor),
Jarod Wilson b9878dc
+		 le16_to_cpu(sz->usbdev->descriptor.idProduct));
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	idev->name = sz->name;
Jarod Wilson b9878dc
+	usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
Jarod Wilson b9878dc
+	strlcat(sz->phys, "/input0", sizeof(sz->phys));
Jarod Wilson b9878dc
+	idev->phys = sz->phys;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	props->priv = sz;
Jarod Wilson b9878dc
+	props->driver_type = RC_DRIVER_IR_RAW;
Jarod Wilson b9878dc
+	props->allowed_protos = IR_TYPE_ALL;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	sz->props = props;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
Jarod Wilson b9878dc
+	if (ret < 0) {
Jarod Wilson b9878dc
+		dev_err(dev, "remote input device register failed\n");
Jarod Wilson b9878dc
+		goto irdev_failed;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	return idev;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+irdev_failed:
Jarod Wilson b9878dc
+	kfree(props);
Jarod Wilson b9878dc
+props_alloc_failed:
Jarod Wilson b9878dc
+	input_free_device(idev);
Jarod Wilson b9878dc
+idev_alloc_failed:
Jarod Wilson b9878dc
+	return NULL;
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/**
Jarod Wilson b9878dc
+ *	streamzap_probe
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ *	Called by usb-core to associated with a candidate device
Jarod Wilson b9878dc
+ *	On any failure the return value is the ERROR
Jarod Wilson b9878dc
+ *	On success return 0
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+static int __devinit streamzap_probe(struct usb_interface *intf,
Jarod Wilson b9878dc
+				     const struct usb_device_id *id)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	struct usb_device *usbdev = interface_to_usbdev(intf);
Jarod Wilson b9878dc
+	struct usb_host_interface *iface_host;
Jarod Wilson b9878dc
+	struct streamzap_ir *sz = NULL;
Jarod Wilson b9878dc
+	char buf[63], name[128] = "";
Jarod Wilson b9878dc
+	int retval = -ENOMEM;
Jarod Wilson b9878dc
+	int pipe, maxp;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* Allocate space for device driver specific data */
Jarod Wilson b9878dc
+	sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL);
Jarod Wilson b9878dc
+	if (!sz)
Jarod Wilson b9878dc
+		return -ENOMEM;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	sz->usbdev = usbdev;
Jarod Wilson b9878dc
+	sz->interface = intf;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* Check to ensure endpoint information matches requirements */
Jarod Wilson b9878dc
+	iface_host = intf->cur_altsetting;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (iface_host->desc.bNumEndpoints != 1) {
Jarod Wilson b9878dc
+		dev_err(&intf->dev, "%s: Unexpected desc.bNumEndpoints (%d)\n",
Jarod Wilson b9878dc
+			__func__, iface_host->desc.bNumEndpoints);
Jarod Wilson b9878dc
+		retval = -ENODEV;
Jarod Wilson b9878dc
+		goto free_sz;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	sz->endpoint = &(iface_host->endpoint[0].desc);
Jarod Wilson b9878dc
+	if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
Jarod Wilson b9878dc
+	    != USB_DIR_IN) {
Jarod Wilson b9878dc
+		dev_err(&intf->dev, "%s: endpoint doesn't match input device "
Jarod Wilson b9878dc
+			"02%02x\n", __func__, sz->endpoint->bEndpointAddress);
Jarod Wilson b9878dc
+		retval = -ENODEV;
Jarod Wilson b9878dc
+		goto free_sz;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
Jarod Wilson b9878dc
+	    != USB_ENDPOINT_XFER_INT) {
Jarod Wilson b9878dc
+		dev_err(&intf->dev, "%s: endpoint attributes don't match xfer "
Jarod Wilson b9878dc
+			"02%02x\n", __func__, sz->endpoint->bmAttributes);
Jarod Wilson b9878dc
+		retval = -ENODEV;
Jarod Wilson b9878dc
+		goto free_sz;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	pipe = usb_rcvintpipe(usbdev, sz->endpoint->bEndpointAddress);
Jarod Wilson b9878dc
+	maxp = usb_maxpacket(usbdev, pipe, usb_pipeout(pipe));
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (maxp == 0) {
Jarod Wilson b9878dc
+		dev_err(&intf->dev, "%s: endpoint Max Packet Size is 0!?!\n",
Jarod Wilson b9878dc
+			__func__);
Jarod Wilson b9878dc
+		retval = -ENODEV;
Jarod Wilson b9878dc
+		goto free_sz;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* Allocate the USB buffer and IRQ URB */
Jarod Wilson b9878dc
+	sz->buf_in = usb_alloc_coherent(usbdev, maxp, GFP_ATOMIC, &sz->dma_in);
Jarod Wilson b9878dc
+	if (!sz->buf_in)
Jarod Wilson b9878dc
+		goto free_sz;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	sz->urb_in = usb_alloc_urb(0, GFP_KERNEL);
Jarod Wilson b9878dc
+	if (!sz->urb_in)
Jarod Wilson b9878dc
+		goto free_buf_in;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	sz->dev = &intf->dev;
Jarod Wilson b9878dc
+	sz->buf_in_len = maxp;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (usbdev->descriptor.iManufacturer
Jarod Wilson b9878dc
+	    && usb_string(usbdev, usbdev->descriptor.iManufacturer,
Jarod Wilson b9878dc
+			  buf, sizeof(buf)) > 0)
Jarod Wilson b9878dc
+		strlcpy(name, buf, sizeof(name));
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (usbdev->descriptor.iProduct
Jarod Wilson b9878dc
+	    && usb_string(usbdev, usbdev->descriptor.iProduct,
Jarod Wilson b9878dc
+			  buf, sizeof(buf)) > 0)
Jarod Wilson b9878dc
+		snprintf(name + strlen(name), sizeof(name) - strlen(name),
Jarod Wilson b9878dc
+			 " %s", buf);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	sz->idev = streamzap_init_input_dev(sz);
Jarod Wilson b9878dc
+	if (!sz->idev)
Jarod Wilson b9878dc
+		goto input_dev_fail;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	sz->idle = true;
Jarod Wilson b9878dc
+	sz->decoder_state = PulseSpace;
Jarod Wilson b9878dc
+	/* FIXME: don't yet have a way to set this */
Jarod Wilson b9878dc
+	sz->timeout_enabled = true;
Jarod Wilson b9878dc
+	#if 0
Jarod Wilson b9878dc
+	/* not yet supported, depends on patches from maxim */
Jarod Wilson b9878dc
+	/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
Jarod Wilson b9878dc
+	sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
Jarod Wilson b9878dc
+	sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
Jarod Wilson b9878dc
+	#endif
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	do_gettimeofday(&sz->signal_start);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* Complete final initialisations */
Jarod Wilson b9878dc
+	usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in,
Jarod Wilson b9878dc
+			 maxp, (usb_complete_t)streamzap_callback,
Jarod Wilson b9878dc
+			 sz, sz->endpoint->bInterval);
Jarod Wilson b9878dc
+	sz->urb_in->transfer_dma = sz->dma_in;
Jarod Wilson b9878dc
+	sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	usb_set_intfdata(intf, sz);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
Jarod Wilson b9878dc
+		dev_err(sz->dev, "urb submit failed\n");
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
Jarod Wilson b9878dc
+		 usbdev->bus->busnum, usbdev->devnum);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* Load the streamzap not-quite-rc5 decoder too */
Jarod Wilson b9878dc
+	load_rc5_sz_decode();
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	return 0;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+input_dev_fail:
Jarod Wilson b9878dc
+	usb_free_urb(sz->urb_in);
Jarod Wilson b9878dc
+free_buf_in:
Jarod Wilson b9878dc
+	usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
Jarod Wilson b9878dc
+free_sz:
Jarod Wilson b9878dc
+	kfree(sz);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	return retval;
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/**
Jarod Wilson b9878dc
+ * streamzap_disconnect
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * Called by the usb core when the device is removed from the system.
Jarod Wilson b9878dc
+ *
Jarod Wilson b9878dc
+ * This routine guarantees that the driver will not submit any more urbs
Jarod Wilson b9878dc
+ * by clearing dev->usbdev.  It is also supposed to terminate any currently
Jarod Wilson b9878dc
+ * active urbs.  Unfortunately, usb_bulk_msg(), used in streamzap_read(),
Jarod Wilson b9878dc
+ * does not provide any way to do this.
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+static void streamzap_disconnect(struct usb_interface *interface)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	struct streamzap_ir *sz = usb_get_intfdata(interface);
Jarod Wilson b9878dc
+	struct usb_device *usbdev = interface_to_usbdev(interface);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	usb_set_intfdata(interface, NULL);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (!sz)
Jarod Wilson b9878dc
+		return;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	sz->usbdev = NULL;
Jarod Wilson b9878dc
+	ir_input_unregister(sz->idev);
Jarod Wilson b9878dc
+	usb_kill_urb(sz->urb_in);
Jarod Wilson b9878dc
+	usb_free_urb(sz->urb_in);
Jarod Wilson b9878dc
+	usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	kfree(sz);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	struct streamzap_ir *sz = usb_get_intfdata(intf);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	usb_kill_urb(sz->urb_in);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	return 0;
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+static int streamzap_resume(struct usb_interface *intf)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	struct streamzap_ir *sz = usb_get_intfdata(intf);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
Jarod Wilson b9878dc
+		dev_err(sz->dev, "Error sumbiting urb\n");
Jarod Wilson b9878dc
+		return -EIO;
Jarod Wilson b9878dc
+	}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	return 0;
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/**
Jarod Wilson b9878dc
+ *	streamzap_init
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+static int __init streamzap_init(void)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	int ret;
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	/* register this driver with the USB subsystem */
Jarod Wilson b9878dc
+	ret = usb_register(&streamzap_driver);
Jarod Wilson b9878dc
+	if (ret < 0)
Jarod Wilson b9878dc
+		printk(KERN_ERR DRIVER_NAME ": usb register failed, "
Jarod Wilson b9878dc
+		       "result = %d\n", ret);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+	return ret;
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+/**
Jarod Wilson b9878dc
+ *	streamzap_exit
Jarod Wilson b9878dc
+ */
Jarod Wilson b9878dc
+static void __exit streamzap_exit(void)
Jarod Wilson b9878dc
+{
Jarod Wilson b9878dc
+	usb_deregister(&streamzap_driver);
Jarod Wilson b9878dc
+}
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+module_init(streamzap_init);
Jarod Wilson b9878dc
+module_exit(streamzap_exit);
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+MODULE_AUTHOR("Jarod Wilson <jarod@wilsonet.com>");
Jarod Wilson b9878dc
+MODULE_DESCRIPTION(DRIVER_DESC);
Jarod Wilson b9878dc
+MODULE_LICENSE("GPL");
Jarod Wilson b9878dc
+
Jarod Wilson b9878dc
+module_param(debug, bool, S_IRUGO | S_IWUSR);
Jarod Wilson b9878dc
+MODULE_PARM_DESC(debug, "Enable debugging messages");
Jarod Wilson b9878dc
diff -Naurp linux-2.6.35.x86_64.orig/include/media/rc-map.h linux-2.6.35.x86_64/include/media/rc-map.h
Jarod Wilson b9878dc
--- linux-2.6.35.x86_64.orig/include/media/rc-map.h	2010-08-15 17:50:34.584382568 -0400
Jarod Wilson b9878dc
+++ linux-2.6.35.x86_64/include/media/rc-map.h	2010-08-16 00:18:02.455993732 -0400
Jarod Wilson b9878dc
@@ -17,12 +17,13 @@
Jarod Wilson b9878dc
 #define IR_TYPE_RC6	(1  << 2)	/* Philips RC6 protocol */
Jarod Wilson b9878dc
 #define IR_TYPE_JVC	(1  << 3)	/* JVC protocol */
Jarod Wilson b9878dc
 #define IR_TYPE_SONY	(1  << 4)	/* Sony12/15/20 protocol */
Jarod Wilson b9878dc
+#define IR_TYPE_RC5_SZ	(1  << 5)	/* RC5 variant used by Streamzap */
Jarod Wilson b9878dc
 #define IR_TYPE_LIRC	(1  << 30)	/* Pass raw IR to lirc userspace */
Jarod Wilson b9878dc
 #define IR_TYPE_OTHER	(1u << 31)
Jarod Wilson b9878dc
 
Jarod Wilson b9878dc
 #define IR_TYPE_ALL (IR_TYPE_RC5 | IR_TYPE_NEC  | IR_TYPE_RC6  | \
Jarod Wilson b9878dc
 		     IR_TYPE_JVC | IR_TYPE_SONY | IR_TYPE_LIRC | \
Jarod Wilson b9878dc
-		     IR_TYPE_OTHER)
Jarod Wilson b9878dc
+		     IR_TYPE_RC5_SZ | IR_TYPE_OTHER)
Jarod Wilson b9878dc
 
Jarod Wilson b9878dc
 struct ir_scancode {
Jarod Wilson b9878dc
 	u32	scancode;
Jarod Wilson b9878dc
@@ -115,6 +116,7 @@ void rc_map_init(void);
Jarod Wilson b9878dc
 #define RC_MAP_RC5_TV                    "rc-rc5-tv"
Jarod Wilson b9878dc
 #define RC_MAP_RC6_MCE                   "rc-rc6-mce"
Jarod Wilson b9878dc
 #define RC_MAP_REAL_AUDIO_220_32_KEYS    "rc-real-audio-220-32-keys"
Jarod Wilson b9878dc
+#define RC_MAP_STREAMZAP                 "rc-streamzap"
Jarod Wilson b9878dc
 #define RC_MAP_TBS_NEC                   "rc-tbs-nec"
Jarod Wilson b9878dc
 #define RC_MAP_TERRATEC_CINERGY_XS       "rc-terratec-cinergy-xs"
Jarod Wilson b9878dc
 #define RC_MAP_TEVII_NEC                 "rc-tevii-nec"