Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMBus Companion Devices #63

Merged
merged 8 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions VoodooPS2Controller.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
CE8DA1C6251839B7008C44E8 /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE8DA1C4251839B2008C44E8 /* libkmod.a */; };
CE8DA1C7251839B9008C44E8 /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE8DA1C4251839B2008C44E8 /* libkmod.a */; };
CE8DA1CC251839BC008C44E8 /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE8DA1C4251839B2008C44E8 /* libkmod.a */; };
EE914A902C952F0D0023CFE0 /* VoodooPS2SMBusDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE914A8E2C952F0D0023CFE0 /* VoodooPS2SMBusDevice.cpp */; };
EE914A912C952F0D0023CFE0 /* VoodooPS2SMBusDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = EE914A8F2C952F0D0023CFE0 /* VoodooPS2SMBusDevice.h */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -131,6 +133,8 @@
EDD95559208E2B640031D99E /* SSDT-Thinkpad_Clickpad.dsl */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SSDT-Thinkpad_Clickpad.dsl"; sourceTree = "<group>"; };
EDD9555A208E2E7A0031D99E /* SSDT-Thinkpad_Trackpad.dsl */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SSDT-Thinkpad_Trackpad.dsl"; sourceTree = "<group>"; };
EDD970FD1FD0B826004CCFFD /* SSDT-HP-FixLidSleep.dsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "SSDT-HP-FixLidSleep.dsl"; sourceTree = "<group>"; };
EE914A8E2C952F0D0023CFE0 /* VoodooPS2SMBusDevice.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VoodooPS2SMBusDevice.cpp; sourceTree = "<group>"; };
EE914A8F2C952F0D0023CFE0 /* VoodooPS2SMBusDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VoodooPS2SMBusDevice.h; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -287,6 +291,8 @@
84833FB0161B62A900845294 /* VoodooPS2SynapticsTouchPad.h */,
84833FAF161B62A900845294 /* VoodooPS2SynapticsTouchPad.cpp */,
4CC27EB2251FBC7700824FE1 /* VoodooPS2TrackpadCommon.h */,
EE914A8F2C952F0D0023CFE0 /* VoodooPS2SMBusDevice.h */,
EE914A8E2C952F0D0023CFE0 /* VoodooPS2SMBusDevice.cpp */,
84167857161B56C4002C60E6 /* Supporting Files */,
);
path = VoodooPS2Trackpad;
Expand Down Expand Up @@ -393,6 +399,7 @@
356B896323007F4F0042F30F /* VoodooInputEvent.h in Headers */,
9828A93024A2B6C200550FAA /* VoodooPS2Elan.h in Headers */,
356B896223007F4F0042F30F /* VoodooInputMessages.h in Headers */,
EE914A912C952F0D0023CFE0 /* VoodooPS2SMBusDevice.h in Headers */,
356B896423007F4F0042F30F /* VoodooInputTransducer.h in Headers */,
84833FB2161B62A900845294 /* VoodooPS2ALPSGlidePoint.h in Headers */,
356B896523007F4F0042F30F /* MultitouchHelpers.h in Headers */,
Expand Down Expand Up @@ -653,6 +660,7 @@
84833FB1161B62A900845294 /* VoodooPS2ALPSGlidePoint.cpp in Sources */,
9828A92F24A2B6C200550FAA /* VoodooPS2Elan.cpp in Sources */,
84833FB3161B62A900845294 /* VoodooPS2SentelicFSP.cpp in Sources */,
EE914A902C952F0D0023CFE0 /* VoodooPS2SMBusDevice.cpp in Sources */,
84833FB5161B62A900845294 /* VoodooPS2SynapticsTouchPad.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
7 changes: 7 additions & 0 deletions VoodooPS2Controller/ApplePS2Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,13 @@ void ApplePS2Device::dispatchMessage(int message, void *data)

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IOReturn ApplePS2Device::startSMBusCompanion(OSDictionary *companionData, UInt8 smbusAddr)
{
return _controller->startSMBusCompanion(companionData, smbusAddr);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

ApplePS2Controller* ApplePS2Device::getController()
{
return _controller;
Expand Down
6 changes: 3 additions & 3 deletions VoodooPS2Controller/ApplePS2Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,8 @@ typedef void (*PS2PowerControlAction)(void * target, UInt32 whatToDo);
// Published property for devices to express interest in receiving messages
#define kDeliverNotifications "RM,deliverNotifications"

#define kSmbusCompanion "VoodooSMBusCompanionDevice"

// Published property for device nub port location
#define kPortKey "Port Num"

Expand All @@ -532,9 +534,6 @@ enum

kPS2M_resetTouchpad = iokit_vendor_specific_msg(151), // Force touchpad reset (data is int*)

// from trackpad on I2C/SMBus
kPS2M_SMBusStart = iokit_vendor_specific_msg(152), // Reset, disable PS2 comms to not interfere with SMBus comms

// from sensor (such as yoga mode indicator) to keyboard
kPS2K_setKeyboardStatus = iokit_vendor_specific_msg(200), // set disable/enable keyboard (data is bool*)
kPS2K_getKeyboardStatus = iokit_vendor_specific_msg(201), // get disable/enable keyboard (data is bool*)
Expand Down Expand Up @@ -607,6 +606,7 @@ class EXPORT ApplePS2Device : public IOService

// Messaging
virtual void dispatchMessage(int message, void *data);
virtual IOReturn startSMBusCompanion(OSDictionary *companionData, UInt8 smbusAddr);

// Exclusive access (command byte contention)

Expand Down
19 changes: 17 additions & 2 deletions VoodooPS2Controller/VoodooPS2Controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ bool ApplePS2Controller::init(OSDictionary* dict)
_deliverNotification = OSSymbol::withCString(kDeliverNotifications);
if (_deliverNotification == NULL)
return false;

_smbusCompanion = OSSymbol::withCString(kSmbusCompanion);
if (_smbusCompanion == NULL)
return false;

queue_init(&_requestQueue);

Expand Down Expand Up @@ -747,6 +751,7 @@ void ApplePS2Controller::stop(IOService * provider)
// Free the RMCF configuration cache
OSSafeReleaseNULL(_rmcfCache);
OSSafeReleaseNULL(_deliverNotification);
OSSafeReleaseNULL(_smbusCompanion);

// Free the request queue lock and empty out the request queue.
if (_requestQueueLock)
Expand Down Expand Up @@ -2126,7 +2131,7 @@ static OSString* getPlatformOverride(IORegistryEntry* reg, const char* sz)
return NULL;
}

static OSString* getPlatformManufacturer(IORegistryEntry* reg)
static LIBKERN_RETURNS_RETAINED OSString* getPlatformManufacturer(IORegistryEntry* reg)
{
// allow override in PS2K ACPI device
OSString* id = getPlatformOverride(reg, "RM,oem-id");
Expand All @@ -2148,7 +2153,7 @@ static OSString* getPlatformManufacturer(IORegistryEntry* reg)
return OSString::withCStringNoCopy(oemID);
}

static OSString* getPlatformProduct(IORegistryEntry* reg)
static LIBKERN_RETURNS_RETAINED OSString* getPlatformProduct(IORegistryEntry* reg)
{
// allow override in PS2K ACPI device
OSString* id = getPlatformOverride(reg, "RM,oem-table-id");
Expand Down Expand Up @@ -2423,3 +2428,13 @@ OSDictionary* ApplePS2Controller::makeConfigurationNode(OSDictionary* list, cons

return result;
}

IOReturn ApplePS2Controller::startSMBusCompanion(OSDictionary *companionData, UInt8 smbusAddr) {
IOReturn ret = callPlatformFunction(_smbusCompanion,
false,
static_cast<void *>(this),
static_cast<void *>(companionData),
reinterpret_cast<void *>(smbusAddr),
nullptr);
return ret;
}
3 changes: 3 additions & 0 deletions VoodooPS2Controller/VoodooPS2Controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ class EXPORT ApplePS2Controller : public IOService
#endif
OSDictionary* _rmcfCache {nullptr};
const OSSymbol* _deliverNotification {nullptr};
const OSSymbol* _smbusCompanion {nullptr};

int _resetControllerFlag {RESET_CONTROLLER_ON_BOOT | RESET_CONTROLLER_ON_WAKEUP};
bool _kbdOnly {0};
Expand Down Expand Up @@ -371,6 +372,8 @@ class EXPORT ApplePS2Controller : public IOService
OSDictionary* getConfigurationOverride(IOACPIPlatformDevice* acpi, const char* method);
OSObject* translateArray(OSArray* array);
OSObject* translateEntry(OSObject* obj);

IOReturn startSMBusCompanion(OSDictionary *companionData, UInt8 smbusAddr);
};

#endif /* _APPLEPS2CONTROLLER_H */
81 changes: 81 additions & 0 deletions VoodooPS2Trackpad/VoodooPS2SMBusDevice.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// VoodooPS2SMBusDevice.cpp
// VoodooPS2Trackpad
//
// Created by Avery Black on 9/13/24.
// Copyright © 2024 Acidanthera. All rights reserved.
//

#include "VoodooPS2SMBusDevice.h"

// =============================================================================
// ApplePS2SmbusDevice Class Implementation
//

OSDefineMetaClassAndStructors(ApplePS2SmbusDevice, IOService);

ApplePS2SmbusDevice *ApplePS2SmbusDevice::withReset(bool resetNeeded, OSDictionary *data, uint8_t addr) {
ApplePS2SmbusDevice *dev = OSTypeAlloc(ApplePS2SmbusDevice);

if (dev == nullptr) {
return nullptr;
}

if (!dev->init()) {
OSSafeReleaseNULL(dev);
return nullptr;
}

dev->_resetNeeded = resetNeeded;
dev->_data = data;
dev->_data->retain();
dev->_addr = addr;
return dev;
}

bool ApplePS2SmbusDevice::start(IOService *provider) {
if (!super::start(provider))
return false;

_nub = OSDynamicCast(ApplePS2MouseDevice, provider);
if (_nub == nullptr)
return false;

if (_resetNeeded)
resetDevice();

if (_nub->startSMBusCompanion(_data, _addr) != kIOReturnSuccess) {
return false;
}

_nub->installPowerControlAction(this,
OSMemberFunctionCast(PS2PowerControlAction, this, &ApplePS2SmbusDevice::powerAction));
return true;
}

void ApplePS2SmbusDevice::free() {
OSSafeReleaseNULL(_data);
super::free();
}

void ApplePS2SmbusDevice::powerAction(uint32_t ordinal) {
if (ordinal == kPS2C_EnableDevice && _resetNeeded) {
(void) resetDevice();
}
}

IOReturn ApplePS2SmbusDevice::resetDevice() {
TPS2Request<> request;
request.commands[0].command = kPS2C_SendCommandAndCompareAck;
request.commands[0].inOrOut = kDP_SetDefaultsAndDisable; // F5
request.commandsCount = 1;
_nub->submitRequestAndBlock(&request);

if (request.commandsCount == 1) {
DEBUG_LOG("VoodooPS2Trackpad: sending $FF failed: %d\n", request.commandsCount);
return kIOReturnError;
}

return kIOReturnSuccess;
}

45 changes: 45 additions & 0 deletions VoodooPS2Trackpad/VoodooPS2SMBusDevice.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// VoodooPS2SMBusDevice.hpp
// VoodooPS2Trackpad
//
// Created by Avery Black on 9/13/24.
// Copyright © 2024 Acidanthera. All rights reserved.
//

#ifndef VoodooPS2SMBusDevice_hpp
#define VoodooPS2SMBusDevice_hpp


#include "../VoodooPS2Controller/ApplePS2MouseDevice.h"
#include <IOKit/IOCommandGate.h>

#include "VoodooPS2TrackpadCommon.h"

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ApplePS2SmbusDevice Class Declaration
// Synaptics and Elans devices still need resets over PS2. This acts as a
// PS/2 stub driver that attaches in lieu of the full touchpad driver to reset
// on wakeups and sleep. This also prevents other devices attaching and using
// the otherwise unused PS/2 interface
//

class EXPORT ApplePS2SmbusDevice : public IOService {
typedef IOService super;
OSDeclareDefaultStructors(ApplePS2SmbusDevice);
public:
static ApplePS2SmbusDevice *withReset(bool resetNeeded, OSDictionary *data, uint8_t addr);

bool start(IOService *provider) override;
void free() override;

private:
ApplePS2MouseDevice *_nub {nullptr};
bool _resetNeeded {false};
OSDictionary *_data {nullptr};
uint8_t _addr{0};

IOReturn resetDevice();
void powerAction(uint32_t ordinal);
};

#endif /* VoodooPS2SMBusDevice_hpp */
Loading
Loading