commit
ccc68cbf7c
@ -0,0 +1,48 @@
|
||||
# Comment/uncomment the following line to disable/enable debugging
|
||||
# DEBUG = y
|
||||
MODULE_NAME = hid-acer-one
|
||||
KVER = $(shell uname -r)
|
||||
MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/hid/
|
||||
|
||||
# Add your debugging flag (or not) to CFLAGS
|
||||
ifeq ($(DEBUG),y)
|
||||
DEBFLAGS = -O -g -DSHORT_DEBUG # "-O" is needed to expand inlines
|
||||
else
|
||||
DEBFLAGS = -O2
|
||||
endif
|
||||
|
||||
ccflags-y += $(DEBFLAGS)
|
||||
|
||||
ifneq ($(KERNELRELEASE),)
|
||||
# call from kernel build system
|
||||
|
||||
obj-m := hid-acer-one.o
|
||||
|
||||
else
|
||||
|
||||
KERNELDIR ?= /lib/modules/$(KVER)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
default:
|
||||
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
|
||||
|
||||
endif
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
|
||||
|
||||
depend .depend dep:
|
||||
$(CC) $(CFLAGS) -M *.c > .depend
|
||||
|
||||
install:
|
||||
install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR)
|
||||
/sbin/depmod -a ${KVER}
|
||||
|
||||
uninstall:
|
||||
rm -f $(MODDESTDIR)/$(MODULE_NAME).ko
|
||||
/sbin/depmod -a ${KVER}
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
||||
@ -0,0 +1,30 @@
|
||||
# Overview of the error
|
||||
Some Acer keyboards report excessively large max usage values. This causes an error at boot which leaves the keyboard inoperable; since the max use values in the report descriptor exceed HID_MAX_USAGES the descriptor isn't parsed.
|
||||
|
||||
This module simply changes the report descriptor to have more sensible max usage values during boot before passing the edited version up to the generic hid module for parsing.
|
||||
|
||||
##### Known keyboards with this issue
|
||||
* `06CB:73F4` (This is the only one targeted by this fix at present)
|
||||
* `06CB:2968`
|
||||
* `06CB:2991`
|
||||
|
||||
This module specifically targets keyboards identifying themsleves as ` 06CB:73F4 `. If your device identifies itself as `06CB:2968` or `06CB:2991` they should work OOTB on Linux Kernels version 4.3 and above, for older kernels the fix (which this module was adapted from) can be found [here](https://github.com/SWW13/hid-acer).
|
||||
|
||||
#### Symptoms of the error
|
||||
|
||||
Symptoms that this might be a problem you are experiencing is a message along the lines of `hid (null): usage index exceeded` followed by hid-generic complaining that `parsing failed` in your dmesg logs.
|
||||
|
||||
## Build / Install
|
||||
First install linux-headers for your version of Linux, some details can be found [here](http://www.cyberciti.biz/tips/build-linux-kernel-module-against-installed-kernel-source-tree.html).
|
||||
|
||||
```
|
||||
git clone https://github.com/BradyMcD/hid-acer-one.git
|
||||
cd hid-acer-one
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
#### Uninstall
|
||||
```
|
||||
sudo make uninstall
|
||||
```
|
||||
@ -0,0 +1,7 @@
|
||||
#ifndef ACER_HIDS
|
||||
#define ACER_HIDS
|
||||
|
||||
#define USB_VENDOR_ID_ACER_SYNAPTICS 0x06cb
|
||||
#define USB_VENDOR_ID_ACER_SYNAPTICS_TP_73F4 0x73F4
|
||||
|
||||
#endif//ACER_HIDS
|
||||
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* HID driver for acer devices
|
||||
*
|
||||
* Copyright (c) 2016 Brady McDonough
|
||||
* Modified from Simon Wörner's hid-acer <https://github.com/SWW13/hid-acer>
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "acer-hids.h"
|
||||
|
||||
/* Some Acer keyboards have an issue where they report an excessive max usages value
|
||||
* The kyboard targeted in this fix identifies itself as 06CB:73F4
|
||||
*
|
||||
* At boot this module pre-parses the report descriptor and changes the values so that they will parse properly
|
||||
*/
|
||||
|
||||
#define ACER_KBD_RDESC_ORIG_SIZE 188
|
||||
#define ACER_KBD_RDESC_CHECK_POS (173 * sizeof(__u8))
|
||||
#define ACER_KBD_RDESC_CHECK_DATA 0x2AFFFF150026FFFF
|
||||
#define ACER_KBD_RDESC_FIX_POS1 ACER_KBD_RDESC_CHECK_POS + 2
|
||||
#define ACER_KBD_RDESC_FIX_POS2 ACER_KBD_RDESC_CHECK_POS + 7
|
||||
|
||||
static __u8 *acer_kbd_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize){
|
||||
|
||||
/* Check that we are looking at the same correct descirptor */
|
||||
if (*rsize == ACER_KBD_RDESC_ORIG_SIZE) {
|
||||
__u64 check = be64_to_cpu(*(__be64 *)(rdesc + ACER_KBD_RDESC_CHECK_POS));
|
||||
|
||||
/* check for invalid max usages */
|
||||
if (check == ACER_KBD_RDESC_CHECK_DATA) {
|
||||
hid_info(hdev, "fixing up acer keyboard report descriptor\n");
|
||||
|
||||
/* change max values to 0xFF00 */
|
||||
rdesc[ACER_KBD_RDESC_FIX_POS1] = 0x00;
|
||||
rdesc[ACER_KBD_RDESC_FIX_POS2] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
return rdesc;
|
||||
}
|
||||
|
||||
static const struct hid_device_id acer_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ACER_SYNAPTICS,
|
||||
USB_VENDOR_ID_ACER_SYNAPTICS_TP_73F4) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, acer_devices);
|
||||
|
||||
static struct hid_driver acer_driver = {
|
||||
.name = "acer",
|
||||
.id_table = acer_devices,
|
||||
.report_fixup = acer_kbd_report_fixup,
|
||||
};
|
||||
module_hid_driver(acer_driver);
|
||||
|
||||
MODULE_AUTHOR("Brady McDonough");
|
||||
MODULE_LICENSE("GPL");
|
||||
Loading…
Reference in new issue