📄 touchscreen.c
字号:
if(ifnum != 0) { info("probe_touchscreen: not correct interface no."); return NULL; } /* * After this point we can be a little noisy about what we are trying to * configure. */ if (dev->descriptor.bNumConfigurations != 1) { info("probe_touchscreen: Only one device configuration is supported."); return NULL; } if (dev->config[0].bNumInterfaces != 1) { info("probe_touchscreen: Only one device interface is supported."); return NULL; } interface = dev->config[0].interface[ifnum].altsetting; //interface = dev->actconfig[0].interface[ifnum].altsetting; endpoint = interface[ifnum].endpoint; /* * Start checking for two bulk endpoints OR two bulk endpoints *and* one * interrupt endpoint. If we have an interrupt endpoint go ahead and * setup the handler. FIXME: This is a future enhancement... */ dbg("probe_touchscreen: Number of Endpoints:%d", (int) interface->bNumEndpoints); if (interface->bNumEndpoints != 1) { info("probe_touchscreen: Only one endpoints supported."); return NULL; } //ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0; ep_cnt = have_intr = 0; if (IS_EP_INTR(endpoint[ep_cnt])) { have_intr = ++ep_cnt; dbg("probe_touchscreen: intr_ep:%d", have_intr); } else { info("probe_touchscreen: Undetected endpoint. Notify the maintainer."); return NULL; /* Shouldn't ever get here unless we have something weird */ } /* * Determine a minor number and initialize the structure associated * with it. The problem with this is that we are counting on the fact * that the user will sequentially add device nodes for the touchscreen * devices. */ /* * Use firs free file devices */ for (minor = 0; minor < TSCRN_MAX_MNR; minor++) { if (!p_tscrn_table[minor]) break; } /* Check to make sure that the last slot isn't already taken */ if (p_tscrn_table[minor]) { err("probe_touchscreen: No more minor devices remaining."); return NULL; } dbg("probe_touchscreen: Allocated minor:%d", minor); if (!(tscrn = kmalloc (sizeof (struct tscrn_usb_data), GFP_KERNEL))) { err("probe_touchscreen: Out of memory."); return NULL; } memset (tscrn, 0, sizeof(struct tscrn_usb_data)); dbg ("probe_touchscreen(%d): Address of tscrn:%p", minor, tscrn); /* Ok, now initialize all the relevant values */ if (!(tscrn->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) { err("probe_touchscreen(%d): Not enough memory for the output buffer.", minor); kfree(tscrn); return NULL; } dbg("probe_touchscreen(%d): obuf address:%p", minor, tscrn->obuf); if (!(tscrn->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) { err("probe_touchscreen(%d): Not enough memory for the input buffer.", minor); kfree(tscrn->obuf); kfree(tscrn); return NULL; } dbg("probe_touchscreen(%d): ibuf address:%p", minor, tscrn->ibuf); if (!(tscrn->setup_packet = (void *)kmalloc(sizeof(*tscrn->setup_packet), GFP_KERNEL))) { err("probe_touchscreen(%d): Not enough memory for the statuc.", minor); kfree(tscrn->ibuf); kfree(tscrn->obuf); kfree(tscrn); return NULL; } dbg("probe_touchscreen(%d): setup_packet address:%p, size=%d size2=%d", minor, tscrn->setup_packet, sizeof(*tscrn->setup_packet),sizeof(devrequest)); memset((char *)tscrn->setup_packet, 0 , sizeof(*tscrn->setup_packet)); // Initiation input_dev structure tscrn->input_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); tscrn->input_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT);//| BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); tscrn->input_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); // Initialization toRead and toWrite variables tscrn->pToWrite = tscrn->obuf; tscrn->pToRead = NULL; // Initiation wait queue dbg("probe_touchscreen(%d): initialization wait_queue", minor); init_waitqueue_head(&tscrn->wait); dbg("probe_touchscreen(%d): wait_queue initialized", minor);#ifdef DEBUG /////////////////////////////////////////////////////////////////////////////////// // Only for testing, not for normal useing of device driver // Register the interface if(!(nRet = usb_interface_claimed(&dev->actconfig[0].interface[ifnum]))) { dbg("probe_touchscreen(%d): interface_claimed=%d", minor, nRet); usb_driver_claim_interface(&touchscreen_driver,&dev->actconfig[0].interface[ifnum],tscrn); } else dbg("probe_touchscreen(%d): error interface_claimed=%d", minor, nRet); dbg("probe_touchscreen(%d): Configuring CTRL handler for intr EP:%d", minor, have_intr); /* sends reset command */ // receive answer data tscrn->setup_packet->requesttype = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; tscrn->setup_packet->request = USB_REQ_GET_CONFIGURATION; tscrn->setup_packet->value = 0x0; tscrn->setup_packet->index = 0x0;//ifnum; tscrn->setup_packet->length = 1; FILL_CONTROL_URB(&tscrn->ctrlin, dev, usb_rcvctrlpipe(dev, 0x80), (unsigned char *)tscrn->setup_packet, tscrn->ibuf, sizeof(tscrn->ibuf), ctrl_touchscreen, tscrn); if ((nRet=usb_submit_urb(&tscrn->ctrlin))) { err("probe_touchscreen(%d): GET_CONFIGURATION:Get smth error=%d status=%d.", minor, nRet, tscrn->ctrlin.status); kfree(tscrn->ibuf); kfree(tscrn->obuf); kfree(tscrn->setup_packet); kfree(tscrn); return NULL; } nCounter = 10; dbg("probe_touchscreen(%d): GET_CONFIGURATION:wait for data: status=%d nRet=%d", minor,tscrn->ctrlin.status, nRet); interruptible_sleep_on(&tscrn->wait); dbg("probe_touchscreen(%d): GET_CONFIGURATION:gets 0x%x,0x%x status=%d nRet=%d", minor,(int)tscrn->ibuf[0],(int)tscrn->ibuf[1], tscrn->ctrlin.status, nRet); if(tscrn->ctrlin.status == (-32)) { dbg("probe_touchscreen(%d): get error -32 status=%d - reset pipe", minor,tscrn->ctrlin.status); nRet = usb_clear_halt(dev,0x00); dbg("probe_touchscreen(%d): get error -32 status=%d - reset pipe nRet=%d", minor,tscrn->ctrlin.status, nRet); } // // receive answer data tscrn->setup_packet->requesttype = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT; tscrn->setup_packet->request = USB_REQ_GET_STATUS; tscrn->setup_packet->value = 0x0; tscrn->setup_packet->index = 0x81; tscrn->setup_packet->length = 2; FILL_CONTROL_URB(&tscrn->ctrlin, dev, usb_rcvctrlpipe(dev, 0x80), (unsigned char *)tscrn->setup_packet, tscrn->ibuf, sizeof(tscrn->ibuf), ctrl_touchscreen, tscrn); if ((nRet=usb_submit_urb(&tscrn->ctrlin))) { err("probe_touchscreen(%d): GET_STATUS:Get smth error=%d status=%d .", minor, nRet, tscrn->ctrlin.status); kfree(tscrn->ibuf); kfree(tscrn->obuf); kfree(tscrn->setup_packet); kfree(tscrn); return NULL; } dbg("probe_touchscreen(%d): GET_STATUS: status=%d nRet=%d", minor,tscrn->ctrlin.status, nRet); interruptible_sleep_on(&tscrn->wait); dbg("probe_touchscreen(%d): GET_STATUS:gets 0x%x,0x%x,0x%x status=%d nRet=%d", minor,(int)tscrn->ibuf[0],(int)tscrn->ibuf[1],(int)tscrn->ibuf[2], tscrn->ctrlin.status, nRet); // -- // get controller id report tscrn->setup_packet->requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE; tscrn->setup_packet->request = TSCRN_USB_REQUEST_CONTROLLER_ID; tscrn->setup_packet->value = 0; tscrn->setup_packet->index = 0; tscrn->setup_packet->length = TSCRN_USB_RAPORT_SIZE_ID; memset((char *)tscrn->ibuf,0,IBUF_SIZE); FILL_CONTROL_URB(&tscrn->ctrlout, dev, usb_rcvctrlpipe(dev, 0x80), (unsigned char *)tscrn->setup_packet, tscrn->ibuf, TSCRN_USB_RAPORT_SIZE_ID, ctrl_touchscreen, tscrn); if ((nRet=usb_submit_urb(&tscrn->ctrlout))) { err("probe_touchscreen(%d): GET_ID:error=%d status=%d .", minor, nRet, tscrn->ctrlout.status); kfree(tscrn->ibuf); kfree(tscrn->obuf); kfree(tscrn->setup_packet); kfree(tscrn); return NULL; } dbg("probe_touchscreen(%d): GET_ID gets 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x status=%d nRet=%d", minor,(int)tscrn->ibuf[0],(int)tscrn->ibuf[1],(int)tscrn->ibuf[2],(int)tscrn->ibuf[3],(int)tscrn->ibuf[4],(int)tscrn->ibuf[5],(int)tscrn->ibuf[6],(int)tscrn->ibuf[7], tscrn->ctrlout.status, nRet); interruptible_sleep_on(&tscrn->wait); dbg("probe_touchscreen(%d): GET_ID gets 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x status=%d nRet=%d", minor,(int)tscrn->ibuf[0],(int)tscrn->ibuf[1],(int)tscrn->ibuf[2],(int)tscrn->ibuf[3],(int)tscrn->ibuf[4],(int)tscrn->ibuf[5],(int)tscrn->ibuf[6],(int)tscrn->ibuf[7], tscrn->ctrlout.status, nRet);#endif //////////////////////////////////////////////////////////////////////////////////// /* Ok, if we detected an interrupt EP, setup a handler for it */ if (have_intr) { dbg("probe_touchscreen(%d): Configuring IRQ handler for intr EP:%d", minor, have_intr); FILL_INT_URB(&tscrn->irq, dev, usb_rcvintpipe(dev, 0x81),//endpoint[(int )(have_intr-1)].bEndpointAddress), tscrn->data, TSCRN_USB_RAPORT_SIZE_DATA, irq_touchscreen, tscrn, endpoint[(int)(have_intr-1)].bInterval); //2); if (usb_submit_urb(&tscrn->irq)) { err("probe_touchscreen(%d): Unable to allocate INT URB.", minor); kfree(tscrn->ibuf); kfree(tscrn->obuf); kfree(tscrn->setup_packet); kfree(tscrn); return NULL; } //the status will be -115 -> thist means EINPROGRESS, but it should be that. dbg("probe_touchscreen(%d): IRQ done interval=%d status=%d", minor,endpoint[(int)(have_intr-1)].bInterval, tscrn->irq.status); } tscrn->intr_ep = have_intr; tscrn->present = 1; tscrn->dev = dev; tscrn->minor = minor; tscrn->isopen = 0; input_register_device(&tscrn->input_dev); return p_tscrn_table[minor] = tscrn;}static void disconnect_touchscreen(struct usb_device *dev, void *ptr){ struct tscrn_usb_data *tscrn = (struct tscrn_usb_data *) ptr; //if(tscrn->intr_ep) //{ if(tscrn->irq.status != 0) { dbg("disconnect_touchscreen(%d): Unlinking IRQ URB", tscrn->minor); usb_unlink_urb(&tscrn->irq); } //} if(tscrn->ctrlin.status != 0) { dbg("disconnect_touchscreen(%d): Unlinking CTRLIN URB", tscrn->minor); usb_unlink_urb(&tscrn->ctrlin); } if(tscrn->ctrlout.status != 0) { dbg("disconnect_touchscreen(%d): Unlinking CTRLOUT URB", tscrn->minor); usb_unlink_urb(&tscrn->ctrlout); } input_unregister_device(&tscrn->input_dev); usb_driver_release_interface(&touchscreen_driver, &tscrn->dev->actconfig->interface[tscrn->ifnum]); kfree(tscrn->ibuf); kfree(tscrn->obuf); kfree(tscrn->setup_packet); dbg("disconnect_touchscreen: De-allocating minor:%d", tscrn->minor); p_tscrn_table[tscrn->minor] = NULL; kfree (tscrn);}static struct file_operations usb_touchscreen_fops = {read: read_touchscreen, //write: write_touchscreen,poll: poll_touchscreen, ioctl: ioctl_touchscreen,open: open_touchscreen,release: close_touchscreen,};static struct usb_driver touchscreen_driver = { "touchscreen", probe_touchscreen, disconnect_touchscreen, { NULL, NULL }, &usb_touchscreen_fops, TSCRN_BASE_MNR};void __exit usb_touchscreen_exit(void){ usb_deregister(&touchscreen_driver);}int __init usb_touchscreen_init (void){ if (usb_register(&touchscreen_driver) < 0) return -1; info("USB Touchscreen support registered."); return 0;}module_init(usb_touchscreen_init);module_exit(usb_touchscreen_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -