diff --git a/BigSurface/BigSurface/Info.plist b/BigSurface/BigSurface/Info.plist index 1eba7d7..549f4e9 100644 --- a/BigSurface/BigSurface/Info.plist +++ b/BigSurface/BigSurface/Info.plist @@ -481,6 +481,8 @@ 400 IOProviderClass VoodooI2CDeviceNub + BaseALIValue + 100 VoodooI2CControllerDriver diff --git a/BigSurface/BigSurface/SurfaceAmbientLightSensor/APDS9960Constants.h b/BigSurface/BigSurface/SurfaceAmbientLightSensor/APDS9960Constants.h index 5deb081..dedd6b1 100644 --- a/BigSurface/BigSurface/SurfaceAmbientLightSensor/APDS9960Constants.h +++ b/BigSurface/BigSurface/SurfaceAmbientLightSensor/APDS9960Constants.h @@ -98,6 +98,8 @@ enum { #define TIME_TO_VALUE(ms) (256 - (ms / 2.78)) +#define CONFIG1_DEFAULT 0x60 + /* LED Drive values */ #define LED_DRIVE_100MA 0 #define LED_DRIVE_50MA 1 diff --git a/BigSurface/BigSurface/SurfaceAmbientLightSensor/SurfaceAmbientLightSensorDriver.cpp b/BigSurface/BigSurface/SurfaceAmbientLightSensor/SurfaceAmbientLightSensorDriver.cpp index 525866b..bf2d636 100644 --- a/BigSurface/BigSurface/SurfaceAmbientLightSensor/SurfaceAmbientLightSensorDriver.cpp +++ b/BigSurface/BigSurface/SurfaceAmbientLightSensor/SurfaceAmbientLightSensorDriver.cpp @@ -37,7 +37,7 @@ IOService* SurfaceAmbientLightSensorDriver::probe(IOService *provider, SInt32 *s reinterpret_cast(&noSensor), sizeof(noSensor), SmcKeyTypeAli, nullptr, SMC_KEY_ATTRIBUTE_CONST | SMC_KEY_ATTRIBUTE_READ)); VirtualSMCAPI::addKey(KeyALRV, vsmcPlugin.data, VirtualSMCAPI::valueWithUint16(1, nullptr, SMC_KEY_ATTRIBUTE_CONST | SMC_KEY_ATTRIBUTE_READ)); VirtualSMCAPI::addKey(KeyALV0, vsmcPlugin.data, VirtualSMCAPI::valueWithData( - reinterpret_cast(&emptyValue), sizeof(emptyValue), SmcKeyTypeAlv, new SMCAmbientLightValue(¤tLux, &forceBits), + reinterpret_cast(&emptyValue), sizeof(emptyValue), SmcKeyTypeAlv, new SMCAmbientLightValue(¤t_lux, &forceBits), SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_WRITE)); VirtualSMCAPI::addKey(KeyALV1, vsmcPlugin.data, VirtualSMCAPI::valueWithData( reinterpret_cast(&emptyValue), sizeof(emptyValue), SmcKeyTypeAlv, nullptr, @@ -49,6 +49,7 @@ IOService* SurfaceAmbientLightSensorDriver::probe(IOService *provider, SInt32 *s } bool SurfaceAmbientLightSensorDriver::start(IOService *provider) { + OSNumber *base; if (!super::start(provider)) return false; @@ -73,6 +74,12 @@ bool SurfaceAmbientLightSensorDriver::start(IOService *provider) { IOLog("%s::Failed to init device\n", getName()); goto exit; } + base = OSDynamicCast(OSNumber, getProperty("BaseALIValue")); + if (!base) { + IOLog("%s::Failed to obtain base ALI setting from property! Using default 100 instead!\n", getName()); + } else { + base_ali = base->unsigned16BitValue(); + } PMinit(); api->joinPMtree(this); @@ -131,17 +138,18 @@ IOReturn SurfaceAmbientLightSensorDriver::initDevice() { IOLog("%s::Device id is %x\n", getName(), id); ENSURE(writeRegister(APDS9960_ENABLE, 0x00)) - ENSURE(writeRegister(APDS9960_WTIME, 0xFF)) - - ENSURE(configDevice(ENABLE_POWER, true)) + // set short wait time to 712ms maximum + ENSURE(writeRegister(APDS9960_WTIME, TIME_TO_VALUE(712))) ENSURE(configDevice(ENABLE_WAIT, true)) // set ADC integration time to 100 ms - ENSURE(writeRegister(APDS9960_ATIME, TIME_TO_VALUE(100))) - ENSURE(writeRegister(APDS9960_WTIME, TIME_TO_VALUE(100))) - ENSURE(writeRegister(APDS9960_CONTROL, ALS_GAIN_16X)) - - configDevice(ENABLE_ALS, true); - readRegister(APDS9960_AICLEAR, &id, 1); + ENSURE(writeRegister(APDS9960_ATIME, TIME_TO_VALUE(200))) + ENSURE(writeRegister(APDS9960_CONFIG1, CONFIG1_DEFAULT)) + ENSURE(writeRegister(APDS9960_CONTROL, ALS_GAIN_1X)) + // these values come from Windows and is NECESSARY + ENSURE(writeRegister(APDS9960_CONFIG2, 0x03)) + ENSURE(writeRegister(APDS9960_CONFIG3, 0x14)) + ENSURE(configDevice(ENABLE_POWER, true)) + ENSURE(configDevice(ENABLE_ALS, true)); return kIOReturnSuccess; } @@ -179,18 +187,13 @@ IOReturn SurfaceAmbientLightSensorDriver::configDevice(UInt8 func, bool enable) void SurfaceAmbientLightSensorDriver::pollALI(OSObject* owner, IOTimerEventSource *timer) { UInt16 color[4]; - IOReturn ret1 = readRegister(APDS9960_CDATAL, reinterpret_cast(color), sizeof(color)); - if (ret1 != kIOReturnSuccess) { + if (readRegister(APDS9960_CDATAL, reinterpret_cast(color), sizeof(color)) != kIOReturnSuccess) { IOLog("%s::Read from ALS failed!\n", getName()); goto exit; } - if (color[0] > 20) { - atomic_store_explicit(¤tLux, color[20], memory_order_release); - VirtualSMCAPI::postInterrupt(SmcEventALSChange); - } else { - atomic_store_explicit(¤tLux, 300, memory_order_release); // readout incorrect when cold boot - } - IOLog("%s::Value: ALI=%04x, r=%04x, g=%04x, b=%04x\n", getName(), color[0], color[1], color[2], color[3]); + atomic_store_explicit(¤t_lux, color[0]+base_ali, memory_order_release); + VirtualSMCAPI::postInterrupt(SmcEventALSChange); + IOLog("%s::Value: ALI=%04d, r=0x%04x, g=0x%04x, b=0x%04x\n", getName(), color[0]+base_ali, color[1], color[2], color[3]); exit: poller->setTimeoutMS(POLLING_INTERVAL); } @@ -237,8 +240,3 @@ void SurfaceAmbientLightSensorDriver::releaseResources() { api = nullptr; } } - -EXPORT extern "C" kern_return_t ADDPR(kern_stop)(kmod_info_t *, void *) { - // It is not safe to unload VirtualSMC plugins! - return KERN_FAILURE; -} diff --git a/BigSurface/BigSurface/SurfaceAmbientLightSensor/SurfaceAmbientLightSensorDriver.hpp b/BigSurface/BigSurface/SurfaceAmbientLightSensor/SurfaceAmbientLightSensorDriver.hpp index 480d21d..7d027f0 100644 --- a/BigSurface/BigSurface/SurfaceAmbientLightSensor/SurfaceAmbientLightSensorDriver.hpp +++ b/BigSurface/BigSurface/SurfaceAmbientLightSensor/SurfaceAmbientLightSensorDriver.hpp @@ -25,7 +25,6 @@ #include "AmbientLightValue.hpp" #include "APDS9960Constants.h" -#define PRODUCT_NAME SurfaceAmbientLightSensorDriver #define POLLING_INTERVAL 1000 class EXPORT SurfaceAmbientLightSensorDriver : public IOService { @@ -52,7 +51,8 @@ class EXPORT SurfaceAmbientLightSensorDriver : public IOService { bool awake {true}; - _Atomic(UInt32) currentLux; + _Atomic(UInt32) current_lux; + UInt16 base_ali {100}; IONotifier *vsmcNotifier {nullptr}; static constexpr SMC_KEY KeyAL = SMC_MAKE_IDENTIFIER('A','L','!',' '); static constexpr SMC_KEY KeyALI0 = SMC_MAKE_IDENTIFIER('A','L','I','0');