JZ2440笔记:USB设备驱动程序

发布于:2024-06-04 ⋅ 阅读:(87) ⋅ 点赞:(0)

(1)vi usbmouseaskey.c

#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>

static struct usb_device_id usbmousekey_id_table [] = {
	{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
		USB_INTERFACE_PROTOCOL_MOUSE) },
	{ }	/* Terminating entry */
};


static int usbmousekey_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	printk("found usbmouse\n");
	return 0;
}

static void usbmousekey_disconnect(struct usb_interface *intf)
{
	printk("disconnect usbmouse\n");
}
}

static struct usb_driver usbmousekey_driver = {
	.name		= "usbmousekey",
	.probe		= usbmousekey_probe,
	.disconnect	= usbmousekey_disconnect,
	.id_table	= usbmousekey_id_table,
};


static int usbmousekey_init(void)
{


	usb_register(&usbmousekey_driver);
	return 0;
}

static void usbmousekey_exit(void)
{
	usb_deregister(&usbmousekey_driver);
}


module_init(usbmousekey_init);
module_exit(usbmousekey_exit);
MODULE_LICENSE("GPL");

测试驱动:

使用去掉自带的USB驱动的uImage

# insmod usbmouseaskey.ko
input: Unspecified device as /class/input/input1

插入USB鼠标
# usb 1-1: new low speed USB device using s3c2410-ohci and address 2
usb 1-1: configuration #1 chosen from 1 choice
取出USB鼠标
usb 1-1: USB disconnect, address 2

(2)vi usbmouseaskey.c(读取设备描述符信息)

static int usbmousekey_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	printk("found usbmouse\n");
	printk("bcdUSB = %x,\n",dev->descriptor.bcdUSB);
	printk("VID    = %x,\n",dev->descriptor.idVendor);
	printk("PID    = %x,\n",dev->descriptor.idProduct);
	return 0;
}

测试驱动:

使用去掉自带的USB驱动的uImage

# insmod usbmouseaskey.ko
usbcore: registered new interface driver usbmousekey
# usb 1-1: new low speed USB device using s3c2410-ohci and address 5
usb 1-1: configuration #1 chosen from 1 choice
found usbmouse
bcdUSB = 200,
VID    = 17ef,
PID    = 6050,
usb 1-1: USB disconnect, address 5
disconnect usbmouse

(3)vi usbmouseaskey.c(增加输入子系统)

static struct input_dev *uk_dev;
static char *usb_buf;
static dma_addr_t usb_buf_phys;
static int len;
static struct urb *uk_urb;

static struct usb_device_id usbmousekey_id_table [] = {
	{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
		USB_INTERFACE_PROTOCOL_MOUSE) },
	{ }	/* Terminating entry */
};

static void usbmouseaskey_irq(struct urb *urb)
{
	int i;
	static int cnt = 0;
	printk("data cnt %d: ", ++cnt);
	for (i=0;i<len;i++)
		printk("%02x",usb_buf[i]);
	printk("\n");
	usb_submit_urb (uk_urb, GFP_KERNEL);
}

static int usbmousekey_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct usb_host_interface *interface;
	struct usb_endpoint_descriptor *endpoint;
	int pipe;
	
	interface = intf->cur_altsetting;
	endpoint = &interface->endpoint[0].desc;
	
	uk_dev = input_allocate_device();
	set_bit(EV_KEY,uk_dev->evbit);
	set_bit(EV_REP,uk_dev->evbit);
	set_bit(KEY_L,uk_dev->keybit);
	set_bit(KEY_S,uk_dev->keybit);
	set_bit(KEY_ENTER,uk_dev->keybit);
	input_register_device(uk_dev);

	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
	len = endpoint->wMaxPacketSize;
	usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);
	uk_urb = usb_alloc_urb(0, GFP_KERNEL);
	usb_fill_int_urb(uk_urb, dev, pipe, usb_buf,len,usbmouseaskey_irq, NULL, endpoint->bInterval);
	uk_urb->transfer_dma = usb_buf_phys;
	uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	usb_submit_urb (uk_urb, GFP_KERNEL);
	
	return 0;
}

static void usbmousekey_disconnect(struct usb_interface *intf)
{
	struct usb_device *dev = interface_to_usbdev(intf);

	printk("disconnect usbmouse\n");
	usb_kill_urb(uk_urb);
	usb_free_urb(uk_urb);
	usb_buffer_free(dev, len, usb_buf, usb_buf_phys);
	input_unregister_device(uk_dev);
	input_free_device(uk_dev);
}

测试驱动:

data cnt 1: 0002f0ff00000000
data cnt 2: 0005e0ff00000000
data cnt 3: 0003f0ff00000000
data cnt 4: 000cd0ff00000000
 

(3)vi usbmouseaskey.c(增加上报按键)

static void usbmouseaskey_irq(struct urb *urb)
{
	static unsigned char pre_val;
	if((pre_val & (1<<0)) != (usb_buf[0] & (1<<0)))
	{
		input_event(uk_dev,EV_KEY,KEY_L,(usb_buf[0] & (1<<0))?1:0);
		input_sync(uk_dev);
	}
	if((pre_val & (1<<1)) != (usb_buf[0] & (1<<1)))
	{
		input_event(uk_dev,EV_KEY,KEY_S,(usb_buf[0] & (1<<1))?1:0);
		input_sync(uk_dev);
	}
	if((pre_val & (1<<2)) != (usb_buf[0] & (1<<2)))
	{
		input_event(uk_dev,EV_KEY,KEY_ENTER,(usb_buf[0] & (1<<2))?1:0);
		input_sync(uk_dev);
	}
	pre_val = usb_buf[0];
	usb_submit_urb (uk_urb, GFP_KERNEL);
}

测试驱动:

# insmod usbmouseaskey.ko
usbcore: registered new interface driver usbmousekey
# usb 1-1: new low speed USB device using s3c2410-ohci and address 3
usb 1-1: configuration #1 chosen from 1 choice
input: Unspecified device as /class/input/input0
# ls /dev/event*
/dev/event0
# cat /dev/event0
[▒W&[▒W[z▒&[▒▒\Mf
\Yf
\w▒\▒▒^Y        &^$Y    ^▒
                          &^"▒
                              _▒▒_▒▒_▒▒_▒▒
# hexdump /dev/event0
0000000 0072 0000 02a7 0008 0001 0026 0001 0000
0000010 0072 0000 02b6 0008 0000 0000 0000 0000
0000020 0072 0000 350d 000a 0001 0026 0000 0000
0000030 0072 0000 3518 000a 0000 0000 0000 0000
0000040 0073 0000 79b0 0009 0001 001f 0001 0000
0000050 0073 0000 79c0 0009 0000 0000 0000 0000
0000060 0073 0000 ea96 000b 0001 001f 0000 0000
0000070 0073 0000 ea9f 000b 0000 0000 0000 0000
0000080 007c 0000 7b7b 000e 0001 001c 0001 0000
0000090 007c 0000 7b8e 000e 0000 0000 0000 0000
00000a0 007d 0000 a430 0002 0001 001c 0000 0000
00000b0 007d 0000 a439 0002 0000 0000 0000 0000

# cat /dev/tty1
lsls
lss


网站公告

今日签到

点亮在社区的每一天
去签到