Linux 2.4G USB遥控板驱动

发布时间 2023-03-23 16:43:36作者: *^VV^*

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/hid.h>
#include <linux/input.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/usb.h>
#include <media/rc-core.h>

static struct rc_map_table usbKey_map[] = {
  { 0x4F, KEY_RIGHT }, { 0x50, KEY_LEFT },
  { 0x51, KEY_DOWN }, { 0x52, KEY_UP },
  { 0x28, KEY_ENTER }, { 0x65, KEY_TAB},
  { 0x29, KEY_ESC }, { 0x2A, KEY_MENU },
  { 0x1E, KEY_1 }, { 0x1F, KEY_2 },
  { 0x20, KEY_3 }, { 0x21, KEY_4 },
  { 0x22, KEY_5 }, { 0x23, KEY_6 },
  { 0x24, KEY_7 }, { 0x25, KEY_8 },
  { 0x26, KEY_9 }, { 0x27, KEY_0 },
  { 0x4E, KEY_PREVIOUS }, { 0x4B, KEY_NEXT },
};

struct usbKey_st
{
  struct input_dev *input;

  size_t buffLenth; //缓存长度
  char *usbKey_vaddr; //虚拟地址
  dma_addr_t usbKey_phyc; //物理地址
  struct urb *usbKey_urb; //usb urb
};
static struct usbKey_st usbKey;

static void usbKey_complete(struct urb *urb)
{
  int ret =0;
  int i=0;

  //判断urb是否正确接收数据
  switch(urb->status)
  {
    case 0:
      break;
    case -ECONNRESET: /* unlink */
    case -ENOENT:
    case -ESHUTDOWN:
      return;
    default: /* error */
      goto resubmit;
  }

  for(i=0 ;i<20 ;i++)
  {
    if(usbKey.usbKey_vaddr[2] == usbKey_map[i].scancode)
    {
      input_report_key(usbKey.input, usbKey_map[i].keycode, 1);
      input_sync(usbKey.input);
      input_report_key(usbKey.input, usbKey_map[i].keycode, 0);
      input_sync(usbKey.input);

      break;
    }
  }

  resubmit:
    ret = usb_submit_urb(urb, GFP_ATOMIC);
    if(ret) printk("usbKey receve error\r\n");
}

static int usbKey_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
  struct usb_device *dev = interface_to_usbdev(intf);
  struct usb_endpoint_descriptor *endpoint;
  struct usb_host_interface *interface;
  int pipe;
  int ret =0,i=0;

  //获取当前接口
  interface=intf->cur_altsetting;

  //当前接口下的端点描述符
  endpoint = &interface->endpoint[0].desc;

  //其中一个中断端点
  if(endpoint->wMaxPacketSize ==8)
  {
    /************************input*****************************/
    //申请input设备
    usbKey.input = input_allocate_device();
    if(usbKey.input ==NULL)
    {
      printk("input_allocate_device error\r\n");
      ret = -ENOMEM;
      goto input_allocate_err;
    }

    //设置input上报事件
    __set_bit(EV_KEY, usbKey.input->evbit); //按键事件
    for(i=0;i<20;i++)
    {
      __set_bit(usbKey_map[i].keycode ,usbKey.input->keybit); //按键值
    }

    //注册input设备
    ret = input_register_device(usbKey.input);
    if(ret)
    {
      printk("input_register_device error\r\n");
      ret = -ENOMEM;
      goto input_register_err;
    }

    /************************USB*****************************/
    //创建一个端点管道
    pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);

    //获取每包最大长度
    usbKey.buffLenth = endpoint->wMaxPacketSize;

    //申请内存
    usbKey.usbKey_vaddr = usb_alloc_coherent(dev, usbKey.buffLenth, GFP_ATOMIC, &usbKey.usbKey_phyc);
    if(usbKey.usbKey_vaddr ==NULL)
    {
      printk("usb_alloc_coherent error\r\n");
      ret = -ENOMEM;
      goto coherent_err;
    }

    //创建usb urb
    usbKey.usbKey_urb = usb_alloc_urb(0, GFP_KERNEL);
    if(usbKey.usbKey_urb ==NULL)
    {
      printk("usb_alloc_urb error\r\n");
      ret = -ENOMEM;
      goto alloc_urb_err;
    }

    //初始化urb
    usb_fill_int_urb(
      usbKey.usbKey_urb,
      dev,
      pipe,
      usbKey.usbKey_vaddr,
      usbKey.buffLenth,
      usbKey_complete,
      0,
      endpoint->bInterval
    );

    //urb DMA 设置
    usbKey.usbKey_urb->transfer_dma = usbKey.usbKey_phyc;
    usbKey.usbKey_urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;

    //urb上报数据
    ret = usb_submit_urb(usbKey.usbKey_urb, GFP_ATOMIC);
    if(ret)
    {
      printk("usb_submit_urb error\r\n");
      ret = -ENOMEM;
      goto submit_urb_err;
    }

    printk("usbKey_probe sucess\r\n");
  }

  //另一个中断端点
  if(endpoint->wMaxPacketSize ==7)
  {
  }

  return 0;

submit_urb_err:
  usb_free_urb(usbKey.usbKey_urb);
alloc_urb_err:
  usb_free_coherent(dev, usbKey.buffLenth, usbKey.usbKey_vaddr, usbKey.usbKey_phyc);
coherent_err:
  input_unregister_device(usbKey.input);
input_register_err:
  input_free_device(usbKey.input);
input_allocate_err:
  return ret;
}

static void usbKey_disconnect(struct usb_interface *intf)
{
  struct usb_device *dev = interface_to_usbdev(intf);
  struct usb_endpoint_descriptor *endpoint;
  struct usb_host_interface *interface;

  //获取当前接口
  interface=intf->cur_altsetting;

  //当前接口下的端点描述符
  endpoint = &interface->endpoint[0].desc;

  //usb卸载
  if(endpoint->wMaxPacketSize ==8)
  {
    /************************USB*****************************/
    usb_kill_urb(usbKey.usbKey_urb);
    usb_free_urb(usbKey.usbKey_urb);
    usb_free_coherent(dev, usbKey.buffLenth, usbKey.usbKey_vaddr, usbKey.usbKey_phyc);

    /************************input*****************************/
    //卸载输入设备
    input_unregister_device(usbKey.input);
    input_free_device(usbKey.input);

    printk("usbKey_disconnect sucess\r\n");
  }

  if(endpoint->wMaxPacketSize ==7)
  {
  }
}

const struct usb_device_id usbKey_id[] =
{
  {USB_DEVICE(0x276d,0x1101)},
  {},
};

static struct usb_driver usbKey_dev =
{
  .name = "usbKey",
  .probe = usbKey_probe,
  .disconnect = usbKey_disconnect,
  .id_table = usbKey_id,
};

static int __init usbKey_init(void)
{
  return usb_register(&usbKey_dev);
}

static void __exit usbKey_exit(void)
{
  usb_deregister(&usbKey_dev);
}

module_init(usbKey_init);
module_exit(usbKey_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("jtb");