Repository: hieplpvip/AsusSMC Branch: master Commit: c15d2f297c86 Files: 49 Total size: 128.3 KB Directory structure: gitextract_5ssq1r4m/ ├── .gitattributes ├── .gitignore ├── .maciasl ├── .travis.yml ├── AsusSMC/ │ ├── AsusSMC.cpp │ ├── AsusSMC.hpp │ ├── Info.plist │ ├── KeyImplementations.cpp │ └── KeyImplementations.hpp ├── AsusSMC.xcodeproj/ │ └── project.pbxproj ├── AsusSMCDaemon/ │ ├── BezelServices.h │ ├── OSD.h │ ├── com.hieplpvip.AsusSMCDaemon.plist │ ├── install_daemon.sh │ └── main.m ├── CHANGELOG.md ├── Global/ │ ├── HIDReport.hpp │ └── HIDUsageTables.h ├── KernEventServer/ │ ├── KernEventServer.cpp │ └── KernEventServer.hpp ├── LICENSE.md ├── README.md ├── Scripts/ │ └── bootstrap.sh ├── VirtualAppleKeyboard/ │ ├── VirtualAppleKeyboard.cpp │ └── VirtualAppleKeyboard.hpp └── patches/ ├── NullPatch.txt ├── als_toggle.txt ├── f1.txt ├── f10.txt ├── f11.txt ├── f12.txt ├── f2.txt ├── f3.txt ├── f4.txt ├── f5.txt ├── f6.txt ├── f7.txt ├── f8.txt ├── f9.txt ├── fake_als.txt ├── kbl_broadwell.txt ├── kbl_coffeelake.txt ├── kbl_icelake.txt ├── kbl_ivybridge.txt ├── kbl_kabylake.txt ├── kbl_tuf.txt ├── kbl_whiskeylake.txt ├── media_arrow.txt └── media_cvspace.txt ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ * text=auto eol=lf ================================================ FILE: .gitignore ================================================ .DS_Store DerivedData Lilu.kext VirtualSMC.kext xcuserdata xcshareddata project.xcworkspace build .idea .vscode .svace-dir cov-int /MacKernelSDK ================================================ FILE: .maciasl ================================================ [als] --> Ambient Light Sensor patches/NullPatch.txt [als] Fake ALS patches/fake_als.txt [kbl] --> Keyboard Backlight patches/NullPatch.txt [kbl] Ivy Bridge patches/kbl_ivybridge.txt [kbl] Haswell/Broadwell/Skylake patches/kbl_broadwell.txt [kbl] Kaby Lake/Kaby Lake-R patches/kbl_kabylake.txt [kbl] Whiskey Lake patches/kbl_whiskeylake.txt [kbl] Coffee Lake patches/kbl_coffeelake.txt [kbl] Ice Lake patches/kbl_icelake.txt [fn] --> FN keys patches/NullPatch.txt [fn] ALS toggle patches/als_toggle.txt [fn] Media - arrow keys patches/media_arrow.txt [fn] Media - Space, C, V patches/media_cvspace.txt [fn] F1 key patches/f1.txt [fn] F2 key patches/f2.txt [fn] F3 key patches/f3.txt [fn] F4 key patches/f4.txt [fn] F5 key patches/f5.txt [fn] F6 key patches/f6.txt [fn] F7 key patches/f7.txt [fn] F8 key patches/f8.txt [fn] F9 key patches/f9.txt [fn] F10 key patches/f10.txt [fn] F11 key patches/f11.txt [fn] F12 key patches/f12.txt ================================================ FILE: .travis.yml ================================================ language: cpp matrix: include: - os: osx name: "Build" osx_image: xcode11.6 compiler: clang script: - git clone https://github.com/acidanthera/MacKernelSDK - src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/hieplpvip/AsusSMC/master/Scripts/bootstrap.sh) && eval "$src" || exit 1 - xcodebuild -jobs 1 -configuration Debug - xcodebuild -jobs 1 -configuration Release deploy: provider: releases skip_cleanup: true file: "build/*/*.zip" file_glob: true api_key: secure: "BOTxFlC2lE8LtOZ0eVXz5eQRV21a248Rirr3Fvsj51kzvUpExtcdlpWv+xFOlIIqsZb2luzj6q1cG8bNpWWp2/EseHdtWqF2/ZwfBLs2XdXTyS5aunUxbZ4FHLhMPDRgNunTcoZuzMRtSAyNl5maGKveKN9irWwI1HbKOh4p9jQDATA2QNDC6v/uQ1fJR3Vjiye9nIKk6SOhmy62qBCjLzEEe0SiRYw2ewMjm0eybfHt3YNwRy2lBfKXpnxsapA41kq4B/ThoJk3TFmRRZDzveJin20CXI2L2jvN9K2d2gWncHG5oRV63m+4CBGl7MLxJaAHD7flGmr4l2qFbIUgMXGlKmQSo7SJEO09K6weG2n6duqXxprnQSyFCOERRu0KyDPHnSUkr6y5FBTkkV3YMOUXRVUk7pA+kOlKjV89O6WLxpirZ9NzGz9jlKg32wTTyj9UBYcrCDIOravL/eTZ7g+xdXNV9vKyhsN2v3iPmHQ+DNJ73DdZjhj+BFT56E8Fz+r5aF13Z6tGVChKNqe3+CYih59Tgzwd+y5YU0Et4b/55Qkh/MexXm8YqJNzzZD7jRKpP3zlOFNuAxIDlBXYUtfgYh5CmcXlOgk8626JDFUSakjwYfxE2+rpQxyhAVNn/etmaSOfsL1pbKDjE1aM0M4Pho68dOju/k4Vb0x4FgA=" on: tags: true - os: osx name: "Analyze Clang" osx_image: xcode11 compiler: clang script: - git clone https://github.com/acidanthera/MacKernelSDK - src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/hieplpvip/AsusSMC/master/Scripts/bootstrap.sh) && eval "$src" || exit 1 - xcodebuild analyze -quiet -configuration Debug CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR="$(pwd)/clang-analyze" && [ "$(find clang-analyze -name "*.html")" = "" ] - xcodebuild analyze -quiet -configuration Release CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR="$(pwd)/clang-analyze" && [ "$(find clang-analyze -name "*.html")" = "" ] - os: osx name: "Analyze Coverity" osx_image: xcode10.2 compiler: clang before_install: - git clone https://github.com/acidanthera/MacKernelSDK - curl -Ls https://entrust.com/root-certificates/entrust_l1k.cer -o ~/entrust_l1k.crt || exit 1 - curl -LS https://curl.haxx.se/ca/cacert.pem -o ~/cacert.pem || exit 1 - cat ~/entrust_l1k.crt >> ~/cacert.pem || exit 1 - echo "cacert=\"$HOME/cacert.pem\"" > ~/.curlrc || exit 1 - echo "ca_certificate=$HOME/cacert.pem" > ~/.wgetrc || exit 1 script: - echo "This script runs coverity..." addons: coverity_scan: project: name: "hieplpvip/AsusSMC" description: "AsusSMC" 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" branch_pattern: ^(master|dev)$ ================================================ FILE: AsusSMC/AsusSMC.cpp ================================================ // // AsusSMC.cpp // AsusSMC // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #include "AsusSMC.hpp" bool ADDPR(debugEnabled) = false; uint32_t ADDPR(debugPrintDelay) = 0; #define super IOService OSDefineMetaClassAndStructors(AsusSMC, IOService) bool AsusSMC::init(OSDictionary *dict) { if (!super::init(dict)) { return false; } _notificationServices = OSSet::withCapacity(1); kev.setVendorID("com.hieplpvip"); kev.setEventCode(AsusSMCEventCode); atomic_init(¤tLux, 0); atomic_init(¤tFanSpeed, 0); return true; } IOService *AsusSMC::probe(IOService *provider, SInt32 *score) { if (!super::probe(provider, score)) { return NULL; } IOACPIPlatformDevice *dev = OSDynamicCast(IOACPIPlatformDevice, provider); if (!dev) { return NULL; } OSObject *obj; dev->evaluateObject("_UID", &obj); OSString *name = OSDynamicCast(OSString, obj); if (!name) { return NULL; } IOService *ret = NULL; if (name->isEqualTo("ATK")) { ret = this; } name->release(); return ret; } bool AsusSMC::start(IOService *provider) { if (!provider || !super::start(provider)) { SYSLOG("atk", "failed to start parent"); return false; } atkDevice = (IOACPIPlatformDevice *)provider; parse_WDG(); initATKDevice(); initALSDevice(); initEC0Device(); initBattery(); initVirtualKeyboard(); startATKDevice(); workloop = getWorkLoop(); if (!workloop) { DBGLOG("atk", "Failed to get workloop"); return false; } workloop->retain(); command_gate = IOCommandGate::commandGate(this); if (!command_gate || (workloop->addEventSource(command_gate) != kIOReturnSuccess)) { DBGLOG("atk", "Could not open command gate"); return false; } setProperty("IsTouchpadEnabled", true); setProperty("Copyright", "Copyright © 2018-2020 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 registerNotifications(); registerVSMC(); registerService(); return true; } void AsusSMC::stop(IOService *provider) { if (poller) { poller->cancelTimeout(); } if (workloop && poller) { workloop->removeEventSource(poller); } if (workloop && command_gate) { workloop->removeEventSource(command_gate); } OSSafeReleaseNULL(workloop); OSSafeReleaseNULL(poller); OSSafeReleaseNULL(command_gate); _publishNotify->remove(); _terminateNotify->remove(); _notificationServices->flushCollection(); OSSafeReleaseNULL(_publishNotify); OSSafeReleaseNULL(_terminateNotify); OSSafeReleaseNULL(_notificationServices); OSSafeReleaseNULL(kbdDevice); super::stop(provider); return; } IOReturn AsusSMC::message(uint32_t type, IOService *provider, void *argument) { DBGLOG("atk", "Received message: %u Type %x Provider %s", *((uint32_t *)argument), type, provider ? provider->getName() : "unknown"); switch (type) { case kIOACPIMessageDeviceNotification: { if (directACPImessaging) { handleMessage(*((uint32_t *)argument)); } else { uint32_t event = *((uint32_t *)argument); OSNumber *arg = OSNumber::withNumber(event, 32); uint32_t res; atkDevice->evaluateInteger("_WED", &res, (OSObject **)&arg, 1); arg->release(); handleMessage(res); } break; } case kSetKeyboardBacklightMessage: { if (hasKeyboardBacklight) { OSNumber *arg = OSNumber::withNumber(*((uint16_t *)argument) / 16, 16); atkDevice->evaluateObject("SKBV", NULL, (OSObject **)&arg, 1); arg->release(); } break; } default: return kIOReturnInvalid; } return kIOReturnSuccess; } int AsusSMC::wmi_parse_guid(const char *in, char *out) { for (int i = 3; i >= 0; i--) { out += snprintf(out, 3, "%02X", in[i] & 0xFF); } out += snprintf(out, 2, "-"); out += snprintf(out, 3, "%02X", in[5] & 0xFF); out += snprintf(out, 3, "%02X", in[4] & 0xFF); out += snprintf(out, 2, "-"); out += snprintf(out, 3, "%02X", in[7] & 0xFF); out += snprintf(out, 3, "%02X", in[6] & 0xFF); out += snprintf(out, 2, "-"); out += snprintf(out, 3, "%02X", in[8] & 0xFF); out += snprintf(out, 3, "%02X", in[9] & 0xFF); out += snprintf(out, 2, "-"); for (int i = 10; i <= 15; i++) { out += snprintf(out, 3, "%02X", in[i] & 0xFF); } *out = '\0'; return 0; } int AsusSMC::wmi_evaluate_method(uint32_t method_id, uint32_t arg0, uint32_t arg1) { OSObject *params[3]; struct wmi_args args = { .arg0 = arg0, .arg1 = arg1 }; params[0] = OSNumber::withNumber(static_cast(0), 32); params[1] = OSNumber::withNumber(method_id, 32); params[2] = OSData::withBytes(&args, sizeof(wmi_args)); uint32_t val; IOReturn ret = atkDevice->evaluateInteger(wmi_method, &val, params, 3); params[0]->release(); params[1]->release(); params[2]->release(); if (ret != kIOReturnSuccess) { DBGLOG("wmi", "wmi_evaluate_method failed"); return -1; } if (val == 0xfffffffe) { DBGLOG("wmi", "wmi_evaluate_method invalid method_id"); return -1; } return val; } int AsusSMC::wmi_get_devstate(uint32_t dev_id) { return wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, dev_id, 0); } bool AsusSMC::wmi_dev_is_present(uint32_t dev_id) { int status = wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, dev_id, 0); return status != -1 && (status & ASUS_WMI_DSTS_PRESENCE_BIT); } void AsusSMC::parse_WDG() { OSObject *wdg; if (atkDevice->evaluateObject("_WDG", &wdg) != kIOReturnSuccess) { SYSLOG("wmi", "No method _WDG!"); return; } OSData *data = OSDynamicCast(OSData, wdg); if (!data) { SYSLOG("guid", "Cast WDG error!"); return; } int total = data->getLength() / sizeof(struct guid_block); char guid_string[37]; for (int i = 0; i < total; i++) { struct guid_block *g = (struct guid_block *) data->getBytesNoCopy(i * sizeof(struct guid_block), sizeof(struct guid_block)); wmi_parse_guid(g->guid, guid_string); if (strncmp(guid_string, ASUS_WMI_MGMT_GUID, 36) == 0) { snprintf(wmi_method, 5, "WM%c%c", g->object_id[0], g->object_id[1]); DBGLOG("wmi", "parse_WDG found WMI method %s", wmi_method); return; } } // Couldn't find WMI method. Let's assume it's WMNB SYSLOG("wmi", "parse_WDG couldn't find WMI method"); lilu_os_strncpy(wmi_method, "WMNB", 5); } void AsusSMC::initATKDevice() { wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0); } void AsusSMC::initALSDevice() { auto dict = IOService::nameMatching("AppleACPIPlatformExpert"); if (!dict) { SYSLOG("als", "WTF? Failed to create matching dictionary"); return; } auto acpi = IOService::waitForMatchingService(dict); dict->release(); if (!acpi) { SYSLOG("als", "WTF? No ACPI"); return; } acpi->release(); dict = IOService::nameMatching("ACPI0008"); if (!dict) { SYSLOG("als", "WTF? Failed to create matching dictionary"); return; } auto deviceIterator = IOService::getMatchingServices(dict); dict->release(); if (!deviceIterator) { SYSLOG("als", "No iterator"); return; } alsDevice = OSDynamicCast(IOACPIPlatformDevice, deviceIterator->getNextObject()); deviceIterator->release(); if (!alsDevice) { SYSLOG("als", "ACPI0008 device not found"); return; } if (alsDevice->validateObject("_ALI") != kIOReturnSuccess || !refreshALS(false)) { SYSLOG("als", "No functional method _ALI on ALS device"); return; } SYSLOG("als", "Found ALS Device %s", alsDevice->getName()); } void AsusSMC::initEC0Device() { isTACHAvailable = true; auto dict = IOService::nameMatching("AppleACPIPlatformExpert"); if (!dict) { SYSLOG("ec0", "WTF? Failed to create matching dictionary"); isTACHAvailable = false; return; } auto acpi = IOService::waitForMatchingService(dict); dict->release(); if (!acpi) { SYSLOG("ec0", "WTF? No ACPI"); isTACHAvailable = false; return; } acpi->release(); dict = IOService::nameMatching("PNP0C09"); if (!dict) { SYSLOG("ec0", "WTF? Failed to create matching dictionary"); isTACHAvailable = false; return; } auto deviceIterator = IOService::getMatchingServices(dict); dict->release(); if (!deviceIterator) { SYSLOG("ec0", "No iterator"); isTACHAvailable = false; return; } ec0Device = OSDynamicCast(IOACPIPlatformDevice, deviceIterator->getNextObject()); deviceIterator->release(); if (!ec0Device) { SYSLOG("ec0", "PNP0C09 device not found"); isTACHAvailable = false; return; } if (ec0Device->validateObject("TACH") != kIOReturnSuccess || !refreshFan()) { SYSLOG("ec0", "No functional method TACH on EC0 device"); isTACHAvailable = false; return; } SYSLOG("ec0", "Found EC0 Device %s", ec0Device->getName()); } void AsusSMC::initBattery() { // Battery Health was introduced in 10.15.5 // Check if we're on 10.15.5+ if (getKernelVersion() < KernelVersion::Catalina || (getKernelVersion() == KernelVersion::Catalina && getKernelMinorVersion() < 5)) { return; } isBatteryRSOCAvailable = wmi_dev_is_present(ASUS_WMI_DEVID_RSOC); if (isBatteryRSOCAvailable) { toggleBatteryConservativeMode(true); } } void AsusSMC::initVirtualKeyboard() { kbdDevice = new VirtualAppleKeyboard; if (!kbdDevice || !kbdDevice->init() || !kbdDevice->attach(this) || !kbdDevice->start(this)) { OSSafeReleaseNULL(kbdDevice); SYSLOG("vkbd", "Failed to init VirtualAppleKeyboard"); } } void AsusSMC::startATKDevice() { // Check direct ACPI messaging support if (atkDevice->validateObject("DMES") == kIOReturnSuccess) { DBGLOG("atk", "Direct ACPI message is supported"); setProperty("IsDirectACPIMessagingSupported", kOSBooleanTrue); directACPImessaging = true; } // Check keyboard backlight support if (atkDevice->validateObject("SKBV") == kIOReturnSuccess) { SYSLOG("atk", "Keyboard backlight is supported"); hasKeyboardBacklight = true; } else { hasKeyboardBacklight = false; DBGLOG("atk", "Keyboard backlight is not supported"); } setProperty("IsKeyboardBacklightSupported", hasKeyboardBacklight); // Turn on ALS sensor toggleALS(true); isALSEnabled = true; setProperty("IsALSEnabled", isALSEnabled); SYSLOG("atk", "ALS is turned on at boot"); } bool AsusSMC::refreshALS(bool post) { if (!alsDevice) { return false; } IOReturn ret = kIOReturnSuccess; uint32_t lux = 150; if (isALSEnabled) { ret = alsDevice->evaluateInteger("_ALI", &lux); if (ret != kIOReturnSuccess) { lux = 0xFFFFFFFF; // ACPI invalid } } atomic_store_explicit(¤tLux, lux, memory_order_release); if (post) { VirtualSMCAPI::postInterrupt(SmcEventALSChange); poller->setTimeoutMS(SensorUpdateTimeoutMS); } DBGLOG("als", "refreshALS lux %u", lux); return ret == kIOReturnSuccess; } bool AsusSMC::refreshFan() { uint32_t speed = 10000; if (isTACHAvailable) { OSNumber *arg = OSNumber::withNumber(static_cast(0), 32); IOReturn ret = ec0Device->evaluateInteger("TACH", &speed, (OSObject **)&arg, 1); arg->release(); if (ret != kIOReturnSuccess) { DBGLOG("fan", "read fan speed using TACH failed"); speed = 10000; } } else { int ret = wmi_get_devstate(ASUS_WMI_DEVID_CPU_FAN_CTRL); if (ret == -1) { DBGLOG("fan", "read fan speed using WMI failed"); speed = 10000; } else { speed = (ret & 0xffff) * 100; } } atomic_store_explicit(¤tFanSpeed, speed, memory_order_release); DBGLOG("fan", "refreshFan speed %u", speed); return speed != 10000; } void AsusSMC::handleMessage(int code) { switch (code) { case 0x57: // AC disconnected case 0x58: // AC connected // ignore silently break; case 0x30: // Volume up dispatchCSMRReport(kHIDUsage_Csmr_VolumeIncrement); break; case 0x31: // Volume down dispatchCSMRReport(kHIDUsage_Csmr_VolumeDecrement); break; case 0x32: // Mute dispatchCSMRReport(kHIDUsage_Csmr_Mute); break; // Media buttons case 0x40: case 0x8A: dispatchCSMRReport(kHIDUsage_Csmr_ScanPreviousTrack); break; case 0x41: case 0x82: dispatchCSMRReport(kHIDUsage_Csmr_ScanNextTrack); break; case 0x45: case 0x5C: dispatchCSMRReport(kHIDUsage_Csmr_PlayOrPause); break; case 0x33: // hardwired On case 0x34: // hardwired Off case 0x35: // Soft Event, Fn + F7 displayOff(); break; case 0x61: // Video Mirror dispatchTCReport(kHIDUsage_AV_TopCase_VideoMirror); break; case 0x6B: // Fn + F9, Touchpad On/Off toggleTouchpad(); break; case 0x5E: letSleep(); break; case 0x7A: // Fn + A, ALS Sensor // We should really do this in userspace // (e.g. "Automatically adjust brightness") isALSEnabled = !isALSEnabled; setProperty("IsALSEnabled", isALSEnabled); break; case 0x7D: // Airplane mode toggleAirplaneMode(); break; case 0xC6: case 0xC7: // ALS Notifcations // ignore break; case 0xC5: // Keyboard Backlight Down if (hasKeyboardBacklight) { dispatchTCReport(kHIDUsage_AV_TopCase_IlluminationDown); } break; case 0xC4: // Keyboard Backlight Up if (hasKeyboardBacklight) { dispatchTCReport(kHIDUsage_AV_TopCase_IlluminationUp); } break; default: if (code >= NOTIFY_BRIGHTNESS_DOWN_MIN && code<= NOTIFY_BRIGHTNESS_DOWN_MAX) // Brightness Down dispatchTCReport(kHIDUsage_AV_TopCase_BrightnessDown); else if (code >= NOTIFY_BRIGHTNESS_UP_MIN && code<= NOTIFY_BRIGHTNESS_UP_MAX) // Brightness Up dispatchTCReport(kHIDUsage_AV_TopCase_BrightnessUp); break; } DBGLOG("atk", "Received key %d(0x%x)", code, code); } void AsusSMC::letSleep() { kev.sendMessage(kDaemonSleep, 0, 0); } void AsusSMC::toggleAirplaneMode() { kev.sendMessage(kDaemonAirplaneMode, 0, 0); } void AsusSMC::toggleTouchpad() { dispatchMessage(kKeyboardGetTouchStatus, &isTouchpadEnabled); isTouchpadEnabled = !isTouchpadEnabled; dispatchMessage(kKeyboardSetTouchStatus, &isTouchpadEnabled); if (isTouchpadEnabled) { setProperty("IsTouchpadEnabled", true); DBGLOG("atk", "Enabled Touchpad"); } else { setProperty("IsTouchpadEnabled", false); DBGLOG("atk", "Disabled Touchpad"); } } void AsusSMC::toggleALS(bool state) { if (wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, ASUS_WMI_DEVID_ALS_ENABLE, state ? 1 : 0) == -1) { SYSLOG("atk", "Failed to %s ALSC", state ? "enable" : "disable"); } else { DBGLOG("atk", "ALS is %s", state ? "enabled" : "disabled"); } } void AsusSMC::toggleBatteryConservativeMode(bool state) { if (!isBatteryRSOCAvailable) { DBGLOG("batt", "RSOC unavailable"); return; } if (wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, ASUS_WMI_DEVID_RSOC, state ? 80 : 100) != 1) { SYSLOG("batt", "Failed to %s battery conservative mode", state ? "enable" : "disable"); } else { DBGLOG("batt", "Battery conservative mode is %s", state ? "enabled" : "disabled"); setProperty("BatteryConservativeMode", state); } } void AsusSMC::displayOff() { if (isPanelBackLightOn) { // Read Panel brigthness value to restore later with backlight toggle readPanelBrightnessValue(); dispatchTCReport(kHIDUsage_AV_TopCase_BrightnessDown, 16); } else { dispatchTCReport(kHIDUsage_AV_TopCase_BrightnessUp, panelBrightnessLevel); } isPanelBackLightOn = !isPanelBackLightOn; } int AsusSMC::checkBacklightEntry() { if (IORegistryEntry *bkl = IORegistryEntry::fromPath(backlightEntry)) { OSSafeReleaseNULL(bkl); return 1; } else { DBGLOG("atk", "Failed to find backlight entry for %s", backlightEntry); return 0; } } int AsusSMC::findBacklightEntry() { // Check for previous found backlight entry if (checkBacklightEntry()) { return 1; } snprintf(backlightEntry, sizeof(backlightEntry), "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@0/display0/AppleBacklightDisplay"); if (checkBacklightEntry()) { return 1; } snprintf(backlightEntry, sizeof(backlightEntry), "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/GFX0@2/AppleIntelFramebuffer@0/display0/AppleBacklightDisplay"); if (checkBacklightEntry()) { return 1; } char deviceName[5][5] = {"PEG0", "PEGP", "PEGR", "P0P2", "IXVE"}; for (int i = 0; i < 5; i++) { snprintf(backlightEntry, sizeof(backlightEntry), "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/%s@1/IOPP/GFX0@0/NVDA,Display-A@0/NVDA/display0/AppleBacklightDisplay", deviceName[i]); if (checkBacklightEntry()) { return 1; } snprintf(backlightEntry, sizeof(backlightEntry), "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/%s@3/IOPP/GFX0@0/NVDA,Display-A@0/NVDATesla/display0/AppleBacklightDisplay", deviceName[i]); if (checkBacklightEntry()) { return 1; } snprintf(backlightEntry, sizeof(backlightEntry), "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/%s@10/IOPP/GFX0@0/NVDA,Display-A@0/NVDATesla/display0/AppleBacklightDisplay", deviceName[i]); if (checkBacklightEntry()) { return 1; } snprintf(backlightEntry, sizeof(backlightEntry), "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/%s@1/IOPP/display@0/NVDA,Display-A@0/NVDA/display0/AppleBacklightDisplay", deviceName[i]); if (checkBacklightEntry()) { return 1; } snprintf(backlightEntry, sizeof(backlightEntry), "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/%s@3/IOPP/display@0/NVDA,Display-A@0/NVDATesla/display0/AppleBacklightDisplay", deviceName[i]); if (checkBacklightEntry()) { return 1; } snprintf(backlightEntry, sizeof(backlightEntry), "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/%s@10/IOPP/display@0/NVDA,Display-A@0/NVDATesla/display0/AppleBacklightDisplay", deviceName[i]); if (checkBacklightEntry()) { return 1; } } return 0; } void AsusSMC::readPanelBrightnessValue() { if (!findBacklightEntry()) { DBGLOG("atk", "GPU device not found"); return; } IORegistryEntry *displayDeviceEntry = IORegistryEntry::fromPath(backlightEntry); if (displayDeviceEntry) { if (OSDictionary *ioDisplayParaDict = OSDynamicCast(OSDictionary, displayDeviceEntry->getProperty("IODisplayParameters"))) { if (OSDictionary *brightnessDict = OSDynamicCast(OSDictionary, ioDisplayParaDict->getObject("brightness"))) { if (OSNumber *brightnessValue = OSDynamicCast(OSNumber, brightnessDict->getObject("value"))) { panelBrightnessLevel = brightnessValue->unsigned32BitValue() / 64; DBGLOG("atk", "Panel brightness level: %d", panelBrightnessLevel); } else { DBGLOG("atk", "Failed to read brightness value"); } } else { DBGLOG("atk", "Failed to find dictionary brightness"); } } else { DBGLOG("atk", "Failed to find dictionary IODisplayParameters"); } } OSSafeReleaseNULL(displayDeviceEntry); } IOReturn AsusSMC::postKeyboardInputReport(const void *report, uint32_t reportSize) { IOReturn result = kIOReturnError; if (!report || reportSize == 0) { return kIOReturnBadArgument; } if (kbdDevice) { if (auto buffer = IOBufferMemoryDescriptor::withBytes(report, reportSize, kIODirectionNone)) { result = kbdDevice->handleReport(buffer, kIOHIDReportTypeInput, kIOHIDOptionsTypeNone); buffer->release(); } } return result; } void AsusSMC::dispatchCSMRReport(int code, int loop) { DBGLOG("atk", "Dispatched key %d(0x%x), loop %d time(s)", code, code, loop); while (loop--) { csmrreport.keys.insert(code); postKeyboardInputReport(&csmrreport, sizeof(csmrreport)); csmrreport.keys.erase(code); postKeyboardInputReport(&csmrreport, sizeof(csmrreport)); } } void AsusSMC::dispatchTCReport(int code, int loop) { DBGLOG("atk", "Dispatched key %d(0x%x), loop %d time(s)", code, code, loop); while (loop--) { tcreport.keys.insert(code); postKeyboardInputReport(&tcreport, sizeof(tcreport)); tcreport.keys.erase(code); postKeyboardInputReport(&tcreport, sizeof(tcreport)); } } void AsusSMC::registerNotifications() { auto *key = OSSymbol::withCString(kDeliverNotifications); auto *propertyMatch = propertyMatching(key, kOSBooleanTrue); IOServiceMatchingNotificationHandler notificationHandler = OSMemberFunctionCast(IOServiceMatchingNotificationHandler, this, &AsusSMC::notificationHandler); _publishNotify = addMatchingNotification(gIOFirstPublishNotification, propertyMatch, notificationHandler, this, 0, 10000); _terminateNotify = addMatchingNotification(gIOTerminatedNotification, propertyMatch, notificationHandler, this, 0, 10000); key->release(); propertyMatch->release(); } void AsusSMC::notificationHandlerGated(IOService *newService, IONotifier *notifier) { if (notifier == _publishNotify) { SYSLOG("notify", "Notification consumer published: %s", newService->getName()); _notificationServices->setObject(newService); } if (notifier == _terminateNotify) { SYSLOG("notify", "Notification consumer terminated: %s", newService->getName()); _notificationServices->removeObject(newService); } } bool AsusSMC::notificationHandler(void *refCon, IOService *newService, IONotifier *notifier) { command_gate->runAction(OSMemberFunctionCast(IOCommandGate::Action, this, &AsusSMC::notificationHandlerGated), newService, notifier); return true; } void AsusSMC::dispatchMessageGated(int *message, void *data) { OSCollectionIterator *i = OSCollectionIterator::withCollection(_notificationServices); if (i != NULL) { while (IOService *service = OSDynamicCast(IOService, i->getNextObject())) { service->message(*message, this, data); } i->release(); } } void AsusSMC::dispatchMessage(int message, void *data) { command_gate->runAction(OSMemberFunctionCast(IOCommandGate::Action, this, &AsusSMC::dispatchMessageGated), &message, data); } void AsusSMC::registerVSMC() { vsmcNotifier = VirtualSMCAPI::registerHandler(vsmcNotificationHandler, this); ALSSensor sensor {ALSSensor::Type::Unknown7, true, 6, false}; ALSSensor noSensor {ALSSensor::Type::NoSensor, false, 0, false}; SMCALSValue::Value emptyValue; SMCKBrdBLightValue::lkb lkb; SMCKBrdBLightValue::lks lks; VirtualSMCAPI::addKey(KeyAL, vsmcPlugin.data, VirtualSMCAPI::valueWithUint16( 0, &forceBits, SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_WRITE)); VirtualSMCAPI::addKey(KeyALI0, vsmcPlugin.data, VirtualSMCAPI::valueWithData( reinterpret_cast(&sensor), sizeof(sensor), SmcKeyTypeAli, nullptr, SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_FUNCTION)); VirtualSMCAPI::addKey(KeyALI1, vsmcPlugin.data, VirtualSMCAPI::valueWithData( reinterpret_cast(&noSensor), sizeof(noSensor), SmcKeyTypeAli, nullptr, SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_FUNCTION)); VirtualSMCAPI::addKey(KeyALRV, vsmcPlugin.data, VirtualSMCAPI::valueWithUint16( 1, nullptr, SMC_KEY_ATTRIBUTE_READ)); VirtualSMCAPI::addKey(KeyALV0, vsmcPlugin.data, VirtualSMCAPI::valueWithData( reinterpret_cast(&emptyValue), sizeof(emptyValue), SmcKeyTypeAlv, new SMCALSValue(¤tLux, &forceBits), SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_WRITE | SMC_KEY_ATTRIBUTE_FUNCTION)); VirtualSMCAPI::addKey(KeyALV1, vsmcPlugin.data, VirtualSMCAPI::valueWithData( reinterpret_cast(&emptyValue), sizeof(emptyValue), SmcKeyTypeAlv, nullptr, SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_WRITE | SMC_KEY_ATTRIBUTE_FUNCTION)); VirtualSMCAPI::addKey(KeyLKSB, vsmcPlugin.data, VirtualSMCAPI::valueWithData( reinterpret_cast(&lkb), sizeof(lkb), SmcKeyTypeLkb, new SMCKBrdBLightValue(this), SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_WRITE | SMC_KEY_ATTRIBUTE_FUNCTION)); VirtualSMCAPI::addKey(KeyLKSS, vsmcPlugin.data, VirtualSMCAPI::valueWithData( reinterpret_cast(&lks), sizeof(lks), SmcKeyTypeLks, nullptr, SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_WRITE | SMC_KEY_ATTRIBUTE_FUNCTION)); VirtualSMCAPI::addKey(KeyMSLD, vsmcPlugin.data, VirtualSMCAPI::valueWithUint8( 0, nullptr, SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_WRITE | SMC_KEY_ATTRIBUTE_FUNCTION)); VirtualSMCAPI::addKey(KeyFNum, vsmcPlugin.data, VirtualSMCAPI::valueWithUint8( 1, nullptr, SMC_KEY_ATTRIBUTE_CONST | SMC_KEY_ATTRIBUTE_READ)); VirtualSMCAPI::addKey(KeyF0Ac, vsmcPlugin.data, VirtualSMCAPI::valueWithFp( 0, SmcKeyTypeFpe2, new F0Ac(¤tFanSpeed), SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_FUNCTION)); FanTypeDescStruct desc; lilu_os_strncpy(desc.strFunction, "System Fan", DiagFunctionStrLen); VirtualSMCAPI::addKey(KeyF0ID, vsmcPlugin.data, VirtualSMCAPI::valueWithData( reinterpret_cast(&desc), sizeof(desc), SmcKeyTypeFds, nullptr, SMC_KEY_ATTRIBUTE_CONST | SMC_KEY_ATTRIBUTE_READ)); if (isBatteryRSOCAvailable) { VirtualSMCAPI::addKey(KeyBDVT, vsmcPlugin.data, VirtualSMCAPI::valueWithFlag( false, new BDVT(this), SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_WRITE | SMC_KEY_ATTRIBUTE_ATOMIC)); } qsort(const_cast(vsmcPlugin.data.data()), vsmcPlugin.data.size(), sizeof(VirtualSMCKeyValue), VirtualSMCKeyValue::compare); } bool AsusSMC::vsmcNotificationHandler(void *sensors, void *refCon, IOService *vsmc, IONotifier *notifier) { if (sensors && vsmc) { DBGLOG("atk", "got vsmc notification"); auto self = static_cast(sensors); auto ret = vsmc->callPlatformFunction(VirtualSMCAPI::SubmitPlugin, true, sensors, &self->vsmcPlugin, nullptr, nullptr); if (ret == kIOReturnSuccess) { DBGLOG("atk", "Submitted plugin"); self->workloop = self->getWorkLoop(); self->poller = IOTimerEventSource::timerEventSource(self, [](OSObject *object, IOTimerEventSource *sender) { auto ls = OSDynamicCast(AsusSMC, object); if (ls) { ls->refreshALS(true); ls->refreshFan(); } }); if (!self->poller || !self->workloop) { SYSLOG("atk", "Failed to create poller or workloop"); return false; } if (self->workloop->addEventSource(self->poller) != kIOReturnSuccess) { SYSLOG("atk", "Failed to add timer event source to workloop"); return false; } if (self->poller->setTimeoutMS(SensorUpdateTimeoutMS) != kIOReturnSuccess) { SYSLOG("atk", "Failed to set timeout"); return false; } return true; } else if (ret != kIOReturnUnsupported) { SYSLOG("atk", "Plugin submission failure %X", ret); } else { DBGLOG("atk", "Plugin submission to non vsmc"); } } else { SYSLOG("atk", "Got null vsmc notification"); } return false; } EXPORT extern "C" kern_return_t ADDPR(kern_start)(kmod_info_t *, void *) { // Report success but actually do not start and let I/O Kit unload us. // This works better and increases boot speed in some cases. PE_parse_boot_argn("liludelay", &ADDPR(debugPrintDelay), sizeof(ADDPR(debugPrintDelay))); ADDPR(debugEnabled) = checkKernelArgument("-vsmcdbg") || checkKernelArgument("-asussmcdbg"); return KERN_SUCCESS; } EXPORT extern "C" kern_return_t ADDPR(kern_stop)(kmod_info_t *, void *) { // It is not safe to unload VirtualSMC plugins! return KERN_FAILURE; } ================================================ FILE: AsusSMC/AsusSMC.hpp ================================================ // // AsusSMC.hpp // AsusSMC // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #ifndef _AsusSMC_hpp #define _AsusSMC_hpp #include #include #include #include "HIDReport.hpp" #include "HIDUsageTables.h" #include "VirtualAppleKeyboard.hpp" #include "KernEventServer.hpp" #include "KeyImplementations.hpp" #define ASUS_WMI_METHODID_DSTS 0x53545344 #define ASUS_WMI_METHODID_DEVS 0x53564544 #define ASUS_WMI_METHODID_INIT 0x54494E49 #define ASUS_WMI_DEVID_ALS_ENABLE 0x00050001 #define ASUS_WMI_DEVID_CPU_FAN_CTRL 0x00110013 #define ASUS_WMI_DEVID_RSOC 0x00120057 #define ASUS_WMI_DSTS_PRESENCE_BIT 0x00010000 #define ASUS_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" #define kDeliverNotifications "RM,deliverNotifications" #define AsusSMCEventCode 0x8102 class AsusSMC : public IOService { OSDeclareDefaultStructors(AsusSMC) VirtualSMCAPI::Plugin vsmcPlugin { xStringify(PRODUCT_NAME), parseModuleVersion(xStringify(MODULE_VERSION)), VirtualSMCAPI::Version, }; public: bool init(OSDictionary *dictionary) override; bool start(IOService *provider) override; void stop(IOService *provider) override; IOService *probe(IOService *provider, SInt32 *score) override; IOReturn message(uint32_t type, IOService *provider, void *argument) override; void letSleep(); void toggleAirplaneMode(); void toggleTouchpad(); void toggleALS(bool state); void toggleBatteryConservativeMode(bool state); void displayOff(); private: struct guid_block { char guid[16]; union { char object_id[2]; struct { uint8_t notify_id; uint8_t reserved; }; }; uint8_t instance_count; uint8_t flags; }; struct wmi_args { uint32_t arg0; uint32_t arg1; } __packed; enum { kKeyboardSetTouchStatus = iokit_vendor_specific_msg(100), // set disable/enable touchpad (data is bool*) kKeyboardGetTouchStatus = iokit_vendor_specific_msg(101), // get disable/enable touchpad (data is bool*) kKeyboardKeyPressTime = iokit_vendor_specific_msg(110), // notify of timestamp a non-modifier key was pressed (data is uint64_t*) }; enum { kDaemonKeyboardBacklight = 1, kDaemonAirplaneMode = 2, kDaemonSleep = 3, kDaemonTouchpad = 4, }; static constexpr uint32_t SensorUpdateTimeoutMS {1000}; static constexpr uint8_t NOTIFY_BRIGHTNESS_UP_MIN = 0x10; static constexpr uint8_t NOTIFY_BRIGHTNESS_UP_MAX = 0x1F; static constexpr uint8_t NOTIFY_BRIGHTNESS_DOWN_MIN = 0x20; static constexpr uint8_t NOTIFY_BRIGHTNESS_DOWN_MAX = 0x2F; char wmi_method[5]; int wmi_parse_guid(const char *in, char *out); int wmi_evaluate_method(uint32_t method_id, uint32_t arg0, uint32_t arg1); int wmi_get_devstate(uint32_t dev_id); bool wmi_dev_is_present(uint32_t dev_id); void parse_WDG(); void initATKDevice(); void initALSDevice(); void initEC0Device(); void initBattery(); void initVirtualKeyboard(); void startATKDevice(); bool refreshALS(bool post); bool refreshFan(); void handleMessage(int code); IOACPIPlatformDevice *atkDevice {nullptr}; IOACPIPlatformDevice *alsDevice {nullptr}; IOACPIPlatformDevice *ec0Device {nullptr}; VirtualAppleKeyboard *kbdDevice {nullptr}; ALSForceBits forceBits; _Atomic(uint32_t) currentLux = ATOMIC_VAR_INIT(0); _Atomic(uint16_t) currentFanSpeed = ATOMIC_VAR_INIT(0); IONotifier *vsmcNotifier {nullptr}; IOWorkLoop *workloop {nullptr}; IOCommandGate *command_gate {nullptr}; IOTimerEventSource *poller {nullptr}; KernEventServer kev; consumer_input csmrreport; apple_vendor_top_case_input tcreport; bool directACPImessaging {false}; bool hasKeyboardBacklight {false}; bool isALSEnabled {true}; bool isTouchpadEnabled {true}; bool isPanelBackLightOn {true}; bool isTACHAvailable {false}; bool isBatteryRSOCAvailable {false}; uint32_t panelBrightnessLevel {16}; char backlightEntry[1000]; int checkBacklightEntry(); int findBacklightEntry(); void readPanelBrightnessValue(); IOReturn postKeyboardInputReport(const void *report, uint32_t reportSize); void dispatchCSMRReport(int code, int loop = 1); void dispatchTCReport(int code, int loop = 1); IONotifier *_publishNotify {nullptr}; IONotifier *_terminateNotify {nullptr}; OSSet *_notificationServices {nullptr}; void registerNotifications(void); void notificationHandlerGated(IOService *newService, IONotifier *notifier); bool notificationHandler(void *refCon, IOService *newService, IONotifier *notifier); void dispatchMessageGated(int *message, void *data); void dispatchMessage(int message, void *data); void registerVSMC(void); static bool vsmcNotificationHandler(void *sensors, void *refCon, IOService *vsmc, IONotifier *notifier); }; #endif //_AsusSMC_hpp ================================================ FILE: AsusSMC/Info.plist ================================================ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType KEXT CFBundleShortVersionString $(MODULE_VERSION) CFBundleVersion $(MODULE_VERSION) IOKitPersonalities AsusSMC CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) IOClass AsusSMC IONameMatch PNP0c14 PNP0C14 PnP0C14 pnp0c14 ASUS010 ASUS0100 ASUS0010 ATK0100 IOProbeScore 9999 IOProviderClass IOACPIPlatformDevice NSHumanReadableCopyright Copyright © 2018-2020 Le Bao Hiep. All rights reserved. OSBundleCompatibleVersion 1.0.0 OSBundleLibraries as.vit9696.Lilu 1.2.0 as.vit9696.VirtualSMC 1.0.0 com.apple.iokit.IOACPIFamily 1.0.0d1 com.apple.iokit.IOHIDFamily 2.0.0 com.apple.iokit.IOUSBHostFamily 1.0.1 com.apple.kpi.bsd 12.0.0 com.apple.kpi.dsep 12.0.0 com.apple.kpi.iokit 12.0.0 com.apple.kpi.libkern 12.0.0 com.apple.kpi.mach 12.0.0 com.apple.kpi.unsupported 12.0.0 OSBundleRequired Root ================================================ FILE: AsusSMC/KeyImplementations.cpp ================================================ // // KeyImplementations.cpp // AsusSMC // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #include "KeyImplementations.hpp" #include "AsusSMC.hpp" SMC_RESULT SMCALSValue::readAccess() { auto value = reinterpret_cast(data); uint32_t lux = atomic_load_explicit(currentLux, memory_order_acquire); uint8_t bits = forceBits->bits(); if (lux == 0xFFFFFFFF) { value->valid = false; } else { value->valid = true; if (!(bits & ALSForceBits::kALSForceHighGain)) value->highGain = true; if (!(bits & ALSForceBits::kALSForceChan)) value->chan0 = OSSwapHostToBigInt16(lux); if (!(bits & ALSForceBits::kALSForceLux)) value->roomLux = OSSwapHostToBigInt32(lux << 14); } return SmcSuccess; } SMC_RESULT SMCKBrdBLightValue::update(const SMC_DATA *src) { lkb *value = new lkb; lilu_os_memcpy(value, src, size); // tval is in range [0x0, 0xffb] uint16_t tval = (value->val1 << 4) | (value->val2 >> 4); DBGLOG("lksb", "LKSB update %d", tval); delete value; if (asusSMCInstance) { asusSMCInstance->message(kSetKeyboardBacklightMessage, nullptr, &tval); } lilu_os_memcpy(data, src, size); return SmcSuccess; } SMC_RESULT F0Ac::readAccess() { uint16_t speed = atomic_load_explicit(currentSpeed, memory_order_acquire); *reinterpret_cast(data) = VirtualSMCAPI::encodeIntFp(SmcKeyTypeFpe2, speed); return SmcSuccess; } SMC_RESULT BDVT::update(const SMC_DATA *src) { bool state = false; lilu_os_memcpy(&state, src, size); // BDVT is 00 when battery health is enabled and 01 when disabled state = !state; AsusSMC *drv = OSDynamicCast(AsusSMC, dst); drv->toggleBatteryConservativeMode(state); lilu_os_memcpy(data, src, size); return SmcSuccess; } ================================================ FILE: AsusSMC/KeyImplementations.hpp ================================================ // // KeyImplementations.hpp // AsusSMC // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // // Ambient light sensor support is based on SMCLightSensor #ifndef KeyImplementations_hpp #define KeyImplementations_hpp #include #include #define kSetKeyboardBacklightMessage 812002 static constexpr SMC_KEY KeyAL = SMC_MAKE_IDENTIFIER('A','L','!',' '); static constexpr SMC_KEY KeyALI0 = SMC_MAKE_IDENTIFIER('A','L','I','0'); static constexpr SMC_KEY KeyALI1 = SMC_MAKE_IDENTIFIER('A','L','I','1'); static constexpr SMC_KEY KeyALRV = SMC_MAKE_IDENTIFIER('A','L','R','V'); static constexpr SMC_KEY KeyALV0 = SMC_MAKE_IDENTIFIER('A','L','V','0'); static constexpr SMC_KEY KeyALV1 = SMC_MAKE_IDENTIFIER('A','L','V','1'); static constexpr SMC_KEY KeyLKSB = SMC_MAKE_IDENTIFIER('L','K','S','B'); static constexpr SMC_KEY KeyLKSS = SMC_MAKE_IDENTIFIER('L','K','S','S'); static constexpr SMC_KEY KeyMSLD = SMC_MAKE_IDENTIFIER('M','S','L','D'); static constexpr SMC_KEY KeyFNum = SMC_MAKE_IDENTIFIER('F','N','u','m'); static constexpr SMC_KEY KeyF0ID = SMC_MAKE_IDENTIFIER('F','0','I','D'); static constexpr SMC_KEY KeyF0Ac = SMC_MAKE_IDENTIFIER('F','0','A','c'); static constexpr SMC_KEY KeyBDVT = SMC_MAKE_IDENTIFIER('B','D','V','T'); typedef enum { FAN_PWM_TACH, FAN_RPM, PUMP_PWM, PUMP_RPM, FAN_PWM_NOTACH, EMPTY_PLACEHOLDER } FanType; typedef enum { LEFT_LOWER_FRONT, CENTER_LOWER_FRONT, RIGHT_LOWER_FRONT, LEFT_MID_FRONT, CENTER_MID_FRONT, RIGHT_MID_FRONT, LEFT_UPPER_FRONT, CENTER_UPPER_FRONT, RIGHT_UPPER_FRONT, LEFT_LOWER_REAR, CENTER_LOWER_REAR, RIGHT_LOWER_REAR, LEFT_MID_REAR, CENTER_MID_REAR, RIGHT_MID_REAR, LEFT_UPPER_REAR, CENTER_UPPER_REAR, RIGHT_UPPER_REAR } LocationType; static constexpr int32_t DiagFunctionStrLen = 12; typedef struct fanTypeDescStruct { uint8_t type {FAN_RPM}; uint8_t ui8Zone {1}; uint8_t location {LEFT_MID_REAR}; uint8_t rsvd {0}; // padding to get us to 16 bytes char strFunction[DiagFunctionStrLen]; } FanTypeDescStruct; class ALSForceBits : public VirtualSMCValue { public: enum { kALSForceScale = 1, kALSForceChan = 2, kALSForceLux = 4, kALSForceHighGain = 8, kALSForceTemp = 16 }; uint8_t bits() { return data[0]; } }; struct ALSSensor { enum Type : uint8_t { NoSensor = 0, BS520 = 1, TSL2561CS = 2, LX1973A = 3, ISL29003 = 4, Unknown7 = 7 }; Type sensorType {Type::NoSensor}; bool validWhenLidClosed {false}; uint8_t unknown {0}; bool controlSIL {false}; ALSSensor(Type sensorType, bool validWhenLidClosed, uint8_t unknown, bool controlSIL): sensorType(sensorType), validWhenLidClosed(validWhenLidClosed), unknown(unknown), controlSIL(controlSIL) {} }; class SMCALSValue : public VirtualSMCValue { _Atomic(uint32_t) *currentLux; ALSForceBits *forceBits; protected: SMC_RESULT readAccess() override; public: struct PACKED Value { bool valid {false}; bool highGain {true}; uint16_t chan0 {0}; uint16_t chan1 {0}; uint32_t roomLux {0}; }; SMCALSValue(_Atomic(uint32_t) *currentLux, ALSForceBits *forceBits) : currentLux(currentLux), forceBits(forceBits) {} }; class SMCKBrdBLightValue : public VirtualSMCValue { IOService *asusSMCInstance {nullptr}; protected: SMC_RESULT update(const SMC_DATA *src) override; public: struct PACKED lks { uint8_t unknown0 {0}; uint8_t unknown1 {1}; }; struct PACKED lkb { uint8_t val1 {0}; uint8_t val2 {1}; }; SMCKBrdBLightValue(IOService *asusSMCInstance): asusSMCInstance(asusSMCInstance) {} }; class F0Ac : public VirtualSMCValue { _Atomic(uint16_t) *currentSpeed; protected: SMC_RESULT readAccess() override; public: F0Ac(_Atomic(uint16_t) *currentSpeed) : currentSpeed(currentSpeed) {} }; class BDVT : public VirtualSMCValue { IOService *dst {nullptr}; protected: SMC_RESULT update(const SMC_DATA *src) override; public: BDVT(IOService *dst) : dst(dst) {} }; #endif /* KeyImplementations_hpp */ ================================================ FILE: AsusSMC.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 4C17428122C85E6E00469B7E /* HIDUsageTables.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C17428022C85E6E00469B7E /* HIDUsageTables.h */; }; 4C4FCB282326880C0010505E /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C4FCB272326880C0010505E /* CoreServices.framework */; }; 4C4FCB2A232688390010505E /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C4FCB29232688390010505E /* AppKit.framework */; }; 4C4FE6252156A1690074AD08 /* AsusSMC.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4C4FE6242156A1690074AD08 /* AsusSMC.hpp */; }; 4C4FE6272156A1690074AD08 /* AsusSMC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C4FE6262156A1690074AD08 /* AsusSMC.cpp */; }; 4C4FE6A02156A3AD0074AD08 /* KernEventServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C4FE69E2156A3AD0074AD08 /* KernEventServer.cpp */; }; 4C4FE6A12156A3AD0074AD08 /* KernEventServer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4C4FE69F2156A3AD0074AD08 /* KernEventServer.hpp */; }; 4C4FE6A62156A4340074AD08 /* VirtualAppleKeyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C4FE6A32156A4340074AD08 /* VirtualAppleKeyboard.cpp */; }; 4C4FE6A72156A4340074AD08 /* VirtualAppleKeyboard.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4C4FE6A42156A4340074AD08 /* VirtualAppleKeyboard.hpp */; }; 4C4FE6A82156A4340074AD08 /* HIDReport.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4C4FE6A52156A4340074AD08 /* HIDReport.hpp */; }; 4C4FE6B62156A4A20074AD08 /* IOBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C4FE6B52156A4A20074AD08 /* IOBluetooth.framework */; }; 4C4FE6B82156A4A70074AD08 /* CoreWLAN.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C4FE6B72156A4A70074AD08 /* CoreWLAN.framework */; }; 4C4FE6BD2156A4FB0074AD08 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4FE6BB2156A4FB0074AD08 /* main.m */; }; 4C4FE6C02156A5820074AD08 /* KeyImplementations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C4FE6BE2156A5820074AD08 /* KeyImplementations.cpp */; }; 4C4FE6C12156A5820074AD08 /* KeyImplementations.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4C4FE6BF2156A5820074AD08 /* KeyImplementations.hpp */; }; 4CA82AB2251A07F300B02E1C /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CA82AB1251A07F000B02E1C /* libkmod.a */; }; 4CC5A8C2244611E600AB526E /* com.hieplpvip.AsusSMCDaemon.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C4FE6BC2156A4FB0074AD08 /* com.hieplpvip.AsusSMCDaemon.plist */; }; 4CC5A8C3244611EA00AB526E /* install_daemon.sh in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C32364A2159051A00700256 /* install_daemon.sh */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 4C8C666224460F2D00D694EB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C4FE6182156A1690074AD08 /* Project object */; proxyType = 1; remoteGlobalIDString = 4C4FE6AC2156A4730074AD08; remoteInfo = AsusSMCDaemon; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ 4C4FE6AB2156A4730074AD08 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 12; dstPath = usr/share/man/man1; dstSubfolderSpec = 16; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4CC5A8C1244611D300AB526E /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 16; files = ( 4CC5A8C2244611E600AB526E /* com.hieplpvip.AsusSMCDaemon.plist in CopyFiles */, 4CC5A8C3244611EA00AB526E /* install_daemon.sh in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 4C17428022C85E6E00469B7E /* HIDUsageTables.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HIDUsageTables.h; sourceTree = ""; }; 4C27D2BF218B647F0089409B /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; }; 4C32364A2159051A00700256 /* install_daemon.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = install_daemon.sh; sourceTree = ""; }; 4C4FCB272326880C0010505E /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; 4C4FCB29232688390010505E /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 4C4FE6212156A1690074AD08 /* AsusSMC.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AsusSMC.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 4C4FE6242156A1690074AD08 /* AsusSMC.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AsusSMC.hpp; sourceTree = ""; }; 4C4FE6262156A1690074AD08 /* AsusSMC.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AsusSMC.cpp; sourceTree = ""; }; 4C4FE6282156A1690074AD08 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4C4FE6672156A3610074AD08 /* kern_config.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_config.hpp; sourceTree = ""; }; 4C4FE6682156A3610074AD08 /* kern_time.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_time.hpp; sourceTree = ""; }; 4C4FE6692156A3610074AD08 /* kern_nvram.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_nvram.hpp; sourceTree = ""; }; 4C4FE66A2156A3610074AD08 /* kern_cpu.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_cpu.hpp; sourceTree = ""; }; 4C4FE66B2156A3610074AD08 /* kern_devinfo.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_devinfo.hpp; sourceTree = ""; }; 4C4FE66C2156A3610074AD08 /* kern_efi.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_efi.hpp; sourceTree = ""; }; 4C4FE66D2156A3610074AD08 /* kern_policy.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_policy.hpp; sourceTree = ""; }; 4C4FE66E2156A3610074AD08 /* kern_user.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_user.hpp; sourceTree = ""; }; 4C4FE66F2156A3610074AD08 /* plugin_start.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = plugin_start.hpp; sourceTree = ""; }; 4C4FE6702156A3610074AD08 /* kern_iokit.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_iokit.hpp; sourceTree = ""; }; 4C4FE6712156A3610074AD08 /* kern_crypto.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_crypto.hpp; sourceTree = ""; }; 4C4FE6722156A3610074AD08 /* kern_mach.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_mach.hpp; sourceTree = ""; }; 4C4FE6732156A3610074AD08 /* kern_compression.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_compression.hpp; sourceTree = ""; }; 4C4FE6742156A3610074AD08 /* kern_file.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_file.hpp; sourceTree = ""; }; 4C4FE6752156A3610074AD08 /* kern_rtc.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_rtc.hpp; sourceTree = ""; }; 4C4FE6762156A3610074AD08 /* kern_disasm.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_disasm.hpp; sourceTree = ""; }; 4C4FE6782156A3610074AD08 /* capstone.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = capstone.h; sourceTree = ""; }; 4C4FE6792156A3610074AD08 /* mips.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mips.h; sourceTree = ""; }; 4C4FE67A2156A3610074AD08 /* sparc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sparc.h; sourceTree = ""; }; 4C4FE67B2156A3610074AD08 /* systemz.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = systemz.h; sourceTree = ""; }; 4C4FE67C2156A3610074AD08 /* arm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = arm.h; sourceTree = ""; }; 4C4FE67D2156A3610074AD08 /* x86.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = x86.h; sourceTree = ""; }; 4C4FE67E2156A3610074AD08 /* ppc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ppc.h; sourceTree = ""; }; 4C4FE67F2156A3610074AD08 /* arm64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = arm64.h; sourceTree = ""; }; 4C4FE6802156A3610074AD08 /* xcore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = xcore.h; sourceTree = ""; }; 4C4FE6812156A3610074AD08 /* platform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = platform.h; sourceTree = ""; }; 4C4FE6822156A3610074AD08 /* kern_patcher.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_patcher.hpp; sourceTree = ""; }; 4C4FE6852156A3610074AD08 /* kern_compat.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_compat.hpp; sourceTree = ""; }; 4C4FE6862156A3610074AD08 /* kern_api.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_api.hpp; sourceTree = ""; }; 4C4FE6872156A3610074AD08 /* kern_util.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_util.hpp; sourceTree = ""; }; 4C4FE68B2156A3610074AD08 /* entry64.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = entry64.S; sourceTree = ""; }; 4C4FE68C2156A3620074AD08 /* build.tool */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.tool; sourceTree = ""; }; 4C4FE68D2156A3620074AD08 /* entry32.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = entry32.S; sourceTree = ""; }; 4C4FE68E2156A3620074AD08 /* wrappers.inc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.pascal; path = wrappers.inc; sourceTree = ""; }; 4C4FE6932156A3620074AD08 /* plugin_start.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = plugin_start.cpp; sourceTree = ""; }; 4C4FE6962156A3700074AD08 /* kern_smcinfo.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_smcinfo.hpp; sourceTree = ""; }; 4C4FE6972156A3700074AD08 /* kern_vsmcapi.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_vsmcapi.hpp; sourceTree = ""; }; 4C4FE6982156A3700074AD08 /* AppleSmc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleSmc.h; sourceTree = ""; }; 4C4FE6992156A3700074AD08 /* kern_keyvalue.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_keyvalue.hpp; sourceTree = ""; }; 4C4FE69A2156A3700074AD08 /* kern_value.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_value.hpp; sourceTree = ""; }; 4C4FE69C2156A3700074AD08 /* AppleSmcBridge.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AppleSmcBridge.hpp; sourceTree = ""; }; 4C4FE69E2156A3AD0074AD08 /* KernEventServer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = KernEventServer.cpp; sourceTree = ""; }; 4C4FE69F2156A3AD0074AD08 /* KernEventServer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = KernEventServer.hpp; sourceTree = ""; }; 4C4FE6A32156A4340074AD08 /* VirtualAppleKeyboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VirtualAppleKeyboard.cpp; sourceTree = ""; }; 4C4FE6A42156A4340074AD08 /* VirtualAppleKeyboard.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = VirtualAppleKeyboard.hpp; sourceTree = ""; }; 4C4FE6A52156A4340074AD08 /* HIDReport.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = HIDReport.hpp; sourceTree = ""; }; 4C4FE6AD2156A4730074AD08 /* AsusSMCDaemon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AsusSMCDaemon; sourceTree = BUILT_PRODUCTS_DIR; }; 4C4FE6B52156A4A20074AD08 /* IOBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOBluetooth.framework; path = System/Library/Frameworks/IOBluetooth.framework; sourceTree = SDKROOT; }; 4C4FE6B72156A4A70074AD08 /* CoreWLAN.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreWLAN.framework; path = System/Library/Frameworks/CoreWLAN.framework; sourceTree = SDKROOT; }; 4C4FE6B92156A4FB0074AD08 /* OSD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSD.h; sourceTree = ""; }; 4C4FE6BA2156A4FB0074AD08 /* BezelServices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BezelServices.h; sourceTree = ""; }; 4C4FE6BB2156A4FB0074AD08 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 4C4FE6BC2156A4FB0074AD08 /* com.hieplpvip.AsusSMCDaemon.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.hieplpvip.AsusSMCDaemon.plist; sourceTree = ""; }; 4C4FE6BE2156A5820074AD08 /* KeyImplementations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyImplementations.cpp; sourceTree = ""; }; 4C4FE6BF2156A5820074AD08 /* KeyImplementations.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KeyImplementations.hpp; sourceTree = ""; }; 4C4FE6C22156AA810074AD08 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 4CA82AB1251A07F000B02E1C /* libkmod.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libkmod.a; path = MacKernelSDK/Library/x86_64/libkmod.a; sourceTree = ""; }; 4CDDD8C822E899F700CC38F4 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 4C4FE61E2156A1690074AD08 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4CA82AB2251A07F300B02E1C /* libkmod.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4C4FE6AA2156A4730074AD08 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4C4FCB2A232688390010505E /* AppKit.framework in Frameworks */, 4C4FCB282326880C0010505E /* CoreServices.framework in Frameworks */, 4C4FE6B82156A4A70074AD08 /* CoreWLAN.framework in Frameworks */, 4C4FE6B62156A4A20074AD08 /* IOBluetooth.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 4C4FE6172156A1690074AD08 = { isa = PBXGroup; children = ( 4CE3969E22CCAB5C00693C33 /* Global */, 4C4FE6232156A1690074AD08 /* AsusSMC */, 4C4FE6AE2156A4730074AD08 /* AsusSMCDaemon */, 4C4FE69D2156A3970074AD08 /* KernEventServer */, 4C4FE6A22156A4270074AD08 /* VirtualAppleKeyboard */, 4C4FE62E2156A2980074AD08 /* SDK */, 4C4FE6222156A1690074AD08 /* Products */, 4C4FE6B42156A4A20074AD08 /* Frameworks */, 4C4FE6C22156AA810074AD08 /* README.md */, 4CDDD8C822E899F700CC38F4 /* CHANGELOG.md */, 4C27D2BF218B647F0089409B /* LICENSE.md */, ); sourceTree = ""; }; 4C4FE6222156A1690074AD08 /* Products */ = { isa = PBXGroup; children = ( 4C4FE6212156A1690074AD08 /* AsusSMC.kext */, 4C4FE6AD2156A4730074AD08 /* AsusSMCDaemon */, ); name = Products; sourceTree = ""; }; 4C4FE6232156A1690074AD08 /* AsusSMC */ = { isa = PBXGroup; children = ( 4C4FE6262156A1690074AD08 /* AsusSMC.cpp */, 4C4FE6242156A1690074AD08 /* AsusSMC.hpp */, 4C4FE6BE2156A5820074AD08 /* KeyImplementations.cpp */, 4C4FE6BF2156A5820074AD08 /* KeyImplementations.hpp */, 4C4FE6282156A1690074AD08 /* Info.plist */, ); path = AsusSMC; sourceTree = ""; }; 4C4FE62E2156A2980074AD08 /* SDK */ = { isa = PBXGroup; children = ( 4C4FE6952156A3700074AD08 /* VirtualSMCSDK */, 4C4FE6662156A3610074AD08 /* Headers */, 4C4FE6882156A3610074AD08 /* Library */, ); name = SDK; sourceTree = ""; }; 4C4FE6662156A3610074AD08 /* Headers */ = { isa = PBXGroup; children = ( 4C4FE6672156A3610074AD08 /* kern_config.hpp */, 4C4FE6682156A3610074AD08 /* kern_time.hpp */, 4C4FE6692156A3610074AD08 /* kern_nvram.hpp */, 4C4FE66A2156A3610074AD08 /* kern_cpu.hpp */, 4C4FE66B2156A3610074AD08 /* kern_devinfo.hpp */, 4C4FE66C2156A3610074AD08 /* kern_efi.hpp */, 4C4FE66D2156A3610074AD08 /* kern_policy.hpp */, 4C4FE66E2156A3610074AD08 /* kern_user.hpp */, 4C4FE66F2156A3610074AD08 /* plugin_start.hpp */, 4C4FE6702156A3610074AD08 /* kern_iokit.hpp */, 4C4FE6712156A3610074AD08 /* kern_crypto.hpp */, 4C4FE6722156A3610074AD08 /* kern_mach.hpp */, 4C4FE6732156A3610074AD08 /* kern_compression.hpp */, 4C4FE6742156A3610074AD08 /* kern_file.hpp */, 4C4FE6752156A3610074AD08 /* kern_rtc.hpp */, 4C4FE6762156A3610074AD08 /* kern_disasm.hpp */, 4C4FE6772156A3610074AD08 /* capstone */, 4C4FE6822156A3610074AD08 /* kern_patcher.hpp */, 4C4FE6852156A3610074AD08 /* kern_compat.hpp */, 4C4FE6862156A3610074AD08 /* kern_api.hpp */, 4C4FE6872156A3610074AD08 /* kern_util.hpp */, ); name = Headers; path = Lilu.kext/Contents/Resources/Headers; sourceTree = ""; }; 4C4FE6772156A3610074AD08 /* capstone */ = { isa = PBXGroup; children = ( 4C4FE6782156A3610074AD08 /* capstone.h */, 4C4FE6792156A3610074AD08 /* mips.h */, 4C4FE67A2156A3610074AD08 /* sparc.h */, 4C4FE67B2156A3610074AD08 /* systemz.h */, 4C4FE67C2156A3610074AD08 /* arm.h */, 4C4FE67D2156A3610074AD08 /* x86.h */, 4C4FE67E2156A3610074AD08 /* ppc.h */, 4C4FE67F2156A3610074AD08 /* arm64.h */, 4C4FE6802156A3610074AD08 /* xcore.h */, 4C4FE6812156A3610074AD08 /* platform.h */, ); path = capstone; sourceTree = ""; }; 4C4FE6882156A3610074AD08 /* Library */ = { isa = PBXGroup; children = ( 4C4FE68A2156A3610074AD08 /* wrappers */, 4C4FE6932156A3620074AD08 /* plugin_start.cpp */, ); name = Library; path = Lilu.kext/Contents/Resources/Library; sourceTree = ""; }; 4C4FE68A2156A3610074AD08 /* wrappers */ = { isa = PBXGroup; children = ( 4C4FE68B2156A3610074AD08 /* entry64.S */, 4C4FE68C2156A3620074AD08 /* build.tool */, 4C4FE68D2156A3620074AD08 /* entry32.S */, 4C4FE68E2156A3620074AD08 /* wrappers.inc */, ); path = wrappers; sourceTree = ""; }; 4C4FE6952156A3700074AD08 /* VirtualSMCSDK */ = { isa = PBXGroup; children = ( 4C4FE6962156A3700074AD08 /* kern_smcinfo.hpp */, 4C4FE6972156A3700074AD08 /* kern_vsmcapi.hpp */, 4C4FE6982156A3700074AD08 /* AppleSmc.h */, 4C4FE6992156A3700074AD08 /* kern_keyvalue.hpp */, 4C4FE69A2156A3700074AD08 /* kern_value.hpp */, 4C4FE69C2156A3700074AD08 /* AppleSmcBridge.hpp */, ); name = VirtualSMCSDK; path = VirtualSMC.kext/Contents/Resources/VirtualSMCSDK; sourceTree = ""; }; 4C4FE69D2156A3970074AD08 /* KernEventServer */ = { isa = PBXGroup; children = ( 4C4FE69E2156A3AD0074AD08 /* KernEventServer.cpp */, 4C4FE69F2156A3AD0074AD08 /* KernEventServer.hpp */, ); path = KernEventServer; sourceTree = ""; }; 4C4FE6A22156A4270074AD08 /* VirtualAppleKeyboard */ = { isa = PBXGroup; children = ( 4C4FE6A32156A4340074AD08 /* VirtualAppleKeyboard.cpp */, 4C4FE6A42156A4340074AD08 /* VirtualAppleKeyboard.hpp */, ); path = VirtualAppleKeyboard; sourceTree = ""; }; 4C4FE6AE2156A4730074AD08 /* AsusSMCDaemon */ = { isa = PBXGroup; children = ( 4C4FE6BA2156A4FB0074AD08 /* BezelServices.h */, 4C4FE6BC2156A4FB0074AD08 /* com.hieplpvip.AsusSMCDaemon.plist */, 4C32364A2159051A00700256 /* install_daemon.sh */, 4C4FE6BB2156A4FB0074AD08 /* main.m */, 4C4FE6B92156A4FB0074AD08 /* OSD.h */, ); path = AsusSMCDaemon; sourceTree = ""; }; 4C4FE6B42156A4A20074AD08 /* Frameworks */ = { isa = PBXGroup; children = ( 4CA82AB1251A07F000B02E1C /* libkmod.a */, 4C4FCB29232688390010505E /* AppKit.framework */, 4C4FCB272326880C0010505E /* CoreServices.framework */, 4C4FE6B72156A4A70074AD08 /* CoreWLAN.framework */, 4C4FE6B52156A4A20074AD08 /* IOBluetooth.framework */, ); name = Frameworks; sourceTree = ""; }; 4CE3969E22CCAB5C00693C33 /* Global */ = { isa = PBXGroup; children = ( 4C17428022C85E6E00469B7E /* HIDUsageTables.h */, 4C4FE6A52156A4340074AD08 /* HIDReport.hpp */, ); path = Global; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 4C4FE61C2156A1690074AD08 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4C4FE6A82156A4340074AD08 /* HIDReport.hpp in Headers */, 4C4FE6A12156A3AD0074AD08 /* KernEventServer.hpp in Headers */, 4C17428122C85E6E00469B7E /* HIDUsageTables.h in Headers */, 4C4FE6252156A1690074AD08 /* AsusSMC.hpp in Headers */, 4C4FE6C12156A5820074AD08 /* KeyImplementations.hpp in Headers */, 4C4FE6A72156A4340074AD08 /* VirtualAppleKeyboard.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 4C4FE6202156A1690074AD08 /* AsusSMC */ = { isa = PBXNativeTarget; buildConfigurationList = 4C4FE62B2156A1690074AD08 /* Build configuration list for PBXNativeTarget "AsusSMC" */; buildPhases = ( 4C4FE61C2156A1690074AD08 /* Headers */, 4C4FE61D2156A1690074AD08 /* Sources */, 4C4FE61E2156A1690074AD08 /* Frameworks */, 4C4FE61F2156A1690074AD08 /* Resources */, 4CC5A8C1244611D300AB526E /* CopyFiles */, 4C8C666424460F3C00D694EB /* Archive */, ); buildRules = ( ); dependencies = ( 4C8C666324460F2D00D694EB /* PBXTargetDependency */, ); name = AsusSMC; productName = AsusSMC; productReference = 4C4FE6212156A1690074AD08 /* AsusSMC.kext */; productType = "com.apple.product-type.kernel-extension"; }; 4C4FE6AC2156A4730074AD08 /* AsusSMCDaemon */ = { isa = PBXNativeTarget; buildConfigurationList = 4C4FE6B12156A4730074AD08 /* Build configuration list for PBXNativeTarget "AsusSMCDaemon" */; buildPhases = ( 4C4FE6A92156A4730074AD08 /* Sources */, 4C4FE6AA2156A4730074AD08 /* Frameworks */, 4C4FE6AB2156A4730074AD08 /* CopyFiles */, ); buildRules = ( ); dependencies = ( ); name = AsusSMCDaemon; productName = AsusSMCDaemon; productReference = 4C4FE6AD2156A4730074AD08 /* AsusSMCDaemon */; productType = "com.apple.product-type.tool"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 4C4FE6182156A1690074AD08 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Le Bao Hiep"; TargetAttributes = { 4C4FE6202156A1690074AD08 = { CreatedOnToolsVersion = 10.0; }; 4C4FE6AC2156A4730074AD08 = { CreatedOnToolsVersion = 10.0; }; }; }; buildConfigurationList = 4C4FE61B2156A1690074AD08 /* Build configuration list for PBXProject "AsusSMC" */; compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 4C4FE6172156A1690074AD08; productRefGroup = 4C4FE6222156A1690074AD08 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 4C4FE6202156A1690074AD08 /* AsusSMC */, 4C4FE6AC2156A4730074AD08 /* AsusSMCDaemon */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 4C4FE61F2156A1690074AD08 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 4C8C666424460F3C00D694EB /* Archive */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( ); name = Archive; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "cd \"${TARGET_BUILD_DIR}\"\n\narchive=\"${PRODUCT_NAME}-${MODULE_VERSION}-$(echo $CONFIGURATION | tr /a-z/ /A-Z/).zip\"\nrm -rf *.zip\nif [ \"$CONFIGURATION\" == \"Release\" ]; then\n strip -x -T \"${EXECUTABLE_PATH}\" &>/dev/null || strip -x \"${EXECUTABLE_PATH}\"\nfi\nzip -qry -FS \"${archive}\" *\n"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 4C4FE61D2156A1690074AD08 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4C4FE6272156A1690074AD08 /* AsusSMC.cpp in Sources */, 4C4FE6C02156A5820074AD08 /* KeyImplementations.cpp in Sources */, 4C4FE6A62156A4340074AD08 /* VirtualAppleKeyboard.cpp in Sources */, 4C4FE6A02156A3AD0074AD08 /* KernEventServer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4C4FE6A92156A4730074AD08 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4C4FE6BD2156A4FB0074AD08 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 4C8C666324460F2D00D694EB /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4C4FE6AC2156A4730074AD08 /* AsusSMCDaemon */; targetProxy = 4C8C666224460F2D00D694EB /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 4C4FE6292156A1690074AD08 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1.4.1; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; KERNEL_EXTENSION_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/MacKernelSDK/Headers"; KERNEL_FRAMEWORK_HEADERS = "$(PROJECT_DIR)/MacKernelSDK/Headers"; LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/MacKernelSDK/Library/x86_64"; MACOSX_DEPLOYMENT_TARGET = 10.11; MODULE_VERSION = 1.4.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; name = Debug; }; 4C4FE62A2156A1690074AD08 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1.4.1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; KERNEL_EXTENSION_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/MacKernelSDK/Headers"; KERNEL_FRAMEWORK_HEADERS = "$(PROJECT_DIR)/MacKernelSDK/Headers"; LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/MacKernelSDK/Library/x86_64"; MACOSX_DEPLOYMENT_TARGET = 10.11; MODULE_VERSION = 1.4.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = macosx; }; name = Release; }; 4C4FE62C2156A1690074AD08 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_DEADCODE_DEADSTORES = NO; CLANG_ANALYZER_DIVIDE_BY_ZERO = NO; CLANG_ANALYZER_NULL_DEREFERENCE = NO; CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "MODULE_VERSION=$(MODULE_VERSION)", "PRODUCT_NAME=$(PRODUCT_NAME)", "$(inherited)", ); HEADER_SEARCH_PATHS = ( "$(PROJECT_DIR)/VirtualSMC.kext/Contents/Resources/", "$(PROJECT_DIR)/Lilu.kext/Contents/Resources/", ); INFOPLIST_FILE = AsusSMC/Info.plist; MODULE_NAME = com.hieplpvip.AsusSMC; MODULE_START = "$(PRODUCT_NAME)_kern_start"; MODULE_STOP = "$(PRODUCT_NAME)_kern_stop"; OTHER_CPLUSPLUSFLAGS = "-Wno-inconsistent-missing-override"; PRODUCT_BUNDLE_IDENTIFIER = com.hieplpvip.AsusSMC; PRODUCT_NAME = "$(TARGET_NAME)"; RUN_CLANG_STATIC_ANALYZER = YES; WRAPPER_EXTENSION = kext; }; name = Debug; }; 4C4FE62D2156A1690074AD08 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "MODULE_VERSION=$(MODULE_VERSION)", "PRODUCT_NAME=$(PRODUCT_NAME)", "$(inherited)", ); HEADER_SEARCH_PATHS = ( "$(PROJECT_DIR)/VirtualSMC.kext/Contents/Resources/", "$(PROJECT_DIR)/Lilu.kext/Contents/Resources/", ); INFOPLIST_FILE = AsusSMC/Info.plist; MODULE_NAME = com.hieplpvip.AsusSMC; MODULE_START = "$(PRODUCT_NAME)_kern_start"; MODULE_STOP = "$(PRODUCT_NAME)_kern_stop"; OTHER_CPLUSPLUSFLAGS = "-Wno-inconsistent-missing-override"; PRODUCT_BUNDLE_IDENTIFIER = com.hieplpvip.AsusSMC; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = kext; }; name = Release; }; 4C4FE6B22156A4730074AD08 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "-"; INFOPLIST_FILE = AsusSMCDaemon/com.hieplpvip.AsusSMCDaemon.plist; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 4C4FE6B32156A4730074AD08 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "-"; INFOPLIST_FILE = AsusSMCDaemon/com.hieplpvip.AsusSMCDaemon.plist; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 4C4FE61B2156A1690074AD08 /* Build configuration list for PBXProject "AsusSMC" */ = { isa = XCConfigurationList; buildConfigurations = ( 4C4FE6292156A1690074AD08 /* Debug */, 4C4FE62A2156A1690074AD08 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4C4FE62B2156A1690074AD08 /* Build configuration list for PBXNativeTarget "AsusSMC" */ = { isa = XCConfigurationList; buildConfigurations = ( 4C4FE62C2156A1690074AD08 /* Debug */, 4C4FE62D2156A1690074AD08 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4C4FE6B12156A4730074AD08 /* Build configuration list for PBXNativeTarget "AsusSMCDaemon" */ = { isa = XCConfigurationList; buildConfigurations = ( 4C4FE6B22156A4730074AD08 /* Debug */, 4C4FE6B32156A4730074AD08 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 4C4FE6182156A1690074AD08 /* Project object */; } ================================================ FILE: AsusSMCDaemon/BezelServices.h ================================================ // // BezelServices.h // AsusSMCDaemon // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #ifndef BezelServices_h #define BezelServices_h typedef enum { BSGraphicBacklightMeter = 0xfffffff7, BSGraphicBacklightFailure = 0xfffffff6, BSGraphicBacklightFailureMessage = 0xfffffff3, BSGraphicBacklightDoubleFailureMessage = 0xfffffff2, BSGraphicKeyboardBacklightMeter = 0xfffffff1, BSGraphicKeyboardBacklightDisabledMeter = 0xfffffff0, BSGraphicKeyboardBacklightNotConnected = 0xffffffef, BSGraphicKeyboardBacklightDisabledNotConnected = 0xffffffee, BSGraphicMacProOpen = 0xffffffe9, BSGraphicSpeakerMuted = 0xffffffe8, BSGraphicSpeaker = 0xffffffe7, BSGraphicRemoteBattery = 0xffffffe6, BSGraphicHotspot = 0xffffffe5, BSGraphicSleep = 0xffffffe3, BSGraphicSpeakerDisabledMuted = 0xffffffe2, BSGraphicSpeakerDisabled = 0xffffffe1, BSGraphicSpeakerMeter = 0xffffffe0, BSGraphicNewRemoteBattery = 0xffffffcb, } BSGraphic; extern void *BSDoGraphicWithMessage(CGDirectDisplayID arg0, BSGraphic arg1, int arg2, const char *arg3, int length); extern void *BSDoGraphicWithMeterAndTimeout(CGDirectDisplayID arg0, BSGraphic arg1, int arg2, float v, int timeout); #endif /* BezelServices_h */ ================================================ FILE: AsusSMCDaemon/OSD.h ================================================ // // OSD.h // AsusSMCDaemon // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #ifndef OSD_h #define OSD_h typedef enum { OSDGraphicBacklight = 1, // 1, 2, 7, 8 OSDGraphicSpeaker = 3, // 3, 5, 17, 23 OSDGraphicSpeakerMuted = 4, // 4, 16, 21, 22 OSDGraphicEject = 6, OSDGraphicNoWiFi = 9, OSDGraphicKeyboardBacklightMeter = 11, // 11, 25 OSDGraphicKeyboardBacklightDisabledMeter = 12, // 12, 26 OSDGraphicKeyboardBacklightNotConnected = 13, // 13, 27 OSDGraphicKeyboardBacklightDisabledNotConnected = 14, // 14, 28 OSDGraphicMacProOpen = 15, OSDGraphicHotspot = 19, OSDGraphicSleep = 20, // There may be more } OSDGraphic; typedef enum { OSDPriorityDefault = 0x1f4 } OSDPriority; @interface OSDManager : NSObject + (instancetype)sharedManager; - (void)showImage:(OSDGraphic)image onDisplayID:(CGDirectDisplayID)display priority:(OSDPriority)priority msecUntilFade:(int)timeout; - (void)showImage:(OSDGraphic)image onDisplayID:(CGDirectDisplayID)display priority:(OSDPriority)priority msecUntilFade:(int)timeout withText:(NSString *)text; - (void)showImage:(OSDGraphic)image onDisplayID:(CGDirectDisplayID)display priority:(OSDPriority)priority msecUntilFade:(int)timeout filledChiclets:(int)filled totalChiclets:(int)total locked:(BOOL)locked; @end #endif /* OSD_h */ ================================================ FILE: AsusSMCDaemon/com.hieplpvip.AsusSMCDaemon.plist ================================================ KeepAlive Label com.hieplpvip.AsusSMCDaemon ProgramArguments /usr/local/bin/AsusSMCDaemon RunAtLoad ServiceIPC ================================================ FILE: AsusSMCDaemon/install_daemon.sh ================================================ #!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" # remove AsusFnKeysDaemon sudo launchctl unload /Library/LaunchAgents/com.hieplpvip.AsusFnKeysDaemon.plist 2>/dev/null sudo pkill -f AsusFnKeysDaemon sudo rm /usr/bin/AsusFnKeysDaemon 2>/dev/null sudo rm /Library/LaunchAgents/com.hieplpvip.AsusFnKeysDaemon.plist 2>/dev/null # remove old AsusSMCDaemon sudo launchctl unload /Library/LaunchAgents/com.hieplpvip.AsusSMCDaemon.plist 2>/dev/null sudo rm /usr/bin/AsusSMCDaemon 2>/dev/null sudo mkdir -p /usr/local/bin/ sudo chmod -R 755 /usr/local/bin/ sudo cp $DIR/AsusSMCDaemon /usr/local/bin/ sudo chmod 755 /usr/local/bin/AsusSMCDaemon sudo chown root:wheel /usr/local/bin/AsusSMCDaemon sudo xattr -d com.apple.quarantine /usr/local/bin/AsusSMCDaemon 2>/dev/null sudo cp $DIR/com.hieplpvip.AsusSMCDaemon.plist /Library/LaunchAgents sudo chmod 644 /Library/LaunchAgents/com.hieplpvip.AsusSMCDaemon.plist sudo chown root:wheel /Library/LaunchAgents/com.hieplpvip.AsusSMCDaemon.plist sudo xattr -d com.apple.quarantine /Library/LaunchAgents/com.hieplpvip.AsusSMCDaemon.plist 2>/dev/null sudo launchctl load /Library/LaunchAgents/com.hieplpvip.AsusSMCDaemon.plist ================================================ FILE: AsusSMCDaemon/main.m ================================================ // // main.m // AsusSMCDaemon // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #define AsusSMCEventCode 0x8102 #import #import #import #import #import #import #import #import "BezelServices.h" #import "OSD.h" /* * kAERestart will cause system to restart * kAEShutDown will cause system to shutdown * kAEReallyLogout will cause system to logout * kAESleep will cause system to sleep */ extern OSStatus MDSendAppleEventToSystemProcess(AEEventID eventToSend); // requires IOBluetooth.framework void IOBluetoothPreferenceSetControllerPowerState(int); int IOBluetoothPreferenceGetControllerPowerState(void); static void *(*_BSDoGraphicWithMeterAndTimeout)(CGDirectDisplayID arg0, BSGraphic arg1, int arg2, float v, int timeout) = NULL; enum { kDaemonKeyboardBacklight = 1, kDaemonAirplaneMode = 2, kDaemonSleep = 3, kDaemonTouchpad = 4, }; struct AsusSMCMessage { int type; int x; int y; }; const int kMaxDisplays = 16; u_int32_t vendorID = 0; bool _loadBezelServices() { // Load BezelServices framework void *handle = dlopen("/System/Library/PrivateFrameworks/BezelServices.framework/Versions/A/BezelServices", RTLD_GLOBAL); if (!handle) { NSLog(@"Error opening framework"); return NO; } else { _BSDoGraphicWithMeterAndTimeout = dlsym(handle, "BSDoGraphicWithMeterAndTimeout"); return _BSDoGraphicWithMeterAndTimeout != NULL; } } bool _loadOSDFramework() { return [[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/OSD.framework"] load]; } OSStatus MDSendAppleEventToSystemProcess(AEEventID eventToSendID) { AEAddressDesc targetDesc; static const ProcessSerialNumber kPSNOfSystemProcess = {0, kSystemProcess }; AppleEvent eventReply = {typeNull, NULL}; AppleEvent eventToSend = {typeNull, NULL}; OSStatus status = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess, sizeof(kPSNOfSystemProcess), &targetDesc); if (status != noErr) return status; status = AECreateAppleEvent(kCoreEventClass, eventToSendID, &targetDesc, kAutoGenerateReturnID, kAnyTransactionID, &eventToSend); AEDisposeDesc(&targetDesc); if (status != noErr) return status; status = AESendMessage(&eventToSend, &eventReply, kAENormalPriority, kAEDefaultTimeout); AEDisposeDesc(&eventToSend); if (status != noErr) return status; AEDisposeDesc(&eventReply); return status; } void showBezelServices(BSGraphic image, float filled) { CGDirectDisplayID currentDisplayId = [NSScreen.mainScreen.deviceDescription [@"NSScreenNumber"] unsignedIntValue]; _BSDoGraphicWithMeterAndTimeout(currentDisplayId, image, 0x0, filled, 1); } void showOSD(OSDGraphic image, int filled, int total) { CGDirectDisplayID currentDisplayId = [NSScreen.mainScreen.deviceDescription [@"NSScreenNumber"] unsignedIntValue]; [[NSClassFromString(@"OSDManager") sharedManager] showImage:image onDisplayID:currentDisplayId priority:OSDPriorityDefault msecUntilFade:1000 filledChiclets:filled totalChiclets:total locked:NO]; } void showKBoardBLightStatus(int level, int max) { if (_BSDoGraphicWithMeterAndTimeout != NULL) { // El Capitan and probably older systems if (level) showBezelServices(BSGraphicKeyboardBacklightMeter, (float)level/max); else showBezelServices(BSGraphicKeyboardBacklightDisabledMeter, 0); } else { // Sierra+ if (level) showOSD(OSDGraphicKeyboardBacklightMeter, level, max); else showOSD(OSDGraphicKeyboardBacklightDisabledMeter, level, max); } } void goToSleep() { if (_BSDoGraphicWithMeterAndTimeout != NULL) // El Capitan and probably older systems MDSendAppleEventToSystemProcess(kAESleep); else { // Sierra+ CGDirectDisplayID currentDisplayId = [NSScreen.mainScreen.deviceDescription [@"NSScreenNumber"] unsignedIntValue]; [[NSClassFromString(@"OSDManager") sharedManager] showImage:OSDGraphicSleep onDisplayID:currentDisplayId priority:OSDPriorityDefault msecUntilFade:1000]; } } BOOL airplaneModeEnabled = NO, lastWifiState; int lastBluetoothState; void toggleAirplaneMode() { airplaneModeEnabled = !airplaneModeEnabled; CWInterface *currentInterface = [CWWiFiClient.sharedWiFiClient interface]; NSError *err = nil; if (airplaneModeEnabled) { lastWifiState = currentInterface.powerOn; lastBluetoothState = IOBluetoothPreferenceGetControllerPowerState(); [currentInterface setPower:NO error:&err]; IOBluetoothPreferenceSetControllerPowerState(0); } else { [currentInterface setPower:lastWifiState error:&err]; IOBluetoothPreferenceSetControllerPowerState(lastBluetoothState); } } int main(int argc, const char *argv[]) { @autoreleasepool { printf("daemon started...\n"); if (!_loadBezelServices()) { _loadOSDFramework(); } // system socket int systemSocket = -1; // create system socket to receive kernel event data systemSocket = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT); // struct for vendor code struct kev_vendor_code vendorCode = {0}; // set vendor name string strncpy(vendorCode.vendor_string, "com.hieplpvip", KEV_VENDOR_CODE_MAX_STR_LEN); // get vendor code ioctl(systemSocket, SIOCGKEVVENDOR, &vendorCode); // struct for kernel request filtering options struct kev_request kevRequest = {0}; // any class kevRequest.kev_class = KEV_ANY_CLASS; // any subclass kevRequest.kev_subclass = KEV_ANY_SUBCLASS; // tell kernel what we want to filter on ioctl(systemSocket, SIOCSKEVFILT, &kevRequest); // bytes received from system socket ssize_t bytesReceived = -1; // message from kext // size is cumulation of header, struct, and max length of a proc path char kextMsg[KEV_MSG_HEADER_SIZE + sizeof(struct AsusSMCMessage)] = {0}; struct AsusSMCMessage *message = NULL; while (YES) { bytesReceived = recv(systemSocket, kextMsg, sizeof(kextMsg), 0); if (bytesReceived != sizeof(kextMsg)) continue; // struct for broadcast data from the kext struct kern_event_msg *kernEventMsg = {0}; // type cast to access kev_event_msg header kernEventMsg = (struct kern_event_msg *)kextMsg; // only care about events sent by AsusSMC if (AsusSMCEventCode != kernEventMsg->event_code) { continue; } // typecast custom data // begins right after header message = (struct AsusSMCMessage *)&kernEventMsg->event_data[0]; //printf("type:%d x:%d y:%d\n", message->type, message->x, message->y); switch (message->type) { case kDaemonKeyboardBacklight: showKBoardBLightStatus(message->x, message->y); break; case kDaemonAirplaneMode: toggleAirplaneMode(); break; case kDaemonSleep: goToSleep(); break; //default: //printf("unknown type %d\n", message->type); } } } return 0; } ================================================ FILE: CHANGELOG.md ================================================ AsusSMC Changelog ======================= #### v1.4.1 - Added MacKernelSDK with Xcode 12 compatibility - Drop experimental custom fan control code - Drop AsusHID as I couldn't make it work on Catalina and above. Please use ROG-HID by @black-dragon74 - Improving touchpad toggling mechanism #### v1.4.0 - Rework keyboard backlight mechanism. Users need to repatch DSDT. More specific, the line `^^KBLV = Arg0 / 16` must be removed. - Rework ambient light sensor mechanism (use WMI for toggling sensor; read value directly with method `_ALI`). DSDT patch is not needed anymore. - Add experimental support for reading fan speed with WMI - Support battery charge threshold found on new laptops (charging stops at 80%). Can be disabled by turning off `Battery Health` in `Energy Saver`. #### v1.3.1 - Removed unimplemented virtual methods for kext to load correctly (thanks @Ubsefor) #### v1.3.0 - Native keyboard backlight on Catalina #### v1.2.3 - Remove unused WMI code - Correct usage of `powerStateOrdinal` in `setPowerState` #### v1.2.2 - Fix keyboard backlight remaining off after sleep on Catalina (thanks to @AR-CADE) #### v1.2.1 - Built with Lilu 1.4.1 and VirtualSMC 1.1.0 - Update `OSBundleLibraries` - Fix `install_daemon.sh` to make it work when folder `/usr/local/bin` does not exist #### v1.2.0 - Added support for USB HID keyboards found on ROG models - Optimized code - Updated MaciASL patches - Unified release archive names - Changed dependency com.apple.iokit.IOHIDSystem to com.apple.iokit.IOHIDFamily - Change AsusSMCDaemon installation location to support Catalina - Add workaround for keyboard backlight on Catalina #### v1.1.1 - Fixed memory leaks - Added support for direct messages from ACPI #### v1.1 - Optimized code #### v1.0.3 - Improved message handling mechanism #### v1.0.2 - Optimized code #### v1.0.1 - Write data to SMC key after setting keyboard backlight #### v1.0.0 - Initial release ================================================ FILE: Global/HIDReport.hpp ================================================ // // HIDReport.hpp // VirtualAppleKeyboard // // Copyright © 2019 Le Bao Hiep. All rights reserved. // class __attribute__((packed)) keys final { public: keys(void) : keys_{} {} const uint8_t(&get_raw_value(void) const)[32] { return keys_; } bool empty(void) const { for (const auto& k : keys_) { if (k != 0) { return false; } } return true; } void clear(void) { memset(keys_, 0, sizeof(keys_)); } void insert(uint8_t key) { if (!exists(key)) { for (auto&& k : keys_) { if (k == 0) { k = key; return; } } } } void erase(uint8_t key) { for (auto&& k : keys_) { if (k == key) { k = 0; } } } bool exists(uint8_t key) const { for (const auto& k : keys_) { if (k == key) { return true; } } return false; } size_t count(void) const { size_t result = 0; for (const auto& k : keys_) { if (k) { ++result; } } return result; } bool operator==(const keys& other) const { return (memcmp(this, &other, sizeof(*this)) == 0); } bool operator!=(const keys& other) const { return !(*this == other); } private: uint8_t keys_[32]; }; class __attribute__((packed)) consumer_input final { public: consumer_input(void) : report_id_(2) {} bool operator==(const consumer_input& other) const { return (memcmp(this, &other, sizeof(*this)) == 0); } bool operator!=(const consumer_input& other) const { return !(*this == other); } private: uint8_t report_id_ __attribute__((unused)); public: keys keys; }; class __attribute__((packed)) apple_vendor_top_case_input final { public: apple_vendor_top_case_input(void) : report_id_(3) {} bool operator==(const apple_vendor_top_case_input& other) const { return (memcmp(this, &other, sizeof(*this)) == 0); } bool operator!=(const apple_vendor_top_case_input& other) const { return !(*this == other); } private: uint8_t report_id_ __attribute__((unused)); public: keys keys; }; ================================================ FILE: Global/HIDUsageTables.h ================================================ // // HIDUsageTables.h // AsusSMC // // Copyright © 2019 Le Bao Hiep. All rights reserved. // #ifndef _HIDUsageTables_h #define _HIDUsageTables_h /* Usage Pages */ enum { kHIDPage_AppleVendorTopCase = 0x00ff, kHIDPage_AsusVendor = 0xff31, kHIDPage_MicrosoftVendor = 0xff00 }; /* AppleVendor Page Top Case (0x00ff) */ enum { kHIDUsage_AV_TopCase_KeyboardFn = 0x0003, kHIDUsage_AV_TopCase_BrightnessUp = 0x0004, kHIDUsage_AV_TopCase_BrightnessDown = 0x0005, kHIDUsage_AV_TopCase_VideoMirror = 0x0006, kHIDUsage_AV_TopCase_IlluminationToggle = 0x0007, kHIDUsage_AV_TopCase_IlluminationUp = 0x0008, kHIDUsage_AV_TopCase_IlluminationDown = 0x0009, kHIDUsage_AV_TopCase_ClamshellLatched = 0x000a, kHIDUsage_AV_TopCase_Reserved_MouseData = 0x00c0 }; /* AsusVendor Page (0xff31) */ enum { kHIDUsage_AsusVendor_BrightnessDown = 0x10, kHIDUsage_AsusVendor_BrightnessUp = 0x20, kHIDUsage_AsusVendor_DisplayOff = 0x35, kHIDUsage_AsusVendor_ROG = 0x38, kHIDUsage_AsusVendor_Power4Gear = 0x5c, /* Fn+Space Power4Gear Hybrid */ kHIDUsage_AsusVendor_TouchpadToggle = 0x6b, kHIDUsage_AsusVendor_Sleep = 0x6c, kHIDUsage_AsusVendor_MicMute = 0x7c, kHIDUsage_AsusVendor_Camera = 0x82, kHIDUsage_AsusVendor_RFKill = 0x88, kHIDUsage_AsusVendor_Fan = 0x99, /* Fn+F5 "fan" symbol on FX503VD */ kHIDUsage_AsusVendor_Calc = 0xb5, kHIDUsage_AsusVendor_Splendid = 0xba, /* Fn+C ASUS Splendid */ kHIDUsage_AsusVendor_IlluminationUp = 0xc4, kHIDUsage_AsusVendor_IlluminationDown = 0xc5 }; /* MicrosoftVendor Page (0xff31) */ enum { kHIDUsage_MicrosoftVendor_WLAN = 0xf1, kHIDUsage_MicrosoftVendor_BrightnessDown = 0xf2, kHIDUsage_MicrosoftVendor_BrightnessUp = 0xf3, kHIDUsage_MicrosoftVendor_DisplayOff = 0xf4, kHIDUsage_MicrosoftVendor_Camera = 0xf7, kHIDUsage_MicrosoftVendor_ROG = 0xf8, }; #endif /* _HIDUsageTables_h */ ================================================ FILE: KernEventServer/KernEventServer.cpp ================================================ // // KernEventServer.cpp // KernEventServer // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #include "KernEventServer.hpp" #include bool KernEventServer::setVendorID(const char *vendorCode) { if (KERN_SUCCESS != kev_vendor_code_find(vendorCode, &vendorID)) { DBGLOG("kevserver", "setVendorID error"); return false; } return true; } void KernEventServer::setEventCode(u_int32_t code) { eventCode = code; } bool KernEventServer::sendMessage(int type, int x, int y) { // kernel event message struct kev_msg kEventMsg = {0}; // zero out kernel message bzero(&kEventMsg, sizeof(struct kev_msg)); // set vendor code kEventMsg.vendor_code = vendorID; // set class kEventMsg.kev_class = KEV_ANY_CLASS; // set subclass kEventMsg.kev_subclass = KEV_ANY_SUBCLASS; // set event code kEventMsg.event_code = eventCode; // type kEventMsg.dv[0].data_length = sizeof(int); kEventMsg.dv[0].data_ptr = &type; // x kEventMsg.dv[1].data_length = sizeof(int); kEventMsg.dv[1].data_ptr = &x; // y kEventMsg.dv[2].data_length = sizeof(int); kEventMsg.dv[2].data_ptr = &y; if (KERN_SUCCESS != kev_msg_post(&kEventMsg)) { DBGLOG("kevserver", "sendMessage error"); return false; } return true; } ================================================ FILE: KernEventServer/KernEventServer.hpp ================================================ // // KernEventServer.hpp // KernEventServer // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #ifndef KernEventServer_hpp #define KernEventServer_hpp extern "C" { #include } #include class KernEventServer { public: bool setVendorID(const char *vendorCode); void setEventCode(u_int32_t code); bool sendMessage(int type, int x, int y); private: const char *getName(); u_int32_t vendorID = 0, eventCode = 0; }; #endif /* KernEventServer_hpp */ ================================================ FILE: LICENSE.md ================================================ The MIT License (MIT) ===================== Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # AsusSMC [![Github release](https://img.shields.io/github/release/hieplpvip/AsusSMC.svg?color=blue)](https://github.com/hieplpvip/AsusSMC/releases/latest) [![Github downloads](https://img.shields.io/github/downloads/hieplpvip/AsusSMC/total.svg?color=blue)](https://github.com/hieplpvip/AsusSMC/releases) [![Build Status](https://travis-ci.com/hieplpvip/AsusSMC.svg?branch=master)](https://travis-ci.com/hieplpvip/AsusSMC) [![Scan Status](https://scan.coverity.com/projects/18304/badge.svg)](https://scan.coverity.com/projects/18304) [![Gitter chat](https://img.shields.io/gitter/room/nwjs/nw.js.svg?colorB=ed1965)](https://gitter.im/hieplpvip/AsusSMC) [![Donate with PayPal](https://img.shields.io/badge/paypal-donate-red.svg)](https://paypal.me/lebhiep) A VirtualSMC plugin provides native support for ALS, keyboard backlight and Fn keys for Asus laptops on macOS. #### Features - Full Fn keys support - Native ALS support - Native keyboard backlight support (16 levels, smooth transition, auto adjusting, auto turning off) - Battery Health Charging #### Requirements - Asus laptop with ATK device - Knowing how to patch DSDT (if not, read [this](https://www.tonymacx86.com/threads/guide-patching-laptop-dsdt-ssdts.152573/)) #### Boot arguments - Add `-asussmcdbg` to enable debug printing (available in DEBUG binaries). #### How to install - Instruction is available in the Wiki. #### Credits - [Apple](https://www.apple.com) for macOS - [vit9696](https://github.com/vit9696) for [Lilu](https://github.com/acidanthera/Lilu) and [VirtualSMC](https://github.com/acidanthera/VirtualSMC) - [lvs1974](https://github.com/lvs1974) and [usr-sse2](https://github.com/usr-sse2) for developing ambient light sensor support - [EMlyDinEsHMG](https://osxlatitude.com/profile/7370-emlydinesh/) for [AsusNBFnKeys source code](https://github.com/EMlyDinEsHMG/AsusNBFnKeys) - [Objective-See](https://objective-see.com) for [kernel-userspace communication](https://objective-see.com/blog/blog_0x0B.html) - [tekezo](https://github.com/tekezo) for [VirtualHIDKeyboard](https://github.com/pqrs-org/Karabiner-VirtualHIDDevice/) - [williambj1](https://github.com/williambj1) for testing HID support ================================================ FILE: Scripts/bootstrap.sh ================================================ #!/bin/bash # # bootstrap.sh # # Copyright © 2019 hieplpvip. All rights reserved. # # This script is supposed to quickly bootstrap Lilu/VirtualSMC SDK for plugin building. # # Latest version available at: # https://raw.githubusercontent.com/hieplpvip/AsusSMC/master/Scripts/bootstrap.sh # # Example usage: # src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/hieplpvip/AsusSMC/master/Scripts/bootstrap.sh) && eval "$src" || exit 1 # SDK_PATH="Lilu.kext" PROJECT_PATH="$(pwd)" if [ $? -ne 0 ] || [ ! -d "${PROJECT_PATH}" ]; then echo "ERROR: Failed to determine working directory!" exit 1 fi # Avoid conflicts with PATH overrides. CURL="/usr/bin/curl" GIT="/usr/bin/git" GREP="/usr/bin/grep" MKDIR="/bin/mkdir" MV="/bin/mv" RM="/bin/rm" SED="/usr/bin/sed" UNAME="/usr/bin/uname" UNZIP="/usr/bin/unzip" UUIDGEN="/usr/bin/uuidgen" XCODEBUILD="/usr/bin/xcodebuild" TOOLS=( "${CURL}" "${GIT}" "${GREP}" "${MKDIR}" "${MV}" "${RM}" "${SED}" "${UNAME}" "${UNZIP}" "${UUIDGEN}" "${XCODEBUILD}" ) for tool in "${TOOLS[@]}"; do if [ ! -x "${tool}" ]; then echo "ERROR: Missing ${tool}!" exit 1 fi done # Prepare temporary directory to avoid conflicts with other scripts. # Sets TMP_PATH. prepare_environment() { local ret=0 local sys=$("${UNAME}") || ret=$? if [ $ret -ne 0 ] || [ "$sys" != "Darwin" ]; then echo "ERROR: This script is only meant to be used on Darwin systems!" return 1 fi local uuid=$("${UUIDGEN}") || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to generate temporary UUID with code ${ret}!" return 1 fi TMP_PATH="/tmp/lilutmp.${uuid}" if [ -e "${TMP_PATH}" ]; then echo "ERROR: Found existing temporary directory ${TMP_PATH}, aborting!" return 1 fi "${MKDIR}" "${TMP_PATH}" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to create temporary directory ${TMP_PATH} with code ${ret}!" return 1 fi cd "${TMP_PATH}" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to cd to temporary directory ${TMP_PATH} with code ${ret}!" "${RM}" -rf "${TMP_PATH}" return 1 fi return 0 } # Install prebuilt Lilu SDK for release distribution. install_lilu_sdk() { local ret=0 echo "Installing prebuilt Lilu SDK..." echo "-> Obtaining release manifest..." echo "-> Cloning the latest version from master..." # This is a really ugly hack due to GitHub API rate limits. local url="https://github.com/acidanthera/Lilu" "${GIT}" clone "${url}" -b "master" "lilu" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to clone repository with code ${ret}!" return 1 fi echo "-> Obtaining the latest tag..." cd "lilu" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to cd to temporary directory lilu with code ${ret}!" return 1 fi local vers=$("${GIT}" describe --abbrev=0 --tags) || ret=$? if [ "$vers" = "" ]; then echo "ERROR: Failed to determine the latest release tag!" return 1 fi echo "-> Discovered the latest tag ${vers}." cd .. || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to cd back from temporary directory with code ${ret}!" return 1 fi "${RM}" -rf lilu || ret=$? if [ $ret -ne 0 ] || [ -d lilu ]; then echo "ERROR: Failed to remove temporary directory lilu with code ${ret}!" return 1 fi local file="Lilu-${vers}-DEBUG.zip" echo "-> Downloading prebuilt debug version ${file}..." local url="https://github.com/acidanthera/Lilu/releases/download/${vers}/${file}" "${CURL}" -LfsO "${url}" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to download ${file} with code ${ret}!" return 1 fi echo "-> Extracting SDK from prebuilt debug version..." if [ ! -f "${file}" ]; then echo "ERROR: Failed to download ${file} to a non-existent location!" return 1 fi "${MKDIR}" "lilu" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to create temporary directory at ${TMP_PATH} with code ${ret}!" return 1 fi cd "lilu" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to cd to temporary directory lilu with code ${ret}!" return 1 fi "${UNZIP}" -q ../"${file}" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to unzip ${file} with code ${ret}!" return 1 fi echo "-> Installing SDK from the prebuilt debug version..." "${RM}" -rf "${PROJECT_PATH}/Lilu.kext" "${MV}" "Lilu.kext" "${PROJECT_PATH}/Lilu.kext" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to install SDK with code ${ret}!" return 1 fi echo "Installed prebuilt Lilu SDK ${vers}!" return 0 } # Install prebuilt VirtualSMC SDK for release distribution. install_vsmc_sdk() { local ret=0 echo "Installing prebuilt VirtualSMC SDK..." echo "-> Obtaining release manifest..." echo "-> Cloning the latest version from master..." # This is a really ugly hack due to GitHub API rate limits. local url="https://github.com/acidanthera/VirtualSMC" "${GIT}" clone "${url}" -b "master" "vsmc" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to clone repository with code ${ret}!" return 1 fi echo "-> Obtaining the latest tag..." cd "vsmc" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to cd to temporary directory vsmc with code ${ret}!" return 1 fi local vers=$("${GIT}" describe --abbrev=0 --tags) || ret=$? if [ "$vers" = "" ]; then echo "ERROR: Failed to determine the latest release tag!" return 1 fi echo "-> Discovered the latest tag ${vers}." cd .. || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to cd back from temporary directory with code ${ret}!" return 1 fi "${RM}" -rf vsmc || ret=$? if [ $ret -ne 0 ] || [ -d vsmc ]; then echo "ERROR: Failed to remove temporary directory vsmc with code ${ret}!" return 1 fi local file="VirtualSMC-${vers}-DEBUG.zip" echo "-> Downloading prebuilt debug version ${file}..." local url="https://github.com/acidanthera/VirtualSMC/releases/download/${vers}/${file}" "${CURL}" -LfsO "${url}" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to download ${file} with code ${ret}!" return 1 fi echo "-> Extracting SDK from prebuilt debug version..." if [ ! -f "${file}" ]; then echo "ERROR: Failed to download ${file} to a non-existent location!" return 1 fi "${MKDIR}" "vsmc" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to create temporary directory at ${TMP_PATH} with code ${ret}!" return 1 fi cd "vsmc" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to cd to temporary directory vsmc with code ${ret}!" return 1 fi "${UNZIP}" -q ../"${file}" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to unzip ${file} with code ${ret}!" return 1 fi echo "-> Installing SDK from the prebuilt debug version..." "${RM}" -rf "${PROJECT_PATH}/VirtualSMC.kext" "${MV}" "Kexts/VirtualSMC.kext" "${PROJECT_PATH}/VirtualSMC.kext" || ret=$? if [ $ret -ne 0 ]; then echo "ERROR: Failed to install SDK with code ${ret}!" return 1 fi echo "Installed prebuilt VirtualSMC SDK ${vers}!" return 0 } prepare_environment || exit 1 ret=0 install_lilu_sdk || ret=$? echo "------------------------------" install_vsmc_sdk || ret=$? cd "${PROJECT_PATH}" || ret=$? "${RM}" -rf "${TMP_PATH}" if [ $ret -ne 0 ]; then echo "ERROR: Failed to bootstrap SDK with code ${ret}!" exit 1 fi ================================================ FILE: VirtualAppleKeyboard/VirtualAppleKeyboard.cpp ================================================ // // VirtualAppleKeyboard.cpp // VirtualAppleKeyboard // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #include "VirtualAppleKeyboard.hpp" #define super IOHIDDevice OSDefineMetaClassAndStructors(VirtualAppleKeyboard, super); const uint8_t virt_reportDescriptor[] = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x06, // Usage (Keyboard) 0xa1, 0x01, // Collection (Application) 0x85, 0x01, // Report Id (1) 0x05, 0x07, // Usage Page (Keyboard/Keypad) 0x19, 0xe0, // Usage Minimum........... (224) 0x29, 0xe7, // Usage Maximum........... (231) 0x15, 0x00, // Logical Minimum......... (0) 0x25, 0x01, // Logical Maximum......... (1) 0x75, 0x01, // Report Size............. (1) 0x95, 0x08, // Report Count............ (8) 0x81, 0x02, // Input...................(Data, Variable, Absolute) // 0x95, 0x01, // Report Count............ (1) 0x75, 0x08, // Report Size............. (8) 0x81, 0x01, // Input...................(Constant) // 0x95, 0x20, // Report Count............ (32) 0x75, 0x08, // Report Size............. (8) 0x15, 0x00, // Logical Minimum......... (0) 0x26, 0xff, 0x00, // Logical Maximum......... (255) 0x05, 0x07, // Usage Page (Keyboard/Keypad) 0x19, 0x00, // Usage Minimum........... (0) 0x29, 0xff, // Usage Maximum........... (255) 0x81, 0x00, // Input...................(Data, Array, Absolute) 0xc0, // End Collection 0x05, 0x0c, // Usage Page (Consumer) 0x09, 0x01, // Usage 1 (kHIDUsage_Csmr_ConsumerControl) 0xa1, 0x01, // Collection (Application) 0x85, 0x02, // Report Id (2) 0x05, 0x0c, // Usage Page (Consumer) 0x95, 0x20, // Report Count............ (32) 0x75, 0x08, // Report Size............. (8) 0x15, 0x00, // Logical Minimum......... (0) 0x26, 0xff, 0x00, // Logical Maximum......... (255) 0x19, 0x00, // Usage Minimum........... (0) 0x29, 0xff, // Usage Maximum........... (255) 0x81, 0x00, // Input...................(Data, Array, Absolute) 0xc0, // End Collection 0x06, 0x00, 0xff, // Usage Page (kHIDPage_AppleVendor) 0x09, 0x01, // Usage 1 (kHIDUsage_AppleVendor_TopCase) 0xa1, 0x01, // Collection (Application) 0x85, 0x03, // Report Id (3) 0x05, 0xff, // Usage Page (kHIDPage_AppleVendorTopCase) 0x95, 0x20, // Report Count............ (32) 0x75, 0x08, // Report Size............. (8) 0x15, 0x00, // Logical Minimum......... (0) 0x26, 0xff, 0x00, // Logical Maximum......... (255) 0x19, 0x00, // Usage Minimum........... (0) 0x29, 0xff, // Usage Maximum........... (255) 0x81, 0x00, // Input...................(Data, Array, Absolute) 0xc0, // End Collection 0x06, 0x00, 0xff, // Usage Page (kHIDPage_AppleVendor) 0x09, 0x0f, // Usage 15 (kHIDUsage_AppleVendor_KeyboardBacklight) 0xa1, 0x01, // Collection (Application) 0x85, 0xbf, // Report ID (191) 0x06, 0x00, 0xff, // Usage Page (kHIDUsage_AppleVendor_KeyboardBacklight) 0x95, 0x20, // Report Count............ (32) 0x75, 0x08, // Report Size............. (8) 0x15, 0x00, // Logical Minimum......... (0) 0x26, 0xff, 0x00, // Logical Maximum......... (255) 0x19, 0x00, // Usage Minimum........... (0) 0x29, 0xff, // Usage Maximum........... (255) 0x81, 0x00, // Input...................(Data, Array, Absolute) 0xc0, // End Collection }; bool VirtualAppleKeyboard::handleStart(IOService *provider) { if (!super::handleStart(provider)) { return false; } setProperty("AppleVendorSupported", kOSBooleanTrue); setProperty("Built-In", kOSBooleanTrue); setProperty("HIDDefaultBehavior", kOSBooleanTrue); return true; } IOReturn VirtualAppleKeyboard::newReportDescriptor(IOMemoryDescriptor **descriptor) const { *descriptor = IOBufferMemoryDescriptor::withBytes(virt_reportDescriptor, sizeof(virt_reportDescriptor), kIODirectionNone); return kIOReturnSuccess; } IOReturn VirtualAppleKeyboard::getReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options) { uint8_t report_id = options & 0xff; OSData *get_buffer = OSData::withCapacity(1); if (report_id == 0xbf) { uint8_t buffer[] = {0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00}; get_buffer->appendBytes(buffer, sizeof(buffer)); } report->writeBytes(0, get_buffer->getBytesNoCopy(), get_buffer->getLength()); get_buffer->release(); return kIOReturnSuccess; } OSString *VirtualAppleKeyboard::newManufacturerString() const { return OSString::withCString("Apple Inc."); } OSString *VirtualAppleKeyboard::newProductString() const { return OSString::withCString("Virtual Apple Keyboard"); } OSNumber *VirtualAppleKeyboard::newVendorIDNumber() const { return OSNumber::withNumber(0x5ac, 32); } OSNumber *VirtualAppleKeyboard::newProductIDNumber() const { return OSNumber::withNumber(0x276, 32); } OSNumber *VirtualAppleKeyboard::newLocationIDNumber() const { return OSNumber::withNumber(0x1000000, 32); } OSNumber *VirtualAppleKeyboard::newCountryCodeNumber() const { return OSNumber::withNumber(0x21, 32); } OSNumber *VirtualAppleKeyboard::newVersionNumber() const { return OSNumber::withNumber(0x895, 32); } OSNumber *VirtualAppleKeyboard::newPrimaryUsagePageNumber() const { return OSNumber::withNumber(kHIDPage_GenericDesktop, 32); } OSNumber *VirtualAppleKeyboard::newPrimaryUsageNumber() const { return OSNumber::withNumber(kHIDUsage_GD_Keyboard, 32); } ================================================ FILE: VirtualAppleKeyboard/VirtualAppleKeyboard.hpp ================================================ // // VirtualAppleKeyboard.hpp // VirtualAppleKeyboard // // Copyright © 2018-2020 Le Bao Hiep. All rights reserved. // #include class VirtualAppleKeyboard final : public IOHIDDevice { OSDeclareDefaultStructors(VirtualAppleKeyboard); public: bool handleStart(IOService *provider) override; IOReturn newReportDescriptor(IOMemoryDescriptor **descriptor) const override; IOReturn getReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options) override; OSString *newManufacturerString() const override; OSString *newProductString() const override; OSNumber *newVendorIDNumber() const override; OSNumber *newProductIDNumber() const override; OSNumber *newLocationIDNumber() const override; OSNumber *newCountryCodeNumber() const override; OSNumber *newVersionNumber() const override; OSNumber *newPrimaryUsagePageNumber() const override; OSNumber *newPrimaryUsageNumber() const override; }; ================================================ FILE: patches/NullPatch.txt ================================================ #Maintained by hieplpvip #NullPatch.txt # This is not a patch.... ================================================ FILE: patches/als_toggle.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q76 for ALS toggle A key to work into Method label _Q76 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x7A)\n } end; ================================================ FILE: patches/f1.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q0A for F1 key to work into Method label _Q0A replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x5E)\n } end; ================================================ FILE: patches/f10.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q13 for F10 key to work into Method label _Q13 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x32)\n } end; ================================================ FILE: patches/f11.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q14 for F11 key to work into Method label _Q14 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x31)\n } end; ================================================ FILE: patches/f12.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q15 for F12 key to work into Method label _Q15 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x30)\n } end; ================================================ FILE: patches/f2.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q0B for F2 key to work into Method label _Q0B replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x7D)\n } end; ================================================ FILE: patches/f3.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q0C for F3 key to work into Method label _Q0C replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0xC5)\n } end; ================================================ FILE: patches/f4.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q0D for F4 key to work into Method label _Q0D replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0xC4)\n } end; ================================================ FILE: patches/f5.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q0E for F5 key to work into Method label _Q0E replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x20)\n } end; ================================================ FILE: patches/f6.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q0F for F6 key to work into Method label _Q0F replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x10)\n } end; ================================================ FILE: patches/f7.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q10 for F7 key to work into Method label _Q10 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x35)\n } end; ================================================ FILE: patches/f8.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q11 for F8 key to work into Method label _Q11 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x61)\n } end; ================================================ FILE: patches/f9.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q12 for F9 key to work into Method label _Q12 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x6B)\n } end; ================================================ FILE: patches/fake_als.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use into_all device label ALS0 remove_entry; into scope label _SB insert begin Device(ALS0)\n {\n Name(_HID, "ACPI0008")\n Name(_CID, "smc-als")\n Name(_ALI, 150)\n Name(_ALR, Package()\n {\n Package() { 100, 150 },\n })\n } end; ================================================ FILE: patches/kbl_broadwell.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use into method label SKBV parent_label ATKD remove_entry; into device label ATKD insert begin Method (SKBV, 1, NotSerialized)\n {\n ^^PCI0.LPCB.EC0.WRAM (0x04B1, Arg0)\n Return (Arg0)\n }\n end; into method label KBLD code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC5) end; into method label KBLU code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC4) end; ================================================ FILE: patches/kbl_coffeelake.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use into method label SKBV parent_label ATKD remove_entry; into device label ATKD insert begin Method (SKBV, 1, NotSerialized)\n {\n ^^PCI0.LPCB.EC0.WRAM (0xBA, 0xC9F0, ^^KBLV)\n ^^PCI0.LPCB.EC0.ST9E (0x1F, 0xFF, Arg0)\n Return (Arg0)\n }\n end; into method label KBLD code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC5) end; into method label KBLU code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC4) end; ================================================ FILE: patches/kbl_icelake.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use into method label SKBV parent_label ATKD remove_entry; into device label ATKD insert begin Method (SKBV, 1, NotSerialized)\n {\n ^^PCI0.LPCB.EC0.ST9E (0x1F, 0xFF, Arg0)\n Return (Arg0)\n }\n end; into method label KBLD code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC5) end; into method label KBLU code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC4) end; ================================================ FILE: patches/kbl_ivybridge.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use into method label SKBV parent_label ATKD remove_entry; into device label ATKD insert begin Method (SKBV, 1, NotSerialized)\n {\n ^^PCI0.LPCB.EC0.WRAM (0x044B, Arg0)\n Return (Arg0)\n }\n end; into method label KBLD code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC5) end; into method label KBLU code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC4) end; ================================================ FILE: patches/kbl_kabylake.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use into method label SKBV parent_label ATKD remove_entry; into device label ATKD insert begin Method (SKBV, 1, NotSerialized)\n {\n ^^PCI0.LPCB.EC0.WRAM (0x09F0, ^^KBLV)\n ^^PCI0.LPCB.EC0.ST9E (0x1F, 0xFF, Arg0)\n Return (Arg0)\n }\n end; into method label KBLD code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC5) end; into method label KBLU code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC4) end; ================================================ FILE: patches/kbl_tuf.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use into method label SKBV parent_label ATKD remove_entry; into device label ATKD insert begin Method (SKBV, 1, NotSerialized)\n {\n Arg0 = (Arg0 / 16) | 0x80\n SLKI(Arg0)\n Return (One)\n }\n end; ================================================ FILE: patches/kbl_whiskeylake.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use into method label SKBV parent_label ATKD remove_entry; into device label ATKD insert begin Method (SKBV, 1, NotSerialized)\n {\n ^^PCI0.LPCB.EC0.ST9E (0x1F, 0xFF, Arg0)\n Return (Arg0)\n }\n end; into method label KBLD code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC5) end; into method label KBLU code_regex ATKD.IANE\s+\(\w+\) replace_matched begin ATKD.IANE (0xC4) end; ================================================ FILE: patches/media_arrow.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q6C for media left arrow key to work into Method label _Q6C replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x40)\n } end; # Replacing method _Q6D for media right arrow key to work into Method label _Q6D replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x41)\n } end; # Replacing method _Q6E for media up arrow key to work into Method label _Q6E replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x43)\n } end; # Replacing method _Q6F for media down arrow key to work into Method label _Q6F replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x45)\n } end; ================================================ FILE: patches/media_cvspace.txt ================================================ #Maintained by hieplpvip #See https://github.com/hieplpvip/AsusSMC/wiki/Installation-Instruction #for how to use # Replacing method _Q71 for space key to work into Method label _Q71 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x5C)\n } end; # Replacing method _Q72 for V key to work # by removing the code which prevents into Method label _Q72 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x8A)\n } end; # Replacing method _Q73 for C key to work # by removing the code which prevents into Method label _Q73 replace_content begin If (ATKP)\n {\n \_SB.ATKD.IANE (0x82)\n } end;