Skip to content

Commit 665069d

Browse files
committed
Add support for Lenovo Legion K510 keyboard
1 parent bbf50ef commit 665069d

5 files changed

Lines changed: 595 additions & 0 deletions

File tree

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*---------------------------------------------------------*\
2+
| LenovoK510Controller.cpp |
3+
| |
4+
| Driver for Lenovo Legion K510 keyboard |
5+
| |
6+
| Bnyro 27 Oct 2025 |
7+
| |
8+
| This file is part of the OpenRGB project |
9+
| SPDX-License-Identifier: GPL-2.0-or-later |
10+
\*---------------------------------------------------------*/
11+
12+
#include <cstring>
13+
#include <vector>
14+
#include "LenovoK510Controller.h"
15+
16+
using namespace std;
17+
18+
LenovoK510Controller::LenovoK510Controller(hid_device* dev_handle, const hid_device_info& info, std::string dev_name)
19+
{
20+
device = dev_handle;
21+
location = info.path;
22+
name = dev_name;
23+
}
24+
25+
LenovoK510Controller::~LenovoK510Controller()
26+
{
27+
hid_close(device);
28+
}
29+
30+
std::string LenovoK510Controller::GetDeviceLocation()
31+
{
32+
return("HID: " + location);
33+
}
34+
35+
std::string LenovoK510Controller::GetDeviceName()
36+
{
37+
return(name);
38+
}
39+
40+
void LenovoK510Controller::SetMode(unsigned int color_mode, RGBColor color, unsigned char mode_value, unsigned int brigthness, unsigned int speed, unsigned int direction)
41+
{
42+
unsigned char usb_buf[K510_DATA_SIZE];
43+
memset(usb_buf, 0x00, K510_DATA_SIZE);
44+
usb_buf[0x00] = 0x04; // ReportID
45+
46+
// magic bytes to trigger an LED update
47+
usb_buf[0x03] = 0x06;
48+
usb_buf[0x04] = 0x38;
49+
50+
usb_buf[0x09] = mode_value;
51+
usb_buf[0x0A] = static_cast<unsigned char>(brigthness);
52+
// speed behaves contrary to normal expectations: the lower the value, the higher the speed
53+
usb_buf[0x0B] = static_cast<unsigned char>(speed);
54+
55+
if(direction == MODE_DIRECTION_UP || direction == MODE_DIRECTION_LEFT)
56+
{
57+
// 0x01 reverses the direction of the animation
58+
usb_buf[0x0C] = 0x01;
59+
}
60+
61+
if(color_mode == MODE_COLORS_MODE_SPECIFIC)
62+
{
63+
usb_buf[0x0D] = 0x00;
64+
usb_buf[0x0E] = static_cast<unsigned char>(RGBGetRValue(color));
65+
usb_buf[0x0F] = static_cast<unsigned char>(RGBGetGValue(color));
66+
usb_buf[0x10] = static_cast<unsigned char>(RGBGetBValue(color));
67+
}
68+
else
69+
{
70+
// sets color to automatic
71+
usb_buf[0x0D] = 0x01;
72+
}
73+
74+
hid_write(device, usb_buf, K510_DATA_SIZE);
75+
}
76+
77+
mode LenovoK510Controller::GetCurrentState()
78+
{
79+
unsigned char usb_buf[K510_DATA_SIZE];
80+
memset(usb_buf, 0x00, K510_DATA_SIZE);
81+
usb_buf[0x00] = 0x04; // ReportID
82+
83+
// magic bytes to get a response containing the current configuration
84+
usb_buf[0x03] = 0x05;
85+
usb_buf[0x04] = 0x38;
86+
87+
hid_write(device, usb_buf, K510_DATA_SIZE);
88+
89+
unsigned char res_buf[K510_DATA_SIZE];
90+
hid_read_timeout(device, res_buf, K510_DATA_SIZE, 50);
91+
92+
mode current_mode;
93+
current_mode.value = res_buf[0x09];
94+
current_mode.brightness = res_buf[0x0A];
95+
current_mode.speed = res_buf[0x0B];
96+
current_mode.direction = res_buf[0x0C];
97+
current_mode.color_mode = res_buf[0x0D] ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
98+
current_mode.colors.push_back(ToRGBColor(res_buf[0x0E], res_buf[0x0F], res_buf[0x10]));
99+
100+
return(current_mode);
101+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*---------------------------------------------------------*\
2+
| LenovoK510Controller.h |
3+
| |
4+
| Driver for Lenovo Legion K510 keyboard |
5+
| |
6+
| Bnyro 27 Oct 2025 |
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+
#include "RGBController.h"
17+
18+
#define K510_DATA_SIZE 64
19+
20+
#define K510_BRIGHTNESS_DEFAULT 2
21+
#define K510_BRIGHTNESS_MIN 0
22+
#define K510_BRIGHTNESS_MAX 2
23+
24+
// the lower the speed value, the faster the animation
25+
#define K510_SPEED_DEFAULT 2
26+
#define K510_SPEED_MIN 4
27+
#define K510_SPEED_MAX 0
28+
29+
enum
30+
{
31+
K510_MODE_CORRUGATED = 0x01,
32+
K510_MODE_CLOUD = 0x02,
33+
K510_MODE_SERPENTINE = 0x03,
34+
K510_MODE_SPECTRUM = 0x04,
35+
K510_MODE_BREATH = 0x05,
36+
K510_MODE_NORMAL = 0x06,
37+
K510_MODE_REACTION = 0x07,
38+
K510_MODE_RIPPLES = 0x08,
39+
K510_MODE_TRAVERSE = 0x09,
40+
K510_MODE_STARS = 0x0A,
41+
K510_MODE_FLOWERS = 0x0B,
42+
K510_MODE_ROLL = 0x0C,
43+
K510_MODE_WAVE = 0x0D,
44+
K510_MODE_CARTOON = 0x0E,
45+
K510_MODE_RAIN = 0x0F,
46+
K510_MODE_SCAN = 0x10,
47+
K510_MODE_SURMOUNT = 0x11,
48+
K510_MODE_SPEED = 0x12,
49+
};
50+
51+
class LenovoK510Controller
52+
{
53+
public:
54+
LenovoK510Controller(hid_device* dev_handle, const hid_device_info& info, std::string dev_name);
55+
~LenovoK510Controller();
56+
57+
std::string GetDeviceLocation();
58+
std::string GetDeviceName();
59+
60+
void SetMode(unsigned int color_mode, RGBColor color, unsigned char mode_value, unsigned int brightness, unsigned int speed, unsigned int direction);
61+
mode GetCurrentState();
62+
;
63+
64+
private:
65+
hid_device* device;
66+
std::string location;
67+
std::string name;
68+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*---------------------------------------------------------*\
2+
| LenovoK510ControllerDetect.cpp |
3+
| |
4+
| Detector for Lenovo Legion K510 keyboard |
5+
| |
6+
| Bnyro 27 Oct 2025 |
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 "RGBController_LenovoK510.h"
14+
#include "LenovoK510Controller.h"
15+
16+
/*---------------------------------------------------------*\
17+
| Lenovo vendor, product, usage and page IDs |
18+
\*---------------------------------------------------------*/
19+
#define LENOVO_VID 0x17EF
20+
#define LEGION_K510_PID 0x619A
21+
#define LENOVO_IFACE_NUM 0x01
22+
#define LENOVO_PAGE 0xFF1C
23+
#define LENOVO_USAGE 0x0092
24+
25+
void DetectLenovoLegionK510Controllers(hid_device_info* info, const std::string& name)
26+
{
27+
hid_device* dev = hid_open_path(info->path);
28+
29+
if(dev)
30+
{
31+
LenovoK510Controller* controller = new LenovoK510Controller(dev, *info, name);
32+
RGBController_LenovoK510* rgb_controller = new RGBController_LenovoK510(controller);
33+
34+
ResourceManager::get()->RegisterRGBController(rgb_controller);
35+
}
36+
}
37+
38+
REGISTER_HID_DETECTOR_IPU("Lenovo Legion K510 Mini Pro", DetectLenovoLegionK510Controllers, LENOVO_VID, LEGION_K510_PID, LENOVO_IFACE_NUM, LENOVO_PAGE, LENOVO_USAGE);

0 commit comments

Comments
 (0)