Skip to content

Commit 8795d99

Browse files
committed
Brightness: add DDC/CI support for Intel
Doesn't work for me. Need more testing
1 parent f8aafb7 commit 8795d99

File tree

3 files changed

+88
-21
lines changed

3 files changed

+88
-21
lines changed

src/detection/brightness/brightness_apple.c

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
11
#include "brightness.h"
22
#include "detection/displayserver/displayserver.h"
33
#include "util/apple/cf_helpers.h"
4-
#include "util/apple/ddcci.h"
54
#include "util/edidHelper.h"
65

6+
#include <CoreGraphics/CoreGraphics.h>
7+
8+
// DDC/CI
9+
#ifdef __aarch64__
10+
typedef CFTypeRef IOAVServiceRef;
11+
extern IOAVServiceRef IOAVServiceCreate(CFAllocatorRef allocator) __attribute__((weak_import));
12+
extern IOAVServiceRef IOAVServiceCreateWithService(CFAllocatorRef allocator, io_service_t service) __attribute__((weak_import));
13+
extern IOReturn IOAVServiceCopyEDID(IOAVServiceRef service, CFDataRef* x2) __attribute__((weak_import));
14+
extern IOReturn IOAVServiceReadI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t offset, void* outputBuffer, uint32_t outputBufferSize) __attribute__((weak_import));
15+
extern IOReturn IOAVServiceWriteI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t dataAddress, void* inputBuffer, uint32_t inputBufferSize) __attribute__((weak_import));
16+
#else
17+
// DDC/CI (Intel)
18+
#include <IOKit/IOKitLib.h>
19+
#include <IOKit/graphics/IOGraphicsLib.h>
20+
#include <IOKit/i2c/IOI2CInterface.h>
21+
extern void CGSServiceForDisplayNumber(CGDirectDisplayID display, io_service_t* service) __attribute__((weak_import));
22+
#endif
23+
24+
// ACPI
725
extern int DisplayServicesGetBrightness(CGDirectDisplayID display, float *brightness) __attribute__((weak_import));
826

927
// Works for internal display
@@ -31,9 +49,10 @@ static const char* detectWithDisplayServices(const FFDisplayServerResult* displa
3149
return NULL;
3250
}
3351

52+
#ifdef __aarch64__
3453
// https://github.com/waydabber/m1ddc
3554
// Works for Apple Silicon and USB-C adapter connection ( but not HTMI )
36-
FF_MAYBE_UNUSED static const char* detectWithDdcci(FFlist* result)
55+
static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult* displayServer, FFlist* result)
3756
{
3857
if (!IOAVServiceCreate || !IOAVServiceReadI2C)
3958
return "IOAVService is not available";
@@ -105,17 +124,80 @@ FF_MAYBE_UNUSED static const char* detectWithDdcci(FFlist* result)
105124

106125
return NULL;
107126
}
127+
#else
128+
static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFlist* result)
129+
{
130+
if (!CGSServiceForDisplayNumber) return "CGSServiceForDisplayNumber is not available";
131+
132+
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
133+
{
134+
if (display->type == FF_DISPLAY_TYPE_EXTERNAL)
135+
{
136+
io_service_t framebuffer = 0;
137+
CGSServiceForDisplayNumber((CGDirectDisplayID)display->id, &framebuffer);
138+
if (framebuffer == 0) continue;
139+
140+
IOItemCount count;
141+
if (IOFBGetI2CInterfaceCount(framebuffer, &count) != KERN_SUCCESS || count == 0) continue;
142+
143+
io_service_t interface = 0;
144+
if (IOFBCopyI2CInterfaceForBus(framebuffer, 0, &interface) != KERN_SUCCESS) continue;
145+
146+
uint8_t i2cOut[12] = {};
147+
IOI2CConnectRef connect;
148+
if (IOI2CInterfaceOpen(interface, kNilOptions, &connect) != KERN_SUCCESS)
149+
{
150+
IOObjectRelease(interface);
151+
continue;
152+
}
153+
154+
uint8_t i2cIn[] = { 0x51, 0x82, 0x01, 0x10 /* luminance */, 0 };
155+
i2cIn[4] = 0x6E ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2] ^ i2cIn[3];
156+
157+
IOI2CRequest request = {
158+
.commFlags = kNilOptions,
159+
.sendAddress = 0x6e,
160+
.sendTransactionType = kIOI2CSimpleTransactionType,
161+
.sendBuffer = (vm_address_t) i2cIn,
162+
.sendBytes = sizeof(i2cIn) / sizeof(i2cIn[0]),
163+
.minReplyDelay = 10,
164+
.replyAddress = 0x6F,
165+
.replySubAddress = 0x51,
166+
.replyTransactionType = kIOI2CDDCciReplyTransactionType,
167+
.replyBytes = sizeof(i2cOut) / sizeof(i2cOut[0]),
168+
.replyBuffer = (vm_address_t) i2cOut,
169+
};
170+
IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request);
171+
IOI2CInterfaceClose(connect, kNilOptions);
172+
IOObjectRelease(interface);
173+
174+
if (ret != KERN_SUCCESS || request.result != kIOReturnSuccess) continue;
175+
176+
if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) continue;
177+
178+
uint32_t current = ((uint32_t) i2cOut[8] << 8u) + (uint32_t) i2cOut[9];
179+
uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7];
180+
181+
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
182+
brightness->max = max;
183+
brightness->min = 0;
184+
brightness->current = current;
185+
ffStrbufInitCopy(&brightness->name, &display->name);
186+
}
187+
}
188+
189+
return NULL;
190+
}
191+
#endif
108192

109193
const char* ffDetectBrightness(FFlist* result)
110194
{
111195
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
112196

113197
detectWithDisplayServices(displayServer, result);
114198

115-
#ifdef __aarch64__
116199
if (displayServer->displays.length > result->length)
117-
detectWithDdcci(result);
118-
#endif
200+
detectWithDdcci(displayServer, result);
119201

120202
return NULL;
121203
}

src/detection/monitor/monitor_apple.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#include "monitor.h"
22
#include "detection/displayserver/displayserver.h"
33
#include "util/apple/cf_helpers.h"
4-
#include "util/apple/ddcci.h"
54
#include "util/edidHelper.h"
65

76
#import <AppKit/NSScreen.h>
87
#import <Foundation/Foundation.h>
8+
#import <CoreGraphics/CoreGraphics.h>
99

1010
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
1111

src/util/apple/ddcci.h

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)