Recently to customers debugging a piece of CNC board, today customers bring a screen, and a USB touch screen chip connected to the screen. The screen will soon be ready for normal display.
Touch screen in the core to find the USB touch screen driver, the kernel started after the USB turn of the touch screen is also normal to find, registered as event interface Events event0, CAT/DEV/EVENT0, touch screen has garbled output, The USB touch screen driver is interrupted and the acquisition data is reported to the input subsystem.
Then, with a few calibration tests in my tslib, I ran and found the following error:
Selected device is not a touchscreen I understand
There is a calibration interface on the screen, but the 5 points of the calibration are instantly connected to the error end of the program.
Many attempts are the result of this, I inserted a USB mouse, to identify the production of event1, I will speak for the Tslib run settings in the environment variable Tslib device set to Event1, and then run the calibration program, and found that the phenomenon of the same as touch screen. It is said that the tslib should be fault-tolerant processing, will be based on a number of conditions to determine whether the environment variable specified by the device is a real touch screen equipment.
Think more unintentionally, or read more code, so in the Tslib source code found above this sentence from the following:
static int check_fd (struct tslib_input *i)
{
struct Tsdev *ts = i->module.dev;
int version;
u_int32_t bit;
u_int64_t Absbit;
if (! ((IOCTL (TS->FD, Eviocgversion, &version) >= 0) &&
(Version = = ev_version) &&
(IOCTL (TS->FD, eviocgbit (0, sizeof (BIT) * 8), &bit) >= 0) &&
(Bit & (1 << ev_abs)) &&
(IOCTL (TS->FD, Eviocgbit (ev_abs, sizeof (absbit) * 8), &absbit) >= 0) &&
(Absbit & (1 << abs_x)) &&
(Absbit & (1 << abs_y)) && (Absbit & (1 << abs_pressure))) {
fprintf (stderr, "Selected device is not a touchscreen I understand\n");
return-1;
}
if (Bit & (1 << Ev_syn))
I->using_syn = 1;
return 0;
}
This check_fd will be based on these conditions to determine whether to print as error.
The first condition is IOCTL get version, kernel source to find the IOCTL definition in driver/input/evdev.c, corresponding command eviocgversion defined value of 0x10000 The value defined in the input.h in the compiler is also 0x10000, and this condition is fine. I think most of the questions on the internet about this mistake are here. Unfortunately mine is not, continue to go down.
The second condition is to get the bit flag of the input device, which is whether it is a touch screen device. USB device I have not been contacted before, but according to Cat/dev/event0, there is a response to the USB part of the acquisition data is not a problem, but reported to the input subsystem out of the question, so should think of is to look at the USB Touch screen driver Registration input device part of the code, The code in the probe function in the USB touch screen driver driver/usb/input/usbtouchscreen.c is as follows:
input_dev->name = usbtouch->name;
Input_dev->phys = usbtouch->phys;
usb_to_input_id (Udev, &input_dev->id);
Input_dev->cdev.dev = &intf->dev;
input_dev->private = Usbtouch;
input_dev->open = Usbtouch_open;
input_dev->close = usbtouch_close;
Input_dev->evbit[0] = BIT (Ev_key) | BIT (Ev_abs);
Input_dev->keybit[long (btn_touch)] = BIT (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);
You can see that the EV_ABS flag bit is set in the Evbit. This second condition is also satisfied.
The third condition is to obtain a touch screen corresponding logo bit for the Absbit logo prepared for the touch-screen input device, because a touchscreen driver has been written before, so you know that the touch screen sign is x y Press, which is the coordinates and compressions.
In the Input_set_abs_params implementation is to absbit a variety of logo bits. and set the scope of the corresponding flag (min max), but this sign such as X y Press range in the back did not see the use, I also found that min max write 0 also no problem, this is a digression.
There is a problem here, max_press and min_press are not set in the devices that are enumerated in the USB touchscreen, and are 0, so the last function to set the press flag bit is not invoked.
So I appear above selected device is not a touchscreen I understand due to Absbit & (1 << abs_pressure) not satisfied.
I will comment out if judgment, and then redo the kernel start, run Tslib test program, found that there is no error on the exit, the problem is solved. I later discovered that the Min max with X y Press was not used in input_set_abs_params, even if it was set to 0.
The calibration test was run normally, but I clicked on the screen and the calibration program didn't detect my click behavior, and then I ran into this problem. Then the research is done.
Run Tslib test program did not detect the Click event, but cat/dev/event0 when the click on the screen is something to the input subsystem, which means that touch screen interruption is normal.
Write another touch screen driver when the Click event escalation coordinate data to the input subsystem is in the touch screen interrupt to do, so need to find this code to see if there is a problem, in the USBTOUCHSCREEN.C found the following code:
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);
}
This code is interrupted by the data to the input subsystem, the report key is the flag input event is pressed and bounced, and for the touch screen reported data including x y Press, this code can be seen because max_press is 0, So the interruption has not been reported to press, that is, the USB touch screen has been reported is the coordinates, but the newspaper has been 0, so the upper program will think that there is no pressure down. So no response. In the interrupt, add the print, found that the data from USB read the press value of 0, whether it is pressed or bounced, but the touch is pressed at the time is 1, bouncing up is 0, you can use this value to report to the input subsystem of the current press, the function is modified as follows:
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);
ZK Modify for USB touchpad
Input_report_abs (Usbtouch->input, Abs_pressure, 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 0
if (type->max_press)
Input_report_abs (Usbtouch->input, Abs_pressure, usbtouch->press);
#endif
Input_sync (Usbtouch->input);
}
Re-compile the kernel, start, run tslib calibration test program, you can click Normally, and Tslib program can detect touch screen data. Success..