Skip to content

Commit 24459b2

Browse files
committed
Brightness (macOS): enhance DDC/CI detection by enumerating all I2C buses
1 parent 88c8dcb commit 24459b2

File tree

1 file changed

+52
-41
lines changed

1 file changed

+52
-41
lines changed

src/detection/brightness/brightness_apple.c

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static const char* detectWithDisplayServices(const FFDisplayServerResult* displa
5555
// Works for Apple Silicon and USB-C adapter connection ( but not HTMI )
5656
static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult* displayServer, FFBrightnessOptions* options, FFlist* result)
5757
{
58-
if (!IOAVServiceCreate || !IOAVServiceReadI2C)
58+
if (!IOAVServiceCreate || !IOAVServiceReadI2C || !IOAVServiceWriteI2C)
5959
return "IOAVService is not available";
6060

6161
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = IO_OBJECT_NULL;
@@ -136,52 +136,63 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
136136
if (framebuffer == 0) continue;
137137

138138
IOItemCount count;
139-
if (IOFBGetI2CInterfaceCount(framebuffer, &count) != KERN_SUCCESS || count == 0) continue;
140-
141-
io_service_t interface = 0;
142-
if (IOFBCopyI2CInterfaceForBus(framebuffer, 0, &interface) != KERN_SUCCESS) continue;
143-
144-
uint8_t i2cOut[12] = {};
145-
IOI2CConnectRef connect;
146-
if (IOI2CInterfaceOpen(interface, kNilOptions, &connect) != KERN_SUCCESS)
139+
if (IOFBGetI2CInterfaceCount(framebuffer, &count) != KERN_SUCCESS || count == 0)
147140
{
148-
IOObjectRelease(interface);
141+
IOObjectRelease(framebuffer);
149142
continue;
150143
}
151144

152-
uint8_t i2cIn[] = { 0x51, 0x82, 0x01, 0x10 /* luminance */, 0 };
153-
i2cIn[4] = 0x6E ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2] ^ i2cIn[3];
154-
155-
IOI2CRequest request = {
156-
.commFlags = kNilOptions,
157-
.sendAddress = 0x6e,
158-
.sendTransactionType = kIOI2CSimpleTransactionType,
159-
.sendBuffer = (vm_address_t) i2cIn,
160-
.sendBytes = ARRAY_SIZE(i2cIn),
161-
.minReplyDelay = options->ddcciSleep,
162-
.replyAddress = 0x6F,
163-
.replySubAddress = 0x51,
164-
.replyTransactionType = kIOI2CDDCciReplyTransactionType,
165-
.replyBytes = ARRAY_SIZE(i2cOut),
166-
.replyBuffer = (vm_address_t) i2cOut,
167-
};
168-
IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request);
169-
IOI2CInterfaceClose(connect, kNilOptions);
170-
IOObjectRelease(interface);
171-
172-
if (ret != KERN_SUCCESS || request.result != kIOReturnSuccess) continue;
173-
174-
if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) continue;
145+
bool found = false;
146+
for (IOItemCount bus = 0; bus < count && !found; ++bus)
147+
{
148+
io_service_t interface = 0;
149+
if (IOFBCopyI2CInterfaceForBus(framebuffer, 0, &interface) != KERN_SUCCESS) continue;
150+
151+
uint8_t i2cOut[12] = {};
152+
IOI2CConnectRef connect;
153+
if (IOI2CInterfaceOpen(interface, kNilOptions, &connect) != KERN_SUCCESS)
154+
{
155+
IOObjectRelease(interface);
156+
continue;
157+
}
158+
159+
uint8_t i2cIn[] = { 0x51, 0x82, 0x01, 0x10 /* luminance */, 0 };
160+
i2cIn[4] = 0x6E ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2] ^ i2cIn[3];
161+
162+
IOI2CRequest request = {
163+
.commFlags = kNilOptions,
164+
.sendAddress = 0x6e,
165+
.sendTransactionType = kIOI2CSimpleTransactionType,
166+
.sendBuffer = (vm_address_t) i2cIn,
167+
.sendBytes = ARRAY_SIZE(i2cIn),
168+
.minReplyDelay = options->ddcciSleep * 1000ULL,
169+
.replyAddress = 0x6F,
170+
.replySubAddress = 0x51,
171+
.replyTransactionType = kIOI2CDDCciReplyTransactionType,
172+
.replyBytes = ARRAY_SIZE(i2cOut),
173+
.replyBuffer = (vm_address_t) i2cOut,
174+
};
175+
IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request);
176+
IOI2CInterfaceClose(connect, kNilOptions);
177+
IOObjectRelease(interface);
175178

176-
uint32_t current = ((uint32_t) i2cOut[8] << 8u) + (uint32_t) i2cOut[9];
177-
uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7];
179+
if (ret != KERN_SUCCESS || request.result != kIOReturnSuccess || request.replyBytes < 10) continue;
180+
if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) continue;
178181

179-
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
180-
brightness->max = max;
181-
brightness->min = 0;
182-
brightness->current = current;
183-
ffStrbufInitCopy(&brightness->name, &display->name);
184-
brightness->builtin = false;
182+
uint32_t current = ((uint32_t) i2cOut[8] << 8u) + (uint32_t) i2cOut[9];
183+
uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7];
184+
185+
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
186+
brightness->max = max;
187+
brightness->min = 0;
188+
brightness->current = current;
189+
ffStrbufInitCopy(&brightness->name, &display->name);
190+
brightness->builtin = false;
191+
192+
found = true;
193+
}
194+
195+
IOObjectRelease(framebuffer);
185196
}
186197
}
187198

0 commit comments

Comments
 (0)