Linux USB Joystick游戏杆驱动

  1. <pre class="cpp" name="code">//驱动代码(中断传输)</pre><pre class="cpp" name="code">#include <linux/kernel.h>     
  2. #include <linux/errno.h>     
  3. #include <linux/init.h>     
  4. #include <linux/slab.h>     
  5. #include <linux/module.h>     
  6. #include <linux/kref.h>     
  7. #include <linux/uaccess.h>     
  8. #include <linux/usb.h>     
  9. #include <linux/mutex.h>     
  10. // Define these values to match your devices     
  11. //joystick: VENDOR_ID 0x0E8F, PRODUCT_ID 0X0002     
  12. //icbc: VENDOR_ID 0x096E, PRODUCT_ID 0X0010     
  13. #define USB_JOYSTICK_VENDOR_ID  0x10c4     
  14. #define USB_JOYSTICK_PRODUCT_ID 0x0000     
  15. /* table of devices that work with this driver */    
  16. static struct usb_device_id joystick_table[] = {    
  17.     { USB_DEVICE(USB_JOYSTICK_VENDOR_ID, USB_JOYSTICK_PRODUCT_ID) },    
  18.     { }                 /* Terminating entry */    
  19. };    
  20. MODULE_DEVICE_TABLE(usb, joystick_table);    
  21. //masks for each key, see file KEY_MASK for more details     
  22. #define KEYMASK_UP      0x00     
  23. #define KEYMASK_DOWN    0xFF     
  24. #define KEYMASK_LEFT    0x00     
  25. #define KEYMASK_RIGHT   0xFF     
  26. #define KEYMASK_L1      0x01     
  27. #define KEYMASK_L2      0x04     
  28. #define KEYMASK_R1      0x02     
  29. #define KEYMASK_R2      0x08     
  30. #define KEYMASK_Y       0x1F     
  31. #define KEYMASK_A       0x4F     
  32. #define KEYMASK_X       0x8F     
  33. #define KEYMASK_B       0x2F     
  34. #define KEYMASK_SELECT  0x10     
  35. #define KEYMASK_START   0x20     
  36. #define INTERV_MILLI(ms)    (ms*HZ/1000)     
  37. static struct fasync_struct *fasync_queue;    
  38. static char *gb_data;    
  39. // Get a minor range for your devices from the usb maintainer     
  40. #define USB_JOYSTICK_MINOR_BASE 192     
  41. // Structure to hold all of our device specific stuff     
  42. struct usb_joystick {    
  43.     struct usb_device       *udev;          /* the usb device for this device */    
  44.     struct usb_interface    *interface;     /* the interface for this device */    
  45.     struct semaphore        limit_sem;      /* limiting the number of writes in progress */    
  46.     struct urb              *in_urb;        /* the urb to read data with */    
  47.     unsigned char           *in_buffer; /* the buffer to receive data */    
  48.     size_t                  in_buffer_size;     /* the size of the receive buffer */    
  49.     char                    *data;    
  50.     dma_addr_t              data_dma;    
  51.     __u8                    in_endpointAddr;    /* the address of the bulk in endpoint */    
  52.     __u8                    out_endpointAddr;   /* the address of the bulk out endpoint */    
  53.     struct kref             kref;    
  54. };    
  55. static int joystick_fasync(int fd, struct file *file, int on);    
  56. static int joystick_open(struct inode *inode, struct file *file)    
  57. {    
  58.     printk("joystick open.\n");    
  59.     return 0;    
  60. }    
  61. static int joystick_release(struct inode *inode, struct file *file)    
  62. {    
  63.     printk("joystick release.\n");    
  64.     joystick_fasync(-1, file, 0);    
  65.     return 0;    
  66. }    
  67. static ssize_t joystick_read(struct file *file, char *buf, size_t count, loff_t *ppos)    
  68. {    
  69.     printk("joystick read.\n");     
  70.     copy_to_user(buf, gb_data, 8);    
  71.     return 0;    
  72. }    
  73. static ssize_t joystick_write(struct file *file, const char *buf, size_t count, loff_t *ppos)    
  74. {    
  75.     printk("joystick write.\n");    
  76.     return 0;    
  77. }    
  78. static int joystick_fasync(int fd, struct file *file, int on)    
  79. {    
  80.     int retval;    
  81.     printk("joystick fasynchronize.\n");    
  82.     retval = fasync_helper(fd, file, on, &fasync_queue);    
  83.     return retval;    
  84. }    
  85. static const struct file_operations joystick_fops = {    
  86.     .owner      =       THIS_MODULE,    
  87.     .open       =       joystick_open,    
  88.     .release    =       joystick_release,    
  89.     .read       =       joystick_read,    
  90.     .write      =       joystick_write,    
  91.     .fasync     =       joystick_fasync,    
  92. };    
  93. static void joystick_irq(struct urb *urb)    
  94. {    
  95.     struct usb_joystick *js_dev = urb->context;    
  96.     char *data;    
  97.     static unsigned long jiff_UP = 0;    
  98.     static unsigned long jiff_DOWN = 0;    
  99.     static unsigned long jiff_LEFT = 0;    
  100.     static unsigned long jiff_RIGHT = 0;    
  101.     static unsigned long jiff_Y = 0;    
  102.     static unsigned long jiff_A = 0;    
  103.     static unsigned long jiff_X = 0;    
  104.     static unsigned long jiff_B = 0;    
  105.     static unsigned long jiff_L1 = 0;    
  106.     static unsigned long jiff_L2 = 0;    
  107.     static unsigned long jiff_R1 = 0;    
  108.     static unsigned long jiff_R2 = 0;    
  109.     static unsigned long jiff_SELECT = 0;    
  110.     static unsigned long jiff_START = 0;    
  111.     static int cnt=0;  
  112.     int retval,status;  
  113.     status=urb->status;  
  114.     cnt++;  
  115.     if(cnt==1000)  
  116.     {  
  117.         cnt=0;  
  118.         printk("urb->status=%d\n",status);  
  119.     }  
  120.     switch(status)    
  121.     {    
  122.     case 0:    
  123.         printk("success,get data...\n");  
  124.         data = js_dev->data;    
  125.         if((data[0] != (char)0x7F) || (data[1] != (char)0x7F) || (data[2] != (char)0x7F) || (data[3] != (char)0x7F) ||     
  126.            (data[4] != (char)0xFF) || (data[5] != (char)0x0F) || (data[6] != (char)0x00) || (data[7] != (char)0x00))    
  127.         {    
  128.               
  129.             printk("%02X %02X %02X %02X %02X %02X %02X %02X\n",    
  130.                             (char)data[0], (char)data[1], (char)data[2], (char)data[3],   
  131.                             (char)data[4], (char)data[5], (char)data[6], (char)data[7]);   
  132.                                 
  133.             //direction keys     
  134.             switch(data[2])    
  135.             {    
  136.             case KEYMASK_LEFT:    
  137.                 if(jiffies > (jiff_LEFT + INTERV_MILLI(200)))    
  138.                 {    
  139.                     jiff_LEFT = jiffies;    
  140.                     printk("LEFT pressed.\n");     
  141.                     goto signal_app;    
  142.                 }    
  143.                 break;    
  144.             case KEYMASK_RIGHT:    
  145.                 if(jiffies > (jiff_RIGHT + INTERV_MILLI(200)))    
  146.                 {    
  147.                     jiff_RIGHT = jiffies;    
  148.                     printk("RIGHT pressed.\n");     
  149.                     goto signal_app;    
  150.                 }    
  151.                 break;    
  152.             }    
  153.             switch(data[3])    
  154.             {    
  155.             case KEYMASK_UP:    
  156.                 if(jiffies > (jiff_UP + INTERV_MILLI(200)))    
  157.                 {    
  158.                     jiff_UP = jiffies;    
  159.                     printk("UP pressed.\n");     
  160.                     goto signal_app;    
  161.                 }    
  162.                 break;    
  163.             case KEYMASK_DOWN:    
  164.                 if(jiffies > (jiff_DOWN + INTERV_MILLI(200)))    
  165.                 {    
  166.                     jiff_DOWN = jiffies;    
  167.                     printk("DOWN pressed.\n");     
  168.                     goto signal_app;    
  169.                 }    
  170.                 break;    
  171.             }    
  172.             //general function keys     
  173.             switch(data[5])    
  174.             {    
  175.             case KEYMASK_Y:    
  176.                 if(jiffies > (jiff_Y + INTERV_MILLI(200)))    
  177.                 {    
  178.                     jiff_Y = jiffies;    
  179.                     printk("Y pressed.\n");     
  180.                     goto signal_app;    
  181.                 }    
  182.                 break;    
  183.             case KEYMASK_A:    
  184.                 if(jiffies > (jiff_A + INTERV_MILLI(200)))    
  185.                 {    
  186.                     jiff_A = jiffies;    
  187.                     printk("A pressed.\n");     
  188.                     goto signal_app;    
  189.                 }    
  190.                 break;    
  191.             case KEYMASK_X:    
  192.                 if(jiffies > (jiff_X + INTERV_MILLI(200)))    
  193.                 {    
  194.                     jiff_X = jiffies;    
  195.                     printk("X pressed.\n");     
  196.                     goto signal_app;    
  197.                 }    
  198.                 break;    
  199.             case KEYMASK_B:    
  200.                 if(jiffies > (jiff_B + INTERV_MILLI(200)))    
  201.                 {    
  202.                     jiff_B = jiffies;    
  203.                     printk("B pressed.\n");     
  204.                     goto signal_app;    
  205.                 }    
  206.                 break;    
  207.             }    
  208.             //advanced function keys     
  209.             switch(data[6])    
  210.             {    
  211.             case KEYMASK_L1:    
  212.                 if(jiffies > (jiff_L1 + INTERV_MILLI(200)))    
  213.                 {    
  214.                     jiff_L1 = jiffies;    
  215.                     printk("L1 pressed.\n");     
  216.                     goto signal_app;    
  217.                 }    
  218.                 break;    
  219.             case KEYMASK_L2:    
  220.                 if(jiffies > (jiff_L2 + INTERV_MILLI(200)))    
  221.                 {    
  222.                     jiff_L2 = jiffies;    
  223.                     printk("L2 pressed.\n");     
  224.                     goto signal_app;    
  225.                 }    
  226.                 break;    
  227.             case KEYMASK_R1:    
  228.                 if(jiffies > (jiff_R1 + INTERV_MILLI(200)))    
  229.                 {    
  230.                     jiff_R1 = jiffies;    
  231.                     printk("R1 pressed.\n");     
  232.                     goto signal_app;    
  233.                 }    
  234.                 break;    
  235.             case KEYMASK_R2:    
  236.                 if(jiffies > (jiff_R2 + INTERV_MILLI(200)))    
  237.                 {    
  238.                     jiff_R2 = jiffies;    
  239.                     printk("R2 pressed.\n");     
  240.                     goto signal_app;    
  241.                 }    
  242.                 break;    
  243.             case KEYMASK_SELECT:    
  244.                 if(jiffies > (jiff_SELECT + INTERV_MILLI(200)))    
  245.                 {    
  246.                     jiff_SELECT = jiffies;    
  247.                     printk("SELECT pressed.\n");     
  248.                     goto signal_app;    
  249.                 }    
  250.                 break;    
  251.             case KEYMASK_START:    
  252.                 if(jiffies > (jiff_START + INTERV_MILLI(200)))    
  253.                 {    
  254.                     jiff_START = jiffies;    
  255.                     printk("START pressed.\n");     
  256.                     goto signal_app;    
  257.                 }    
  258.                 break;    
  259.             }    
  260.         }    
  261.         break;    
  262.     default:    
  263.         break;    
  264.     }    
  265.     goto submit_urb;    
  266. signal_app:    
  267.     //notify our application that at least one key was pressed     
  268.     if(fasync_queue)   
  269.     {   
  270.         kill_fasync(&fasync_queue, SIGIO, POLL_IN);   
  271.         printk("notify our application that at least one key was pressed.\n");  
  272.     }   
  273. submit_urb:    
  274.     retval=usb_submit_urb(urb, GFP_ATOMIC);   
  275.     if(retval)  
  276.         printk("usb_submit_urb error.\n");  
  277. }    
  278. /*  
  279.  * usb class driver info in order to get a minor number from the usb core,  
  280.  * and to have the device registered with the driver core  
  281.  */    
  282. static struct usb_class_driver joystick_class = {    
  283.     .name =     "joystick%d",    
  284.     .fops =     &joystick_fops,    
  285.     .minor_base =   USB_JOYSTICK_MINOR_BASE,    
  286. };    
  287. static int joystick_probe(struct usb_interface *interface,    
  288.               const struct usb_device_id *id)    
  289. {    
  290.     struct usb_device *dev = interface_to_usbdev(interface);    
  291.     struct usb_joystick *js_dev = NULL;    
  292.     struct usb_host_interface *iface_desc;    
  293.     struct usb_endpoint_descriptor *endpoint;    
  294.     size_t maxp;    
  295.     int pipe;    
  296.     int retval = -ENOMEM;    
  297.     printk("*************** Probe for joystick. ****************\n");    
  298.     //dev->udev = usb_get_dev(interface_to_usbdev(interface));     
  299.     //dev->interface = interface;     
  300.     iface_desc = interface->cur_altsetting;    
  301.     printk("numEndpoints=%d\n",iface_desc->desc.bNumEndpoints);  
  302.     if(iface_desc->desc.bNumEndpoints < 1)    
  303.        {  
  304.      printk("Finding interface...");    
  305.      return -ENODEV;   
  306.     }   
  307.     endpoint = &iface_desc->endpoint[0].desc;    
  308.     if(!endpoint)    
  309.     {  
  310.      printk("No endpoint");    
  311.         return -ENODEV;  
  312.     }    
  313.     printk("direction(%02X): ", endpoint->bEndpointAddress);    
  314.     if(endpoint->bEndpointAddress & USB_DIR_IN)    
  315.         printk("to host\n");    
  316.     else    
  317.         printk("to device\n");    
  318.     printk("Endpoint type: ");    
  319.     switch(endpoint->bmAttributes)    
  320.     {    
  321.         case 0:    
  322.             printk("control\n");    
  323.             break;    
  324.         case 1:    
  325.             printk("ISOC\n");    
  326.             break;    
  327.         case 2:    
  328.             printk("bulk\n");    
  329.             break;    
  330.         case 3:    
  331.             printk("intterupt\n");    
  332.             break;    
  333.         default:    
  334.             printk("Unkown.\n");    
  335.     }    
  336.     printk("MaxPacketSize: %d\n", endpoint->wMaxPacketSize);    
  337.     //obtain usb_device pointor from usb_interface     
  338.     dev = interface_to_usbdev(interface);    
  339.     pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);    
  340.     maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));    
  341.     printk("pipe: %08X, maxp: %08X\n", pipe, maxp);    
  342.     printk("sizeof(struct usb_joystick)=%d\n",sizeof(struct usb_joystick));  
  343.     js_dev = kzalloc(sizeof(struct usb_joystick), GFP_KERNEL);  
  344.     printk("Oh Yeah!\n");    
  345.     if(!js_dev)    
  346.         goto fail0;    
  347.     kref_init(&js_dev->kref);    
  348.     js_dev->data = usb_alloc_coherent(dev, 64, GFP_ATOMIC, &js_dev->data_dma);    
  349.     if(!js_dev->data)    
  350.         goto fail1;    
  351.     gb_data = js_dev->data;    
  352.     js_dev->in_urb = usb_alloc_urb(0, GFP_KERNEL);    
  353.     if(!js_dev->in_urb)    
  354.         goto fail2;    
  355.     usb_fill_int_urb(js_dev->in_urb, dev, pipe, js_dev->data, (maxp > 8 ? 8 : maxp), joystick_irq, js_dev, endpoint->bInterval);    
  356.     js_dev->in_urb->transfer_dma = js_dev->data_dma;    
  357.     js_dev->in_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;    
  358.     js_dev->udev = usb_get_dev(dev);    
  359.     js_dev->interface = interface;    
  360.     usb_set_intfdata(interface, js_dev);    
  361.     retval = usb_register_dev(interface, &joystick_class);    
  362.     if(retval)    
  363.     {    
  364.         //something prevented us from registering this driver     
  365.         err("Not able to get a minor for this driver.");    
  366.         usb_set_intfdata(interface, NULL);    
  367.         goto fail3;    
  368.     }    
  369.     usb_submit_urb(js_dev->in_urb, GFP_ATOMIC);    
  370.     dev_info(&interface->dev, "USB JoyStick now attaches to minor %d\n", interface->minor);    
  371.     printk("*************** End of probe ****************\n");    
  372.     return 0;    
  373. fail3:    
  374.     printk("fail3.\n");    
  375.     usb_free_urb(js_dev->in_urb);    
  376. fail2:    
  377.     printk("fail2.\n");    
  378.     usb_free_coherent(dev, 8, js_dev->data, js_dev->data_dma);    
  379. fail1:    
  380.     printk("fail1.\n");    
  381.     kfree(js_dev);    
  382. fail0:    
  383.     printk("fail0.\n");    
  384.     return -ENODEV;    
  385. }    
  386. static void joystick_disconnect(struct usb_interface *interface)    
  387. {    
  388.     struct usb_joystick *js_dev;    
  389.     int minor = interface->minor;    
  390.     js_dev = usb_get_intfdata(interface);    
  391.         
  392.     usb_set_intfdata(interface, NULL);    
  393.     if(js_dev)    
  394.     {    
  395.         usb_kill_urb(js_dev->in_urb);    
  396.         //give back out minor     
  397.         usb_deregister_dev(interface, &joystick_class);    
  398.     }    
  399.     dev_info(&interface->dev, "USB minor#%d now disconnected", minor);    
  400. }    
  401. static struct usb_driver joystick_driver = {    
  402.     .name =         "joystick",    
  403.     .probe =        joystick_probe,    
  404.     .disconnect =   joystick_disconnect,    
  405.     .id_table =     joystick_table,    
  406. };    
  407. //init USB skeleton module     
  408. static int __init usb_joystick_init(void)    
  409. {    
  410.     int result;    
  411.     /* register this driver with the USB subsystem */    
  412.     result = usb_register(&joystick_driver);    
  413.     if (result)    
  414.         printk("usb_register failed. Error number %d", result);    
  415.     printk("************** joystick driver initialized. ****************\n");    
  416.     return result;    
  417. }    
  418. //unload USB skeleton module     
  419. static void __exit usb_joystick_exit(void)    
  420. {    
  421.     /* deregister this driver with the USB subsystem */    
  422.     usb_deregister(&joystick_driver);    
  423.     printk("**************** joystick driver unloaded. ****************\n");    
  424. }    
  425. module_init(usb_joystick_init);    
  426. module_exit(usb_joystick_exit);    
  427. MODULE_LICENSE("GPL");    
  428. MODULE_AUTHOR("Cricket Long");  </pre><br>  
  429. <pre></pre>  
  430. <p>测试代码:</p>  
  431. <pre class="cpp" name="code">#include <stdio.h>    
  432. #include <stdlib.h>    
  433. #include <unistd.h>    
  434. #include <fcntl.h>    
  435. #include <signal.h>    
  436. #include <sys/ioctl.h>    
  437. void interrupt_handler(int num);    
  438. int fd;    
  439. int main(int argc, char **argv)    
  440. {    
  441.      char buf[2];    
  442.      int oflags;    
  443.      fd = open("/dev/joystick0", O_RDWR);    
  444.      if(fd != -1)    
  445.      {    
  446.          printf("fd: %d/n", fd);    
  447.          signal(SIGIO, interrupt_handler);    
  448.          fcntl(fd, F_SETOWN, getpid());    
  449.          oflags = fcntl(fd, F_GETFL);    
  450.          fcntl(fd, F_SETFL, oflags | FASYNC);    
  451.          while(1){};    
  452.      }    
  453.      else    
  454.          printf("Could not open device!\n");    
  455.      return 0;    
  456. }    
  457. void interrupt_handler(int num)    
  458. {    
  459.      char data[8];    
  460.      read(fd, data, 8);    
  461.      printf("%02X %02X %02X %02X %02X %02X %02X %02X/n", (char)data[0], (char)data[1], (char)data[2], (char)data[3],    
  462.                                                         (char)data[4], (char)data[5], (char)data[6], (char)data[7]);    
  463. }  </pre>  
  464. <p><br>  
  465.  </p>  
  466. <pre></pre> 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值