From 5be336b326484cfc31400645757f3852f2aa5d54 Mon Sep 17 00:00:00 2001 From: Avery Black Date: Thu, 17 Oct 2024 19:00:18 -0700 Subject: [PATCH 01/11] Pass I2C HID input report and timestamp to functions --- VoodooRMI/Functions/F01.cpp | 9 +--- VoodooRMI/Functions/F01.hpp | 2 +- VoodooRMI/Functions/F03.cpp | 24 +++++----- VoodooRMI/Functions/F03.hpp | 6 +-- VoodooRMI/Functions/F11.cpp | 29 +++++++----- VoodooRMI/Functions/F11.hpp | 2 +- VoodooRMI/Functions/F12.cpp | 44 +++++++++++-------- VoodooRMI/Functions/F12.hpp | 2 +- VoodooRMI/Functions/F17.cpp | 6 +-- VoodooRMI/Functions/F17.hpp | 2 +- VoodooRMI/Functions/Input/RMIFunction.cpp | 33 ++++++++++++++ VoodooRMI/Functions/Input/RMIFunction.hpp | 4 +- VoodooRMI/Functions/Input/RMIGPIOFunction.cpp | 21 +++------ VoodooRMI/Functions/Input/RMIGPIOFunction.hpp | 4 +- .../Functions/Input/RMITrackpointFunction.cpp | 5 +-- .../Functions/Input/RMITrackpointFunction.hpp | 1 + VoodooRMI/RMIBus.cpp | 39 +++++----------- VoodooRMI/RMIBus.hpp | 3 +- VoodooRMI/Transports/I2C/RMII2C.cpp | 40 ++++++++++++----- VoodooRMI/Transports/I2C/RMII2C.hpp | 7 +-- VoodooRMI/Transports/RMITransport.hpp | 41 +++++++++-------- VoodooRMI/Transports/SMBus/RMISMBus.cpp | 3 +- 22 files changed, 184 insertions(+), 143 deletions(-) diff --git a/VoodooRMI/Functions/F01.cpp b/VoodooRMI/Functions/F01.cpp index 16a1c98..f5647de 100644 --- a/VoodooRMI/Functions/F01.cpp +++ b/VoodooRMI/Functions/F01.cpp @@ -373,17 +373,12 @@ int F01::rmi_f01_resume() return error; } -void F01::attention() +void F01::attention([[maybe_unused]] AbsoluteTime time, UInt8 *data[], size_t *size) { - int error; UInt8 device_status = 0; - error = readByte(getDataAddr(), &device_status); - - if (error) { - IOLogError("F01: Failed to read device status: %d", error); + if (!getInputData(&device_status, sizeof(device_status), data, size)) return; - } if (RMI_F01_STATUS_BOOTLOADER(device_status)) IOLogError("Device in bootloader mode, please update firmware"); diff --git a/VoodooRMI/Functions/F01.hpp b/VoodooRMI/Functions/F01.hpp index 98c805e..04bec0b 100644 --- a/VoodooRMI/Functions/F01.hpp +++ b/VoodooRMI/Functions/F01.hpp @@ -125,7 +125,7 @@ class F01 : public RMIFunction { public: bool attach(IOService *provider) override; IOReturn config() override; - void attention() override; + void attention(AbsoluteTime time, UInt8 *data[], size_t *size) override; IOReturn setPowerState(unsigned long powerStateOrdinal, IOService *whatDevice) override; diff --git a/VoodooRMI/Functions/F03.cpp b/VoodooRMI/Functions/F03.cpp index 7b8ff87..116a25d 100644 --- a/VoodooRMI/Functions/F03.cpp +++ b/VoodooRMI/Functions/F03.cpp @@ -155,7 +155,7 @@ int F03::rmi_f03_pt_write(unsigned char val) return error; } -void F03::handlePacket(UInt8 *packet) +void F03::handlePacket(AbsoluteTime time, UInt8 *packet) { RMITrackpointReport report; // Trackpoint isn't initialized! @@ -172,6 +172,7 @@ void F03::handlePacket(UInt8 *packet) timer->enable(); } + report.timestamp = time; report.buttons = (packet[0] & 0x7); report.dx = ((packet[0] & 0x10) ? 0xffffff00 : 0) | packet[1]; report.dy = -(((packet[0] & 0x20) ? 0xffffff00 : 0) | packet[2]); @@ -199,26 +200,21 @@ IOReturn F03::setPowerState(unsigned long powerStateOrdinal, IOService *whatDevi return kIOPMAckImplied; } -void F03::attention() +void F03::attention(AbsoluteTime time, UInt8 *data[], size_t *size) { - const UInt16 data_addr = getDataAddr() + RMI_F03_OB_OFFSET; - const UInt8 ob_len = rx_queue_length * RMI_F03_OB_SIZE; - UInt8 obs[RMI_F03_QUEUE_LENGTH * RMI_F03_OB_SIZE]; + const UInt8 ob_len = RMI_F03_OB_OFFSET + (rx_queue_length * RMI_F03_OB_SIZE); + UInt8 obs[RMI_F03_OB_OFFSET + (RMI_F03_QUEUE_LENGTH * RMI_F03_OB_SIZE)]; - int error = readBlock(data_addr, obs, ob_len); - if (error) { - IOLogError("F03 - Failed to read output buffers: %d", error); + if (!getInputData(obs, ob_len, data, size)) return; - } - for (int i = 0; i < ob_len; i += RMI_F03_OB_SIZE) { + for (int i = RMI_F03_OB_OFFSET; i < ob_len; i += RMI_F03_OB_SIZE) { UInt8 ob_status = obs[i]; UInt8 ob_data = obs[i + RMI_F03_OB_DATA_OFFSET]; if (!(ob_status & RMI_F03_RX_DATA_OFB)) continue; - IOLogDebug("F03 - Recieved data over PS2: %x", ob_data); if (ob_status & RMI_F03_OB_FLAG_TIMEOUT) { IOLogDebug("F03 Timeout Flag"); @@ -229,7 +225,7 @@ void F03::attention() continue; } - handleByte(ob_data); + handleByte(time, ob_data); } } @@ -296,7 +292,7 @@ void F03::initPS2Interrupt(OSObject *owner, IOTimerEventSource *timer) timer->disable(); } -void F03::handleByte(UInt8 byte) +void F03::handleByte(AbsoluteTime time, UInt8 byte) { if (!cmdcnt && !flags) { // Wait for start of packets @@ -306,7 +302,7 @@ void F03::handleByte(UInt8 byte) databuf[index++] = byte; if (index == 3) - handlePacket(databuf); + handlePacket(time, databuf); return; } diff --git a/VoodooRMI/Functions/F03.hpp b/VoodooRMI/Functions/F03.hpp index 719a5f6..38ad054 100644 --- a/VoodooRMI/Functions/F03.hpp +++ b/VoodooRMI/Functions/F03.hpp @@ -24,7 +24,7 @@ class F03 : public RMITrackpointFunction { bool start(IOService *provider) override; void stop(IOService *provider) override; IOReturn setPowerState(unsigned long powerStateOrdinal, IOService *whatDevice) override; - void attention() override; + void attention(AbsoluteTime time, UInt8 *data[], size_t *size) override; private: IOWorkLoop *work_loop {nullptr}; @@ -53,11 +53,11 @@ class F03 : public RMITrackpointFunction { int ps2DoSendbyteGated(UInt8 byte, uint64_t timeout); int ps2CommandGated(UInt8 *param, unsigned int *command); int ps2Command(UInt8 *param, unsigned int command); - void handleByte(UInt8); + void handleByte(AbsoluteTime time, UInt8); void initPS2(); void initPS2Interrupt(OSObject *owner, IOTimerEventSource *timer); - void handlePacket(UInt8 *packet); + void handlePacket(AbsoluteTime time, UInt8 *packet); }; #endif /* F03_hpp */ diff --git a/VoodooRMI/Functions/F11.cpp b/VoodooRMI/Functions/F11.cpp index dcd29ff..eb7c0a0 100644 --- a/VoodooRMI/Functions/F11.cpp +++ b/VoodooRMI/Functions/F11.cpp @@ -40,22 +40,31 @@ void F11::free() super::free(); } -void F11::attention() +void F11::attention(AbsoluteTime time, UInt8 *data[], size_t *size) { int error, abs_size; size_t fingers; UInt8 finger_state; - AbsoluteTime timestamp; - error = readBlock(getDataAddr(), data_pkt, pkt_size); - if (error < 0) { - IOLogError("Could not read F11 attention data: %d", error); - return; + if (data) { + if (*size < attn_size) { + IOLogError("F11 attention larger than remaining data"); + return; + } + + memcpy(data_pkt, *data, attn_size); + (*data) += attn_size; + (*size) -= attn_size; + } else { + error = readBlock(getDataAddr(), data_pkt, pkt_size); + + if (error < 0) { + IOLogError("F11 Could not read attention data: %d", error); + return; + } } - clock_get_uptime(×tamp); - - if (shouldDiscardReport(timestamp)) + if (shouldDiscardReport(time)) return; IOLogDebug("F11 Packet"); @@ -94,7 +103,7 @@ void F11::attention() } } - report.timestamp = timestamp; + report.timestamp = time; report.fingers = fingers; handleReport(&report); diff --git a/VoodooRMI/Functions/F11.hpp b/VoodooRMI/Functions/F11.hpp index 9af8c6f..d706356 100644 --- a/VoodooRMI/Functions/F11.hpp +++ b/VoodooRMI/Functions/F11.hpp @@ -500,7 +500,7 @@ class F11 : public RMITrackpadFunction { public: bool attach(IOService *provider) override; - void attention() override; + void attention(AbsoluteTime time, UInt8 *data[], size_t *size) override; void free() override; IOReturn config() override; diff --git a/VoodooRMI/Functions/F12.cpp b/VoodooRMI/Functions/F12.cpp index 58cbbb0..cf05964 100644 --- a/VoodooRMI/Functions/F12.cpp +++ b/VoodooRMI/Functions/F12.cpp @@ -267,22 +267,30 @@ int F12::rmi_f12_read_sensor_tuning() return 0; } -void F12::attention() +void F12::attention(AbsoluteTime time, UInt8 *data[], size_t *size) { - AbsoluteTime timestamp; - if (!data1) return; - int retval = readBlock(getDataAddr(), data_pkt, pkt_size); - - if (retval < 0) { - IOLogError("F12 - Failed to read object data. Code: %d", retval); - return; + if (data) { + if (*size < attn_size) { + IOLogError("F12 attention larger than remaining data"); + return; + } + + memcpy(data_pkt, *data, attn_size); + (*data) += attn_size; + (*size) -= attn_size; + } else { + IOReturn error = readBlock(getDataAddr(), data_pkt, pkt_size); + + if (error < 0) { + IOLogError("F12 Could not read attention data: %d", error); + return; + } } - clock_get_uptime(×tamp); - if (shouldDiscardReport(timestamp)) + if (shouldDiscardReport(time)) return; IOLogDebug("F12 Packet"); @@ -293,12 +301,12 @@ void F12::attention() #endif // debug int fingers = min (nbr_fingers, 5); - UInt8 *data = &data_pkt[data1_offset]; + UInt8 *fingerData = &data_pkt[data1_offset]; for (int i = 0; i < fingers; i++) { rmi_2d_sensor_abs_object *obj = &report.objs[i]; - switch (data[0]) { + switch (fingerData[0]) { case RMI_F12_OBJECT_FINGER: obj->type = RMI_2D_OBJECT_FINGER; break; @@ -309,16 +317,16 @@ void F12::attention() obj->type = RMI_2D_OBJECT_NONE; } - obj->x = (data[2] << 8) | data[1]; - obj->y = (data[4] << 8) | data[3]; - obj->z = data[5]; - obj->wx = data[6]; - obj->wy = data[7]; + obj->x = (fingerData[2] << 8) | fingerData[1]; + obj->y = (fingerData[4] << 8) | fingerData[3]; + obj->z = fingerData[5]; + obj->wx = fingerData[6]; + obj->wy = fingerData[7]; data += F12_DATA1_BYTES_PER_OBJ; } - report.timestamp = timestamp; + report.timestamp = time; report.fingers = fingers; handleReport(&report); diff --git a/VoodooRMI/Functions/F12.hpp b/VoodooRMI/Functions/F12.hpp index d6d011e..1766c80 100644 --- a/VoodooRMI/Functions/F12.hpp +++ b/VoodooRMI/Functions/F12.hpp @@ -54,7 +54,7 @@ class F12 : public RMITrackpadFunction { public: bool attach(IOService *provider) override; - void attention() override; + void attention(AbsoluteTime time, UInt8 *data[], size_t *size) override; void free() override; IOReturn config() override; diff --git a/VoodooRMI/Functions/F17.cpp b/VoodooRMI/Functions/F17.cpp index d07e68c..e7583e9 100644 --- a/VoodooRMI/Functions/F17.cpp +++ b/VoodooRMI/Functions/F17.cpp @@ -34,7 +34,7 @@ void F17::free() super::free(); } -void F17::attention() +void F17::attention(AbsoluteTime time, UInt8 *data[], size_t *size) { int retval = 0; for (int i = 0; i < f17.query.number_of_sticks + 1 && !retval; i++) @@ -244,8 +244,8 @@ int F17::rmi_f17_process_stick(struct rmi_f17_stick_data *stick) { } else { IOLogDebug("%s: Reporting dx: %d, dy: %d\n", __func__, stick->data.rel.x_delta, stick->data.rel.y_delta); - report.dx = (SInt32)((SInt64)stick->data.rel.x_delta * conf.trackpointMult / DEFAULT_MULT); - report.dy = -(SInt32)((SInt64)stick->data.rel.y_delta * conf.trackpointMult / DEFAULT_MULT); + report.dx = (SInt32)((SInt64)stick->data.rel.x_delta; + report.dy = -(SInt32)((SInt64)stick->data.rel.y_delta; report.buttons = 0; handleReport(&report); diff --git a/VoodooRMI/Functions/F17.hpp b/VoodooRMI/Functions/F17.hpp index cffbf10..c58ec70 100644 --- a/VoodooRMI/Functions/F17.hpp +++ b/VoodooRMI/Functions/F17.hpp @@ -150,7 +150,7 @@ class F17 : public RMITrackpointFunction { public: bool attach(IOService *provider) override; void free() override; - void attention() override; + void attention(AbsoluteTime time, UInt8 *data[], size_t *size) override; IOReturn config() override; private: diff --git a/VoodooRMI/Functions/Input/RMIFunction.cpp b/VoodooRMI/Functions/Input/RMIFunction.cpp index 137c5a5..f51bece 100644 --- a/VoodooRMI/Functions/Input/RMIFunction.cpp +++ b/VoodooRMI/Functions/Input/RMIFunction.cpp @@ -5,6 +5,7 @@ */ #include "RMIFunction.hpp" +#include "RMILogging.h" OSDefineMetaClassAndStructors(RMIFunction, IOService) @@ -39,3 +40,35 @@ bool RMIFunction::start(IOService *provider) { registerService(); return true; } + +bool RMIFunction::getInputData(UInt8 dest[], size_t destSize, UInt8 *srcData[], size_t *srcSize) { + if (srcData) { + if (*srcSize < destSize) { + IOLogError("%s Attention size smaller than expected", getName()); + return false; + } + + memcpy(dest, *srcData, destSize); + (*srcData) += destSize; + (*srcSize) -= destSize; + return true; + } + + if (destSize == 1) { + IOReturn error = readByte(getDataAddr(), dest); + + if (error) { + IOLogError("%s Failed to read device status: %d", getName(), error); + return false; + } + } else { + IOReturn error = readBlock(getDataAddr(), dest, destSize); + + if (error) { + IOLogError("%s Failed to read block data: %d", getName(), error); + return false; + } + } + + return true; +} diff --git a/VoodooRMI/Functions/Input/RMIFunction.hpp b/VoodooRMI/Functions/Input/RMIFunction.hpp index 74e3a94..50dfebf 100644 --- a/VoodooRMI/Functions/Input/RMIFunction.hpp +++ b/VoodooRMI/Functions/Input/RMIFunction.hpp @@ -56,13 +56,15 @@ class RMIFunction : public IOService { virtual IOReturn config() { return kIOReturnSuccess; }; // Attention is called whenever this function has data. Any input data // should be read here. - virtual void attention() { }; + virtual void attention(AbsoluteTime time, UInt8 *data[], size_t *size) { }; private: RmiPdtEntry pdtEntry; RMIBus *bus {nullptr}; protected: + bool getInputData(UInt8 dest[], size_t destSize, UInt8 *srcData[], size_t *srcSize); + // Useful functions to talk to RMI4 devicce inline void sendVoodooInputPacket(UInt32 msg, void *packet) { IOService *vi = bus->getVoodooInput(); diff --git a/VoodooRMI/Functions/Input/RMIGPIOFunction.cpp b/VoodooRMI/Functions/Input/RMIGPIOFunction.cpp index 9f1c2e7..7acb262 100644 --- a/VoodooRMI/Functions/Input/RMIGPIOFunction.cpp +++ b/VoodooRMI/Functions/Input/RMIGPIOFunction.cpp @@ -96,20 +96,16 @@ int RMIGPIOFunction::mapGpios() return 0; } -void RMIGPIOFunction::attention() +void RMIGPIOFunction::attention(AbsoluteTime time, UInt8 *data[], size_t *size) { - int error = readBlock(getDataAddr(), - data_regs, register_count); - - if (error < 0) { - IOLogError("Could not read %s data: %d", getName(), error); - } - + if (!getInputData(data_regs, register_count, data, size)) + return; + if (has_gpio) - reportButton(); + reportButton(time); } -void RMIGPIOFunction::reportButton() +void RMIGPIOFunction::reportButton(AbsoluteTime time) { TrackpointReport relativeEvent {}; unsigned int mask, trackpointBtns = 0, btns = 0; @@ -150,12 +146,9 @@ void RMIGPIOFunction::reportButton() } if (numButtons > 1) { - AbsoluteTime timestamp; - clock_get_uptime(×tamp); - relativeEvent.dx = relativeEvent.dy = 0; relativeEvent.buttons = btns; - relativeEvent.timestamp = timestamp; + relativeEvent.timestamp = time; sendVoodooInputPacket(kIOMessageVoodooTrackpointRelativePointer, &relativeEvent); } diff --git a/VoodooRMI/Functions/Input/RMIGPIOFunction.hpp b/VoodooRMI/Functions/Input/RMIGPIOFunction.hpp index 8c51a36..33d34a8 100644 --- a/VoodooRMI/Functions/Input/RMIGPIOFunction.hpp +++ b/VoodooRMI/Functions/Input/RMIGPIOFunction.hpp @@ -18,7 +18,7 @@ class RMIGPIOFunction : public RMIFunction { public: bool attach(IOService *provider) override; IOReturn config() override; - void attention() override; + void attention(AbsoluteTime time, UInt8 *data[], size_t *size) override; void free() override; protected: @@ -42,7 +42,7 @@ class RMIGPIOFunction : public RMIFunction { virtual inline bool is_valid_button(int button) {return false;}; int mapGpios(); - void reportButton(); + void reportButton(AbsoluteTime time); }; #endif /* RMIGPIOFunction_hpp */ diff --git a/VoodooRMI/Functions/Input/RMITrackpointFunction.cpp b/VoodooRMI/Functions/Input/RMITrackpointFunction.cpp index bafc8f3..f44ec2c 100644 --- a/VoodooRMI/Functions/Input/RMITrackpointFunction.cpp +++ b/VoodooRMI/Functions/Input/RMITrackpointFunction.cpp @@ -9,14 +9,11 @@ OSDefineMetaClassAndStructors(RMITrackpointFunction, RMIFunction) void RMITrackpointFunction::handleReport(RMITrackpointReport *report) { - AbsoluteTime timestamp; - clock_get_uptime(×tamp); - TrackpointReport trackpointReport; + trackpointReport.timestamp = report->timestamp; trackpointReport.dx = report->dx; trackpointReport.dy = report->dy; trackpointReport.buttons = report->buttons | overwrite_buttons; - trackpointReport.timestamp = timestamp; sendVoodooInputPacket(kIOMessageVoodooTrackpointMessage, &trackpointReport); if (report->dx || report->dy) { diff --git a/VoodooRMI/Functions/Input/RMITrackpointFunction.hpp b/VoodooRMI/Functions/Input/RMITrackpointFunction.hpp index 40ebef5..89d53a4 100644 --- a/VoodooRMI/Functions/Input/RMITrackpointFunction.hpp +++ b/VoodooRMI/Functions/Input/RMITrackpointFunction.hpp @@ -9,6 +9,7 @@ #include struct RMITrackpointReport { + AbsoluteTime timestamp; SInt32 dx; SInt32 dy; UInt32 buttons; diff --git a/VoodooRMI/RMIBus.cpp b/VoodooRMI/RMIBus.cpp index b954ef9..9f2ecd8 100644 --- a/VoodooRMI/RMIBus.cpp +++ b/VoodooRMI/RMIBus.cpp @@ -77,7 +77,7 @@ bool RMIBus::start(IOService *provider) { // Ready for interrupts setProperty(RMIBusIdentifier, kOSBooleanTrue); - if (!transport->open(this)) { + if (!transport->open(this, 0, OSMemberFunctionCast(RMIAttentionAction, this, &RMIBus::handleHostNotify))) { IOLogError("Could not open transport"); goto err; } @@ -106,19 +106,21 @@ bool RMIBus::start(IOService *provider) { return false; } -void RMIBus::handleHostNotify() { +void RMIBus::handleHostNotify(AbsoluteTime time, UInt8 *data, size_t size) { UInt32 irqStatus; - if (controlFunction == nullptr) { IOLogError("Interrupt - No F01"); return; } - IOReturn error = controlFunction->readIRQ(irqStatus); - - if (error != kIOReturnSuccess){ - IOLogError("Unable to read IRQ"); - return; + if (data) { + irqStatus = data[0]; + } else { + IOReturn error = controlFunction->readIRQ(irqStatus); + if (error != kIOReturnSuccess){ + IOLogError("Unable to read IRQ"); + return; + } } OSIterator* iter = OSCollectionIterator::withCollection(functions); @@ -127,35 +129,18 @@ void RMIBus::handleHostNotify() { return; } + UInt8 *dataPtr = &data[1]; while(RMIFunction *func = OSDynamicCast(RMIFunction, iter->getNextObject())) { if (func->hasAttnSig(irqStatus)) { - func->attention(); + func->attention(time, &dataPtr, &size); } } OSSafeReleaseNULL(iter); } -void RMIBus::handleHostNotifyLegacy() { - if (controlFunction == nullptr) { - IOLogError("Interrupt - No F01"); - } - - OSIterator* iter = OSCollectionIterator::withCollection(functions); - while(RMIFunction *func = OSDynamicCast(RMIFunction, iter->getNextObject())) - func->attention(); - OSSafeReleaseNULL(iter); -} - IOReturn RMIBus::message(UInt32 type, IOService *provider, void *argument) { switch (type) { - case kIOMessageVoodooI2CHostNotify: - case kIOMessageVoodooSMBusHostNotify: - handleHostNotify(); - break; - case kIOMessageVoodooI2CLegacyHostNotify: - handleHostNotifyLegacy(); - break; case kIOMessageRMI4ResetHandler: rmiEnableSensor(); break; diff --git a/VoodooRMI/RMIBus.hpp b/VoodooRMI/RMIBus.hpp index e8e9217..ab4ee06 100644 --- a/VoodooRMI/RMIBus.hpp +++ b/VoodooRMI/RMIBus.hpp @@ -87,8 +87,7 @@ class RMIBus : public IOService { IOService *trackpointFunction {nullptr}; F01 *controlFunction {nullptr}; - void handleHostNotify(); - void handleHostNotifyLegacy(); + void handleHostNotify(AbsoluteTime time, UInt8 *data, size_t size); // IRQ information UInt8 irqCount {0}; diff --git a/VoodooRMI/Transports/I2C/RMII2C.cpp b/VoodooRMI/Transports/I2C/RMII2C.cpp index d5a6f4c..5da75af 100644 --- a/VoodooRMI/Transports/I2C/RMII2C.cpp +++ b/VoodooRMI/Transports/I2C/RMII2C.cpp @@ -102,6 +102,7 @@ bool RMII2C::start(IOService *provider) { interrupt_source = IOInterruptEventSource::interruptEventSource(this, OSMemberFunctionCast(IOInterruptEventAction, this, &RMII2C::interruptOccured), device_nub, 0); if (interrupt_source) { + interrupt_source->enablePrimaryInterruptTimestamp(true); work_loop->addEventSource(interrupt_source); } else { IOLogInfo("%s::%s Could not get interrupt event source, falling back to polling", getName(), name); @@ -110,10 +111,12 @@ bool RMII2C::start(IOService *provider) { IOLogError("%s::%s Could not get timer event source", getName(), name); goto exit; } - + work_loop->addEventSource(interrupt_simulator); } + inputBuffer = new UInt8[hdesc.wMaxInputLength]; + startInterrupt(); PMinit(); @@ -150,6 +153,10 @@ void RMII2C::releaseResources() { device_nub->close(this); device_nub = nullptr; } + + if (inputBuffer) { + delete inputBuffer; + } OSSafeReleaseNULL(command_gate); OSSafeReleaseNULL(interrupt_source); @@ -278,16 +285,13 @@ int RMII2C::reset() { return retval; }; -bool RMII2C::handleOpen(IOService *forClient, IOOptionBits options, void *arg) { - if (forClient && forClient->getProperty(RMIBusIdentifier)) { - bus = forClient; - bus->retain(); - - startInterrupt(); - return true; +bool RMII2C::open(IOService *client, IOOptionBits options, RMIAttentionAction action) { + if (!super::open(client, options, action)) { + return false; } - - return IOService::handleOpen(forClient, options, arg); + + startInterrupt(); + return true; } int RMII2C::readBlock(UInt16 rmiaddr, UInt8 *databuff, size_t len) { @@ -395,8 +399,20 @@ int RMII2C::blockWrite(UInt16 rmiaddr, UInt8 *buf, size_t len) { void RMII2C::interruptOccured(OSObject *owner, IOInterruptEventSource *src, int intCount) { if (!ready || !bus) return; - - messageClient(reportMode == RMI_MODE_ATTN_REPORTS ? kIOMessageVoodooI2CLegacyHostNotify : kIOMessageVoodooI2CHostNotify, bus); + + if (device_nub->readI2C(inputBuffer, hdesc.wMaxInputLength) != kIOReturnSuccess) { + IOLogError("%s::%s Unable to read interrupt data", getName(), name); + return; + } + + UInt16 size = inputBuffer[0] | (inputBuffer[1] << 8); + UInt8 reportId = inputBuffer[2]; + + if (!size || reportId != RMI_ATTN_REPORT_ID) { + return; + } + + handleAttention(mach_absolute_time(), &inputBuffer[3], size - 3); } void RMII2C::simulateInterrupt(OSObject* owner, IOTimerEventSource* timer) { diff --git a/VoodooRMI/Transports/I2C/RMII2C.hpp b/VoodooRMI/Transports/I2C/RMII2C.hpp index 79719fb..766036e 100644 --- a/VoodooRMI/Transports/I2C/RMII2C.hpp +++ b/VoodooRMI/Transports/I2C/RMII2C.hpp @@ -72,7 +72,7 @@ typedef struct __attribute__((__packed__)) { class RMII2C : public RMITransport { OSDeclareDefaultStructors(RMII2C); - typedef IOService super; + typedef RMITransport super; public: const char* name; @@ -81,7 +81,7 @@ class RMII2C : public RMITransport { bool start(IOService *provider) APPLE_KEXT_OVERRIDE; void stop(IOService *provider) APPLE_KEXT_OVERRIDE; IOReturn setPowerState(unsigned long powerState, IOService *whatDevice) APPLE_KEXT_OVERRIDE; - bool handleOpen(IOService *forClient, IOOptionBits options, void *arg) APPLE_KEXT_OVERRIDE; + bool open(IOService *client, IOOptionBits options, RMIAttentionAction action) APPLE_KEXT_OVERRIDE; int reset() APPLE_KEXT_OVERRIDE; int readBlock(UInt16 rmiaddr, UInt8 *databuff, size_t len) APPLE_KEXT_OVERRIDE; @@ -92,7 +92,8 @@ class RMII2C : public RMITransport { bool ready {false}; unsigned long currentPowerState {1}; int page {0}; - int reportMode {RMI_MODE_NO_PACKED_ATTN_REPORTS}; + int reportMode {RMI_MODE_ATTN_REPORTS}; + UInt8 *inputBuffer {nullptr}; VoodooI2CDeviceNub *device_nub {nullptr}; diff --git a/VoodooRMI/Transports/RMITransport.hpp b/VoodooRMI/Transports/RMITransport.hpp index 78eed9b..4ba6449 100644 --- a/VoodooRMI/Transports/RMITransport.hpp +++ b/VoodooRMI/Transports/RMITransport.hpp @@ -15,14 +15,14 @@ #include #define kIOMessageVoodooSMBusHostNotify iokit_vendor_specific_msg(420) -#define kIOMessageVoodooI2CHostNotify iokit_vendor_specific_msg(421) -#define kIOMessageVoodooI2CLegacyHostNotify iokit_vendor_specific_msg(422) #define kIOMessageRMI4ResetHandler iokit_vendor_specific_msg(423) #define kIOMessageRMI4Sleep iokit_vendor_specific_msg(424) #define kIOMessageRMI4Resume iokit_vendor_specific_msg(425) #define RMIBusIdentifier "Synaptics RMI4 Device" #define RMIBusSupported "RMI4 Supported" +typedef void (*RMIAttentionAction)(OSObject *target, AbsoluteTime timestamp, UInt8 *data, size_t size); + /* * read/write/reset APIs can be used before opening. Opening/Closing is needed to recieve interrupts */ @@ -38,30 +38,35 @@ class RMITransport : public IOService { virtual int reset() { return 0; }; virtual OSDictionary *createConfig() { return nullptr; }; - - /* - * IMPORTANT: These handleClose/handleOpen must be called. These can be overriden, - * but said implementation must call the ones below. - */ - inline virtual void handleClose(IOService *forClient, IOOptionBits options) override { - OSSafeReleaseNULL(bus); - IOService::handleClose(forClient, options); + + virtual bool open(IOService *client, IOOptionBits options, RMIAttentionAction action) { + if (!IOService::open(client, options)) { + return false; + } + + bus = client; + interruptAction = action; + return true; + } + + virtual void close(IOService *client, IOOptionBits options = 0) override { + bus = nullptr; + interruptAction = nullptr; + IOService::close(client); } - inline virtual bool handleOpen(IOService *forClient, IOOptionBits options, void *arg) override { - if (forClient && forClient->getProperty(RMIBusIdentifier) - && IOService::handleOpen(forClient, options, arg)) { - bus = forClient; - bus->retain(); - - return true; + void handleAttention(AbsoluteTime timestamp, UInt8 *data, size_t size) { + if (!interruptAction) { + return; } - return false; + (*interruptAction)(bus, timestamp, data, size); } protected: IOService *bus {nullptr}; +private: + RMIAttentionAction interruptAction {nullptr}; }; #endif // RMITransport_H diff --git a/VoodooRMI/Transports/SMBus/RMISMBus.cpp b/VoodooRMI/Transports/SMBus/RMISMBus.cpp index 99288fe..6e3f984 100644 --- a/VoodooRMI/Transports/SMBus/RMISMBus.cpp +++ b/VoodooRMI/Transports/SMBus/RMISMBus.cpp @@ -268,7 +268,8 @@ IOReturn RMISMBus::message(UInt32 type, IOService *provider, void *argument) { switch (type) { case kIOMessageVoodooSMBusHostNotify: - return messageClient(kIOMessageVoodooSMBusHostNotify, bus); + handleAttention(mach_absolute_time(), nullptr, 0); + return kIOReturnSuccess; default: return IOService::message(type, provider, argument); } From 5f8bf24021462dff95a97cb45459bbc85484ac88 Mon Sep 17 00:00:00 2001 From: Avery Black Date: Thu, 17 Oct 2024 19:05:04 -0700 Subject: [PATCH 02/11] Fix compile and pointer to null data --- VoodooRMI/Functions/F17.cpp | 4 ++-- VoodooRMI/RMIBus.cpp | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/VoodooRMI/Functions/F17.cpp b/VoodooRMI/Functions/F17.cpp index e7583e9..16c7060 100644 --- a/VoodooRMI/Functions/F17.cpp +++ b/VoodooRMI/Functions/F17.cpp @@ -244,8 +244,8 @@ int F17::rmi_f17_process_stick(struct rmi_f17_stick_data *stick) { } else { IOLogDebug("%s: Reporting dx: %d, dy: %d\n", __func__, stick->data.rel.x_delta, stick->data.rel.y_delta); - report.dx = (SInt32)((SInt64)stick->data.rel.x_delta; - report.dy = -(SInt32)((SInt64)stick->data.rel.y_delta; + report.dx = (SInt32)((SInt64)stick->data.rel.x_delta); + report.dy = -(SInt32)((SInt64)stick->data.rel.y_delta); report.buttons = 0; handleReport(&report); diff --git a/VoodooRMI/RMIBus.cpp b/VoodooRMI/RMIBus.cpp index 9f2ecd8..963e7ad 100644 --- a/VoodooRMI/RMIBus.cpp +++ b/VoodooRMI/RMIBus.cpp @@ -108,6 +108,7 @@ bool RMIBus::start(IOService *provider) { void RMIBus::handleHostNotify(AbsoluteTime time, UInt8 *data, size_t size) { UInt32 irqStatus; + UInt8 *dataPtr = nullptr; if (controlFunction == nullptr) { IOLogError("Interrupt - No F01"); return; @@ -115,6 +116,8 @@ void RMIBus::handleHostNotify(AbsoluteTime time, UInt8 *data, size_t size) { if (data) { irqStatus = data[0]; + dataPtr = &data[1]; + size -= sizeof(UInt8); } else { IOReturn error = controlFunction->readIRQ(irqStatus); if (error != kIOReturnSuccess){ @@ -129,7 +132,6 @@ void RMIBus::handleHostNotify(AbsoluteTime time, UInt8 *data, size_t size) { return; } - UInt8 *dataPtr = &data[1]; while(RMIFunction *func = OSDynamicCast(RMIFunction, iter->getNextObject())) { if (func->hasAttnSig(irqStatus)) { func->attention(time, &dataPtr, &size); From 5f9647546fe3a451a22849c99b0685f2244898e1 Mon Sep 17 00:00:00 2001 From: Avery Black Date: Thu, 17 Oct 2024 19:06:45 -0700 Subject: [PATCH 03/11] Fix warning I apparently don't have unused function argument warnings enabled? --- VoodooRMI/Functions/F01.cpp | 2 +- VoodooRMI/Functions/F17.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/VoodooRMI/Functions/F01.cpp b/VoodooRMI/Functions/F01.cpp index f5647de..b9ab659 100644 --- a/VoodooRMI/Functions/F01.cpp +++ b/VoodooRMI/Functions/F01.cpp @@ -373,7 +373,7 @@ int F01::rmi_f01_resume() return error; } -void F01::attention([[maybe_unused]] AbsoluteTime time, UInt8 *data[], size_t *size) +void F01::attention(AbsoluteTime time, UInt8 *data[], size_t *size) { UInt8 device_status = 0; diff --git a/VoodooRMI/Functions/F17.cpp b/VoodooRMI/Functions/F17.cpp index 16c7060..acf1a5f 100644 --- a/VoodooRMI/Functions/F17.cpp +++ b/VoodooRMI/Functions/F17.cpp @@ -215,7 +215,6 @@ int F17::config() { int F17::rmi_f17_process_stick(struct rmi_f17_stick_data *stick) { int retval = 0; - const RmiConfiguration &conf = getConfiguration(); RMITrackpointReport report; if (stick->query.general.has_absolute) { From 9461db414b11529b52a8bbfd626c297e02fb201f Mon Sep 17 00:00:00 2001 From: Avery Black Date: Thu, 17 Oct 2024 19:13:10 -0700 Subject: [PATCH 04/11] Remove isLegacy option for I2C --- VoodooRMI/Transports/I2C/Info.plist | 2 -- VoodooRMI/Transports/I2C/RMII2C.cpp | 25 ++++--------------------- VoodooRMI/Transports/I2C/RMII2C.hpp | 1 - 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/VoodooRMI/Transports/I2C/Info.plist b/VoodooRMI/Transports/I2C/Info.plist index 0acaf56..3598dea 100644 --- a/VoodooRMI/Transports/I2C/Info.plist +++ b/VoodooRMI/Transports/I2C/Info.plist @@ -35,8 +35,6 @@ VoodooI2CDeviceNub IOClass RMII2C - Legacy - CFBundleIdentifier com.1Revenger1.RMII2C diff --git a/VoodooRMI/Transports/I2C/RMII2C.cpp b/VoodooRMI/Transports/I2C/RMII2C.cpp index 5da75af..2481376 100644 --- a/VoodooRMI/Transports/I2C/RMII2C.cpp +++ b/VoodooRMI/Transports/I2C/RMII2C.cpp @@ -28,14 +28,6 @@ RMII2C *RMII2C::probe(IOService *provider, SInt32 *score) { name = provider->getName(); IOLogDebug("%s::%s probing", getName(), name); - OSBoolean *isLegacy= OSDynamicCast(OSBoolean, getProperty("Legacy")); - if (isLegacy == nullptr) { - IOLogInfo("%s::%s Legacy mode not set, default to false", getName(), name); - } else if (isLegacy->getValue()) { - reportMode = RMI_MODE_ATTN_REPORTS; - IOLogInfo("%s::%s running in legacy mode", getName(), name); - } - device_nub = OSDynamicCast(VoodooI2CDeviceNub, provider); if (!device_nub) { IOLogError("%s::%s Could not cast nub", getName(), name); @@ -57,7 +49,7 @@ RMII2C *RMII2C::probe(IOService *provider, SInt32 *score) { do { IOLogDebug("%s::%s Trying to set mode, attempt %d", getName(), name, attempts); - error = rmi_set_mode(reportMode); + error = rmi_set_mode(RMI_MODE_ATTN_REPORTS); IOSleep(500); } while (error < 0 && attempts++ < 5); @@ -271,7 +263,7 @@ int RMII2C::rmi_set_mode(UInt8 mode) { } int RMII2C::reset() { - int retval = rmi_set_mode(reportMode); + int retval = rmi_set_mode(RMI_MODE_ATTN_REPORTS); if (retval < 0) return retval; @@ -341,16 +333,7 @@ int RMII2C::readBlock(UInt16 rmiaddr, UInt8 *databuff, size_t len) { goto exit; } - // FIXME: whether to rebuild packet - if (reportMode == RMI_MODE_ATTN_REPORTS && len == 68) { - memcpy(databuff, i2cInput+4, 16); - device_nub->readI2C(i2cInput, len+4); - memcpy(databuff+16, i2cInput+4, 16); - device_nub->readI2C(i2cInput, len+4); - memcpy(databuff+32, i2cInput+4, 16); - } else { - memcpy(databuff, i2cInput+4, len); - } + memcpy(databuff, i2cInput+4, len); exit: delete[] i2cInput; IOLockUnlock(page_mutex); @@ -430,7 +413,7 @@ IOReturn RMII2C::setPowerStateGated() { // FIXME: Hardcode 1s sleep delay because device will otherwise time out during reconfig IOSleep(1000); - int retval = rmi_set_mode(reportMode); + int retval = rmi_set_mode(RMI_MODE_ATTN_REPORTS); if (retval < 0) { IOLogError("Failed to config trackpad!"); return kIOPMAckImplied; diff --git a/VoodooRMI/Transports/I2C/RMII2C.hpp b/VoodooRMI/Transports/I2C/RMII2C.hpp index 766036e..d1475cf 100644 --- a/VoodooRMI/Transports/I2C/RMII2C.hpp +++ b/VoodooRMI/Transports/I2C/RMII2C.hpp @@ -92,7 +92,6 @@ class RMII2C : public RMITransport { bool ready {false}; unsigned long currentPowerState {1}; int page {0}; - int reportMode {RMI_MODE_ATTN_REPORTS}; UInt8 *inputBuffer {nullptr}; VoodooI2CDeviceNub *device_nub {nullptr}; From afa284044671fafc2383f0e5e663fbc4afa088a5 Mon Sep 17 00:00:00 2001 From: Avery Black Date: Thu, 17 Oct 2024 19:19:37 -0700 Subject: [PATCH 05/11] Fix nullptr check for hid input data --- VoodooRMI/Functions/F11.cpp | 2 +- VoodooRMI/Functions/F12.cpp | 2 +- VoodooRMI/Functions/Input/RMIFunction.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VoodooRMI/Functions/F11.cpp b/VoodooRMI/Functions/F11.cpp index eb7c0a0..8ee73df 100644 --- a/VoodooRMI/Functions/F11.cpp +++ b/VoodooRMI/Functions/F11.cpp @@ -46,7 +46,7 @@ void F11::attention(AbsoluteTime time, UInt8 *data[], size_t *size) size_t fingers; UInt8 finger_state; - if (data) { + if (*data) { if (*size < attn_size) { IOLogError("F11 attention larger than remaining data"); return; diff --git a/VoodooRMI/Functions/F12.cpp b/VoodooRMI/Functions/F12.cpp index cf05964..c16fbe0 100644 --- a/VoodooRMI/Functions/F12.cpp +++ b/VoodooRMI/Functions/F12.cpp @@ -272,7 +272,7 @@ void F12::attention(AbsoluteTime time, UInt8 *data[], size_t *size) if (!data1) return; - if (data) { + if (*data) { if (*size < attn_size) { IOLogError("F12 attention larger than remaining data"); return; diff --git a/VoodooRMI/Functions/Input/RMIFunction.cpp b/VoodooRMI/Functions/Input/RMIFunction.cpp index f51bece..801b57b 100644 --- a/VoodooRMI/Functions/Input/RMIFunction.cpp +++ b/VoodooRMI/Functions/Input/RMIFunction.cpp @@ -42,7 +42,7 @@ bool RMIFunction::start(IOService *provider) { } bool RMIFunction::getInputData(UInt8 dest[], size_t destSize, UInt8 *srcData[], size_t *srcSize) { - if (srcData) { + if (*srcData) { if (*srcSize < destSize) { IOLogError("%s Attention size smaller than expected", getName()); return false; From 2ddd0f6c26205cd52078702edb90927cd786d84f Mon Sep 17 00:00:00 2001 From: Avery Black Date: Thu, 17 Oct 2024 19:25:24 -0700 Subject: [PATCH 06/11] Use I2C interrupt timestamp if possible --- VoodooRMI/Transports/I2C/RMII2C.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/VoodooRMI/Transports/I2C/RMII2C.cpp b/VoodooRMI/Transports/I2C/RMII2C.cpp index 2481376..6a0129c 100644 --- a/VoodooRMI/Transports/I2C/RMII2C.cpp +++ b/VoodooRMI/Transports/I2C/RMII2C.cpp @@ -395,7 +395,12 @@ void RMII2C::interruptOccured(OSObject *owner, IOInterruptEventSource *src, int return; } - handleAttention(mach_absolute_time(), &inputBuffer[3], size - 3); + AbsoluteTime timestamp = mach_absolute_time(); + if (src != nullptr) { + timestamp = src->getPimaryInterruptTimestamp(); + } + + handleAttention(timestamp, &inputBuffer[3], size - 3); } void RMII2C::simulateInterrupt(OSObject* owner, IOTimerEventSource* timer) { From f63343c70fbe8212e68b029c89ba407390834256 Mon Sep 17 00:00:00 2001 From: Avery Black Date: Fri, 18 Oct 2024 12:27:51 -0700 Subject: [PATCH 07/11] Get timestamp from interrupt timestamp --- VoodooRMI/Transports/I2C/RMII2C.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VoodooRMI/Transports/I2C/RMII2C.cpp b/VoodooRMI/Transports/I2C/RMII2C.cpp index 6a0129c..b78555d 100644 --- a/VoodooRMI/Transports/I2C/RMII2C.cpp +++ b/VoodooRMI/Transports/I2C/RMII2C.cpp @@ -396,8 +396,8 @@ void RMII2C::interruptOccured(OSObject *owner, IOInterruptEventSource *src, int } AbsoluteTime timestamp = mach_absolute_time(); - if (src != nullptr) { - timestamp = src->getPimaryInterruptTimestamp(); + if (interrupt_source != nullptr) { + timestamp = interrupt_source->getPimaryInterruptTimestamp(); } handleAttention(timestamp, &inputBuffer[3], size - 3); From c925d87c4934f11c0f243e5f6ce3b72a9c3a4105 Mon Sep 17 00:00:00 2001 From: Avery Black Date: Sun, 20 Oct 2024 08:23:17 -0700 Subject: [PATCH 08/11] Simplify F12 probing, set offset to zero for HID attention reports --- VoodooRMI/Functions/F12.cpp | 44 +++++-------------- VoodooRMI/Functions/F12.hpp | 17 ++----- .../Functions/Input/RMITrackpadFunction.hpp | 3 -- 3 files changed, 15 insertions(+), 49 deletions(-) diff --git a/VoodooRMI/Functions/F12.cpp b/VoodooRMI/Functions/F12.cpp index c16fbe0..9043b26 100644 --- a/VoodooRMI/Functions/F12.cpp +++ b/VoodooRMI/Functions/F12.cpp @@ -79,9 +79,9 @@ bool F12::attach(IOService *provider) /* * Figure out what data is contained in the data registers. HID devices * may have registers defined, but their data is not reported in the - * HID attention report. Registers which are not reported in the HID - * attention report check to see if the device is receiving data from - * HID attention reports. + * HID attention report. As we don't care about pen or acm data, we can do + * a simplified check for ACM data to get attention size and ignore the data + * offset. */ item = rmi_get_register_desc_item(&data_reg_desc, 0); if (item) @@ -89,43 +89,23 @@ bool F12::attach(IOService *provider) item = rmi_get_register_desc_item(&data_reg_desc, 1); if (!item) { - return false; IOLogError("F12 - No Data1 Reg!"); + return false; } - - data1 = item; + data1_offset = data_offset; - data_offset += item->reg_size; - nbr_fingers = item->num_subpackets; - report_abs = 1; attn_size += item->reg_size; - - item = rmi_get_register_desc_item(&data_reg_desc, 2); - if (item) - data_offset += item->reg_size; - - item = rmi_get_register_desc_item(&data_reg_desc, 3); - if (item) - data_offset += item->reg_size; - - item = rmi_get_register_desc_item(&data_reg_desc, 4); - if (item) - data_offset += item->reg_size; + nbr_fingers = item->num_subpackets; item = rmi_get_register_desc_item(&data_reg_desc, 5); - if (item) { - data5 = item; - data5_offset = data_offset; - data_offset += item->reg_size; + if (item) attn_size += item->reg_size; - } - // Skip 6-15 as they do not increase attention size and only gives relative info + // Skip 6-15 as they do not increase attention size setProperty("Number of fingers", nbr_fingers, 8); IOLogDebug("F12 - Number of fingers %u", nbr_fingers); - return true; } @@ -269,9 +249,8 @@ int F12::rmi_f12_read_sensor_tuning() void F12::attention(AbsoluteTime time, UInt8 *data[], size_t *size) { - if (!data1) - return; - + size_t offset = data1_offset; + if (*data) { if (*size < attn_size) { IOLogError("F12 attention larger than remaining data"); @@ -281,6 +260,7 @@ void F12::attention(AbsoluteTime time, UInt8 *data[], size_t *size) memcpy(data_pkt, *data, attn_size); (*data) += attn_size; (*size) -= attn_size; + offset = 0; } else { IOReturn error = readBlock(getDataAddr(), data_pkt, pkt_size); @@ -301,7 +281,7 @@ void F12::attention(AbsoluteTime time, UInt8 *data[], size_t *size) #endif // debug int fingers = min (nbr_fingers, 5); - UInt8 *fingerData = &data_pkt[data1_offset]; + UInt8 *fingerData = &data_pkt[offset]; for (int i = 0; i < fingers; i++) { rmi_2d_sensor_abs_object *obj = &report.objs[i]; diff --git a/VoodooRMI/Functions/F12.hpp b/VoodooRMI/Functions/F12.hpp index 1766c80..91ba8a0 100644 --- a/VoodooRMI/Functions/F12.hpp +++ b/VoodooRMI/Functions/F12.hpp @@ -72,26 +72,15 @@ class F12 : public RMITrackpadFunction { /* F12 Data */ UInt8 *data_pkt; - size_t pkt_size; - size_t attn_size; + size_t pkt_size {0}; + size_t attn_size {0}; bool has_dribble; + size_t data1_offset; rmi_register_descriptor query_reg_desc; rmi_register_descriptor control_reg_desc; rmi_register_descriptor data_reg_desc; - /* F12 Data1 describes sensed objects */ - const rmi_register_desc_item *data1 {nullptr}; - UInt16 data1_offset; - - /* F12 Data5 describes finger ACM */ - const rmi_register_desc_item *data5 {nullptr}; - UInt16 data5_offset; - - /* F12 Data5 describes Pen */ - const rmi_register_desc_item *data6 {nullptr}; - UInt16 data6_offset; - int rmi_f12_read_sensor_tuning(); int rmi_read_register_desc(UInt16 addr, rmi_register_descriptor *rdesc); diff --git a/VoodooRMI/Functions/Input/RMITrackpadFunction.hpp b/VoodooRMI/Functions/Input/RMITrackpadFunction.hpp index b3939ec..6523103 100644 --- a/VoodooRMI/Functions/Input/RMITrackpadFunction.hpp +++ b/VoodooRMI/Functions/Input/RMITrackpadFunction.hpp @@ -82,9 +82,6 @@ class RMITrackpadFunction : public RMIFunction { const Rmi2DSensorData &getData() const; protected: - UInt8 report_abs {0}; - UInt8 report_rel {0}; - UInt8 nbr_fingers; void handleReport(RMI2DSensorReport *report); From 47ae60e538548281b346a3767b7942462fa7094d Mon Sep 17 00:00:00 2001 From: Avery Black Date: Mon, 21 Oct 2024 08:48:37 -0700 Subject: [PATCH 09/11] Fix not incrementing F12 data --- VoodooRMI/Functions/F12.cpp | 24 +++++++++++------------- VoodooRMI/Functions/F12.hpp | 2 -- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/VoodooRMI/Functions/F12.cpp b/VoodooRMI/Functions/F12.cpp index 9043b26..c54f335 100644 --- a/VoodooRMI/Functions/F12.cpp +++ b/VoodooRMI/Functions/F12.cpp @@ -249,6 +249,7 @@ int F12::rmi_f12_read_sensor_tuning() void F12::attention(AbsoluteTime time, UInt8 *data[], size_t *size) { + RMI2DSensorReport report {}; size_t offset = data1_offset; if (*data) { @@ -281,29 +282,26 @@ void F12::attention(AbsoluteTime time, UInt8 *data[], size_t *size) #endif // debug int fingers = min (nbr_fingers, 5); - UInt8 *fingerData = &data_pkt[offset]; - for (int i = 0; i < fingers; i++) { - rmi_2d_sensor_abs_object *obj = &report.objs[i]; + rmi_2d_sensor_abs_object &obj = report.objs[i]; + UInt8 *fingerData = &data_pkt[offset + (fingers * F12_DATA1_BYTES_PER_OBJ)]; switch (fingerData[0]) { case RMI_F12_OBJECT_FINGER: - obj->type = RMI_2D_OBJECT_FINGER; + obj.type = RMI_2D_OBJECT_FINGER; break; case RMI_F12_OBJECT_STYLUS: - obj->type = RMI_2D_OBJECT_STYLUS; + obj.type = RMI_2D_OBJECT_STYLUS; break; default: - obj->type = RMI_2D_OBJECT_NONE; + obj.type = RMI_2D_OBJECT_NONE; } - obj->x = (fingerData[2] << 8) | fingerData[1]; - obj->y = (fingerData[4] << 8) | fingerData[3]; - obj->z = fingerData[5]; - obj->wx = fingerData[6]; - obj->wy = fingerData[7]; - - data += F12_DATA1_BYTES_PER_OBJ; + obj.x = (fingerData[2] << 8) | fingerData[1]; + obj.y = (fingerData[4] << 8) | fingerData[3]; + obj.z = fingerData[5]; + obj.wx = fingerData[6]; + obj.wy = fingerData[7]; } report.timestamp = time; diff --git a/VoodooRMI/Functions/F12.hpp b/VoodooRMI/Functions/F12.hpp index 91ba8a0..03bd5e3 100644 --- a/VoodooRMI/Functions/F12.hpp +++ b/VoodooRMI/Functions/F12.hpp @@ -62,8 +62,6 @@ class F12 : public RMITrackpadFunction { private: IOService *voodooInputInstance {nullptr}; - RMI2DSensorReport report {}; - static rmi_register_desc_item *rmi_get_register_desc_item(rmi_register_descriptor *rdesc, UInt16 reg); static size_t rmi_register_desc_calc_size(rmi_register_descriptor *rdesc); static int rmi_register_desc_calc_reg_offset(rmi_register_descriptor *rdesc, UInt16 reg); From 80a1b9b46dfd21796ce5517c4b586279efdfe968 Mon Sep 17 00:00:00 2001 From: Avery Black Date: Mon, 21 Oct 2024 08:49:24 -0700 Subject: [PATCH 10/11] Fix only reading last finger --- VoodooRMI/Functions/F12.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VoodooRMI/Functions/F12.cpp b/VoodooRMI/Functions/F12.cpp index c54f335..6610997 100644 --- a/VoodooRMI/Functions/F12.cpp +++ b/VoodooRMI/Functions/F12.cpp @@ -284,7 +284,7 @@ void F12::attention(AbsoluteTime time, UInt8 *data[], size_t *size) int fingers = min (nbr_fingers, 5); for (int i = 0; i < fingers; i++) { rmi_2d_sensor_abs_object &obj = report.objs[i]; - UInt8 *fingerData = &data_pkt[offset + (fingers * F12_DATA1_BYTES_PER_OBJ)]; + UInt8 *fingerData = &data_pkt[offset + (i * F12_DATA1_BYTES_PER_OBJ)]; switch (fingerData[0]) { case RMI_F12_OBJECT_FINGER: From 7193d4251b4141b1c293b786ff60bc2b78e19dcf Mon Sep 17 00:00:00 2001 From: Avery Black Date: Tue, 22 Oct 2024 18:59:13 -0700 Subject: [PATCH 11/11] Revert F01 changes --- VoodooRMI/Functions/F01.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/VoodooRMI/Functions/F01.cpp b/VoodooRMI/Functions/F01.cpp index b9ab659..bdf1e72 100644 --- a/VoodooRMI/Functions/F01.cpp +++ b/VoodooRMI/Functions/F01.cpp @@ -375,10 +375,14 @@ int F01::rmi_f01_resume() void F01::attention(AbsoluteTime time, UInt8 *data[], size_t *size) { + IOReturn error; UInt8 device_status = 0; - if (!getInputData(&device_status, sizeof(device_status), data, size)) + error = readByte(getDataAddr(), &device_status); + if (error) { + IOLogError("F01: Failed to read device status: %d", error); return; + } if (RMI_F01_STATUS_BOOTLOADER(device_status)) IOLogError("Device in bootloader mode, please update firmware");