Skip to content

Commit

Permalink
using Windows init sequence, add base ALI value----thanks llccd
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiashangning committed Nov 20, 2021
1 parent a349125 commit 87450ad
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 26 deletions.
2 changes: 2 additions & 0 deletions BigSurface/BigSurface/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,8 @@
<integer>400</integer>
<key>IOProviderClass</key>
<string>VoodooI2CDeviceNub</string>
<key>BaseALIValue</key>
<integer>100</integer>
</dict>
<key>VoodooI2CControllerDriver</key>
<dict>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ IOService* SurfaceAmbientLightSensorDriver::probe(IOService *provider, SInt32 *s
reinterpret_cast<const SMC_DATA *>(&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<const SMC_DATA *>(&emptyValue), sizeof(emptyValue), SmcKeyTypeAlv, new SMCAmbientLightValue(&currentLux, &forceBits),
reinterpret_cast<const SMC_DATA *>(&emptyValue), sizeof(emptyValue), SmcKeyTypeAlv, new SMCAmbientLightValue(&current_lux, &forceBits),
SMC_KEY_ATTRIBUTE_READ | SMC_KEY_ATTRIBUTE_WRITE));
VirtualSMCAPI::addKey(KeyALV1, vsmcPlugin.data, VirtualSMCAPI::valueWithData(
reinterpret_cast<const SMC_DATA *>(&emptyValue), sizeof(emptyValue), SmcKeyTypeAlv, nullptr,
Expand All @@ -49,6 +49,7 @@ IOService* SurfaceAmbientLightSensorDriver::probe(IOService *provider, SInt32 *s
}

bool SurfaceAmbientLightSensorDriver::start(IOService *provider) {
OSNumber *base;
if (!super::start(provider))
return false;

Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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<UInt8 *>(color), sizeof(color));
if (ret1 != kIOReturnSuccess) {
if (readRegister(APDS9960_CDATAL, reinterpret_cast<UInt8 *>(color), sizeof(color)) != kIOReturnSuccess) {
IOLog("%s::Read from ALS failed!\n", getName());
goto exit;
}
if (color[0] > 20) {
atomic_store_explicit(&currentLux, color[20], memory_order_release);
VirtualSMCAPI::postInterrupt(SmcEventALSChange);
} else {
atomic_store_explicit(&currentLux, 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(&current_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);
}
Expand Down Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include "AmbientLightValue.hpp"
#include "APDS9960Constants.h"

#define PRODUCT_NAME SurfaceAmbientLightSensorDriver
#define POLLING_INTERVAL 1000

class EXPORT SurfaceAmbientLightSensorDriver : public IOService {
Expand All @@ -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');
Expand Down

0 comments on commit 87450ad

Please sign in to comment.