@import Darwin; @import Foundation; @import IOKit; // clang -fmodules -o brt brt.m && ./brt typedef CFTypeRef IOAVServiceRef; extern IOAVServiceRef IOAVServiceCreate(CFAllocatorRef allocator); extern IOReturn IOAVServiceCopyEDID(IOAVServiceRef service, CFDataRef* x2); // outputBufferSize must be less than (1 << 12) (4096 bytes) extern IOReturn IOAVServiceReadI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t offset, void* outputBuffer, uint32_t outputBufferSize); // This didn't work for me (returned no error, but EDID not written) extern IOReturn IOAVServiceWriteI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t dataAddress, void* inputBuffer, uint32_t inputBufferSize); #define BRIGHTNESS 0x10 #define CONTRAST 0x12 #define AUDIO_SPEAKER_VOLUME 0x62 #define AUDIO_MUTE 0x8D struct DDCWriteCommand { UInt8 control_id; UInt8 new_value; }; int main(int argc, char** argv) { IOAVServiceRef avService = IOAVServiceCreate(kCFAllocatorDefault); if (!avService) { NSLog(@"Can't open IOAVService: do you have an external monitor? Are you on M1?"); return 1; } char data[16]; struct DDCWriteCommand command; command.control_id = BRIGHTNESS; if (argc == 2) { command.new_value = atoi(argv[1]); } else { command.new_value = 1; } data[0] = 0x84; data[1] = 0x03; data[2] = command.control_id; data[3] = (command.new_value) >> 8; data[4] = command.new_value & 255; data[5] = 0x6E ^ 0x51 ^ data[0] ^ data[1] ^ data[2] ^ data[3] ^ data[4]; IOReturn err = IOAVServiceWriteI2C(avService, 0x37, 0x51, data, 6); return err; }