View unanswered posts    View active topics

All times are UTC - 6 hours





Post new topic Reply to topic  [ 1 post ] 
Print view Previous topic   Next topic  
Author Message
Search for:
PostPosted: Sun Aug 29, 2004 8:59 am 
Offline
Joined: Fri Nov 14, 2003 4:02 pm
Posts: 68
Location: Edmonton, Alberta, Canada
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


Top
 Profile  
 

Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 


All times are UTC - 6 hours




Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group

Theme Created By ceyhansuyu