Skip to content

Commit 6d9e4a8

Browse files
Алексей КуликовCalcProgrammer1
authored andcommitted
Add support RGB keyboard for Lenovo IdeaPad3
1 parent c010242 commit 6d9e4a8

File tree

7 files changed

+503
-0
lines changed

7 files changed

+503
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*-------------------------------------------------------------------*\
2+
| Lenovo4ZoneUSBController.cpp |
3+
| |
4+
| interface for Lenovo 4-Zones Devices |
5+
\*-------------------------------------------------------------------*/
6+
7+
#include <iostream>
8+
#include "Lenovo4ZoneUSBController.h"
9+
#include "LogManager.h"
10+
11+
Lenovo4ZoneUSBController::Lenovo4ZoneUSBController(hid_device* dev_handle, const char* path, uint16_t in_pid)
12+
{
13+
const uint8_t sz = HID_MAX_STR;
14+
wchar_t tmp[sz];
15+
16+
dev = dev_handle;
17+
location = path;
18+
pid = in_pid;
19+
20+
hid_get_manufacturer_string(dev, tmp, sz);
21+
std::wstring w_tmp = std::wstring(tmp);
22+
name = std::string(w_tmp.begin(), w_tmp.end());
23+
24+
hid_get_product_string(dev, tmp, sz);
25+
w_tmp = std::wstring(tmp);
26+
name.append(" ").append(std::string(w_tmp.begin(), w_tmp.end()));
27+
28+
setDeviceSoftwareMode();
29+
}
30+
31+
Lenovo4ZoneUSBController::~Lenovo4ZoneUSBController()
32+
{
33+
hid_close(dev);
34+
}
35+
36+
void Lenovo4ZoneUSBController::setMode(const KeyboardState &in_mode)
37+
{
38+
uint8_t buffer[LENOVO_4_ZONE_HID_PACKET_SIZE];
39+
memcpy(buffer, &in_mode, LENOVO_4_ZONE_HID_PACKET_SIZE);
40+
hid_send_feature_report(dev, buffer, LENOVO_4_ZONE_HID_PACKET_SIZE);
41+
}
42+
43+
uint16_t Lenovo4ZoneUSBController::getPid()
44+
{
45+
return pid;
46+
}
47+
48+
std::string Lenovo4ZoneUSBController::getName()
49+
{
50+
return name;
51+
}
52+
53+
std::string Lenovo4ZoneUSBController::getLocation()
54+
{
55+
return location;
56+
}
57+
58+
59+
void Lenovo4ZoneUSBController::sendBasicInstruction(uint8_t )
60+
{
61+
}
62+
63+
void Lenovo4ZoneUSBController::setDeviceSoftwareMode()
64+
{
65+
/*---------------------------------------*\
66+
| this is required for the device listen |
67+
| to the software protocol |
68+
\*---------------------------------------*/
69+
sendBasicInstruction(0xB2);
70+
}
71+
72+
void Lenovo4ZoneUSBController::setDeviceHardwareMode()
73+
{
74+
/*---------------------------------------*\
75+
|releases the device from sofware mode so |
76+
|that onboard controlls can be used |
77+
|this has not been shown to happen between|
78+
|reboots |
79+
\*---------------------------------------*/
80+
sendBasicInstruction(0xB1);
81+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*-------------------------------------------------------------------*\
2+
| Lenovo4ZoneUSBController.h |
3+
| |
4+
| interface for Lenovo 4-Zones Devices |
5+
\*-------------------------------------------------------------------*/
6+
7+
#pragma once
8+
9+
#include "RGBController.h"
10+
#include "LogManager.h"
11+
#include "LenovoDevices4Zone.h"
12+
13+
#include <string>
14+
#include <array>
15+
#include <vector>
16+
#include <utility>
17+
#include <hidapi/hidapi.h>
18+
19+
#ifndef HID_MAX_STR
20+
#define HID_MAX_STR 255
21+
#endif
22+
23+
#define LENOVO_4_ZONE_HID_PACKET_SIZE 33
24+
25+
class Lenovo4ZoneUSBController
26+
{
27+
public:
28+
/*--------------*\
29+
|ctor(s) and dtor|
30+
\*--------------*/
31+
Lenovo4ZoneUSBController(hid_device* dev_handle, const char* path, uint16_t in_pid);
32+
~Lenovo4ZoneUSBController();
33+
34+
void setMode(const KeyboardState &in_mode);
35+
36+
/*--------------*\
37+
|device functions|
38+
\*--------------*/
39+
uint16_t getPid();
40+
std::string getName();
41+
std::string getLocation();
42+
void setDeviceSoftwareMode();
43+
void setDeviceHardwareMode();
44+
45+
private:
46+
/*--------------*\
47+
|data members |
48+
\*--------------*/
49+
std::string name;
50+
hid_device *dev;
51+
std::string location;
52+
uint16_t pid;
53+
KeyboardState mode;
54+
55+
/*--------------*\
56+
|device functions|
57+
\*--------------*/
58+
void sendBasicInstruction(uint8_t instruction);
59+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*-------------------------------------------------------------------*\
2+
| Lenovo4ZoneUSBDetect.h |
3+
| |
4+
| Describes zones for Lenovo 4-Zone Device |
5+
\*-------------------------------------------------------------------*/
6+
7+
#include "Detector.h"
8+
#include "LogManager.h"
9+
#include "RGBController.h"
10+
#include "Lenovo4ZoneUSBController.h"
11+
#include "LenovoDevices4Zone.h"
12+
#include "RGBController_Lenovo4ZoneUSB.h"
13+
#include <hidapi/hidapi.h>
14+
15+
/*-----------------------------------------------------*\
16+
| vendor IDs |
17+
\*-----------------------------------------------------*/
18+
#define ITE_VID 0x048D
19+
20+
/*-----------------------------------------------------*\
21+
| Interface, Usage, and Usage Page |
22+
\*-----------------------------------------------------*/
23+
enum
24+
{
25+
LENOVO_PAGE = 0xFF89,
26+
LENOVO_USAGE = 0x10
27+
};
28+
29+
void DetectLenovo4ZoneUSBControllers(hid_device_info* info, const std::string& name)
30+
{
31+
hid_device* dev = hid_open_path(info->path);
32+
33+
if(dev)
34+
{
35+
Lenovo4ZoneUSBController* controller = new Lenovo4ZoneUSBController(dev, info->path, info->product_id);
36+
RGBController_Lenovo4ZoneUSB* rgb_controller = new RGBController_Lenovo4ZoneUSB(controller);
37+
rgb_controller->name = name;
38+
39+
ResourceManager::get()->RegisterRGBController(rgb_controller);
40+
}
41+
}
42+
43+
REGISTER_HID_DETECTOR_PU("Lenovo Ideapad 3-15ach6", DetectLenovo4ZoneUSBControllers, ITE_VID, IDEAPAD_315ACH6, LENOVO_PAGE, LENOVO_USAGE);
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*-------------------------------------------------------------------*\
2+
| LenovoDevices4Zone.h |
3+
| |
4+
| Describes zones for Lenovo 4-Zone Device |
5+
| |
6+
\*-------------------------------------------------------------------*/
7+
#pragma once
8+
9+
#include <string>
10+
#include "RGBControllerKeyNames.h"
11+
#include "RGBController.h"
12+
#include "LenovoDevices.h"
13+
14+
/*-----------------------------------------------------*\
15+
| Keyboard product IDs |
16+
\*-----------------------------------------------------*/
17+
#define IDEAPAD_315ACH6 0xC963
18+
19+
enum LENOVO_4_ZONE_EFFECT
20+
{
21+
LENOVO_4_ZONE_EFFECT_STATIC = 1,
22+
LENOVO_4_ZONE_EFFECT_BREATH = 3,
23+
LENOVO_4_ZONE_EFFECT_WAVE = 4,
24+
LENOVO_4_ZONE_EFFECT_SMOOTH = 6,
25+
};
26+
27+
enum LENOVO_4_ZONE_BRIGHTNESS
28+
{
29+
LENOVO_4_ZONE_BRIGHTNESS_LOW = 1,
30+
LENOVO_4_ZONE_BRIGHTNESS_HIGH = 2,
31+
};
32+
33+
enum LENOVO_4_ZONE_SPEED
34+
{
35+
LENOVO_4_ZONE_SPEED_SLOWEST = 1,
36+
LENOVO_4_ZONE_SPEED_SLOW = 2,
37+
LENOVO_4_ZONE_SPEED_FAST = 3,
38+
LENOVO_4_ZONE_SPEED_FASTEST = 4,
39+
};
40+
41+
/// struct a USB packet for set the keyboard LEDs
42+
class KeyboardState
43+
{
44+
public:
45+
uint8_t header[2] = {0xCC, 0x16};
46+
uint8_t effect = LENOVO_4_ZONE_EFFECT_STATIC;
47+
uint8_t speed = LENOVO_4_ZONE_SPEED_SLOWEST;
48+
uint8_t brightness = LENOVO_4_ZONE_BRIGHTNESS_LOW;
49+
uint8_t zone0_rgb[3] = {0xFF, 0xFF, 0xFF};
50+
uint8_t zone1_rgb[3] = {0xFF, 0xFF, 0xFF};
51+
uint8_t zone2_rgb[3] = {0xFF, 0xFF, 0xFF};
52+
uint8_t zone3_rgb[3] = {0xFF, 0xFF, 0xFF};
53+
uint8_t padding = 0;
54+
uint8_t wave_ltr = 0;
55+
uint8_t wave_rtl = 0;
56+
uint8_t unused[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
57+
58+
void Reset()
59+
{
60+
header[0] = 0xCC, header[1] = 0x16;
61+
effect = LENOVO_4_ZONE_EFFECT_STATIC;
62+
speed = LENOVO_4_ZONE_SPEED_SLOWEST;
63+
brightness = LENOVO_4_ZONE_BRIGHTNESS_LOW;
64+
zone0_rgb[0] = 0xFF, zone0_rgb[1] = 0xFF, zone0_rgb[2] = 0xFF;
65+
zone1_rgb[0] = 0xFF, zone1_rgb[1] = 0xFF, zone1_rgb[2] = 0xFF;
66+
zone2_rgb[0] = 0xFF, zone2_rgb[1] = 0xFF, zone2_rgb[2] = 0xFF;
67+
zone3_rgb[0] = 0xFF, zone3_rgb[1] = 0xFF, zone3_rgb[2] = 0xFF;
68+
padding = 0;
69+
wave_ltr = 0;
70+
wave_rtl = 0;
71+
for(int i = 0; i < 13; ++i)
72+
{
73+
unused[i] = 0;
74+
}
75+
}
76+
77+
void SetColors(std::vector<RGBColor> group_colors)
78+
{
79+
zone0_rgb[0] = RGBGetRValue(group_colors[0]);
80+
zone0_rgb[1] = RGBGetGValue(group_colors[0]);
81+
zone0_rgb[2] = RGBGetBValue(group_colors[0]);
82+
zone1_rgb[0] = RGBGetRValue(group_colors[1]);
83+
zone1_rgb[1] = RGBGetGValue(group_colors[1]);
84+
zone1_rgb[2] = RGBGetBValue(group_colors[1]);
85+
zone2_rgb[0] = RGBGetRValue(group_colors[2]);
86+
zone2_rgb[1] = RGBGetGValue(group_colors[2]);
87+
zone2_rgb[2] = RGBGetBValue(group_colors[2]);
88+
zone3_rgb[0] = RGBGetRValue(group_colors[3]);
89+
zone3_rgb[1] = RGBGetGValue(group_colors[3]);
90+
zone3_rgb[2] = RGBGetBValue(group_colors[3]);
91+
}
92+
};
93+
94+
/*-------------------------*\
95+
| 4-Zone keyboard |
96+
\*-------------------------*/
97+
98+
static const lenovo_led lenovo_4_zone_leds[]
99+
{
100+
{0x00, "Left side"},
101+
{0x01, "Left center"},
102+
{0x02, "Right center"},
103+
{0x03, "Right side"},
104+
};
105+

0 commit comments

Comments
 (0)