Skip to content

Commit

Permalink
v1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
hieplpvip committed Sep 13, 2020
1 parent a95b5d9 commit 39c8abe
Show file tree
Hide file tree
Showing 43 changed files with 1,021 additions and 741 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
4 changes: 1 addition & 3 deletions .maciasl
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
[als] --> Ambient Light Sensor patches/NullPatch.txt
[als] Fake ALS patches/fake_als.txt
[als] Patch ALSS patches/patch_alss.txt
[als] Patch ALSC patches/patch_alsc.txt
[kbl] --> Keyboard Backlight patches/NullPatch.txt
[kbl] Ivy Bridge patches/kbl_ivybridge.txt
[kbl] Haswell/Broadwell/Skylake patches/kbl_broadwell.txt
Expand All @@ -23,4 +21,4 @@
[fn] F9 key patches/f9.txt
[fn] F10 key patches/f10.txt
[fn] F11 key patches/f11.txt
[fn] F12 key patches/f12.txt
[fn] F12 key patches/f12.txt
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ matrix:
notification_email: $NOTIFICATION_EMAIL
build_command_prepend: "src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/hieplpvip/AsusSMC/master/Scripts/bootstrap.sh) && eval \"$src\" || exit 1 ; src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/Lilu/master/Lilu/Scripts/covstrap.sh) && eval \"$src\" || exit 1"
build_command: "xcodebuild -configuration Release -sdk macosx10.12"
branch_pattern: master
branch_pattern: ^(master|dev)$
251 changes: 135 additions & 116 deletions AsusHID/AsusHIDDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// AsusHIDDriver.cpp
// AsusHID
//
// Copyright © 2019 Le Bao Hiep. All rights reserved.
// Copyright © 2019-2020 Le Bao Hiep. All rights reserved.
//

#include "AsusHIDDriver.hpp"
Expand All @@ -11,33 +11,30 @@
OSDefineMetaClassAndStructors(AsusHIDDriver, IOHIDEventDriver);

bool AsusHIDDriver::start(IOService *provider) {
DBGLOG("hid", "start is called");

if (!super::start(provider)) {
SYSLOG("hid", "Error loading HID driver");
SYSLOG("hid", "failed to start parent");
return false;
}

hid_interface = OSDynamicCast(IOHIDInterface, provider);
if (!hid_interface)
if (!hid_interface) {
SYSLOG("hid", "failed to cast IOHIDInterface");
return false;
}

OSArray *elements = hid_interface->createMatchingElements();
if (elements) parseCustomKeyboardElements(elements);
//elements->retain();
if (elements) {
parseCustomKeyboardElements(elements);
}
OSSafeReleaseNULL(elements);

setProperty("AsusHIDSupported", true);
setProperty("Copyright", "Copyright © 2019 Le Bao Hiep. All rights reserved.");

extern kmod_info_t kmod_info;
setProperty("AsusSMC-Version", kmod_info.version);
#ifdef DEBUG
setProperty("AsusSMC-Build", "Debug");
#else
setProperty("AsusSMC-Build", "Release");
#endif
setProperty("Copyright", "Copyright © 2019-2020 Le Bao Hiep. All rights reserved.");

asus_kbd_init();
asus_kbd_get_functions();
setProperty("IsKeyboardBacklightSupported", (SUPPORT_KBD_BACKLIGHT & _kbd_function) ? true : false);

auto key = OSSymbol::withCString("AsusSMCCore");
auto dict = propertyMatching(key, kOSBooleanTrue);
Expand All @@ -46,113 +43,95 @@ bool AsusHIDDriver::start(IOService *provider) {
dict->release();

if (_asusSMC) {
setProperty("KeyboardBacklightSupported", true);
_asusSMC->message(kAddAsusHIDDriver, this);
DBGLOG("hid", "Connected with AsusSMC");
_asusSMC->message(kHIDAdd, this);
DBGLOG("hid", "connected with AsusSMC");
}

readyForReports = true;

return true;
}

void AsusHIDDriver::stop(IOService *provider) {
DBGLOG("hid", "stop is called");
if (_asusSMC) {
_asusSMC->message(kDelAsusHIDDriver, this);
DBGLOG("hid", "Disconnected with AsusSMC");
_asusSMC->message(kHIDDelete, this);
DBGLOG("hid", "disconnected with AsusSMC");
}
OSSafeReleaseNULL(_asusSMC);
hid_interface = nullptr;
super::stop(provider);
}

void AsusHIDDriver::parseCustomKeyboardElements(OSArray *elementArray) {
customKeyboardElements = OSArray::withCapacity(4);
UInt32 count, index;
for (index = 0, count = elementArray->getCount(); index < count; index++) {
customKeyboardElements = OSArray::withCapacity(1);
for (uint32_t index = 0, count = elementArray->getCount(); index < count; index++) {
IOHIDElement *element = OSDynamicCast(IOHIDElement, elementArray->getObject(index));
if (!element || element->getUsage() == 0)
continue;
if (element->getType() == kIOHIDElementTypeCollection)
continue;

UInt32 usagePage = element->getUsagePage();
UInt32 usage = element->getUsage();
bool store = false;

switch (usagePage) {
case kHIDPage_AsusVendor:
switch (usage) {
case kHIDUsage_AsusVendor_BrightnessDown:
case kHIDUsage_AsusVendor_BrightnessUp:
case kHIDUsage_AsusVendor_DisplayOff:
case kHIDUsage_AsusVendor_ROG:
case kHIDUsage_AsusVendor_Power4Gear:
case kHIDUsage_AsusVendor_TouchpadToggle:
case kHIDUsage_AsusVendor_Sleep:
case kHIDUsage_AsusVendor_MicMute:
case kHIDUsage_AsusVendor_Camera:
case kHIDUsage_AsusVendor_RFKill:
case kHIDUsage_AsusVendor_Fan:
case kHIDUsage_AsusVendor_Calc:
case kHIDUsage_AsusVendor_Splendid:
case kHIDUsage_AsusVendor_IlluminationUp:
case kHIDUsage_AsusVendor_IlluminationDown:
store = true;
break;
}
break;
case kHIDPage_MicrosoftVendor:
switch (usage) {
case kHIDUsage_MicrosoftVendor_WLAN:
case kHIDUsage_MicrosoftVendor_BrightnessDown:
case kHIDUsage_MicrosoftVendor_BrightnessUp:
case kHIDUsage_MicrosoftVendor_DisplayOff:
case kHIDUsage_MicrosoftVendor_Camera:
case kHIDUsage_MicrosoftVendor_ROG:
store = true;
break;
}
break;
}
if (store)
uint32_t usagePage = element->getUsagePage();
if (usagePage == kHIDPage_AsusVendor || usagePage == kHIDPage_MicrosoftVendor) {
customKeyboardElements->setObject(element);
}
}
setProperty("CustomKeyboardElements", customKeyboardElements);
}

void AsusHIDDriver::handleInterruptReport(AbsoluteTime timeStamp, IOMemoryDescriptor *report, IOHIDReportType reportType, UInt32 reportID) {
DBGLOG("hid", "handleInterruptReport reportLength=%d reportType=%d reportID=%d", report->getLength(), reportType, reportID);
UInt32 index, count;
for (index = 0, count = customKeyboardElements->getCount(); index < count; index++) {
void AsusHIDDriver::handleInterruptReport(uint64_t timeStamp, IOMemoryDescriptor *report, IOHIDReportType reportType, uint32_t reportID) {
DBGLOG("hid", "handleInterruptReport: reportLength=%d reportType=%d reportID=%d", report->getLength(), reportType, reportID);

super::handleInterruptReport(timeStamp, report, reportType, reportID);

if (!readyForReports || reportType != kIOHIDReportTypeInput)
return;

handleKeyboardReportCustom(timeStamp, reportID);
}

void AsusHIDDriver::handleKeyboardReportCustom(uint64_t timeStamp, uint32_t reportID) {
DBGLOG("hid", "handleKeyboardReportCustom: reportID=%d", reportID);

if (!customKeyboardElements) {
DBGLOG("hid", "handleInterruptReport: null customKeyboardElements");
return;
}

for (uint32_t index = 0, count = customKeyboardElements->getCount(); index < count; index++) {
IOHIDElement *element;
AbsoluteTime elementTimeStamp;
UInt32 usagePage, usage, value, preValue;
uint64_t elementTimeStamp;
uint32_t usagePage, usage, value, preValue;

element = OSDynamicCast(IOHIDElement, customKeyboardElements->getObject(index));
if (!element || element->getReportID() != reportID)
continue;

elementTimeStamp = element->getTimeStamp();
if (CMP_ABSOLUTETIME(&timeStamp, &elementTimeStamp) != 0)
if (timeStamp != elementTimeStamp)
continue;

usagePage = element->getUsagePage();
usage = element->getUsage();

preValue = element->getValue(kIOHIDValueOptionsFlagPrevious) != 0;
value = element->getValue() != 0;

// Fix for double reports of KBD illumination (credits @black-dragon74)
if (usagePage == kHIDPage_AsusVendor && (usage == kHIDUsage_AsusVendor_IlluminationUp || usage == kHIDUsage_AsusVendor_IlluminationDown)) {
value = element->getValue(kIOHIDValueOptionsFlagRelativeSimple) != 0;
} else {
value = element->getValue() != 0;
}

if (value == preValue)
continue;

usagePage = element->getUsagePage();
usage = element->getUsage();

dispatchKeyboardEvent(timeStamp, usagePage, usage, value);
return;
}
super::handleInterruptReport(timeStamp, report, reportType, reportID);
}

void AsusHIDDriver::dispatchKeyboardEvent(AbsoluteTime timeStamp, UInt32 usagePage, UInt32 usage, UInt32 value, IOOptionBits options) {
DBGLOG("hid", "dispatchKeyboardEvent usagePage=%d usage=%d", usagePage, usage);
void AsusHIDDriver::dispatchKeyboardEvent(uint64_t timeStamp, uint32_t usagePage, uint32_t usage, uint32_t value, IOOptionBits options) {
if (usagePage == kHIDPage_AsusVendor) {
switch (usage) {
case kHIDUsage_AsusVendor_BrightnessDown:
Expand All @@ -172,23 +151,21 @@ void AsusHIDDriver::dispatchKeyboardEvent(AbsoluteTime timeStamp, UInt32 usagePa
usage = kHIDUsage_AV_TopCase_IlluminationDown;
break;
case kHIDUsage_AsusVendor_Sleep:
if (value && _asusSMC) _asusSMC->message(kSleep, this);
return;
if (value && _asusSMC) _asusSMC->message(kHIDSleep, this);
break;
case kHIDUsage_AsusVendor_TouchpadToggle:
if (value && _asusSMC) _asusSMC->message(kTouchpadToggle, this);
return;
if (value && _asusSMC) _asusSMC->message(kHIDTouchpadToggle, this);
break;
case kHIDUsage_AsusVendor_DisplayOff:
if (value && _asusSMC) _asusSMC->message(kDisplayOff, this);
return;
default:
return;
if (value && _asusSMC) _asusSMC->message(kHIDDisplayOff, this);
break;
}
}
if (usagePage == kHIDPage_MicrosoftVendor) {
switch (usage) {
case kHIDUsage_MicrosoftVendor_WLAN:
if (value && _asusSMC) _asusSMC->message(kAirplaneMode, this);
return;
if (value && _asusSMC) _asusSMC->message(kHIDAirplaneMode, this);
break;
case kHIDUsage_MicrosoftVendor_BrightnessDown:
usagePage = kHIDPage_AppleVendorTopCase;
usage = kHIDUsage_AV_TopCase_BrightnessDown;
Expand All @@ -198,52 +175,94 @@ void AsusHIDDriver::dispatchKeyboardEvent(AbsoluteTime timeStamp, UInt32 usagePa
usage = kHIDUsage_AV_TopCase_BrightnessUp;
break;
case kHIDUsage_MicrosoftVendor_DisplayOff:
if (value && _asusSMC) _asusSMC->message(kDisplayOff, this);
return;
default:
if (value && _asusSMC) _asusSMC->message(kHIDDisplayOff, this);
break;
}
}

// Fix erratic caps lock key (credits @black-dragon74)
if (usage == kHIDUsage_KeyboardCapsLock) {
IOSleep(80);
}

DBGLOG("hid", "dispatchKeyboardEvent usagePage=%d usage=%d value=%d", usagePage, usage, value);
super::dispatchKeyboardEvent(timeStamp, usagePage, usage, value, options);
}

void AsusHIDDriver::setKeyboardBacklight(uint8_t val) {
asus_kbd_backlight_set(val / 64);
void AsusHIDDriver::setKeyboardBacklight(uint16_t val) {
asus_kbd_backlight_set(val);
}

#pragma mark -
#pragma mark Ported from hid-asus.c
#pragma mark -

void AsusHIDDriver::asus_kbd_init() {
uint8_t buf[] = { KBD_FEATURE_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
OSData* dat = OSData::withBytes(buf, KBD_FEATURE_REPORT_SIZE);
IOBufferMemoryDescriptor* report = IOBufferMemoryDescriptor::withBytes(dat->getBytesNoCopy(0, KBD_FEATURE_REPORT_SIZE), dat->getLength(), kIODirectionInOut);

IOBufferMemoryDescriptor *report = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionInOut, sizeof(buf));
if (!report) {
SYSLOG("hid", "asus_kbd_init: Could not allocate IOBufferMemoryDescriptor");
return;
}

report->writeBytes(0, buf, sizeof(buf));

hid_interface->setReport(report, kIOHIDReportTypeFeature, KBD_FEATURE_REPORT_ID);
dat->release();

report->release();
}

void AsusHIDDriver::asus_kbd_backlight_set(uint8_t val) {
DBGLOG("hid", "asus_kbd_backlight_set val=%d", val);
uint8_t buf[] = { KBD_FEATURE_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
buf[4] = val;
OSData* dat = OSData::withBytes(buf, KBD_FEATURE_REPORT_SIZE);
IOBufferMemoryDescriptor* report = IOBufferMemoryDescriptor::withBytes(dat->getBytesNoCopy(0, KBD_FEATURE_REPORT_SIZE), dat->getLength(), kIODirectionInOut);
void AsusHIDDriver::asus_kbd_get_functions() {
uint8_t buf[] = { KBD_FEATURE_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };

IOBufferMemoryDescriptor *report = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionInOut, sizeof(buf));
if (!report) {
SYSLOG("hid", "asus_kbd_get_functions: Could not allocate IOBufferMemoryDescriptor");
return;
}

report->writeBytes(0, buf, sizeof(buf));

hid_interface->setReport(report, kIOHIDReportTypeFeature, KBD_FEATURE_REPORT_ID);
dat->release();

hid_interface->getReport(report, kIOHIDReportTypeFeature, KBD_FEATURE_REPORT_ID);

uint8_t *func = (uint8_t *)IOMalloc(KBD_FEATURE_REPORT_SIZE);

if (!func) {
SYSLOG("hid", "asus_kbd_get_functions: Could not allocate memory for reading report");
goto exit;
}

report->prepare();
report->readBytes(0, func, KBD_FEATURE_REPORT_SIZE);
report->complete();

_kbd_function = func[6];

IOFree(func, KBD_FEATURE_REPORT_SIZE);

exit:
report->release();
}

void AsusHIDDriver::asus_kbd_get_functions(uint8_t *kbd_func) {
uint8_t buf[] = { KBD_FEATURE_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
OSData* dat = OSData::withBytes(buf, KBD_FEATURE_REPORT_SIZE);
IOBufferMemoryDescriptor* report = IOBufferMemoryDescriptor::withBytes(dat->getBytesNoCopy(0, KBD_FEATURE_REPORT_SIZE), dat->getLength(), kIODirectionInOut);
void AsusHIDDriver::asus_kbd_backlight_set(uint8_t val) {
DBGLOG("hid", "asus_kbd_backlight_set: val=%d", val);

if (!(SUPPORT_KBD_BACKLIGHT & _kbd_function)) {
DBGLOG("hid", "asus_kbd_backlight_set: Keyboard backlight is not supported");
return;
}

uint8_t buf[] = { KBD_FEATURE_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00 };
buf[4] = val;

IOBufferMemoryDescriptor *report = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionInOut, sizeof(buf));
if (!report) {
SYSLOG("hid", "asus_kbd_backlight_set: Could not allocate IOBufferMemoryDescriptor");
return;
}

report->writeBytes(0, buf, sizeof(buf));

hid_interface->setReport(report, kIOHIDReportTypeFeature, KBD_FEATURE_REPORT_ID);
hid_interface->getReport(report, kIOHIDReportTypeFeature, KBD_FEATURE_REPORT_ID);
uint8_t readbuf[KBD_FEATURE_REPORT_SIZE] = {};
report->readBytes(0, &readbuf, KBD_FEATURE_REPORT_SIZE);
*kbd_func = readbuf[6];
dat->release();

report->release();
}
Loading

0 comments on commit 39c8abe

Please sign in to comment.