diff mbox

HID: asus: add support for hotkeys

Message ID 1462985167-8566-1-git-send-email-usk.fujimaki@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yusuke Fujimaki May 11, 2016, 4:46 p.m. UTC
Asus X205TA and E200HA keyboard hotkeys (excluding volume control) sends vendor specific usage id.
This patch add input mapping to support such hotkeys.

Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
---
 drivers/hid/hid-asus.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Comments

Dmitry Torokhov May 11, 2016, 10:07 p.m. UTC | #1
Hi Yusuke,

On Wed, May 11, 2016 at 9:46 AM, Yusuke Fujimaki <usk.fujimaki@gmail.com> wrote:
> Asus X205TA and E200HA keyboard hotkeys (excluding volume control) sends vendor specific usage id.
> This patch add input mapping to support such hotkeys.
>
> Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>

Can this be done via udev keymaps/hwdb instead of kernel driver?

> ---
>  drivers/hid/hid-asus.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>
> diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> index 7a811ec..a71f90c 100644
> --- a/drivers/hid/hid-asus.c
> +++ b/drivers/hid/hid-asus.c
> @@ -26,6 +26,10 @@
>
>  #include "hid-ids.h"
>
> +#define HID_UP_ASUSVENDOR      0xff310000
> +#define asus_map_key_clear(c)  hid_map_usage_clear(hi, usage, bit, max, \
> +                                       EV_KEY, (c))
> +
>  static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
>                 unsigned int *rsize)
>  {
> @@ -36,6 +40,26 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
>         return rdesc;
>  }
>
> +static int asus_input_mapping(struct hid_device *hdev, struct hid_input *hi,
> +               struct hid_field *field, struct hid_usage *usage,
> +               unsigned long **bit, int *max)
> +{
> +       if ((usage->hid & HID_USAGE_PAGE) != HID_UP_ASUSVENDOR)
> +               return 0;
> +
> +       switch (usage->hid & HID_USAGE) {
> +       case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN);      break;
> +       case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP);        break;
> +       case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF);         break;
> +       case 0x6b: asus_map_key_clear(KEY_TOUCHPAD_TOGGLE);     break;
> +       case 0x6c: asus_map_key_clear(KEY_SLEEP);               break;
> +       case 0x88: asus_map_key_clear(KEY_RFKILL);              break;
> +       default:
> +               return 0;
> +       }
> +       return 1;
> +}
> +
>  static const struct hid_device_id asus_devices[] = {
>         { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD) },
>         { }
> @@ -45,6 +69,7 @@ MODULE_DEVICE_TABLE(hid, asus_devices);
>  static struct hid_driver asus_driver = {
>         .name = "asus",
>         .id_table = asus_devices,
> +       .input_mapping = asus_input_mapping,
>         .report_fixup = asus_report_fixup
>  };
>  module_hid_driver(asus_driver);
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yusuke Fujimaki May 12, 2016, 6:10 p.m. UTC | #2
Hi Dmitry,

> Can this be done via udev keymaps/hwdb instead of kernel driver?
I couldn't remap hotkeys.
evtest command output is below.

Fn+F1(sleep)
Event: time 1463068038.605052, type 3 (EV_ABS), code 40 (ABS_MISC), value 0
Event: time 1463068038.605052, -------------- EV_SYN ------------
Event: time 1463068038.669030, type 3 (EV_ABS), code 40 (ABS_MISC), value 1
Event: time 1463068038.669030, -------------- EV_SYN ------------

Fn+F2(Airplane mode)
Event: time 1463068094.753052, type 3 (EV_ABS), code 40 (ABS_MISC), value 0
Event: time 1463068094.753052, -------------- EV_SYN ------------
Event: time 1463068094.805040, type 3 (EV_ABS), code 40 (ABS_MISC), value 1
Event: time 1463068094.805040, -------------- EV_SYN ------------

Fn+F5(Display Brightness Down)
Event: time 1463068127.261051, type 3 (EV_ABS), code 40 (ABS_MISC), value 0
Event: time 1463068127.261051, type 3 (EV_ABS), code 56
(ABS_MT_BLOB_ID), value 1
Event: time 1463068127.261051, -------------- EV_SYN ------------
Event: time 1463068127.313042, type 3 (EV_ABS), code 56
(ABS_MT_BLOB_ID), value 0
Event: time 1463068127.313042, type 3 (EV_ABS), code 40 (ABS_MISC), value 1
Event: time 1463068127.313042, -------------- EV_SYN ------------

Fn+F6(Display Brightness Up)
Event: time 1463068227.209051, type 3 (EV_ABS), code 40 (ABS_MISC), value 0
Event: time 1463068227.209051, -------------- EV_SYN ------------
Event: time 1463068227.277042, type 3 (EV_ABS), code 40 (ABS_MISC), value 1
Event: time 1463068227.277042, -------------- EV_SYN ------------

Fn+F7(Display Power Off)
Event: time 1463068227.209051, type 3 (EV_ABS), code 40 (ABS_MISC), value 0
Event: time 1463068227.209051, -------------- EV_SYN ------------
Event: time 1463068227.277042, type 3 (EV_ABS), code 40 (ABS_MISC), value 1
Event: time 1463068227.277042, -------------- EV_SYN ------------

Fn+F9 (Touchpad toggle)
Event: time 1463068441.937052, type 3 (EV_ABS), code 40 (ABS_MISC), value 0
Event: time 1463068441.937052, -------------- EV_SYN ------------
Event: time 1463068441.989049, type 3 (EV_ABS), code 40 (ABS_MISC), value 1
Event: time 1463068441.989049, -------------- EV_SYN ------------

Below volume control hotkeys work out of the box.

Fn+F10 (Mute)
Event: time 1463068508.229058, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e2
Event: time 1463068508.229058, type 1 (EV_KEY), code 113 (KEY_MUTE), value 1
Event: time 1463068508.229058, -------------- EV_SYN ------------
Event: time 1463068508.281048, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e2
Event: time 1463068508.281048, type 1 (EV_KEY), code 113 (KEY_MUTE), value 0
Event: time 1463068508.281048, -------------- EV_SYN ------------

Fn+F11(Volume Down)
Event: time 1463068543.501053, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00ea
Event: time 1463068543.501053, type 1 (EV_KEY), code 114
(KEY_VOLUMEDOWN), value 1
Event: time 1463068543.501053, -------------- EV_SYN ------------
Event: time 1463068543.565055, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00ea
Event: time 1463068543.565055, type 1 (EV_KEY), code 114
(KEY_VOLUMEDOWN), value 0
Event: time 1463068543.565055, -------------- EV_SYN ------------

Fn+F12(Volume Up)
Event: time 1463068575.305053, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1463068575.305053, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 1
Event: time 1463068575.305053, -------------- EV_SYN ------------
Event: time 1463068575.345093, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1463068575.345093, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 0
Event: time 1463068575.345093, -------------- EV_SYN ------------

If there is any method to remap above hotkeys via udev,please tell me.

Best regards.
Jiri Kosina May 12, 2016, 8:28 p.m. UTC | #3
On Fri, 13 May 2016, Yusuke FUJIMAKI wrote:

> Hi Dmitry,
> 
> > Can this be done via udev keymaps/hwdb instead of kernel driver?
> I couldn't remap hotkeys.

How exactly did you invike setkeycodes and how did that change evtest 
output?
Yusuke Fujimaki May 17, 2016, 6:01 p.m. UTC | #4
Hi Jiri,

When i press hotkey (excluding volume control) on vanilla kernel, no
output from "showkey -s".
therefore i can't run setkeycodes.

Best regards.

2016-05-13 5:28 GMT+09:00 Jiri Kosina <jikos@kernel.org>:
> On Fri, 13 May 2016, Yusuke FUJIMAKI wrote:
>
>> Hi Dmitry,
>>
>> > Can this be done via udev keymaps/hwdb instead of kernel driver?
>> I couldn't remap hotkeys.
>
> How exactly did you invike setkeycodes and how did that change evtest
> output?
>
> --
> Jiri Kosina
> SUSE Labs
>
diff mbox

Patch

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 7a811ec..a71f90c 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -26,6 +26,10 @@ 
 
 #include "hid-ids.h"
 
+#define HID_UP_ASUSVENDOR	0xff310000
+#define asus_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, max, \
+					EV_KEY, (c))
+
 static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int *rsize)
 {
@@ -36,6 +40,26 @@  static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 	return rdesc;
 }
 
+static int asus_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_ASUSVENDOR)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+	case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN);	break;
+	case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP);	break;
+	case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF);		break;
+	case 0x6b: asus_map_key_clear(KEY_TOUCHPAD_TOGGLE);	break;
+	case 0x6c: asus_map_key_clear(KEY_SLEEP);		break;
+	case 0x88: asus_map_key_clear(KEY_RFKILL);		break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+
 static const struct hid_device_id asus_devices[] = {
 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD) },
 	{ }
@@ -45,6 +69,7 @@  MODULE_DEVICE_TABLE(hid, asus_devices);
 static struct hid_driver asus_driver = {
 	.name = "asus",
 	.id_table = asus_devices,
+	.input_mapping = asus_input_mapping,
 	.report_fixup = asus_report_fixup
 };
 module_hid_driver(asus_driver);