LinHES Forums http://forums.linhes.org/ |
|
Lola remote incorporation into knoppmyth http://forums.linhes.org/viewtopic.php?f=2&t=2273 |
Page 1 of 1 |
Author: | billytwowilly [ Sun Aug 29, 2004 8:59 am ] |
Post subject: | Lola remote incorporation into knoppmyth |
Well, I fired off some emails to the mythtv users mailing list a long time ago with the intention of getting the lola remote to work out of the box with knoppmyth. I have had no time at all to devote to it, so now I'm passing the torch. I'd upload the code to here that I got from the mailing list to pretty much make the lola remote work, but it doesn't look like this list supports uploading code, so i'll put it as text here and if you want a better copy then email me. Here's an lircrc file: Code: #Starts the mythfrontend from X begin prog = irexec button = power config = sudo /sbin/shutdown -r now end begin prog = irexec button = 2 config = sudo /sbin/service mythbackend restart end begin prog = irexec button = 1 config = /usr/bin/mythfrontend -l ~/frontend.log end #MythTV - Number button config begin prog = mythtv button = 0 config = 0 end begin prog = mythtv button = 1 config = 1 end begin prog = mythtv button = 2 config = 2 end begin prog = mythtv button = 3 config = 3 end begin prog = mythtv button = 4 config = 4 end begin prog = mythtv button = 5 config = 5 end begin prog = mythtv button = 6 config = 6 end begin prog = mythtv button = 7 config = 7 end begin prog = mythtv button = 8 config = 8 end begin prog = mythtv button = 9 config = 9 end #MythTV - Circle button config begin prog = mythtv button = up config = Up end begin prog = mythtv button = down config = Down end begin prog = mythtv button = right config = Right end begin prog = mythtv button = left config = Left end begin prog = mythtv button = menu config = Enter end #MythTV - Thumb button config begin prog = mythtv button = toggle_up config = Up end begin prog = mythtv button = toggle_down config = Down end begin prog = mythtv button = toggle_left config = Left end begin prog = mythtv button = toggle_right config = Right end begin prog = mythtv button = toggle_enter config = Enter end #MythTV - Page Up button Config begin prog = mythtv button = pg_up config = Esc end #MythTV - Action button config begin prog = mythtv button = play config = Enter end begin prog = mythtv button = pause config = p end begin prog = mythtv button = rec config = r end begin prog = mythtv button = stop config = Esc end begin prog = mythtv button = ff config = Right end begin prog = mythtv button = rew config = Left end begin prog = mythtv button = scan- config = PgUp end begin prog = mythtv button = scan+ config = PgDown end #MythTV - Misc button config begin prog = mythtv button = end_bt config = i end begin prog = mythtv button = find config = o end begin prog = mythtv button = top_bt config = m end begin prog = mythtv button = select config = c end # Xine - Confiuration begin prog = xine button = pg_up config = Quit end begin prog = xine button = play config = Play end begin prog = xine button = stop config = Stop end begin prog = xine button = pause config = Pause end begin prog = xine button = ff config = RIGHT end begin prog = xine button = toggle_up config = EventUp end begin prog = xine button = toggle_down config = EventDown end begin prog = xine button = toggle_right config = EventRight end begin prog = xine button = toggle_left config = EventLeft end begin prog = xine button = toggle_enter config = EventSelect end begin prog = xine button = menu config = Menu end begin prog = xine button = ff config = SeekRelative+30 end begin prog = xine button = rew config = SeekRelative-30 end begin prog = xine button = toggle_right config = SeekRelative+600 end begin prog = xine button = toggle_left config = SeekRelative-600 end begin prog = xine button = scan- config = EventPrior end begin prog = xine button = scan+ config = EventNext end Here's an lircd.conf file: Code: # Please make this file available to others # by sending it to <lirc@bartelmus.de> # # this config file was automatically generated # using lirc-0.7.0-CVS(atiusb) on Fri May 28 22:10:23 2004 # # contributed by # # brand: lircd.conf # model no. of remote control: # devices being controlled by this remote: # begin remote name lircd.conf bits 40 eps 30 aeps 100 one 0 0 zero 0 0 gap 139898 toggle_bit 0 begin codes power 0x0000001457028000 up 0x00000014600B8000 down 0x00000014610C8000 left 0x000000145D088000 right 0x000000145E098000 menu 0x000000145F0A8000 1 0x00000014620D8000 2 0x00000014630E8000 3 0x00000014640F8000 4 0x0000001465108000 5 0x0000001466118000 6 0x0000001467128000 7 0x0000001468138000 8 0x0000001469148000 9 0x000000146A158000 0 0x000000146C178000 a_d 0x000000146B168000 a_b 0x000000146D188000 album 0x000000146E198000 artist 0x00000014701B8000 genre 0x0000001476218000 track 0x0000001478238000 pg_up 0x00000014711C8000 pg_down 0x0000001475208000 toggle_up 0x000000146F1A8000 toggle_down 0x0000001477228000 toggle_left 0x00000014721D8000 toggle_right 0x00000014741F8000 toggle_enter 0x00000014731E8000 Playlist 0x0000001456018000 playing 0x00000014822D8000 top_bt 0x00000014832E8000 end_bt 0x00000014842F8000 find 0x000000145C078000 select 0x0000001485308000 scan- 0x00000014802B8000 rew 0x0000001479248000 play 0x000000147A258000 ff 0x000000147B268000 scan+ 0x000000147F2A8000 rec 0x000000147C278000 stop 0x000000147D288000 pause 0x000000147E298000 end codes end remote Here's an modified ati remote source: Code: /* * * Copyright (c) 2002 Vladimir Dergachev * * USB ATI Remote support * */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so by * e-mail - mail your message to volodya@mindspring.com * * This driver was derived from usbati_remote and usbkbd drivers by Vojtech Pavlik */ #include <linux/config.h> #if defined(CONFIG_MODVERSIONS) && !defined(__GENKSYMS__) && !defined(__DEPEND__) #define MODVERSIONS #include <linux/modversions.h> #endif #include <linux/kernel.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> /* * Version Information */ #define DRIVER_VERSION "2.1.0" #define DRIVER_AUTHOR "Vladimir Dergachev <volodya@minspring.com>" #define DRIVER_DESC "USB ATI Remote driver" MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); MODULE_LICENSE("GPL"); MODULE_PARM(channel_mask, "i"); MODULE_PARM_DESC(channel_mask, "bitmask that determines which remote control channels to ignore"); int channel_mask=0; /* Get hi and low bytes of a 16-bits int */ #define HI(a) ((unsigned char)((a) >> 8)) #define LO(a) ((unsigned char)((a) & 0xff)) #define SEND_FLAG_IN_PROGRESS 1 #define SEND_FLAG_COMPLETE 2 struct ati_remote { unsigned char data[8]; char name[128]; char input_name[16][160]; unsigned char old[16][2]; unsigned long old_jiffies[16]; struct usb_device *usbdev; struct input_dev dev[16]; struct urb irq, out; wait_queue_head_t wait; int open; int send_flags; }; static char init1[]={ 0x01, 0x00, 0x20, 0x14 }; static char init2[]={ 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; #define KIND_END 0 #define KIND_LITERAL 1 #define KIND_FILTERED 2 #define KIND_LU 3 #define KIND_RU 4 #define KIND_LD 5 #define KIND_RD 6 #define KIND_ACCEL 7 static struct { short kind; unsigned char data1, data2; int type; unsigned int code; int value; } ati_remote_translation_table[]={ {KIND_LITERAL, 0x3d, 0x78, EV_KEY, BTN_LEFT, 1}, /* left ati_remote button */ {KIND_LITERAL, 0x3e, 0x79, EV_KEY, BTN_LEFT, 0}, {KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1}, /* right ati_remote button */ {KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0}, /* ati_remote */ {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ {KIND_ACCEL, 0x37, 0x72, EV_REL, REL_Y, -1}, /* up */ {KIND_ACCEL, 0x38, 0x73, EV_REL, REL_Y, 1}, /* down */ {KIND_LU, 0x39, 0x74, EV_REL, 0, 0}, /* left up */ {KIND_RU, 0x3a, 0x75, EV_REL, 0, 0}, /* right up */ {KIND_LD, 0x3c, 0x77, EV_REL, 0, 0}, /* left down */ {KIND_RD, 0x3b, 0x76, EV_REL, 0, 0}, /* right down */ /* keyboard.. */ {KIND_FILTERED, 0xe2, 0x1d, EV_KEY, KEY_LEFT, 1}, /* key left */ {KIND_FILTERED, 0xe4, 0x1f, EV_KEY, KEY_RIGHT, 1}, /* key right */ {KIND_FILTERED, 0xe7, 0x22, EV_KEY, KEY_DOWN, 1}, /* key down */ {KIND_FILTERED, 0xdf, 0x1a, EV_KEY, KEY_UP, 1}, /* key left */ {KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_ENTER, 1}, /* key enter */ {KIND_FILTERED, 0xd2, 0x0d, EV_KEY, KEY_1, 1}, {KIND_FILTERED, 0xd3, 0x0e, EV_KEY, KEY_2, 1}, {KIND_FILTERED, 0xd4, 0x0f, EV_KEY, KEY_3, 1}, {KIND_FILTERED, 0xd5, 0x10, EV_KEY, KEY_4, 1}, {KIND_FILTERED, 0xd6, 0x11, EV_KEY, KEY_5, 1}, {KIND_FILTERED, 0xd7, 0x12, EV_KEY, KEY_6, 1}, {KIND_FILTERED, 0xd8, 0x13, EV_KEY, KEY_7, 1}, {KIND_FILTERED, 0xd9, 0x14, EV_KEY, KEY_8, 1}, {KIND_FILTERED, 0xda, 0x15, EV_KEY, KEY_9, 1}, {KIND_FILTERED, 0xdc, 0x17, EV_KEY, KEY_0, 1}, {KIND_FILTERED, 0xdd, 0x18, EV_KEY, KEY_C, 1}, /* key A/B */ {KIND_FILTERED, 0xc5, 0x00, EV_KEY, KEY_A, 1}, {KIND_FILTERED, 0xc6, 0x01, EV_KEY, KEY_M, 1}, /* key playlist */ {KIND_FILTERED, 0xde, 0x19, EV_KEY, KEY_G, 1}, /* key album */ {KIND_FILTERED, 0xe0, 0x1b, EV_KEY, KEY_L, 1}, /* key artist */ {KIND_FILTERED, 0xe6, 0x21, EV_KEY, KEY_GRAVE, 1}, /* key genre */ {KIND_FILTERED, 0xe8, 0x23, EV_KEY, KEY_F, 1}, /* key track */ {KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_D, 1}, /* key add/del */ {KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_ESC, 1}, /* key power */ {KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_PROG1, 1}, /* key TV */ {KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_PROG2, 1}, /* key DVD */ {KIND_FILTERED, 0xca, 0x05, EV_KEY, KEY_WWW, 1}, /* key Web */ {KIND_FILTERED, 0xcb, 0x06, EV_KEY, KEY_BOOKMARKS, 1}, /* key "open book" */ {KIND_FILTERED, 0xcc, 0x07, EV_KEY, KEY_O, 1}, /* key find */ {KIND_FILTERED, 0xe1, 0x1c, EV_KEY, KEY_PAGEUP, 1}, /* key "timer" */ {KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_RIGHTBRACE, 1}, /* key vol+ */ {KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_LEFTBRACE, 1}, /* key vol- */ {KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_F9, 1}, /* key mute */ {KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_DOWN, 1}, /* next channel*/ {KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_UP, 1}, /* prev channel */ {KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_R, 1}, /* key record */ {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_P, 1}, /* key play */ {KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_LEFT, 1}, /* key rewind */ {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_RIGHT, 1}, /* key ffwd */ {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_ESC, 1}, /* key stop */ {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_P, 1}, /* key pause */ {KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_Q, 1}, /* key scan- */ {KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_Z, 1}, /* key scan+ */ {KIND_FILTERED, 0xf2, 0x2d, EV_KEY, KEY_I, 1}, /* key playing */ {KIND_FILTERED, 0xf3, 0x2e, EV_KEY, KEY_HOME, 1}, /* key top */ {KIND_FILTERED, 0xf4, 0x2f, EV_KEY, KEY_END, 1}, /* key end */ {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_H, 1}, /* key select */ {KIND_FILTERED, 0xe5, 0x20, EV_KEY, KEY_PAGEDOWN, 1}, /* maximize */ {KIND_END, 0x00, 0x00, EV_MAX+1, 0, 0} /* END */ }; /* * Send a packet of bytes to the device */ static void send_packet(struct ati_remote *ati_remote, u16 cmd, unsigned char* data) { DECLARE_WAITQUEUE(wait, current); int timeout = HZ; /* 1 second */ memcpy(ati_remote->out.transfer_buffer + 1, data, LO(cmd)); ((char*)ati_remote->out.transfer_buffer)[0] = HI(cmd); ati_remote->out.transfer_buffer_length = LO(cmd) + 1; ati_remote->out.dev = ati_remote->usbdev; ati_remote->send_flags=SEND_FLAG_IN_PROGRESS; set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&ati_remote->wait, &wait); if (usb_submit_urb(&ati_remote->out)) { set_current_state(TASK_RUNNING); remove_wait_queue(&ati_remote->wait, &wait); printk("done\n"); return; } while (timeout && (ati_remote->out.status == -EINPROGRESS) && !(ati_remote->send_flags & SEND_FLAG_COMPLETE)){ timeout = schedule_timeout(timeout); rmb(); } set_current_state(TASK_RUNNING); remove_wait_queue(&ati_remote->wait, &wait); usb_unlink_urb(&ati_remote->out); } static void ati_remote_irq(struct urb *urb) { struct ati_remote *ati_remote = urb->context; unsigned char *data = ati_remote->data; struct input_dev *dev = &(ati_remote->dev[0x0f]); int i; int accel; int remote_num=0x0f; if (urb->status) return; if(urb->actual_length==4){ if((data[0]!=0x14)||((data[3] & 0x0f)!=0x00)) printk("** weird key=%02x%02x%02x%02x\n", data[0], data[1], data[2], data[3]); remote_num=(data[3]>>4)&0x0f; dev=&(ati_remote->dev[remote_num]); if(channel_mask & (1<<(remote_num+1)))return; /* ignore signals from this channel */ } else if(urb->actual_length==1){ if((data[0]!=(unsigned char)0xff)&&(data[0]!=0x00)) printk("** weird byte=0x%02x\n", data[0]); } else { printk("length=%d %02x %02x %02x %02x %02x %02x %02x %02x\n", urb->actual_length, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); } accel=1; if((urb->actual_length==4) && (ati_remote->old[remote_num][0]==data[1])&&(ati_remote->old[remote_num][1]==data[2])){ if(ati_remote->old_jiffies[remote_num]+4*HZ<jiffies)accel=8; else if(ati_remote->old_jiffies[remote_num]+3*HZ<jiffies)accel=6; else if(ati_remote->old_jiffies[remote_num]+2*HZ<jiffies)accel=4; else if(ati_remote->old_jiffies[remote_num]+HZ<jiffies)accel=3; else if(ati_remote->old_jiffies[remote_num]+(HZ>>1)<jiffies)accel=2; } if((urb->actual_length==4) && (data[0]==0x14) && ((data[3]&0x0f)==0x00)){ for(i=0;ati_remote_translation_table[i].kind!=KIND_END;i++){ if((((ati_remote_translation_table[i].data1 & 0x0f)==(data[1] & 0x0f))) && ((((ati_remote_translation_table[i].data1>>4)-(data[1]>>4)+remote_num)&0x0f)==0x0f) && (ati_remote_translation_table[i].data2==data[2])){ switch(ati_remote_translation_table[i].kind){ case KIND_LITERAL: input_event(dev, ati_remote_translation_table[i].type, ati_remote_translation_table[i].code, ati_remote_translation_table[i].value); break; case KIND_ACCEL: input_event(dev, ati_remote_translation_table[i].type, ati_remote_translation_table[i].code, ati_remote_translation_table[i].value*accel); break; case KIND_LU: input_report_rel(dev, REL_X, -accel); input_report_rel(dev, REL_Y, -accel); break; case KIND_RU: input_report_rel(dev, REL_X, accel); input_report_rel(dev, REL_Y, -accel); break; case KIND_LD: input_report_rel(dev, REL_X, -accel); input_report_rel(dev, REL_Y, accel); break; case KIND_RD: input_report_rel(dev, REL_X, accel); input_report_rel(dev, REL_Y, accel); break; case KIND_FILTERED: if((ati_remote->old[remote_num][0]==data[1])&&(ati_remote->old[remote_num][1]==data[2])&&((ati_remote->old_jiffies[remote_num]+(HZ>>2))>jiffies)){ return; } input_event(dev, ati_remote_translation_table[i].type, ati_remote_translation_table[i].code, 1); input_event(dev, ati_remote_translation_table[i].type, ati_remote_translation_table[i].code, 0); ati_remote->old_jiffies[remote_num]=jiffies; break; default: printk("kind=%d\n", ati_remote_translation_table[i].kind); } break; } } if(ati_remote_translation_table[i].kind==KIND_END){ printk("** unknown key=%02x%02x\n", data[1], data[2]); } if((ati_remote->old[remote_num][0]!=data[1])||(ati_remote->old[remote_num][1]!=data[2])) ati_remote->old_jiffies[remote_num]=jiffies; ati_remote->old[remote_num][0]=data[1]; ati_remote->old[remote_num][1]=data[2]; } } static int ati_remote_open(struct input_dev *dev) { struct ati_remote *ati_remote = dev->private; /* printk("ati_remote_open %d\n", ati_remote->open); */ if (ati_remote->open++) return 0; ati_remote->irq.dev = ati_remote->usbdev; if (usb_submit_urb(&ati_remote->irq)){ printk(KERN_ERR "ati_remote: error submitting urb\n"); return -EIO; } /* printk("done: ati_remote_open now open=%d\n", ati_remote->open); */ return 0; } static void ati_remote_close(struct input_dev *dev) { struct ati_remote *ati_remote = dev->private; if (!--ati_remote->open) usb_unlink_urb(&ati_remote->irq); } static void ati_remote_usb_out(struct urb *urb) { struct ati_remote *ati_remote = urb->context; if (urb->status) return; ati_remote->send_flags|=SEND_FLAG_COMPLETE; wmb(); if (waitqueue_active(&ati_remote->wait)) wake_up(&ati_remote->wait); } static void *ati_remote_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) { struct usb_interface *iface; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint, *epout; struct ati_remote *ati_remote; int pipe, maxp; char *buf; int i,j; iface = &dev->actconfig->interface[ifnum]; interface = &iface->altsetting[iface->act_altsetting]; if (interface->bNumEndpoints != 2) return NULL; /* use the first endpoint only for now */ endpoint = interface->endpoint + 0; if (!(endpoint->bEndpointAddress & 0x80)) return NULL; if ((endpoint->bmAttributes & 3) != 3) return NULL; epout = interface->endpoint + 1; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); printk("maxp=%d endpoint=0x%02x\n", maxp, endpoint->bEndpointAddress); usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); if (!(ati_remote = kmalloc(sizeof(struct ati_remote)+32, GFP_KERNEL))) return NULL; memset(ati_remote, 0, sizeof(struct ati_remote)+32); ati_remote->usbdev = dev; if (!(buf = kmalloc(63, GFP_KERNEL))) { kfree(ati_remote); return NULL; } if (dev->descriptor.iManufacturer && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) strcat(ati_remote->name, buf); if (dev->descriptor.iProduct && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) sprintf(ati_remote->name, "%s %s", ati_remote->name, buf); if (!strlen(ati_remote->name)) sprintf(ati_remote->name, "USB ATI (X10) remote %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); kfree(buf); for(i=0;i<16;i++){ for(j=0;ati_remote_translation_table[j].kind!=KIND_END;j++) if(ati_remote_translation_table[j].type==EV_KEY) set_bit(ati_remote_translation_table[j].code, ati_remote->dev[i].keybit); clear_bit(BTN_LEFT, ati_remote->dev[i].keybit); clear_bit(BTN_RIGHT, ati_remote->dev[i].keybit); ati_remote->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_REL); ati_remote->dev[i].keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); ati_remote->dev[i].relbit[0] = BIT(REL_X) | BIT(REL_Y); ati_remote->dev[i].keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA); ati_remote->dev[i].relbit[0] |= BIT(REL_WHEEL); ati_remote->dev[i].private = ati_remote; ati_remote->dev[i].open = ati_remote_open; ati_remote->dev[i].close = ati_remote_close; sprintf(ati_remote->input_name[i], "%s remote channel %d", ati_remote->name, i+1); ati_remote->dev[i].name = ati_remote->input_name[i]; ati_remote->dev[i].idbus = BUS_USB; ati_remote->dev[i].idvendor = dev->descriptor.idVendor; ati_remote->dev[i].idproduct = dev->descriptor.idProduct; ati_remote->dev[i].idversion = dev->descriptor.bcdDevice; ati_remote->old[i][0]=0; ati_remote->old[i][1]=0; ati_remote->old_jiffies[i]=jiffies; } init_waitqueue_head(&ati_remote->wait); printk("bInterval=%d\n", endpoint->bInterval); FILL_INT_URB(&ati_remote->irq, dev, pipe, ati_remote->data, maxp > 8 ? 8 : maxp, ati_remote_irq, ati_remote, endpoint->bInterval); FILL_INT_URB(&ati_remote->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress), ati_remote + 1, 32, ati_remote_usb_out, ati_remote, epout->bInterval); printk(KERN_INFO "%s on usb%d:%d.%d\n", ati_remote->name, dev->bus->busnum, dev->devnum, ifnum); for(i=0;i<16;i++){ input_register_device(&(ati_remote->dev[i])); printk(KERN_INFO "\tremote control channel %d corresponds to input%d\n", i+1, ati_remote->dev[i].number); } send_packet(ati_remote, 0x8004, init1); send_packet(ati_remote, 0x8007, init2); return ati_remote; } static void ati_remote_disconnect(struct usb_device *dev, void *ptr) { int i; struct ati_remote *ati_remote = ptr; usb_unlink_urb(&ati_remote->irq); for(i=0;i<16;i++) input_unregister_device(&(ati_remote->dev[i])); kfree(ati_remote); } static struct usb_device_id ati_remote_id_table [] = { { USB_DEVICE(0x0bc7, 0x004) }, { USB_DEVICE(0x0bc7, 0x002) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, ati_remote_id_table); static struct usb_driver ati_remote_driver = { name: "ati_remote", probe: ati_remote_probe, disconnect: ati_remote_disconnect, id_table: ati_remote_id_table, }; static int __init ati_remote_init(void) { usb_register(&ati_remote_driver); info(DRIVER_VERSION ":" DRIVER_DESC); return 0; } static void __exit ati_remote_exit(void) { usb_deregister(&ati_remote_driver); } module_init(ati_remote_init); module_exit(ati_remote_exit); Here's the makefile for the above file: Code: ifeq ($(KDIR),) export KDIR := /usr/src/linux endif ifeq ($(PWD),) export PWD := $(shell pwd) endif ifeq ($(KERNELRELEASE),) .DEFAULT: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(@) else ifeq ($(PATCHLEVEL),6) obj-m := ati_remote26.o endif ifeq ($(PATCHLEVEL),4) obj-m := ati_remote.o TOPDIR := $(KDIR) include $(TOPDIR)/Rules.make endif endif .PHONY: install test remove clean tarball all: modules install: modules echo "Installation rule TODO (is tricky)" test: modules sync insmod $(PWD)/ati_remote26.ko || insmod $(PWD)/ati_remote.o remove: sync rmmod ati_remote26 || rmmod ati_remote clean: rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.bck $(PWD)/*.bak $(PWD)/core rm -f $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/.*.flags tarball: (cd $(PWD)/.. ; tar cvf - ati_remote/ati_remote.c ati_remote/ati_remote26.c ati_remote/Makefile ati_remote/README ati_remote/README_LIRC ati_remote/README.Makefile | gzip - ) > $(PWD)/ati_remote.tgz Above is two ways to do it, one with lirc and one with modified ati remote driver. have fun guys;) Chris |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |