HID over I2C Touchpad support ? - Huawei Matebook X Pro

I recently bought a Huawei Matebook X Pro. Out of the box 11.2 and 12-Current boot.
However, the touchpad and touchscreen are not even being detected at all.
I tested Ubuntu 18.04 on it as well, which detects all hardware just fine. It turns out the laptop has a Synaptic touchpad connected over I2C.

Is anyone aware if HID over I2C will come to FreeBSD any time soon ?

Yesterday I tested to add ig4_load="YES" to /boot/loader.conf. I saw in 12-Current a checking https://github.com/freebsd/freebsd/...23d36aa#diff-9344fa2ebfa6399678c352b94e7c3cb7 ( Add support for i2c controllers on Skylake and Kaby Lake ).
Loading ig4 makes a little difference, it detects an "Intel Sunrise Point-LP I2C Controller". However the initialization failed with "ig4iic_pci0: controller error during attach-2".

Anyways, I'm don't know if I'm going in the right direction here, maybe it's totally unrelated.

Looking forward to get some advice.

PS:
If someone has the same laptop. You will need to modify your acpi battery driver to get battery initialization done. FreeBSD has as of today only support for "_BIF" but this laptop does not implement that in his DSDT. Instead you want to read from "_BIX". I got some inspiration on how to implement that from here. Works. https://github.com/openbsd/src/comm...f=split#diff-0ee599c4cd860206b8d64e11374d06d1.
 
Sure. Please consider the following as a quick hack to get it work.

1. In: /usr/src/sys/dev/acpica/acpiio.h add the following struct

C:
struct acpi_bix {
    uint8_t rev;            /* BIX Revision */
    uint32_t units;            /* Units (mW or mA). */
#define ACPI_BIX_UNITS_MW    0    /* Capacity in mWh, rate in mW. */
#define ACPI_BIX_UNITS_MA    1    /* Capacity in mAh, rate in mA. */
    uint32_t dcap;            /* Design Capacity */
    uint32_t lfcap;            /* Last Full capacity */
    uint32_t btech;            /* Battery Technology */
    uint32_t dvol;            /* Design voltage (mV) */
    uint32_t wcap;            /* WARN capacity */
    uint32_t lcap;            /* Low capacity */
    uint32_t ccnt;            /* Bix cycle count */
    uint32_t accu;            /* Bix accuracy */
    uint32_t maxs;            /* Bix max sample */
    uint32_t mins;            /* Bix min sample */
    uint32_t maxa;            /* Bix max average */
    uint32_t mina;            /* Bix min average */
    uint32_t gra1;            /* Granularity 1 (Warn to Low) */
    uint32_t gra2;            /* Granularity 2 (Full to Warn) */
    char model[ACPI_CMBAT_MAXSTRLEN];    /* model identifier */
    char serial[ACPI_CMBAT_MAXSTRLEN];    /* Serial number */
    char type[ACPI_CMBAT_MAXSTRLEN];    /* Type */
    char oeminfo[ACPI_CMBAT_MAXSTRLEN];    /* OEM information */
};

2. Next, in: /usr/src/sys/dev/acpica/acpi_cmbat.c
2.1 I added a new buffer: bix_buffer
2.2 AcpiEvaluateObject will now read from _BIX and puts the result into our bix_buffer
2.3 ACPI_PKG_VALID(res, 20), we need to change that from 13 to 20 to pass the ckeck. _BIX has 20 elements.
2.4 now we need to adapt the index for the following lines, to copy the right data from the "BIX" to our "BIF" struct. E.g. "if (acpi_PkgInt32(res, 0, &sc->bif.units) != 0)" changes to if (acpi_PkgInt32(res, 1, &sc->bif.units) != 0). In "BIF" the "units" are the 1st element but in "BIX" its the 2nd. Just adapt the indexes for all the fields.

C:
static void
acpi_cmbat_get_bif(void *arg)
{
    struct acpi_cmbat_softc *sc;
    ACPI_STATUS    as;
    ACPI_OBJECT    *res;
    ACPI_HANDLE    h;
    ACPI_BUFFER    bif_buffer;
    ACPI_BUFFER    bix_buffer;
    device_t dev;

    ACPI_SERIAL_ASSERT(cmbat);

    dev = arg;
    sc = device_get_softc(dev);
    h = acpi_get_handle(dev);
    bif_buffer.Pointer = NULL;
    bif_buffer.Length = ACPI_ALLOCATE_BUFFER;
    bix_buffer.Pointer = NULL;
    bix_buffer.Length = ACPI_ALLOCATE_BUFFER;

    as = AcpiEvaluateObject(h, "_BIX", NULL, &bix_buffer);
    if (ACPI_FAILURE(as)) {
    ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
            "error fetching current battery info -- %s\n",
            AcpiFormatException(as));
    goto end;
    }

    res = (ACPI_OBJECT *)bix_buffer.Pointer;
    if (!ACPI_PKG_VALID(res, 20)) {
    ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
            "battery info corrupted\n");
    goto end;
    }

    if (acpi_PkgInt32(res, 1, &sc->bif.units) != 0)
    goto end;
    if (acpi_PkgInt32(res, 2, &sc->bif.dcap) != 0)
    goto end;
    if (acpi_PkgInt32(res, 3, &sc->bif.lfcap) != 0)
    goto end;
    if (acpi_PkgInt32(res, 4, &sc->bif.btech) != 0)
    goto end;
    if (acpi_PkgInt32(res, 5, &sc->bif.dvol) != 0)
    goto end;
    if (acpi_PkgInt32(res, 6, &sc->bif.wcap) != 0)
    goto end;
    if (acpi_PkgInt32(res, 7, &sc->bif.lcap) != 0)
    goto end;
    if (acpi_PkgInt32(res, 14, &sc->bif.gra1) != 0)
    goto end;
    if (acpi_PkgInt32(res, 15, &sc->bif.gra2) != 0)
    goto end;
    if (acpi_PkgStr(res,  16, sc->bif.model, ACPI_CMBAT_MAXSTRLEN) != 0)
    goto end;
    if (acpi_PkgStr(res, 17, sc->bif.serial, ACPI_CMBAT_MAXSTRLEN) != 0)
    goto end;
    if (acpi_PkgStr(res, 18, sc->bif.type, ACPI_CMBAT_MAXSTRLEN) != 0)
    goto end;
    if (acpi_PkgStr(res, 19, sc->bif.oeminfo, ACPI_CMBAT_MAXSTRLEN) != 0)
    goto end;

end:
    if (bix_buffer.Pointer != NULL)
    AcpiOsFree(bix_buffer.Pointer);
    if (bif_buffer.Pointer != NULL)
    AcpiOsFree(bif_buffer.Pointer);
}

3. Buid the kernel
3.1 Create a new kernel configuration: touch /usr/src/sys/amd64/conf/BATTERY
3.2 open the file and add:
Code:
include GENERIC
3.2 build the kernel make [B]-j16[/B] buildkernel [B]-DKERNFAST[/B] KERNCONF=BATTERY INSTKERNNAME=BATTERY
3.2.1 remove the -j16 and/or -DKERNFAST if make is complaining
3.3 install the kernel make -j16 installkernel -DKERNFAST KERNCONF=BATTERY INSTKERNNAME=BATTERY
3.4 make your new kernel boot by default if you want: in /boot/loader.conf
Code:
kernel=BATTERY

Thats it.
Now your battery should show up.
JFYI: I don't make use of all the extra fields in BIX. Making this work is a whole lot more work.
The moment you change the old acpi_bif struct, some programs which call into ACPIA will fail. E.g. "upower -d" and such.

However, I would be happy if you want to find a proper solution.
Also, my battery never shows 100% charged. At max it shows around 99 %. Not sure why. It could be my workaround has a bug or anything else. I just had no time to look into this.

I tested with 11.2 and 12 Current. Both worked.

Just curious. You also have the Matebook X Pro ?
I would love to partner up to find solutions for all the other issues. ( Touchpad and Nvidia card namely )
Let me know if you have other issues. I could share some of my tweeks.

I hope it works for you.

cu
Daniel
 
Back
Top