Skip to content

Instantly share code, notes, and snippets.

@alin23
Created July 2, 2021 06:21
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alin23/531151c49e013554e6ca2186cef3fa90 to your computer and use it in GitHub Desktop.
Save alin23/531151c49e013554e6ca2186cef3fa90 to your computer and use it in GitHub Desktop.
@import Darwin;
@import Foundation;
@import IOKit;
// clang -fmodules -o i2cwrite i2cwrite.m && ./i2cwrite
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 root?");
return 1;
}
IOReturn err;
UInt8 data[256];
memset(data, 0, sizeof(data));
// MARK: Write BRIGHTNESS
struct DDCWriteCommand command;
command.control_id = BRIGHTNESS;
command.new_value = 70;
NSLog(@"\nSetting BRIGHTNESS to %d", command.new_value);
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];
for (int i = 0; i < 3; ++i)
{
err = IOAVServiceWriteI2C(avService, 0x37, 0x51, data, 6);
if (err) {
NSLog(@"i2c error: %s", mach_error_string(err));
}
usleep(50000);
}
NSData *nsdata = [NSData dataWithBytes:(const void *)data length:(NSUInteger)6];
NSLog(@"Written to i2c: %@", nsdata);
// MARK: Read BRIGHTNESS
data[0] = 0x82;
data[1] = 0x01;
data[2] = BRIGHTNESS;
data[3] = 0x6e ^ data[0] ^ data[1] ^ data[2] ^ data[3];
char i2cBytes[12];
memset(i2cBytes, 0, sizeof(i2cBytes));
NSData *sendingData = [NSData dataWithBytes:(const void *)data length:(NSUInteger)4];
NSLog(@"sending: %@", sendingData);
usleep(50000);
err = IOAVServiceWriteI2C(avService, 0x37, 0x51, data, 4);
if (err) {
NSLog(@"i2c error: %s", mach_error_string(err));
return 1;
}
usleep(50000);
err = IOAVServiceReadI2C(avService, 0x37, 0x51, i2cBytes, 12);
if (err) {
NSLog(@"i2c error: %s", mach_error_string(err));
} else {
NSData *readData = [NSData dataWithBytes:(const void *)i2cBytes length:(NSUInteger)11];
NSLog(@"readbuf: %@", readData);
NSRange maxValueRange = {7, 1};
NSRange currentValueRange = {9, 1};
char maxValue, currentValue;
[[readData subdataWithRange:maxValueRange] getBytes:&maxValue length:sizeof(1)];
[[readData subdataWithRange:currentValueRange] getBytes:&currentValue length:sizeof(1)];
NSLog(@"\nMAX: %d\nCURRENT: %d", maxValue, currentValue);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment