diff --git a/src/detection/brightness/brightness_apple.c b/src/detection/brightness/brightness_apple.c index a3b1d3c8f..947115bfb 100644 --- a/src/detection/brightness/brightness_apple.c +++ b/src/detection/brightness/brightness_apple.c @@ -1,9 +1,27 @@ #include "brightness.h" #include "detection/displayserver/displayserver.h" #include "util/apple/cf_helpers.h" -#include "util/apple/ddcci.h" #include "util/edidHelper.h" +#include + +// DDC/CI +#ifdef __aarch64__ +typedef CFTypeRef IOAVServiceRef; +extern IOAVServiceRef IOAVServiceCreate(CFAllocatorRef allocator) __attribute__((weak_import)); +extern IOAVServiceRef IOAVServiceCreateWithService(CFAllocatorRef allocator, io_service_t service) __attribute__((weak_import)); +extern IOReturn IOAVServiceCopyEDID(IOAVServiceRef service, CFDataRef* x2) __attribute__((weak_import)); +extern IOReturn IOAVServiceReadI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t offset, void* outputBuffer, uint32_t outputBufferSize) __attribute__((weak_import)); +extern IOReturn IOAVServiceWriteI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t dataAddress, void* inputBuffer, uint32_t inputBufferSize) __attribute__((weak_import)); +#else +// DDC/CI (Intel) +#include +#include +#include +extern void CGSServiceForDisplayNumber(CGDirectDisplayID display, io_service_t* service) __attribute__((weak_import)); +#endif + +// ACPI extern int DisplayServicesGetBrightness(CGDirectDisplayID display, float *brightness) __attribute__((weak_import)); // Works for internal display @@ -31,9 +49,10 @@ static const char* detectWithDisplayServices(const FFDisplayServerResult* displa return NULL; } +#ifdef __aarch64__ // https://github.com/waydabber/m1ddc // Works for Apple Silicon and USB-C adapter connection ( but not HTMI ) -FF_MAYBE_UNUSED static const char* detectWithDdcci(FFlist* result) +static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult* displayServer, FFlist* result) { if (!IOAVServiceCreate || !IOAVServiceReadI2C) return "IOAVService is not available"; @@ -105,6 +124,71 @@ FF_MAYBE_UNUSED static const char* detectWithDdcci(FFlist* result) return NULL; } +#else +static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFlist* result) +{ + if (!CGSServiceForDisplayNumber) return "CGSServiceForDisplayNumber is not available"; + + FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays) + { + if (display->type == FF_DISPLAY_TYPE_EXTERNAL) + { + io_service_t framebuffer = 0; + CGSServiceForDisplayNumber((CGDirectDisplayID)display->id, &framebuffer); + if (framebuffer == 0) continue; + + IOItemCount count; + if (IOFBGetI2CInterfaceCount(framebuffer, &count) != KERN_SUCCESS || count == 0) continue; + + io_service_t interface = 0; + if (IOFBCopyI2CInterfaceForBus(framebuffer, 0, &interface) != KERN_SUCCESS) continue; + + uint8_t i2cOut[12] = {}; + IOI2CConnectRef connect; + if (IOI2CInterfaceOpen(interface, kNilOptions, &connect) != KERN_SUCCESS) + { + IOObjectRelease(interface); + continue; + } + + uint8_t i2cIn[] = { 0x51, 0x82, 0x01, 0x10 /* luminance */, 0 }; + i2cIn[4] = 0x6E ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2] ^ i2cIn[3]; + + IOI2CRequest request = { + .commFlags = kNilOptions, + .sendAddress = 0x6e, + .sendTransactionType = kIOI2CSimpleTransactionType, + .sendBuffer = (vm_address_t) i2cIn, + .sendBytes = sizeof(i2cIn) / sizeof(i2cIn[0]), + .minReplyDelay = 10, + .replyAddress = 0x6F, + .replySubAddress = 0x51, + .replyTransactionType = kIOI2CDDCciReplyTransactionType, + .replyBytes = sizeof(i2cOut) / sizeof(i2cOut[0]), + .replyBuffer = (vm_address_t) i2cOut, + }; + IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request); + IOI2CInterfaceClose(connect, kNilOptions); + IOObjectRelease(interface); + + if (ret != KERN_SUCCESS || request.result != kIOReturnSuccess) continue; + + if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) continue; + + uint32_t current = ((uint32_t) i2cOut[8] << 8u) + (uint32_t) i2cOut[9]; + uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7]; + + FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result); + brightness->max = max; + brightness->min = 0; + brightness->current = current; + ffStrbufInitCopy(&brightness->name, &display->name); + } + } + + return NULL; +} +#endif const char* ffDetectBrightness(FFlist* result) { @@ -112,10 +196,8 @@ const char* ffDetectBrightness(FFlist* result) detectWithDisplayServices(displayServer, result); - #ifdef __aarch64__ if (displayServer->displays.length > result->length) - detectWithDdcci(result); - #endif + detectWithDdcci(displayServer, result); return NULL; } diff --git a/src/detection/monitor/monitor_apple.m b/src/detection/monitor/monitor_apple.m index 9d9ceb4bc..be3b51a46 100644 --- a/src/detection/monitor/monitor_apple.m +++ b/src/detection/monitor/monitor_apple.m @@ -1,11 +1,11 @@ #include "monitor.h" #include "detection/displayserver/displayserver.h" #include "util/apple/cf_helpers.h" -#include "util/apple/ddcci.h" #include "util/edidHelper.h" #import #import +#import extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import)); diff --git a/src/util/apple/ddcci.h b/src/util/apple/ddcci.h deleted file mode 100644 index a0de17482..000000000 --- a/src/util/apple/ddcci.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#ifndef FASTFETCH_INCLUDED_util_apple_ddcci_h - -#include - -// DDC/CI -typedef CFTypeRef IOAVServiceRef; -extern IOAVServiceRef IOAVServiceCreate(CFAllocatorRef allocator) __attribute__((weak_import)); -extern IOAVServiceRef IOAVServiceCreateWithService(CFAllocatorRef allocator, io_service_t service) __attribute__((weak_import)); -extern IOReturn IOAVServiceCopyEDID(IOAVServiceRef service, CFDataRef* x2) __attribute__((weak_import)); -extern IOReturn IOAVServiceReadI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t offset, void* outputBuffer, uint32_t outputBufferSize) __attribute__((weak_import)); -extern IOReturn IOAVServiceWriteI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t dataAddress, void* inputBuffer, uint32_t inputBufferSize) __attribute__((weak_import)); - -#endif