2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
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
*/
/*
*/
2017-11-26 18:40:10 +03:00
# include <linux/dmi.h>
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 <linux/hid.h>
# include <linux/module.h>
2018-10-09 09:40:56 +03:00
# include <linux/platform_data/x86/asus-wmi.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 */
2019-01-29 07:31:29 +03:00
# include <linux/power_supply.h>
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
2020-04-28 17:22:53 +03:00
# define MEDION_E1239T_TPAD_INTF 1
2017-05-25 17:49:21 +03:00
2020-04-28 17:22:54 +03:00
# define E1239T_TP_TOGGLE_REPORT_ID 0x05
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
2020-10-27 00:02:17 +03:00
# define FEATURE_KBD_LED_REPORT_ID1 0x5d
# define FEATURE_KBD_LED_REPORT_ID2 0x5e
2017-04-06 13:18:17 +03:00
# 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
2019-01-29 07:31:29 +03:00
# define BATTERY_REPORT_ID (0x03)
# define BATTERY_REPORT_SIZE (1 + 8)
# define BATTERY_LEVEL_MAX ((u8)255)
# define BATTERY_STAT_DISCONNECT (0)
# define BATTERY_STAT_CHARGING (1)
# define BATTERY_STAT_FULL (2)
2016-11-29 10:59:25 +03:00
# 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)
2017-09-07 22:17:28 +03:00
# define QUIRK_G752_KEYBOARD BIT(8)
2021-05-06 00:39:34 +03:00
# define QUIRK_T90CHI BIT(9)
# define QUIRK_MEDION_E1239T BIT(10)
# define QUIRK_ROG_NKEY_KEYBOARD BIT(11)
2021-08-07 05:49:21 +03:00
# define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12)
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 ;
2020-04-28 17:22:52 +03:00
int report_size ;
2017-07-02 17:34:12 +03:00
} ;
2016-11-29 10:59:25 +03:00
struct asus_drvdata {
unsigned long quirks ;
2019-01-29 07:31:29 +03:00
struct hid_device * hdev ;
2016-11-29 10:59:25 +03:00
struct input_dev * input ;
2020-04-28 17:22:54 +03:00
struct input_dev * tp_kbd_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 ;
2019-01-29 07:31:29 +03:00
struct power_supply * battery ;
struct power_supply_desc battery_desc ;
int battery_capacity ;
int battery_stat ;
bool battery_in_query ;
unsigned long battery_next_query ;
2016-11-29 10:59:25 +03:00
} ;
2019-01-29 07:31:29 +03:00
static int asus_report_battery ( struct asus_drvdata * , u8 * , int ) ;
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 ,
2020-04-28 17:22:52 +03:00
. report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */ ,
2017-07-02 17:34:12 +03:00
} ;
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 ,
2020-04-28 17:22:52 +03:00
. report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */ ,
2017-07-02 17:34:12 +03:00
} ;
2017-11-26 18:40:10 +03:00
static const struct asus_touchpad_info asus_t100ha_tp = {
. max_x = 2640 ,
. max_y = 1320 ,
. res_x = 30 , /* units/mm */
. res_y = 29 , /* units/mm */
. contact_size = 5 ,
. max_contacts = 5 ,
2020-04-28 17:22:52 +03:00
. report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */ ,
2017-11-26 18:40:10 +03:00
} ;
2018-01-05 14:09:18 +03:00
static const struct asus_touchpad_info asus_t200ta_tp = {
. max_x = 3120 ,
. max_y = 1716 ,
. res_x = 30 , /* units/mm */
. res_y = 28 , /* units/mm */
. contact_size = 5 ,
. max_contacts = 5 ,
2020-04-28 17:22:52 +03:00
. report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */ ,
2018-01-05 14:09:18 +03:00
} ;
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 ,
2020-04-28 17:22:52 +03:00
. report_size = 15 /* 2 byte header + 3 * 4 + 1 byte footer */ ,
2017-08-04 16:31:04 +03:00
} ;
2020-04-28 17:22:53 +03:00
static const struct asus_touchpad_info medion_e1239t_tp = {
. max_x = 2640 ,
. max_y = 1380 ,
. res_x = 29 , /* units/mm */
. res_y = 28 , /* units/mm */
. contact_size = 5 ,
. max_contacts = 5 ,
. report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */ ,
} ;
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 ;
2022-10-24 19:11:02 +03:00
int oldid , i ;
2016-11-29 10:59:25 +03:00
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 ;
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 ;
}
}
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 ;
2020-04-28 17:22:52 +03:00
if ( size ! = drvdat - > tp - > report_size )
2017-07-02 17:34:12 +03:00
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
}
2020-04-28 17:22:54 +03:00
static int asus_e1239t_event ( struct asus_drvdata * drvdat , u8 * data , int size )
{
if ( size ! = 3 )
return 0 ;
/* Handle broken mute key which only sends press events */
if ( ! drvdat - > tp & &
data [ 0 ] = = 0x02 & & data [ 1 ] = = 0xe2 & & data [ 2 ] = = 0x00 ) {
input_report_key ( drvdat - > input , KEY_MUTE , 1 ) ;
input_sync ( drvdat - > input ) ;
input_report_key ( drvdat - > input , KEY_MUTE , 0 ) ;
input_sync ( drvdat - > input ) ;
return 1 ;
}
/* Handle custom touchpad toggle key which only sends press events */
if ( drvdat - > tp_kbd_input & &
data [ 0 ] = = 0x05 & & data [ 1 ] = = 0x02 & & data [ 2 ] = = 0x28 ) {
input_report_key ( drvdat - > tp_kbd_input , KEY_F21 , 1 ) ;
input_sync ( drvdat - > tp_kbd_input ) ;
input_report_key ( drvdat - > tp_kbd_input , KEY_F21 , 0 ) ;
input_sync ( drvdat - > tp_kbd_input ) ;
return 1 ;
}
return 0 ;
}
2018-11-26 13:52:16 +03:00
static int asus_event ( struct hid_device * hdev , struct hid_field * field ,
struct hid_usage * usage , __s32 value )
{
if ( ( usage - > hid & HID_USAGE_PAGE ) = = 0xff310000 & &
2019-10-24 14:59:09 +03:00
( usage - > hid & HID_USAGE ) ! = 0x00 & &
( usage - > hid & HID_USAGE ) ! = 0xff & & ! usage - > type ) {
2018-11-26 13:52:16 +03:00
hid_warn ( hdev , " Unmapped Asus vendor usagepage code 0x%02x \n " ,
usage - > hid & HID_USAGE ) ;
}
return 0 ;
}
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 ) ;
2019-01-29 07:31:29 +03:00
if ( drvdata - > battery & & data [ 0 ] = = BATTERY_REPORT_ID )
return asus_report_battery ( drvdata , data , size ) ;
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
2020-04-28 17:22:54 +03:00
if ( drvdata - > quirks & QUIRK_MEDION_E1239T )
return asus_e1239t_event ( drvdata , data , size ) ;
2021-02-19 00:38:46 +03:00
if ( drvdata - > quirks & QUIRK_USE_KBD_BACKLIGHT ) {
2020-10-27 00:02:17 +03:00
/*
* Skip these report ID , the device emits a continuous stream associated
* with the AURA mode it is in which looks like an ' echo ' .
*/
if ( report - > id = = FEATURE_KBD_LED_REPORT_ID1 | |
report - > id = = FEATURE_KBD_LED_REPORT_ID2 ) {
return - 1 ;
/* Additional report filtering */
} else if ( report - > id = = FEATURE_KBD_REPORT_ID ) {
/*
* G14 and G15 send these codes on some keypresses with no
* discernable reason for doing so . We ' ll filter them out to avoid
* unmapped warning messages later .
*/
if ( data [ 1 ] = = 0xea | | data [ 1 ] = = 0xec | | data [ 1 ] = = 0x02 | |
data [ 1 ] = = 0x8a | | data [ 1 ] = = 0x9e ) {
return - 1 ;
}
}
2021-04-18 12:12:29 +03:00
if ( drvdata - > quirks & QUIRK_ROG_NKEY_KEYBOARD ) {
/*
* G713 and G733 send these codes on some keypresses , depending on
* the key pressed it can trigger a shutdown event if not caught .
*/
if ( data [ 0 ] = = 0x02 & & data [ 1 ] = = 0x30 ) {
return - 1 ;
}
}
2020-10-27 00:02:17 +03:00
}
2021-08-07 05:49:21 +03:00
if ( drvdata - > quirks & QUIRK_ROG_CLAYMORE_II_KEYBOARD ) {
/*
* CLAYMORE II keyboard sends this packet when it goes to sleep
* this causes the whole system to go into suspend .
*/
if ( size = = 2 & & data [ 0 ] = = 0x02 & & data [ 1 ] = = 0x00 ) {
return - 1 ;
}
}
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 ;
2020-10-27 00:02:17 +03:00
/*
* The report ID should be set from the incoming buffer due to LED and key
* interfaces having different pages
*/
ret = hid_hw_raw_request ( hdev , buf [ 0 ] , dmabuf ,
2017-04-06 13:18:17 +03:00
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 ;
}
2020-10-27 00:02:17 +03:00
static int rog_nkey_led_init ( struct hid_device * hdev )
{
u8 buf_init_start [ ] = { FEATURE_KBD_LED_REPORT_ID1 , 0xB9 } ;
u8 buf_init2 [ ] = { FEATURE_KBD_LED_REPORT_ID1 , 0x41 , 0x53 , 0x55 , 0x53 , 0x20 ,
0x54 , 0x65 , 0x63 , 0x68 , 0x2e , 0x49 , 0x6e , 0x63 , 0x2e , 0x00 } ;
u8 buf_init3 [ ] = { FEATURE_KBD_LED_REPORT_ID1 ,
0x05 , 0x20 , 0x31 , 0x00 , 0x08 } ;
int ret ;
hid_info ( hdev , " Asus initialise N-KEY Device " ) ;
/* The first message is an init start */
ret = asus_kbd_set_report ( hdev , buf_init_start , sizeof ( buf_init_start ) ) ;
if ( ret < 0 ) {
hid_warn ( hdev , " Asus failed to send init start command: %d \n " , ret ) ;
return ret ;
}
/* Followed by a string */
ret = asus_kbd_set_report ( hdev , buf_init2 , sizeof ( buf_init2 ) ) ;
if ( ret < 0 ) {
hid_warn ( hdev , " Asus failed to send init command 1.0: %d \n " , ret ) ;
return ret ;
}
/* Followed by a string */
ret = asus_kbd_set_report ( hdev , buf_init3 , sizeof ( buf_init3 ) ) ;
if ( ret < 0 ) {
hid_warn ( hdev , " Asus failed to send init command 1.1: %d \n " , ret ) ;
return ret ;
}
/* begin second report ID with same data */
buf_init2 [ 0 ] = FEATURE_KBD_LED_REPORT_ID2 ;
buf_init3 [ 0 ] = FEATURE_KBD_LED_REPORT_ID2 ;
ret = asus_kbd_set_report ( hdev , buf_init2 , sizeof ( buf_init2 ) ) ;
if ( ret < 0 ) {
hid_warn ( hdev , " Asus failed to send init command 2.0: %d \n " , ret ) ;
return ret ;
}
ret = asus_kbd_set_report ( hdev , buf_init3 , sizeof ( buf_init3 ) ) ;
if ( ret < 0 )
hid_warn ( hdev , " Asus failed to send init command 2.1: %d \n " , ret ) ;
return ret ;
}
2017-04-06 13:18:17 +03:00
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 ) ;
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 ) ;
}
2018-10-09 09:40:56 +03:00
/* WMI-based keyboard backlight LED control (via asus-wmi driver) takes
* precedence . We only activate HID - based backlight control when the
* WMI control is not available .
*/
static bool asus_kbd_wmi_led_control_present ( struct hid_device * hdev )
{
u32 value ;
int ret ;
HID: asus: fix build warning wiht CONFIG_ASUS_WMI disabled
asus_wmi_evaluate_method() is an empty dummy function when CONFIG_ASUS_WMI
is disabled, or not reachable from a built-in device driver. This leads to
a theoretical evaluation of an uninitialized variable that the compiler
complains about, failing to check that the hardcoded return value makes
this an unreachable code path:
In file included from include/linux/printk.h:336,
from include/linux/kernel.h:14,
from include/linux/list.h:9,
from include/linux/dmi.h:5,
from drivers/hid/hid-asus.c:29:
drivers/hid/hid-asus.c: In function 'asus_input_configured':
include/linux/dynamic_debug.h:135:3: error: 'value' may be used uninitialized in this function [-Werror=maybe-uninitialized]
__dynamic_dev_dbg(&descriptor, dev, fmt, \
^~~~~~~~~~~~~~~~~
drivers/hid/hid-asus.c:359:6: note: 'value' was declared here
u32 value;
^~~~~
With an extra IS_ENABLED() check, the warning goes away.
Fixes: 3b692c55e58d ("HID: asus: only support backlight when it's not driven by WMI")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2018-11-02 18:14:32 +03:00
if ( ! IS_ENABLED ( CONFIG_ASUS_WMI ) )
return false ;
2019-05-14 22:00:31 +03:00
ret = asus_wmi_evaluate_method ( ASUS_WMI_METHODID_DSTS ,
2018-10-09 09:40:56 +03:00
ASUS_WMI_DEVID_KBD_BACKLIGHT , 0 , & value ) ;
hid_dbg ( hdev , " WMI backlight check: rc %d value %x " , ret , value ) ;
if ( ret )
return false ;
return ! ! ( value & ASUS_WMI_DSTS_PRESENCE_BIT ) ;
}
2017-04-06 13:18:17 +03:00
static int asus_kbd_register_leds ( struct hid_device * hdev )
{
struct asus_drvdata * drvdata = hid_get_drvdata ( hdev ) ;
unsigned char kbd_func ;
int ret ;
2020-10-27 00:02:17 +03:00
if ( drvdata - > quirks & QUIRK_ROG_NKEY_KEYBOARD ) {
ret = rog_nkey_led_init ( hdev ) ;
if ( ret < 0 )
return ret ;
} else {
/* Initialize keyboard */
ret = asus_kbd_init ( hdev ) ;
if ( ret < 0 )
return ret ;
2017-04-06 13:18:17 +03:00
2020-10-27 00:02:17 +03:00
/* Get keyboard functions */
ret = asus_kbd_get_functions ( hdev , & kbd_func ) ;
if ( ret < 0 )
return ret ;
2017-04-06 13:18:17 +03:00
2020-10-27 00:02:17 +03:00
/* Check for backlight support */
if ( ! ( kbd_func & SUPPORT_KBD_BACKLIGHT ) )
return - ENODEV ;
}
2017-04-06 13:18:17 +03:00
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 ;
}
2019-01-29 07:31:29 +03:00
/*
* [ 0 ] REPORT_ID ( same value defined in report descriptor )
* [ 1 ] rest battery level . range [ 0. .255 ]
* [ 2 ] . . [ 7 ] Bluetooth hardware address ( MAC address )
* [ 8 ] charging status
* = 0 : AC offline / discharging
* = 1 : AC online / charging
* = 2 : AC online / fully charged
*/
static int asus_parse_battery ( struct asus_drvdata * drvdata , u8 * data , int size )
{
u8 sts ;
u8 lvl ;
int val ;
lvl = data [ 1 ] ;
sts = data [ 8 ] ;
drvdata - > battery_capacity = ( ( int ) lvl * 100 ) / ( int ) BATTERY_LEVEL_MAX ;
switch ( sts ) {
case BATTERY_STAT_CHARGING :
val = POWER_SUPPLY_STATUS_CHARGING ;
break ;
case BATTERY_STAT_FULL :
val = POWER_SUPPLY_STATUS_FULL ;
break ;
case BATTERY_STAT_DISCONNECT :
default :
val = POWER_SUPPLY_STATUS_DISCHARGING ;
break ;
}
drvdata - > battery_stat = val ;
return 0 ;
}
static int asus_report_battery ( struct asus_drvdata * drvdata , u8 * data , int size )
{
/* notify only the autonomous event by device */
if ( ( drvdata - > battery_in_query = = false ) & &
( size = = BATTERY_REPORT_SIZE ) )
power_supply_changed ( drvdata - > battery ) ;
return 0 ;
}
static int asus_battery_query ( struct asus_drvdata * drvdata )
{
u8 * buf ;
int ret = 0 ;
buf = kmalloc ( BATTERY_REPORT_SIZE , GFP_KERNEL ) ;
if ( ! buf )
return - ENOMEM ;
drvdata - > battery_in_query = true ;
ret = hid_hw_raw_request ( drvdata - > hdev , BATTERY_REPORT_ID ,
buf , BATTERY_REPORT_SIZE ,
HID_INPUT_REPORT , HID_REQ_GET_REPORT ) ;
drvdata - > battery_in_query = false ;
if ( ret = = BATTERY_REPORT_SIZE )
ret = asus_parse_battery ( drvdata , buf , BATTERY_REPORT_SIZE ) ;
else
ret = - ENODATA ;
kfree ( buf ) ;
return ret ;
}
static enum power_supply_property asus_battery_props [ ] = {
POWER_SUPPLY_PROP_STATUS ,
POWER_SUPPLY_PROP_PRESENT ,
POWER_SUPPLY_PROP_CAPACITY ,
POWER_SUPPLY_PROP_SCOPE ,
POWER_SUPPLY_PROP_MODEL_NAME ,
} ;
# define QUERY_MIN_INTERVAL (60 * HZ) /* 60[sec] */
static int asus_battery_get_property ( struct power_supply * psy ,
enum power_supply_property psp ,
union power_supply_propval * val )
{
struct asus_drvdata * drvdata = power_supply_get_drvdata ( psy ) ;
int ret = 0 ;
switch ( psp ) {
case POWER_SUPPLY_PROP_STATUS :
case POWER_SUPPLY_PROP_CAPACITY :
if ( time_before ( drvdata - > battery_next_query , jiffies ) ) {
drvdata - > battery_next_query =
jiffies + QUERY_MIN_INTERVAL ;
ret = asus_battery_query ( drvdata ) ;
if ( ret )
return ret ;
}
if ( psp = = POWER_SUPPLY_PROP_STATUS )
val - > intval = drvdata - > battery_stat ;
else
val - > intval = drvdata - > battery_capacity ;
break ;
case POWER_SUPPLY_PROP_PRESENT :
val - > intval = 1 ;
break ;
case POWER_SUPPLY_PROP_SCOPE :
val - > intval = POWER_SUPPLY_SCOPE_DEVICE ;
break ;
case POWER_SUPPLY_PROP_MODEL_NAME :
val - > strval = drvdata - > hdev - > name ;
break ;
default :
ret = - EINVAL ;
break ;
}
return ret ;
}
static int asus_battery_probe ( struct hid_device * hdev )
{
struct asus_drvdata * drvdata = hid_get_drvdata ( hdev ) ;
struct power_supply_config pscfg = { . drv_data = drvdata } ;
int ret = 0 ;
drvdata - > battery_capacity = 0 ;
drvdata - > battery_stat = POWER_SUPPLY_STATUS_UNKNOWN ;
drvdata - > battery_in_query = false ;
drvdata - > battery_desc . properties = asus_battery_props ;
drvdata - > battery_desc . num_properties = ARRAY_SIZE ( asus_battery_props ) ;
drvdata - > battery_desc . get_property = asus_battery_get_property ;
drvdata - > battery_desc . type = POWER_SUPPLY_TYPE_BATTERY ;
drvdata - > battery_desc . use_for_apm = 0 ;
drvdata - > battery_desc . name = devm_kasprintf ( & hdev - > dev , GFP_KERNEL ,
" asus-keyboard-%s-battery " ,
strlen ( hdev - > uniq ) ?
hdev - > uniq : dev_name ( & hdev - > dev ) ) ;
if ( ! drvdata - > battery_desc . name )
return - ENOMEM ;
drvdata - > battery_next_query = jiffies ;
drvdata - > battery = devm_power_supply_register ( & hdev - > dev ,
& ( drvdata - > battery_desc ) , & pscfg ) ;
if ( IS_ERR ( drvdata - > battery ) ) {
ret = PTR_ERR ( drvdata - > battery ) ;
drvdata - > battery = NULL ;
hid_err ( hdev , " Unable to register battery device \n " ) ;
return ret ;
}
power_supply_powers ( drvdata - > battery , & hdev - > dev ) ;
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 ;
2020-04-28 17:22:54 +03:00
/* Handle MULTI_INPUT on E1239T mouse/touchpad USB interface */
if ( drvdata - > tp & & ( drvdata - > quirks & QUIRK_MEDION_E1239T ) ) {
switch ( hi - > report - > id ) {
case E1239T_TP_TOGGLE_REPORT_ID :
input_set_capability ( input , EV_KEY , KEY_F21 ) ;
input - > name = " Asus Touchpad Keys " ;
drvdata - > tp_kbd_input = input ;
return 0 ;
case INPUT_REPORT_ID :
break ; /* Touchpad report, handled below */
default :
return 0 ; /* Ignore other reports */
}
}
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 ;
2018-10-09 09:40:56 +03:00
if ( drvdata - > enable_backlight & &
! asus_kbd_wmi_led_control_present ( hdev ) & &
asus_kbd_register_leds ( hdev ) )
2017-04-06 13:18:17 +03:00
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 .
*/
2020-04-28 17:22:50 +03:00
if ( ( drvdata - > quirks & ( QUIRK_T100CHI | QUIRK_T90CHI ) ) & &
( field - > application = = ( HID_UP_GENDESK | 0x0080 ) | |
field - > application = = HID_GD_MOUSE | |
usage - > hid = = ( HID_UP_GENDEVCTRLS | 0x0024 ) | |
usage - > hid = = ( HID_UP_GENDEVCTRLS | 0x0025 ) | |
usage - > hid = = ( HID_UP_GENDEVCTRLS | 0x0026 ) ) )
return - 1 ;
2017-08-04 16:31:04 +03:00
2020-10-27 00:02:17 +03:00
/* ASUS-specific keyboard hotkeys and led backlight */
if ( ( usage - > hid & HID_USAGE_PAGE ) = = HID_UP_ASUSVENDOR ) {
2017-03-02 00:48:51 +03:00
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 ;
2021-11-12 01:47:35 +03:00
case 0x35 : asus_map_key_clear ( KEY_DISPLAY_OFF ) ; break ;
2017-03-09 02:31:13 +03:00
case 0x6c : asus_map_key_clear ( KEY_SLEEP ) ; break ;
2018-11-26 13:52:17 +03:00
case 0x7c : asus_map_key_clear ( KEY_MICMUTE ) ; break ;
2017-03-09 02:31:13 +03:00
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
2018-11-26 13:52:17 +03:00
/* Fn+F5 "fan" symbol on FX503VD */
case 0x99 : asus_map_key_clear ( KEY_PROG4 ) ; break ;
2020-10-27 00:02:17 +03:00
/* Fn+F5 "fan" symbol on N-Key keyboard */
case 0xae : asus_map_key_clear ( KEY_PROG4 ) ; break ;
/* Fn+Ret "Calc" symbol on N-Key keyboard */
case 0x92 : asus_map_key_clear ( KEY_CALC ) ; break ;
/* Fn+Left Aura mode previous on N-Key keyboard */
case 0xb2 : asus_map_key_clear ( KEY_PROG2 ) ; break ;
/* Fn+Right Aura mode next on N-Key keyboard */
case 0xb3 : 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 ;
2020-04-28 17:22:49 +03:00
set_bit ( EV_REP , hi - > input - > evbit ) ;
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 ) {
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 ;
}
2020-04-28 17:22:49 +03:00
set_bit ( EV_REP , hi - > input - > evbit ) ;
2017-06-05 23:58:56 +03:00
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 ;
}
}
2020-04-28 17:22:54 +03:00
/*
* The mute button is broken and only sends press events , we
* deal with this in our raw_event handler , so do not map it .
*/
if ( ( drvdata - > quirks & QUIRK_MEDION_E1239T ) & &
usage - > hid = = ( HID_UP_CONSUMER | 0xe2 ) ) {
input_set_capability ( hi - > input , EV_KEY , KEY_MUTE ) ;
return - 1 ;
}
2016-11-29 10:59:25 +03:00
return 0 ;
}
static int asus_start_multitouch ( struct hid_device * hdev )
{
int ret ;
2018-01-06 18:50:27 +03:00
static const unsigned char buf [ ] = {
FEATURE_REPORT_ID , 0x00 , 0x03 , 0x01 , 0x00
} ;
2016-11-29 10:59:25 +03:00
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 ;
2019-01-29 07:31:29 +03:00
/*
* T90CHI ' s keyboard dock returns same ID values as T100CHI ' s dock .
* Thus , identify T90CHI dock with product name string .
*/
2019-01-29 07:23:20 +03:00
if ( strstr ( hdev - > name , " T90CHI " ) ) {
drvdata - > quirks & = ~ QUIRK_T100CHI ;
drvdata - > quirks | = QUIRK_T90CHI ;
}
2017-07-02 17:34:12 +03:00
if ( drvdata - > quirks & QUIRK_IS_MULTITOUCH )
drvdata - > tp = & asus_i2c_tp ;
2021-12-01 21:35:01 +03:00
if ( ( drvdata - > quirks & QUIRK_T100_KEYBOARD ) & & hid_is_usb ( hdev ) ) {
2017-05-25 17:49:21 +03:00
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 ;
2017-11-26 18:40:10 +03:00
/*
2018-01-05 14:09:18 +03:00
* The T100HA uses the same USB - ids as the T100TAF and
* the T200TA uses the same USB - ids as the T100TA , while
* both have different max x / y values as the T100TA [ F ] .
2017-11-26 18:40:10 +03:00
*/
if ( dmi_match ( DMI_PRODUCT_NAME , " T100HAN " ) )
drvdata - > tp = & asus_t100ha_tp ;
2018-01-05 14:09:18 +03:00
else if ( dmi_match ( DMI_PRODUCT_NAME , " T200TA " ) )
drvdata - > tp = & asus_t200ta_tp ;
2017-11-26 18:40:10 +03:00
else
drvdata - > tp = & asus_t100ta_tp ;
2017-07-02 17:34:12 +03:00
}
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 .
*/
2018-03-20 14:04:49 +03:00
hdev - > quirks | = HID_QUIRK_MULTI_INPUT ;
2017-08-04 16:31:04 +03:00
drvdata - > tp = & asus_t100chi_tp ;
}
2021-12-01 21:35:01 +03:00
if ( ( drvdata - > quirks & QUIRK_MEDION_E1239T ) & & hid_is_usb ( hdev ) ) {
2020-04-28 17:22:53 +03:00
struct usb_host_interface * alt =
to_usb_interface ( hdev - > dev . parent ) - > altsetting ;
if ( alt - > desc . bInterfaceNumber = = MEDION_E1239T_TPAD_INTF ) {
2020-04-28 17:22:54 +03:00
/* For separate input-devs for tp and tp toggle key */
hdev - > quirks | = HID_QUIRK_MULTI_INPUT ;
2020-04-28 17:22:53 +03:00
drvdata - > quirks | = QUIRK_SKIP_INPUT_MAPPING ;
drvdata - > tp = & medion_e1239t_tp ;
}
}
2016-11-29 10:59:25 +03:00
if ( drvdata - > quirks & QUIRK_NO_INIT_REPORTS )
hdev - > quirks | = HID_QUIRK_NO_INIT_REPORTS ;
2019-01-29 07:31:29 +03:00
drvdata - > hdev = hdev ;
if ( drvdata - > quirks & ( QUIRK_T100CHI | QUIRK_T90CHI ) ) {
ret = asus_battery_probe ( hdev ) ;
if ( ret ) {
hid_err ( hdev ,
" Asus hid battery_probe failed: %d \n " , ret ) ;
return ret ;
}
}
2016-11-29 10:59:25 +03:00
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
}
2017-09-07 22:17:28 +03:00
static const __u8 asus_g752_fixed_rdesc [ ] = {
0x19 , 0x00 , /* Usage Minimum (0x00) */
0x2A , 0xFF , 0x00 , /* Usage Maximum (0xFF) */
} ;
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 ;
}
2018-01-05 14:09:19 +03:00
/* For the T100TA/T200TA keyboard dock */
2017-05-15 10:31:41 +03:00
if ( drvdata - > quirks & QUIRK_T100_KEYBOARD & &
2018-01-05 14:09:19 +03:00
( * rsize = = 76 | | * rsize = = 101 ) & &
rdesc [ 73 ] = = 0x81 & & rdesc [ 74 ] = = 0x01 ) {
2017-05-15 10:31:41 +03:00
hid_info ( hdev , " Fixing up Asus T100 keyb report descriptor \n " ) ;
rdesc [ 74 ] & = ~ HID_MAIN_ITEM_CONSTANT ;
}
2019-01-29 07:23:20 +03:00
/* For the T100CHI/T90CHI keyboard dock */
if ( drvdata - > quirks & ( QUIRK_T100CHI | QUIRK_T90CHI ) ) {
int rsize_orig ;
int offs ;
if ( drvdata - > quirks & QUIRK_T100CHI ) {
rsize_orig = 403 ;
offs = 388 ;
} else {
rsize_orig = 306 ;
offs = 291 ;
}
2017-07-02 17:34:15 +03:00
/*
* 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 .
*/
2019-01-29 07:23:20 +03:00
if ( * rsize = = rsize_orig & &
rdesc [ offs ] = = 0x09 & & rdesc [ offs + 1 ] = = 0x76 ) {
* rsize = rsize_orig + 1 ;
rdesc = kmemdup ( rdesc , * rsize , GFP_KERNEL ) ;
if ( ! rdesc )
return NULL ;
hid_info ( hdev , " Fixing up %s keyb report descriptor \n " ,
drvdata - > quirks & QUIRK_T100CHI ?
" T100CHI " : " T90CHI " ) ;
memmove ( rdesc + offs + 4 , rdesc + offs + 2 , 12 ) ;
rdesc [ offs ] = 0x19 ;
rdesc [ offs + 1 ] = 0x00 ;
rdesc [ offs + 2 ] = 0x29 ;
rdesc [ offs + 3 ] = 0xff ;
rdesc [ offs + 14 ] = 0x00 ;
}
2017-07-02 17:34:15 +03:00
}
2019-01-29 07:23:20 +03:00
2017-09-07 22:17:28 +03:00
if ( drvdata - > quirks & QUIRK_G752_KEYBOARD & &
* rsize = = 75 & & rdesc [ 61 ] = = 0x15 & & rdesc [ 62 ] = = 0x00 ) {
/* report is missing usage mninum and maximum */
__u8 * new_rdesc ;
size_t new_size = * rsize + sizeof ( asus_g752_fixed_rdesc ) ;
new_rdesc = devm_kzalloc ( & hdev - > dev , new_size , GFP_KERNEL ) ;
if ( new_rdesc = = NULL )
return rdesc ;
hid_info ( hdev , " Fixing up Asus G752 keyb report descriptor \n " ) ;
/* copy the valid part */
memcpy ( new_rdesc , rdesc , 61 ) ;
/* insert missing part */
memcpy ( new_rdesc + 61 , asus_g752_fixed_rdesc , sizeof ( asus_g752_fixed_rdesc ) ) ;
/* copy remaining data */
memcpy ( new_rdesc + 61 + sizeof ( asus_g752_fixed_rdesc ) , rdesc + 61 , * rsize - 61 ) ;
* rsize = new_size ;
rdesc = new_rdesc ;
}
2017-05-15 10:31:41 +03:00
2022-07-28 20:51:11 +03:00
if ( drvdata - > quirks & QUIRK_ROG_NKEY_KEYBOARD & &
* rsize = = 331 & & rdesc [ 190 ] = = 0x85 & & rdesc [ 191 ] = = 0x5a & &
rdesc [ 204 ] = = 0x95 & & rdesc [ 205 ] = = 0x05 ) {
hid_info ( hdev , " Fixing up Asus N-KEY keyb report descriptor \n " ) ;
rdesc [ 205 ] = 0x01 ;
}
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 ,
2017-10-28 10:31:40 +03:00
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 ) , QUIRK_USE_KBD_BACKLIGHT } ,
2017-03-02 00:48:51 +03:00
{ 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-09-07 22:17:28 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3 ) , QUIRK_G752_KEYBOARD } ,
2018-11-26 13:52:17 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD ) ,
QUIRK_USE_KBD_BACKLIGHT } ,
2020-10-27 00:02:17 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD ) ,
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD } ,
2021-02-19 00:10:02 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 ) ,
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD } ,
2021-08-07 05:49:21 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD ) ,
QUIRK_ROG_CLAYMORE_II_KEYBOARD } ,
2017-05-15 10:31:41 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
2017-11-26 18:40:10 +03:00
USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD ) ,
QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES } ,
{ HID_USB_DEVICE ( USB_VENDOR_ID_ASUSTEK ,
USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD ) ,
2017-05-15 10:31:41 +03:00
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 } ,
2020-04-28 17:22:53 +03:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_ITE , USB_DEVICE_ID_ITE_MEDION_E1239T ) ,
QUIRK_MEDION_E1239T } ,
2021-05-06 00:39:34 +03:00
/*
* Note bind to the HID_GROUP_GENERIC group , so that we only bind to the keyboard
* part , while letting hid - multitouch . c handle the touchpad .
*/
{ HID_DEVICE ( BUS_USB , HID_GROUP_GENERIC ,
USB_VENDOR_ID_ASUSTEK , USB_DEVICE_ID_ASUSTEK_T101HA_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
{ }
} ;
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
2018-11-26 13:52:16 +03:00
. event = asus_event ,
2016-11-29 10:59:25 +03:00
. 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 " ) ;