cvuchener / k90-linux-driver

Linux kernel space driver for Corsair Vengeance K90 Keyboard
22 stars 2 forks source link

I have a Raptor K30 Keyboard, how can I help? #5

Open dracwyrm opened 8 years ago

dracwyrm commented 8 years ago

Hi,

As the title states, I have a K30 model that has 6 G keys, three memory keys, one memory record button, on button with a lock on it with the windows logo(?), three levels of brightness for the backlighting, volume keys, and media keys. Is there anything that you need to make sure your drives can be 100% compatible with this keyboard?

Thanks for your hard work on this driver.

-Jon

dracwyrm commented 8 years ago

Here is the USB ID for the K30: 1b1c:1b0a Corsair

cvuchener commented 8 years ago

The HID usage codes part seems to be consistent accross corsair devices. But advanced features like backlight or macro profiles have slight variation that makes it more complex to support everything and I am thinking about deprecating those in the kernel driver and replacing them with a user-space tool (https://github.com/cvuchener/corsair-usb-config).

For testing the key remapping, you can try adding your device in the corsair_devices table in hid-corsair.c without enabling advanced features:

{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K30) },

and adding in hid-ids.h:

#define USB_DEVICE_ID_CORSAIR_K30   0x1b0a

(or I can create a branch for that, if you don't know how to edit the driver). It is preferable to have a second keyboard when testing in case something goes wrong with the driver or else do not install the driver in a permanent way (do not use the udev rule, load and bind the driver manually), so that if you reboot everything goes back to normal.

If you do not want to test the driver directly, you may simply check that the HID usage codes match those: https://github.com/cvuchener/k90-linux-driver/blob/master/hid_usage_codes.md, using usbmon or hid-recorder.

Testing advanced features is more complicated, the easiest and safest way is to study the windows driver first (but you need windows for that, a vm with usb passthough should work). You could although test my user-space tool by adding your device in device_table in main.cpp using an existing class and see what works and what does not (there is an undocumented command "raw-status" to test). But that can be dangerous, some usb transfer may set the device in a bad state, most of the time, resetting it should be enough but when sending random packets I some times had to reflash the firmware to make it work again.

How far you can go is mainly depending on if you have access to windows and a second keyboard to use during recovery. If you don't have those, you may prefer to stop at remapping usage codes.

dracwyrm commented 8 years ago

Thanks for replying back. I used usbmon to get these results. Do they make sense? G1 = 0000d000 00000000 00000000 000000 G2 = 0000d100 00000000 00000000 000000 G3 = 0000d200 00000000 00000000 000000 G4 = 0000d300 00000000 00000000 000000 G5 = 0000d400 00000000 00000000 000000 G6 = 0000d500 00000000 00000000 000000

MR 1st press = 0000f600 00000000 00000000 000000 MR 2nd press = 0000f700 00000000 00000000 000000

m1 = 0000f100 00000000 00000000 000000 m2 = 0000f200 00000000 00000000 000000 m3 = 0000f300 00000000 00000000 000000

Lock 1st press = 0000f400 00000000 00000000 000000 Lock 2nd press = 0000f500 00000000 00000000 000000

Light button start from off: 1st press = 0000fb00 00000000 00000000 000000 2nd press = 0000fc00 00000000 00000000 000000 3rd press = 0000fd00 00000000 00000000 000000 4th press = 0000fa00 00000000 00000000 000000 (back to off)

Mute = e2000000 00000000 00000000 000000 Vol down = ea000000 00000000 00000000 000000 Vol up = e9000000 00000000 00000000 000000

Stop = b7000000 00000000 00000000 000000 Rewind = b6000000 00000000 00000000 000000 play/pause = cd000000 00000000 00000000 000000 Fastforward = b5000000 00000000 00000000 000000

Also, I have a Windows 10 kvm/qemu VM where I have a USB controller passed. Normally I just use the input patches to pass a fake keyboard through, but I could disable that and plug the keyboard directly in to the passthroughed USB controller to install the official drivers. If I do that, what do I need to get the needed information for you to fully support this keyboard in either this driver or the new user space one?

Thanks, Jon

cvuchener commented 8 years ago

The usage code are the same, it should work fine for the remapping part.

Do you have any problem with the sound/media keys? They work with the generic driver for my keyboard.

Also, I have a Windows 10 kvm/qemu VM where I have a USB controller passed. Normally I just use the input patches to pass a fake keyboard through, but I could disable that and plug the keyboard directly in to the passthroughed USB controller to install the official drivers. If I do that, what do I need to get the needed information for you to fully support this keyboard in either this driver or the new user space one?

Record usb traffic while using the driver (I use USBPcap on windows, but with a vm, I think using usbmon on the linux host is enough). Keep you recording short and explain what you did in details. Interesting test would be:

If you know a little about USB protocol you can try comparing what you see with the protocol documented there : https://github.com/cvuchener/k90-linux-driver/blob/master/control_messages.md.

BitMonster1010 commented 8 years ago

I also have a k30 keyboard, could the driver "break" (not make it work ok) my keyboard on linux?

cvuchener commented 8 years ago

Errors in the installation or configuration of the kernel driver can lead to case where no driver manage the keyboard, so it is best to have a second keyboard to fix things (it is hard to run command or edit files without one).

About testing USB command, it is hard to tell and there will never be any guarantee. When testing random commands on my K90, I did manage to kind of brick it (solved by reflashing the firmware, so nothing too long term, but it required a second keyboard and windows). Make someone else try random commands is not a good idea anyway, so I need to start with some observation of the windows driver first.

If you only want to fix the keycodes, you can try a pure udev solution, that should be easier and safer : Add a file in /etc/udev/hwdb.d/ (any name ending with .hwdb should work, e.g. 60-corsair.hwdb) containing:

# Corsair K90
evdev:input:b0003v1B1Cp1B02*
# Corsair K30
evdev:input:b0003v1B1Cp1B0A*
# Corsair K40
evdev:input:b0003v1B1Cp1B0E*
 KEYBOARD_KEY_700d0=f13     # G1
 KEYBOARD_KEY_700d1=f14     # G2
 KEYBOARD_KEY_700d2=f15     # G3
 KEYBOARD_KEY_700d3=f16     # G4
 KEYBOARD_KEY_700d4=f17     # G5
 KEYBOARD_KEY_700d5=f18     # G6
 KEYBOARD_KEY_700d6=0xff    # G7
 KEYBOARD_KEY_700d7=0xff    # G8
 KEYBOARD_KEY_700d8=0xff    # G9
 KEYBOARD_KEY_700d9=0xff    # G10
 KEYBOARD_KEY_700da=0xff    # G11
 KEYBOARD_KEY_700db=0xff    # G12
 KEYBOARD_KEY_700dc=0xff    # G13
 KEYBOARD_KEY_700dd=0xff    # G14
 KEYBOARD_KEY_700de=0xff    # G15
 KEYBOARD_KEY_700df=0xff    # G16
 KEYBOARD_KEY_700e8=0xff    # G17
 KEYBOARD_KEY_700e9=0xff    # G18
 KEYBOARD_KEY_700f1=0xff    # M1
 KEYBOARD_KEY_700f2=0xff    # M2
 KEYBOARD_KEY_700f3=0xff    # M3
 KEYBOARD_KEY_700f4=0xff    # Meta lock (off)
 KEYBOARD_KEY_700f5=0xff    # Meta lock (on)
 KEYBOARD_KEY_700f6=0xff    # MR (start)
 KEYBOARD_KEY_700f7=0xff    # MR (stop)
 KEYBOARD_KEY_700fa=0xff    # Light (off)
 KEYBOARD_KEY_700fb=0xff    # Light (33%)
 KEYBOARD_KEY_700fc=0xff    # Light (67%)
 KEYBOARD_KEY_700fd=0xff    # Light (100%)

You can change the part after the = to any key you want (see /usr/include/linux/input-event-codes.h or /usr/include/linux/input.h for the list of linux key codes). 0xff is a hack using an invalid key code that should behave like there is no key code at all. See /usr/udev/hwdb.d/60-keyboard.hwdb for documentation.

After writing this file, reload udev hwdb (udevadm hwdb --update) then retrigger udev events for the device (udevadm trigger). Test the keyboard with evtest.

BitMonster1010 commented 8 years ago

I'll try that, because I just want to make the G keys work. So the method you told me now, shouldn't break my keyboard, right?

BitMonster1010 commented 8 years ago

Does it matter if I use hexadecimal or decimal when changing the codes for the g keys?

BitMonster1010 commented 8 years ago

The G keys are still not working, do I have to unplug and plug the keyboard back?

cvuchener commented 8 years ago

Does it matter if I use hexadecimal or decimal when changing the codes for the g keys?

I am not sure but I don't think decimal codes work, it would conflict with key name like KEY1. I would recommend to use key names when possible. The doc says key names come from the kernel API, so I guess it is the part after "KEY" in lower case.

Look at examples in /usr/udev/hwdb.d/60-keyboard.hwdb or in archlinux doc.

The G keys are still not working,

How exactly are they not working? Do you get any key event like KEY_UNKNOWN or nothing at all? I don't know about the K30 but the K90 use several interfaces so the G-keys are not sent on the same device as the regular keys. Did you test the correct device?

If you give me the output of for f in /sys/bus/hid/devices/*\:1B1C\:*; do echo $f; xxd $f/report_descriptor; echo $f/input/input*/event*; for i in $f/input/input*/id/*; do echo $i: $(< $i); done; done (can be run as a regular user, nothing dangerous, just reading infos on the devices), then I could tell which is the correct device.

Also keep in mind that X11 does not support key codes above 255 in case you want to use something like xbindkeys. Make sure to test with the evdev interface (evtest is good for that) before trying anything using X11.

do I have to unplug and plug the keyboard back?

Yes maybe that can help, I am not sure if the udev command I gave are enough, but the trigger command should have done that (or does it need the device to be specified?). Maybe add a udevadm control --reload after updating the hwdb, before pluging unplugging/plugging back the keyboard.

BitMonster1010 commented 8 years ago

Output of the command you gave me to see the device:

/sys/bus/hid/devices/0003:1B1C:1B0A.0002
0000000: 0501 0906 a101 0507 19e0 29e7 1500 2501  ..........)...%.
0000010: 7501 9508 8102 7508 9501 8101 0507 1900  u.....u.........
0000020: 2aff 0015 0026 ff00 7508 9506 8100 0508  *....&..u.......
0000030: 1901 2903 2501 7501 9503 9102 9505 9101  ..).%.u.........
0000040: c0                                       .
/sys/bus/hid/devices/0003:1B1C:1B0A.0002/input/input6/event3
/sys/bus/hid/devices/0003:1B1C:1B0A.0002/input/input6/id/bustype: 0003
/sys/bus/hid/devices/0003:1B1C:1B0A.0002/input/input6/id/product: 1b0a
/sys/bus/hid/devices/0003:1B1C:1B0A.0002/input/input6/id/vendor: 1b1c
/sys/bus/hid/devices/0003:1B1C:1B0A.0002/input/input6/id/version: 0111
/sys/bus/hid/devices/0003:1B1C:1B0A.0003
0000000: 050c 0901 a101 050c 1900 2aff 0f15 0026  ..........*....&
0000010: ff0f 7510 9502 8100 c0                   ..u......
/sys/bus/hid/devices/0003:1B1C:1B0A.0003/input/input7/event4
/sys/bus/hid/devices/0003:1B1C:1B0A.0003/input/input7/id/bustype: 0003
/sys/bus/hid/devices/0003:1B1C:1B0A.0003/input/input7/id/product: 1b0a
/sys/bus/hid/devices/0003:1B1C:1B0A.0003/input/input7/id/vendor: 1b1c
/sys/bus/hid/devices/0003:1B1C:1B0A.0003/input/input7/id/version: 0111
/sys/bus/hid/devices/0003:1B1C:1B0A.0004
0000000: 0501 0906 a101 0507 19e0 29e7 1500 2501  ..........)...%.
0000010: 7501 9508 8102 1900 296f 1500 2501 7501  u.......)o..%.u.
0000020: 9570 8102 c0                             .p...
/sys/bus/hid/devices/0003:1B1C:1B0A.0004/input/input8/event5
/sys/bus/hid/devices/0003:1B1C:1B0A.0004/input/input8/id/bustype: 0003
/sys/bus/hid/devices/0003:1B1C:1B0A.0004/input/input8/id/product: 1b0a
/sys/bus/hid/devices/0003:1B1C:1B0A.0004/input/input8/id/vendor: 1b1c
/sys/bus/hid/devices/0003:1B1C:1B0A.0004/input/input8/id/version: 0111

I haven't tried unplugging and plugging the keyboard back yet. Should I do that? I also entered the key code as hexadecimal, I used f13, f14, f15, f16, f17 and f18 keys (0xb7,0xb8,0xb9,0xba,0xbb,0xbc)

cvuchener commented 8 years ago

G-keys should be on the first one: event3, media keys on the second: event4, regular keys on event5.

The ids I used in the hwdb file match yours, so that file should work.

cvuchener commented 8 years ago

I also entered the key code as hexadecimal, I used f13, f14, f15, f16, f17 and f18 keys (0xb7,0xb8,0xb9,0xba,0xbb,0xbc)

That was what the file I gave did. Anyway try it without modifying it first. You can play with that later.

BitMonster1010 commented 8 years ago

Ok I tested on event3, but it gives me KEY_UNKNOWN

BitMonster1010 commented 8 years ago

I'll try using the hex codes

BitMonster1010 commented 8 years ago

Hex doesn't work either

cvuchener commented 8 years ago

Do you also get MSC_SCAN events? Does the value match the part before the = (e.g. 700d0)?

I tested on my side and udevadm hwdb --update + udevadm trigger is enough to update after a change. Did you run these commands as root? udevadm trigger does not work if run as regular but does not print an error, that can be misleading.

BitMonster1010 commented 8 years ago

I ran them as root and I got those MSC_SCAN events. screenshot from 2016-06-14 21 58 29

Corsair K90

evdev:input:b0003v1B1Cp1B02*

Corsair K30

evdev:input:b0003v1B1Cp1B0A*

Corsair K40

evdev:input:b0003v1B1Cp1B0E* KEYBOARD_KEY_700d0=0xb7 # G1 KEYBOARD_KEY_700d1=0xb8 # G2 KEYBOARD_KEY_700d2=0xb9 # G3 KEYBOARD_KEY_700d3=0xba # G4 KEYBOARD_KEY_700d4=0xbb # G5 KEYBOARD_KEY_700d5=0xbc # G6 KEYBOARD_KEY_700d6=0xff # G7 KEYBOARD_KEY_700d7=0xff # G8 KEYBOARD_KEY_700d8=0xff # G9 KEYBOARD_KEY_700d9=0xff # G10 KEYBOARD_KEY_700da=0xff # G11 KEYBOARD_KEY_700db=0xff # G12 KEYBOARD_KEY_700dc=0xff # G13 KEYBOARD_KEY_700dd=0xff # G14 KEYBOARD_KEY_700de=0xff # G15 KEYBOARD_KEY_700df=0xff # G16 KEYBOARD_KEY_700e8=0xff # G17 KEYBOARD_KEY_700e9=0xff # G18 KEYBOARD_KEY_700f1=0xff # M1 KEYBOARD_KEY_700f2=0xff # M2 KEYBOARD_KEY_700f3=0xff # M3 KEYBOARD_KEY_700f4=0xff # Meta lock (off) KEYBOARD_KEY_700f5=0xff # Meta lock (on) KEYBOARD_KEY_700f6=0xff # MR (start) KEYBOARD_KEY_700f7=0xff # MR (stop) KEYBOARD_KEY_700fa=0xff # Light (off) KEYBOARD_KEY_700fb=0xff # Light (33%) KEYBOARD_KEY_700fc=0xff # Light (67%) KEYBOARD_KEY_700fd=0xff # Light (100%)

And this is what I have in the file, try using the hex code maybe?

cvuchener commented 8 years ago

I don't know if it comes from the way you pasted the file, but make sure the KEYBOARDKEY* lines begin with a space.

Check the location and filename. Quoting man hwdb

The hwdb files are read from the files located in the system hwdb directory /usr/lib/udev/hwdb.d and the local administration directory /etc/udev/hwdb.d. All hwdb files are collectively sorted and processed in lexical order, regardless of the directories in which they live. However, files with identical filenames replace each other. Files in /etc have the highest priority and take precedence over files with the same name in /usr/lib. This can be used to override a system-supplied hwdb file with a local file if needed; a symlink in /etc with the same name as a hwdb file in /usr/lib, pointing to /dev/null, disables the hwdb file entirely. hwdb files must have the extension .hwdb; other extensions are ignored.

If these are not the problem I am out of ideas.

BitMonster1010 commented 8 years ago

These are not the problem. I checked the location it's in /etc/udev/hwdb.d and the file name is 60-corsair.hwdb. Anyway thanks for the help, I will tell you if I will manage to make them work.

BitMonster1010 commented 8 years ago

On what linux distro did you run it on? I have ubuntu.

cvuchener commented 8 years ago

I am using fedora, udev v229.

I found that : http://unix.stackexchange.com/a/216811 I you are using ubuntu 14.04, it has udev v204, so try using keyboard:usb:v1B1Cp1B0A* instead of evdev:input:b0003v1B1Cp1B0A*. More recent versions of ubuntu, should use the newer method (15.10 has v225, 16.04 has v229).

cvuchener commented 8 years ago

I have just learned, that reserved could be used instead of 0xff, that would be much cleaner (no key code is sent).

BitMonster1010 commented 8 years ago

ah, so that's why it wasn't working, so I should also change the 0xff to reserved, right?

BitMonster1010 commented 8 years ago

still doesn't work, maybe try using a ubuntu 14.04 virtual machine and find a way to make it work.

cvuchener commented 8 years ago

I had some problem too with ubuntu 14.04. I solved it with that: https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1361338

All of these steps are necessary:

  • udevadm hwdb --update
  • udevadm control --reload
  • replug the keyboard or do a unbind-bind-cycle via sysfs

Not doing any one of them will not produce the intended effect.

FYI, in my test, /etc/udev/hwdb/60-corsair.hwdb contained:

keyboard:usb:v1B1Cp1B02*
 KEYBOARD_KEY_700d0=f13     # G1
 KEYBOARD_KEY_700d1=f14     # G2
 KEYBOARD_KEY_700d2=f15     # G3
 KEYBOARD_KEY_700d3=f16     # G4
 KEYBOARD_KEY_700d4=f17     # G5
 KEYBOARD_KEY_700d5=f18     # G6
 KEYBOARD_KEY_700d6=reserved    # G7
 KEYBOARD_KEY_700d7=reserved    # G8
 KEYBOARD_KEY_700d8=reserved    # G9
 KEYBOARD_KEY_700d9=reserved    # G10
 KEYBOARD_KEY_700da=reserved    # G11
 KEYBOARD_KEY_700db=reserved    # G12
 KEYBOARD_KEY_700dc=reserved    # G13
 KEYBOARD_KEY_700dd=reserved    # G14
 KEYBOARD_KEY_700de=reserved    # G15
 KEYBOARD_KEY_700df=reserved    # G16
 KEYBOARD_KEY_700e8=reserved    # G17
 KEYBOARD_KEY_700e9=reserved    # G18
 KEYBOARD_KEY_700f1=reserved    # M1
 KEYBOARD_KEY_700f2=reserved    # M2
 KEYBOARD_KEY_700f3=reserved    # M3
 KEYBOARD_KEY_700f4=reserved    # Meta lock (off)
 KEYBOARD_KEY_700f5=reserved    # Meta lock (on)
 KEYBOARD_KEY_700f6=reserved    # MR (start)
 KEYBOARD_KEY_700f7=reserved    # MR (stop)
 KEYBOARD_KEY_700fa=reserved    # Light (off)
 KEYBOARD_KEY_700fb=reserved    # Light (33%)
 KEYBOARD_KEY_700fc=reserved    # Light (67%)
 KEYBOARD_KEY_700fd=reserved    # Light (100%)
BitMonster1010 commented 8 years ago

it still doesn't work I replugged the keyboard, I should try with a unbind-bind-cycle via sysfs, but how do I do that?

BitMonster1010 commented 8 years ago

also do I have to restart my computer?

cvuchener commented 8 years ago

I replugged the keyboard, I should try with a unbind-bind-cycle via sysfs, but how do I do that?

By writing the name of the device in the unbind and bind files in the driver directory on the sysfs. You can do that for the usb device, usb interfaces or the hid devices.

Look for the device names in /sys/bus/<busname>/devices. HID names are easier to understand they look like BBBB:VVVV:PPPP:NNNN where BBBB is the bus number (0003 for USB), VVVV the vendor id (1B1C for corsair), PPPP the product id (1B0A for the K30), NNNN is just a number to differentiate the devices (you should have three HID devices for the K30). USB device names look like busnum-port[.port...], you can get the ports with lsusb -t. USB interfaces add -configuration.interface add the end of the device name.

Once you have found your device, check the driver symlink inside the device directory to get the driver name. It should be usb for usb devices, usbhid for usb interfaces, hid-generic for the hid devices.

Now you have all the information you need, use the following commands (the keyboard won't work between the two commands, you should type them on the same line with a semicolon to separate them if you are typing that with the K30):

sudo tee /sys/bus/<busname>/drivers/<drivername>/unbind <<< "<devicename>"; sudo tee /sys/bus/<busname>/drivers/<drivername>/bind <<< "<devicename>"

or if you cannot understand what I wrote, just run:

for f in /sys/bus/hid/devices/0003\:1B1C\:1B0A.*; do
dev=$(basename "$f")
sudo tee /sys/bus/hid/drivers/hid-generic/unbind <<< "$dev"
sudo tee /sys/bus/hid/drivers/hid-generic/bind <<< "$dev"
done

If everything goes well, it should print the names of the HID devices and unbind-bind them.

also do I have to restart my computer?

It can help, but the commands form the ubuntu bug were enough for me.

BitMonster1010 commented 8 years ago

Ok, I got a new keyboard now, a Corsair Vengeance K95, I still want the G Keys to work though, I saw that there's a driver for linux for this keyboard (unofficial driver), should I try using that driver or still use the method you told me (if I do that, then you should give me the k95's usb id). I also noticed that the G Keys don't have KEY_UNKNOWN, they have different keys (not each of the g keys though, G1->G8 use ABS_MT_TOOL_TYPE, G9->G10 use ABS_MT_BLOB_ID, G11->G18 use ABS_MT_TRACKING_ID.

cvuchener commented 8 years ago

Is it the RGB version ?

It is strange that you have ABS_* (absolute axis) events for keys. I thought from ckb source code that both the RGB and non-RGB K95 used the same usage code as the other corsair keyboards I know.

Either way you can try configuring udev or using ckb as you prefer. You can get the vid/pid with lsusb.

BitMonster1010 commented 8 years ago

yes it's the RGB version

cvuchener commented 8 years ago

Although I thought it was the same for the key HID usage code, the protocol for the other features is completely different from older corsair keyboards. You should ask MSC (ckb dev) about any problem you have with it.

BitMonster1010 commented 8 years ago

I installed the driver and works ok, I also managed to get the G Keys work with it. Anyway thanks for the help!