HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
/*
2016-04-03 17:15:16 +03:00
* HID driver for Asus notebook built - in keyboard .
HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
* Fixes small logical maximum to match usage maximum .
*
2016-04-03 17:15:16 +03:00
* Currently supported devices are :
* EeeBook X205TA
* VivoBook E200HA
*
HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
* Copyright ( c ) 2016 Yusuke Fujimaki < usk . fujimaki @ gmail . com >
*
* This module based on hid - ortek by
* Copyright ( c ) 2010 Johnathon Harris < jmharris @ gmail . com >
* Copyright ( c ) 2011 Jiri Kosina
2016-11-29 10:59:25 +03:00
*
* This module has been updated to add support for Asus i2c touchpad .
*
* Copyright ( c ) 2016 Brendan McGrath < redmcg @ redmandi . dyndns . org >
* Copyright ( c ) 2016 Victor Vlasenko < victor . vlasenko @ sysgears . com >
* Copyright ( c ) 2016 Frederik Wenigwieser < frederik . wenigwieser @ gmail . com >
HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
*/
/*
* 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/hid.h>
# include <linux/module.h>
2016-11-29 10:59:25 +03:00
# include <linux/input/mt.h>
2017-05-25 17:49:21 +03:00
# include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */
HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
# include "hid-ids.h"
2016-11-29 10:59:25 +03:00
MODULE_AUTHOR ( " Yusuke Fujimaki <usk.fujimaki@gmail.com> " ) ;
MODULE_AUTHOR ( " Brendan McGrath <redmcg@redmandi.dyndns.org> " ) ;
MODULE_AUTHOR ( " Victor Vlasenko <victor.vlasenko@sysgears.com> " ) ;
MODULE_AUTHOR ( " Frederik Wenigwieser <frederik.wenigwieser@gmail.com> " ) ;
MODULE_DESCRIPTION ( " Asus HID Keyboard and TouchPad " ) ;
2017-05-25 17:49:21 +03:00
# define T100_TPAD_INTF 2
2017-08-04 16:31:04 +03:00
# define T100CHI_MOUSE_REPORT_ID 0x06
2016-11-29 10:59:25 +03:00
# define FEATURE_REPORT_ID 0x0d
# define INPUT_REPORT_ID 0x5d
2017-04-06 13:18:17 +03:00
# define FEATURE_KBD_REPORT_ID 0x5a
# define FEATURE_KBD_REPORT_SIZE 16
# define SUPPORT_KBD_BACKLIGHT BIT(0)
2016-11-29 10:59:25 +03:00
# define MAX_TOUCH_MAJOR 8
# define MAX_PRESSURE 128
# define BTN_LEFT_MASK 0x01
# define CONTACT_TOOL_TYPE_MASK 0x80
# define CONTACT_X_MSB_MASK 0xf0
# define CONTACT_Y_MSB_MASK 0x0f
# define CONTACT_TOUCH_MAJOR_MASK 0x07
# define CONTACT_PRESSURE_MASK 0x7f
# define QUIRK_FIX_NOTEBOOK_REPORT BIT(0)
# define QUIRK_NO_INIT_REPORTS BIT(1)
# define QUIRK_SKIP_INPUT_MAPPING BIT(2)
# define QUIRK_IS_MULTITOUCH BIT(3)
2017-03-09 02:31:14 +03:00
# define QUIRK_NO_CONSUMER_USAGES BIT(4)
2017-04-06 13:18:17 +03:00
# define QUIRK_USE_KBD_BACKLIGHT BIT(5)
2017-05-15 10:31:41 +03:00
# define QUIRK_T100_KEYBOARD BIT(6)
2017-07-02 17:34:15 +03:00
# define QUIRK_T100CHI BIT(7)
2016-11-29 10:59:25 +03:00
2017-03-09 02:31:13 +03:00
# define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
2017-03-09 02:31:14 +03:00
QUIRK_NO_INIT_REPORTS | \
QUIRK_NO_CONSUMER_USAGES )
2017-07-02 17:34:12 +03:00
# define I2C_TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \
2016-11-29 10:59:25 +03:00
QUIRK_SKIP_INPUT_MAPPING | \
QUIRK_IS_MULTITOUCH )
# define TRKID_SGN ((TRKID_MAX + 1) >> 1)
2017-04-06 13:18:17 +03:00
struct asus_kbd_leds {
struct led_classdev cdev ;
struct hid_device * hdev ;
struct work_struct work ;
unsigned int brightness ;
bool removed ;
} ;
2017-07-02 17:34:12 +03:00
struct asus_touchpad_info {
int max_x ;
int max_y ;
2017-07-02 17:34:14 +03:00
int res_x ;
int res_y ;
2017-07-02 17:34:12 +03:00
int contact_size ;
int max_contacts ;
} ;
2016-11-29 10:59:25 +03:00
struct asus_drvdata {
unsigned long quirks ;
struct input_dev * input ;
2017-04-06 13:18:17 +03:00
struct asus_kbd_leds * kbd_backlight ;
2017-07-02 17:34:12 +03:00
const struct asus_touchpad_info * tp ;
2017-04-06 13:18:17 +03:00
bool enable_backlight ;
2016-11-29 10:59:25 +03:00
} ;
2017-07-02 17:34:12 +03:00
static const struct asus_touchpad_info asus_i2c_tp = {
. max_x = 2794 ,
. max_y = 1758 ,
. contact_size = 5 ,
. max_contacts = 5 ,
} ;
static const struct asus_touchpad_info asus_t100ta_tp = {
. max_x = 2240 ,
2017-07-02 17:34:13 +03:00
. max_y = 1120 ,
2017-07-02 17:34:14 +03:00
. res_x = 30 , /* units/mm */
. res_y = 27 , /* units/mm */
2017-07-02 17:34:12 +03:00
. contact_size = 5 ,
. max_contacts = 5 ,
} ;
2017-08-04 16:31:04 +03:00
static const struct asus_touchpad_info asus_t100chi_tp = {
. max_x = 2640 ,
. max_y = 1320 ,
. res_x = 31 , /* units/mm */
. res_y = 29 , /* units/mm */
. contact_size = 3 ,
. max_contacts = 4 ,
} ;
2017-07-02 17:34:12 +03:00
static void asus_report_contact_down ( struct asus_drvdata * drvdat ,
2016-11-29 10:59:25 +03:00
int toolType , u8 * data )
{
2017-07-02 17:34:12 +03:00
struct input_dev * input = drvdat - > input ;
int touch_major , pressure , x , y ;
x = ( data [ 0 ] & CONTACT_X_MSB_MASK ) < < 4 | data [ 1 ] ;
y = drvdat - > tp - > max_y - ( ( data [ 0 ] & CONTACT_Y_MSB_MASK ) < < 8 | data [ 2 ] ) ;
2016-11-29 10:59:25 +03:00
2017-08-04 16:31:04 +03:00
input_report_abs ( input , ABS_MT_POSITION_X , x ) ;
input_report_abs ( input , ABS_MT_POSITION_Y , y ) ;
if ( drvdat - > tp - > contact_size < 5 )
return ;
2016-11-29 10:59:25 +03:00
if ( toolType = = MT_TOOL_PALM ) {
touch_major = MAX_TOUCH_MAJOR ;
pressure = MAX_PRESSURE ;
} else {
touch_major = ( data [ 3 ] > > 4 ) & CONTACT_TOUCH_MAJOR_MASK ;
pressure = data [ 4 ] & CONTACT_PRESSURE_MASK ;
}
input_report_abs ( input , ABS_MT_TOUCH_MAJOR , touch_major ) ;
input_report_abs ( input , ABS_MT_PRESSURE , pressure ) ;
}
/* Required for Synaptics Palm Detection */
2017-07-02 17:34:12 +03:00
static void asus_report_tool_width ( struct asus_drvdata * drvdat )
2016-11-29 10:59:25 +03:00
{
2017-07-02 17:34:12 +03:00
struct input_mt * mt = drvdat - > input - > mt ;
2016-11-29 10:59:25 +03:00
struct input_mt_slot * oldest ;
int oldid , count , i ;
2017-08-04 16:31:04 +03:00
if ( drvdat - > tp - > contact_size < 5 )
return ;
2016-11-29 10:59:25 +03:00
oldest = NULL ;
oldid = mt - > trkid ;
count = 0 ;
for ( i = 0 ; i < mt - > num_slots ; + + i ) {
struct input_mt_slot * ps = & mt - > slots [ i ] ;
int id = input_mt_get_value ( ps , ABS_MT_TRACKING_ID ) ;
if ( id < 0 )
continue ;
if ( ( id - oldid ) & TRKID_SGN ) {
oldest = ps ;
oldid = id ;
}
count + + ;
}
if ( oldest ) {
2017-07-02 17:34:12 +03:00
input_report_abs ( drvdat - > input , ABS_TOOL_WIDTH ,
2016-11-29 10:59:25 +03:00
input_mt_get_value ( oldest , ABS_MT_TOUCH_MAJOR ) ) ;
}
}
2017-07-02 17:34:12 +03:00
static int asus_report_input ( struct asus_drvdata * drvdat , u8 * data , int size )
2016-11-29 10:59:25 +03:00
{
2017-08-04 16:31:04 +03:00
int i , toolType = MT_TOOL_FINGER ;
2016-11-29 10:59:25 +03:00
u8 * contactData = data + 2 ;
2017-07-02 17:34:12 +03:00
if ( size ! = 3 + drvdat - > tp - > contact_size * drvdat - > tp - > max_contacts )
return 0 ;
for ( i = 0 ; i < drvdat - > tp - > max_contacts ; i + + ) {
2016-11-29 10:59:25 +03:00
bool down = ! ! ( data [ 1 ] & BIT ( i + 3 ) ) ;
2017-08-04 16:31:04 +03:00
if ( drvdat - > tp - > contact_size > = 5 )
toolType = contactData [ 3 ] & CONTACT_TOOL_TYPE_MASK ?
2016-11-29 10:59:25 +03:00
MT_TOOL_PALM : MT_TOOL_FINGER ;
2017-07-02 17:34:12 +03:00
input_mt_slot ( drvdat - > input , i ) ;
input_mt_report_slot_state ( drvdat - > input , toolType , down ) ;
2016-11-29 10:59:25 +03:00
if ( down ) {
2017-07-02 17:34:12 +03:00
asus_report_contact_down ( drvdat , toolType , contactData ) ;
contactData + = drvdat - > tp - > contact_size ;
2016-11-29 10:59:25 +03:00
}
}
2017-07-02 17:34:12 +03:00
input_report_key ( drvdat - > input , BTN_LEFT , data [ 1 ] & BTN_LEFT_MASK ) ;
asus_report_tool_width ( drvdat ) ;
input_mt_sync_frame ( drvdat - > input ) ;
input_sync ( drvdat - > input ) ;
2016-11-29 10:59:25 +03:00
2017-07-02 17:34:12 +03:00
return 1 ;
2016-11-29 10:59:25 +03:00
}
static int asus_raw_event ( struct hid_device * hdev ,
struct hid_report * report , u8 * data , int size )
{
struct asus_drvdata * drvdata = hid_get_drvdata ( hdev ) ;
2017-07-02 17:34:12 +03:00
if ( drvdata - > tp & & data [ 0 ] = = INPUT_REPORT_ID )
return asus_report_input ( drvdata , data , size ) ;
2016-11-29 10:59:25 +03:00
return 0 ;
}
2017-04-06 13:18:17 +03:00
static int asus_kbd_set_report ( struct hid_device * hdev , u8 * buf , size_t buf_size )
{
unsigned char * dmabuf ;
int ret ;
dmabuf = kmemdup ( buf , buf_size , GFP_KERNEL ) ;
if ( ! dmabuf )
return - ENOMEM ;
ret = hid_hw_raw_request ( hdev , FEATURE_KBD_REPORT_ID , dmabuf ,
buf_size , HID_FEATURE_REPORT ,
HID_REQ_SET_REPORT ) ;
kfree ( dmabuf ) ;
return ret ;
}
static int asus_kbd_init ( struct hid_device * hdev )
{
u8 buf [ ] = { FEATURE_KBD_REPORT_ID , 0x41 , 0x53 , 0x55 , 0x53 , 0x20 , 0x54 ,
0x65 , 0x63 , 0x68 , 0x2e , 0x49 , 0x6e , 0x63 , 0x2e , 0x00 } ;
int ret ;
ret = asus_kbd_set_report ( hdev , buf , sizeof ( buf ) ) ;
if ( ret < 0 )
hid_err ( hdev , " Asus failed to send init command: %d \n " , ret ) ;
return ret ;
}
static int asus_kbd_get_functions ( struct hid_device * hdev ,
unsigned char * kbd_func )
{
u8 buf [ ] = { FEATURE_KBD_REPORT_ID , 0x05 , 0x20 , 0x31 , 0x00 , 0x08 } ;
u8 * readbuf ;
int ret ;
ret = asus_kbd_set_report ( hdev , buf , sizeof ( buf ) ) ;
if ( ret < 0 ) {
hid_err ( hdev , " Asus failed to send configuration command: %d \n " , ret ) ;
return ret ;
}
readbuf = kzalloc ( FEATURE_KBD_REPORT_SIZE , GFP_KERNEL ) ;
if ( ! readbuf )
return - ENOMEM ;
ret = hid_hw_raw_request ( hdev , FEATURE_KBD_REPORT_ID , readbuf ,
FEATURE_KBD_REPORT_SIZE , HID_FEATURE_REPORT ,
HID_REQ_GET_REPORT ) ;
if ( ret < 0 ) {
hid_err ( hdev , " Asus failed to request functions: %d \n " , ret ) ;
kfree ( readbuf ) ;
return ret ;
}
* kbd_func = readbuf [ 6 ] ;
kfree ( readbuf ) ;
return ret ;
}
static void asus_kbd_backlight_set ( struct led_classdev * led_cdev ,
enum led_brightness brightness )
{
struct asus_kbd_leds * led = container_of ( led_cdev , struct asus_kbd_leds ,
cdev ) ;
if ( led - > brightness = = brightness )
return ;
led - > brightness = brightness ;
schedule_work ( & led - > work ) ;
}
static enum led_brightness asus_kbd_backlight_get ( struct led_classdev * led_cdev )
{
struct asus_kbd_leds * led = container_of ( led_cdev , struct asus_kbd_leds ,
cdev ) ;
return led - > brightness ;
}
static void asus_kbd_backlight_work ( struct work_struct * work )
{
struct asus_kbd_leds * led = container_of ( work , struct asus_kbd_leds , work ) ;
u8 buf [ ] = { FEATURE_KBD_REPORT_ID , 0xba , 0xc5 , 0xc4 , 0x00 } ;
int ret ;
if ( led - > removed )
return ;
buf [ 4 ] = led - > brightness ;
ret = asus_kbd_set_report ( led - > hdev , buf , sizeof ( buf ) ) ;
if ( ret < 0 )
hid_err ( led - > hdev , " Asus failed to set keyboard backlight: %d \n " , ret ) ;
}
static int asus_kbd_register_leds ( struct hid_device * hdev )
{
struct asus_drvdata * drvdata = hid_get_drvdata ( hdev ) ;
unsigned char kbd_func ;
int ret ;
/* Initialize keyboard */
ret = asus_kbd_init ( hdev ) ;
if ( ret < 0 )
return ret ;
/* Get keyboard functions */
ret = asus_kbd_get_functions ( hdev , & kbd_func ) ;
if ( ret < 0 )
return ret ;
/* Check for backlight support */
if ( ! ( kbd_func & SUPPORT_KBD_BACKLIGHT ) )
return - ENODEV ;
drvdata - > kbd_backlight = devm_kzalloc ( & hdev - > dev ,
sizeof ( struct asus_kbd_leds ) ,
GFP_KERNEL ) ;
if ( ! drvdata - > kbd_backlight )
return - ENOMEM ;
drvdata - > kbd_backlight - > removed = false ;
drvdata - > kbd_backlight - > brightness = 0 ;
drvdata - > kbd_backlight - > hdev = hdev ;
drvdata - > kbd_backlight - > cdev . name = " asus::kbd_backlight " ;
drvdata - > kbd_backlight - > cdev . max_brightness = 3 ;
drvdata - > kbd_backlight - > cdev . brightness_set = asus_kbd_backlight_set ;
drvdata - > kbd_backlight - > cdev . brightness_get = asus_kbd_backlight_get ;
INIT_WORK ( & drvdata - > kbd_backlight - > work , asus_kbd_backlight_work ) ;
ret = devm_led_classdev_register ( & hdev - > dev , & drvdata - > kbd_backlight - > cdev ) ;
if ( ret < 0 ) {
/* No need to have this still around */
devm_kfree ( & hdev - > dev , drvdata - > kbd_backlight ) ;
}
return ret ;
}
2016-11-29 10:59:25 +03:00
static int asus_input_configured ( struct hid_device * hdev , struct hid_input * hi )
{
2016-12-10 13:20:42 +03:00
struct input_dev * input = hi - > input ;
2016-11-29 10:59:25 +03:00
struct asus_drvdata * drvdata = hid_get_drvdata ( hdev ) ;
2017-08-04 16:31:04 +03:00
/* T100CHI uses MULTI_INPUT, bind the touchpad to the mouse hid_input */
if ( drvdata - > quirks & QUIRK_T100CHI & &
hi - > report - > id ! = T100CHI_MOUSE_REPORT_ID )
return 0 ;
2017-07-02 17:34:12 +03:00
if ( drvdata - > tp ) {
2016-11-29 10:59:25 +03:00
int ret ;
2017-07-02 17:34:12 +03:00
input_set_abs_params ( input , ABS_MT_POSITION_X , 0 ,
drvdata - > tp - > max_x , 0 , 0 ) ;
input_set_abs_params ( input , ABS_MT_POSITION_Y , 0 ,
drvdata - > tp - > max_y , 0 , 0 ) ;
2017-07-02 17:34:14 +03:00
input_abs_set_res ( input , ABS_MT_POSITION_X , drvdata - > tp - > res_x ) ;
input_abs_set_res ( input , ABS_MT_POSITION_Y , drvdata - > tp - > res_y ) ;
2017-08-04 16:31:04 +03:00
if ( drvdata - > tp - > contact_size > = 5 ) {
input_set_abs_params ( input , ABS_TOOL_WIDTH , 0 ,
MAX_TOUCH_MAJOR , 0 , 0 ) ;
input_set_abs_params ( input , ABS_MT_TOUCH_MAJOR , 0 ,
MAX_TOUCH_MAJOR , 0 , 0 ) ;
input_set_abs_params ( input , ABS_MT_PRESSURE , 0 ,
MAX_PRESSURE , 0 , 0 ) ;
}
2016-11-29 10:59:25 +03:00
__set_bit ( BTN_LEFT , input - > keybit ) ;
__set_bit ( INPUT_PROP_BUTTONPAD , input - > propbit ) ;
2017-07-02 17:34:12 +03:00
ret = input_mt_init_slots ( input , drvdata - > tp - > max_contacts ,
INPUT_MT_POINTER ) ;
2016-11-29 10:59:25 +03:00
if ( ret ) {
hid_err ( hdev , " Asus input mt init slots failed: %d \n " , ret ) ;
return ret ;
}
}
2016-12-10 13:20:42 +03:00
drvdata - > input = input ;
2017-04-06 13:18:17 +03:00
if ( drvdata - > enable_backlight & & asus_kbd_register_leds ( hdev ) )
hid_warn ( hdev , " Failed to initialize backlight. \n " ) ;
2016-11-29 10:59:25 +03:00
return 0 ;
}
2017-03-09 02:31:13 +03:00
# define asus_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, \
2017-03-02 00:48:51 +03:00
max , EV_KEY , ( c ) )
2016-11-29 10:59:25 +03:00
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 )
{
struct asus_drvdata * drvdata = hid_get_drvdata ( hdev ) ;
if ( drvdata - > quirks & QUIRK_SKIP_INPUT_MAPPING ) {
/* Don't map anything from the HID report.
* We do it all manually in asus_input_configured
*/
return - 1 ;
}
2017-08-04 16:31:04 +03:00
/*
* Ignore a bunch of bogus collections in the T100CHI descriptor .
* This avoids a bunch of non - functional hid_input devices getting
* created because of the T100CHI using HID_QUIRK_MULTI_INPUT .
*/
if ( drvdata - > quirks & QUIRK_T100CHI ) {
if ( field - > application = = ( HID_UP_GENDESK | 0x0080 ) | |
usage - > hid = = ( HID_UP_GENDEVCTRLS | 0x0024 ) | |
usage - > hid = = ( HID_UP_GENDEVCTRLS | 0x0025 ) | |
usage - > hid = = ( HID_UP_GENDEVCTRLS | 0x0026 ) )
return - 1 ;
/*
* We use the hid_input for the mouse report for the touchpad ,
* keep the left button , to avoid the core removing it .
*/
if ( field - > application = = HID_GD_MOUSE & &
usage - > hid ! = ( HID_UP_BUTTON | 1 ) )
return - 1 ;
}
2017-03-09 02:31:13 +03:00
/* ASUS-specific keyboard hotkeys */
2017-03-02 00:48:51 +03:00
if ( ( usage - > hid & HID_USAGE_PAGE ) = = 0xff310000 ) {
set_bit ( EV_REP , hi - > input - > evbit ) ;
switch ( usage - > hid & HID_USAGE ) {
2017-03-09 02:31:13 +03:00
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 0x6c : asus_map_key_clear ( KEY_SLEEP ) ; break ;
case 0x82 : asus_map_key_clear ( KEY_CAMERA ) ; break ;
2017-03-09 02:31:15 +03:00
case 0x88 : asus_map_key_clear ( KEY_RFKILL ) ; break ;
2017-03-09 02:31:13 +03:00
case 0xb5 : asus_map_key_clear ( KEY_CALC ) ; break ;
case 0xc4 : asus_map_key_clear ( KEY_KBDILLUMUP ) ; break ;
case 0xc5 : asus_map_key_clear ( KEY_KBDILLUMDOWN ) ; break ;
2017-03-02 00:48:51 +03:00
/* ASUS touchpad toggle */
2017-03-09 02:31:13 +03:00
case 0x6b : asus_map_key_clear ( KEY_F21 ) ; break ;
2017-03-02 00:48:51 +03:00
/* ROG key */
2017-03-09 02:31:13 +03:00
case 0x38 : asus_map_key_clear ( KEY_PROG1 ) ; break ;
2017-03-02 00:48:51 +03:00
/* Fn+C ASUS Splendid */
2017-03-09 02:31:13 +03:00
case 0xba : asus_map_key_clear ( KEY_PROG2 ) ; break ;
2017-03-02 00:48:51 +03:00
/* Fn+Space Power4Gear Hybrid */
2017-03-09 02:31:13 +03:00
case 0x5c : asus_map_key_clear ( KEY_PROG3 ) ; break ;
2017-03-02 00:48:51 +03:00
default :
2017-03-09 02:31:14 +03:00
/* ASUS lazily declares 256 usages, ignore the rest,
* as some make the keyboard appear as a pointer device . */
return - 1 ;
2017-03-02 00:48:51 +03:00
}
2017-04-06 13:18:17 +03:00
/*
* Check and enable backlight only on devices with UsagePage = =
* 0xff31 to avoid initializing the keyboard firmware multiple
* times on devices with multiple HID descriptors but same
* PID / VID .
*/
if ( drvdata - > quirks & QUIRK_USE_KBD_BACKLIGHT )
drvdata - > enable_backlight = true ;
2017-03-02 00:48:51 +03:00
return 1 ;
}
2017-06-05 23:58:56 +03:00
if ( ( usage - > hid & HID_USAGE_PAGE ) = = HID_UP_MSVENDOR ) {
set_bit ( EV_REP , hi - > input - > evbit ) ;
switch ( usage - > hid & HID_USAGE ) {
case 0xff01 : asus_map_key_clear ( BTN_1 ) ; break ;
case 0xff02 : asus_map_key_clear ( BTN_2 ) ; break ;
case 0xff03 : asus_map_key_clear ( BTN_3 ) ; break ;
case 0xff04 : asus_map_key_clear ( BTN_4 ) ; break ;
case 0xff05 : asus_map_key_clear ( BTN_5 ) ; break ;
case 0xff06 : asus_map_key_clear ( BTN_6 ) ; break ;
case 0xff07 : asus_map_key_clear ( BTN_7 ) ; break ;
case 0xff08 : asus_map_key_clear ( BTN_8 ) ; break ;
case 0xff09 : asus_map_key_clear ( BTN_9 ) ; break ;
case 0xff0a : asus_map_key_clear ( BTN_A ) ; break ;
case 0xff0b : asus_map_key_clear ( BTN_B ) ; break ;
case 0x00f1 : asus_map_key_clear ( KEY_WLAN ) ; break ;
case 0x00f2 : asus_map_key_clear ( KEY_BRIGHTNESSDOWN ) ; break ;
case 0x00f3 : asus_map_key_clear ( KEY_BRIGHTNESSUP ) ; break ;
case 0x00f4 : asus_map_key_clear ( KEY_DISPLAY_OFF ) ; break ;
case 0x00f7 : asus_map_key_clear ( KEY_CAMERA ) ; break ;
case 0x00f8 : asus_map_key_clear ( KEY_PROG1 ) ; break ;
default :
return 0 ;
}
return 1 ;
}
2017-03-09 02:31:14 +03:00
if ( drvdata - > quirks & QUIRK_NO_CONSUMER_USAGES & &
( usage - > hid & HID_USAGE_PAGE ) = = HID_UP_CONSUMER ) {
switch ( usage - > hid & HID_USAGE ) {
case 0xe2 : /* Mute */
case 0xe9 : /* Volume up */
case 0xea : /* Volume down */
return 0 ;
default :
/* Ignore dummy Consumer usages which make the
* keyboard incorrectly appear as a pointer device .
*/
return - 1 ;
}
}
2016-11-29 10:59:25 +03:00
return 0 ;
}
static int asus_start_multitouch ( struct hid_device * hdev )
{
int ret ;
const unsigned char buf [ ] = { FEATURE_REPORT_ID , 0x00 , 0x03 , 0x01 , 0x00 } ;
unsigned char * dmabuf = kmemdup ( buf , sizeof ( buf ) , GFP_KERNEL ) ;
if ( ! dmabuf ) {
ret = - ENOMEM ;
hid_err ( hdev , " Asus failed to alloc dma buf: %d \n " , ret ) ;
return ret ;
}
ret = hid_hw_raw_request ( hdev , dmabuf [ 0 ] , dmabuf , sizeof ( buf ) ,
HID_FEATURE_REPORT , HID_REQ_SET_REPORT ) ;
kfree ( dmabuf ) ;
if ( ret ! = sizeof ( buf ) ) {
hid_err ( hdev , " Asus failed to start multitouch: %d \n " , ret ) ;
return ret ;
}
return 0 ;
}
static int __maybe_unused asus_reset_resume ( struct hid_device * hdev )
{
struct asus_drvdata * drvdata = hid_get_drvdata ( hdev ) ;
2017-07-02 17:34:12 +03:00
if ( drvdata - > tp )
2016-11-29 10:59:25 +03:00
return asus_start_multitouch ( hdev ) ;
return 0 ;
}
static int asus_probe ( struct hid_device * hdev , const struct hid_device_id * id )
{
int ret ;
struct asus_drvdata * drvdata ;
drvdata = devm_kzalloc ( & hdev - > dev , sizeof ( * drvdata ) , GFP_KERNEL ) ;
if ( drvdata = = NULL ) {
hid_err ( hdev , " Can't alloc Asus descriptor \n " ) ;
return - ENOMEM ;
}
hid_set_drvdata ( hdev , drvdata ) ;
drvdata - > quirks = id - > driver_data ;
2017-07-02 17:34:12 +03:00
if ( drvdata - > quirks & QUIRK_IS_MULTITOUCH )
drvdata - > tp = & asus_i2c_tp ;
2017-05-25 17:49:21 +03:00
if ( drvdata - > quirks & QUIRK_T100_KEYBOARD ) {
struct usb_interface * intf = to_usb_interface ( hdev - > dev . parent ) ;
2017-07-02 17:34:12 +03:00
if ( intf - > altsetting - > desc . bInterfaceNumber = = T100_TPAD_INTF ) {
drvdata - > quirks = QUIRK_SKIP_INPUT_MAPPING ;
drvdata - > tp = & asus_t100ta_tp ;
}
2017-05-25 17:49:21 +03:00
}
2017-08-04 16:31:04 +03:00
if ( drvdata - > quirks & QUIRK_T100CHI ) {
/*
* All functionality is on a single HID interface and for
* userspace the touchpad must be a separate input_dev .
*/
hdev - > quirks | = HID_QUIRK_MULTI_INPUT |
HID_QUIRK_NO_EMPTY_INPUT ;
drvdata - > tp = & asus_t100chi_tp ;
}
2016-11-29 10:59:25 +03:00
if ( drvdata - > quirks & QUIRK_NO_INIT_REPORTS )
hdev - > quirks | = HID_QUIRK_NO_INIT_REPORTS ;
ret = hid_parse ( hdev ) ;
if ( ret ) {
hid_err ( hdev , " Asus hid parse failed: %d \n " , ret ) ;
return ret ;
}
ret = hid_hw_start ( hdev , HID_CONNECT_DEFAULT ) ;
if ( ret ) {
hid_err ( hdev , " Asus hw start failed: %d \n " , ret ) ;
return ret ;
}
if ( ! drvdata - > input ) {
hid_err ( hdev , " Asus input not registered \n " ) ;
ret = - ENOMEM ;
goto err_stop_hw ;
}
2017-07-02 17:34:12 +03:00
if ( drvdata - > tp ) {
2016-12-10 13:20:42 +03:00
drvdata - > input - > name = " Asus TouchPad " ;
} else {
drvdata - > input - > name = " Asus Keyboard " ;
}
2016-11-29 10:59:25 +03:00
2017-07-02 17:34:12 +03:00
if ( drvdata - > tp ) {
2016-11-29 10:59:25 +03:00
ret = asus_start_multitouch ( hdev ) ;
if ( ret )
goto err_stop_hw ;
}
return 0 ;
err_stop_hw :
hid_hw_stop ( hdev ) ;
return ret ;
}
2017-04-06 13:18:17 +03:00
static void asus_remove ( struct hid_device * hdev )
{
struct asus_drvdata * drvdata = hid_get_drvdata ( hdev ) ;
if ( drvdata - > kbd_backlight ) {
drvdata - > kbd_backlight - > removed = true ;
cancel_work_sync ( & drvdata - > kbd_backlight - > work ) ;
}
2017-05-30 23:39:46 +03:00
hid_hw_stop ( hdev ) ;
2017-04-06 13:18:17 +03:00
}
HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
static __u8 * asus_report_fixup ( struct hid_device * hdev , __u8 * rdesc ,
unsigned int * rsize )
{
2016-11-29 10:59:25 +03:00
struct asus_drvdata * drvdata = hid_get_drvdata ( hdev ) ;
if ( drvdata - > quirks & QUIRK_FIX_NOTEBOOK_REPORT & &
* rsize > = 56 & & rdesc [ 54 ] = = 0x25 & & rdesc [ 55 ] = = 0x65 ) {
2016-04-03 17:15:16 +03:00
hid_info ( hdev , " Fixing up Asus notebook report descriptor \n " ) ;
HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
rdesc [ 55 ] = 0xdd ;
}
2017-07-02 17:34:15 +03:00
/* For the T100TA keyboard dock */
2017-05-15 10:31:41 +03:00
if ( drvdata - > quirks & QUIRK_T100_KEYBOARD & &
* rsize = = 76 & & rdesc [ 73 ] = = 0x81 & & rdesc [ 74 ] = = 0x01 ) {
hid_info ( hdev , " Fixing up Asus T100 keyb report descriptor \n " ) ;
rdesc [ 74 ] & = ~ HID_MAIN_ITEM_CONSTANT ;
}
2017-07-02 17:34:15 +03:00
/* For the T100CHI keyboard dock */
if ( drvdata - > quirks & QUIRK_T100CHI & &
* rsize = = 403 & & rdesc [ 388 ] = = 0x09 & & rdesc [ 389 ] = = 0x76 ) {
/*
* Change Usage ( 76 h ) to Usage Minimum ( 00 h ) , Usage Maximum
* ( FFh ) and clear the flags in the Input ( ) byte .
* Note the descriptor has a bogus 0 byte at the end so we
* only need 1 extra byte .
*/
* rsize = 404 ;
rdesc = kmemdup ( rdesc , * rsize , GFP_KERNEL ) ;
if ( ! rdesc )
return NULL ;
hid_info ( hdev , " Fixing up T100CHI keyb report descriptor \n " ) ;
memmove ( rdesc + 392 , rdesc + 390 , 12 ) ;
rdesc [ 388 ] = 0x19 ;
rdesc [ 389 ] = 0x00 ;
rdesc [ 390 ] = 0x29 ;
rdesc [ 391 ] = 0xff ;
rdesc [ 402 ] = 0x00 ;
}
2017-05-15 10:31:41 +03:00
HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
return rdesc ;
}
static const struct hid_device_id asus_devices [ ] = {
2016-11-29 10:59:25 +03:00
{ HID_I2C_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
2017-03-09 02:31:13 +03:00
USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD ) , I2C_KEYBOARD_QUIRKS } ,
2016-11-29 10:59:25 +03:00
{ HID_I2C_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
2017-07-02 17:34:12 +03:00
USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD ) , I2C_TOUCHPAD_QUIRKS } ,
2017-03-02 00:48:51 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 ) } ,
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
2017-04-06 13:18:17 +03:00
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2 ) , QUIRK_USE_KBD_BACKLIGHT } ,
2017-05-15 10:31:41 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD ) ,
QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES } ,
2017-06-05 23:58:56 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_CHICONY , USB_DEVICE_ID_ASUS_AK1D ) } ,
2017-06-05 23:58:57 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_TURBOX , USB_DEVICE_ID_ASUS_MD_5110 ) } ,
2017-06-05 23:58:56 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_JESS , USB_DEVICE_ID_ASUS_MD_5112 ) } ,
2017-07-02 17:34:15 +03:00
{ HID_BLUETOOTH_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD ) , QUIRK_T100CHI } ,
HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
{ }
} ;
MODULE_DEVICE_TABLE ( hid , asus_devices ) ;
static struct hid_driver asus_driver = {
2016-11-29 10:59:25 +03:00
. name = " asus " ,
. id_table = asus_devices ,
. report_fixup = asus_report_fixup ,
. probe = asus_probe ,
2017-04-06 13:18:17 +03:00
. remove = asus_remove ,
2016-11-29 10:59:25 +03:00
. input_mapping = asus_input_mapping ,
. input_configured = asus_input_configured ,
# ifdef CONFIG_PM
. reset_resume = asus_reset_resume ,
# endif
. raw_event = asus_raw_event
HID: Asus X205TA keyboard driver
Asus X205TA built-in keyboard contains wrong
logical maximum value in report descriptor.
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Array,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage (LED)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101) * too small *
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xdd, // Usage Maximum (221)
0x81, 0x00, // Input(Data,Array,Abs)
In Asus X205TA japanese keyboard model,there are language
specific keys over usage id 101.
This patch correct wrong logical maximum in report
descriptor.
Signed-off-by: Yusuke Fujimaki <usk.fujimaki@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2016-03-21 10:18:42 +03:00
} ;
module_hid_driver ( asus_driver ) ;
MODULE_LICENSE ( " GPL " ) ;