📄 usbtouchscreen.c
字号:
/* touch data in IdealTEK mode */ dev->x = (pkt[1] << 5) | (pkt[2] >> 2); dev->y = (pkt[3] << 5) | (pkt[4] >> 2); dev->touch = (pkt[0] & 0x40) ? 1 : 0; return 1; case 0x98: /* touch data in MT emulation mode */ dev->x = (pkt[2] << 5) | (pkt[1] >> 2); dev->y = (pkt[4] << 5) | (pkt[3] >> 2); dev->touch = (pkt[0] & 0x40) ? 1 : 0; return 1; default: return 0; }}#endif/***************************************************************************** * General Touch Part */#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCHstatic int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt){ dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1] ; dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3] ; dev->press = pkt[5] & 0xff; dev->touch = pkt[0] & 0x01; return 1;}#endif/***************************************************************************** * GoTop Part */#ifdef CONFIG_TOUCHSCREEN_USB_GOTOPstatic int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt){ dev->x = ((pkt[1] & 0x38) << 4) | pkt[2]; dev->y = ((pkt[1] & 0x07) << 7) | pkt[3]; dev->touch = pkt[0] & 0x01; return 1;}#endif/***************************************************************************** * the different device descriptors */#ifdef MULTI_PACKETstatic void usbtouch_process_multi(struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);#endifstatic 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, .min_xc = 0x0, .max_xc = 0x1000, .min_yc = 0x0, .max_yc = 0x1000, .rept_size = 8, //posiflex usbtch, (warning !! report size: don't use 5 byte) .read_data = usbtouch_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 = 0x0500, .min_yc = 0x0, .max_yc = 0x0500, .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};/***************************************************************************** * Generic Part */static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, unsigned char *pkt, int len){ struct usbtouch_device_info *type = usbtouch->type; if (!type->read_data(usbtouch, pkt)) 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); input_report_abs(usbtouch->input, ABS_Y, usbtouch->y); } if (type->max_press) input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press); input_sync(usbtouch->input);}#ifdef MULTI_PACKETstatic void usbtouch_process_multi(struct usbtouch_usb *usbtouch, unsigned char *pkt, int len){ unsigned char *buffer; int pkt_len, pos, buf_len, tmp; /* process buffer */ if (unlikely(usbtouch->buf_len)) { /* try to get size */ pkt_len = usbtouch->type->get_pkt_len( usbtouch->buffer, usbtouch->buf_len); /* drop? */ if (unlikely(!pkt_len)) goto out_flush_buf; /* need to append -pkt_len bytes before able to get size */ if (unlikely(pkt_len < 0)) { int append = -pkt_len; if (unlikely(append > len)) append = len; if (usbtouch->buf_len + append >= usbtouch->type->rept_size) goto out_flush_buf; memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, append); usbtouch->buf_len += append; pkt_len = usbtouch->type->get_pkt_len( usbtouch->buffer, usbtouch->buf_len); if (pkt_len < 0) return; } /* append */ tmp = pkt_len - usbtouch->buf_len; if (usbtouch->buf_len + tmp >= usbtouch->type->rept_size) goto out_flush_buf; memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp); usbtouch_process_pkt(usbtouch, usbtouch->buffer, pkt_len); buffer = pkt + tmp; buf_len = len - tmp; } else { buffer = pkt; buf_len = len; } /* loop over the received packet, process */ pos = 0; while (pos < buf_len) { /* get packet len */ pkt_len = usbtouch->type->get_pkt_len(buffer + pos, buf_len - pos); /* unknown packet: skip one byte */ if (unlikely(!pkt_len)) { pos++; continue; } /* full packet: process */ if (likely((pkt_len > 0) && (pkt_len <= buf_len - pos))) { usbtouch_process_pkt(usbtouch, buffer + pos, pkt_len); } else { /* incomplete packet: save in buffer */ memcpy(usbtouch->buffer, buffer + pos, buf_len - pos); usbtouch->buf_len = buf_len - pos; return; } pos += pkt_len; }out_flush_buf: usbtouch->buf_len = 0; return;}#endifstatic void usbtouch_irq(struct urb *urb){ struct usbtouch_usb *usbtouch = urb->context; int retval; int ii; switch (urb->status) { case 0: /* success */ break; case -ETIME: /* this urb is timing out */ pr_info("%s - urb timed out - was the device unplugged?", __FUNCTION__); return; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ pr_info("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: pr_info("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length); memcpy(usbtouch->dataSave, usbtouch->data, 5);// wake_up_interruptible(&usbtouch->rd_wait_q);// do_gettimeofday (&tv);// if(1)pr_info("irq time: %d sec, %d us\n",tv.tv_sec, tv.tv_usec); if(1)pr_info("print 5 byte\n"); for ( ii = 0 ; ii < 5 ; ii++ ) {// if(1)pr_info("ii= %x",ii); if(1)pr_info("( %x)",usbtouch->data[ii]); } if(1)pr_info("\n"); if(1)pr_info("end print 5 byte\n");exit: retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) err("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval);}static int usbtouch_open(struct input_dev *input){ struct usbtouch_usb *usbtouch = input_get_drvdata(input); if(1)pr_info("usbtch: %s entered, \n", __FUNCTION__ ); usbtouch->irq->dev = usbtouch->udev; if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) return -EIO; return 0;}static void usbtouch_close(struct input_dev *input){ struct usbtouch_usb *usbtouch = input_get_drvdata(input); if(1)pr_info("usbtch: %s entered, \n", __FUNCTION__ ); usb_kill_urb(usbtouch->irq);}static void usbtouch_free_buffers(struct usb_device *udev, struct usbtouch_usb *usbtouch){ usb_buffer_free(udev, usbtouch->type->rept_size, usbtouch->data, usbtouch->data_dma); kfree(usbtouch->buffer);}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_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_device *udev = interface_to_usbdev(intf); struct usbtouch_device_info *type; int err = -ENOMEM; int scr_minor; int retval; if(1)pr_info("usbtouch_probe: enter, pr_info\n"); interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); input_dev = input_allocate_device(); if (!usbtouch || !input_dev) goto out_free; kref_init(&usbtouch->kref);// sema_init(&usbtouch->limit_sem, WRITES_IN_FLIGHT); mutex_init(&usbtouch->io_mutex); type = &usbtouch_dev_info[id->driver_info]; usbtouch->type = type; if (!type->process_pkt) type->process_pkt = usbtouch_process_pkt; usbtouch->data = usb_buffer_alloc(udev, type->rept_size, GFP_KERNEL, &usbtouch->data_dma); if (!usbtouch->data) goto out_free; if (type->get_pkt_len) { usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL); if (!usbtouch->buffer) goto out_free_buffers; } usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL); if (!usbtouch->irq) { pr_info("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__); goto out_free_buffers; } usbtouch->udev = udev; usbtouch->input = input_dev; 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)); 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; input_set_drvdata(input_dev, usbtouch); input_dev->open = usbtouch_open; input_dev->close = usbtouch_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); input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0); if (type->max_press) input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, type->max_press, 0, 0); usb_fill_int_urb(usbtouch->irq, usbtouch->udev, usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress), usbtouch->data, type->rept_size, usbtouch_irq, usbtouch, endpoint->bInterval); usbtouch->irq->dev = usbtouch->udev; usbtouch->irq->transfer_dma = usbtouch->data_dma; usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* device specific init */ if (type->init) { err = type->init(usbtouch); if (err) { pr_info("%s - type->init() failed, err: %d", __FUNCTION__, err); goto out_free_buffers; } } err = input_register_device(usbtouch->input); if (err) { pr_info("%s - input_register_device failed, err: %d", __FUNCTION__, err); goto out_free_buffers; } usb_set_intfdata(intf, usbtouch); /* we can register the device now, as it is ready */ retval = usb_register_dev (intf, &usbtch_class); if (retval) { /* something prevented us from registering this driver */ err ("Not able to get a minor for this device."); usb_set_intfdata (intf, NULL); goto fail1; } usbtouch->minor = intf->minor; if(1)pr_info("%s - minor %d\n", __FUNCTION__, usbtouch->minor);// if(1)pr_info("%s - input_register_device\n", __FUNCTION__);// input_register_device(usbtouch->input); usbtouch->present = 1;// init_waitqueue_head(&usbtouch->rd_wait_q); scr_minor = 0; p_scr_table[scr_minor] = usbtouch;// qla2x00_start_timer(usbtouch, qla2x00_timer, WATCH_INTERVAL); return 0;out_free_buffers: usbtouch_free_buffers(udev, usbtouch);out_free:fail1: input_free_device(input_dev); kfree(usbtouch); return err;}static void usbtouch_disconnect(struct usb_interface *intf){ struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); pr_info("%s - called", __FUNCTION__); if (!usbtouch) return; pr_info("%s - usbtouch is initialized, cleaning up", __FUNCTION__); usb_set_intfdata(intf, NULL); usb_kill_urb(usbtouch->irq); input_unregister_device(usbtouch->input);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -