Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge 'em #3

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
339 changes: 339 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

17 changes: 11 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
MODULE_NAME = fn_keys_mod
MODULE_NAME = aerofnkeys
KVER = $(shell uname -r)
MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/hid/

obj-m += fn_keys_mod.o
obj-m += $(MODULE_NAME).o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
$(MAKE) -C /lib/modules/$(KVER)/build M=$(PWD) modules
# Remove the debugging symbols and shrink this module down:
strip --strip-debug $(MODULE_NAME).ko
# Here we sign the module to allow loading in a system with kernel_lockdown enabled (e.g. anything Ubuntu including and beyond 20.04 LTS)
/usr/src/linux-headers-${KVER}/scripts/sign-file sha512 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der $(MODULE_NAME).ko

clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
$(MAKE) -C /lib/modules/${KVER}/build M=$(PWD) clean

install:
xz -9 fn_keys_mod.ko
install -p -m 644 $(MODULE_NAME).ko.xz $(MODDESTDIR)
#xz -9 $(MODULE_NAME).ko
#install -p -m 644 $(MODULE_NAME).ko.xz $(MODDESTDIR)
install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR)
/sbin/depmod -a ${KVER}

uninstall:
Expand Down
51 changes: 20 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,38 @@
# aerofnkeys
Custom HID Quirks Driver that fixes function keys not working in the Gigabyte Aero 15 SB on Linux.
Custom HID Quirks Driver that fixes function keys not working in the Gigabyte Aero 15 SB & D-series on Linux.

Works by intercepting non-HID compliant usages raw and emulating the correct keycode presses.
Works by intercepting non-HID compliant usages raw and emulating the correct keycode presses because Gigabyte is stupid.

## Notes

- Compatible with the Chu Yuen Keyboard for the Gigabyte Aero 15 SB (Vendor ID: ID 1044, Product ID: 7A3B).
- Compatible with the Chu Yuen Keyboard for the Gigabyte Aero 15 SB (Vendor ID: ID 1044, Product ID: 7A3B) and the Aero 15 D series (Chu Yuen 1044:7A3D).
- To check compatibility run `lsusb`, find your keyboard and compare the ID values with the ones stated above.
- At the moment I've managed to get only the brightness keys to work on my system *(Fedora 34; Kernel 5.13.12; Gnome 40.4)*. I am investigating why the wifi and touchpad toggle keys are not working.

- Make sure you have the kernel headers installed for the kernel version your PC is running. To see if already installed on Arch/Manjaro run `pacman -Q linux-headers`.

# How to Install

1. `git clone https://github.com/jaytohe/aerofnkeys.git`
2. `cd aerofnkeys`
3. `make`
4. `sudo make install`

To load the module manually do :`sudo modprobe fn_keys_mod`

To load the module automatically on startup you need to edit the GRUB bootloader configuration file and specify a parameter for the usbhid kernel module.

To do that :
1. `sudo nano /etc/default/grub`
2. Find the GRUB_CMDLINE_LINUX entry.
3. Append the following kernel parameter at the end of said entry's line :
4. `usbhid.quirks=0x1044:0x7a3b:0x0000`
5. Ctrl+O and CTRL+X to save and quit nano.
6. If on Ubuntu run : `update-grub` else:
7. `grub-mkconfig -o /boot/grub/grub.cfg`
9. Done! Reboot and check if the fn brightness keys work.
## Recommended DKMS Method
1. `git clone https://github.com/atomspring/aerofnkeys.git /usr/src/aerofnkeys-1.0`
2. `dkms add aerofnkeys/1.0`
3. `dkms install aerofnkeys/1.0`
4. `echo aerofnkeys > /etc/modules-load.d/load_aerofnkeys.conf`
5. Reboot & give your backlight keys a go. Enjoy!

If not, undo the changes to /etc/default/grub and run grub-mkconfig again. Afterwards, do:

`echo fn_keys_mod>/etc/modules-load.d/load_fn_keys_mod.conf`

This should manually load the fn_keys_mod module on boot without the use of usbhid. Reboot and check.

# How to survive kernel updates

The steps above will install and enable the module only for the currently running kernel version. If the kernel is updated, the module will need to be re-compiled.
## Manual method
1. `git clone https://github.com/atomspring/aerofnkeys.git /usr/src/aerofnkeys-1.0`
2. `cd /usr/src/aerofnkeys-1.0`
3. `make`
4. `make install`

To avoid the hassle, you can use the [Dynamic Kernel Module Support (DKMS)](https://en.wikipedia.org/wiki/Dynamic_Kernel_Module_Support) to automatically rebuild when a kernel update occurs.
# Troubleshooting

I recommend following [this guide](https://wiki.centos.org/HowTos/BuildingKernelModules#Building_a_kernel_module_using_Dynamic_Kernel_Module_Support_.28DKMS.29).
If you get an error message when running `modprobe aerofnkeys` which says something along the lines of "exec format error", try clearing out the DKMS built module by running:
1. `dkms remove aerofnkeys/1.0 -k $(uname -r)`
2. `dkms install aerofnkeys/1.0 -k $(uname -r)`
3. `modprobe -v aerofnkeys`

Inspect the module by running `modinfo` or `file` about the specific kernel's build of aerofnkeys.

69 changes: 69 additions & 0 deletions aerofnkeys.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <linux/module.h>
#include <linux/input.h>
#include <linux/hid.h>
#include "hid-ids.h"

#define SEND_KEY(c) send_key( ((report->field)[0])->hidinput->input, (c));


static void send_key(struct input_dev *inputd, unsigned int keycode) { //emulate keyboard single key press and release.
input_report_key(inputd, keycode, 1);
input_sync(inputd);
input_report_key(inputd, keycode, 0);
input_sync(inputd);
}

static int gigabyte_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
{

if(unlikely(report->id == 4 && size == 4)) { //if report comes from vendor usage page
switch(data[3]) {
/*
* All FN-keys (except vol_up, vol_down, vol_mute) send only key presses and no key releases.
* We simulate an instaneous key press and release at the cost of the ability to handle long-press of a key.
*/
case 0x7c:
SEND_KEY(KEY_WLAN); //TODO: Fix not working for me (running Gnome 40 and kernel 5.13).
break;
case 0x7d:
SEND_KEY(KEY_BRIGHTNESSDOWN);
break;
case 0x7e:
SEND_KEY(KEY_BRIGHTNESSUP);
break;
case 0x81:
SEND_KEY(KEY_TOUCHPAD_TOGGLE); //TODO: Fix not working for me (running Gnome 40 and kernel 5.13).
break;

//TODO: Add support for remaining non-working fn-keys keys.
}
}

return 0;
}




static const struct hid_device_id gigabyte_devices[] = {
//binding to HID_GROUP_GENERIC to let hid-multitouch.c handle the touchpad and trackpoint.
{.bus=BUS_USB, .group=HID_GROUP_GENERIC, .vendor=USB_VENDOR_ID_CHUYEN, .product=USB_DEVICE_ID_CHUYEN_7A3B},
{.bus=BUS_USB, .group=HID_GROUP_GENERIC, .vendor=USB_VENDOR_ID_CHUYEN, .product=USB_DEVICE_ID_CHUYEN_7A3F}
};
//Array of Structs ; hid_device_id is a struct as well.




static struct hid_driver gigabyte_hid_driver = {
.name = "gigabyte",
.id_table = gigabyte_devices,
.raw_event=gigabyte_raw_event,

};

module_hid_driver(gigabyte_hid_driver);

MODULE_AUTHOR("Github: jaytohe (+a tiny bit of help from atomspring)");
MODULE_DESCRIPTION("Bare-bones support for Gigabyte Aero 15/17 fn-keys");
MODULE_LICENSE("GPL");
7 changes: 7 additions & 0 deletions dkms.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
PACKAGE_NAME="aerofnkeys"
PACKAGE_VERSION="1.0"
MAKE="'make' -j1 all"
BUILT_MODULE_NAME[0]="aerofnkeys"
DEST_MODULE_LOCATION[0]="/kernel/drivers/hid"
AUTOINSTALL="yes"
POST_BUILD="sign_module.sh"
4 changes: 4 additions & 0 deletions hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#ifndef HID_IDS_H_FILE
#define HID_IDS_H_FILE

//Vendor and Device IDs for Gigabyte Aero 15 D-Series Keyboard
#define USB_VENDOR_ID_CHUYEN 0x1044
#define USB_DEVICE_ID_CHUYEN_7A3F 0x7a3f

//Vendor and Device IDs for Gigabyte Aero 15 SB Keyboard
#define USB_VENDOR_ID_CHUYEN 0x1044
#define USB_DEVICE_ID_CHUYEN_7A3B 0x7a3b
Expand Down
26 changes: 26 additions & 0 deletions sign_module.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash -
### NAME
### sign_module.sh
###
### SYNOPSIS
### sign_module.sh [options]
###
### DESCRIPTION
###
### REQUIREMENTS
###
### AUTHOR
### Ding-Yi Chen (definite), dingyichen@gmail.com
### Created in 2019-02-26 11:01:11
###
set -eu # Exit when returns non-zero, Error when variable is unset.
LOGGER_TAG=dkms-sign
KEY_DIR=/var/lib/shim-signed/mok
MODULE_NAME=$(sed -n -e '/PACKAGE_NAME/ s/.*=//p' dkms.conf)
: ${PACKAGE_VERSION:=$(sed -n -e '/PACKAGE_VERSION/ s/.*=//p' dkms.conf)}
: ${KERNEL_RELEASE:=$(uname -r)}
KO_FILE=$(echo /var/lib/dkms/$MODULE_NAME/$PACKAGE_VERSION/$KERNEL_RELEASE/x86_64/module/$MODULE_NAME.ko | tr -d '"')
xz -d $KO_FILE.xz
#/usr/src/kernels/$KERNEL_RELEASE/scripts/sign-file sha512 $KEY_DIR/MOK.priv $KEY_DIR/MOK.der $KO_FILE
kmodsign sha512 $KEY_DIR/MOK.priv $KEY_DIR/MOK.der $KO_FILE
xz -z $KO_FILE