zoukankan      html  css  js  c++  java
  • usb触摸屏驱动

    源码在/drivers/input/touchscreen/usbtouchscreen.c中

    static int __init usbtouch_init(void)	//入口函数
    {
    	return usb_register(&usbtouch_driver);	//注册usb触摸屏驱动
    }
    module_init(usbtouch_init);

    看usbtouch_driver的定义

    static struct usb_driver usbtouch_driver = {
    	.name		= "usbtouchscreen",
    	.probe		= usbtouch_probe,	//usb触摸屏探测到
    	.disconnect	= usbtouch_disconnect,
    	.suspend	= usbtouch_suspend,
    	.resume		= usbtouch_resume,
    	.reset_resume	= usbtouch_reset_resume,
    	.id_table	= usbtouch_devices,
    	.supports_autosuspend = 1,
    };

    当有设备匹配的时候会调用probe方法,也就是usbtouch_probe

    在static const struct usb_device_id usbtouch_devices[]中定义了的usb设备插入就会匹配并触发probe

    可以用宏USB_DEVICE简化设置usb设备id信息,如下:

    {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},

    driver_info是驱动类型,有一下选择

    enum {
    	DEVTYPE_IGNORE = -1,
    	DEVTYPE_EGALAX,
    	DEVTYPE_PANJIT,
    	DEVTYPE_3M,
    	DEVTYPE_ITM,
    	DEVTYPE_ETURBO,
    	DEVTYPE_GUNZE,
    	DEVTYPE_DMC_TSC10,
    	DEVTYPE_IRTOUCH,
    	DEVTYPE_IDEALTEK,
    	DEVTYPE_GENERAL_TOUCH,
    	DEVTYPE_GOTOP,
    	DEVTYPE_JASTEC,
    	DEVTYPE_E2I,
    	DEVTYPE_ZYTRONIC,
    	DEVTYPE_TC45USB,
    	DEVTYPE_NEXIO,
    };

    没有选择也可以自己添加一个在枚举体后面
    (0x3823,0x0001)这两个分别是usb设备的厂商id和产品id
    下面代码是我插拔usb触摸屏的打印信息

    usb 1-1.1: new full speed USB device using musb-hdrc and address 9
    usb 1-1.1: New USB device found, idVendor=0408, idProduct=3001
    usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    usb 1-1.1: Product: HCTouch    
    usb 1-1.1: Manufacturer: HC
    input: HC HCTouch     as /devices/platform/omap/ti81xx-usbss/musb-hdrc.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input6
    input: HC HCTouch     as /devices/platform/omap/ti81xx-usbss/musb-hdrc.0/usb1/1-1/1-1.1/1-1.1:1.1/input/input7

    作为我的设备,我就把idVendor=0408, idProduct=3001添加进USB_DEVICE宏就行

    {USB_DEVICE(0x0408, 0x3001), .driver_info = DEVTYPE_HCTOUCH},

    OK!插上设备就会匹配的

    input: HC HCTouch     as /devices/platform/omap/ti81xx-usbss/musb-hdrc.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input6
    input: HC HCTouch     as /devices/platform/omap/ti81xx-usbss/musb-hdrc.0/usb1/1-1/1-1.1/1-1.1:1.1/input/input7

    这个就是匹配后的打印信息

    接着就是probe方法了

    static int usbtouch_probe(struct usb_interface *intf,const struct usb_device_id *id)
    {
    	struct usbtouch_usb *usbtouch;
    	struct input_dev *input_dev;
    	struct usb_endpoint_descriptor *endpoint;
    	struct usb_device *udev = interface_to_usbdev(intf);
    	struct usbtouch_device_info *type;
    	int err = -ENOMEM;
    
    	/* some devices are ignored */
    	if (id->driver_info == DEVTYPE_IGNORE)	//忽略的设备类型
    		return -ENODEV;
    
    	endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting);	//获取端点描述符数组指针
    	if (!endpoint)
    		return -ENXIO;
    
    	usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL);	//分配usbtouch_usb结构体对象内存
    	input_dev = input_allocate_device();	//分配输入设备对象内存
    	if (!usbtouch || !input_dev)	//分配不成功退出
    		goto out_free;
    
    	type = &usbtouch_dev_info[id->driver_info];	//根据id的driver_info信息获取全局usbtouch_dev_info数组项
    	usbtouch->type = type;	//指定usbtouch_dev_info
    	if (!type->process_pkt)	//若usbtouch_dev_info不存在process_pkt方法
    		type->process_pkt = usbtouch_process_pkt;	//则默认设置为usbtouch_process_pkt
    
    	usbtouch->data = usb_alloc_coherent(udev, type->rept_size,GFP_KERNEL, &usbtouch->data_dma);	//分配缓冲区
    	if (!usbtouch->data)
    		goto out_free;
    
    	if (type->get_pkt_len) {	//若usbtouch_dev_info存在get_pkt_len方法
    		usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL);	//则要根据rept_size分配usb_touch_usb对象缓冲区
    		if (!usbtouch->buffer)
    			goto out_free_buffers;
    	}
    
    	usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);	//分配urb
    	if (!usbtouch->irq) {
    		dbg("%s - usb_alloc_urb failed: usbtouch->irq", __func__);
    		goto out_free_buffers;
    	}
    
    	usbtouch->interface = intf;	//设置usb_touch_usb的usb接口
    	usbtouch->input = input_dev;//捆绑usb_touch_usb和输入设备
    
    	if (udev->manufacturer)	//存在工厂名则设置工厂名
    		strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name));
    
    	if (udev->product) {	//存在产品名则设置产品名
    		if (udev->manufacturer)
    			strlcat(usbtouch->name, " ", sizeof(usbtouch->name));
    		strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name));
    	}
    
    	if (!strlen(usbtouch->name))	//若不存在工厂名和产品名
    		snprintf(usbtouch->name, sizeof(usbtouch->name),
    			"USB Touchscreen %04x:%04x",
    			 le16_to_cpu(udev->descriptor.idVendor),
    			 le16_to_cpu(udev->descriptor.idProduct));
    
    	usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys));	//设置usb设备路径
    	strlcat(usbtouch->phys, "/input0", sizeof(usbtouch->phys));
    
    	input_dev->name = usbtouch->name;	//设置输入设备名
    	input_dev->phys = usbtouch->phys;	//设置输入设备路径
    	usb_to_input_id(udev, &input_dev->id);
    	input_dev->dev.parent = &intf->dev;	//设置usb设备为输入设备的父设备
    
    	input_set_drvdata(input_dev, usbtouch);
    
    	input_dev->open = usbtouch_open;	//设置输入设备的open方法
    	input_dev->close = usbtouch_close;	//设置输入设备的close方法
    
    	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);	//按键和绝对位移事件
    	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);	//触摸按键
    	input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);	//绝对x坐标位移
    	input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);	//绝对y坐标位移
    	if (type->max_press)
    		input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press,type->max_press, 0, 0);
    
    	if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT)	//中断传输方式
    		usb_fill_int_urb(usbtouch->irq, udev,
    			 usb_rcvintpipe(udev, endpoint->bEndpointAddress),
    			 usbtouch->data, type->rept_size,
    			 usbtouch_irq, usbtouch, endpoint->bInterval);
    	else	//bulk传输方式
    		usb_fill_bulk_urb(usbtouch->irq, udev,
    			 usb_rcvbulkpipe(udev, endpoint->bEndpointAddress),
    			 usbtouch->data, type->rept_size,
    			 usbtouch_irq, usbtouch);
    
    	usbtouch->irq->dev = udev;	//urb和usb设备捆绑
    	usbtouch->irq->transfer_dma = usbtouch->data_dma;	//传输数据dma地址缓冲区
    	usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;	//传输标志物dma映射传输
    
    	/* device specific allocations */
    	if (type->alloc) {	//usbtouch_dev_info对象存在alloc方法
    		err = type->alloc(usbtouch);	//则调用该方法
    		if (err) {
    			dbg("%s - type->alloc() failed, err: %d", __func__, err);
    			goto out_free_urb;
    		}
    	}
    
    	/* device specific initialisation*/
    	if (type->init) {	//usbtouch_dev_info对象存在初始化方法
    		err = type->init(usbtouch);	//则调用该初始化方法
    		if (err) {
    			dbg("%s - type->init() failed, err: %d", __func__, err);
    			goto out_do_exit;
    		}
    	}
    
    	err = input_register_device(usbtouch->input);	//注册输入设备
    	if (err) {
    		dbg("%s - input_register_device failed, err: %d", __func__, err);
    		goto out_do_exit;
    	}
    
    	usb_set_intfdata(intf, usbtouch);
    
    	if (usbtouch->type->irq_always) {	//usbtouch_dev_info对象存在irq_always方法
    		/* this can't fail */
    		usb_autopm_get_interface(intf);	//电源唤醒
    		err = usb_submit_urb(usbtouch->irq, GFP_KERNEL);	//提交urb
    		if (err) {
    			usb_autopm_put_interface(intf);	//电源挂起
    			err("%s - usb_submit_urb failed with result: %d",
    			    __func__, err);
    			goto out_unregister_input;
    		}
    	}
    
    	return 0;
    
    out_unregister_input:
    	input_unregister_device(input_dev);
    	input_dev = NULL;
    out_do_exit:
    	if (type->exit)
    		type->exit(usbtouch);
    out_free_urb:
    	usb_free_urb(usbtouch->irq);
    out_free_buffers:
    	usbtouch_free_buffers(udev, usbtouch);
    out_free:
    	input_free_device(input_dev);
    	kfree(usbtouch);
    	return err;
    }

    错中复杂的关系不用管,关键是

    1.type = &usbtouch_dev_info[id->driver_info]; //根据id的driver_info信息获取全局usbtouch_dev_info数组项

    2.if (!type->process_pkt) //若usbtouch_dev_info不存在process_pkt方法
      type->process_pkt = usbtouch_process_pkt; //则默认设置为usbtouch_process_pkt

    3.申请的urb的回调函数是usbtouch_irq
    4.if (type->init) { //usbtouch_dev_info对象存在初始化方法
      err = type->init(usbtouch); //则调用该初始化方法

    usbtouch_dev_info是全局usbtouch_device_info数组

    static struct usbtouch_device_info usbtouch_dev_info[] = {
    #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
    	[DEVTYPE_EGALAX] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x07ff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x07ff,
    		.rept_size	= 16,
    		.process_pkt	= usbtouch_process_multi,
    		.get_pkt_len	= egalax_get_pkt_len,
    		.read_data	= egalax_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_PANJIT
    	[DEVTYPE_PANJIT] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x0fff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x0fff,
    		.rept_size	= 8,
    		.read_data	= panjit_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_3M
    	[DEVTYPE_3M] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x4000,
    		.min_yc		= 0x0,
    		.max_yc		= 0x4000,
    		.rept_size	= 11,
    		.read_data	= mtouch_read_data,
    		.init		= mtouch_init,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_ITM
    	[DEVTYPE_ITM] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x0fff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x0fff,
    		.max_press	= 0xff,
    		.rept_size	= 8,
    		.read_data	= itm_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO
    	[DEVTYPE_ETURBO] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x07ff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x07ff,
    		.rept_size	= 8,
    		.process_pkt	= usbtouch_process_multi,
    		.get_pkt_len	= eturbo_get_pkt_len,
    		.read_data	= eturbo_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_GUNZE
    	[DEVTYPE_GUNZE] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x0fff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x0fff,
    		.rept_size	= 4,
    		.read_data	= gunze_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_DMC_TSC10
    	[DEVTYPE_DMC_TSC10] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x03ff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x03ff,
    		.rept_size	= 5,
    		.init		= dmc_tsc10_init,
    		.read_data	= dmc_tsc10_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
    	[DEVTYPE_IRTOUCH] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x0fff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x0fff,
    		.rept_size	= 8,
    		.read_data	= irtouch_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK
    	[DEVTYPE_IDEALTEK] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x0fff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x0fff,
    		.rept_size	= 8,
    		.process_pkt	= usbtouch_process_multi,
    		.get_pkt_len	= idealtek_get_pkt_len,
    		.read_data	= idealtek_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
    	[DEVTYPE_GENERAL_TOUCH] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x7fff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x7fff,
    		.rept_size	= 7,
    		.read_data	= general_touch_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
    	[DEVTYPE_GOTOP] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x03ff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x03ff,
    		.rept_size	= 4,
    		.read_data	= gotop_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_JASTEC
    	[DEVTYPE_JASTEC] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x0fff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x0fff,
    		.rept_size	= 4,
    		.read_data	= jastec_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_E2I
    	[DEVTYPE_E2I] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x7fff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x7fff,
    		.rept_size	= 6,
    		.init		= e2i_init,
    		.read_data	= e2i_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
    	[DEVTYPE_ZYTRONIC] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x03ff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x03ff,
    		.rept_size	= 5,
    		.read_data	= zytronic_read_data,
    		.irq_always     = true,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB
    	[DEVTYPE_TC45USB] = {
    		.min_xc		= 0x0,
    		.max_xc		= 0x0fff,
    		.min_yc		= 0x0,
    		.max_yc		= 0x0fff,
    		.rept_size	= 5,
    		.read_data	= tc45usb_read_data,
    	},
    #endif
    
    #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO
    	[DEVTYPE_NEXIO] = {
    		.rept_size	= 1024,
    		.irq_always	= true,
    		.read_data	= nexio_read_data,
    		.alloc		= nexio_alloc,
    		.init		= nexio_init,
    		.exit		= nexio_exit,
    	},
    #endif
    };
    

    由于我DIY了一个,所以后面要添加

    	[DEVTYPE_HCTOUCH] = {
    		.min_xc		= 0x0,	//最小x坐标
    		.max_xc		= 0x7fff,	//最大x坐标
    		.min_yc		= 0x0,	//最小y坐标
    		.max_yc		= 0x7fff,	//最大y坐标
    		.rept_size	= 7,	//还不知道是干嘛用的
    		.read_data	= hc_touch_read_data,	//关键的读数据方法
    	},

    当触摸屏幕的时候,usb会通过urb传递数据,紧接着肯定会调用usbtouch_irq啦

    static void usbtouch_irq(struct urb *urb)
    {
    	struct usbtouch_usb *usbtouch = urb->context;
    	int retval;
    
    	switch (urb->status) {
    	case 0:	//正常流程跳出switch语句
    		/* success */
    		break;
    	case -ETIME:
    		/* this urb is timing out */
    		dbg("%s - urb timed out - was the device unplugged?",
    		    __func__);
    		return;
    	case -ECONNRESET:
    	case -ENOENT:
    	case -ESHUTDOWN:
    	case -EPIPE:
    		/* this urb is terminated, clean up */
    		dbg("%s - urb shutting down with status: %d",
    		    __func__, urb->status);
    		return;
    	default:
    		dbg("%s - nonzero urb status received: %d",
    		    __func__, urb->status);
    		goto exit;
    	}
    	//执行usbtouch_device_info对象的process_pkt方法
    	usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length);
    
    exit:
    	usb_mark_last_busy(interface_to_usbdev(usbtouch->interface));
    	retval = usb_submit_urb(urb, GFP_ATOMIC);
    	if (retval)
    		err("%s - usb_submit_urb failed with result: %d",
    		    __func__, retval);
    }

    这里的关键是会调用process_pkt方法也就是默认的usbtouch_process_pkt函数

    static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,unsigned char *pkt, int len)	//默认的usb触摸数据包处理函数
    {
    	struct usbtouch_device_info *type = usbtouch->type;	//获取usbtouch_device_info对象
    
    	if (!type->read_data(usbtouch, pkt))	//调用usbtouch_device_info对象的read_data方法
    			return;
    
    	input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch);	//上报触摸事件
    
    	if (swap_xy) {	//竖屏模式
    		input_report_abs(usbtouch->input, ABS_X, usbtouch->y);
    		input_report_abs(usbtouch->input, ABS_Y, usbtouch->x);
    	} else {
    		input_report_abs(usbtouch->input, ABS_X, usbtouch->x);	//上报绝对坐标X事件
    		input_report_abs(usbtouch->input, ABS_Y, usbtouch->y);	//上报绝对坐标Y事件
    	}
    	if (type->max_press)
    		input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press);
    	input_sync(usbtouch->input);	//同步输入事件
    }

    这个函数主要是调用了usbtouch_device_info对象的read_data方法也就是上面提到的数组的read_data方法(hc_touch_read_data)

    数据读取完毕后上报触摸事件,绝对XY坐标事件,然后同步交由输入子系统去处理坐标等具体事项

    hc_touch_read_data函数读取usb接口传递过来的数据,该数据就包含了坐标和触摸信息,函数主要是对这些信息做下运算处理

    static int hc_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
    {
    	dev->x = (pkt[2] << 8) | pkt[1];
    	dev->y = (pkt[4] << 8) | pkt[3];
    	dev->press = pkt[5] & 0xff;
    	dev->touch = pkt[0] & 0x01;
    
    	return 1;
    }

    这些处理的细节跟具体硬件厂商或者协议有关,调试可以将dev->x和dev->y打印出来
    可能你加了打印之后触摸屏幕压根就没有打印信息

    那是因为要打开设备,所以应用层也要有测试软件,有界面的测试软件最好

    没有也可以用下面这段代码去简单测试一下(来着网络)

    #include <stdio.h>
    #include <linux/input.h>
    
    static int event0_fd = -1;
    struct input_event ev0[64];
    
    static int handle_event0()
    {
    	int button = 0, realx=0, realy=0, i, rd;
    	rd = read(event0_fd, ev0, sizeof(struct input_event)* 64);
    	if(rd < sizeof(struct input_event)) return 0;
    	for(i=0;i<rd/sizeof(struct input_event); i++)
    	{
    		if(EV_ABS == ev0[i].type)
    		{
    			if(ev0[i].code == 0) {
    				realx = ev0[i].value;
    			} else if(ev0[i].code == 1) {
    				realy = ev0[i].value;
    			}
    		}
    		printf("realx:%3d; realy:%3d\n",realx,realy);
    		//printf("event(%d):type:%d; code:%3d; value:%3d; realx:%3d; realy:%3d\n",i,ev0[i].type,ev0[i].code,ev0[i].value,realx,realy);
    		
    	}
    	return 1;
    }
    
    
    int main(void)
    {
    	int done = 1;
    	event0_fd = open("/dev/input/event1",02);	//打开设备
    	if(event0_fd <0) {
    		printf("open input device error\n");
    		return -1;
    	}
    	while (done)
    	{
    		//printf("begin handle_event0...\n");
    		done = handle_event0();
    		//printf("end handle_event0...\n");
    	}
    	if(event0_fd > 0)
    	{
    		close(event0_fd);
    		event0_fd = -1;
    	}
    	return 0;
    }


    这段代码打开的设备修改成你的设备路径,插拔触摸屏判断哪个是你触摸屏的设备
    或者ls -l  /sys/class/input看信息结合插入设备的打印信息也可以判断你的设备是哪个

    lrwxrwxrwx    1 root     root            0 Mar 23 17:20 event0 -> http://www.cnblogs.com/devices/platform/omap/ti81xx-usbss/musb-hdrc.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input6/event0
    lrwxrwxrwx    1 root     root            0 Mar 23 17:20 event1 -> http://www.cnblogs.com/devices/platform/omap/ti81xx-usbss/musb-hdrc.0/usb1/1-1/1-1.1/1-1.1:1.1/input/input7/event1
    lrwxrwxrwx    1 root     root            0 Mar 23 17:20 event2 -> http://www.cnblogs.com/devices/platform/omap/ti81xx-usbss/musb-hdrc.0/usb1/1-1/1-1.3/1-1.3:1.0/input/input8/event2

    再或者cat /proc/bus/input/devices也可以

    I: Bus=0003 Vendor=0408 Product=3001 Version=0200
    N: Name="HC HCTouch    "
    P: Phys=usb-musb-hdrc.0-1.1/input0
    S: Sysfs=/devices/platform/omap/ti81xx-usbss/musb-hdrc.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input6
    U: Uniq=
    H: Handlers=mouse0 event0 
    B: EV=b
    B: KEY=400 0 0 0 0 0 0 0 0 0 0
    B: ABS=3
    
    I: Bus=0003 Vendor=0408 Product=3001 Version=0200
    N: Name="HC HCTouch    "
    P: Phys=usb-musb-hdrc.0-1.1/input0
    S: Sysfs=/devices/platform/omap/ti81xx-usbss/musb-hdrc.0/usb1/1-1/1-1.1/1-1.1:1.1/input/input7
    U: Uniq=
    H: Handlers=mouse1 event1 
    B: EV=b
    B: KEY=400 0 0 0 0 0 0 0 0 0 0
    B: ABS=3

    这里我的设备有两个input是因为我是2点的屏

    还有一点要补充就是关于内核编译选项的

    Device Drivers  --->Input device support  --->

    [*]   Touchscreens  ---> 

    <*>   USB Touchscreen Driver  这个要选择

     [*] HID Devices  --->    <*>   USB Human Interface Device (full HID) support 选中



     

  • 相关阅读:
    从简单需求到OLAP的RANK系列函数
    数据库的Index Scan V.S. Rscan
    z/OS上Dataset 的移动
    如何保存CONSOLE LOG
    c#对文件进行MD5加密校验
    基于webpivottable做的透视表
    通过asp.net程序来控制自己开发的windows服务
    AES加密和解密
    C#添加日志
    cmd执行mssql脚本或者执行mysql脚本
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2998530.html
Copyright © 2011-2022 走看看