Merge branch 'newfw' into master

This commit is contained in:
Tasos Sahanidis
2017-12-04 23:38:44 +02:00
6 changed files with 54 additions and 24 deletions
+3 -2
View File
@@ -388,8 +388,9 @@ void hid_kb_translate(unsigned char* kbinput, int endpoint, int length, const un
#define BUTTON_HID_COUNT 5
void hid_mouse_translate(unsigned char* kbinput, short* xaxis, short* yaxis, int endpoint, int length, const unsigned char* urbinput){
if((endpoint != 2 && endpoint != -2) || length < 10)
void hid_mouse_translate(unsigned char* kbinput, short* xaxis, short* yaxis, int endpoint, int length, const unsigned char* urbinput, ushort fwversion){
//The HID Input Endpoint on FWv3 is 64 bytes, so we can't check for length.
if((endpoint != 2 && endpoint != -2) || (fwversion < 0x300 && length < 10))
return;
// EP 2: mouse input
if(urbinput[0] != 1)
+1 -1
View File
@@ -64,7 +64,7 @@ extern const key keymap[N_KEYS_EXTENDED];
// Translates input from HID to a ckb input bitfield.
// Use positive endpoint for non-RGB keyboards, negative endpoint for RGB
void hid_kb_translate(unsigned char* kbinput, int endpoint, int length, const unsigned char* urbinput);
void hid_mouse_translate(unsigned char* kbinput, short* xaxis, short* yaxis, int endpoint, int length, const unsigned char* urbinput);
void hid_mouse_translate(unsigned char* kbinput, short* xaxis, short* yaxis, int endpoint, int length, const unsigned char* urbinput, ushort fwversion);
// Copies input from Corsair reports
void corsair_kbcopy(unsigned char* kbinput, int endpoint, const unsigned char* urbinput);
+2 -2
View File
@@ -146,7 +146,7 @@ int updatergb_kb(usbdevice* kb, int force){
}
int savergb_kb(usbdevice* kb, lighting* light, int mode){
if(kb->fwversion >= 0x0120 || IS_NEW_PROTOCOL(kb)){
if(kb->fwversion >= 0x0120 || IS_V2_OVERRIDE(kb)){
uchar data_pkt[12][MSG_SIZE] = {
// Red
{ 0x7f, 0x01, 60, 0 },
@@ -188,7 +188,7 @@ int savergb_kb(usbdevice* kb, lighting* light, int mode){
}
int loadrgb_kb(usbdevice* kb, lighting* light, int mode){
if(kb->fwversion >= 0x0120 || IS_NEW_PROTOCOL(kb)){
if(kb->fwversion >= 0x0120 || IS_V2_OVERRIDE(kb)){
uchar data_pkt[12][MSG_SIZE] = {
{ 0x0e, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x01 },
{ 0xff, 0x01, 60, 0 },
+1 -1
View File
@@ -169,7 +169,7 @@ const char* product_str(short product);
#define IS_PLATINUM(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K95_PLATINUM))
/// Used when a device has a firmware with a low version number that uses the new protocol
#define IS_NEW_PROTOCOL(kb) (IS_PLATINUM(kb) || IS_K63(kb) || IS_K68(kb) || IS_HARPOON(kb) || IS_GLAIVE(kb) || (kb)->product == P_STRAFE_NRGB_2)
#define IS_V2_OVERRIDE(kb) (IS_PLATINUM(kb) || IS_K63(kb) || IS_K68(kb) || IS_HARPOON(kb) || IS_GLAIVE(kb) || (kb)->product == P_STRAFE_NRGB_2)
/// USB delays for when the keyboards get picky about timing
/// That was the original comment, but it is used anytime.
+24 -11
View File
@@ -67,9 +67,10 @@ static char kbsyspath[DEV_MAX][FILENAME_MAX];
///
int os_usbsend(usbdevice* kb, const uchar* out_msg, int is_recv, const char* file, int line) {
int res;
if ((kb->fwversion >= 0x120 || IS_NEW_PROTOCOL(kb)) && !is_recv){
if ((kb->fwversion >= 0x120 || IS_V2_OVERRIDE(kb)) && !is_recv){
struct usbdevfs_bulktransfer transfer = {0};
transfer.ep = (kb->fwversion >= 0x130 && kb->fwversion < 0x200) ? 4 : 3;
// FW 2.XX uses 0x03, FW 3.XX uses 0x02
transfer.ep = (kb->fwversion >= 0x130 && kb->fwversion < 0x200) ? 4 : (kb->fwversion >= 0x300 ? 2 : 3);
transfer.len = MSG_SIZE;
transfer.timeout = 5000;
transfer.data = (void*)out_msg;
@@ -212,7 +213,16 @@ int _nk95cmd(usbdevice* kb, uchar bRequest, ushort wValue, const char* file, int
///
void os_sendindicators(usbdevice* kb) {
static int countForReset = 0;
struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, 0x00, 1, 500, &kb->ileds };
void *ileds;
ushort leds;
if(kb->fwversion >= 0x300) {
leds = (kb->ileds << 8) | 0x0001;
ileds = &leds;
}
else {
ileds = &kb->ileds;
}
struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, 0x00, (kb->fwversion >= 0x300 ? 2 : 1), 500, ileds };
int res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer);
if(res <= 0) {
ckb_err("%s\n", res ? strerror(errno) : "No data written");
@@ -262,14 +272,14 @@ void* os_inputmain(void* context){
///
/// device | detect with macro combination | endpoint # | buffer-length
/// ------ | ----------------------------- | ---------- | -------------
/// each | none | 0 | 8
/// each | none | 0 | 8, 64 for FW v3
/// RGB Mouse | IS_RGB && IS_MOUSE | 1 | 10
/// RGB Keyboard | IS_RGB && !IS_MOUSE | 1 | 21
/// RGB Mouse or Keyboard | IS_RGB | 2 | MSG_SIZE (64)
/// non RGB Mouse or Keyboard | !IS_RGB | 1 | 4
/// non RGB Mouse or Keyboard | !IS_RGB | 2 | 15
///
urbs[0].buffer_length = 8;
urbs[0].buffer_length = (kb->fwversion >= 0x300 ? MSG_SIZE : 8);
if(urbcount > 1 && IS_RGB(vendor, product)) {
if(IS_MOUSE(vendor, product))
urbs[1].buffer_length = 10;
@@ -278,9 +288,9 @@ void* os_inputmain(void* context){
urbs[2].buffer_length = MSG_SIZE;
if(urbcount != 3)
urbs[urbcount - 1].buffer_length = MSG_SIZE;
} else {
urbs[1].buffer_length = 4;
urbs[2].buffer_length = 15;
} else if(kb->fwversion < 0x300) {
urbs[1].buffer_length = 4;
urbs[2].buffer_length = 15;
}
/// Now submit all the URBs via ioctl(USBDEVFS_SUBMITURB) with type USBDEVFS_URB_TYPE_INTERRUPT (the endpoints are defined as type interrupt).
@@ -330,17 +340,20 @@ void* os_inputmain(void* context){
/// non RGB Keyboard | !IS_RGB && !IS_MOUSE | nA | nA | hid_kb_translate()
///
pthread_mutex_lock(imutex(kb));
// EP workaround for FWv3
// Corsair input comes through 0x81, but case 1 in keymap.c is used for 6KRO
uchar urbendpoint = (kb->fwversion >= 0x300 ? 2 : (urb->endpoint & 0xF));
if(IS_MOUSE(vendor, product)){
switch(urb->actual_length){
case 8:
case 10:
case 11:
// HID mouse input
hid_mouse_translate(kb->input.keys, &kb->input.rel_x, &kb->input.rel_y, -(urb->endpoint & 0xF), urb->actual_length, urb->buffer);
hid_mouse_translate(kb->input.keys, &kb->input.rel_x, &kb->input.rel_y, -urbendpoint, urb->actual_length, urb->buffer, kb->fwversion);
break;
case MSG_SIZE:
// Corsair mouse input
corsair_mousecopy(kb->input.keys, -(urb->endpoint & 0xF), urb->buffer);
corsair_mousecopy(kb->input.keys, -urbendpoint, urb->buffer);
break;
}
} else if(IS_RGB(vendor, product)){
@@ -357,7 +370,7 @@ void* os_inputmain(void* context){
break;
case MSG_SIZE:
// RGB EP 3: Corsair input
corsair_kbcopy(kb->input.keys, -(urb->endpoint & 0xF), urb->buffer);
corsair_kbcopy(kb->input.keys, -urbendpoint, urb->buffer);
break;
}
} else {
+23 -7
View File
@@ -103,7 +103,7 @@ int os_usbsend(usbdevice* kb, const uchar* out_msg, int is_recv, const char* fil
kern_return_t res = kIOReturnSuccess;
///
/// \todo Be aware: This condition is exact inverted to the condition in the linux dependent os_usbsend(). It may be correct, but please check it.
if((kb->fwversion < 0x120 && !IS_NEW_PROTOCOL(kb)) || is_recv){
if((kb->fwversion < 0x120 && !IS_V2_OVERRIDE(kb)) || is_recv){
int ep = kb->epcount;
// For old devices, or for receiving data, use control transfers
IOUSBDevRequestTO rq = { 0x21, 0x09, 0x0200, ep - 1, MSG_SIZE, (void*)out_msg, 0, 5000, 5000 };
@@ -119,7 +119,8 @@ int os_usbsend(usbdevice* kb, const uchar* out_msg, int is_recv, const char* fil
}
} else {
// For newer devices, use interrupt transfers
int ep = (kb->fwversion >= 0x130 && kb->fwversion < 0x200) ? 4 : 3;
// macOS sees 4 endpoints (including ep0) for FW 3.XX
int ep = (kb->fwversion >= 0x130 && (kb->fwversion < 0x200 || kb->fwversion >= 0x300)) ? 4 : 3;
usb_iface_t h_usb = kb->ifusb[ep - 1];
hid_dev_t h_hid = kb->ifhid[ep - 1];
if(h_usb)
@@ -176,7 +177,16 @@ int _nk95cmd(usbdevice* kb, uchar bRequest, ushort wValue, const char* file, int
}
void os_sendindicators(usbdevice* kb){
IOUSBDevRequestTO rq = { 0x21, 0x09, 0x0200, 0x00, 1, &kb->ileds, 0, 500, 500 };
void *ileds;
ushort leds;
if(kb->fwversion >= 0x300) {
leds = (kb->ileds << 8) | 0x0001;
ileds = &leds;
}
else {
ileds = &kb->ileds;
}
IOUSBDevRequestTO rq = { 0x21, 0x09, 0x0200, 0x00, (kb->fwversion >= 0x300 ? 2 : 1), ileds, 0, 500, 500 };
kern_return_t res = (*kb->handle)->DeviceRequestTO(kb->handle, &rq);
if(res == kIOReturnNotOpen){
// Handle not open - try to go through the HID system instead
@@ -229,7 +239,7 @@ static void intreport(void* context, IOReturn result, void* sender, IOHIDReportT
case 8:
case 10:
case 11:
hid_mouse_translate(kb->input.keys, &kb->input.rel_x, &kb->input.rel_y, -2, length, data);
hid_mouse_translate(kb->input.keys, &kb->input.rel_x, &kb->input.rel_y, -2, length, data, kb->fwversion);
break;
case MSG_SIZE:
corsair_mousecopy(kb->input.keys, kb->epcount >= 4 ? -3 : -2, data);
@@ -773,7 +783,9 @@ static usbdevice* add_hid(hid_dev_t handle, io_object_t** rm_notify){
long input = hidgetlong(handle, CFSTR(kIOHIDMaxInputReportSizeKey));
long output = hidgetlong(handle, CFSTR(kIOHIDMaxOutputReportSizeKey));
long feature = hidgetlong(handle, CFSTR(kIOHIDMaxFeatureReportSizeKey));
long fwversion = hidgetlong(handle, CFSTR(kIOHIDVersionNumberKey));
int handle_idx;
// Handle 3 is for controlling the device (only exists for RGB)
if(feature == 64)
handle_idx = 3;
@@ -785,9 +797,13 @@ static usbdevice* add_hid(hid_dev_t handle, io_object_t** rm_notify){
(input <= 1 && output == 64))) // FW >= 2.00 (Scimitar)
handle_idx = 2;
// Handle 0 is for BIOS mode input (RGB) or non-RGB key input
else if(output <= 1 && feature <= 1 &&
(input == 8 || // Keyboards
input == 7)) // Mice
else if((output <= 1 && feature <= 1 &&
(input == 8 || // Keyboards
input == 7)) || // Mice
(fwversion >= 0x300 && // FWv3 hack
input == 64 &&
output <= 2 &&
feature == 1))
handle_idx = 0;
// Handle 1 is for standard HID input (RGB) or media keys (non-RGB)
else if(output <= 1 && feature <= 1 &&