ASUS ExpertBook CX54 Chromebook Plus touchpad issue

SCREEBO (ASUS Chromebook CX54): ELAN0000 touchpad fails coreboot detect under Full ROM — stock ROM shows it needs a power/reset GPIO that the MrChromebox build doesn’t drive

System

Device ASUS Chromebook Plus CX54 (SCREEBO, Rex / Meteor Lake)
Firmware coreboot / MrChromebox-2603.2, release date 05/17/2026, 32 MiB ROM
OS Fedora Workstation 44
Kernel 7.1.3-200.fc44.x86_64
WP disable / flash method SuzyQable + CCD

Everything else on this board works: display, keyboard, Wi-Fi, audio (after chromebook-linux-audio), USB, camera, touchscreen. An external USB mouse is fine. The internal touchpad is completely absent — no input device, nothing in libinput list-devices, no i2c-hid binding, no I²C client created.

The touchpad worked normally under ChromeOS before conversion.

New account, so I can’t attach files — logs are pasted inline. Happy to send the full 1548-line cbmem -c, the SSDT disassembly, or anything else on request.

Summary

This is not an ACPI table bug, which is where I started. The ACPI generator behaves correctly. The problem is upstream of it:

  1. fw_config selects the 0x15 touchpad and disables the 0x10 alternate.

  2. coreboot enables the 0x15 device.

  3. coreboot runs its detect probe at 0x15 — no response.

  4. Because drivers/i2c/generic omits undetected touchpads from the SSDT (documented behavior), no device node is emitted.

  5. Linux therefore has nothing to bind i2c-hid to.

The missing SSDT entry is a symptom. The root cause is that nothing answers at 0x15.

I have not been able to determine which I²C bus the touchpad is on, and there’s an anomaly around I2C2 that I think is the most interesting thing in this report. Details in §2 and §6.

Evidence

1. coreboot console (cbmem -c)

Filtered with grep -iE 'i2c|tpad|touchpad|detect|elan|probe|not present'. These are the relevant lines, not a contiguous region:

[INFO ]  I2C: 00:10 disabled by fw_config
[INFO ]  PCI 15.2, PIN C, using IRQ #29
[DEBUG]  I2C: 00:1a enabled
[DEBUG]  I2C: 00:41 enabled
[DEBUG]  I2C: 00:10 disabled
[DEBUG]  I2C: 00:15 enabled
[DEBUG]  I2C: 00:50 enabled
[DEBUG]  I2C: 00:36 enabled
[DEBUG]  I2C: 00:50 enabled
[DEBUG]  I2C bus 0 version 0x3230322a
[INFO ]  DW I2C bus 0 at 0x814ea000 (400 KHz)
[DEBUG]  I2C bus 1 version 0x3230322a
[INFO ]  DW I2C bus 1 at 0x814e9000 (400 KHz)
[DEBUG]  I2C bus 3 version 0x3230322a
[INFO ]  DW I2C bus 3 at 0x814e8000 (400 KHz)
[DEBUG]  I2C bus 4 version 0x3230322a
[INFO ]  DW I2C bus 4 at 0x814e6000 (400 KHz)
[DEBUG]  I2C bus 5 version 0x3230322a
[INFO ]  DW I2C bus 5 at 0x814e5000 (400 KHz)
[INFO ]  Probing TPM I2C: done! DID_VID 0x504a6666
[DEBUG]  GSC TPM 2.0 (i2c 4:0x50 id 0x504a)
[INFO ]  \_SB.PCI0.I2C0.RT58: Headset Codec at I2C: 00:1a
[INFO ]  \_SB.PCI0.I2C1.H041: ILITEK Touchscreen at I2C: 00:41
[INFO ]  \_SB.PCI0.I2C4.TPMI: I2C TPM at I2C: 00:50
[INFO ]  \_SB.PCI0.I2C5.CAM0: Intel MIPI Camera Device at I2C 0x36

The 0x15 device is enabled but never emitted as an SSDT node. Four devices get nodes; the touchpad is not among them.

2. Two things I can’t explain

(a) PCI 15.2, PIN C, using IRQ #29. coreboot assigns an interrupt to the I2C2 controller during PCI enumeration. But there is no DW I2C bus 2 init line anywhere in the log, and 00:15.2 does not appear in lspci on the booted system. Something brought that function far enough along to allocate an IRQ, and then it ended up disabled. Every other enabled SerialIO controller (0, 1, 3, 4, 5) gets a DW I2C bus N at 0x... (400 KHz) line. I2C2 gets an IRQ and nothing else.

(b) Which bus is the touchpad on? The I2C: 00:15 enabled line doesn’t say. The 00: prefix isn’t a bus number — the codec on I2C0 logs as 00:1a and the TPM on I2C4 logs as 00:50. So 00: appears to be a devicetree link index, not the controller.

That leaves two candidates, and I can’t distinguish them from a running system:

  • Touchpad on I2C3 (Linux i2c-2, PCI 00:15.3) — the controller is up at 400 kHz, but the bus is completely silent (§3).

  • Touchpad on I2C2 (PCI 00:15.2) — the controller allocated an IRQ, was never initialized, and is absent from PCI. If the touchpad lives here, nothing in Linux could ever see it, and detect would have run against a dead controller.

Given (a), I lean toward I2C2, but I’d rather present the anomaly than assert a conclusion.

3. Bus 3 (Linux i2c-2) is enumerated and completely silent

$ sudo i2cdetect -y -r 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Nothing at 0x15. Nothing anywhere. Interrupt counters:

$ grep -i i2c /proc/interrupts
  27:  ...       ... i2c_designware.0, idma64.0
  28:  ... 1122124 ... i2c_designware.1, idma64.1     <- touchscreen, climbing
  30:  ...       0 ... i2c_designware.2, idma64.2     <- SoC I2C3, zero since boot
  31:  ...  134816 ... i2c_designware.3               <- TPM
  32:  ...       0 ... i2c_designware.4
  99:  ...   17781 ... cr50_i2c

4. Instantiated I²C devices match the SSDT exactly

$ ls -l /sys/bus/i2c/devices/
i2c-RTL5682:00  -> .../0000:00:15.0/i2c_designware.0/i2c-0/   # codec
i2c-ILTK0001:00 -> .../0000:00:15.1/i2c_designware.1/i2c-1/   # touchscreen
i2c-GOOG0005:00 -> .../0000:00:19.0/i2c_designware.3/i2c-3/   # Ti50 TPM
i2c-OVTI08F4:00 -> .../0000:00:19.1/i2c_designware.4/i2c-4/   # camera

Four devices, four SSDT nodes.

5. PCI enumeration — 00:15.2 is absent

$ lspci -nn | grep -i 'serial bus'
00:15.0 Serial IO I2C Controller #0 [8086:7e78]
00:15.1 Serial IO I2C Controller #1 [8086:7e79]
00:15.3 Serial IO I2C Controller #3 [8086:7e7b]
00:19.0 Serial IO I2C Controller #4 [8086:7e50]
00:19.1 Serial IO I2C Controller #5 [8086:7e51]

The DSDT still declares Device (I2C2) with _ADR 0x00150002 (SoC boilerplate), but the PCI function is gone.

6. GPP_H pad modes — several I²C-capable pads are in GPIO mode

$ sudo grep -iE 'GPP_H' /sys/kernel/debug/pinctrl/INTC1083:00/pins
pin 103 (GPP_H_0)  GPIO   0x44000300 0x00024018 [ACPI]
pin 104 (GPP_H_1)  GPIO   0x44000300 0x00024019 [ACPI]
pin 105 (GPP_H_2)  GPIO   0x44000300 0x0002401a [ACPI]
pin 106 (GPP_H_3)  GPIO   0x44000300 0x0000001b [ACPI]
pin 107 (GPP_H_4)  GPIO   0x44000300 0x0002401c [ACPI]
pin 108 (GPP_H_5)  GPIO   0x44000300 0x0002401d [ACPI]
pin 109 (GPP_H_6)  mode 1 0x00000402 0x0000001e [LOCKED, ACPI]
pin 110 (GPP_H_7)  mode 1 0x00000402 0x0000001f [LOCKED, ACPI]
pin 111 (GPP_H_8)  mode 1 0x40000402 0x00000020 [ACPI]
pin 112 (GPP_H_9)  mode 1 0x40000400 0x00000021 [ACPI]
pin 113 (GPP_H_10) GPIO   0x04000102 0x00024022 [LOCKED]
pin 114 (GPP_H_11) GPIO   0x44000300 0x00024023 [ACPI]
pin 115 (GPP_H_12) GPIO   0x44000300 0x00000024 [ACPI]
pin 117 (GPP_H_14) GPIO   0x84000201 0x00000026 [ACPI]
pin 118 (GPP_H_15) GPIO   0x44000300 0x00024027 [ACPI]
pin 119 (GPP_H_16) mode 1 0x40000400 0x00000028 [ACPI]
...

Note pin 116 / GPP_H_13 is absent from the listing entirely.

Exactly two adjacent pairs in this bank are in native function mode: (H_6, H_7) and (H_8, H_9) — and I have exactly two working I²C buses whose pads must be native (I2C0 codec, I2C1 touchscreen). H_10 through H_15 are all GPIO.

I don’t know Meteor Lake’s pad-to-SerialIO mapping and don’t want to guess it. But if the controllers map to consecutive pad pairs here, the pads for I2C2 and I2C3 are not in native function mode — which would explain a controller that’s up with nothing driven on the wires. Someone with the SoC pad map can confirm or kill this in seconds.

7. The touchscreen’s SSDT node, for comparison

The generator works correctly when a device is detected:

Scope (\_SB.PCI0.I2C1)
{
    Device (H041)
    {
        Name (_HID, "ILTK0001")
        Name (_CID, "PNP0C50")
        Name (_DDN, "ILITEK Touchscreen")
        Method (_STA, 0, NotSerialized) { Return (0x0F) }
        Name (_CRS, Buffer (0x002C) { ... })   // I2cSerialBusV2 0x41, 400kHz, \_SB.PCI0.I2C1
                                               // Interrupt: IRQ 55, Level, ActiveLow
        Name (_PR0, Package (0x01) { PR00 })
        PowerResource (PR00, 0x00, 0x0000)
        {
            Method (_ON, 0, Serialized)
            {
                \_SB.PCI0.CTXS (0xEC)
                \_SB.PCI0.STXS (0xDD)
                Sleep (0x0C)
                \_SB.PCI0.STXS (0xEC)
                Sleep (0xC8)
            }
            ...
        }
    }
}

What I ruled out

Not an ACPI generation bug. The SSDT is internally consistent: exactly the four detected devices, all correctly formed.

Not fixable with an SSDT override. The device doesn’t ACK, so i2c-hid cannot read the HID descriptor even with a hand-written node.

Not an EC-gated power rail. All 75 cros-ec-gpio lines are named, none relate to the touchpad — they cover fans, USB-C retimers, LEDs, keyboard backlight, rails, and the FP sensor:

gpiochip1 [cros-ec-gpio.3.auto]  (67 lines)
gpiochip2 [cros-ec-gpio.12.auto] (8 lines)  — ap_ec_int_l, write-protect, fp_sensor_sel, slp_l, ...

Probably not a missing SoC enable/reset GPIO. The touchscreen has one (hence its PowerResource); trackpads on this platform generally don’t.

Stock ROM analysis (the important part)

I extracted fallback/ramstage and fallback/dsdt.aml from the COREBOOT region of my pre-flash stock backup (cbfstool ... extract) and compared against the running MrChromebox firmware.

Same touchpad, both firmwares. Stock ramstage’s devicetree string table contains ELAN0000 / ELAN Touchpad — the identical part MrChromebox’s fw_config selects and enables (I2C: 00:15 enabled). So device selection is not the problem; both agree on an ELAN0000 at 0x15.

Stock power-sequences its I²C-HID devices. The stock ramstage contains the coreboot I²C-generic driver machinery for enable/reset GPIOs:

%s: Enable and/or Reset GPIO required for %s.
reset-gpio
reset-gpios
enable-gpios
irq-gpios
src/soc/intel/common/block/gpio/gpio.c

Interpretation. The ELAN touchpad on this board is behind an enable/reset GPIO. Stock firmware drives it; the MrChromebox SCREEBO build appears not to (either the enable/reset GPIO is absent from the touchpad’s devicetree entry, or the relevant pad isn’t configured to its native/output state in gpio.c). The result: the ELAN part is never powered up, never ACKs at 0x15, and detect correctly drops it from the SSDT.

This lines up with the pinctrl dump above — several GPP_H pads that would carry I²C or an enable line read as plain GPIO mode on the running system.

What I could not extract. The specific pad number for the touchpad’s enable/reset line lives in a compiled pad_config struct with no string, and I couldn’t reliably locate it in the stripped ramstage without the SCREEBO headers. That’s the one piece a maintainer with the source tree can read directly. I’m happy to send the extracted stock-ramstage.elf and stock-dsdt.aml, or the whole stock ROM, for that comparison.

Questions

  1. Is SCREEBO touchpad detection known-broken in current Full ROM builds? (Mine is 2603.2 / 05-17-2026.)

  2. Which SerialIO controller is the SCREEBO touchpad on — I2C2 or I2C3?

  3. Why does PCI 15.2 get an IRQ assignment but never a bus init, and end up absent from PCI? Is I2C2 intentionally disabled in the devicetree for this variant?

  4. Are the GPP_H pads for I2C2/I2C3 supposed to be PAD_CFG_NF in screebo/gpio.c? They read as GPIO mode on my system.

  5. Does the SCREEBO devicetree entry for the ELAN0000 touchpad include its enable/reset GPIO, and is that pad configured in the Full ROM gpio.c? Stock ramstage carries the enable/reset-GPIO machinery; this seems the most likely divergence.

  6. Is there a test build I could flash and report back on?

I still have my pre-flash stock ROM backup and can restore it, boot ChromeOS, and dump stock cbmem -c + ACPI tables for a diff if that would be useful. Happy to test builds, probe buses, or dump anything else.

Thanks for all the Meteor Lake work — the rest of this machine runs great.

@MrChromebox Given the stock ramstage carries enable/reset-GPIO handling for the ELAN0000 and the Full ROM build doesn’t seem to, is the touchpad’s enable GPIO missing from SCREEBO’s overridetree? Happy to send the stock ROM

I get that LLM’s are fancy new tools and everyone thinks they are helpful, but in this case you’ve outsourced the debugging to something that doesn’t know 2+2, and handed me a pile of shit.

I don’t accept your LLM-generated analysis as correct, because I know you didn’t verify it (also I know it’s wrong, there are no reset or enable GPIOs specifically for the touchpad - if there were, they would be defined in gpio.c and the override devicetree). I can also tell from the questions it’s asking that you didn’t point it at the MrChromebox or stock source, both of which are readily available. The touchpad is on i2c-3 BTW. And you can easily compare the programmed GPIOs (and see their functions) in the H block via the source.

Haha fair enough. And thanks for the response. I realized I must have accidentally pulled the touch trackpad harness. I pulled the back off and saw it loose which I must have done when swapping out a new SSD. Thanks for the response it was helpful