If every fifth touch input doesn't work, read this. https://github.com/Goshin/VoodooI2CHID/commit/d729e26a124432d7fdc1758eb446c118a06c34c9.


The problem with comet lake cpu's I2C controllers is, that I2C0 controller won't go to D0 state just by calling enablePCIPowerManagement as intended by VoodooI2CPCIController::configurePCI() . The trick here is to force enable D0 power management mode via directly editing the pci configuration space.

  1. Download any linux distro (ubuntu preferred) live usb and boot with it.

  2. type sudo lspci -vv and find your I2C* device. It will say something like

00:15.0 Class 0c80: Device 8086:02e8
	Subsystem: Device 1d05:107a
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0, Cache Line Size: 64 bytes
	Interrupt: pin A routed to IRQ 16
	Region 0: Memory at 7f9311c000 (64-bit, non-prefetchable)
	Capabilities: [80] Power Management version 3
		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
		Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: [90] Vendor Specific Information: Len=14 <?>

Important part is Capabilities: [80] Power Management version 3 . It means that configuration for touchpad power is stored at offset 0x80 of this device's PCI configuration space.

<aside> 💡 pci configuration space stores various preference values of pci device.

</aside>

After configurePCI has been called, we manually modify the pci config space to enable D0 mode like the code below. Here we modify 16bit word from 0x84 = 0x80 + 0x4. (0x4 is a fixed value. 0x80 may be different for i2c bus by bus. Patch VoodooI2CController.cpp like this.

void VoodooI2CPCIController::configurePCI() {
    IOLog("%s::%s Set PCI power state D0\\n", getName(), physical_device.name);
    auto pci_device = physical_device.pci_device;
    pci_device->enablePCIPowerManagement(kPCIPMCSPowerStateD0);

    // Let's play hack. Force D0 here
    // Modify 0x80 below to your findings
    uint16_t oldPowerStateWord = pci_device->configRead16(0x80 + 0x4);
    uint16_t newPowerStateWord = (oldPowerStateWord & (~0x3)) | 0x0;
    // Modify 0x80 below to your findings.
    pci_device->configWrite16(0x80 + 0x4, newPowerStateWord);

    pci_device->setBusMasterEnable(true);
    pci_device->setMemoryEnable(true);
}

Compile VoodooI2C with the patched code and inject it with CLOVER/OC. After that you can follow the normal I2C installation guide, like pinning interrupts or using polling mode.