A codeless kext (one Info.plist, no binary) that lets VoodooI2C drive the I2C controllers of Intel's Arrow Lake-HX / 800-series PCH (8086:7F4C to 7F4F), so an I2C touchpad on those laptops works in macOS. VoodooI2C 2.9.1 only matches Sunrise Point, Cannon Lake, Comet Lake and Ice Lake controller IDs; this adds a personality for the Arrow Lake ones with the right timing values and the controller class that wakes the device from D3hot.
Written for a Lenovo Legion 5 15IAX10, whose ELAN06FA touchpad (PNP0C50, ACPI \_SB.PC02.I2C1.TPD0) sits on I2C1 = 8086:7F4D.
| What | Tested on | Result |
|---|---|---|
Touchpad ELAN06FA on 8086:7F4D |
Legion 5 15IAX10, VoodooI2C 2.9.1 + VoodooI2CHID, macOS 15.8.1 and 26.7.1 (25G241), OpenCore 1.0.8 | pointer, tap, two-finger scroll working daily since 2026-10-16; interrupt polled (-vi2c-force-polling), see below |
- It needs
-vi2c-force-polling: VoodooGPIO has no community data for the Arrow Lake GPIO controllers (INTC1082/INTC1084), so the touchpad interrupt cannot be routed and VoodooI2C polls instead. That costs a little CPU and latency; it does not affect how the pad feels here. - It only matches the controller. Your touchpad still needs the right VoodooI2C satellite (VoodooI2CHID for
PNP0C50HID-over-I2C devices) and an ACPI_STAthat says the device is present under Darwin. - Tested on one laptop and one controller revision.
-
Install VoodooI2C 2.9.1 (with its VoodooGPIO and VoodooI2CServices plugins) and VoodooI2CHID the usual way. If VoodooPS2 is also loaded, load only one copy of VoodooInput.
-
Copy
LegionI2CArrowLake.kexttoEFI/OC/Kexts/and add it toconfig.plist,Kernel > Add, after VoodooI2C and VoodooI2CHID:BundlePath LegionI2CArrowLake.kext ExecutablePath (empty) PlistPath Contents/Info.plist MinKernel (empty) MaxKernel (empty) Enabled true -
Add
-vi2c-force-pollingtoboot-args. -
Reboot and check:
ioreg -r -c VoodooI2CPCILakeController -l -w0 | grep -E 'IOPCIMatch|I2CClkRate|COMP' ioreg -r -c VoodooI2CHIDDevice | head -
Rollback: set
Enabledto false. It has no code, so the worst case is a touchpad that stays dead.
| Key | Value | Where it comes from |
|---|---|---|
IOPCIMatch |
0x7f4c8086&0xFFFCFFFF |
matches 7F4C, 7F4D, 7F4E, 7F4F |
IOClass |
VoodooI2CPCILakeController |
the VoodooI2C controller class that forces the function to D0 through PMCSR before touching it |
I2CClkRate |
133000000 | Linux intel-lpss-pci.c, bxt_i2c_info for these IDs |
I2CSdaHoldTimeNs |
42 | same |
I2CSdaFallingTimeNs |
171 | same |
I2CSclFallingTimeNs |
208 | same |
IOProbeScore |
9999 | above VoodooI2C's own personalities, which do not match anyway |
VoodooI2C's controller personalities carry the clock and timing values per PCH generation and name a controller class. Linux gives the Arrow Lake-HX LPSS I2C functions the same bxt_i2c_info timing table as Ice Lake (0x34E8), so the Ice Lake values are copied. The first version used the plain VoodooI2CPCIController class and failed: the firmware leaves the controller in D3hot, every register read returned 0xffffffff (COMP_TYPE included), and VoodooI2C gave up. The VoodooI2CPCILakeController class writes the PMCSR (capability 0x80) to bring the function to D0 first, which is what 1.1.0 changed. More in docs/HOW-IT-WORKS.md.
- VoodooI2C (alexandred and contributors, GPL-2.0): the driver this plugs into.
- Linux
drivers/mfd/intel-lpss-pci.c: the device IDs and timing table.
The Info.plist is ISC (see LICENSE). VoodooI2C itself is GPL-2.0 and is not included here.