diff options
Diffstat (limited to 'abs/core/lirc')
-rw-r--r-- | abs/core/lirc/kernel-2.6.35.patch | 1654 |
1 files changed, 1654 insertions, 0 deletions
diff --git a/abs/core/lirc/kernel-2.6.35.patch b/abs/core/lirc/kernel-2.6.35.patch new file mode 100644 index 0000000..179fe65 --- /dev/null +++ b/abs/core/lirc/kernel-2.6.35.patch @@ -0,0 +1,1654 @@ +--- drivers/lirc_atiusb/lirc_atiusb.c 2009/03/11 00:21:46 1.85 ++++ drivers/lirc_atiusb/lirc_atiusb.c 2010/03/17 14:16:15 1.86 +@@ -17,7 +17,7 @@ + * Vassilis Virvilis <vasvir@iit.demokritos.gr> 2006 + * reworked the patch for lirc submission + * +- * $Id: lirc_atiusb.c,v 1.85 2009/03/11 00:21:46 jarodwilson Exp $ ++ * $Id: lirc_atiusb.c,v 1.86 2010/03/17 14:16:15 jarodwilson Exp $ + */ + + /* +@@ -67,7 +69,7 @@ + #include "drivers/kcompat.h" + #include "drivers/lirc_dev/lirc_dev.h" + +-#define DRIVER_VERSION "$Revision: 1.85 $" ++#define DRIVER_VERSION "$Revision: 1.86 $" + #define DRIVER_AUTHOR "Paul Miller <pmiller9@users.sourceforge.net>" + #define DRIVER_DESC "USB remote driver for LIRC" + #define DRIVER_NAME "lirc_atiusb" +@@ -1374,7 +1376,7 @@ + DRIVER_VERSION "\n"); + printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); + dprintk(DRIVER_NAME ": debug mode enabled: " +- "$Id: lirc_atiusb.c,v 1.85 2009/03/11 00:21:46 jarodwilson Exp $\n"); ++ "$Id: lirc_atiusb.c,v 1.86 2010/03/17 14:16:15 jarodwilson Exp $\n"); + + repeat_jiffies = repeat*HZ/100; + +--- drivers/lirc_atiusb/lirc_atiusb.c 2010/03/17 14:16:15 1.86 ++++ drivers/lirc_atiusb/lirc_atiusb.c 2010/07/24 14:35:58 1.87 +@@ -17,7 +17,7 @@ + * Vassilis Virvilis <vasvir@iit.demokritos.gr> 2006 + * reworked the patch for lirc submission + * +- * $Id: lirc_atiusb.c,v 1.86 2010/03/17 14:16:15 jarodwilson Exp $ ++ * $Id: lirc_atiusb.c,v 1.87 2010/07/24 14:35:58 jarodwilson Exp $ + */ + + /* +@@ -69,7 +69,7 @@ + #include "drivers/kcompat.h" + #include "drivers/lirc_dev/lirc_dev.h" + +-#define DRIVER_VERSION "$Revision: 1.86 $" ++#define DRIVER_VERSION "$Revision: 1.87 $" + #define DRIVER_AUTHOR "Paul Miller <pmiller9@users.sourceforge.net>" + #define DRIVER_DESC "USB remote driver for LIRC" + #define DRIVER_NAME "lirc_atiusb" +@@ -824,7 +824,11 @@ + ir->devnum); + case 3: + #ifdef KERNEL_2_5 ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) ++ usb_free_coherent(iep->ir->usbdev, iep->len, iep->buf, iep->dma); ++#else + usb_buffer_free(iep->ir->usbdev, iep->len, iep->buf, iep->dma); ++#endif + #else + kfree(iep->buf); + #endif +@@ -869,7 +873,11 @@ + iep->len = len; + + #ifdef KERNEL_2_5 ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) ++ iep->buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &iep->dma); ++#else + iep->buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &iep->dma); ++#endif + #else + iep->buf = kmalloc(len, GFP_KERNEL); + #endif +@@ -931,8 +939,13 @@ + } + case 3: + #ifdef KERNEL_2_5 ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) ++ usb_free_coherent(oep->ir->usbdev, USB_OUTLEN, ++ oep->buf, oep->dma); ++#else + usb_buffer_free(oep->ir->usbdev, USB_OUTLEN, + oep->buf, oep->dma); ++#endif + #else + kfree(oep->buf); + #endif +@@ -965,8 +978,13 @@ + init_waitqueue_head(&oep->wait); + + #ifdef KERNEL_2_5 ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) ++ oep->buf = usb_alloc_coherent(dev, USB_OUTLEN, ++ GFP_ATOMIC, &oep->dma); ++#else + oep->buf = usb_buffer_alloc(dev, USB_OUTLEN, + GFP_ATOMIC, &oep->dma); ++#endif + #else + oep->buf = kmalloc(USB_OUTLEN, GFP_KERNEL); + #endif +@@ -1376,7 +1394,7 @@ + DRIVER_VERSION "\n"); + printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); + dprintk(DRIVER_NAME ": debug mode enabled: " +- "$Id: lirc_atiusb.c,v 1.86 2010/03/17 14:16:15 jarodwilson Exp $\n"); ++ "$Id: lirc_atiusb.c,v 1.87 2010/07/24 14:35:58 jarodwilson Exp $\n"); + + repeat_jiffies = repeat*HZ/100; + +--- drivers/lirc_atiusb/lirc_atiusb.c 2010/07/24 14:35:58 1.87 ++++ drivers/lirc_atiusb/lirc_atiusb.c 2010/07/25 16:43:33 1.88 +@@ -17,7 +17,7 @@ + * Vassilis Virvilis <vasvir@iit.demokritos.gr> 2006 + * reworked the patch for lirc submission + * +- * $Id: lirc_atiusb.c,v 1.87 2010/07/24 14:35:58 jarodwilson Exp $ ++ * $Id: lirc_atiusb.c,v 1.88 2010/07/25 16:43:33 jarodwilson Exp $ + */ + + /* +@@ -69,7 +69,7 @@ + #include "drivers/kcompat.h" + #include "drivers/lirc_dev/lirc_dev.h" + +-#define DRIVER_VERSION "$Revision: 1.87 $" ++#define DRIVER_VERSION "$Revision: 1.88 $" + #define DRIVER_AUTHOR "Paul Miller <pmiller9@users.sourceforge.net>" + #define DRIVER_DESC "USB remote driver for LIRC" + #define DRIVER_NAME "lirc_atiusb" +@@ -824,12 +824,8 @@ + ir->devnum); + case 3: + #ifdef KERNEL_2_5 +-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) + usb_free_coherent(iep->ir->usbdev, iep->len, iep->buf, iep->dma); + #else +- usb_buffer_free(iep->ir->usbdev, iep->len, iep->buf, iep->dma); +-#endif +-#else + kfree(iep->buf); + #endif + iep->buf = 0; +@@ -873,12 +869,8 @@ + iep->len = len; + + #ifdef KERNEL_2_5 +-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) + iep->buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &iep->dma); + #else +- iep->buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &iep->dma); +-#endif +-#else + iep->buf = kmalloc(len, GFP_KERNEL); + #endif + if (!iep->buf) { +@@ -939,14 +931,9 @@ + } + case 3: + #ifdef KERNEL_2_5 +-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) + usb_free_coherent(oep->ir->usbdev, USB_OUTLEN, + oep->buf, oep->dma); + #else +- usb_buffer_free(oep->ir->usbdev, USB_OUTLEN, +- oep->buf, oep->dma); +-#endif +-#else + kfree(oep->buf); + #endif + oep->buf = 0; +@@ -978,14 +965,9 @@ + init_waitqueue_head(&oep->wait); + + #ifdef KERNEL_2_5 +-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) + oep->buf = usb_alloc_coherent(dev, USB_OUTLEN, + GFP_ATOMIC, &oep->dma); + #else +- oep->buf = usb_buffer_alloc(dev, USB_OUTLEN, +- GFP_ATOMIC, &oep->dma); +-#endif +-#else + oep->buf = kmalloc(USB_OUTLEN, GFP_KERNEL); + #endif + if (!oep->buf) +@@ -1394,7 +1376,7 @@ + DRIVER_VERSION "\n"); + printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); + dprintk(DRIVER_NAME ": debug mode enabled: " +- "$Id: lirc_atiusb.c,v 1.87 2010/07/24 14:35:58 jarodwilson Exp $\n"); ++ "$Id: lirc_atiusb.c,v 1.88 2010/07/25 16:43:33 jarodwilson Exp $\n"); + + repeat_jiffies = repeat*HZ/100; + +--- drivers/kcompat.h 2009/08/02 11:15:28 5.45 ++++ drivers/kcompat.h 2010/07/27 05:43:21 5.50 +@@ -1,4 +1,4 @@ +-/* $Id: kcompat.h,v 5.45 2009/08/02 11:15:28 lirc Exp $ */ ++/* $Id: kcompat.h,v 5.50 2010/07/27 05:43:21 jarodwilson Exp $ */ + + #ifndef _KCOMPAT_H + #define _KCOMPAT_H +@@ -9,6 +9,11 @@ + #define __func__ __FUNCTION__ + #endif + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34) ++#define usb_alloc_coherent usb_buffer_alloc ++#define usb_free_coherent usb_buffer_free ++#endif ++ + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + #define LIRC_THIS_MODULE(x) x, + #else /* >= 2.6.16 */ +@@ -364,6 +369,11 @@ + #endif /* kernel < 2.6.11 */ + #endif /* kernel >= 2.6.0 */ + ++/*************************** pm_wakeup.h ******************************/ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) ++static inline void device_set_wakeup_capable(struct device *dev, int val) {} ++#endif /* kernel < 2.6.27 */ ++ + /*************************** interrupt.h ******************************/ + /* added in 2.6.18, old defines removed in 2.6.24 */ + #ifndef IRQF_DISABLED +@@ -378,6 +388,9 @@ + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) + #define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED + #endif ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) ++#define __SPIN_LOCK_UNLOCKED(x) SPIN_LOCK_UNLOCKED; ++#endif + + /***************************** slab.h *********************************/ + /* added in 2.6.14 */ +@@ -405,4 +418,14 @@ + #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) + #endif + ++/****************************** kernel.h **********************************/ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) ++#define DIV_ROUND_CLOSEST(x, divisor)( \ ++{ \ ++ typeof(divisor) __divisor = divisor; \ ++ (((x) + ((__divisor) / 2)) / (__divisor)); \ ++} \ ++) ++#endif ++ + #endif /* _KCOMPAT_H */ +--- drivers/lirc_igorplugusb/lirc_igorplugusb.c 2009/11/09 18:59:21 1.35 ++++ drivers/lirc_igorplugusb/lirc_igorplugusb.c 2010/07/25 16:43:33 1.38 +@@ -450,7 +452,7 @@ + } + + #if defined(KERNEL_2_5) +- ir->buf_in = usb_buffer_alloc(dev, ++ ir->buf_in = usb_alloc_coherent(dev, + DEVICE_BUFLEN+DEVICE_HEADERLEN, + GFP_ATOMIC, &ir->dma_in); + #else +@@ -486,7 +488,7 @@ + switch (mem_failure) { + case 9: + #if defined(KERNEL_2_5) +- usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, ++ usb_free_coherent(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, + ir->buf_in, ir->dma_in); + #else + kfree(ir->buf_in); +@@ -566,7 +568,7 @@ + + + #if defined(KERNEL_2_5) +- usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in); ++ usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); + #else + kfree(ir->buf_in); + #endif +--- drivers/lirc_mceusb/lirc_mceusb.c 2010/03/17 14:16:16 1.54 ++++ drivers/lirc_mceusb/lirc_mceusb.c 2010/07/25 16:43:33 1.70 +@@ -80,6 +80,7 @@ + #define DRIVER_NAME "lirc_mceusb" + + #define USB_BUFLEN 32 /* USB reception buffer length */ ++#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ + #define LIRCBUF_SIZE 256 /* LIRC work buffer length */ + + /* MCE constants */ +@@ -95,7 +96,7 @@ + #define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ + #define MCE_PULSE_MASK 0x7F /* Pulse mask */ + #define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */ +-#define MCE_PACKET_LENGTH_MASK 0x7F /* Pulse mask */ ++#define MCE_PACKET_LENGTH_MASK 0x7F /* Packet length mask */ + + + /* module parameters */ +@@ -116,8 +117,8 @@ + #define RECV_FLAG_IN_PROGRESS 3 + #define RECV_FLAG_COMPLETE 4 + +-#define MCEUSB_INBOUND 1 +-#define MCEUSB_OUTBOUND 2 ++#define MCEUSB_RX 1 ++#define MCEUSB_TX 2 + + #define VENDOR_PHILIPS 0x0471 + #define VENDOR_SMK 0x0609 +@@ -211,6 +212,8 @@ + { USB_DEVICE(VENDOR_FORMOSA, 0xe03a) }, + /* Formosa Industrial Computing AIM IR605/A */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) }, ++ /* Formosa Industrial Computing AIM IR605/A */ ++ { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) }, + /* Fintek eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FINTEK, 0x0602) }, + /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ +@@ -233,8 +236,9 @@ + { } + }; + +-static struct usb_device_id pinnacle_list[] = { ++static struct usb_device_id gen3_list[] = { + { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, + {} + }; + +@@ -282,10 +286,9 @@ + unsigned char is_pulse; + struct { + u32 connected:1; +- u32 pinnacle:1; + u32 transmitter_mask_inverted:1; + u32 microsoft_gen1:1; +- u32 reserved:28; ++ u32 reserved:29; + } flags; + + unsigned char transmitter_mask; +@@ -295,16 +298,44 @@ + int send_flags; + wait_queue_head_t wait_out; + +- struct mutex lock; ++ struct mutex dev_lock; + }; + +-/* init strings */ +-static char init1[] = {0x00, 0xff, 0xaa, 0xff, 0x0b}; +-static char init2[] = {0xff, 0x18}; +- +-static char pin_init1[] = { 0x9f, 0x07}; +-static char pin_init2[] = { 0x9f, 0x13}; +-static char pin_init3[] = { 0x9f, 0x0d}; ++/* ++ * MCE Device Command Strings ++ * Device command responses vary from device to device... ++ * - DEVICE_RESET resets the hardware to its default state ++ * - GET_REVISION fetches the hardware/software revision, common ++ * replies are ff 0b 45 ff 1b 08 and ff 0b 50 ff 1b 42 ++ * - GET_CARRIER_FREQ gets the carrier mode and frequency of the ++ * device, with replies in the form of 9f 06 MM FF, where MM is 0-3, ++ * meaning clk of 10000000, 2500000, 625000 or 156250, and FF is ++ * ((clk / frequency) - 1) ++ * - GET_RX_TIMEOUT fetches the receiver timeout in units of 50us, ++ * response in the form of 9f 0c msb lsb ++ * - GET_TX_BITMASK fetches the transmitter bitmask, replies in ++ * the form of 9f 08 bm, where bm is the bitmask ++ * - GET_RX_SENSOR fetches the RX sensor setting -- long-range ++ * general use one or short-range learning one, in the form of ++ * 9f 14 ss, where ss is either 01 for long-range or 02 for short ++ * - SET_CARRIER_FREQ sets a new carrier mode and frequency ++ * - SET_TX_BITMASK sets the transmitter bitmask ++ * - SET_RX_TIMEOUT sets the receiver timeout ++ * - SET_RX_SENSOR sets which receiver sensor to use ++ */ ++static char DEVICE_RESET[] = {0x00, 0xff, 0xaa}; ++static char GET_REVISION[] = {0xff, 0x0b}; ++static char GET_UNKNOWN[] = {0xff, 0x18}; ++static char GET_UNKNOWN2[] = {0x9f, 0x05}; ++static char GET_CARRIER_FREQ[] = {0x9f, 0x07}; ++static char GET_RX_TIMEOUT[] = {0x9f, 0x0d}; ++static char GET_TX_BITMASK[] = {0x9f, 0x13}; ++static char GET_RX_SENSOR[] = {0x9f, 0x15}; ++/* sub in desired values in lower byte or bytes for full command */ ++//static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00}; ++//static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00}; ++//static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00}; ++//static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00}; + + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) + static unsigned long usecs_to_jiffies(const unsigned int u) +@@ -320,22 +351,126 @@ + #endif + } + #endif +-static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, int len) ++static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, ++ int len, bool out) + { + char codes[USB_BUFLEN * 3 + 1]; ++ char inout[9]; + int i; ++ u8 cmd, subcmd, data1, data2; ++ int idx = 0; + +- if (len <= 0) +- return; ++ if (ir->flags.microsoft_gen1 && !out) ++ idx = 2; + +- if (ir->flags.microsoft_gen1 && len <= 2) ++ if (len <= idx) + return; + + for (i = 0; i < len && i < USB_BUFLEN; i++) + snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF); + +- printk(KERN_INFO "" DRIVER_NAME "[%d]: data received %s (length=%d)\n", +- ir->devnum, codes, len); ++ printk(KERN_INFO "" DRIVER_NAME "[%d]: %sx data: %s (length=%d)\n", ++ ir->devnum, (out ? "t" : "r"), codes, len); ++ ++ if (out) ++ strcpy(inout, "Request\0"); ++ else ++ strcpy(inout, "Got\0"); ++ ++ cmd = buf[idx] & 0xff; ++ subcmd = buf[idx + 1] & 0xff; ++ data1 = buf[idx + 2] & 0xff; ++ data2 = buf[idx + 3] & 0xff; ++ ++ switch (cmd) { ++ case 0x00: ++ if (subcmd == 0xff && data1 == 0xaa) ++ printk(KERN_INFO "Device reset requested\n"); ++ else ++ printk(KERN_INFO "Unknown command 0x%02x 0x%02x\n", ++ cmd, subcmd); ++ break; ++ case 0xff: ++ switch (subcmd) { ++ case 0x0b: ++ if (len == 2) ++ printk(KERN_INFO "Get hw/sw rev?\n"); ++ else ++ printk(KERN_INFO "hw/sw rev 0x%02x 0x%02x " ++ "0x%02x 0x%02x\n", data1, data2, ++ buf[4], buf[5]); ++ break; ++ case 0xaa: ++ printk(KERN_INFO "Device reset requested\n"); ++ break; ++ case 0xfe: ++ printk(KERN_INFO "Previous command not supported\n"); ++ break; ++ case 0x18: ++ case 0x1b: ++ default: ++ printk(KERN_INFO "Unknown command 0x%02x 0x%02x\n", ++ cmd, subcmd); ++ break; ++ } ++ break; ++ case 0x9f: ++ switch (subcmd) { ++ case 0x03: ++ printk(KERN_INFO "Ping\n"); ++ break; ++ case 0x04: ++ printk(KERN_INFO "Resp to 9f 05 of 0x%02x 0x%02x\n", ++ data1, data2); ++ break; ++ case 0x06: ++ printk(KERN_INFO "%s carrier mode and freq of 0x%02x 0x%02x\n", ++ inout, data1, data2); ++ break; ++ case 0x07: ++ printk(KERN_INFO "Get carrier mode and freq\n"); ++ break; ++ case 0x08: ++ printk(KERN_INFO "%s transmit blaster mask of 0x%02x\n", ++ inout, data1); ++ break; ++ case 0x0c: ++ /* value is in units of 50us, so x*50/100 or x/2 ms */ ++ printk(KERN_INFO "%s receive timeout of %d ms\n", ++ inout, ((data1 << 8) | data2) / 2); ++ break; ++ case 0x0d: ++ printk(KERN_INFO "Get receive timeout\n"); ++ break; ++ case 0x13: ++ printk(KERN_INFO "Get transmit blaster mask\n"); ++ break; ++ case 0x14: ++ printk(KERN_INFO "%s %s-range receive sensor in use\n", ++ inout, data1 == 0x02 ? "short" : "long"); ++ break; ++ case 0x15: ++ if (len == 2) ++ printk(KERN_INFO "Get receive sensor\n"); ++ else ++ printk(KERN_INFO "Received pulse count is %d\n", ++ ((data1 << 8) | data2)); ++ break; ++ case 0xfe: ++ printk(KERN_INFO "Error! Hardware is likely wedged...\n"); ++ break; ++ case 0x05: ++ case 0x09: ++ case 0x0f: ++ default: ++ printk(KERN_INFO "Unknown command 0x%02x 0x%02x\n", ++ cmd, subcmd); ++ break; ++ } ++ break; ++ default: ++ break; ++ } + } + + static void usb_async_callback(struct urb *urb, struct pt_regs *regs) +@@ -355,54 +490,48 @@ + ir->devnum, urb->status, len); + + if (debug) +- mceusb_dev_printdata(ir, urb->transfer_buffer, len); ++ mceusb_dev_printdata(ir, urb->transfer_buffer, len, true); + } + + } + + /* request incoming or send outgoing usb packet - used to initialize remote */ +-static void request_packet_async(struct mceusb_dev *ir, +- struct usb_endpoint_descriptor *ep, +- unsigned char *data, int size, int urb_type) ++static void mce_request_packet(struct mceusb_dev *ir, ++ struct usb_endpoint_descriptor *ep, ++ unsigned char *data, int size, int urb_type) + { + int res; + struct urb *async_urb; + unsigned char *async_buf; + +- if (urb_type) { ++ if (urb_type == MCEUSB_TX) { + async_urb = usb_alloc_urb(0, GFP_KERNEL); +- if (unlikely(!async_urb)) ++ if (unlikely(!async_urb)) { ++ printk(KERN_ERR "Error, couldn't allocate urb!\n"); + return; ++ } + +- async_buf = kmalloc(size, GFP_KERNEL); ++ async_buf = kzalloc(size, GFP_KERNEL); + if (!async_buf) { ++ printk(KERN_ERR "Error, couldn't allocate buf!\n"); + usb_free_urb(async_urb); + return; + } + +- if (urb_type == MCEUSB_OUTBOUND) { +- /* outbound data */ +- usb_fill_int_urb(async_urb, ir->usbdev, +- usb_sndintpipe(ir->usbdev, +- ep->bEndpointAddress), +- async_buf, size, +- (usb_complete_t) usb_async_callback, +- ir, ep->bInterval); +- memcpy(async_buf, data, size); +- } else { +- /* inbound data */ +- usb_fill_int_urb(async_urb, ir->usbdev, +- usb_rcvintpipe(ir->usbdev, +- ep->bEndpointAddress), +- async_buf, size, +- (usb_complete_t) usb_async_callback, +- ir, ep->bInterval); +- } +- async_urb->transfer_flags = URB_ASYNC_UNLINK; +- } else { ++ /* outbound data */ ++ usb_fill_int_urb(async_urb, ir->usbdev, ++ usb_sndintpipe(ir->usbdev, ep->bEndpointAddress), ++ async_buf, size, (usb_complete_t) usb_async_callback, ++ ir, ep->bInterval); ++ memcpy(async_buf, data, size); ++ ++ } else if (urb_type == MCEUSB_RX) { + /* standard request */ + async_urb = ir->urb_in; + ir->send_flags = RECV_FLAG_IN_PROGRESS; ++ } else { ++ printk(KERN_ERR "Error! Unknown urb type %d\n", urb_type); ++ return; + } + + dprintk(DRIVER_NAME "[%d]: receive request called (size=%#x)\n", +@@ -421,6 +550,16 @@ + ir->devnum, res); + } + ++static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) ++{ ++ mce_request_packet(ir, ir->usb_ep_out, data, size, MCEUSB_TX); ++} ++ ++static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size) ++{ ++ mce_request_packet(ir, ir->usb_ep_in, data, size, MCEUSB_RX); ++} ++ + static int unregister_from_lirc(struct mceusb_dev *ir) + { + struct lirc_driver *d = ir->d; +@@ -496,9 +635,9 @@ + dprintk(DRIVER_NAME "[%d]: mceusb IR device closed\n", ir->devnum); + + if (ir->flags.connected) { +- mutex_lock(&ir->lock); ++ mutex_lock(&ir->dev_lock); + ir->flags.connected = 0; +- mutex_unlock(&ir->lock); ++ mutex_unlock(&ir->dev_lock); + } + MOD_DEC_USE_COUNT; + } +@@ -616,7 +755,7 @@ + buf_len = urb->actual_length; + + if (debug) +- mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len); ++ mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false); + + if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { + ir->send_flags = SEND_FLAG_COMPLETE; +@@ -715,8 +854,7 @@ + cmdbuf[cmdcount++] = 0x80; + + /* Transmit the command to the mce device */ +- request_packet_async(ir, ir->usb_ep_out, cmdbuf, +- cmdcount, MCEUSB_OUTBOUND); ++ mce_async_out(ir, cmdbuf, cmdcount); + + /* + * The lircd gap calculation expects the write function to +@@ -762,9 +900,7 @@ + ir->carrier_freq = carrier; + dprintk(DRIVER_NAME "[%d]: SET_CARRIER disabling " + "carrier modulation\n", ir->devnum); +- request_packet_async(ir, ir->usb_ep_out, +- cmdbuf, sizeof(cmdbuf), +- MCEUSB_OUTBOUND); ++ mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); + return carrier; + } + +@@ -779,9 +915,7 @@ + ir->devnum, carrier); + + /* Transmit new carrier to mce device */ +- request_packet_async(ir, ir->usb_ep_out, +- cmdbuf, sizeof(cmdbuf), +- MCEUSB_OUTBOUND); ++ mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); + return carrier; + } + } +@@ -799,7 +933,6 @@ + { + int result; + unsigned int ivalue; +- unsigned long lvalue; + struct mceusb_dev *ir = NULL; + + /* Retrieve lirc_driver data for the device */ +@@ -828,26 +961,6 @@ + dprintk(DRIVER_NAME ": SET_TRANSMITTERS mask=%d\n", ivalue); + break; + +- case LIRC_GET_SEND_MODE: +- +- result = put_user(LIRC_SEND2MODE(LIRC_CAN_SEND_PULSE & +- LIRC_CAN_SEND_MASK), +- (unsigned long *) arg); +- +- if (result) +- return result; +- break; +- +- case LIRC_SET_SEND_MODE: +- +- result = get_user(lvalue, (unsigned long *) arg); +- +- if (result) +- return result; +- if (lvalue != (LIRC_MODE_PULSE&LIRC_CAN_SEND_MASK)) +- return -EINVAL; +- break; +- + case LIRC_SET_SEND_CARRIER: + + result = get_user(ivalue, (unsigned int *) arg); +@@ -870,45 +983,25 @@ + .ioctl = mceusb_lirc_ioctl, + }; + +-static int mceusb_gen1_init(struct mceusb_dev *ir) ++static void mceusb_gen1_init(struct mceusb_dev *ir) + { +- int i, ret; +- char junk[64], data[8]; +- int partial = 0; +- +- /* +- * Clear off the first few messages. These look like calibration +- * or test data, I can't really tell. This also flushes in case +- * we have random ir data queued up. +- */ +- for (i = 0; i < 40; i++) +- usb_bulk_msg(ir->usbdev, +- usb_rcvbulkpipe(ir->usbdev, +- ir->usb_ep_in->bEndpointAddress), +- junk, 64, &partial, HZ * 10); +- +- ir->is_pulse = 1; +- +- memset(data, 0, 8); +- +- /* Get Status */ +- ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), +- USB_REQ_GET_STATUS, USB_DIR_IN, +- 0, 0, data, 2, HZ * 3); +- +- /* ret = usb_get_status( ir->usbdev, 0, 0, data ); */ +- dprintk("%s - ret = %d status = 0x%x 0x%x\n", __func__, +- ret, data[0], data[1]); ++ int ret; ++ int maxp = ir->len_in; ++ char *data; ++ ++ data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL); ++ if (!data) { ++ printk(KERN_ERR "%s: memory allocation failed!\n", __func__); ++ return; ++ } + + /* + * This is a strange one. They issue a set address to the device + * on the receive control pipe and expect a certain value pair back + */ +- memset(data, 0, 8); +- + ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), + USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, +- data, 2, HZ * 3); ++ data, USB_CTRL_MSG_SZ, HZ * 3); + dprintk("%s - ret = %d, devnum = %d\n", + __func__, ret, ir->usbdev->devnum); + dprintk("%s - data[0] = %d, data[1] = %d\n", +@@ -933,12 +1026,62 @@ + 0x0000, 0x0100, NULL, 0, HZ * 3); + dprintk("%s - retC = %d\n", __func__, ret); + +- return ret; ++ /* device reset */ ++ mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get hw/sw revision? */ ++ mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ kfree(data); ++ ++ return; + + }; + +-static int mceusb_dev_probe(struct usb_interface *intf, +- const struct usb_device_id *id) ++static void mceusb_gen2_init(struct mceusb_dev *ir) ++{ ++ int maxp = ir->len_in; ++ ++ /* device reset */ ++ mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get hw/sw revision? */ ++ mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* unknown what the next two actually return... */ ++ mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN)); ++ mce_sync_in(ir, NULL, maxp); ++ mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2)); ++ mce_sync_in(ir, NULL, maxp); ++} ++ ++static void mceusb_get_parameters(struct mceusb_dev *ir) ++{ ++ int maxp = ir->len_in; ++ ++ /* get the carrier and frequency */ ++ mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get the transmitter bitmask */ ++ mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get receiver timeout value */ ++ mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get receiver sensor setting */ ++ mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR)); ++ mce_sync_in(ir, NULL, maxp); ++} ++ ++static int __devinit mceusb_dev_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) + { + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *idesc; +@@ -954,19 +1097,15 @@ + int i; + char buf[63], name[128] = ""; + int mem_failure = 0; +- int is_pinnacle; +- int is_microsoft_gen1; ++ bool is_gen3; ++ bool is_microsoft_gen1; + + dprintk(DRIVER_NAME ": %s called\n", __func__); + +- usb_reset_device(dev); +- + config = dev->actconfig; +- + idesc = intf->cur_altsetting; + +- is_pinnacle = usb_match_id(intf, pinnacle_list) ? 1 : 0; +- ++ is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0; + is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0; + + /* step through the endpoints to find first bulk in and out endpoint */ +@@ -985,14 +1124,7 @@ + "found\n"); + ep_in = ep; + ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; +- if (is_pinnacle) +- /* +- * setting seems to 1 seem to cause issues with +- * Pinnacle timing out on transfer. +- */ +- ep_in->bInterval = ep->bInterval; +- else +- ep_in->bInterval = 1; ++ ep_in->bInterval = 1; + } + + if ((ep_out == NULL) +@@ -1007,14 +1139,7 @@ + "found\n"); + ep_out = ep; + ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; +- if (is_pinnacle) +- /* +- * setting seems to 1 seem to cause issues with +- * Pinnacle timing out on transfer. +- */ +- ep_out->bInterval = ep->bInterval; +- else +- ep_out->bInterval = 1; ++ ep_out->bInterval = 1; + } + } + if (ep_in == NULL || ep_out == NULL) { +@@ -1029,39 +1154,27 @@ + + mem_failure = 0; + ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); +- if (!ir) { +- mem_failure = 1; +- goto mem_failure_switch; +- } ++ if (!ir) ++ goto mem_alloc_fail; + + driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); +- if (!driver) { +- mem_failure = 2; +- goto mem_failure_switch; +- } ++ if (!driver) ++ goto mem_alloc_fail; + +- rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); +- if (!rbuf) { +- mem_failure = 3; +- goto mem_failure_switch; +- } +- +- if (lirc_buffer_init(rbuf, sizeof(lirc_t), LIRCBUF_SIZE)) { +- mem_failure = 4; +- goto mem_failure_switch; +- } +- +- ir->buf_in = usb_buffer_alloc(dev, maxp, GFP_ATOMIC, &ir->dma_in); +- if (!ir->buf_in) { +- mem_failure = 5; +- goto mem_failure_switch; +- } ++ rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL); ++ if (!rbuf) ++ goto mem_alloc_fail; ++ ++ if (lirc_buffer_init(rbuf, sizeof(lirc_t), LIRCBUF_SIZE)) ++ goto mem_alloc_fail; ++ ++ ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &ir->dma_in); ++ if (!ir->buf_in) ++ goto buf_in_alloc_fail; + + ir->urb_in = usb_alloc_urb(0, GFP_KERNEL); +- if (!ir->urb_in) { +- mem_failure = 7; +- goto mem_failure_switch; +- } ++ if (!ir->urb_in) ++ goto urb_in_alloc_fail; + + strcpy(driver->name, DRIVER_NAME " "); + driver->minor = -1; +@@ -1078,33 +1191,12 @@ + driver->dev = &intf->dev; + driver->owner = THIS_MODULE; + +- mutex_init(&ir->lock); ++ mutex_init(&ir->dev_lock); + init_waitqueue_head(&ir->wait_out); + + minor = lirc_register_driver(driver); + if (minor < 0) +- mem_failure = 9; +- +-mem_failure_switch: +- +- switch (mem_failure) { +- case 9: +- usb_free_urb(ir->urb_in); +- case 7: +- usb_buffer_free(dev, maxp, ir->buf_in, ir->dma_in); +- case 5: +- lirc_buffer_free(rbuf); +- case 4: +- kfree(rbuf); +- case 3: +- kfree(driver); +- case 2: +- kfree(ir); +- case 1: +- printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", +- devnum, mem_failure); +- return -ENOMEM; +- } ++ goto lirc_register_fail; + + driver->minor = minor; + ir->d = driver; +@@ -1113,7 +1205,6 @@ + ir->len_in = maxp; + ir->overflow_len = 0; + ir->flags.connected = 0; +- ir->flags.pinnacle = is_pinnacle; + ir->flags.microsoft_gen1 = is_microsoft_gen1; + ir->flags.transmitter_mask_inverted = + usb_match_id(intf, transmitter_mask_list) ? 0 : 1; +@@ -1121,8 +1212,6 @@ + ir->lircdata = PULSE_MASK; + ir->is_pulse = 0; + +- /* ir->flags.transmitter_mask_inverted must be set */ +- set_transmitter_mask(ir, MCE_DEFAULT_TX_MASK); + /* Saving usb interface data for use by the transmitter routine */ + ir->usb_ep_in = ep_in; + ir->usb_ep_out = ep_out; +@@ -1139,73 +1228,49 @@ + printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, + dev->bus->busnum, devnum); + +- /* inbound data */ ++ /* flush buffers on the device */ ++ mce_sync_in(ir, NULL, maxp); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* wire up inbound data handler */ + usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, + maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval); + ir->urb_in->transfer_dma = ir->dma_in; + ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + /* initialize device */ +- if (ir->flags.pinnacle) { +- int usbret; +- +- /* +- * I have no idea why but this reset seems to be crucial to +- * getting the device to do outbound IO correctly - without +- * this the device seems to hang, ignoring all input - although +- * IR signals are correctly sent from the device, no input is +- * interpreted by the device and the host never does the +- * completion routine +- */ +- +- usbret = usb_reset_configuration(dev); +- printk(DRIVER_NAME "[%d]: usb reset config ret %x\n", +- devnum, usbret); +- +- /* +- * its possible we really should wait for a return +- * for each of these... +- */ +- request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND); +- request_packet_async(ir, ep_out, pin_init1, sizeof(pin_init1), +- MCEUSB_OUTBOUND); +- request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND); +- request_packet_async(ir, ep_out, pin_init2, sizeof(pin_init2), +- MCEUSB_OUTBOUND); +- request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND); +- request_packet_async(ir, ep_out, pin_init3, sizeof(pin_init3), +- MCEUSB_OUTBOUND); +- } else if (ir->flags.microsoft_gen1) { +- /* original ms mce device requires some additional setup */ ++ if (ir->flags.microsoft_gen1) + mceusb_gen1_init(ir); +- } else { ++ else if (!is_gen3) ++ mceusb_gen2_init(ir); + +- request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND); +- request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND); +- request_packet_async(ir, ep_out, init1, +- sizeof(init1), MCEUSB_OUTBOUND); +- request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND); +- request_packet_async(ir, ep_out, init2, +- sizeof(init2), MCEUSB_OUTBOUND); +- } ++ mceusb_get_parameters(ir); + +- /* +- * if we don't issue the correct number of receives (MCEUSB_INBOUND) +- * for each outbound, then the first few ir pulses will be interpreted +- * by the usb_async_callback routine - we should ensure we have the +- * right amount OR less - as the meusb_dev_recv routine will handle +- * the control packets OK - they start with 0x9f - but the async +- * callback doesn't handle ir pulse packets +- */ +- request_packet_async(ir, ep_in, NULL, maxp, 0); ++ /* ir->flags.transmitter_mask_inverted must be set */ ++ set_transmitter_mask(ir, MCE_DEFAULT_TX_MASK); + + usb_set_intfdata(intf, ir); + + return 0; ++ ++ /* Error-handling path */ ++lirc_register_fail: ++ usb_free_urb(ir->urb_in); ++urb_in_alloc_fail: ++ usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in); ++buf_in_alloc_fail: ++ lirc_buffer_free(rbuf); ++mem_alloc_fail: ++ kfree(rbuf); ++ kfree(driver); ++ kfree(ir); ++ printk(KERN_ERR "out of memory (code=%d)\n", mem_failure); ++ ++ return -ENOMEM; + } + + +-static void mceusb_dev_disconnect(struct usb_interface *intf) ++static void __devexit mceusb_dev_disconnect(struct usb_interface *intf) + { + struct usb_device *dev = interface_to_usbdev(intf); + struct mceusb_dev *ir = usb_get_intfdata(intf); +@@ -1218,11 +1283,11 @@ + ir->usbdev = NULL; + wake_up_all(&ir->wait_out); + +- mutex_lock(&ir->lock); ++ mutex_lock(&ir->dev_lock); + usb_kill_urb(ir->urb_in); + usb_free_urb(ir->urb_in); +- usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in); +- mutex_unlock(&ir->lock); ++ usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); ++ mutex_unlock(&ir->dev_lock); + + unregister_from_lirc(ir); + } +--- drivers/lirc_streamzap/lirc_streamzap.c 2010/03/17 14:16:16 1.48 ++++ drivers/lirc_streanzap/lirc_streamzap.c 2010/07/25 16:43:33 1.54 +@@ -1,4 +1,4 @@ +-/* $Id: lirc_streamzap.c,v 1.48 2009/03/15 09:34:00 lirc Exp $ */ ++/* $Id: lirc_streamzap.c,v 1.54 2010/07/25 16:43:33 jarodwilson Exp $ */ + /* + * Streamzap Remote Control driver + * +@@ -54,7 +56,7 @@ + #include "drivers/kcompat.h" + #include "drivers/lirc_dev/lirc_dev.h" + +-#define DRIVER_VERSION "$Revision: 1.48 $" ++#define DRIVER_VERSION "$Revision: 1.54 $" + #define DRIVER_NAME "lirc_streamzap" + #define DRIVER_DESC "Streamzap Remote Control driver" + +@@ -83,10 +85,11 @@ + + #define STREAMZAP_PULSE_MASK 0xf0 + #define STREAMZAP_SPACE_MASK 0x0f ++#define STREAMZAP_TIMEOUT 0xff + #define STREAMZAP_RESOLUTION 256 + + /* number of samples buffered */ +-#define STREAMZAP_BUFFER_SIZE 128 ++#define STREAMZAP_BUFFER_SIZE 256 + + enum StreamzapDecoderState { + PulseSpace, +@@ -154,6 +157,7 @@ + struct timer_list flush_timer; + int flush; + int in_use; ++ int timeout_enabled; + }; + + +@@ -317,12 +321,14 @@ + + deltv = sz->signal_start.tv_sec-sz->signal_last.tv_sec; + if (deltv > 15) { +- tmp = PULSE_MASK; /* really long time */ ++ /* really long time */ ++ tmp = LIRC_SPACE(LIRC_VALUE_MASK); + } else { + tmp = (lirc_t) (deltv*1000000+ + sz->signal_start.tv_usec - + sz->signal_last.tv_usec); + tmp -= sz->sum; ++ tmp = LIRC_SPACE(tmp); + } + dprintk("ls %u", sz->driver.minor, tmp); + push(sz, (char *)&tmp); +@@ -334,7 +340,7 @@ + pulse = ((lirc_t) value)*STREAMZAP_RESOLUTION; + pulse += STREAMZAP_RESOLUTION/2; + sz->sum += pulse; +- pulse |= PULSE_BIT; ++ pulse = LIRC_PULSE(pulse); + + dprintk("p %u", sz->driver.minor, pulse&PULSE_MASK); + push(sz, (char *)&pulse); +@@ -354,6 +360,7 @@ + space = ((lirc_t) value)*STREAMZAP_RESOLUTION; + space += STREAMZAP_RESOLUTION/2; + sz->sum += space; ++ space = LIRC_SPACE(space); + dprintk("s %u", sz->driver.minor, space); + push(sz, (char *)&space); + } +@@ -426,9 +433,16 @@ + sz->decoder_state = IgnorePulse; + break; + case FullSpace: +- if (sz->buf_in[i] == 0xff) { ++ if (sz->buf_in[i] == STREAMZAP_TIMEOUT) { + sz->idle = 1; + stop_timer(sz); ++ if (sz->timeout_enabled) { ++ lirc_t timeout = ++ LIRC_TIMEOUT ++ (STREAMZAP_TIMEOUT * ++ STREAMZAP_RESOLUTION); ++ push(sz, (char *)&timeout); ++ } + flush_delay_buffer(sz); + } else + push_full_space(sz, sz->buf_in[i]); +@@ -546,8 +560,8 @@ + + sz->buf_in_len = sz->endpoint->wMaxPacketSize; + #ifdef KERNEL_2_5 +- sz->buf_in = usb_buffer_alloc(sz->udev, sz->buf_in_len, +- GFP_ATOMIC, &sz->dma_in); ++ sz->buf_in = usb_alloc_coherent(sz->udev, sz->buf_in_len, ++ GFP_ATOMIC, &sz->dma_in); + #else + sz->buf_in = kmalloc(sz->buf_in_len, GFP_KERNEL); + #endif +@@ -579,8 +593,12 @@ + sz->driver.minor = -1; + sz->driver.sample_rate = 0; + sz->driver.code_length = sizeof(lirc_t) * 8; +- sz->driver.features = LIRC_CAN_REC_MODE2 | LIRC_CAN_GET_REC_RESOLUTION; ++ sz->driver.features = LIRC_CAN_REC_MODE2 | ++ LIRC_CAN_GET_REC_RESOLUTION | ++ LIRC_CAN_SET_REC_TIMEOUT; + sz->driver.data = sz; ++ sz->driver.min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION; ++ sz->driver.max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION; + sz->driver.rbuf = &sz->lirc_buf; + sz->driver.set_use_inc = &streamzap_use_inc; + sz->driver.set_use_dec = &streamzap_use_dec; +@@ -657,7 +675,7 @@ + if (sz) { + usb_free_urb(sz->urb_in); + #ifdef KERNEL_2_5 +- usb_buffer_free(udev, sz->buf_in_len, sz->buf_in, sz->dma_in); ++ usb_free_coherent(udev, sz->buf_in_len, sz->buf_in, sz->dma_in); + #else + if (sz->buf_in) { + kfree(sz->buf_in); +@@ -691,6 +709,8 @@ + sz->flush = 1; + add_timer(&sz->flush_timer); + ++ sz->timeout_enabled = 0; ++ + sz->urb_in->dev = sz->udev; + #ifdef KERNEL_2_5 + if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { +@@ -733,18 +753,35 @@ + static int streamzap_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg) + { +- int result; ++ int result = 0; ++ lirc_t val; ++ unsigned int flag = 0; ++ struct usb_streamzap *sz = lirc_get_pdata(filep); + + switch (cmd) { + case LIRC_GET_REC_RESOLUTION: + result = put_user(STREAMZAP_RESOLUTION, (unsigned int *) arg); +- if (result) +- return result; ++ break; ++ case LIRC_SET_REC_TIMEOUT: ++ result = get_user(val, (lirc_t *)arg); ++ if (result == 0) { ++ if (val != STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) ++ result = -EINVAL; ++ } ++ break; ++ case LIRC_SET_REC_TIMEOUT_REPORTS: ++ result = get_user(flag, (unsigned int *)arg); ++ if (result == 0) { ++ if (flag != 0) ++ sz->timeout_enabled = 1; ++ else ++ sz->timeout_enabled = 0; ++ } + break; + default: + return -ENOIOCTLCMD; + } +- return 0; ++ return result; + } + + /** +@@ -788,7 +825,7 @@ + usb_free_urb(sz->urb_in); + + #ifdef KERNEL_2_5 +- usb_buffer_free(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in); ++ usb_free_coherent(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in); + #else + kfree(sz->buf_in); + #endif +--- drivers/lirc.h 2009/08/29 07:52:41 5.19 ++++ drivers/lirc.h 2010/05/13 15:45:48 5.27 +@@ -1,4 +1,4 @@ +-/* $Id: lirc.h,v 5.19 2009/08/29 07:52:41 lirc Exp $ */ ++/* $Id: lirc.h,v 5.27 2010/05/13 15:45:48 lirc Exp $ */ + + #ifndef _LINUX_LIRC_H + #define _LINUX_LIRC_H +@@ -12,8 +12,31 @@ + #include <sys/ioctl.h> + #endif + +-#define PULSE_BIT 0x01000000 +-#define PULSE_MASK 0x00FFFFFF ++/* <obsolete> */ ++#define PULSE_BIT 0x01000000 ++#define PULSE_MASK 0x00FFFFFF ++/* </obsolete> */ ++ ++#define LIRC_MODE2_SPACE 0x00000000 ++#define LIRC_MODE2_PULSE 0x01000000 ++#define LIRC_MODE2_FREQUENCY 0x02000000 ++#define LIRC_MODE2_TIMEOUT 0x03000000 ++ ++#define LIRC_VALUE_MASK 0x00FFFFFF ++#define LIRC_MODE2_MASK 0xFF000000 ++ ++#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE) ++#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE) ++#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY) ++#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT) ++ ++#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK) ++#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK) ++ ++#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE) ++#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE) ++#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY) ++#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT) + + typedef int lirc_t; + +@@ -27,17 +50,17 @@ + #define LIRC_MODE_RAW 0x00000001 + #define LIRC_MODE_PULSE 0x00000002 + #define LIRC_MODE_MODE2 0x00000004 +-#define LIRC_MODE_CODE 0x00000008 ++/* obsolete: #define LIRC_MODE_CODE 0x00000008 */ + #define LIRC_MODE_LIRCCODE 0x00000010 +-#define LIRC_MODE_STRING 0x00000020 ++/* obsolete: #define LIRC_MODE_STRING 0x00000020 */ + + + #define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) + #define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) + #define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) +-#define LIRC_CAN_SEND_CODE LIRC_MODE2SEND(LIRC_MODE_CODE) ++/* obsolete: #define LIRC_CAN_SEND_CODE LIRC_MODE2SEND(LIRC_MODE_CODE) */ + #define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) +-#define LIRC_CAN_SEND_STRING LIRC_MODE2SEND(LIRC_MODE_STRING) ++/* obsolete: #define LIRC_CAN_SEND_STRING LIRC_MODE2SEND(LIRC_MODE_STRING) */ + + #define LIRC_CAN_SEND_MASK 0x0000003f + +@@ -48,9 +71,9 @@ + #define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) + #define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) + #define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) +-#define LIRC_CAN_REC_CODE LIRC_MODE2REC(LIRC_MODE_CODE) ++/* obsolete: #define LIRC_CAN_REC_CODE LIRC_MODE2REC(LIRC_MODE_CODE) */ + #define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) +-#define LIRC_CAN_REC_STRING LIRC_MODE2REC(LIRC_MODE_STRING) ++/* obsolete: #define LIRC_CAN_REC_STRING LIRC_MODE2REC(LIRC_MODE_STRING) */ + + #define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) + +@@ -60,6 +83,10 @@ + #define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 + #define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 + #define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 ++#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000 ++#define LIRC_CAN_SET_REC_FILTER 0x08000000 ++ ++#define LIRC_CAN_MEASURE_CARRIER 0x02000000 + + #define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) + #define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) +@@ -78,10 +105,23 @@ + #define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, unsigned int) + #define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, unsigned int) + ++#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, lirc_t) ++#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, lirc_t) ++ ++#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, lirc_t) ++#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, lirc_t) ++#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, lirc_t) ++#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, lirc_t) ++ + /* code length in bits, currently only for LIRC_MODE_LIRCCODE */ + #define LIRC_GET_LENGTH _IOR('i', 0x0000000f, unsigned long) + ++/* all values set should be reset by the driver when the device is ++ reopened */ ++ ++/* obsolete: drivers only support one mode */ + #define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, unsigned long) ++/* obsolete: drivers only support one mode */ + #define LIRC_SET_REC_MODE _IOW('i', 0x00000012, unsigned long) + /* Note: these can reset the according pulse_width */ + #define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, unsigned int) +@@ -90,6 +130,26 @@ + #define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, unsigned int) + #define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, unsigned int) + ++/* a value of 0 disables all hardware timeouts and data should be ++ reported as soon as possible */ ++#define LIRC_SET_REC_TIMEOUT _IOW('i', 0x00000018, lirc_t) ++/* 1 enables, 0 disables timeout reports in MODE2 */ ++#define LIRC_SET_REC_TIMEOUT_REPORTS _IOW('i', 0x00000019, unsigned int) ++ ++/* pulses shorter than this are filtered out by hardware (software ++ emulation in lirc_dev/lircd?) */ ++#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x0000001a, lirc_t) ++/* spaces shorter than this are filtered out by hardware (software ++ emulation in lirc_dev/lircd?) */ ++#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001b, lirc_t) ++/* if filter cannot be set independently for pulse/space, this should ++ be used */ ++#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001c, lirc_t) ++ ++/* if enabled from the next key press on the driver will send ++ LIRC_MODE2_FREQUENCY packets */ ++#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, unsigned int) ++ + /* + * to set a range use + * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the +@@ -102,4 +162,7 @@ + + #define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) + ++#define LIRC_SETUP_START _IO('i', 0x00000021) ++#define LIRC_SETUP_END _IO('i', 0x00000022) ++ + #endif +--- drivers/lirc_dev/lirc_dev.c 2009/08/31 16:57:55 1.96 ++++ drivers/lirc_dev/lirc_dev.c 2010/05/13 15:45:48 1.105 +@@ -17,7 +17,7 @@ + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +- * $Id: lirc_dev.c,v 1.96 2009/08/31 16:57:55 lirc Exp $ ++ * $Id: lirc_dev.c,v 1.105 2010/05/13 15:45:48 lirc Exp $ + * + */ + +@@ -367,8 +369,7 @@ + ir->chunk_size = ir->buf->chunk_size; + + if (d->features == 0) +- d->features = (d->code_length > 8) ? +- LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_CODE; ++ d->features = LIRC_CAN_REC_LIRCCODE; + + ir->d = *d; + ir->d.minor = minor; +@@ -541,7 +542,7 @@ + static int irctl_open(struct inode *inode, struct file *file) + { + struct irctl *ir; +- int retval; ++ int retval = 0; + + if (iminor(inode) >= MAX_IRCTL_DEVICES || !irctls[iminor(inode)]) { + dprintk("lirc_dev [%d]: open result = -ENODEV\n", +@@ -591,6 +592,8 @@ + if (ir->task) + wake_up_process(ir->task); + #endif ++ } else { ++ retval = -ENODEV; + } + error: + if (ir) +@@ -692,6 +695,23 @@ + case LIRC_GET_FEATURES: + result = put_user(ir->d.features, (unsigned long *)arg); + break; ++ case LIRC_GET_LENGTH: ++ result = put_user(ir->d.code_length, (unsigned long *) arg); ++ break; ++ case LIRC_GET_MIN_TIMEOUT: ++ if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || ++ ir->d.min_timeout == 0) ++ return -ENOSYS; ++ ++ result = put_user(ir->d.min_timeout, (lirc_t *) arg); ++ break; ++ case LIRC_GET_MAX_TIMEOUT: ++ if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || ++ ir->d.max_timeout == 0) ++ return -ENOSYS; ++ ++ result = put_user(ir->d.max_timeout, (lirc_t *) arg); ++ break; + case LIRC_GET_REC_MODE: + if (!(ir->d.features & LIRC_CAN_REC_MASK)) + return -ENOSYS; +@@ -700,6 +720,16 @@ + (ir->d.features & LIRC_CAN_REC_MASK), + (unsigned long *)arg); + break; ++ case LIRC_GET_SEND_MODE: ++ if (!(ir->d.features & LIRC_CAN_SEND_MASK)) ++ return -ENOSYS; ++ ++ result = put_user(LIRC_SEND2MODE ++ (ir->d.features & LIRC_CAN_SEND_MASK), ++ (unsigned long *)arg); ++ break; ++ ++ /*obsolete */ + case LIRC_SET_REC_MODE: + if (!(ir->d.features & LIRC_CAN_REC_MASK)) + return -ENOSYS; +@@ -707,18 +737,30 @@ + result = get_user(mode, (unsigned long *)arg); + if (!result && !(LIRC_MODE2REC(mode) & ir->d.features)) + result = -EINVAL; +- /* +- * FIXME: We should actually set the mode somehow but +- * for now, lirc_serial doesn't support mode changing either +- */ + break; +- case LIRC_GET_LENGTH: +- result = put_user(ir->d.code_length, (unsigned long *) arg); ++ case LIRC_SET_SEND_MODE: ++ if (!(ir->d.features & LIRC_CAN_SEND_MASK)) ++ return -ENOSYS; ++ ++ result = get_user(mode, (unsigned long *)arg); ++ if (!result && !(LIRC_MODE2SEND(mode) & ir->d.features)) ++ result = -EINVAL; + break; + default: + result = -EINVAL; + } + ++ switch (cmd) { ++ case LIRC_SET_REC_MODE: ++ case LIRC_SET_SEND_MODE: ++ printk(KERN_NOTICE LOGHEAD "userspace uses outdated ioctl " ++ "please update your lirc installation\n", ++ ir->d.name, ir->d.minor); ++ break; ++ default: ++ break; ++ } ++ + dprintk(LOGHEAD "ioctl result = %d\n", + ir->d.name, ir->d.minor, result); + +@@ -791,16 +833,31 @@ + case LIRC_GET_SEND_DUTY_CYCLE: + case LIRC_GET_REC_DUTY_CYCLE: + case LIRC_GET_REC_RESOLUTION: ++ case LIRC_GET_MIN_TIMEOUT: ++ case LIRC_GET_MAX_TIMEOUT: ++ case LIRC_GET_MIN_FILTER_PULSE: ++ case LIRC_GET_MAX_FILTER_PULSE: ++ case LIRC_GET_MIN_FILTER_SPACE: ++ case LIRC_GET_MAX_FILTER_SPACE: + case LIRC_SET_SEND_CARRIER: + case LIRC_SET_REC_CARRIER: + case LIRC_SET_SEND_DUTY_CYCLE: + case LIRC_SET_REC_DUTY_CYCLE: + case LIRC_SET_TRANSMITTER_MASK: ++ case LIRC_SET_REC_TIMEOUT: ++ case LIRC_SET_REC_TIMEOUT_REPORTS: ++ case LIRC_SET_REC_FILTER_PULSE: ++ case LIRC_SET_REC_FILTER_SPACE: ++ case LIRC_SET_REC_FILTER: ++ case LIRC_SET_MEASURE_CARRIER_MODE: + case LIRC_SET_REC_DUTY_CYCLE_RANGE: + case LIRC_SET_REC_CARRIER_RANGE: ++ case LIRC_NOTIFY_DECODE: ++ case LIRC_SETUP_START: ++ case LIRC_SETUP_END: + /* +- * These commands expect (unsigned int *)arg +- * so no problems here. Just handle the locking. ++ * These commands expect (unsigned int *) or (lirc_t *) ++ * arg so no problems here. Just handle the locking. + */ + lock_kernel(); + cmd = cmd32; +--- drivers/lirc_dev/lirc_dev.h 2009/12/28 15:21:17 1.38 ++++ drivers/lirc_dev/lirc_dev.h 2010/04/25 08:33:52 1.41 +@@ -4,7 +4,7 @@ + * (L) by Artur Lipowski <alipowski@interia.pl> + * This code is licensed under GNU GPL + * +- * $Id: lirc_dev.h,v 1.38 2009/12/28 15:21:17 jarodwilson Exp $ ++ * $Id: lirc_dev.h,v 1.41 2010/04/25 08:33:52 lirc Exp $ + * + */ + +@@ -28,6 +28,8 @@ + #include <linux/kfifo.h> + #endif + ++#include "drivers/lirc.h" ++ + struct lirc_buffer { + wait_queue_head_t wait_poll; + spinlock_t fifo_lock; +@@ -68,13 +70,13 @@ + #endif + static inline void lirc_buffer_clear(struct lirc_buffer *buf) + { +- unsigned long flags; +- + #ifdef LIRC_HAVE_KFIFO + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) + if (buf->fifo) + kfifo_reset(buf->fifo); + #else ++ unsigned long flags; ++ + if (buf->fifo_initialized) { + spin_lock_irqsave(&buf->fifo_lock, flags); + kfifo_reset(&buf->fifo); +@@ -82,6 +84,8 @@ + } + #endif + #else ++ unsigned long flags; ++ + lirc_buffer_lock(buf, &flags); + _lirc_buffer_clear(buf); + lirc_buffer_unlock(buf, &flags); +@@ -331,6 +335,8 @@ + int sample_rate; + unsigned long features; + void *data; ++ lirc_t min_timeout; ++ lirc_t max_timeout; + int (*add_to_buf) (void *data, struct lirc_buffer *buf); + #ifndef LIRC_REMOVE_DURING_EXPORT + wait_queue_head_t* (*get_queue) (void *data); +@@ -338,7 +344,7 @@ + struct lirc_buffer *rbuf; + int (*set_use_inc) (void *data); + void (*set_use_dec) (void *data); +- struct file_operations *fops; ++ const struct file_operations *fops; + struct device *dev; + struct module *owner; + }; |