Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *  HID driver for Asus notebook built-in keyboard.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *  Fixes small logical maximum to match usage maximum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *  Currently supported devices are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *    EeeBook X205TA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *    VivoBook E200HA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *  Copyright (c) 2016 Yusuke Fujimaki <usk.fujimaki@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *  This module based on hid-ortek by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *  Copyright (c) 2010 Johnathon Harris <jmharris@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *  Copyright (c) 2011 Jiri Kosina
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *  This module has been updated to add support for Asus i2c touchpad.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *  Copyright (c) 2016 Brendan McGrath <redmcg@redmandi.dyndns.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *  Copyright (c) 2016 Victor Vlasenko <victor.vlasenko@sysgears.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *  Copyright (c) 2016 Frederik Wenigwieser <frederik.wenigwieser@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/hid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/platform_data/x86/asus-wmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/input/mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include "hid-ids.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) MODULE_AUTHOR("Yusuke Fujimaki <usk.fujimaki@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) MODULE_AUTHOR("Brendan McGrath <redmcg@redmandi.dyndns.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) MODULE_AUTHOR("Victor Vlasenko <victor.vlasenko@sysgears.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) MODULE_AUTHOR("Frederik Wenigwieser <frederik.wenigwieser@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define T100_TPAD_INTF 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define MEDION_E1239T_TPAD_INTF 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define E1239T_TP_TOGGLE_REPORT_ID 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define T100CHI_MOUSE_REPORT_ID 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define FEATURE_REPORT_ID 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define INPUT_REPORT_ID 0x5d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define FEATURE_KBD_REPORT_ID 0x5a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define FEATURE_KBD_REPORT_SIZE 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define SUPPORT_KBD_BACKLIGHT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define MAX_TOUCH_MAJOR 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define MAX_PRESSURE 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define BTN_LEFT_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define CONTACT_TOOL_TYPE_MASK 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define CONTACT_X_MSB_MASK 0xf0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define CONTACT_Y_MSB_MASK 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define CONTACT_TOUCH_MAJOR_MASK 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define CONTACT_PRESSURE_MASK 0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define	BATTERY_REPORT_ID	(0x03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define	BATTERY_REPORT_SIZE	(1 + 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define	BATTERY_LEVEL_MAX	((u8)255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define	BATTERY_STAT_DISCONNECT	(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define	BATTERY_STAT_CHARGING	(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define	BATTERY_STAT_FULL	(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define QUIRK_FIX_NOTEBOOK_REPORT	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define QUIRK_NO_INIT_REPORTS		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define QUIRK_SKIP_INPUT_MAPPING	BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define QUIRK_IS_MULTITOUCH		BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define QUIRK_NO_CONSUMER_USAGES	BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define QUIRK_USE_KBD_BACKLIGHT		BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define QUIRK_T100_KEYBOARD		BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define QUIRK_T100CHI			BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define QUIRK_G752_KEYBOARD		BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define QUIRK_T101HA_DOCK		BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define QUIRK_T90CHI			BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define QUIRK_MEDION_E1239T		BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define I2C_KEYBOARD_QUIRKS			(QUIRK_FIX_NOTEBOOK_REPORT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 						 QUIRK_NO_INIT_REPORTS | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 						 QUIRK_NO_CONSUMER_USAGES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define I2C_TOUCHPAD_QUIRKS			(QUIRK_NO_INIT_REPORTS | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 						 QUIRK_SKIP_INPUT_MAPPING | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 						 QUIRK_IS_MULTITOUCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define TRKID_SGN       ((TRKID_MAX + 1) >> 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) struct asus_kbd_leds {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	struct led_classdev cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	struct hid_device *hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	struct work_struct work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	unsigned int brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	bool removed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) struct asus_touchpad_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	int max_x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	int max_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	int res_x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	int res_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	int contact_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	int max_contacts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	int report_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) struct asus_drvdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	unsigned long quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	struct hid_device *hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	struct input_dev *tp_kbd_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	struct asus_kbd_leds *kbd_backlight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	const struct asus_touchpad_info *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	bool enable_backlight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	struct power_supply *battery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	struct power_supply_desc battery_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	int battery_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	int battery_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	bool battery_in_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	unsigned long battery_next_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) static int asus_report_battery(struct asus_drvdata *, u8 *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) static const struct asus_touchpad_info asus_i2c_tp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	.max_x = 2794,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	.max_y = 1758,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	.contact_size = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	.max_contacts = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) static const struct asus_touchpad_info asus_t100ta_tp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	.max_x = 2240,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	.max_y = 1120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	.res_x = 30, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	.res_y = 27, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	.contact_size = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	.max_contacts = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) static const struct asus_touchpad_info asus_t100ha_tp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	.max_x = 2640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	.max_y = 1320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	.res_x = 30, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	.res_y = 29, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	.contact_size = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	.max_contacts = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) static const struct asus_touchpad_info asus_t200ta_tp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	.max_x = 3120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	.max_y = 1716,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	.res_x = 30, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	.res_y = 28, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	.contact_size = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	.max_contacts = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) static const struct asus_touchpad_info asus_t100chi_tp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	.max_x = 2640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	.max_y = 1320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	.res_x = 31, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	.res_y = 29, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	.contact_size = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	.max_contacts = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	.report_size = 15 /* 2 byte header + 3 * 4 + 1 byte footer */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) static const struct asus_touchpad_info medion_e1239t_tp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	.max_x = 2640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	.max_y = 1380,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	.res_x = 29, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	.res_y = 28, /* units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	.contact_size = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	.max_contacts = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	.report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) static void asus_report_contact_down(struct asus_drvdata *drvdat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		int toolType, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	struct input_dev *input = drvdat->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	int touch_major, pressure, x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	x = (data[0] & CONTACT_X_MSB_MASK) << 4 | data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	y = drvdat->tp->max_y - ((data[0] & CONTACT_Y_MSB_MASK) << 8 | data[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	input_report_abs(input, ABS_MT_POSITION_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	input_report_abs(input, ABS_MT_POSITION_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	if (drvdat->tp->contact_size < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	if (toolType == MT_TOOL_PALM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		touch_major = MAX_TOUCH_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 		pressure = MAX_PRESSURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		touch_major = (data[3] >> 4) & CONTACT_TOUCH_MAJOR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		pressure = data[4] & CONTACT_PRESSURE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	input_report_abs(input, ABS_MT_PRESSURE, pressure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) /* Required for Synaptics Palm Detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) static void asus_report_tool_width(struct asus_drvdata *drvdat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	struct input_mt *mt = drvdat->input->mt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	struct input_mt_slot *oldest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	int oldid, count, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	if (drvdat->tp->contact_size < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	oldest = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	oldid = mt->trkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	for (i = 0; i < mt->num_slots; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		struct input_mt_slot *ps = &mt->slots[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		if (id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		if ((id - oldid) & TRKID_SGN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 			oldest = ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 			oldid = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	if (oldest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		input_report_abs(drvdat->input, ABS_TOOL_WIDTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 			input_mt_get_value(oldest, ABS_MT_TOUCH_MAJOR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	int i, toolType = MT_TOOL_FINGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	u8 *contactData = data + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	if (size != drvdat->tp->report_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	for (i = 0; i < drvdat->tp->max_contacts; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		bool down = !!(data[1] & BIT(i+3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		if (drvdat->tp->contact_size >= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 			toolType = contactData[3] & CONTACT_TOOL_TYPE_MASK ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 						MT_TOOL_PALM : MT_TOOL_FINGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		input_mt_slot(drvdat->input, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		input_mt_report_slot_state(drvdat->input, toolType, down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		if (down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 			asus_report_contact_down(drvdat, toolType, contactData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 			contactData += drvdat->tp->contact_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	input_report_key(drvdat->input, BTN_LEFT, data[1] & BTN_LEFT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	asus_report_tool_width(drvdat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	input_mt_sync_frame(drvdat->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	input_sync(drvdat->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	if (size != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	/* Handle broken mute key which only sends press events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	if (!drvdat->tp &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	    data[0] == 0x02 && data[1] == 0xe2 && data[2] == 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		input_report_key(drvdat->input, KEY_MUTE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		input_sync(drvdat->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		input_report_key(drvdat->input, KEY_MUTE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		input_sync(drvdat->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	/* Handle custom touchpad toggle key which only sends press events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	if (drvdat->tp_kbd_input &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	    data[0] == 0x05 && data[1] == 0x02 && data[2] == 0x28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		input_report_key(drvdat->tp_kbd_input, KEY_F21, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		input_sync(drvdat->tp_kbd_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		input_report_key(drvdat->tp_kbd_input, KEY_F21, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		input_sync(drvdat->tp_kbd_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) static int asus_event(struct hid_device *hdev, struct hid_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		      struct hid_usage *usage, __s32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	    (usage->hid & HID_USAGE) != 0x00 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	    (usage->hid & HID_USAGE) != 0xff && !usage->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 			 usage->hid & HID_USAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) static int asus_raw_event(struct hid_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		struct hid_report *report, u8 *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	if (drvdata->battery && data[0] == BATTERY_REPORT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		return asus_report_battery(drvdata, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	if (drvdata->tp && data[0] == INPUT_REPORT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		return asus_report_input(drvdata, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	if (drvdata->quirks & QUIRK_MEDION_E1239T)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		return asus_e1239t_event(drvdata, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	unsigned char *dmabuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	dmabuf = kmemdup(buf, buf_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	if (!dmabuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	ret = hid_hw_raw_request(hdev, FEATURE_KBD_REPORT_ID, dmabuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 				 buf_size, HID_FEATURE_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 				 HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	kfree(dmabuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) static int asus_kbd_init(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		     0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		hid_err(hdev, "Asus failed to send init command: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) static int asus_kbd_get_functions(struct hid_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 				  unsigned char *kbd_func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	u8 *readbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		hid_err(hdev, "Asus failed to send configuration command: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	readbuf = kzalloc(FEATURE_KBD_REPORT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	if (!readbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	ret = hid_hw_raw_request(hdev, FEATURE_KBD_REPORT_ID, readbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 				 FEATURE_KBD_REPORT_SIZE, HID_FEATURE_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 				 HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		hid_err(hdev, "Asus failed to request functions: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		kfree(readbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	*kbd_func = readbuf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	kfree(readbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) static void asus_kbd_backlight_set(struct led_classdev *led_cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 				   enum led_brightness brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 						 cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	if (led->brightness == brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	led->brightness = brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	schedule_work(&led->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 						 cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	return led->brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) static void asus_kbd_backlight_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	if (led->removed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	buf[4] = led->brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	ret = asus_kbd_set_report(led->hdev, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) /* WMI-based keyboard backlight LED control (via asus-wmi driver) takes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437)  * precedence. We only activate HID-based backlight control when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438)  * WMI control is not available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	if (!IS_ENABLED(CONFIG_ASUS_WMI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 				       ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	return !!(value & ASUS_WMI_DSTS_PRESENCE_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) static int asus_kbd_register_leds(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	unsigned char kbd_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	/* Initialize keyboard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	ret = asus_kbd_init(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	/* Get keyboard functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	ret = asus_kbd_get_functions(hdev, &kbd_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	/* Check for backlight support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	if (!(kbd_func & SUPPORT_KBD_BACKLIGHT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	drvdata->kbd_backlight = devm_kzalloc(&hdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 					      sizeof(struct asus_kbd_leds),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 					      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	if (!drvdata->kbd_backlight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	drvdata->kbd_backlight->removed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	drvdata->kbd_backlight->brightness = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	drvdata->kbd_backlight->hdev = hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	drvdata->kbd_backlight->cdev.name = "asus::kbd_backlight";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	drvdata->kbd_backlight->cdev.max_brightness = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	drvdata->kbd_backlight->cdev.brightness_set = asus_kbd_backlight_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	drvdata->kbd_backlight->cdev.brightness_get = asus_kbd_backlight_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	ret = devm_led_classdev_register(&hdev->dev, &drvdata->kbd_backlight->cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		/* No need to have this still around */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		devm_kfree(&hdev->dev, drvdata->kbd_backlight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502)  * [0]       REPORT_ID (same value defined in report descriptor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503)  * [1]	     rest battery level. range [0..255]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504)  * [2]..[7]  Bluetooth hardware address (MAC address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505)  * [8]       charging status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506)  *            = 0 : AC offline / discharging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507)  *            = 1 : AC online  / charging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)  *            = 2 : AC online  / fully charged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) static int asus_parse_battery(struct asus_drvdata *drvdata, u8 *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	u8 sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	u8 lvl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	lvl = data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	sts = data[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	drvdata->battery_capacity = ((int)lvl * 100) / (int)BATTERY_LEVEL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	switch (sts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	case BATTERY_STAT_CHARGING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		val = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	case BATTERY_STAT_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		val = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	case BATTERY_STAT_DISCONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		val = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	drvdata->battery_stat = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) static int asus_report_battery(struct asus_drvdata *drvdata, u8 *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	/* notify only the autonomous event by device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	if ((drvdata->battery_in_query == false) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 			 (size == BATTERY_REPORT_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		power_supply_changed(drvdata->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) static int asus_battery_query(struct asus_drvdata *drvdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	buf = kmalloc(BATTERY_REPORT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	drvdata->battery_in_query = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	ret = hid_hw_raw_request(drvdata->hdev, BATTERY_REPORT_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 				buf, BATTERY_REPORT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 				HID_INPUT_REPORT, HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	drvdata->battery_in_query = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	if (ret == BATTERY_REPORT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 		ret = asus_parse_battery(drvdata, buf, BATTERY_REPORT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) static enum power_supply_property asus_battery_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	POWER_SUPPLY_PROP_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	POWER_SUPPLY_PROP_SCOPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	POWER_SUPPLY_PROP_MODEL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) #define	QUERY_MIN_INTERVAL	(60 * HZ)	/* 60[sec] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static int asus_battery_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 				enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 				union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	struct asus_drvdata *drvdata = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	case POWER_SUPPLY_PROP_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		if (time_before(drvdata->battery_next_query, jiffies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 			drvdata->battery_next_query =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 					 jiffies + QUERY_MIN_INTERVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 			ret = asus_battery_query(drvdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		if (psp == POWER_SUPPLY_PROP_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 			val->intval = drvdata->battery_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 			val->intval = drvdata->battery_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	case POWER_SUPPLY_PROP_PRESENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		val->intval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	case POWER_SUPPLY_PROP_SCOPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	case POWER_SUPPLY_PROP_MODEL_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		val->strval = drvdata->hdev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) static int asus_battery_probe(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	struct power_supply_config pscfg = { .drv_data = drvdata };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	drvdata->battery_capacity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	drvdata->battery_stat = POWER_SUPPLY_STATUS_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	drvdata->battery_in_query = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	drvdata->battery_desc.properties = asus_battery_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	drvdata->battery_desc.num_properties = ARRAY_SIZE(asus_battery_props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	drvdata->battery_desc.get_property = asus_battery_get_property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	drvdata->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	drvdata->battery_desc.use_for_apm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	drvdata->battery_desc.name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 					"asus-keyboard-%s-battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 					strlen(hdev->uniq) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 					hdev->uniq : dev_name(&hdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	if (!drvdata->battery_desc.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	drvdata->battery_next_query = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	drvdata->battery = devm_power_supply_register(&hdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 				&(drvdata->battery_desc), &pscfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	if (IS_ERR(drvdata->battery)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		ret = PTR_ERR(drvdata->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		drvdata->battery = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		hid_err(hdev, "Unable to register battery device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	power_supply_powers(drvdata->battery, &hdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	struct input_dev *input = hi->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	/* T100CHI uses MULTI_INPUT, bind the touchpad to the mouse hid_input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	if (drvdata->quirks & QUIRK_T100CHI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	    hi->report->id != T100CHI_MOUSE_REPORT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	/* Handle MULTI_INPUT on E1239T mouse/touchpad USB interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	if (drvdata->tp && (drvdata->quirks & QUIRK_MEDION_E1239T)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		switch (hi->report->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		case E1239T_TP_TOGGLE_REPORT_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			input_set_capability(input, EV_KEY, KEY_F21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			input->name = "Asus Touchpad Keys";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			drvdata->tp_kbd_input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		case INPUT_REPORT_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 			break; /* Touchpad report, handled below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			return 0; /* Ignore other reports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	if (drvdata->tp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		input_set_abs_params(input, ABS_MT_POSITION_X, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 				     drvdata->tp->max_x, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 				     drvdata->tp->max_y, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		input_abs_set_res(input, ABS_MT_POSITION_X, drvdata->tp->res_x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		input_abs_set_res(input, ABS_MT_POSITION_Y, drvdata->tp->res_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		if (drvdata->tp->contact_size >= 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			input_set_abs_params(input, ABS_TOOL_WIDTH, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 					     MAX_TOUCH_MAJOR, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 			input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 					     MAX_TOUCH_MAJOR, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			input_set_abs_params(input, ABS_MT_PRESSURE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 					      MAX_PRESSURE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		__set_bit(BTN_LEFT, input->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		ret = input_mt_init_slots(input, drvdata->tp->max_contacts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 					  INPUT_MT_POINTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			hid_err(hdev, "Asus input mt init slots failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	drvdata->input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	if (drvdata->enable_backlight &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	    !asus_kbd_wmi_led_control_present(hdev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	    asus_kbd_register_leds(hdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		hid_warn(hdev, "Failed to initialize backlight.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) #define asus_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 						    max, EV_KEY, (c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) static int asus_input_mapping(struct hid_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		struct hid_input *hi, struct hid_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		struct hid_usage *usage, unsigned long **bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		int *max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	if (drvdata->quirks & QUIRK_SKIP_INPUT_MAPPING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		/* Don't map anything from the HID report.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		 * We do it all manually in asus_input_configured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	 * Ignore a bunch of bogus collections in the T100CHI descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	 * This avoids a bunch of non-functional hid_input devices getting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	 * created because of the T100CHI using HID_QUIRK_MULTI_INPUT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	if ((drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	    (field->application == (HID_UP_GENDESK | 0x0080) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	     field->application == HID_GD_MOUSE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	     usage->hid == (HID_UP_GENDEVCTRLS | 0x0024) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	     usage->hid == (HID_UP_GENDEVCTRLS | 0x0025) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	     usage->hid == (HID_UP_GENDEVCTRLS | 0x0026)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	/* ASUS-specific keyboard hotkeys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	if ((usage->hid & HID_USAGE_PAGE) == 0xff310000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		switch (usage->hid & HID_USAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		case 0x6c: asus_map_key_clear(KEY_SLEEP);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		case 0x7c: asus_map_key_clear(KEY_MICMUTE);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		case 0x82: asus_map_key_clear(KEY_CAMERA);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		case 0x88: asus_map_key_clear(KEY_RFKILL);			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		case 0xb5: asus_map_key_clear(KEY_CALC);			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		case 0xc4: asus_map_key_clear(KEY_KBDILLUMUP);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		case 0xc5: asus_map_key_clear(KEY_KBDILLUMDOWN);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		/* ASUS touchpad toggle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		case 0x6b: asus_map_key_clear(KEY_F21);			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		/* ROG key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		case 0x38: asus_map_key_clear(KEY_PROG1);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		/* Fn+C ASUS Splendid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		case 0xba: asus_map_key_clear(KEY_PROG2);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		/* Fn+Space Power4Gear Hybrid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		case 0x5c: asus_map_key_clear(KEY_PROG3);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		/* Fn+F5 "fan" symbol on FX503VD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		case 0x99: asus_map_key_clear(KEY_PROG4);		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			/* ASUS lazily declares 256 usages, ignore the rest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			 * as some make the keyboard appear as a pointer device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		 * Check and enable backlight only on devices with UsagePage ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		 * 0xff31 to avoid initializing the keyboard firmware multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		 * times on devices with multiple HID descriptors but same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		 * PID/VID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			drvdata->enable_backlight = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		set_bit(EV_REP, hi->input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		switch (usage->hid & HID_USAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		case 0xff01: asus_map_key_clear(BTN_1);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		case 0xff02: asus_map_key_clear(BTN_2);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		case 0xff03: asus_map_key_clear(BTN_3);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		case 0xff04: asus_map_key_clear(BTN_4);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		case 0xff05: asus_map_key_clear(BTN_5);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		case 0xff06: asus_map_key_clear(BTN_6);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		case 0xff07: asus_map_key_clear(BTN_7);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		case 0xff08: asus_map_key_clear(BTN_8);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		case 0xff09: asus_map_key_clear(BTN_9);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		case 0xff0a: asus_map_key_clear(BTN_A);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		case 0xff0b: asus_map_key_clear(BTN_B);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		case 0x00f1: asus_map_key_clear(KEY_WLAN);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		case 0x00f2: asus_map_key_clear(KEY_BRIGHTNESSDOWN);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		case 0x00f3: asus_map_key_clear(KEY_BRIGHTNESSUP);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		case 0x00f4: asus_map_key_clear(KEY_DISPLAY_OFF);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		case 0x00f7: asus_map_key_clear(KEY_CAMERA);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		case 0x00f8: asus_map_key_clear(KEY_PROG1);	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		set_bit(EV_REP, hi->input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	if (drvdata->quirks & QUIRK_NO_CONSUMER_USAGES &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		(usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		switch (usage->hid & HID_USAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		case 0xe2: /* Mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		case 0xe9: /* Volume up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		case 0xea: /* Volume down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			/* Ignore dummy Consumer usages which make the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 			 * keyboard incorrectly appear as a pointer device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	 * The mute button is broken and only sends press events, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	 * deal with this in our raw_event handler, so do not map it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	if ((drvdata->quirks & QUIRK_MEDION_E1239T) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	    usage->hid == (HID_UP_CONSUMER | 0xe2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		input_set_capability(hi->input, EV_KEY, KEY_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) static int asus_start_multitouch(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	static const unsigned char buf[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		FEATURE_REPORT_ID, 0x00, 0x03, 0x01, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	if (!dmabuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		hid_err(hdev, "Asus failed to alloc dma buf: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, sizeof(buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 					HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	kfree(dmabuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	if (ret != sizeof(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		hid_err(hdev, "Asus failed to start multitouch: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	if (drvdata->tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		return asus_start_multitouch(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	struct asus_drvdata *drvdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	if (drvdata == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		hid_err(hdev, "Can't alloc Asus descriptor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	hid_set_drvdata(hdev, drvdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	drvdata->quirks = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	 * T90CHI's keyboard dock returns same ID values as T100CHI's dock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	 * Thus, identify T90CHI dock with product name string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	if (strstr(hdev->name, "T90CHI")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		drvdata->quirks &= ~QUIRK_T100CHI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		drvdata->quirks |= QUIRK_T90CHI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		drvdata->tp = &asus_i2c_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 			drvdata->quirks = QUIRK_SKIP_INPUT_MAPPING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			 * The T100HA uses the same USB-ids as the T100TAF and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			 * the T200TA uses the same USB-ids as the T100TA, while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			 * both have different max x/y values as the T100TA[F].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			if (dmi_match(DMI_PRODUCT_NAME, "T100HAN"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 				drvdata->tp = &asus_t100ha_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 			else if (dmi_match(DMI_PRODUCT_NAME, "T200TA"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 				drvdata->tp = &asus_t200ta_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 				drvdata->tp = &asus_t100ta_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	if (drvdata->quirks & QUIRK_T100CHI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		 * All functionality is on a single HID interface and for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		 * userspace the touchpad must be a separate input_dev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		hdev->quirks |= HID_QUIRK_MULTI_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		drvdata->tp = &asus_t100chi_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	if ((drvdata->quirks & QUIRK_MEDION_E1239T) && hid_is_usb(hdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		struct usb_host_interface *alt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 			to_usb_interface(hdev->dev.parent)->altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		if (alt->desc.bInterfaceNumber == MEDION_E1239T_TPAD_INTF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 			/* For separate input-devs for tp and tp toggle key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 			hdev->quirks |= HID_QUIRK_MULTI_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 			drvdata->quirks |= QUIRK_SKIP_INPUT_MAPPING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 			drvdata->tp = &medion_e1239t_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	if (drvdata->quirks & QUIRK_NO_INIT_REPORTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	drvdata->hdev = hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	if (drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		ret = asus_battery_probe(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			hid_err(hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			    "Asus hid battery_probe failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	ret = hid_parse(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		hid_err(hdev, "Asus hid parse failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	/* use hid-multitouch for T101HA touchpad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (id->driver_data & QUIRK_T101HA_DOCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	    hdev->collection->usage == HID_GD_MOUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		hid_err(hdev, "Asus hw start failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	if (!drvdata->input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		hid_err(hdev, "Asus input not registered\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		goto err_stop_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	if (drvdata->tp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		drvdata->input->name = "Asus TouchPad";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		drvdata->input->name = "Asus Keyboard";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	if (drvdata->tp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		ret = asus_start_multitouch(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 			goto err_stop_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) err_stop_hw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	hid_hw_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static void asus_remove(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	if (drvdata->kbd_backlight) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		drvdata->kbd_backlight->removed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		cancel_work_sync(&drvdata->kbd_backlight->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	hid_hw_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static const __u8 asus_g752_fixed_rdesc[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)         0x19, 0x00,			/*   Usage Minimum (0x00)       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)         0x2A, 0xFF, 0x00,		/*   Usage Maximum (0xFF)       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		unsigned int *rsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	if (drvdata->quirks & QUIRK_FIX_NOTEBOOK_REPORT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 			*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		hid_info(hdev, "Fixing up Asus notebook report descriptor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		rdesc[55] = 0xdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	/* For the T100TA/T200TA keyboard dock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	if (drvdata->quirks & QUIRK_T100_KEYBOARD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		 (*rsize == 76 || *rsize == 101) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		 rdesc[73] == 0x81 && rdesc[74] == 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		hid_info(hdev, "Fixing up Asus T100 keyb report descriptor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		rdesc[74] &= ~HID_MAIN_ITEM_CONSTANT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	/* For the T100CHI/T90CHI keyboard dock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	if (drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		int rsize_orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		int offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		if (drvdata->quirks & QUIRK_T100CHI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			rsize_orig = 403;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			offs = 388;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			rsize_orig = 306;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			offs = 291;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		 * Change Usage (76h) to Usage Minimum (00h), Usage Maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		 * (FFh) and clear the flags in the Input() byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		 * Note the descriptor has a bogus 0 byte at the end so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		 * only need 1 extra byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		if (*rsize == rsize_orig &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 			rdesc[offs] == 0x09 && rdesc[offs + 1] == 0x76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			*rsize = rsize_orig + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			if (!rdesc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 				return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			hid_info(hdev, "Fixing up %s keyb report descriptor\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 				drvdata->quirks & QUIRK_T100CHI ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 				"T100CHI" : "T90CHI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			memmove(rdesc + offs + 4, rdesc + offs + 2, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			rdesc[offs] = 0x19;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			rdesc[offs + 1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 			rdesc[offs + 2] = 0x29;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			rdesc[offs + 3] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 			rdesc[offs + 14] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	if (drvdata->quirks & QUIRK_G752_KEYBOARD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		 *rsize == 75 && rdesc[61] == 0x15 && rdesc[62] == 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		/* report is missing usage mninum and maximum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		__u8 *new_rdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		size_t new_size = *rsize + sizeof(asus_g752_fixed_rdesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		new_rdesc = devm_kzalloc(&hdev->dev, new_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		if (new_rdesc == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 			return rdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		hid_info(hdev, "Fixing up Asus G752 keyb report descriptor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		/* copy the valid part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		memcpy(new_rdesc, rdesc, 61);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		/* insert missing part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		memcpy(new_rdesc + 61, asus_g752_fixed_rdesc, sizeof(asus_g752_fixed_rdesc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		/* copy remaining data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		memcpy(new_rdesc + 61 + sizeof(asus_g752_fixed_rdesc), rdesc + 61, *rsize - 61);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		*rsize = new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		rdesc = new_rdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	return rdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) static const struct hid_device_id asus_devices[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD), I2C_KEYBOARD_QUIRKS},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD), I2C_TOUCHPAD_QUIRKS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1), QUIRK_USE_KBD_BACKLIGHT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2), QUIRK_USE_KBD_BACKLIGHT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3), QUIRK_G752_KEYBOARD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	  QUIRK_USE_KBD_BACKLIGHT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 		USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	  QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	  QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD), QUIRK_T101HA_DOCK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_ASUS_AK1D) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), QUIRK_T100CHI },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	{ HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE_MEDION_E1239T),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		QUIRK_MEDION_E1239T },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) MODULE_DEVICE_TABLE(hid, asus_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static struct hid_driver asus_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	.name			= "asus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	.id_table		= asus_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	.report_fixup		= asus_report_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	.probe                  = asus_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	.remove			= asus_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	.input_mapping          = asus_input_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	.input_configured       = asus_input_configured,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	.reset_resume           = asus_reset_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	.event			= asus_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	.raw_event		= asus_raw_event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) module_hid_driver(asus_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) MODULE_LICENSE("GPL");