Skip to content

Commit ea0afec

Browse files
authored
Merge branch 'CalcProgrammer1:master' into master
2 parents 7f970c4 + 476f81d commit ea0afec

62 files changed

Lines changed: 4155 additions & 104 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*---------------------------------------------------------*\
2+
| ClevoKeyboardController.cpp |
3+
| |
4+
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
5+
| Protocol based on tuxedo-drivers ite_8291 module |
6+
| |
7+
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
8+
| |
9+
| This file is part of the OpenRGB project |
10+
| SPDX-License-Identifier: GPL-2.0-or-later |
11+
\*---------------------------------------------------------*/
12+
13+
#include "ClevoKeyboardController.h"
14+
#include <cstring>
15+
16+
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info)
17+
{
18+
dev = dev_handle;
19+
location = info.path;
20+
version = info.release_number;
21+
}
22+
23+
ClevoKeyboardController::~ClevoKeyboardController()
24+
{
25+
hid_close(dev);
26+
}
27+
28+
std::string ClevoKeyboardController::GetDeviceLocation()
29+
{
30+
return("HID: " + location);
31+
}
32+
33+
std::string ClevoKeyboardController::GetSerialString()
34+
{
35+
wchar_t serial_string[128];
36+
int ret = hid_get_serial_number_string(dev, serial_string, 128);
37+
38+
if(ret != 0)
39+
{
40+
return("");
41+
}
42+
43+
std::wstring return_wstring = serial_string;
44+
std::string return_string(return_wstring.begin(), return_wstring.end());
45+
46+
return(return_string);
47+
}
48+
49+
std::string ClevoKeyboardController::GetFirmwareVersion()
50+
{
51+
char version_string[16];
52+
snprintf(version_string, sizeof(version_string), "%d.%02d", version >> 8, version & 0xFF);
53+
return(version_string);
54+
}
55+
56+
void ClevoKeyboardController::WriteControl(unsigned char* data)
57+
{
58+
hid_send_feature_report(dev, data, CLEVO_KEYBOARD_REPORT_SIZE);
59+
}
60+
61+
void ClevoKeyboardController::WriteRowData(unsigned char* data)
62+
{
63+
hid_write(dev, data, CLEVO_KEYBOARD_ROW_DATA_SIZE);
64+
}
65+
66+
void ClevoKeyboardController::TurnOff()
67+
{
68+
/*---------------------------------------------------------*\
69+
| Turn off: 08 01 00 00 00 00 00 00 |
70+
\*---------------------------------------------------------*/
71+
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
72+
73+
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
74+
buf[0] = 0x08;
75+
buf[1] = 0x01;
76+
77+
WriteControl(buf);
78+
}
79+
80+
void ClevoKeyboardController::SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char behaviour)
81+
{
82+
/*---------------------------------------------------------*\
83+
| Set params: 08 [power] [mode] [speed] [brightness] 08 |
84+
| [behaviour] 00 |
85+
| power: 01=off, 02=on |
86+
\*---------------------------------------------------------*/
87+
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
88+
89+
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
90+
buf[0] = 0x08;
91+
buf[1] = 0x02; // Power on
92+
buf[2] = mode;
93+
buf[3] = speed;
94+
buf[4] = brightness;
95+
buf[5] = 0x08;
96+
buf[6] = behaviour;
97+
98+
WriteControl(buf);
99+
}
100+
101+
void ClevoKeyboardController::SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue)
102+
{
103+
/*---------------------------------------------------------*\
104+
| Set color define: 14 00 [index] R G B 00 00 |
105+
| index: 1-7 for built-in effects |
106+
\*---------------------------------------------------------*/
107+
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
108+
109+
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
110+
buf[0] = 0x14;
111+
buf[1] = 0x00;
112+
buf[2] = color_idx;
113+
buf[3] = red;
114+
buf[4] = green;
115+
buf[5] = blue;
116+
117+
WriteControl(buf);
118+
}
119+
120+
void ClevoKeyboardController::SendColors(unsigned char* color_data, unsigned char brightness)
121+
{
122+
/*---------------------------------------------------------*\
123+
| Per-key RGB mode (mode 0x33) |
124+
| 1. Set params with mode 0x33 and brightness |
125+
| 2. For each row 0-5: |
126+
| - Announce row: 16 00 [row] 00 00 00 00 00 |
127+
| - Send 65 bytes row data via output report |
128+
| |
129+
| Row data format (65 bytes): |
130+
| [0x00 padding][0x00 padding] |
131+
| [B0..B20][G0..G20][R0..R20] |
132+
\*---------------------------------------------------------*/
133+
unsigned char ctrl_buf[CLEVO_KEYBOARD_REPORT_SIZE];
134+
unsigned char row_buf[CLEVO_KEYBOARD_ROW_DATA_SIZE];
135+
136+
/*---------------------------------------------------------*\
137+
| Clamp brightness |
138+
\*---------------------------------------------------------*/
139+
if(brightness > CLEVO_KEYBOARD_BRIGHTNESS_MAX)
140+
{
141+
brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
142+
}
143+
144+
/*---------------------------------------------------------*\
145+
| Set params for per-key mode |
146+
\*---------------------------------------------------------*/
147+
memset(ctrl_buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
148+
ctrl_buf[0] = 0x08;
149+
ctrl_buf[1] = 0x02; // Power on
150+
ctrl_buf[2] = CLEVO_KEYBOARD_MODE_DIRECT; // Per-key mode
151+
ctrl_buf[3] = 0x00; // Speed (unused)
152+
ctrl_buf[4] = brightness;
153+
ctrl_buf[5] = 0x00;
154+
ctrl_buf[6] = 0x00;
155+
156+
WriteControl(ctrl_buf);
157+
158+
/*---------------------------------------------------------*\
159+
| Send each row |
160+
\*---------------------------------------------------------*/
161+
for(int row = 0; row < CLEVO_KEYBOARD_NUM_ROWS; row++)
162+
{
163+
/*-----------------------------------------------------*\
164+
| Announce row data |
165+
\*-----------------------------------------------------*/
166+
memset(ctrl_buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
167+
ctrl_buf[0] = 0x16;
168+
ctrl_buf[1] = 0x00;
169+
ctrl_buf[2] = row;
170+
171+
WriteControl(ctrl_buf);
172+
173+
/*-----------------------------------------------------*\
174+
| Build row data buffer |
175+
| Format: [pad][pad][B0..B20][G0..G20][R0..R20] |
176+
\*-----------------------------------------------------*/
177+
memset(row_buf, 0x00, CLEVO_KEYBOARD_ROW_DATA_SIZE);
178+
179+
for(int col = 0; col < CLEVO_KEYBOARD_NUM_COLS; col++)
180+
{
181+
int led_idx = (row * CLEVO_KEYBOARD_NUM_COLS) + col;
182+
int color_offset = led_idx * 3;
183+
184+
unsigned char red = color_data[color_offset + 0];
185+
unsigned char green = color_data[color_offset + 1];
186+
unsigned char blue = color_data[color_offset + 2];
187+
188+
/*-------------------------------------------------*\
189+
| Row data layout (after 2-byte padding): |
190+
| Bytes 2-22: Blue values for columns 0-20 |
191+
| Bytes 23-43: Green values for columns 0-20 |
192+
| Bytes 44-64: Red values for columns 0-20 |
193+
\*-------------------------------------------------*/
194+
row_buf[2 + col] = blue;
195+
row_buf[2 + CLEVO_KEYBOARD_NUM_COLS + col] = green;
196+
row_buf[2 + CLEVO_KEYBOARD_NUM_COLS*2 + col] = red;
197+
}
198+
199+
WriteRowData(row_buf);
200+
}
201+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*---------------------------------------------------------*\
2+
| ClevoKeyboardController.h |
3+
| |
4+
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
5+
| |
6+
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
7+
| |
8+
| This file is part of the OpenRGB project |
9+
| SPDX-License-Identifier: GPL-2.0-or-later |
10+
\*---------------------------------------------------------*/
11+
12+
#pragma once
13+
14+
#include <string>
15+
#include <hidapi.h>
16+
17+
/*-----------------------------------------------------*\
18+
| ITE 8291 keyboard defines |
19+
\*-----------------------------------------------------*/
20+
#define CLEVO_KEYBOARD_REPORT_SIZE 8
21+
#define CLEVO_KEYBOARD_ROW_DATA_SIZE 65
22+
23+
#define CLEVO_KEYBOARD_NUM_ROWS 6
24+
#define CLEVO_KEYBOARD_NUM_COLS 21
25+
#define CLEVO_KEYBOARD_NUM_LEDS (CLEVO_KEYBOARD_NUM_ROWS * CLEVO_KEYBOARD_NUM_COLS)
26+
27+
#define CLEVO_KEYBOARD_BRIGHTNESS_MIN 0x00
28+
#define CLEVO_KEYBOARD_BRIGHTNESS_MAX 0x32
29+
30+
#define CLEVO_KEYBOARD_SPEED_MIN 0x01
31+
#define CLEVO_KEYBOARD_SPEED_MAX 0x0A
32+
33+
/*-----------------------------------------------------*\
34+
| ITE 8291 modes |
35+
\*-----------------------------------------------------*/
36+
enum
37+
{
38+
CLEVO_KEYBOARD_MODE_DIRECT = 0x33,
39+
CLEVO_KEYBOARD_MODE_BREATH = 0x02,
40+
CLEVO_KEYBOARD_MODE_WAVE = 0x03,
41+
CLEVO_KEYBOARD_MODE_REACTIVE = 0x04,
42+
CLEVO_KEYBOARD_MODE_RAINBOW = 0x05,
43+
CLEVO_KEYBOARD_MODE_RIPPLE = 0x06,
44+
CLEVO_KEYBOARD_MODE_MARQUEE = 0x09,
45+
CLEVO_KEYBOARD_MODE_RAINDROP = 0x0A,
46+
CLEVO_KEYBOARD_MODE_AURORA = 0x0E,
47+
CLEVO_KEYBOARD_MODE_SPARK = 0x11,
48+
};
49+
50+
/*-----------------------------------------------------*\
51+
| Wave/reactive behaviour |
52+
\*-----------------------------------------------------*/
53+
enum
54+
{
55+
CLEVO_KEYBOARD_DIRECTION_LEFT = 0x01,
56+
CLEVO_KEYBOARD_DIRECTION_RIGHT = 0x02,
57+
CLEVO_KEYBOARD_DIRECTION_UP = 0x03,
58+
CLEVO_KEYBOARD_DIRECTION_DOWN = 0x04,
59+
};
60+
61+
enum
62+
{
63+
CLEVO_KEYBOARD_REACTIVE_KEYPRESS = 0x00,
64+
CLEVO_KEYBOARD_REACTIVE_AUTO = 0x01,
65+
};
66+
67+
class ClevoKeyboardController
68+
{
69+
public:
70+
ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info);
71+
~ClevoKeyboardController();
72+
73+
std::string GetDeviceLocation();
74+
std::string GetSerialString();
75+
std::string GetFirmwareVersion();
76+
77+
void TurnOff();
78+
void SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char behaviour);
79+
void SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue);
80+
void SendColors(unsigned char* color_data, unsigned char brightness);
81+
82+
private:
83+
hid_device* dev;
84+
std::string location;
85+
unsigned short version;
86+
87+
void WriteControl(unsigned char* data);
88+
void WriteRowData(unsigned char* data);
89+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*---------------------------------------------------------*\
2+
| ClevoKeyboardControllerDetect.cpp |
3+
| |
4+
| Detector for Clevo per-key RGB keyboard (ITE 8291) |
5+
| |
6+
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
7+
| |
8+
| This file is part of the OpenRGB project |
9+
| SPDX-License-Identifier: GPL-2.0-or-later |
10+
\*---------------------------------------------------------*/
11+
12+
#include "Detector.h"
13+
#include "ClevoKeyboardController.h"
14+
#include "RGBController_ClevoKeyboard.h"
15+
#include "RGBController.h"
16+
#include <hidapi.h>
17+
18+
/*-----------------------------------------------------*\
19+
| ITE Tech vendor ID |
20+
\*-----------------------------------------------------*/
21+
#define ITE_VID 0x048D
22+
23+
/*-----------------------------------------------------*\
24+
| Clevo Keyboard product IDs |
25+
| These are ITE 8291 per-key RGB keyboard controllers |
26+
\*-----------------------------------------------------*/
27+
#define CLEVO_KEYBOARD_PID_600B 0x600B
28+
29+
void DetectClevoKeyboardControllers(hid_device_info* info, const std::string& name)
30+
{
31+
hid_device* dev = hid_open_path(info->path);
32+
33+
if(dev)
34+
{
35+
ClevoKeyboardController* controller = new ClevoKeyboardController(dev, *info);
36+
RGBController_ClevoKeyboard* rgb_controller = new RGBController_ClevoKeyboard(controller);
37+
rgb_controller->name = name;
38+
39+
ResourceManager::get()->RegisterRGBController(rgb_controller);
40+
}
41+
}
42+
43+
REGISTER_HID_DETECTOR_PU("Clevo Keyboard", DetectClevoKeyboardControllers, 0x048D, 0x600B, 0xFF03, 0x01);

0 commit comments

Comments
 (0)