前段时间由于工作的需要,基于2.6.29内核,完善了其对eGalax Touchkit两款触摸屏的支持。
我所用到的这两款触摸屏,一个是电阻屏vendor =0x0eef, product=0x0002,另一个是电容屏vendor =0x0eef,product= 0x7241。这两款触摸屏均为usb接口的,其驱动所涉及的文件是\drivers\input\touchscreen\usbtouchscreen.c
首先从static struct usb_device_id usbtouch_devices[] 结构体可以看出来,电阻屏的id是包含进来的,而电容屏的并没有,按照电阻屏的那个id格式将电容屏的id添加进来就可以了。
static struct usb_device_id usbtouch_devices[] = { #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX /* ignore the HID capable devices, handled by usbhid */ {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE}, {USB_DEVICE_HID_CLASS(0x0eef, 0x0002), .driver_info = DEVTYPE_IGNORE}, /* normal device IDs */ {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX}, {USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX}, {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX}, {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX}, {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX}, {USB_DEVICE(0x0eef, 0x7241), .driver_info = DEVTYPE_EGALAX}, /* 电容屏所需要添加的 */ {USB_DEVICE(0x1234, 0x0001), .driver_info = DEVTYPE_EGALAX}, {USB_DEVICE(0x1234, 0x0002), .driver_info = DEVTYPE_EGALAX}, #endif {} };
这个驱动要修改的关键在于,这两款触摸屏在使用前是需要向其发送初始化代码的,而原文件里恰恰是没有这个东西,也是之所以鼓捣了老长时间都无法得到正确的触摸点坐标的原因。
首先在staticstruct usbtouch_device_info usbtouch_dev_info[]结构体里可以看出来,针对DEVTYPE_EGALAX是并没有设置(*init)函数的,那我们首先需要添加进来这个初始化函数
#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, .init = egalax_init, }, #endif
具体的初始化函数实现如下:
static int egalax_init(struct usbtouch_usb *usbtouch) { unsigned char *buf; int size = 4; buf = kmalloc(size, GFP_KERNEL); if(! buf) { err("%s - out of memory\n", __func__); return -ENOMEM; } memset(buf, 0, size); buf[0] = 0x0A; buf[1] = 1; buf[2] = 'A'; if (egalax_send_data(usbtouch, buf, 3)) { err("%s - failed to send start command\n", __func__); return -EIO; } return 0; }
这里又涉及到一个发送指令的函数:
static ssize_t egalax_send_data(struct usbtouch_usb *dev, unsigned char *buf, int len) { int retval = 0; dev->setup_packet.BmRequestType = 0x40; dev->setup_packet.Brequest = 0; dev->setup_packet.Wvalue = 0; dev->setup_packet.Windex = 0; dev->setup_packet.Wlength = cpu_to_le16(len); usb_fill_control_urb(dev->urb_ctl, dev->udev, usb_sndctrlpipe(dev->udev, 0), (unsigned char*)&dev->setup_packet, (void *)buf, len, egalax_urb_ctl_callback, dev); retval = usb_submit_urb(dev->urb_ctl, GFP_KERNEL); if (retval) err("%s - usb_submit_urb failed with result: %d", __func__, retval); return retval; }
最后要注意的是,电容屏跟电阻屏返回的数据是略有不同的,分情况去读取就没有问题了
作者:jackielee524 发表于2013-3-25 23:41:25 原文链接
阅读:90 评论:0 查看评论