#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");
标签:USB,urb,struct,usbKey,KEY,Linux,usb,input,2.4 From: https://www.cnblogs.com/linux-learn/p/17247992.html