@@ -123,38 +123,70 @@ static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult*
123123 return NULL ;
124124}
125125#else
126+ static IOOptionBits getSupportedTransactionType (void ) {
127+ FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = IO_OBJECT_NULL ;
128+
129+ if (IOServiceGetMatchingServices (MACH_PORT_NULL , IOServiceNameMatching ("IOFramebufferI2CInterface" ), & iterator ) != KERN_SUCCESS )
130+ return 0 ;
131+
132+ io_registry_entry_t registryEntry ;
133+ while ((registryEntry = IOIteratorNext (iterator )) != MACH_PORT_NULL )
134+ {
135+ FF_IOOBJECT_AUTO_RELEASE io_service_t io_service = registryEntry ;
136+ FF_CFTYPE_AUTO_RELEASE CFNumberRef IOI2CTransactionTypes = IORegistryEntryCreateCFProperty (io_service , CFSTR (kIOI2CTransactionTypesKey ), kCFAllocatorDefault , kNilOptions );
137+
138+ if (IOI2CTransactionTypes )
139+ {
140+ int64_t types = 0 ;
141+ ffCfNumGetInt64 (IOI2CTransactionTypes , & types );
142+
143+ /*
144+ We want DDCciReply but Simple is better than No-thing.
145+ Combined and DisplayPortNative are not useful in our case.
146+ */
147+ if (types ) {
148+ if ((1 << kIOI2CSimpleTransactionType ) & (uint64_t ) types )
149+ return kIOI2CSimpleTransactionType ;
150+ if ((1 << kIOI2CDDCciReplyTransactionType ) & (uint64_t ) types )
151+ return kIOI2CDDCciReplyTransactionType ;
152+ if ((1 << kIOI2CCombinedTransactionType ) & (uint64_t ) types )
153+ return kIOI2CCombinedTransactionType ;
154+ if ((1 << kIOI2CDisplayPortNativeTransactionType ) & (uint64_t ) types )
155+ return kIOI2CDisplayPortNativeTransactionType ;
156+ }
157+ }
158+ break ;
159+ }
160+
161+ return 0 ;
162+ }
163+
126164static const char * detectWithDdcci (const FFDisplayServerResult * displayServer , FFBrightnessOptions * options , FFlist * result )
127165{
128166 if (!CGSServiceForDisplayNumber ) return "CGSServiceForDisplayNumber is not available" ;
167+ IOOptionBits transactionType = getSupportedTransactionType ();
129168
130169 FF_LIST_FOR_EACH (FFDisplayResult , display , displayServer -> displays )
131170 {
132171 if (display -> type == FF_DISPLAY_TYPE_EXTERNAL )
133172 {
134- io_service_t framebuffer = 0 ;
173+ FF_IOOBJECT_AUTO_RELEASE io_service_t framebuffer = IO_OBJECT_NULL ;
135174 CGSServiceForDisplayNumber ((CGDirectDisplayID )display -> id , & framebuffer );
136- if (framebuffer == 0 ) continue ;
175+ if (framebuffer == IO_OBJECT_NULL ) continue ;
137176
138177 IOItemCount count ;
139178 if (IOFBGetI2CInterfaceCount (framebuffer , & count ) != KERN_SUCCESS || count == 0 )
140- {
141- IOObjectRelease (framebuffer );
142179 continue ;
143- }
144180
145- bool found = false;
146- for (IOItemCount bus = 0 ; bus < count && !found ; ++ bus )
181+ for (IOItemCount bus = 0 ; bus < count ; ++ bus )
147182 {
148- io_service_t interface = 0 ;
149- if (IOFBCopyI2CInterfaceForBus (framebuffer , 0 , & interface ) != KERN_SUCCESS ) continue ;
183+ FF_IOOBJECT_AUTO_RELEASE io_service_t interface = IO_OBJECT_NULL ;
184+ if (IOFBCopyI2CInterfaceForBus (framebuffer , bus , & interface ) != KERN_SUCCESS ) continue ;
150185
151186 uint8_t i2cOut [12 ] = {};
152- IOI2CConnectRef connect ;
187+ IOI2CConnectRef connect = NULL ;
153188 if (IOI2CInterfaceOpen (interface , kNilOptions , & connect ) != KERN_SUCCESS )
154- {
155- IOObjectRelease (interface );
156189 continue ;
157- }
158190
159191 uint8_t i2cIn [] = { 0x51 , 0x82 , 0x01 , 0x10 /* luminance */ , 0 };
160192 i2cIn [4 ] = 0x6E ^ i2cIn [0 ] ^ i2cIn [1 ] ^ i2cIn [2 ] ^ i2cIn [3 ];
@@ -168,13 +200,12 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
168200 .minReplyDelay = options -> ddcciSleep * 1000ULL ,
169201 .replyAddress = 0x6F ,
170202 .replySubAddress = 0x51 ,
171- .replyTransactionType = kIOI2CDDCciReplyTransactionType ,
203+ .replyTransactionType = transactionType ,
172204 .replyBytes = ARRAY_SIZE (i2cOut ),
173205 .replyBuffer = (vm_address_t ) i2cOut ,
174206 };
175207 IOReturn ret = IOI2CSendRequest (connect , kNilOptions , & request );
176208 IOI2CInterfaceClose (connect , kNilOptions );
177- IOObjectRelease (interface );
178209
179210 if (ret != KERN_SUCCESS || request .result != kIOReturnSuccess || request .replyBytes < 10 ) continue ;
180211 if (i2cOut [2 ] != 0x02 || i2cOut [3 ] != 0x00 ) continue ;
@@ -189,10 +220,8 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
189220 ffStrbufInitCopy (& brightness -> name , & display -> name );
190221 brightness -> builtin = false;
191222
192- found = true ;
223+ break ;
193224 }
194-
195- IOObjectRelease (framebuffer );
196225 }
197226 }
198227
0 commit comments