Ilitek multi-touch disable

Hello Toradex Team,

I’m using imx8mm with dahlia board, DSI display adaptor and 5.15.148-6.6.0-devel+git.23a8e831749d. The touch controller is a ilitek_i2c_ts standard driver with multi-touch.
The problem we’re facing is when using UI tauri it works well, except when is zoomed with 2 fingers. The App does not need the zoom, but sometimes the client by mistake make the zoom, the App gets zoomed out, and the CPU goes to 100% and hangs.
From what we’ve searched it seems in our version of tauri is not possible to disable zoom, so we are trying other alternatives such as disabling multi-touch on the ilitek driver (long shot)
Is this possible at all? For example, I’m guessing a resistive touch-screen we would not have this issue because only have one-touch point, but probably changing the driver and make it one-touch could solve the problem.

EDIT: Changing the ILITEK_SUPPORT_MAX_POINT from 40 to 1 can do the trick?
#define ILITEK_SUPPORT_MAX_POINT 40

Regards

Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


:handshake:

To disable multi-touch on the Ilitek touch controller driver, you can modify the driver to report only single-touch events. This involves changing the driver code to ignore additional touch points beyond the first one. Here are the general steps you can follow:

  1. Locate the Driver Source Code: Find the source code for the ilitek_i2c_ts driver. This is typically located in the kernel source tree under drivers/input/touchscreen/.

  2. Modify the Driver: Edit the driver code to limit the touch points reported. You will need to modify the part of the code that handles touch events. Specifically, you can change the code to only process the first touch point and ignore others.

  3. Rebuild the Kernel: After modifying the driver, you will need to rebuild the kernel and install the new kernel on your device.

Here is a simplified example of what the modification might look like in the driver code:

// Example modification in the driver code
static void ilitek_report_touch(struct ilitek_ts_data *ts, int id, int x, int y, int pressure)
{
    if (id == 0) { // Only process the first touch point
        input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
        input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
        input_report_abs(ts->input_dev, ABS_MT_PRESSURE, pressure);
        input_mt_sync(ts->input_dev);
    }
}
  1. Deploy the New Kernel: Once the kernel is rebuilt, deploy it to your device and test to ensure that only single-touch events are being reported.

This approach should help you avoid the zoom issue by effectively turning your multi-touch screen into a single-touch screen.

Best regards, Toradex AI Assistant

Hi @peterz !

Before digging into driver modification (which will generate more maintenance work in the long run), have you checked if you can disable multi-touch support on Weston?

https://man.archlinux.org/man/weston.ini.5

To be honest I never heard about Tauri :sweat_smile: Quickly going through its Github, version 2.0.0-beta.12 added something related to zoom. Couldn’t you try to use this version (or newer) to check how/if this can help you?

Btw, this is an interesting read related to how things work from libinput point of view :slight_smile:

https://wayland.freedesktop.org/libinput/doc/latest/gestures.html#touchscreen-gestures

Let us know if any of this helps :smiley:

Best regards,

Hello @henrique.tx ,
I’ve been there and it seems no solution in the weston configs.
Also, for tauri the version 2.0 only alows to set a zoom, but not to disable the pinch-zoom.

Hi @peterz

I tend to agree with you. But, to be honest, if I were you, I would just actually try to check the configurations there before modifying the driver.

I would even first try to modify the framework source code instead of modifying the driver.

Have you tried to get in touch with the framework developers asking for help on how to disable gestures/multi-touch support? They might be interested in your use case as a feature/configuration for their framework.

Best regards,

Hi @peterz !

Do you have any news here?

I am curious about the approach you will take. :slight_smile:

Best regards,

Hello @henrique.tx ,
Yes, I changed the driver, all the other options were infeseable or take too much time.
We cannot rely on the good will of an open source project to add a new feature, that usually takes a lot of time, and changing the driver was rather easier and did the trick.

Hi @peterz !

Thanks for the feedback.

Yesterday I tried to manipulate how libinput interprets the touch of Capacitive Touch Display 10.1" DSI | Toradex Developer Center by creating a udev rule to modify the ENV{ID_INPUT_*} of the display.

Reference: Static device configuration via udev — libinput 1.26.2 documentation

The udev rule was something like this:

SUBSYSTEM=="input", ENV{ID_PATH}=="platform-30a30000.i2c", ENV{ID_INPUT_TOUCHSCREEN}="", ENV{ID_INPUT_TABLET}="1"

I tried with ID_INPUT_MOUSE, ID_INPUT_TOUCHPAD, and ID_INPUT_TABLET, but none of them helped as libinpit fails to recognize the device with some error like this:

libinput list-devices
event2  - ilitek_ts: libinput bug: missing tablet capabilities: pen btn-stylus resolution. Ignoring this device.

Thanks for sharing which approach you took.

Would you perhaps be able to share how you customized the driver? It might be useful for other users :slight_smile:

I agree that waiting on them might take to long. But I meant asking them for directions on how to perform the modification you need. People on open source projects may not do it on the spot, but they’re usually very accessible and could have given you some directions/examples on how to do it. :slight_smile:

Best regards,

Hello @henrique.tx ,
Basically I just tweak the ilitek_process_and_report_v6 in the file ilitek_ts_i2c.c, then compile it as kernel module under a new name using torizoncore build kernel, then I blacklisted the old ilitek_ts_i2c module by doing:
sudo echo "blacklist ilitek_ts_i2c" > /etc/modprobe.d/ilitek_ts_i2c-blacklist.conf
and then force to load the new driver
sudo echo ilitek_ts_i2c_SINGLE_TOUCH> /etc/modules-load.d/ilitek_ts_i2c_SINGLE_TOUCH.conf
Probably there are more ways to code this but this kind of solved my problem.
Hope this helps.

static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
{
    int error = 0;
    u8 buf[512];
    int packet_len = 5;
    // int packet_max_point = 10;   // Removed as it's not needed anymore
    // int report_max_point;        // Removed as it's not needed anymore
    int i;
    struct input_dev *input = ts->input_dev;
    struct device *dev = &ts->client->dev;
    unsigned int x, y, status, id;

    error = ilitek_i2c_write_and_read(ts, NULL, 0, 0, buf, 64);
    if (error) {
        dev_err(dev, "get touch info failed, err:%d\n", error);
        goto err_sync_frame;
    }

    if (buf[0] != ILITEK_TP_I2C_REPORT_ID) {
        dev_err(dev, "get touch info failed. Wrong id: 0x%02X\n", buf[0]);
        goto err_sync_frame;
    }

    // Only process the first touch point
    status = buf[1] & 0x40;
    if (status) {
        id = buf[1] & 0x3F;
        x = get_unaligned_le16(buf + 2);
        y = get_unaligned_le16(buf + 4);

        if (x > ts->screen_max_x || x < ts->screen_min_x ||
            y > ts->screen_max_y || y < ts->screen_min_y) {
            dev_warn(dev, "invalid position, X[%d,%u,%d], Y[%d,%u,%d]\n",
                     ts->screen_min_x, x, ts->screen_max_x,
                     ts->screen_min_y, y, ts->screen_max_y);
        } else {
            ilitek_touch_down(ts, 0, x, y); // Always use ID 0 for single-touch
        }
    }

    input_mt_sync_frame(input);
    input_sync(input);
err_sync_frame:
    return error;
}

Hi @peterz !

Thanks a lot for sharing it!

Hopefully it will help others.

I marked your message above as the Solution.

Have a nice day!

Best regards,