Recently need to put a touch screen device to TV, now more common is the use of USB interface Touch box, for various platforms, here is a general record on Android kernel in the Usbtouchscreen driver.
Writing is not easy, reprint need to indicate the source: http://blog.csdn.net/jscese/article/details/41827495
Driver compilation:
The current kernel are all self-contained usbtouchscreen drivers, my version 3.1.10
Source is located in:/kernel/drivers/input/touchscreen/usbtouchscreen.c
From this path can be seen in the driver branch, my side of the platform itself is not released, and did not compile into the kernel, who would think of touch TV it ~
After make menuconfig, via device drivers-->input device SUPPORT-->TOUCHSCREENS-->USB touchscreen Driver Then select the desired touchscreen type
By viewing the Kconfig Makefile in the relevant directory, refer to: Kernel compile configuration mechanism
To register the USB drive:
Familiar with the Linux driver know module entry: Module_init (Usbtouch_init), here to see this init:
static int __init usbtouch_init (void) { return usb_register (&usbtouch_driver); The registered function of the USB core is called, and a usb_driver struct pointer is passed in.
Usb_register implemented in/kernel/include/linux/usb.h:
static inline int usb_register (struct usb_driver *driver) { return Usb_register_driver (Driver, This_module, kbuild_ ModName);//Here is the USB core driver, register this module driver to the USB bus}
This must be the first to register the bus, when a USB device is plugged in, the USB device driver, that is, Usb_generic_driver will interact with the USB device, get all its various descriptors, and for each interface is defined as a device, and then loaded into the usb_ Bus, let it match its corresponding interface driver, interested can go to see the/kernel/drivers/base/bus.c in the
Bus_for_each_drvFunction.
The interface driver that is registered to the bus here is usbtouch_driver
Usbtouch_driver:
The variable usbtouch_driver of this usb_driver type is the soul core of the entire usbtouchscreen, and can be viewed in the usb.h described above in the Usb_driver structure prototype,
Here Usbtouch_driver uses some of the interfaces:
static struct Usb_driver Usbtouch_driver = { . Name = "Usbtouchscreen",//driver name . Probe = Usbtouch_ Probe, //probe interface, used on the bus to match the driver corresponding to the detection of the device,/KERNEL/DRIVERS/USB/CORE/DRIVER.C in the usb_probe_interface call to our driver interface . Disconnect = Usbtouch_disconnect, //As opposed to probe, called when disconnected . Suspend = usbtouch_suspend,//usb device hangs . Resume = Usbtouch_resume, //And above hangs opposite, wakes . Reset_resume = Usbtouch_reset_resume, // Reset Wake . id_table = usbtouch_devices,//Supported Device ID table . supports_autosuspend = 1,};
Id_table:
The first thing you can do is look at the id_table variable, which represents the list of supported device IDs, with the following data types:
struct USB_DEVICE_ID {/* which fields to match against? */__u16match_flags;/* used for product specific matches; Range is Inclusive */__u16idvendor;__u16idproduct;__u16bcddevice_lo;__u16bcddevice_hi;/* used for device class matches */__ u8bdeviceclass;__u8bdevicesubclass;__u8bdeviceprotocol;/* used for interface class matches */__u8binterfaceclass;__ u8binterfacesubclass;__u8binterfaceprotocol;/* not matched against */kernel_ulong_tdriver_info;};
These device information will be mentioned above the USB bus to match the corresponding driver, only the information here and USB device driver over there to collect the device information matching, will be called into this driver.
Current id_table:
static const struct USB_DEVICE_ID usbtouch_devices[] = {#ifdef Config_touchscreen_usb_egalax/ * Ignore the HID capabl e devices, handled by Usbhid * /{Usb_device_hid_class (0x0eef, 0x0001),. Driver_info = Devtype_ignore}, {usb_ Device_hid_class (0x0eef, 0x0002),. Driver_info = Devtype_ignore},... #endif ...};
Where you can see two-byte hexadecimal digits, the first represents the Idvendor vendor Id,idproduct Product ID, which is typically identified as a device.
Driver_info:
As in the array above usbtouch_devices , Driver_info is set to the enumeration value:
/* Device types */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,};
So where are the real info of these driver stored? At the time of registration, it's just a sign up for an enumerated number.
These enumeration values work when a device is actually recognized! In the following Usbtouch_probe will be introduced!
Usbtouch_probe:
There is a slight mention in front of how the Usbtouchscreen driver is mapped to, and this process is not done in depth, as the first access point in this driver is usbtouch_probe.
static int usbtouch_probe (struct usb_interface *intf, const struct usb_device_id *id) {struct USBTOUCH_USB *usbtouch; Usbtouch equipment struct Input_dev *input_dev; Input device struct usb_endpoint_descriptor *endpoint; USB endpoint struct Usb_device *udev = Interface_to_usbdev (intf); Obtain the corresponding device struct Usbtouch_device_info *type from USB interface; This is the true driver info mentioned above endpoint = Usbtouch_get_input_endpoint (intf->cur_altsetting); Gets the endpoint if (!endpoint) Return-enxio; Usbtouch = kzalloc (sizeof (struct USBTOUCH_USB), gfp_kernel); Input_dev = Input_allocate_device (); Allocate memory, request input device structure ... type = &usbtouch_dev_info[id->driver_info]; Here is the enumeration value mentioned above, the real info is placed in this array! ... usbtouch->irq = usb_alloc_urb (0, Gfp_kernel); A URB is assigned to the data that is used to obtain the touch events returned by the touchscreen device, and the URB concept can refer to the USB driver if (!USBTOUCH->IRQ) {dbg ("%s-usb_alloc_urb Failed:usb Touch->irq ", __func__); Goto Out_free_buffers; }...//down are some allocated memory, input registration, initialization operation INput_dev->evbit[0] = Bit_mask (Ev_key) | Bit_mask (Ev_abs); Here is the input device touch coordinates initialization assignment, for ABS absolute coordinates 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 (usb_endpoint_type (endpoint) = = U Sb_endpoint_xfer_int) usb_fill_int_urb (USBTOUCH->IRQ, Udev, Usb_rcvintpipe (Udev, ENDPOINT->BENDPO intaddress), Usbtouch->data, Type->rept_size, Usbtouch_irq, Usbtouch, Endpoint->binterval ); else Usb_fill_bulk_urb (USBTOUCH->IRQ, Udev, Usb_rcvbulkpipe (Udev, endpoint->bendpointaddress), Usbtouch->data, Type->rept_size, USBTOUCH_IRQ, Usbtouch); The callback function for initializing URB is USBTOUCH_IRQ usbtouch->irq->dev = Udev; USBTOUCH->IRQ->TRANSFER_DMA = usbtouch->data_dma; Usbtouch->irq->transfer_flags |=Urb_no_transfer_dma_map, ...}
Usbtouch_device_info:
This is an info array of the drive modules extracted from the above Driver_info and Usbtouch_probe, and the different Usbtouchscreen registers an enumeration value, which is the value of Usbtouch_dev_info the first element of the array.
struct Usbtouch_device_info {int min_xc, MAX_XC; int MIN_YC, MAX_YC; int min_press, max_press; int rept_size; /* * Always service the USB devices IRQ No just when the-input device is * open. This was useful when devices had a watchdog which prevents us * from periodically polling the device. Leave this unset unless your * touchscreen device requires it, as it does consume more of the the USB * bandwidth. */bool Irq_always; void (*PROCESS_PKT) (struct Usbtouch_usb *usbtouch, unsigned char *pkt, int len); This function pointer is used to receive processing interrupts. /* * Used to get the packet len. Possible return values: * > 0:packet len * = 0:skip One Byte * < 0:-return value more bytes needed */INT (*get_pkt_len) (unsigned char *pkt, int len); Int (*read_data) (struct Usbtouch_usb *usbtouch, unsigned char *pkt); Int (*alloc) (struct USBTOUCH_USB *usbtouch); Int (*init) (struct USBTOUCH_USB *usbtouch); void (*exit) (struct USBTOUCH_USB *usbtouch);};
Usbtouch_dev_infoArray:
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 = +, . Process_pkt = usbtouch_process_multi,//is used to interrupt the callback function to handle interrupts, get input event, upload data . get_ Pkt_len = Egalax_get_pkt_len, . Read_data = egalax_read_data,//For interrupt callback function, for reading 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 ...};
You can see that the members of this array are distinguished by the previously mentioned registered enumeration values! These x, y parameters and callback functions are extracted from the usbtouch_probe mentioned above.
USBTOUCH_IRQ:
This function, as an interrupt response function, is initialized in the above Usbtouch_probe to see the main implementation of the function:
static void Usbtouch_irq (struct urb *urb) {... USBTOUCH->TYPE->PROCESS_PKT (Usbtouch, Usbtouch->data, urb->actual_length); This type is Usbtouch_device_info, when the PROCESS_PKT pointer naturally points to the corresponding function above, if this is the trigger device type is Devtype_egalax, then call the Usbtouch_ process_multi//If this is Devtype_irtouch then execute the USBTOUCH_PROCESS_PKT function, because usbtouch_probe://If (!type->process_ PKT)// type->process_pkt = usbtouch_process_pkt; ...}
The next one is called to Usbtouch_process_pkt, read by Type->read_data, with the same pointer as above, and then call Input_report_key Send, Input_sync for synchronization.
The driver section on Usbtouchscreen is analyzed here.
LINUX/ANDROID--USB Touch Screen Driver-Usbtouchscreen