Kmdf Hid Minidriver For Touch I2c Device Calibration Link
In most cases, hidi2c.sys is sufficient. However, it does NOT support custom calibration. It forwards raw HID reports directly from the I2C device to the HID class driver. To inject calibration, we must replace or layer our own KMDF HID Minidriver.
Most I2C touch controllers assert an interrupt GPIO when data is ready. In KMDF, you create a passive-level interrupt:
WDF_INTERRUPT_CONFIG interruptConfig;
WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, TouchCalibEvtInterruptIsr, TouchCalibEvtInterruptDpc);
interruptConfig.PassiveHandling = TRUE; // Allows I2C calls
WdfInterruptCreate(Device, &interruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &Interrupt);
In the DPC (Deferred Procedure Call), you: kmdf hid minidriver for touch i2c device calibration
Example submission:
NTSTATUS SendHidReport(WDFDEVICE Device, HID_TOUCH_REPORT *report) WDFMEMORY memory; WDF_MEMORY_DESCRIPTOR memDesc;WdfMemoryCreatePreallocated(WDF_NO_OBJECT_ATTRIBUTES, report, sizeof(HID_TOUCH_REPORT), &memory); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, report, sizeof(HID_TOUCH_REPORT)); return HidDevice_SubmitInterruptReadReport(Device, &memDesc);
NTSTATUS GetInputReport(WDFDEVICE Device, PVOID ReportBuffer, ULONG BufferLength) // 1. Raw read from I2C BYTE rawReport[64]; NTSTATUS status = I2CReadRawData(Device, rawReport, sizeof(rawReport)); if (!NT_SUCCESS(status)) return status;// 2. Apply calibration (depends on report format) PTOUCH_REPORT pReport = (PTOUCH_REPORT)rawReport; for (int i = 0; i < pReport->ContactCount; i++) ApplyCalibration(&pReport->Contacts[i].X, &pReport->Contacts[i].Y, &g_Calibration); // 3. Copy to output RtlCopyMemory(ReportBuffer, rawReport, min(BufferLength, rawReportSize)); return STATUS_SUCCESS;
Many touch controllers use a command-based interface: In most cases, hidi2c
| Command | I2C Opcode | Description | |---------|------------|-------------| | CALIB_ENTER | 0x55 0xAA | Enter calibration mode | | CALIB_WRITE | 0x10 | Write calibration block (address + data) | | CALIB_READ | 0x11 | Read calibration block | | CALIB_VERIFY | 0x12 | Compute and verify checksum | | CALIB_EXIT | 0x55 0xCC | Exit to normal mode |
| Type | Method | Data Source | |------|--------|--------------| | Static offset | X' = X * a + b | Factory stored in registry | | Bilinear mapping | 2x2 transform matrix | User-guided calibration | | Temperature drift | Linear interpolation | On-die sensor read via I²C | | Noise baseline | Per-node delta | Initial reading after reset | In the DPC (Deferred Procedure Call), you: