Linux Audio

Check our new training course

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