ohmu
·
2026-10-15
1#pragma once
2
3#include "fastfetch.h"
4#include "modules/brightness/option.h"
5
6typedef struct FFBrightnessResult {
7 FFstrbuf name;
8 double min, max, current;
9 bool builtin;
10} FFBrightnessResult;
11
12enum {
13 FF_DDC_EDID_ADDR = 0x50u,
14 FF_DDC_EDID_WRITE_ADDR = FF_DDC_EDID_ADDR << 1,
15 FF_DDC_CI_ADDR = 0x37u,
16 FF_DDC_CI_WRITE_ADDR = FF_DDC_CI_ADDR << 1,
17 FF_DDC_CI_READ_ADDR = FF_DDC_CI_WRITE_ADDR | 1,
18 FF_DDC_CI_VCP_COMMAND = 0x51u,
19 FF_DDC_CI_GET_VCP = 0x01u,
20 FF_DDC_CI_SET_VCP = 0x03u,
21 FF_DDC_CI_COMMAND_PACKET = 0x80u,
22 FF_DDC_CI_LUMINANCE_OPCODE = 0x10u,
23 FF_DDC_CI_VCP_RESPONSE_LENGTH = 8u,
24 FF_DDC_CI_VCP_RESPONSE_PACKET_SIZE = 11u,
25 FF_DDC_CI_VCP_RESPONSE_BUFFER_SIZE = 12u,
26 FF_DDC_CI_RESPONSE_CHECKSUM_ADDR = 0x50u,
27};
28#define FF_BRIGHTNESS_DDCCI_SLEEP_SKIP ((uint32_t) -1)
29#define FF_DDC_CI_MAKE_HEADER(len) (FF_DDC_CI_COMMAND_PACKET | ((len) & 0x7F))
30
31static inline uint8_t ffDdcCiChecksum(uint8_t address, const uint8_t* data, size_t length) {
32 uint8_t checksum = address;
33 for (size_t i = 0; i < length; ++i) {
34 checksum ^= data[i];
35 }
36 return checksum;
37}
38
39static inline void ffDdcCiBuildGetVcpRequest(uint8_t request[5]) {
40 request[0] = FF_DDC_CI_VCP_COMMAND;
41 request[1] = FF_DDC_CI_MAKE_HEADER(2);
42 request[2] = FF_DDC_CI_GET_VCP;
43 request[3] = FF_DDC_CI_LUMINANCE_OPCODE;
44 request[4] = ffDdcCiChecksum(FF_DDC_CI_WRITE_ADDR, request, 4);
45}
46
47static inline bool ffDdcCiValidateGetVcpResponse(const uint8_t response[FF_DDC_CI_VCP_RESPONSE_BUFFER_SIZE]) {
48 if (response[0] != FF_DDC_CI_WRITE_ADDR
49 || response[1] != FF_DDC_CI_MAKE_HEADER(FF_DDC_CI_VCP_RESPONSE_LENGTH)
50 || response[2] != 0x02u
51 || response[3] != 0x00u
52 || response[4] != FF_DDC_CI_LUMINANCE_OPCODE
53 || response[5] != 0x00u) {
54 return false;
55 }
56
57 return ffDdcCiChecksum(FF_DDC_CI_RESPONSE_CHECKSUM_ADDR, response, FF_DDC_CI_VCP_RESPONSE_PACKET_SIZE - 1u) == response[FF_DDC_CI_VCP_RESPONSE_PACKET_SIZE - 1u];
58}
59
60#define FF_I2C_DEVICE_CACHE_MAX 32
61
62typedef struct FFBrightnessDdcCache {
63 int devices[FF_I2C_DEVICE_CACHE_MAX];
64 size_t count;
65} FFBrightnessDdcCache;
66
67static inline FFstrbuf ffBrightnessDdcCachePath(void) {
68 FFstrbuf path = ffStrbufCreateCopy(&instance.state.platform.cacheDir);
69 ffStrbufEnsureEndsWithC(&path, '/');
70 ffStrbufAppendS(&path, "fastfetch/brightness/i2c_cache.txt");
71 return path;
72}
73
74const char* ffDetectBrightness(FFBrightnessOptions* options, FFlist* result); // list of FFBrightnessResult