View unanswered posts    View active topics

All times are UTC - 6 hours





Post new topic Reply to topic  [ 23 posts ] 
Go to page 1, 2  Next

Print view Previous topic   Next topic  

Is the remote layout good?
Yes 75%  75%  [ 3 ]
No <- if you choose this you better damn well give me some good suggestions;) 25%  25%  [ 1 ]
Total votes : 4

Author Message
Search for:
 Post subject: Edited ati_remote source
PostPosted: Tue Feb 10, 2004 1:29 am 
Offline
Joined: Fri Nov 14, 2003 4:02 pm
Posts: 68
Location: Edmonton, Alberta, Canada
well, I got started on the ati_remote source and decided on this preliminary configuration:

http://members.shaw.ca/quilley/atiremote23.jpg

Suggestions welcome.

I'm having a bit of trouble getting the brackets, the question mark and the bar to compile in the source though. this is the error I get:
ati_remote.c:154: `KEY_BRACKETLEFT' undeclared here (not in a function)
ati_remote.c:154: initializer element is not constant
ati_remote.c:154: (near initialization for `ati_remote_translation_table[42].code')
ati_remote.c:155: `KEY_BRACKETRIGHT' undeclared here (not in a function)
ati_remote.c:155: initializer element is not constant
ati_remote.c:155: (near initialization for `ati_remote_translation_table[43].code')
ati_remote.c:156: `KEY_bar' undeclared here (not in a function)
ati_remote.c:156: initializer element is not constant
ati_remote.c:156: (near initialization for `ati_remote_translation_table[44].code')
ati_remote.c:158: `KEY_QUESTION' undeclared here (not in a function)
ati_remote.c:158: initializer element is not constant
ati_remote.c:158: (near initialization for `ati_remote_translation_table[46].code')
make[2]: *** [ati_remote.o] Error 1
make[2]: Leaving directory `/home/chris/ati_remote'
make[1]: *** [_mod_/home/chris/ati_remote] Error 2
make[1]: Leaving directory `/usr/src/kernel-source-2.4.21-xfs'
make: *** [modules] Error 2


I'm not sure exactly what to do because xev gives the following labels for the perspective keys:

[ bracketleft
] bracketright
? question
| bar

so they should just work in the code but they don't. I'd really appreciate some help with this problem.

Thanks,

Chris


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 10, 2004 6:15 pm 
Offline
Joined: Fri Nov 14, 2003 4:02 pm
Posts: 68
Location: Edmonton, Alberta, Canada
here's the relevant code:
{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_ENTER, 1}, // key checkbox (return to previous)

{KIND_FILTERED, 0xc5, 0x00, EV_KEY, KEY_A, 1}, /* A */
{KIND_FILTERED, 0xc6, 0x01, EV_KEY, KEY_B, 1}, /* B */
{KIND_FILTERED, 0xde, 0x19, EV_KEY, KEY_HOME, 1}, /* C */
{KIND_FILTERED, 0xe0, 0x1b, EV_KEY, KEY_ENTER, 1}, /* D */
{KIND_FILTERED, 0xe6, 0x21, EV_KEY, KEY_E, 1}, /* E */
{KIND_FILTERED, 0xe8, 0x23, EV_KEY, KEY_Z, 1}, /* F */

{KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_M, 1}, /* key menu */
{KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_POWER, 1}, /* key power */
{KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_C, 1}, /* key TV */
{KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_T, 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_EDIT, 1}, /* key "hand" */
{KIND_FILTERED, 0xe1, 0x1c, EV_KEY, KEY_I, 1}, /* key "timer" */

{KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_BRACKETLEFT, 1}, /* volu up */
{KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_BRACKETRIGHT, 1}, /* vol down */
{KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_bar, 1}, /* mute */
{KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_SLASH, 1}, // next channel
{KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_QUESTION, 1}, // prev channel

{KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_SPACE, 1}, // key record
{KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_ENTER, 1}, // key playcd
{KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_PAGEUP, 1}, // key rewind
{KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_PAGEDOWN, 1}, // key fast-forward
{KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_ESC, 1}, // key stop
{KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_P, 1}, // key pause

{KIND_FILTERED, 0xe5, 0x20, EV_KEY, KEY_FRONT, 1}, /* maximize */

{KIND_END, 0x00, 0x00, EV_MAX+1, 0, 0} /* END */
};


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 10, 2004 6:52 pm 
Offline
Site Admin
Joined: Fri Oct 31, 2003 11:40 pm
Posts: 357
Location: Irvine, Ca
Best that I can determine from looking at /usr/include/input.h at about line 125 is that the key names might be KEY_LEFTBRACE and KEY_RIGHTBRACE. Check that out. :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 10, 2004 8:51 pm 
Offline
Joined: Fri Nov 14, 2003 4:02 pm
Posts: 68
Location: Edmonton, Alberta, Canada
Well, KEY_RIGHTBRACE and KEY_LEFTBRACE appear to be working. Now I just need to find out what "?" and "|" should be bound as and we have ourselves a nice remote setup. Anyone have any ideas?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 11, 2004 7:22 pm 
Offline
Joined: Fri Nov 14, 2003 4:02 pm
Posts: 68
Location: Edmonton, Alberta, Canada
here's the ati_remote.c code in its entirety:

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_ENTER, 1},  // key checkbox (return to previous)
       
   {KIND_FILTERED, 0xc5, 0x00, EV_KEY, KEY_A, 1},   /* A */
   {KIND_FILTERED, 0xc6, 0x01, EV_KEY, KEY_B, 1},   /* B */
   {KIND_FILTERED, 0xde, 0x19, EV_KEY, KEY_HOME, 1},   /* C */
   {KIND_FILTERED, 0xe0, 0x1b, EV_KEY, KEY_ENTER, 1},   /* D */
   {KIND_FILTERED, 0xe6, 0x21, EV_KEY, KEY_E, 1},   /* E */
   {KIND_FILTERED, 0xe8, 0x23, EV_KEY, KEY_Z, 1},   /* F */

   {KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_M, 1},   /* key menu */
   {KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_POWER, 1},   /* key power */
   {KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_C, 1},   /* key TV */
   {KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_T, 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_EDIT, 1},   /* key "hand" */
   {KIND_FILTERED, 0xe1, 0x1c, EV_KEY, KEY_I, 1},   /* key "timer" */
   
   {KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_LEFTBRACE, 1},  /* volu up */
   {KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_RIGHTBRACE, 1},   /* vol down */
   {KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_COMMA, 1},   /* mute */
   {KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_SLASH, 1},      // next channel
   {KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_F3, 1},    // prev channel
   
   {KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_SPACE, 1},     // key record
   {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_ENTER, 1},    // key playcd
   {KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_PAGEUP, 1},      // key rewind
   {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_PAGEDOWN, 1},     // key fast-forward
   {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_ESC, 1},       // key stop
   {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_P, 1},         // key pause

   {KIND_FILTERED, 0xe5, 0x20, EV_KEY, KEY_FRONT, 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) },
    { }                  /* 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);



Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 11, 2004 7:23 pm 
Offline
Joined: Fri Nov 14, 2003 4:02 pm
Posts: 68
Location: Edmonton, Alberta, Canada
and here's the relevant section of the code that I made slight changes to:
Code:
      /* 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_ENTER, 1},  // key checkbox (return to previous)
       
   {KIND_FILTERED, 0xc5, 0x00, EV_KEY, KEY_A, 1},   /* A */
   {KIND_FILTERED, 0xc6, 0x01, EV_KEY, KEY_B, 1},   /* B */
   {KIND_FILTERED, 0xde, 0x19, EV_KEY, KEY_HOME, 1},   /* C */
   {KIND_FILTERED, 0xe0, 0x1b, EV_KEY, KEY_ENTER, 1},   /* D */
   {KIND_FILTERED, 0xe6, 0x21, EV_KEY, KEY_E, 1},   /* E */
   {KIND_FILTERED, 0xe8, 0x23, EV_KEY, KEY_Z, 1},   /* F */

   {KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_M, 1},   /* key menu */
   {KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_POWER, 1},   /* key power */
   {KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_C, 1},   /* key TV */
   {KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_T, 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_EDIT, 1},   /* key "hand" */
   {KIND_FILTERED, 0xe1, 0x1c, EV_KEY, KEY_I, 1},   /* key "timer" */
   
   {KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_LEFTBRACE, 1},  /* volu up */
   {KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_RIGHTBRACE, 1},   /* vol down */
   {KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_COMMA, 1},   /* mute */
   {KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_SLASH, 1},      // next channel
   {KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_F3, 1},    // prev channel
   
   {KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_SPACE, 1},     // key record
   {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_ENTER, 1},    // key playcd
   {KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_PAGEUP, 1},      // key rewind
   {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_PAGEDOWN, 1},     // key fast-forward
   {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_ESC, 1},       // key stop
   {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_P, 1},         // key pause

   {KIND_FILTERED, 0xe5, 0x20, EV_KEY, KEY_FRONT, 1},   /* maximize */
   
   {KIND_END, 0x00, 0x00, EV_MAX+1, 0, 0} /* END */
   };


I need to figure out what to put in for the ? and | keys

Thanks,

Chris


Top
 Profile  
 
 Post subject: Just some ideas....
PostPosted: Wed Feb 11, 2004 11:41 pm 
Offline
Joined: Mon Jan 05, 2004 1:30 pm
Posts: 139
Location: New Hope, MN
Key possible keywords
? QUESTION QUESTIONMARK
| BAR PIPE VERTICALBAR


However best bet would be to see if the program author has a table of key to keywords availble to work from.

-Rusty


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 12, 2004 12:15 am 
Offline
Joined: Fri Nov 14, 2003 4:02 pm
Posts: 68
Location: Edmonton, Alberta, Canada
it's input.h
There just isn't anything obvious in there.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 20, 2004 3:40 pm 
Offline
Joined: Wed Dec 10, 2003 8:31 pm
Posts: 1996
Location: /dev/null
Good work with this man! There has to be a way to add those keys to this thing. Did you post this on the mythusers list? Also, do you think it would be eaiser to do with lirc instead of the native kernel support?

_________________
Retired KM user (R4 - R6.04); friend to LH users.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 21, 2004 1:06 pm 
Offline
Joined: Mon Jan 05, 2004 1:30 pm
Posts: 139
Location: New Hope, MN
With lirc it would be "simpler" to configure what a button does, as you know what scancode the button generates (out of irrecord) and in capturing that scancode you have already 'named' it, so you know what scancode to associate with a key in the .mythtv/lircrc file.

Whether that is a 'better' solution is a completely different question. I like the idea of using the remote as a keyboard instead of through lirc, as you can then use lirc to provide a remote interface for (as an example) the black haupauge! remote that you can give to the kids to let them have very basic remote control capabilities, and keep the ATI remote for higher level controlls. You could use the ATI remote to edit videos, etc. which is much harder to do with the Black remote because of the much smaller selection of buttons to work with.

-Rusty

_________________
Master:
- AMD 1800XP on a MSI KT4V motherboard, via KT400 bios
- 120 G Segate Baracuda /, /cache, /myth, swap
- 200 G Segate Baracuda /myth/tv
- 3 Haupauge! WinTV PVR250s
- 19" Daewoo Monitor (1280x1024 ni)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 13, 2004 11:34 am 
Offline
Joined: Thu Dec 11, 2003 4:46 am
Posts: 11
is this the setup currently in r4v2? if not what is the quick and dirty way to get it set up with these settings?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 13, 2004 8:23 am 
Offline
Joined: Mon Feb 16, 2004 7:06 pm
Posts: 309
Location: Toronto
To get the volume keys to work, i just used the alternate keys F9, F10, F11

here is my remote.c

{KIND_FILTERED, 0x3d, 0x78, EV_KEY, KEY_ENTER, 1}, /* left ati_remote button */
//{KIND_LITERAL, 0x3e, 0x79, EV_KEY, BTN_LEFT, 0},
{KIND_FILTERED, 0x41, 0x7c, EV_KEY, KEY_ESC, 1}, /* right ati_remote button */
//{KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},
/* ati_remote */
{KIND_FILTERED, 0x35, 0x70, EV_KEY, KEY_LEFT, 1}, /* left */
{KIND_FILTERED, 0x36, 0x71, EV_KEY, KEY_RIGHT, 1}, /* right */
{KIND_FILTERED, 0x37, 0x72, EV_KEY, KEY_UP, 1}, /* up */
{KIND_FILTERED, 0x38, 0x73, EV_KEY, KEY_DOWN, 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_D, 1}, /* key "checkbox" */

{KIND_FILTERED, 0xc5, 0x00, EV_KEY, KEY_A, 1},
{KIND_FILTERED, 0xc6, 0x01, EV_KEY, KEY_B, 1},
{KIND_FILTERED, 0xde, 0x19, EV_KEY, KEY_HOME, 1},
{KIND_FILTERED, 0xe0, 0x1b, EV_KEY, KEY_END, 1},
{KIND_FILTERED, 0xe6, 0x21, EV_KEY, KEY_I, 1},
{KIND_FILTERED, 0xe8, 0x23, EV_KEY, KEY_O, 1},

{KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_M, 1}, /* key menu */
{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_Z, 1}, /* key "open book" */
{KIND_FILTERED, 0xcc, 0x07, EV_KEY, KEY_C, 1}, /* key "hand" */
{KIND_FILTERED, 0xe1, 0x1c, EV_KEY, KEY_ESC, 1}, /* key "timer" */

{KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_F10, 1}, //COL DOWN
{KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_F11, 1}, //VOL UP
{KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_F9, 1}, //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}, //RECORD
{KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_P, 1}, /* PLAY */
{KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_UP, 1}, //REWIND
{KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_DOWN, 1}, //FASTFORWARD
{KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_ESC, 1}, //STOP
{KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_P, 1}, //PAUSE

{KIND_FILTERED, 0xe5, 0x20, EV_KEY, KEY_ENTER, 1}, /* maximize */

{KIND_END, 0x00, 0x00, EV_MAX+1, 0, 0} /* END */
};


some things look backwared, but everything works right this way. What i would like to know is if you can get one of the buttons to start a program like mythfrontend for th TV button.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 15, 2004 8:41 pm 
Offline
Joined: Fri Nov 14, 2003 4:02 pm
Posts: 68
Location: Edmonton, Alberta, Canada
I'm fairly certain you can't get it to start a program because it's just a keyboard. Well, you probably could, but you'd have to do some severe mucking about with some other program to watch for a specific key press. If anyone knows a better way please pipe up.

Chris


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 15, 2004 10:55 pm 
Offline
Joined: Fri Nov 14, 2003 4:02 pm
Posts: 68
Location: Edmonton, Alberta, Canada
You could probably hack something together that was really ugly with this:

http://freshmeat.net/projects/hotkeys/

Or one of these:

http://freshmeat.net/search/?q=hotkeys& ... x=0&Go.y=0

I don't have the need for it so I'm not going to do any hacking on this, but if you get something sweet and usefull working then make sure to tell cesman about it so he can include it in r5.

Cheers,

Chris


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 18, 2004 8:16 pm 
Offline
Joined: Mon Feb 16, 2004 7:06 pm
Posts: 309
Location: Toronto
I installed the libxosd2_2.2.7-1_i386.deb and hotkeys_0.5.7.1.1_i386.deb packages to get hotkeys running. After installed i was able to use the remote to trigger some of the hotkeys. The only keys that i could get to trigger hotkeys were TV, DVD and Web. I tried to use different keyboards with the same result, but i didn't try them all. If you try one and get it working please post here.

Here are the relevent lines of the /etc/hotkeys.conf to get the TV button to start mythfrontend and DVD button to start ogle.

PrevTrack=ogle
NextTrack=mythfrontend

This is basically what i wanted but i would still like to have the "B" button start and xterm.


Top
 Profile  
 

Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ] 
Go to page 1, 2  Next



All times are UTC - 6 hours




Who is online

Users browsing this forum: No registered users and 7 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:  
Powered by phpBB® Forum Software © phpBB Group

Theme Created By ceyhansuyu