From: Martin B. <mbl...@gm...> - 2005-03-01 12:06:25
|
I wrote a driver for the new MCE (aka Philips eHome) remote. Basically it works great, however the initialization of the remote fails most of the time. I need to plug it in at least two or three times to have it initialized correctly. USB Snoopy on Windows shows me the exact same initialization sequence that I use in my driver but somehow the transciever behaves differently. Did anyone experience similar problems? Is there something in the USB enumeration process that Linux does differently than Windows that might affect the initialization process? regrads martin |
From: EC <zy...@ve...> - 2005-03-01 23:05:39
|
Tue, 01 Mar 2005 13:06:16 +0100 | Martin Blatter <mbl...@gm...> ::-I wrote a driver for the new MCE (aka Philips eHome) remote. Basically it works ::-great, however the initialization of the remote fails most of the ::-time. I need to plug it ::-in at least two or three times to have it initialized correctly. ::- ::-USB Snoopy on Windows shows me the exact same initialization sequence that ::-I use in my driver but somehow the transciever behaves differently. Did anyone ::-experience similar problems? Is there something in the USB enumeration process ::-that Linux does differently than Windows that might affect the ::-initialization process? ::- ::-regrads ::-martin ::- ::- ::-------------------------------------------------------- ::-SF email is sponsored by - The IT Product Guide ::-Read honest & candid reviews on hundreds of IT Products from real users. ::-Discover which products truly live up to the hype. Start reading now. ::-http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click Would you mind making the driver available? I know there are many people (myself included) on this list that are eager to get their mce remotes working. Another guy <http://article.gmane.org/gmane.comp.hardware.lirc/1979> said he had been working on a driver too, but he has been away since. We could even test your initialization problems ;). //EC |
From: <spa...@co...> - 2005-03-02 15:36:24
|
>>>>> "EC" == EC <zy...@ve...> writes: EC> Tue, 01 Mar 2005 13:06:16 +0100 | Martin Blatter EC> <mbl...@gm...> ::-I wrote a driver for the new MCE (aka EC> Philips eHome) remote. Basically it works ::-great, however the EC> initialization of the remote fails most of the ::-time. I need to EC> plug it ::-in at least two or three times to have it initialized EC> correctly. ::- ::-USB Snoopy on Windows shows me the exact same EC> initialization sequence that ::-I use in my driver but somehow EC> the transciever behaves differently. Did anyone ::-experience EC> similar problems? Is there something in the USB enumeration EC> process ::-that Linux does differently than Windows that might EC> affect the ::-initialization process? ::- ::-regrads ::-martin EC> ::- ::- EC> ::-------------------------------------------------------- ::-SF EC> email is sponsored by - The IT Product Guide ::-Read honest & EC> candid reviews on hundreds of IT Products from real users. EC> ::-Discover which products truly live up to the hype. Start EC> reading now. EC> ::-http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click EC> Would you mind making the driver available? I know there are many EC> people (myself included) on this list that are eager to get their EC> mce remotes working. Another guy EC> <http://article.gmane.org/gmane.comp.hardware.lirc/1979> said he EC> had been working on a driver too, but he has been away since. We EC> could even test your initialization problems ;). EC> //EC I would be happy to test it out. Thanks |
From: Jim C. <Jim...@ut...> - 2005-03-02 04:30:38
Attachments:
lirc_mceusb.c
|
Yeah, I have been away for a bit. I've been busy with school, but I've been checking into things with the driver with a couple of guys. Jeff Burricelli tells me that it works great every time with his setup (2.6.10), so I'm going to go ahead and just attach the full driver to this e-mail. I've had initialization problems with the receiver like Martin describes, but it's always seemed like something with the Linux USB sub-system itself and not the driver. So, whoever wants to try out the driver is welcome to it. It would be especially nice if others running the latest and greatest could check it out. If it consistently works, then the initialization issues could be cleared up in later kernels. Good luck with the driver. I'll watch the list for news about it, and if things work out well, I'll make a couple of final changes and submit a patch. Or Martin can do his. Either way. Jim EC wrote: >Tue, 01 Mar 2005 13:06:16 +0100 | Martin Blatter <mbl...@gm...> > >::-I wrote a driver for the new MCE (aka Philips eHome) remote. >Basically it works ::-great, however the initialization of the remote >fails most of the ::-time. I need to plug it >::-in at least two or three times to have it initialized correctly. >::- >::-USB Snoopy on Windows shows me the exact same initialization sequence >that ::-I use in my driver but somehow the transciever behaves >differently. Did anyone ::-experience similar problems? Is there >something in the USB enumeration process ::-that Linux does differently >than Windows that might affect the ::-initialization process? >::- >::-regrads >::-martin >::- >::- >::-------------------------------------------------------- >::-SF email is sponsored by - The IT Product Guide >::-Read honest & candid reviews on hundreds of IT Products from real >users. ::-Discover which products truly live up to the hype. Start >reading now. ::-http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > >Would you mind making the driver available? I know there are many >people (myself included) on this list that are eager to get their mce >remotes working. Another guy ><http://article.gmane.org/gmane.comp.hardware.lirc/1979> said he had >been working on a driver too, but he has been away since. >We could even test your initialization problems ;). > > |
From: EC <zy...@ve...> - 2005-03-03 00:13:55
|
Tue, 01 Mar 2005 21:30:34 -0700 | Jim Cottrell <Jim...@ut...> ::-Yeah, I have been away for a bit. I've been busy with school, but I've ::-been checking into things with the driver with a couple of guys. Jeff ::-Burricelli tells me that it works great every time with his setup ::-(2.6.10), so I'm going to go ahead and just attach the full driver to ::-this e-mail. I've had initialization problems with the receiver like ::-Martin describes, but it's always seemed like something with the Linux ::-USB sub-system itself and not the driver. So, whoever wants to try out ::-the driver is welcome to it. It would be especially nice if others ::-running the latest and greatest could check it out. If it consistently ::-works, then the initialization issues could be cleared up in later kernels. ::- ::-Good luck with the driver. I'll watch the list for news about it, and ::-if things work out well, I'll make a couple of final changes and submit ::-a patch. Or Martin can do his. Either way. ::- ::-Jim ::- Thank you for the work. However I am having some problems. I am not sure if they are the same as yours, but here it goes. I started by moving your lirc_mceusb.c in place of the old one, then set up and installed lirc (latest cvs). # uname -r 2.6.10 I plug the reciever in and it automatically ins' lirc_dev and lirc_mceusb. Then it gives me the following in my syslog (lirc is set up to use syslog()): Mar 2 18:58:22 kodos kernel: usbcore: deregistering driver lirc_mceusb Mar 2 18:58:33 kodos kernel: usb 1-2: new full speed USB device using uhci_hcd and address 5 Mar 2 18:58:33 kodos kernel: lirc_dev: IR Remote Control driver registered, at major 61 Mar 2 18:58:33 kodos kernel: lirc_dev: lirc_register_plugin:sample_rate: 80 Mar 2 18:58:33 kodos kernel: devfs_mk_dev: could not append to parent for lirc/0 Mar 2 18:58:34 kodos kernel: usb 1-2: modprobe timed out on ep1in Mar 2 18:58:34 kodos usb.agent[3019]: lirc_mceusb: loaded successfully Mar 2 18:58:34 kodos kernel: usbcore: registered new driver lirc_mceusb Mar 2 18:58:34 kodos kernel: /home/ec/lirc/drivers/lirc_mceusb/lirc_mceusb.c: USB Microsoft IR Transceiver Driver v0.2 then I run # mode2 -d /dev/lirc/0 and get no output when i press any of the buttons. After I ctl+c mode2, the Mar 2 19:03:40 kodos kernel: usb 1-2: lirc_dev timed out on ep1in Mar 2 19:04:11 kodos last message repeated 116 times start to pile up if I try to run mode2 again, it gives me: mode2: error opening /dev/lirc/0 mode2: Device or resource busy I then rmmod lirc_mceusb and get Mar 2 19:10:22 kodos kernel: lirc_dev: lirc_unregister_plugin:plugin lirc_mceusb [0] in use!<6>/home/ec/lirc/drivers/lirc_mceusb/lirc_mceusb.c: Microsoft IR Transceiver #0 now disconnected and rmmod lirc_dev Mar 2 19:10:53 kodos kernel: Unable to handle kernel paging request at virtual address e117006a Mar 2 19:10:53 kodos kernel: printing eip: Mar 2 19:10:53 kodos kernel: e117006a Mar 2 19:10:53 kodos kernel: *pde = 1fa4a067 Mar 2 19:10:53 kodos kernel: *pte = 00000000 Mar 2 19:10:53 kodos kernel: Oops: 0000 [#5] Mar 2 19:10:53 kodos kernel: PREEMPT Mar 2 19:10:53 kodos kernel: Modules linked in: thermal fan button processor joydev nvidia Mar 2 19:10:53 kodos kernel: CPU: 0 Mar 2 19:10:53 kodos kernel: EIP: 0060:[<e117006a>] Tainted: P VLI Mar 2 19:10:53 kodos kernel: EFLAGS: 00010286 (2.6.10) Mar 2 19:10:53 kodos kernel: EIP is at 0xe117006a Mar 2 19:10:53 kodos kernel: eax: 00000000 ebx: e1172f20 ecx: 00000000 edx: c459ffa4 Mar 2 19:10:53 kodos kernel: esi: 00000000 edi: 0000000c ebp: ffffffff esp: c459ffd0 Mar 2 19:10:53 kodos kernel: ds: 007b es: 007b ss: 0068 Mar 2 19:10:53 kodos kernel: Process lirc_dev (pid: 3094, threadinfo=c459f000 task=c459e9e0) Mar 2 19:10:53 kodos kernel: Stack: dfa6c800 c5527700 00000000 c459f000 e1170000 00000000 00000000 00000000 Mar 2 19:10:53 kodos kernel: c01012bd e1172f20 00000000 00000000 Mar 2 19:10:53 kodos kernel: Call Trace: Mar 2 19:10:53 kodos kernel: [<c01012bd>] kernel_thread_helper+0x5/0x18 Mar 2 19:10:53 kodos kernel: Code: Bad EIP value. Did you solve this by just re-plugging the reciever? Or is this something else? Thanks for any insight. //Eli |
From: Jim C. <Jim...@ut...> - 2005-03-03 00:40:40
|
I haven't seen anything like that before. Give the driver a try with LIRC 0.7.0. I haven't looked much at the current CVS changes, so there might be something going on there. Jim |
From: EC <zy...@ve...> - 2005-03-03 02:21:29
|
Wed, 02 Mar 2005 17:40:36 -0700 | Jim Cottrell <Jim...@ut...> ::-I haven't seen anything like that before. Give the driver a try with ::-LIRC 0.7.0. I haven't looked much at the current CVS changes, so there ::-might be something going on there. ::- ::-Jim ::- ::- ::-------------------------------------------------------- ::-SF email is sponsored by - The IT Product Guide ::-Read honest & candid reviews on hundreds of IT Products from real users. ::-Discover which products truly live up to the hype. Start reading now. ::-http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click yep, works great on 0.7.0 I am still getting those "lirc_dev timed out on ep1in" messages constantly to the console, but they are not fatal. Now for the tedious process of setting up a ~/.lircrc... //ec |
From: Jim C. <Jim...@ut...> - 2005-03-03 05:28:48
|
The timeout message is normal, because the driver polls the receiver for data. Martin Blatter has told me his driver uses interrupts, which I didn't think was possible with this receiver. So, we might be able to do away with the timeouts. Jim EC wrote: >Wed, 02 Mar 2005 17:40:36 -0700 | Jim Cottrell <Jim...@ut...> > >::-I haven't seen anything like that before. Give the driver a try with >::-LIRC 0.7.0. I haven't looked much at the current CVS changes, so there >::-might be something going on there. >::- >::-Jim >::- >::- >::-------------------------------------------------------- >::-SF email is sponsored by - The IT Product Guide >::-Read honest & candid reviews on hundreds of IT Products from real users. >::-Discover which products truly live up to the hype. Start reading now. >::-http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > >yep, works great on 0.7.0 >I am still getting those "lirc_dev timed out on ep1in" messages constantly to the console, >but they are not fatal. >Now for the tedious process of setting up a ~/.lircrc... > >//ec > > >------------------------------------------------------- >SF email is sponsored by - The IT Product Guide >Read honest & candid reviews on hundreds of IT Products from real users. >Discover which products truly live up to the hype. Start reading now. >http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > > > |
From: Martin B. <mbl...@gm...> - 2005-03-03 12:40:22
Attachments:
lirc_philipsusb.c.gz
|
Well, I just installed kernel 2.6.11 based on the input I got from this list and guess what, initialization works every time! It looks like the problem lies within USB enumeration in the Linux kernel code. So I'm afraid you'll have to install kernel 2.6.10 or higher to use this driver. The interrupt-driven version is attached. You might want to rename it to lirc_mceusb for easier installation when testing. Don't forget to change the driver name on line 55 as well. I will add some finishing touches and clean up the code later this week and eventually submit it to the lirc folks. Have fun playing with the remote ;-) regards martin On Wed, 02 Mar 2005 22:28:45 -0700, Jim Cottrell <Jim...@ut...> wrote: > The timeout message is normal, because the driver polls the receiver for > data. Martin Blatter has told me his driver uses interrupts, which I > didn't think was possible with this receiver. So, we might be able to > do away with the timeouts. |
From: Dan C. <dc...@ac...> - 2005-03-06 19:44:38
|
I'm really glad a few folks have had the time to look into this and build a driver for the new remotes. If i ever have free time (hah!) i'll look into the interrupt vs bulk thing. Strange that it only advertises bulk endpoints but you can use them as interrupt - if that works on the older remotes too then it might make sense to add the initialization stuff and the vendor/product id the older remotes use into the new driver, since i think people might get confused between the two. Some MCE2005 remotes are microsoft branded. Thanks again Jim and Martin, also thanks to Troy Roberts did some initial investigation into the new remotes. Martin Blatter wrote: > Well, I just installed kernel 2.6.11 based on the input I got from this list > and guess what, initialization works every time! > > It looks like the problem lies within USB enumeration in the Linux kernel > code. So I'm afraid you'll have to install kernel 2.6.10 or higher to use > this driver. > > The interrupt-driven version is attached. You might want to rename > it to lirc_mceusb for easier installation when testing. Don't forget to > change the driver name on line 55 as well. > > I will add some finishing touches and clean up the code later this week > and eventually submit it to the lirc folks. > > Have fun playing with the remote ;-) > > regards > martin > > On Wed, 02 Mar 2005 22:28:45 -0700, Jim Cottrell <Jim...@ut...> wrote: > >>The timeout message is normal, because the driver polls the receiver for >>data. Martin Blatter has told me his driver uses interrupts, which I >>didn't think was possible with this receiver. So, we might be able to >>do away with the timeouts. |
From: <spa...@co...> - 2005-03-03 02:15:36
|
Great work! It works here on the first try. I have to check all the buttons. Do I need an update lircd.conf file? This with kernel 2.6.10, and lirc-0.7.0 Thanks a lot!!! |
From: Ryan T. <ry...@tr...> - 2005-03-05 10:05:51
|
I've been pretty busy lately, but finally got time this weekend to upgrade to kernel 2.6.10 and test out the driver. For the first time ever, I am able to use my remote! Kudos to you for such great work. Now I can get back my wireless keyboard/mouse I donated to my Mythtv box over a year ago. Ryan Jim Cottrell wrote: > Yeah, I have been away for a bit. I've been busy with school, but I've > been checking into things with the driver with a couple of guys. Jeff > Burricelli tells me that it works great every time with his setup > (2.6.10), so I'm going to go ahead and just attach the full driver to > this e-mail. I've had initialization problems with the receiver like > Martin describes, but it's always seemed like something with the Linux > USB sub-system itself and not the driver. So, whoever wants to try out > the driver is welcome to it. It would be especially nice if others > running the latest and greatest could check it out. If it consistently > works, then the initialization issues could be cleared up in later kernels. > > Good luck with the driver. I'll watch the list for news about it, and > if things work out well, I'll make a couple of final changes and submit > a patch. Or Martin can do his. Either way. > > Jim > > > EC wrote: > >> Tue, 01 Mar 2005 13:06:16 +0100 | Martin Blatter <mbl...@gm...> >> >> ::-I wrote a driver for the new MCE (aka Philips eHome) remote. >> Basically it works ::-great, however the initialization of the remote >> fails most of the ::-time. I need to plug it >> ::-in at least two or three times to have it initialized correctly. >> ::- >> ::-USB Snoopy on Windows shows me the exact same initialization sequence >> that ::-I use in my driver but somehow the transciever behaves >> differently. Did anyone ::-experience similar problems? Is there >> something in the USB enumeration process ::-that Linux does differently >> than Windows that might affect the ::-initialization process? >> ::- >> ::-regrads >> ::-martin >> ::- >> ::- >> ::-------------------------------------------------------- >> ::-SF email is sponsored by - The IT Product Guide >> ::-Read honest & candid reviews on hundreds of IT Products from real >> users. ::-Discover which products truly live up to the hype. Start >> reading now. ::-http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click >> >> Would you mind making the driver available? I know there are many >> people (myself included) on this list that are eager to get their mce >> remotes working. Another guy >> <http://article.gmane.org/gmane.comp.hardware.lirc/1979> said he had >> been working on a driver too, but he has been away since. >> We could even test your initialization problems ;). >> >> > > ------------------------------------------------------------------------ > > /* > * USB Microsoft IR Transceiver driver - 0.2 > * > * Copyright (c) 2003-2004 Dan Conti (dc...@ac...) > * > * This driver is based on the USB skeleton driver packaged with the > * kernel, and the notice from that package has been retained below. > * > * The Microsoft IR Transceiver is a neat little IR receiver with two > * emitters on it designed for Windows Media Center. This driver might > * work for all media center remotes, but I have only tested it with > * the philips model. The first revision of this driver only supports > * the receive function - the transmit function will be much more > * tricky due to the nature of the hardware. Microsoft chose to build > * this device inexpensively, therefore making it extra dumb. > * There is no interrupt endpoint on this device; all usb traffic > * happens over two bulk endpoints. As a result of this, poll() for > * this device is an actual hardware poll (instead of a receive queue > * check) and is rather expensive. > * > * All trademarks property of their respective owners. This driver was > * originally based on the USB skeleton driver, although significant > * portions of that code have been removed as the driver has evolved. > * > * 2003_11_11 - Restructured to minimalize code interpretation in the > * driver. The normal use case will be with lirc. > * > * 2004_01_01 - Removed all code interpretation. Generate mode2 data > * for passing off to lirc. Cleanup > * > * 2004_01_04 - Removed devfs handle. Put in a temporary workaround > * for a known issue where repeats generate two > * sequential spaces (last_was_repeat_gap) > * > * 2004_02_17 - Changed top level api to no longer use fops, and > * instead use new interface for polling via > * lirc_thread. Restructure data read/mode2 generation to > * a single pass, reducing number of buffers. Rev to .2 > * > * 2004_02_27 - Last of fixups to plugin->add_to_buf API. Properly > * handle broken fragments from the receiver. Up the > * sample rate and remove any pacing from > * fetch_more_data. Fixes all known issues. > * > * 2005_02_17 - Updated to support new Phillips remote. > * > * TODO > * - Fix up minor number, registration of major/minor with usb subsystem > * > */ > /* > * USB Skeleton driver - 1.1 > * > * Copyright (C) 2001-2003 Greg Kroah-Hartman (gr...@kr...) > * > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License as > * published by the Free Software Foundation, version 2. > * > * > * This driver is to be used as a skeleton driver to be able to create a > * USB driver quickly. The design of it is based on the usb-serial and > * dc2xx drivers. > * > * Thanks to Oliver Neukum, David Brownell, and Alan Stern for their help > * in debugging this driver. > * > * > * History: > * > * 2003-05-06 - 1.1 - changes due to usb core changes with usb_register_dev() > * 2003-02-25 - 1.0 - fix races involving urb->status, unlink_urb(), and > * disconnect. Fix transfer amount in read(). Use > * macros instead of magic numbers in probe(). Change > * size variables to size_t. Show how to eliminate > * DMA bounce buffer. > * 2002_12_12 - 0.9 - compile fixes and got rid of fixed minor array. > * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device > * driver. > * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do > * not have both a bulk in and bulk out endpoint. > * Thanks to Holger Waechtler for the fix. > * 2001_11_05 - 0.6 - fix minor locking problem in skel_disconnect. > * Thanks to Pete Zaitcev for the fix. > * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux > * 2001_08_21 - 0.4 - more small bug fixes. > * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel > * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people > * 2001_05_01 - 0.1 - first version > * > */ > > #include <linux/config.h> > #include <linux/kernel.h> > #include <linux/errno.h> > #include <linux/init.h> > #include <linux/slab.h> > #include <linux/module.h> > #include <linux/smp_lock.h> > #include <linux/usb.h> > #ifdef KERNEL_2_5 > #include <linux/completion.h> > #include <asm/uaccess.h> > #else > #include <linux/spinlock.h> > #include <linux/list.h> > #include <linux/fcntl.h> > #include <linux/poll.h> > #include <linux/sched.h> > #include <linux/signal.h> > #endif > > #ifdef CONFIG_USB_DEBUG > static int debug = 1; > #else > static int debug = 0; > #endif > > #include "drivers/kcompat.h" > #include "drivers/lirc.h" > #include "drivers/lirc_dev/lirc_dev.h" > > /* Use our own dbg macro */ > #define dprintk(fmt, args...) \ > do{ \ > if(debug) printk(KERN_DEBUG __FILE__ ": " \ > fmt "\n", ## args); \ > }while(0) > > /* Version Information */ > #define DRIVER_VERSION "v0.2" > #define DRIVER_AUTHOR "Dan Conti, dc...@ac..." > #define DRIVER_DESC "USB Microsoft IR Transceiver Driver" > #define DRIVER_NAME "lirc_mceusb" > > /* IDs for old and new products */ > #define USB_MCEUSB_VENDOR_ID1 0x045e > #define USB_MCEUSB_PRODUCT_ID1 0x006d > #define USB_MCEUSB_VENDOR_ID2 0x0471 > #define USB_MCEUSB_PRODUCT_ID2 0x0815 > > > /* table of devices that work with this driver */ > static struct usb_device_id mceusb_table [] = { > { USB_DEVICE(USB_MCEUSB_VENDOR_ID1, USB_MCEUSB_PRODUCT_ID1) }, > { USB_DEVICE(USB_MCEUSB_VENDOR_ID2, USB_MCEUSB_PRODUCT_ID2) }, > { } /* Terminating entry */ > }; > > /* we can have up to this number of device plugged in at once */ > #define MAX_DEVICES 16 > > /* Structure to hold all of our device specific stuff */ > struct usb_skel { > struct usb_device * udev; /* save off the usb device pointer */ > struct usb_interface * interface; /* the interface for this device */ > unsigned char minor; /* the starting minor number for this device */ > unsigned char num_ports; /* the number of ports this device has */ > char num_interrupt_in; /* number of interrupt in endpoints we have */ > char num_bulk_in; /* number of bulk in endpoints we have */ > char num_bulk_out; /* number of bulk out endpoints we have */ > > unsigned char * bulk_in_buffer; /* the buffer to receive data */ > int bulk_in_size; /* the size of the receive buffer */ > __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ > > unsigned char * bulk_out_buffer; /* the buffer to send data */ > int bulk_out_size; /* the size of the send buffer */ > struct urb * write_urb; /* the urb used to send data */ > __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ > > atomic_t write_busy; /* true iff write urb is busy */ > struct completion write_finished; /* wait for the write to finish */ > > wait_queue_head_t wait_q; /* for timeouts */ > int open_count; /* number of times this port has been opened */ > struct semaphore sem; /* locks this structure */ > > int present; /* if the device is not disconnected */ > > struct lirc_plugin* plugin; > > lirc_t lircdata[256]; /* place to store values until lirc processes them */ > int lircidx; /* current index */ > int lirccnt; /* remaining values */ > > int usb_valid_bytes_in_bulk_buffer; /* leftover data from a previous read */ > int mce_bytes_left_in_packet; /* for packets split across multiple reads */ > > int header_bytes; /* Older remote sends 2-byte header */ > int remote_type; /* 1 for older remotes, 2 for newer */ > > /* Value to hold the last received space; 0 if last value > * received was a pulse > */ > int last_space; > > #ifdef KERNEL_2_5 > dma_addr_t dma_in; > dma_addr_t dma_out; > #endif > }; > > #define MCE_TIME_UNIT 50 > > /* driver api */ > #ifdef KERNEL_2_5 > static int mceusb_probe (struct usb_interface *interface, const struct usb_device_id *id); > static void mceusb_disconnect (struct usb_interface *interface); > static void mceusb_write_bulk_callback (struct urb *urb, struct pt_regs *regs); > #else > static void * mceusb_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id); > static void mceusb_disconnect (struct usb_device *dev, void *ptr); > static void mceusb_write_bulk_callback (struct urb *urb); > #endif > > /* read data from the usb bus; convert to mode2 */ > static int msir_fetch_more_data( struct usb_skel* dev, int dont_block ); > > /* helper functions */ > static void msir_cleanup( struct usb_skel* dev ); > static void set_use_dec( void* data ); > static int set_use_inc( void* data ); > > /* array of pointers to our devices that are currently connected */ > static struct usb_skel *minor_table[MAX_DEVICES]; > > /* lock to protect the minor_table structure */ > static DECLARE_MUTEX (minor_table_mutex); > static void mceusb_setup1( struct usb_device *udev ); > static void mceusb_setup2( struct usb_device *udev, struct usb_skel* dev ); > > /* usb specific object needed to register this driver with the usb subsystem */ > static struct usb_driver mceusb_driver = { > .owner = THIS_MODULE, > .name = DRIVER_NAME, > .probe = mceusb_probe, > .disconnect = mceusb_disconnect, > .id_table = mceusb_table, > }; > > > /** > * usb_mceusb_debug_data > */ > static inline void usb_mceusb_debug_data (const char *function, int size, > const unsigned char *data) > { > int i; > if (!debug) > return; > > printk(KERN_DEBUG __FILE__": %s - length = %d, data = ", > function, size); > for (i = 0; i < size; ++i) { > printk(KERN_DEBUG "%.2x ", data[i]); > } > printk(KERN_DEBUG "\n"); > } > > /** > *mceusb_delete > */ > static inline void mceusb_delete (struct usb_skel *dev) > { > dprintk("%s", __func__); > minor_table[dev->minor] = NULL; > #ifdef KERNEL_2_5 > usb_buffer_free(dev->udev, dev->bulk_in_size, dev->bulk_in_buffer, dev->dma_in); > usb_buffer_free(dev->udev, dev->bulk_out_size, dev->bulk_out_buffer, dev->dma_out); > #else > if (dev->bulk_in_buffer != NULL) > kfree (dev->bulk_in_buffer); > if (dev->bulk_out_buffer != NULL) > kfree (dev->bulk_out_buffer); > #endif > if (dev->write_urb != NULL) > usb_free_urb (dev->write_urb); > kfree (dev); > } > > /* Setup routine for older MS remote */ > static void mceusb_setup1( struct usb_device *udev ) > { > char data[8]; > int res; > > memset( data, 0, 8 ); > > /* Get Status */ > res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), > USB_REQ_GET_STATUS, USB_DIR_IN, > 0, 0, data, 2, HZ * 3); > > /* res = usb_get_status( udev, 0, 0, data ); */ > dprintk("%s - res = %d status = 0x%x 0x%x", __func__, > res, data[0], data[1]); > > /* 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 ); > > res = usb_control_msg( udev, usb_rcvctrlpipe(udev, 0), > 5, USB_TYPE_VENDOR, 0, 0, > data, 2, HZ * 3 ); > dprintk("%s - res = %d, devnum = %d", __func__, res, udev->devnum); > dprintk("%s - data[0] = %d, data[1] = %d", __func__, > data[0], data[1] ); > > > /* set feature */ > res = usb_control_msg( udev, usb_sndctrlpipe(udev, 0), > USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, > 0xc04e, 0x0000, NULL, 0, HZ * 3 ); > > dprintk("%s - res = %d", __func__, res); > > /* These two are sent by the windows driver, but stall for > * me. I dont have an analyzer on the linux side so i can't > * see what is actually different and why the device takes > * issue with them > */ > #if 0 > /* this is some custom control message they send */ > res = usb_control_msg( udev, usb_sndctrlpipe(udev, 0), > 0x04, USB_TYPE_VENDOR, > 0x0808, 0x0000, NULL, 0, HZ * 3 ); > > dprintk("%s - res = %d", __func__, res); > > /* this is another custom control message they send */ > res = usb_control_msg( udev, usb_sndctrlpipe(udev, 0), > 0x02, USB_TYPE_VENDOR, > 0x0000, 0x0100, NULL, 0, HZ * 3 ); > > dprintk("%s - res = %d", __func__, res); > #endif > } > > /* Setup routine for newer Phillips remote */ > static void mceusb_setup2( struct usb_device *udev, struct usb_skel* dev ) > { > char data[16]; > int res, size; > > memset( data, 0, 16 ); > res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), > USB_REQ_GET_STATUS, USB_DIR_IN, 0, 0, > data, 2, HZ); > dprintk("%s - Get Status: res = %d, status = 0x%x 0x%x", __func__, res, data[0], data[1]); > > memset( data, 0, 16 ); > res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), > USB_REQ_SET_CONFIGURATION, 0, 1, 0, > data, 0, HZ); > dprintk("%s - Set Configuration #1: res = %d", __func__, res); > > /* Doesn't seem strictly necessary, but the Windows driver does it */ > > memset( data, 0, 16 ); > data[0] = 0; > data[1] = 0xFF; > data[2] = 0xAA; > data[3] = 0xFF; > data[4] = 0x0B; > > res = usb_bulk_msg(udev, usb_sndbulkpipe(udev, dev->bulk_out_endpointAddr), > data, 5, &size, HZ); > dprintk("%s - Send #1: res = %d, data = 0x%x 0x%x, size=%d, sendAddr=%d", __func__, res, data[0], data[1], size, dev->bulk_out_endpointAddr); > if (res == -ETIMEDOUT) > { > err("%s - Unsuccessful initialization", __func__); > return; > } > > memset( data, 0, 16 ); > res = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, dev->bulk_in_endpointAddr), > data, 16, &size, HZ); > dprintk("%s - Receive #1: res = %d, size=%d, receiveAddr=%d", __func__, res, size, dev->bulk_in_endpointAddr); > > memset( data, 0, 16 ); > data[0] = 0xFF; > data[1] = 0x18; > > res = usb_bulk_msg(udev, usb_sndbulkpipe(udev, dev->bulk_out_endpointAddr), > data, 2, &size, HZ); > dprintk("%s - Send #2: res = %d, size=%d, sendAddr=%d", __func__, res, size, dev->bulk_out_endpointAddr); > > memset( data, 0, 16 ); > res = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, dev->bulk_in_endpointAddr), > data, 16, &size, HZ * 5); > dprintk("%s - Receive #2: res = %d, size=%d, receiveAddr=%d", __func__, res, size, dev->bulk_in_endpointAddr); > } > > static void msir_cleanup( struct usb_skel* dev ) > { > memset( dev->bulk_in_buffer, 0, dev->bulk_in_size ); > > dev->usb_valid_bytes_in_bulk_buffer = 0; > > dev->last_space = PULSE_MASK; > > dev->mce_bytes_left_in_packet = 0; > dev->lircidx = 0; > dev->lirccnt = 0; > memset( dev->lircdata, 0, sizeof(dev->lircdata) ); > } > > static int set_use_inc(void* data) > { > MOD_INC_USE_COUNT; > return 0; > } > > static void set_use_dec(void* data) > { > /* check for unplug here */ > struct usb_skel* dev = (struct usb_skel*) data; > if( !dev->udev ) > { > lirc_unregister_plugin( dev->minor ); > lirc_buffer_free( dev->plugin->rbuf ); > kfree( dev->plugin->rbuf ); > kfree( dev->plugin ); > } > > MOD_DEC_USE_COUNT; > } > > /* > * msir_fetch_more_data > * > * The goal here is to read in more remote codes from the remote. In > * the event that the remote isn't sending us anything, the caller > * will block until a key is pressed (i.e. this performs phys read, > * filtering, and queueing of data) unless dont_block is set to 1; in > * this situation, it will perform a few reads and will exit out if it > * does not see any appropriate data > * > * dev->sem should be locked when this function is called - fine grain > * locking isn't really important here anyways > * > * This routine always returns the number of words available > * > */ > static int msir_fetch_more_data( struct usb_skel* dev, int dont_block ) > { > int retries = 0; > int words_to_read = > (sizeof(dev->lircdata)/sizeof(lirc_t)) - dev->lirccnt; > int partial, this_read = 0; > int bulkidx = 0; > int bytes_left_in_packet = 0; > signed char* signedp = (signed char*)dev->bulk_in_buffer; > > if( words_to_read == 0 ) > return dev->lirccnt; > > /* this forces all existing data to be read by lirc before we > * issue another usb command. this is the only form of > * throttling we have > */ > if( dev->lirccnt ) > { > return dev->lirccnt; > } > > /* reserve room for our leading space */ > if( dev->last_space ) > words_to_read--; > > while( words_to_read ) > { > /* handle signals and USB disconnects */ > if( signal_pending(current) ) > { > return dev->lirccnt ? dev->lirccnt : -EINTR; > } > if( !dev->udev ) > { > return -ENODEV; > } > > bulkidx = 0; > > /* > * perform data read (phys or from previous buffer) > */ > > /* use leftovers if present, otherwise perform a read */ > if( dev->usb_valid_bytes_in_bulk_buffer ) > { > this_read = partial = > dev->usb_valid_bytes_in_bulk_buffer; > dev->usb_valid_bytes_in_bulk_buffer = 0; > } > else > { > int retval; > > this_read = dev->bulk_in_size; > partial = 0; > retval = usb_bulk_msg > (dev->udev, > usb_rcvbulkpipe > (dev->udev, dev->bulk_in_endpointAddr), > (unsigned char*)dev->bulk_in_buffer, > this_read, &partial, HZ/4); > > /* retry a few times on overruns; map all > other errors to -EIO */ > if( retval ) > { > if( retval == -EOVERFLOW && > retries < 5 ) > { > retries++; > interruptible_sleep_on_timeout > ( &dev->wait_q, HZ ); > continue; > } > else > { > return -EIO; > } > } > > retries = 0; > if( partial ) > this_read = partial; > > /* skip the header */ > bulkidx += dev->header_bytes; > > /* check for empty reads (header only) */ > if (dev->header_bytes > 0 && this_read == dev->header_bytes) > { > /* assume no data */ > if( dont_block ) > { > break; > } > > /* sleep for a bit before performing > another read */ > interruptible_sleep_on_timeout > ( &dev->wait_q, 1 ); > continue; > } > } > > /* > * process data > */ > > /* at this point this_read is > 0 */ > while( bulkidx < this_read && > (words_to_read > (dev->last_space ? 1 : 0)) ) > //while( bulkidx < this_read && words_to_read ) > { > int keycode; > int pulse = 0; > > /* read packet length if needed */ > if( !bytes_left_in_packet ) > { > > /* we assume we are on a packet length > * value. it is possible, in some > * cases, to get a packet that does > * not start with a length, apparently > * due to some sort of fragmenting, > * but occaisonally we do not receive > * the second half of a fragment > */ > bytes_left_in_packet = > 128 + signedp[bulkidx++]; > > > /* This is a bit of a hack. Basically, > timing out the bulk transfer on the > new remote delays key presses noticeably, > so this tries to quit early when it > reaches the end of transmission - Jim */ > if (bytes_left_in_packet == 31 && dev->remote_type == 2) > { > dev->mce_bytes_left_in_packet = 0; > return dev->lirccnt; > } > > /* unfortunately rather than keep all > * the data in the packetized format, > * the transceiver sends a trailing 8 > * bytes that aren't part of the > * transmittion from the remote, > * aren't packetized, and dont really > * have any value. we can basically > * tell we have hit them if 1) we have > * a loooong space currently stored > * up, and 2) the bytes_left value for > * this packet is obviously wrong > */ > if( bytes_left_in_packet > 4 ) > { > if( dev->mce_bytes_left_in_packet ) > { > bytes_left_in_packet = dev->mce_bytes_left_in_packet; > bulkidx--; > } > bytes_left_in_packet = 0; > bulkidx = this_read; > } > > /* always clear this if we have a > valid packet */ > dev->mce_bytes_left_in_packet = 0; > > /* continue here to verify we haven't > hit the end of the bulk_in */ > continue; > > } > > /* > * generate mode2 > */ > > keycode = signedp[bulkidx++]; > if( keycode < 0 ) > { > pulse = 1; > keycode += 128; > } > keycode *= MCE_TIME_UNIT; > > bytes_left_in_packet--; > > if( pulse ) > { > if( dev->last_space ) > { > dev->lircdata[dev->lirccnt++] = > dev->last_space; > dev->last_space = 0; > words_to_read--; > > /* clear the lirc_t for the pulse */ > dev->lircdata[dev->lirccnt] = 0; > } > dev->lircdata[dev->lirccnt] += keycode; > dev->lircdata[dev->lirccnt] |= PULSE_BIT; > } > else > { > /* on pulse->space transition, add one > for the existing pulse */ > if( dev->lircdata[dev->lirccnt] && > !dev->last_space ) > { > dev->lirccnt++; > words_to_read--; > } > > dev->last_space += keycode; > } > } > } > > /* save off some info if we are exiting mid-packet, or with > leftovers */ > if( bytes_left_in_packet ) > { > dev->mce_bytes_left_in_packet = bytes_left_in_packet; > } > if( bulkidx < this_read ) > { > dev->usb_valid_bytes_in_bulk_buffer = (this_read - bulkidx); > memcpy( dev->bulk_in_buffer, &(dev->bulk_in_buffer[bulkidx]), > dev->usb_valid_bytes_in_bulk_buffer ); > } > return dev->lirccnt; > } > > /* mceusb_add_to_buf: called by lirc_dev to fetch all available keys > * this is used as a polling interface for us: since we set > * plugin->sample_rate we will periodically get the below call to > * check for new data returns 0 on success, or -ENODATA if nothing is > * available > */ > static int mceusb_add_to_buf(void* data, struct lirc_buffer* buf ) > { > struct usb_skel* dev = (struct usb_skel*) data; > > down( &dev->sem ); > > /* verify device still present */ > if( dev->udev == NULL ) > { > up( &dev->sem ); > return -ENODEV; > } > > if( !dev->lirccnt ) > { > int res; > dev->lircidx = 0; > > res = msir_fetch_more_data( dev, 1 ); > > if( res == 0 ) > res = -ENODATA; > if( res < 0 ) { > up( &dev->sem ); > return res; > } > } > > if( dev->lirccnt ) > { > int keys_to_copy; > > /* determine available buffer space and available data */ > keys_to_copy = lirc_buffer_available( buf ); > if( keys_to_copy > dev->lirccnt ) > { > keys_to_copy = dev->lirccnt; > } > > lirc_buffer_write_n( buf, (unsigned char*) &(dev->lircdata[dev->lircidx]), keys_to_copy ); > dev->lircidx += keys_to_copy; > dev->lirccnt -= keys_to_copy; > > up( &dev->sem ); > return 0; > } > > up( &dev->sem ); > return -ENODATA; > } > > /** > * mceusb_write_bulk_callback > */ > #ifdef KERNEL_2_5 > static void mceusb_write_bulk_callback (struct urb *urb, struct pt_regs *regs) > #else > static void mceusb_write_bulk_callback (struct urb *urb) > #endif > { > struct usb_skel *dev = (struct usb_skel *)urb->context; > > dprintk("%s - minor %d", __func__, dev->minor); > > if ((urb->status != -ENOENT) && > (urb->status != -ECONNRESET)) { > dprintk("%s - nonzero write buld status received: %d", > __func__, urb->status); > return; > } > > return; > } > > /** > * mceusb_probe > * > * Called by the usb core when a new device is connected that it > * thinks this driver might be interested in. > */ > #ifdef KERNEL_2_5 > static int mceusb_probe(struct usb_interface *interface, const struct usb_device_id *id) > { > struct usb_device *udev = interface_to_usbdev(interface); > struct usb_host_interface *iface_desc; > #else > static void * mceusb_probe(struct usb_device *udev, unsigned int ifnum, > const struct usb_device_id *id) > { > struct usb_interface *interface = &udev->actconfig->interface[ifnum]; > struct usb_interface_descriptor *iface_desc; > #endif > struct usb_skel *dev = NULL; > struct usb_endpoint_descriptor *endpoint; > > struct lirc_plugin* plugin; > struct lirc_buffer* rbuf; > > int minor; > size_t buffer_size; > int i, remote_type; > int retval = -ENOMEM; > > /* See if the device offered us matches what we can accept */ > if (udev->descriptor.idVendor == USB_MCEUSB_VENDOR_ID1 && > udev->descriptor.idProduct == USB_MCEUSB_PRODUCT_ID1) { > remote_type = 1; > } > else if (udev->descriptor.idVendor == USB_MCEUSB_VENDOR_ID2 && > udev->descriptor.idProduct == USB_MCEUSB_PRODUCT_ID2) { > remote_type = 2; > } > else > { > dprintk("Wrong Vendor/Product IDs"); > > #ifdef KERNEL_2_5 > return -ENODEV; > #else > return NULL; > #endif > } > > /* select a "subminor" number (part of a minor number) */ > down (&minor_table_mutex); > for (minor = 0; minor < MAX_DEVICES; ++minor) { > if (minor_table[minor] == NULL) > break; > } > if (minor >= MAX_DEVICES) { > info ("Too many devices plugged in, " > "can not handle this device."); > goto error; > } > > /* allocate memory for our device state and initialize it */ > dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL); > if (dev == NULL) { > err ("Out of memory"); > #ifdef KERNEL_2_5 > retval = -ENOMEM; > #endif > goto error; > } > minor_table[minor] = dev; > > memset (dev, 0x00, sizeof (*dev)); > init_MUTEX (&dev->sem); > dev->udev = udev; > dev->interface = interface; > dev->minor = minor; > > /* set up the endpoint information */ > /* check out the endpoints */ > /* use only the first bulk-in and bulk-out endpoints */ > #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,4) > iface_desc = interface->cur_altsetting; > #else > iface_desc = &interface->altsetting[0]; > #endif > > #ifdef KERNEL_2_5 > for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { > endpoint = &iface_desc->endpoint[i].desc; > #else > for (i = 0; i < iface_desc->bNumEndpoints; ++i) { > endpoint = &iface_desc->endpoint[i]; > #endif > if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) && > ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == > USB_ENDPOINT_XFER_BULK)) { > dprintk("we found a bulk in endpoint"); > buffer_size = endpoint->wMaxPacketSize; > dev->bulk_in_size = buffer_size; > dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; > #ifdef KERNEL_2_5 > dev->bulk_in_buffer = usb_buffer_alloc > (udev, buffer_size, SLAB_ATOMIC, &dev->dma_in); > #else > dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); > #endif > if (!dev->bulk_in_buffer) { > err("Couldn't allocate bulk_in_buffer"); > goto error; > } > } > > if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == 0x00) && > ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == > USB_ENDPOINT_XFER_BULK)) { > dprintk("we found a bulk out endpoint"); > #ifdef KERNEL_2_5 > dev->write_urb = usb_alloc_urb(0, GFP_KERNEL); > #else > dev->write_urb = usb_alloc_urb(0); > #endif > if (!dev->write_urb) { > err("No free urbs available"); > goto error; > } > buffer_size = endpoint->wMaxPacketSize; > dev->bulk_out_size = buffer_size; > dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; > #ifdef KERNEL_2_5 > dev->bulk_out_buffer = usb_buffer_alloc(udev, buffer_size, SLAB_ATOMIC, &dev->dma_out); > #else > dev->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); > #endif > if (!dev->bulk_out_buffer) { > err("Couldn't allocate bulk_out_buffer"); > goto error; > } > #ifdef KERNEL_2_5 > usb_fill_bulk_urb(dev->write_urb, udev, > usb_sndbulkpipe > (udev, endpoint->bEndpointAddress), > dev->bulk_out_buffer, buffer_size, > mceusb_write_bulk_callback, dev); > #else > FILL_BULK_URB(dev->write_urb, udev, > usb_sndbulkpipe > (udev, endpoint->bEndpointAddress), > dev->bulk_out_buffer, buffer_size, > mceusb_write_bulk_callback, dev); > #endif > } > } > > if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { > err("Couldn't find both bulk-in and bulk-out endpoints"); > goto error; > } > > /* init the waitq */ > init_waitqueue_head( &dev->wait_q ); > > > /* Set up our lirc plugin */ > if(!(plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL))) { > err("out of memory"); > goto error; > } > memset( plugin, 0, sizeof(struct lirc_plugin) ); > > if(!(rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL))) { > err("out of memory"); > kfree( plugin ); > goto error; > } > > /* the lirc_atiusb module doesn't memset rbuf here ... ? */ > if( lirc_buffer_init( rbuf, sizeof(lirc_t), 128)) { > err("out of memory"); > kfree( plugin ); > kfree( rbuf ); > goto error; > } > > strcpy(plugin->name, DRIVER_NAME " "); > plugin->minor = minor; > plugin->code_length = sizeof(lirc_t) * 8; > plugin->features = LIRC_CAN_REC_MODE2; // | LIRC_CAN_SEND_MODE2; > plugin->data = dev; > plugin->rbuf = rbuf; > plugin->ioctl = NULL; > plugin->set_use_inc = &set_use_inc; > plugin->set_use_dec = &set_use_dec; > plugin->sample_rate = 80; // sample at 100hz (10ms) > plugin->add_to_buf = &mceusb_add_to_buf; > // plugin->fops = &mceusb_fops; > if( lirc_register_plugin(plugin) < 0 ) > { > kfree( plugin ); > lirc_buffer_free( rbuf ); > kfree( rbuf ); > goto error; > } > dev->plugin = plugin; > > /* 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 > */ > { > char junk[64]; > int partial = 0, retval; > do > { > retval = usb_bulk_msg > (udev, usb_rcvbulkpipe > (udev, dev->bulk_in_endpointAddr), > junk, 64, > &partial, HZ); > } while (partial > 0); > } > > msir_cleanup( dev ); > > dev->remote_type = remote_type; > if (remote_type == 1) > { > dev->header_bytes = 2; > mceusb_setup1( udev ); > } > else > { > dev->header_bytes = 0; > mceusb_setup2( udev, dev ); > } > > #ifdef KERNEL_2_5 > /* we can register the device now, as it is ready */ > usb_set_intfdata (interface, dev); > #endif > /* let the user know what node this device is now attached to */ > //info ("USB Microsoft IR Transceiver device now attached to msir%d", dev->minor); > up (&minor_table_mutex); > #ifdef KERNEL_2_5 > return 0; > #else > return dev; > #endif > error: > mceusb_delete (dev); > dev = NULL; > dprintk("%s: retval = %x", __func__, retval); > up (&minor_table_mutex); > #ifdef KERNEL_2_5 > return retval; > #else > return NULL; > #endif > } > > /** > * mceusb_disconnect > * > * Called by the usb core when the device is removed from the system. > * > * This routine guarantees that the driver will not submit any more urbs > * by clearing dev->udev. It is also supposed to terminate any currently > * active urbs. Unfortunately, usb_bulk_msg(), used in skel_read(), does > * not provide any way to do this. But at least we can cancel an active > * write. > */ > #ifdef KERNEL_2_5 > static void mceusb_disconnect(struct usb_interface *interface) > #else > static void mceusb_disconnect(struct usb_device *udev, void *ptr) > #endif > { > struct usb_skel *dev; > int minor; > #ifdef KERNEL_2_5 > dev = usb_get_intfdata (interface); > usb_set_intfdata (interface, NULL); > #else > dev = (struct usb_skel *)ptr; > #endif > > down (&minor_table_mutex); > down (&dev->sem); > minor = dev->minor; > > /* unhook lirc things */ > lirc_unregister_plugin( minor ); > lirc_buffer_free( dev->plugin->rbuf ); > kfree( dev->plugin->rbuf ); > kfree( dev->plugin ); > #ifdef KERNEL_2_5 > /* terminate an ongoing write */ > if (atomic_read (&dev->write_busy)) { > usb_unlink_urb (dev->write_urb); > wait_for_completion (&dev->write_finished); > } > > /* prevent device read, write and ioctl */ > dev->present = 0; > #endif > > mceusb_delete (dev); > > info("Microsoft IR Transceiver #%d now disconnected", minor); > up (&dev->sem); > up (&minor_table_mutex); > } > > > > /** > * usb_mceusb_init > */ > static int __init usb_mceusb_init(void) > { > int result; > > /* register this driver with the USB subsystem */ > result = usb_register(&mceusb_driver); > #ifdef KERNEL_2_5 > if ( result ) { > #else > if ( result < 0 ) { > #endif > err("usb_register failed for the " DRIVER_NAME " driver. error number %d",result); > #ifdef KERNEL_2_5 > return result; > #else > return -1; > #endif > } > > info(DRIVER_DESC " " DRIVER_VERSION); > return 0; > } > > > /** > * usb_mceusb_exit > */ > static void __exit usb_mceusb_exit(void) > { > /* deregister this driver with the USB subsystem */ > usb_deregister(&mceusb_driver); > } > > module_init (usb_mceusb_init); > module_exit (usb_mceusb_exit); > > MODULE_DESCRIPTION(DRIVER_DESC); > MODULE_AUTHOR(DRIVER_AUTHOR); > MODULE_LICENSE("GPL"); > MODULE_DEVICE_TABLE (usb, mceusb_table); > > module_param(debug, int, 0644); > MODULE_PARM_DESC(debug, "Debug enabled or not"); > > EXPORT_NO_SYMBOLS; |
From: J.BAKSHI <jo...@vs...> - 2005-03-07 14:43:49
|
hi list, I have been using mplayer along with my homebrew LIRC since long. but I have come to know about some application for home entertainment like freevo, xawtv, Mythtv in some discussion in this list. I lik to know how these application help home entertainment with LIRC and which one is the best among all these ? users of these application please response. thanks in advanced . thanks to LIRC. |
From: Eric J. <al...@xm...> - 2005-03-07 15:05:07
|
On Sun, 06 Mar 2005 11:31:06 +0530 "J.BAKSHI" <jo...@vs...> wrote: > hi list, > I have been using mplayer along with my homebrew LIRC since long. but I > have come to know about some application for home entertainment like > freevo, xawtv, Mythtv in some discussion in this list. I lik to know how > these application help home entertainment with LIRC and which one is the > best among all these ? > users of these application please response. > thanks in advanced . thanks to LIRC. It is very bad form to start a new thread by replying to a message. It confuses the heck out of mailers that understand threading, and this annoys the very people you're asking for help. In the future, just send a new message to lir...@li... I've not used myth, but I currently use freevo. As the owner of two TiVos and a proprietary satellite recorder, I couldn't be less interested in some linux app's ability to record analog video. I've never used those features, and until i start thinking about building an hdpvr, probably never will. I hear that mythtv does a much better job than freevo at recording analog video. Freevo, on the other hand, does pretty good service as a jukebox for prerecorded media, and a front end for xmame/xmess. It is written entirely in python, which is a very easy language to understand. It's very easy to use lirc with freevo. Just get lirc set up, install or build your config file, and it even has a piece that tries to automatically configure itself to understand your remote. |
From: Patrick K. <ke...@gm...> - 2005-03-13 21:11:19
|
> > > > Have fun playing with the remote ;-) > > > > regards > > martin > > Thanks again for the driver. But I don't get any output from mode2. I have this in modules.conf: alias char-major-61 lirc_mceusb When I plug in the receiver, my log messages have : Mar 13 13:00:37 media kernel: usb 3-2: new full speed USB device using ohci_hcd and address 3 Mar 13 13:00:37 media kernel: lirc_dev: lirc_register_plugin:sample_rate: 0 Mar 13 13:00:37 media kernel: lirc_philipsusb[3]: Philips eHome Infrared Transceiver on usb3:3 and when i startup lircd I get: Mar 13 12:59:24 media lircd: lircd startup succeeded but nothing from mode2 or irw, what am I doing wrong? |
From: Martin B. <mbl...@gm...> - 2005-03-14 17:32:38
|
On Sun, 13 Mar 2005 13:11:05 -0800, Patrick Kelley <ke...@gm...> wrote: > I have this in modules.conf: alias char-major-61 lirc_mceusb > Mar 13 13:00:37 media kernel: lirc_philipsusb[3]: Philips eHome > Infrared Transceiver on usb3:3 You need to either change the lirc_mceusb ib modules.conf to lirc_philipsusb or simplay rename lirc_philipsusb.c to lirc_mceusb.c and change the appropriate line with the driver name in the source code. regards martin |