|
| 1 | +/*-----------------------------------------*\ |
| 2 | +| GigabyteAorusLaptopController.h | |
| 3 | +| | |
| 4 | +| Driver for Gigabyte Aorus Laptop | |
| 5 | +| controller | |
| 6 | +| | |
| 7 | +| Guimard Morgan (morg) 06/05/2023 | |
| 8 | +\*-----------------------------------------*/ |
| 9 | +#include "GigabyteAorusLaptopController.h" |
| 10 | +#include <string.h> |
| 11 | +#include <cmath> |
| 12 | + |
| 13 | +/*---------------------------------------------------------*\ |
| 14 | +| Indexed colors mapping | |
| 15 | +| blue 04 | |
| 16 | +| green 02 | |
| 17 | +| orange 05 | |
| 18 | +| purple 06 | |
| 19 | +| red 01 | |
| 20 | +| white 07 | |
| 21 | +| yellow 03 | |
| 22 | +\*---------------------------------------------------------*/ |
| 23 | +static unsigned char argb_colour_index_data[2][2][2] = |
| 24 | + { //B0 B1 |
| 25 | + { { 0x01, 0x04 }, //G0 R0 |
| 26 | + { 0x02, 0x04 }, }, //G1 R0 |
| 27 | + { { 0x01, 0x06 }, //G0 R1 |
| 28 | + { 0x05, 0x07 }, } //G1 R1 |
| 29 | +}; |
| 30 | + |
| 31 | +GigabyteAorusLaptopController::GigabyteAorusLaptopController(hid_device* dev_handle, const hid_device_info& info) |
| 32 | +{ |
| 33 | + dev = dev_handle; |
| 34 | + location = info.path; |
| 35 | + version = ""; |
| 36 | + |
| 37 | + wchar_t serial_string[128]; |
| 38 | + int ret = hid_get_serial_number_string(dev, serial_string, 128); |
| 39 | + |
| 40 | + if(ret != 0) |
| 41 | + { |
| 42 | + serial_number = ""; |
| 43 | + } |
| 44 | + else |
| 45 | + { |
| 46 | + std::wstring return_wstring = serial_string; |
| 47 | + serial_number = std::string(return_wstring.begin(), return_wstring.end()); |
| 48 | + } |
| 49 | +} |
| 50 | + |
| 51 | +GigabyteAorusLaptopController::~GigabyteAorusLaptopController() |
| 52 | +{ |
| 53 | + hid_close(dev); |
| 54 | +} |
| 55 | + |
| 56 | +std::string GigabyteAorusLaptopController::GetDeviceLocation() |
| 57 | +{ |
| 58 | + return("HID: " + location); |
| 59 | +} |
| 60 | + |
| 61 | +std::string GigabyteAorusLaptopController::GetSerialString() |
| 62 | +{ |
| 63 | + return(serial_number); |
| 64 | +} |
| 65 | + |
| 66 | +std::string GigabyteAorusLaptopController::GetFirmwareVersion() |
| 67 | +{ |
| 68 | + return(version); |
| 69 | +} |
| 70 | + |
| 71 | +void GigabyteAorusLaptopController::SetDirect(uint8_t brightness, RGBColor color) |
| 72 | +{ |
| 73 | + /*---------------------------------------------------------*\ |
| 74 | + | Direct mode protocol | |
| 75 | + | ID C R G B Br C Ch | |
| 76 | + | 08 01 00 00 FF 32 00 C5 | |
| 77 | + | | |
| 78 | + | C = constant | |
| 79 | + | RGB = color | |
| 80 | + | Br= brightness | |
| 81 | + | Ch = checksum: 0xFF - all bytes | |
| 82 | + \*---------------------------------------------------------*/ |
| 83 | + |
| 84 | + unsigned char usb_buf[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1]; |
| 85 | + memset(usb_buf, 0x00, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 86 | + |
| 87 | + usb_buf[1] = GIGABYTE_AORUS_LAPTOP_REPORT_ID; |
| 88 | + usb_buf[2] = 0x01; |
| 89 | + usb_buf[3] = RGBGetRValue(color); |
| 90 | + usb_buf[4] = RGBGetGValue(color); |
| 91 | + usb_buf[5] = RGBGetBValue(color); |
| 92 | + usb_buf[6] = brightness; |
| 93 | + |
| 94 | + unsigned char checksum = 0xFF; |
| 95 | + |
| 96 | + for(unsigned int i = 1; i < 8; i++) |
| 97 | + { |
| 98 | + checksum -= usb_buf[i]; |
| 99 | + } |
| 100 | + |
| 101 | + usb_buf[8] = checksum; |
| 102 | + |
| 103 | + hid_send_feature_report(dev, usb_buf, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 104 | +} |
| 105 | + |
| 106 | +void GigabyteAorusLaptopController::SetMode(uint8_t mode_value, uint8_t speed, uint8_t brightness, uint8_t direction, RGBColor color) |
| 107 | +{ |
| 108 | + /*---------------------------------------------------------*\ |
| 109 | + | Hardware mode protocol | |
| 110 | + | ID C M Sp Br Cl Dr Ch | |
| 111 | + | 08 00 01 08 32 01 00 XX | |
| 112 | + | | |
| 113 | + | C = constant | |
| 114 | + | M = mode | |
| 115 | + | Sp = speed | |
| 116 | + | Br = brightness | |
| 117 | + | Cl = Indexed color | |
| 118 | + | Dr = Direction | |
| 119 | + | Ch = checksum: 0xFF - all bytes | |
| 120 | + \*---------------------------------------------------------*/ |
| 121 | + |
| 122 | + unsigned char red = RGBGetRValue(color); |
| 123 | + unsigned char grn = RGBGetGValue(color); |
| 124 | + unsigned char blu = RGBGetBValue(color); |
| 125 | + |
| 126 | + unsigned char indexed_color = GetColourIndex(red,grn,blu); |
| 127 | + |
| 128 | + unsigned char usb_buf[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1]; |
| 129 | + memset(usb_buf, 0x00, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 130 | + |
| 131 | + usb_buf[1] = GIGABYTE_AORUS_LAPTOP_REPORT_ID; // report id |
| 132 | + |
| 133 | + usb_buf[3] = mode_value; // mode value |
| 134 | + usb_buf[4] = speed; // speed 0x01 -> 0x09 |
| 135 | + usb_buf[5] = brightness; // brightness 0x00 -> 0x32 |
| 136 | + usb_buf[6] = indexed_color; // color (red, orange, yellow, green, blue, purple, white) |
| 137 | + usb_buf[7] = direction; // direction 0x01: right, 0x02 left, 0x03 up , 0x04 down |
| 138 | + |
| 139 | + unsigned char checksum = 0xFF; |
| 140 | + |
| 141 | + for(unsigned int i = 1; i < 8; i++) |
| 142 | + { |
| 143 | + checksum -= usb_buf[i]; |
| 144 | + } |
| 145 | + |
| 146 | + usb_buf[8] = checksum; // checksum |
| 147 | + |
| 148 | + hid_send_feature_report(dev, usb_buf, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 149 | +} |
| 150 | + |
| 151 | +unsigned char GigabyteAorusLaptopController::GetColourIndex(unsigned char red, unsigned char green, unsigned char blue) |
| 152 | +{ |
| 153 | + /*-----------------------------------------------------*\ |
| 154 | + | This device uses a limited colour pallette referenced | |
| 155 | + | by an index | |
| 156 | + | 0x01 red | |
| 157 | + | 0x02 orange | |
| 158 | + | 0x03 yellow | |
| 159 | + | 0x04 green | |
| 160 | + | 0x05 blue | |
| 161 | + | 0x06 purple | |
| 162 | + | 0x07 white | |
| 163 | + \*-----------------------------------------------------*/ |
| 164 | + unsigned int divisor = GetLargestColour( red, green, blue); |
| 165 | + unsigned int r = round( red / divisor ); |
| 166 | + unsigned int g = round( green / divisor ); |
| 167 | + unsigned int b = round( blue / divisor ); |
| 168 | + unsigned char idx = argb_colour_index_data[r][g][b]; |
| 169 | + return idx; |
| 170 | +} |
| 171 | + |
| 172 | +unsigned int GigabyteAorusLaptopController::GetLargestColour(unsigned int red, unsigned int green, unsigned int blue) |
| 173 | +{ |
| 174 | + unsigned int largest; |
| 175 | + |
| 176 | + if ( red > green ) |
| 177 | + { |
| 178 | + ( red > blue ) ? largest = red : largest = blue; |
| 179 | + } |
| 180 | + else |
| 181 | + { |
| 182 | + ( green > blue ) ? largest = green : largest = blue; |
| 183 | + } |
| 184 | + |
| 185 | + return (largest == 0) ? 1 : largest; |
| 186 | +} |
| 187 | + |
| 188 | +void GigabyteAorusLaptopController::SetCustom(std::vector<RGBColor> colors, std::vector<unsigned int> positions) |
| 189 | +{ |
| 190 | + /*---------------------------------------------------------*\ |
| 191 | + | Custom mode protocol | |
| 192 | + | ID C M Sp Br Cl Dr Ch | |
| 193 | + | 08 00 33 01 2D 05 01 90 | |
| 194 | + | 92 00 00 00 00 00 00 6D -> | |
| 195 | + | GET REPORT REQUEST <- | |
| 196 | + | read 8x64 bytes <- | |
| 197 | + | 12 00 00 08 00 00 00 E5 -> | |
| 198 | + | 00 RR GG BB ..... -> data (8 * 64 bytes) | |
| 199 | + \*---------------------------------------------------------*/ |
| 200 | + |
| 201 | + /*---------------------------------------------------------*\ |
| 202 | + | Sends mode packet | |
| 203 | + \*---------------------------------------------------------*/ |
| 204 | + unsigned char usb_buf[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1]; |
| 205 | + memset(usb_buf, 0x00, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 206 | + |
| 207 | + usb_buf[1] = GIGABYTE_AORUS_LAPTOP_REPORT_ID; |
| 208 | + usb_buf[3] = GIGABYTE_AORUS_LAPTOP_CUSTOM_MODE_VALUE; |
| 209 | + usb_buf[4] = 0x01; |
| 210 | + usb_buf[5] = 0x32; |
| 211 | + usb_buf[6] = 0x05; |
| 212 | + usb_buf[7] = 0x01; |
| 213 | + |
| 214 | + unsigned char checksum = 0xFF; |
| 215 | + |
| 216 | + for(unsigned int i = 1; i < 8; i++) |
| 217 | + { |
| 218 | + checksum -= usb_buf[i]; |
| 219 | + } |
| 220 | + |
| 221 | + usb_buf[8] = checksum; |
| 222 | + |
| 223 | + hid_send_feature_report(dev, usb_buf, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 224 | + |
| 225 | + /*---------------------------------------------------------*\ |
| 226 | + | Sends first packet | |
| 227 | + \*---------------------------------------------------------*/ |
| 228 | + unsigned char start_packet[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1] = |
| 229 | + { |
| 230 | + 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D |
| 231 | + }; |
| 232 | + |
| 233 | + hid_send_feature_report(dev, start_packet, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 234 | + |
| 235 | + /*---------------------------------------------------------*\ |
| 236 | + | GET REPORT REQUEST | |
| 237 | + \*---------------------------------------------------------*/ |
| 238 | + unsigned char report_packet[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1]; |
| 239 | + memset(report_packet, 0x00, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 240 | + |
| 241 | + report_packet[1] = GIGABYTE_AORUS_LAPTOP_REPORT_ID; |
| 242 | + hid_get_feature_report(dev, report_packet, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 243 | + |
| 244 | + /*---------------------------------------------------------*\ |
| 245 | + | Sends 2nd packet | |
| 246 | + \*---------------------------------------------------------*/ |
| 247 | + unsigned char second_packet[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1] = |
| 248 | + { |
| 249 | + 0x00, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xE5 |
| 250 | + }; |
| 251 | + |
| 252 | + hid_send_feature_report(dev, second_packet, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1); |
| 253 | + |
| 254 | + /*---------------------------------------------------------*\ |
| 255 | + | Creates the data packets | |
| 256 | + \*---------------------------------------------------------*/ |
| 257 | + unsigned char color_data[64 * 8]; |
| 258 | + memset(color_data, 0x00, 64 * 8); |
| 259 | + |
| 260 | + for(unsigned int i = 0; i < positions.size(); i++) |
| 261 | + { |
| 262 | + color_data[positions[i] * 4 + 1] = RGBGetRValue(colors[i]); |
| 263 | + color_data[positions[i] * 4 + 2] = RGBGetGValue(colors[i]); |
| 264 | + color_data[positions[i] * 4 + 3] = RGBGetBValue(colors[i]); |
| 265 | + } |
| 266 | + |
| 267 | + unsigned char color_buf[64 + 1]; |
| 268 | + color_buf[0] = 0; |
| 269 | + |
| 270 | + for(unsigned int i = 0; i < 8; i++) |
| 271 | + { |
| 272 | + memcpy(&color_buf[1], &(color_data[64*i]), 64); |
| 273 | + hid_write(dev, color_buf, 65); |
| 274 | + } |
| 275 | +} |
0 commit comments