linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] HID: add Apple Magic Mouse 2 support
@ 2021-03-27 13:05 John Chen
  2021-03-27 13:05 ` [PATCH 1/4] HID: magicmouse: " John Chen
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: John Chen @ 2021-03-27 13:05 UTC (permalink / raw)
  To: linux-kernel
  Cc: Rohit Pidaparthi, RicardoEPRodrigues, Jiri Kosina,
	Benjamin Tissoires, John Chen

The HID descriptor of Magic Mouse 2 contains BTN_LEFT, BTN_RIGHT, REL_X,
REL_Y, whether it's charging, whether it's fully charged, and battery
capacity.

$ xxd -p report_descriptor
05010902a101851205091901290215002501950275018102950175068103
05010901a1001601f826ff073601fb46ff046513550d0930093175109502
8106750895028101c00602ff09558555150026ff0075089540b1a2c00600
ff0914a10185900584750195031500250109610585094409468102950581
0175089501150026ff0009658102c000

As hidinput can handle the BTNs and RELs, the Magic Mouse 2 already
functions as a basic mouse. Nevertheless, It should be reasonable to
extend hid-magicmouse to support Magic Mouse 2 as well. Furthermore,
hidinput is patched to handle the battery capacity.

This work is based on Recardo's, which is in turned based on Rohitpid's.
Their GitHub repositories are linked below:
https://github.com/RicardoEPRodrigues/magicmouse-hid
https://github.com/rohitpid/Linux-Magic-Trackpad-2-Driver

John Chen (4):
  HID: magicmouse: add Apple Magic Mouse 2 support
  HID: magicmouse: fix 3 button emulation of Mouse 2
  HID: magicmouse: fix reconnection of Magic Mouse 2
  HID: input: map battery capacity (00850065)

 drivers/hid/hid-debug.c      |   1 +
 drivers/hid/hid-ids.h        |   1 +
 drivers/hid/hid-input.c      |  11 +++
 drivers/hid/hid-magicmouse.c | 156 ++++++++++++++++++++++++++++-------
 include/linux/hid.h          |   3 +
 5 files changed, 140 insertions(+), 32 deletions(-)

-- 
2.31.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/4] HID: magicmouse: add Apple Magic Mouse 2 support
  2021-03-27 13:05 [PATCH 0/4] HID: add Apple Magic Mouse 2 support John Chen
@ 2021-03-27 13:05 ` John Chen
  2021-03-27 13:05 ` [PATCH 2/4] HID: magicmouse: fix 3 button emulation of Mouse 2 John Chen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: John Chen @ 2021-03-27 13:05 UTC (permalink / raw)
  To: linux-kernel
  Cc: Rohit Pidaparthi, RicardoEPRodrigues, Jiri Kosina,
	Benjamin Tissoires, John Chen

Bluetooth device
	Vendor 004c (Apple)
	Device 0269 (Magic Mouse 2)

Add support for Apple Magic Mouse 2, putting the device in multi-touch
mode.

Co-authored-by: Rohit Pidaparthi <rohitpid@gmail.com>
Co-authored-by: RicardoEPRodrigues <ricardo.e.p.rodrigues@gmail.com>
Signed-off-by: John Chen <johnchen902@gmail.com>
---
 drivers/hid/hid-ids.h        |  1 +
 drivers/hid/hid-magicmouse.c | 53 ++++++++++++++++++++++++++++++++----
 2 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index e42aaae3138f..fa0edf03570a 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -93,6 +93,7 @@
 #define BT_VENDOR_ID_APPLE		0x004c
 #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE	0x0304
 #define USB_DEVICE_ID_APPLE_MAGICMOUSE	0x030d
+#define USB_DEVICE_ID_APPLE_MAGICMOUSE2	0x0269
 #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD	0x030e
 #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2	0x0265
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI	0x020e
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index abd86903875f..7aad6ca56780 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -54,6 +54,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
 #define TRACKPAD2_USB_REPORT_ID 0x02
 #define TRACKPAD2_BT_REPORT_ID 0x31
 #define MOUSE_REPORT_ID    0x29
+#define MOUSE2_REPORT_ID   0x12
 #define DOUBLE_REPORT_ID   0xf7
 /* These definitions are not precise, but they're close enough.  (Bits
  * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
@@ -195,7 +196,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 	int id, x, y, size, orientation, touch_major, touch_minor, state, down;
 	int pressure = 0;
 
-	if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+	if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
+	    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
 		id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
 		x = (tdata[1] << 28 | tdata[0] << 20) >> 20;
 		y = -((tdata[2] << 24 | tdata[1] << 16) >> 20);
@@ -296,7 +298,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 			input_report_abs(input, ABS_MT_PRESSURE, pressure);
 
 		if (report_undeciphered) {
-			if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
+			if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
+			    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2)
 				input_event(input, EV_MSC, MSC_RAW, tdata[7]);
 			else if (input->id.product !=
 					USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)
@@ -380,6 +383,34 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 		 * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
 		 */
 		break;
+	case MOUSE2_REPORT_ID:
+		/* Size is either 8 or (14 + 8 * N) */
+		if (size != 8 && (size < 14 || (size - 14) % 8 != 0))
+			return 0;
+		npoints = (size - 14) / 8;
+		if (npoints > 15) {
+			hid_warn(hdev, "invalid size value (%d) for MOUSE2_REPORT_ID\n",
+					size);
+			return 0;
+		}
+		msc->ntouches = 0;
+		for (ii = 0; ii < npoints; ii++)
+			magicmouse_emit_touch(msc, ii, data + ii * 8 + 14);
+
+		/* When emulating three-button mode, it is important
+		 * to have the current touch information before
+		 * generating a click event.
+		 */
+		x = (int)((data[3] << 24) | (data[2] << 16)) >> 16;
+		y = (int)((data[5] << 24) | (data[4] << 16)) >> 16;
+		clicks = data[1];
+
+		/* The following bits provide a device specific timestamp. They
+		 * are unused here.
+		 *
+		 * ts = data[11] >> 6 | data[12] << 2 | data[13] << 10;
+		 */
+		break;
 	case DOUBLE_REPORT_ID:
 		/* Sometimes the trackpad sends two touch reports in one
 		 * packet.
@@ -392,7 +423,8 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 		return 0;
 	}
 
-	if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+	if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
+	    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
 		magicmouse_emit_buttons(msc, clicks & 3);
 		input_report_rel(input, REL_X, x);
 		input_report_rel(input, REL_Y, y);
@@ -415,7 +447,8 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
 
 	__set_bit(EV_KEY, input->evbit);
 
-	if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+	if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
+	    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
 		__set_bit(BTN_LEFT, input->keybit);
 		__set_bit(BTN_RIGHT, input->keybit);
 		if (emulate_3button)
@@ -480,7 +513,8 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
 	 * the origin at the same position, and just uses the additive
 	 * inverse of the reported Y.
 	 */
-	if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+	if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
+	    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
 		input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
 		input_set_abs_params(input, ABS_MT_POSITION_X,
 				     MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
@@ -586,6 +620,7 @@ static int magicmouse_probe(struct hid_device *hdev,
 {
 	const u8 *feature;
 	const u8 feature_mt[] = { 0xD7, 0x01 };
+	const u8 feature_mt_mouse2[] = { 0xF1, 0x02, 0x01 };
 	const u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 };
 	const u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 };
 	u8 *buf;
@@ -631,6 +666,9 @@ static int magicmouse_probe(struct hid_device *hdev,
 	if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
 		report = hid_register_report(hdev, HID_INPUT_REPORT,
 			MOUSE_REPORT_ID, 0);
+	else if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2)
+		report = hid_register_report(hdev, HID_INPUT_REPORT,
+			MOUSE2_REPORT_ID, 0);
 	else if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
 		if (id->vendor == BT_VENDOR_ID_APPLE)
 			report = hid_register_report(hdev, HID_INPUT_REPORT,
@@ -660,6 +698,9 @@ static int magicmouse_probe(struct hid_device *hdev,
 			feature_size = sizeof(feature_mt_trackpad2_usb);
 			feature = feature_mt_trackpad2_usb;
 		}
+	} else if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
+		feature_size = sizeof(feature_mt_mouse2);
+		feature = feature_mt_mouse2;
 	} else {
 		feature_size = sizeof(feature_mt);
 		feature = feature_mt;
@@ -696,6 +737,8 @@ static int magicmouse_probe(struct hid_device *hdev,
 static const struct hid_device_id magic_mice[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
+	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
+		USB_DEVICE_ID_APPLE_MAGICMOUSE2), .driver_data = 0 },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
 	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/4] HID: magicmouse: fix 3 button emulation of Mouse 2
  2021-03-27 13:05 [PATCH 0/4] HID: add Apple Magic Mouse 2 support John Chen
  2021-03-27 13:05 ` [PATCH 1/4] HID: magicmouse: " John Chen
@ 2021-03-27 13:05 ` John Chen
  2021-03-27 13:05 ` [PATCH 3/4] HID: magicmouse: fix reconnection of Magic " John Chen
  2021-03-27 13:05 ` [PATCH 4/4] HID: input: map battery capacity (00850065) John Chen
  3 siblings, 0 replies; 8+ messages in thread
From: John Chen @ 2021-03-27 13:05 UTC (permalink / raw)
  To: linux-kernel
  Cc: Rohit Pidaparthi, RicardoEPRodrigues, Jiri Kosina,
	Benjamin Tissoires, John Chen

It is observed that, with 3 button emulation, when middle button is
clicked, either the left button or right button is clicked as well. It
is caused by hidinput "correctly" acting on the event, oblivious to the
3 button emulation.

As raw_event has taken care of everything, no further processing is
needed. However, the only way to stop at raw_event is to return an error
(negative) value. Therefore, the processing is stopped at event instead.

Signed-off-by: John Chen <johnchen902@gmail.com>
---
 drivers/hid/hid-magicmouse.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 7aad6ca56780..c646b4cd3783 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -440,6 +440,21 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 	return 1;
 }
 
+static int magicmouse_event(struct hid_device *hdev, struct hid_field *field,
+		struct hid_usage *usage, __s32 value)
+{
+	struct magicmouse_sc *msc = hid_get_drvdata(hdev);
+	if (msc->input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 &&
+	    field->report->id == MOUSE2_REPORT_ID) {
+		// magic_mouse_raw_event has done all the work. Skip hidinput.
+		//
+		// Specifically, hidinput may modify BTN_LEFT and BTN_RIGHT,
+		// breaking emulate_3button.
+		return 1;
+	}
+	return 0;
+}
+
 static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
 {
 	int error;
@@ -754,6 +769,7 @@ static struct hid_driver magicmouse_driver = {
 	.id_table = magic_mice,
 	.probe = magicmouse_probe,
 	.raw_event = magicmouse_raw_event,
+	.event = magicmouse_event,
 	.input_mapping = magicmouse_input_mapping,
 	.input_configured = magicmouse_input_configured,
 };
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/4] HID: magicmouse: fix reconnection of Magic Mouse 2
  2021-03-27 13:05 [PATCH 0/4] HID: add Apple Magic Mouse 2 support John Chen
  2021-03-27 13:05 ` [PATCH 1/4] HID: magicmouse: " John Chen
  2021-03-27 13:05 ` [PATCH 2/4] HID: magicmouse: fix 3 button emulation of Mouse 2 John Chen
@ 2021-03-27 13:05 ` John Chen
  2021-03-27 13:05 ` [PATCH 4/4] HID: input: map battery capacity (00850065) John Chen
  3 siblings, 0 replies; 8+ messages in thread
From: John Chen @ 2021-03-27 13:05 UTC (permalink / raw)
  To: linux-kernel
  Cc: Rohit Pidaparthi, RicardoEPRodrigues, Jiri Kosina,
	Benjamin Tissoires, John Chen

It is observed that the Magic Mouse 2 would not enter multi-touch mode
unless the mouse is connected before loading the module. It seems to be
a quirk specific to Magic Mouse 2

Retrying after 500ms fixes the problem for me. The delay can't be
reduced much further --- 300ms didn't work for me. Retrying immediately
after receiving an event didn't work either.

Signed-off-by: John Chen <johnchen902@gmail.com>
---
 drivers/hid/hid-magicmouse.c | 93 ++++++++++++++++++++++++------------
 1 file changed, 63 insertions(+), 30 deletions(-)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index c646b4cd3783..69aefef9fe07 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -16,6 +16,7 @@
 #include <linux/input/mt.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/workqueue.h>
 
 #include "hid-ids.h"
 
@@ -128,6 +129,9 @@ struct magicmouse_sc {
 		u8 size;
 	} touches[16];
 	int tracking_ids[16];
+
+	struct hid_device *hdev;
+	struct delayed_work work;
 };
 
 static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -629,9 +633,7 @@ static int magicmouse_input_configured(struct hid_device *hdev,
 	return 0;
 }
 
-
-static int magicmouse_probe(struct hid_device *hdev,
-	const struct hid_device_id *id)
+static int magicmouse_enable_multitouch(struct hid_device *hdev)
 {
 	const u8 *feature;
 	const u8 feature_mt[] = { 0xD7, 0x01 };
@@ -639,10 +641,52 @@ static int magicmouse_probe(struct hid_device *hdev,
 	const u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 };
 	const u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 };
 	u8 *buf;
+	int ret;
+	int feature_size;
+
+	if (hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+		if (hdev->vendor == BT_VENDOR_ID_APPLE) {
+			feature_size = sizeof(feature_mt_trackpad2_bt);
+			feature = feature_mt_trackpad2_bt;
+		} else { /* USB_VENDOR_ID_APPLE */
+			feature_size = sizeof(feature_mt_trackpad2_usb);
+			feature = feature_mt_trackpad2_usb;
+		}
+	} else if (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
+		feature_size = sizeof(feature_mt_mouse2);
+		feature = feature_mt_mouse2;
+	} else {
+		feature_size = sizeof(feature_mt);
+		feature = feature_mt;
+	}
+
+	buf = kmemdup(feature, feature_size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = hid_hw_raw_request(hdev, buf[0], buf, feature_size,
+				HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+	kfree(buf);
+	return ret;
+}
+
+static void magicmouse_enable_mt_work(struct work_struct *work)
+{
+	struct magicmouse_sc *msc =
+		container_of(work, struct magicmouse_sc, work.work);
+	int ret;
+
+	ret = magicmouse_enable_multitouch(msc->hdev);
+	if (ret < 0)
+		hid_err(msc->hdev, "unable to request touch data (%d)\n", ret);
+}
+
+static int magicmouse_probe(struct hid_device *hdev,
+	const struct hid_device_id *id)
+{
 	struct magicmouse_sc *msc;
 	struct hid_report *report;
 	int ret;
-	int feature_size;
 
 	if (id->vendor == USB_VENDOR_ID_APPLE &&
 	    id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
@@ -656,6 +700,8 @@ static int magicmouse_probe(struct hid_device *hdev,
 	}
 
 	msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
+	msc->hdev = hdev;
+	INIT_DEFERRABLE_WORK(&msc->work, magicmouse_enable_mt_work);
 
 	msc->quirks = id->driver_data;
 	hid_set_drvdata(hdev, msc);
@@ -705,28 +751,6 @@ static int magicmouse_probe(struct hid_device *hdev,
 	}
 	report->size = 6;
 
-	if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
-		if (id->vendor == BT_VENDOR_ID_APPLE) {
-			feature_size = sizeof(feature_mt_trackpad2_bt);
-			feature = feature_mt_trackpad2_bt;
-		} else { /* USB_VENDOR_ID_APPLE */
-			feature_size = sizeof(feature_mt_trackpad2_usb);
-			feature = feature_mt_trackpad2_usb;
-		}
-	} else if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
-		feature_size = sizeof(feature_mt_mouse2);
-		feature = feature_mt_mouse2;
-	} else {
-		feature_size = sizeof(feature_mt);
-		feature = feature_mt;
-	}
-
-	buf = kmemdup(feature, feature_size, GFP_KERNEL);
-	if (!buf) {
-		ret = -ENOMEM;
-		goto err_stop_hw;
-	}
-
 	/*
 	 * Some devices repond with 'invalid report id' when feature
 	 * report switching it into multitouch mode is sent to it.
@@ -735,13 +759,14 @@ static int magicmouse_probe(struct hid_device *hdev,
 	 * but there seems to be no other way of switching the mode.
 	 * Thus the super-ugly hacky success check below.
 	 */
-	ret = hid_hw_raw_request(hdev, buf[0], buf, feature_size,
-				HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
-	kfree(buf);
-	if (ret != -EIO && ret != feature_size) {
+	ret = magicmouse_enable_multitouch(hdev);
+	if (ret != -EIO && ret < 0) {
 		hid_err(hdev, "unable to request touch data (%d)\n", ret);
 		goto err_stop_hw;
 	}
+	if (ret == -EIO && id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
+		schedule_delayed_work(&msc->work, msecs_to_jiffies(500));
+	}
 
 	return 0;
 err_stop_hw:
@@ -749,6 +774,13 @@ static int magicmouse_probe(struct hid_device *hdev,
 	return ret;
 }
 
+static void magicmouse_remove(struct hid_device *hdev)
+{
+	struct magicmouse_sc *msc = hid_get_drvdata(hdev);
+	cancel_delayed_work_sync(&msc->work);
+	hid_hw_stop(hdev);
+}
+
 static const struct hid_device_id magic_mice[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
@@ -768,6 +800,7 @@ static struct hid_driver magicmouse_driver = {
 	.name = "magicmouse",
 	.id_table = magic_mice,
 	.probe = magicmouse_probe,
+	.remove = magicmouse_remove,
 	.raw_event = magicmouse_raw_event,
 	.event = magicmouse_event,
 	.input_mapping = magicmouse_input_mapping,
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/4] HID: input: map battery capacity (00850065)
  2021-03-27 13:05 [PATCH 0/4] HID: add Apple Magic Mouse 2 support John Chen
                   ` (2 preceding siblings ...)
  2021-03-27 13:05 ` [PATCH 3/4] HID: magicmouse: fix reconnection of Magic " John Chen
@ 2021-03-27 13:05 ` John Chen
  2021-03-27 14:14   ` Pochang Chen
                     ` (2 more replies)
  3 siblings, 3 replies; 8+ messages in thread
From: John Chen @ 2021-03-27 13:05 UTC (permalink / raw)
  To: linux-kernel
  Cc: Rohit Pidaparthi, RicardoEPRodrigues, Jiri Kosina,
	Benjamin Tissoires, John Chen

This is the capacity in percentage, relative to design capacity.
Specifically, it is present in Apple Magic Mouse 2.

In contrast, usage 00850064 is also the capacity in percentage, but is
relative to full capacity. It is not mapped here because I don't have
such device.

Signed-off-by: John Chen <johnchen902@gmail.com>
---
 drivers/hid/hid-debug.c |  1 +
 drivers/hid/hid-input.c | 11 +++++++++++
 include/linux/hid.h     |  3 +++
 3 files changed, 15 insertions(+)

diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index d7eaf9100370..59f8d716d78f 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -417,6 +417,7 @@ static const struct hid_usage_entry hid_usage_table[] = {
     { 0x85, 0x44, "Charging" },
     { 0x85, 0x45, "Discharging" },
     { 0x85, 0x4b, "NeedReplacement" },
+    { 0x85, 0x65, "AbsoluteStateOfCharge" },
     { 0x85, 0x66, "RemainingCapacity" },
     { 0x85, 0x68, "RunTimeToEmpty" },
     { 0x85, 0x6a, "AverageTimeToFull" },
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 236bccd37760..5dea3669a927 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1074,6 +1074,17 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 		}
 		goto unknown;
 
+	case HID_UP_BATTERY:
+		switch (usage->hid) {
+		case HID_BAT_ABSOLUTESTATEOFCHARGE:
+			hidinput_setup_battery(device, HID_INPUT_REPORT, field);
+			usage->type = EV_PWR;
+			device->battery_min = 0;
+			device->battery_max = 100;
+			return;
+		}
+		goto unknown;
+
 	case HID_UP_HPVENDOR:	/* Reported on a Dutch layout HP5308 */
 		set_bit(EV_REP, input->evbit);
 		switch (usage->hid & HID_USAGE) {
diff --git a/include/linux/hid.h b/include/linux/hid.h
index ef702b3f56e3..b40e1abbe11d 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -153,6 +153,7 @@ struct hid_item {
 #define HID_UP_CONSUMER		0x000c0000
 #define HID_UP_DIGITIZER	0x000d0000
 #define HID_UP_PID		0x000f0000
+#define HID_UP_BATTERY		0x00850000
 #define HID_UP_HPVENDOR         0xff7f0000
 #define HID_UP_HPVENDOR2        0xff010000
 #define HID_UP_MSVENDOR		0xff000000
@@ -297,6 +298,8 @@ struct hid_item {
 #define HID_DG_TOOLSERIALNUMBER	0x000d005b
 #define HID_DG_LATENCYMODE	0x000d0060
 
+#define HID_BAT_ABSOLUTESTATEOFCHARGE	0x00850065
+
 #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS	0xff310076
 /*
  * HID report types --- Ouch! HID spec says 1 2 3!
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] HID: input: map battery capacity (00850065)
  2021-03-27 13:05 ` [PATCH 4/4] HID: input: map battery capacity (00850065) John Chen
@ 2021-03-27 14:14   ` Pochang Chen
  2021-03-27 17:22   ` kernel test robot
  2021-03-27 17:50   ` kernel test robot
  2 siblings, 0 replies; 8+ messages in thread
From: Pochang Chen @ 2021-03-27 14:14 UTC (permalink / raw)
  To: linux-kernel
  Cc: Rohit Pidaparthi, RicardoEPRodrigues, Jiri Kosina, Benjamin Tissoires

On Sat, Mar 27, 2021 at 9:06 PM John Chen <johnchen902@gmail.com> wrote:
> +                       hidinput_setup_battery(device, HID_INPUT_REPORT, field);
> +                       usage->type = EV_PWR;
> +                       device->battery_min = 0;
> +                       device->battery_max = 100;

I just realized that this won't compile without CONFIG_HID_BATTERY_STRENGTH.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] HID: input: map battery capacity (00850065)
  2021-03-27 13:05 ` [PATCH 4/4] HID: input: map battery capacity (00850065) John Chen
  2021-03-27 14:14   ` Pochang Chen
@ 2021-03-27 17:22   ` kernel test robot
  2021-03-27 17:50   ` kernel test robot
  2 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2021-03-27 17:22 UTC (permalink / raw)
  To: John Chen, linux-kernel
  Cc: kbuild-all, Rohit Pidaparthi, RicardoEPRodrigues, Jiri Kosina,
	Benjamin Tissoires, John Chen

[-- Attachment #1: Type: text/plain, Size: 29406 bytes --]

Hi John,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hid/for-next]
[also build test ERROR on linux/master linus/master v5.12-rc4 next-20210326]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/John-Chen/HID-add-Apple-Magic-Mouse-2-support/20210327-211004
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
config: x86_64-kexec (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/00e05cc61c9d267c5857d61fd40638d560460f89
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review John-Chen/HID-add-Apple-Magic-Mouse-2-support/20210327-211004
        git checkout 00e05cc61c9d267c5857d61fd40638d560460f89
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/hid/hid-input.c: In function 'hidinput_configure_usage':
>> drivers/hid/hid-input.c:1082:10: error: 'struct hid_device' has no member named 'battery_min'
    1082 |    device->battery_min = 0;
         |          ^~
>> drivers/hid/hid-input.c:1083:10: error: 'struct hid_device' has no member named 'battery_max'
    1083 |    device->battery_max = 100;
         |          ^~


vim +1082 drivers/hid/hid-input.c

   568	
   569	static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
   570					     struct hid_usage *usage)
   571	{
   572		struct input_dev *input = hidinput->input;
   573		struct hid_device *device = input_get_drvdata(input);
   574		int max = 0, code;
   575		unsigned long *bit = NULL;
   576	
   577		field->hidinput = hidinput;
   578	
   579		if (field->flags & HID_MAIN_ITEM_CONSTANT)
   580			goto ignore;
   581	
   582		/* Ignore if report count is out of bounds. */
   583		if (field->report_count < 1)
   584			goto ignore;
   585	
   586		/* only LED usages are supported in output fields */
   587		if (field->report_type == HID_OUTPUT_REPORT &&
   588				(usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
   589			goto ignore;
   590		}
   591	
   592		if (device->driver->input_mapping) {
   593			int ret = device->driver->input_mapping(device, hidinput, field,
   594					usage, &bit, &max);
   595			if (ret > 0)
   596				goto mapped;
   597			if (ret < 0)
   598				goto ignore;
   599		}
   600	
   601		switch (usage->hid & HID_USAGE_PAGE) {
   602		case HID_UP_UNDEFINED:
   603			goto ignore;
   604	
   605		case HID_UP_KEYBOARD:
   606			set_bit(EV_REP, input->evbit);
   607	
   608			if ((usage->hid & HID_USAGE) < 256) {
   609				if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore;
   610				map_key_clear(hid_keyboard[usage->hid & HID_USAGE]);
   611			} else
   612				map_key(KEY_UNKNOWN);
   613	
   614			break;
   615	
   616		case HID_UP_BUTTON:
   617			code = ((usage->hid - 1) & HID_USAGE);
   618	
   619			switch (field->application) {
   620			case HID_GD_MOUSE:
   621			case HID_GD_POINTER:  code += BTN_MOUSE; break;
   622			case HID_GD_JOYSTICK:
   623					if (code <= 0xf)
   624						code += BTN_JOYSTICK;
   625					else
   626						code += BTN_TRIGGER_HAPPY - 0x10;
   627					break;
   628			case HID_GD_GAMEPAD:
   629					if (code <= 0xf)
   630						code += BTN_GAMEPAD;
   631					else
   632						code += BTN_TRIGGER_HAPPY - 0x10;
   633					break;
   634			default:
   635				switch (field->physical) {
   636				case HID_GD_MOUSE:
   637				case HID_GD_POINTER:  code += BTN_MOUSE; break;
   638				case HID_GD_JOYSTICK: code += BTN_JOYSTICK; break;
   639				case HID_GD_GAMEPAD:  code += BTN_GAMEPAD; break;
   640				default:              code += BTN_MISC;
   641				}
   642			}
   643	
   644			map_key(code);
   645			break;
   646	
   647		case HID_UP_SIMULATION:
   648			switch (usage->hid & 0xffff) {
   649			case 0xba: map_abs(ABS_RUDDER);   break;
   650			case 0xbb: map_abs(ABS_THROTTLE); break;
   651			case 0xc4: map_abs(ABS_GAS);      break;
   652			case 0xc5: map_abs(ABS_BRAKE);    break;
   653			case 0xc8: map_abs(ABS_WHEEL);    break;
   654			default:   goto ignore;
   655			}
   656			break;
   657	
   658		case HID_UP_GENDESK:
   659			if ((usage->hid & 0xf0) == 0x80) {	/* SystemControl */
   660				switch (usage->hid & 0xf) {
   661				case 0x1: map_key_clear(KEY_POWER);  break;
   662				case 0x2: map_key_clear(KEY_SLEEP);  break;
   663				case 0x3: map_key_clear(KEY_WAKEUP); break;
   664				case 0x4: map_key_clear(KEY_CONTEXT_MENU); break;
   665				case 0x5: map_key_clear(KEY_MENU); break;
   666				case 0x6: map_key_clear(KEY_PROG1); break;
   667				case 0x7: map_key_clear(KEY_HELP); break;
   668				case 0x8: map_key_clear(KEY_EXIT); break;
   669				case 0x9: map_key_clear(KEY_SELECT); break;
   670				case 0xa: map_key_clear(KEY_RIGHT); break;
   671				case 0xb: map_key_clear(KEY_LEFT); break;
   672				case 0xc: map_key_clear(KEY_UP); break;
   673				case 0xd: map_key_clear(KEY_DOWN); break;
   674				case 0xe: map_key_clear(KEY_POWER2); break;
   675				case 0xf: map_key_clear(KEY_RESTART); break;
   676				default: goto unknown;
   677				}
   678				break;
   679			}
   680	
   681			if ((usage->hid & 0xf0) == 0xb0) {	/* SC - Display */
   682				switch (usage->hid & 0xf) {
   683				case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break;
   684				default: goto ignore;
   685				}
   686				break;
   687			}
   688	
   689			/*
   690			 * Some lazy vendors declare 255 usages for System Control,
   691			 * leading to the creation of ABS_X|Y axis and too many others.
   692			 * It wouldn't be a problem if joydev doesn't consider the
   693			 * device as a joystick then.
   694			 */
   695			if (field->application == HID_GD_SYSTEM_CONTROL)
   696				goto ignore;
   697	
   698			if ((usage->hid & 0xf0) == 0x90) {	/* D-pad */
   699				switch (usage->hid) {
   700				case HID_GD_UP:	   usage->hat_dir = 1; break;
   701				case HID_GD_DOWN:  usage->hat_dir = 5; break;
   702				case HID_GD_RIGHT: usage->hat_dir = 3; break;
   703				case HID_GD_LEFT:  usage->hat_dir = 7; break;
   704				default: goto unknown;
   705				}
   706				if (field->dpad) {
   707					map_abs(field->dpad);
   708					goto ignore;
   709				}
   710				map_abs(ABS_HAT0X);
   711				break;
   712			}
   713	
   714			switch (usage->hid) {
   715			/* These usage IDs map directly to the usage codes. */
   716			case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
   717			case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
   718				if (field->flags & HID_MAIN_ITEM_RELATIVE)
   719					map_rel(usage->hid & 0xf);
   720				else
   721					map_abs_clear(usage->hid & 0xf);
   722				break;
   723	
   724			case HID_GD_WHEEL:
   725				if (field->flags & HID_MAIN_ITEM_RELATIVE) {
   726					set_bit(REL_WHEEL, input->relbit);
   727					map_rel(REL_WHEEL_HI_RES);
   728				} else {
   729					map_abs(usage->hid & 0xf);
   730				}
   731				break;
   732			case HID_GD_SLIDER: case HID_GD_DIAL:
   733				if (field->flags & HID_MAIN_ITEM_RELATIVE)
   734					map_rel(usage->hid & 0xf);
   735				else
   736					map_abs(usage->hid & 0xf);
   737				break;
   738	
   739			case HID_GD_HATSWITCH:
   740				usage->hat_min = field->logical_minimum;
   741				usage->hat_max = field->logical_maximum;
   742				map_abs(ABS_HAT0X);
   743				break;
   744	
   745			case HID_GD_START:	map_key_clear(BTN_START);	break;
   746			case HID_GD_SELECT:	map_key_clear(BTN_SELECT);	break;
   747	
   748			case HID_GD_RFKILL_BTN:
   749				/* MS wireless radio ctl extension, also check CA */
   750				if (field->application == HID_GD_WIRELESS_RADIO_CTLS) {
   751					map_key_clear(KEY_RFKILL);
   752					/* We need to simulate the btn release */
   753					field->flags |= HID_MAIN_ITEM_RELATIVE;
   754					break;
   755				}
   756				goto unknown;
   757	
   758			default: goto unknown;
   759			}
   760	
   761			break;
   762	
   763		case HID_UP_LED:
   764			switch (usage->hid & 0xffff) {		      /* HID-Value:                   */
   765			case 0x01:  map_led (LED_NUML);     break;    /*   "Num Lock"                 */
   766			case 0x02:  map_led (LED_CAPSL);    break;    /*   "Caps Lock"                */
   767			case 0x03:  map_led (LED_SCROLLL);  break;    /*   "Scroll Lock"              */
   768			case 0x04:  map_led (LED_COMPOSE);  break;    /*   "Compose"                  */
   769			case 0x05:  map_led (LED_KANA);     break;    /*   "Kana"                     */
   770			case 0x27:  map_led (LED_SLEEP);    break;    /*   "Stand-By"                 */
   771			case 0x4c:  map_led (LED_SUSPEND);  break;    /*   "System Suspend"           */
   772			case 0x09:  map_led (LED_MUTE);     break;    /*   "Mute"                     */
   773			case 0x4b:  map_led (LED_MISC);     break;    /*   "Generic Indicator"        */
   774			case 0x19:  map_led (LED_MAIL);     break;    /*   "Message Waiting"          */
   775			case 0x4d:  map_led (LED_CHARGING); break;    /*   "External Power Connected" */
   776	
   777			default: goto ignore;
   778			}
   779			break;
   780	
   781		case HID_UP_DIGITIZER:
   782			if ((field->application & 0xff) == 0x01) /* Digitizer */
   783				__set_bit(INPUT_PROP_POINTER, input->propbit);
   784			else if ((field->application & 0xff) == 0x02) /* Pen */
   785				__set_bit(INPUT_PROP_DIRECT, input->propbit);
   786	
   787			switch (usage->hid & 0xff) {
   788			case 0x00: /* Undefined */
   789				goto ignore;
   790	
   791			case 0x30: /* TipPressure */
   792				if (!test_bit(BTN_TOUCH, input->keybit)) {
   793					device->quirks |= HID_QUIRK_NOTOUCH;
   794					set_bit(EV_KEY, input->evbit);
   795					set_bit(BTN_TOUCH, input->keybit);
   796				}
   797				map_abs_clear(ABS_PRESSURE);
   798				break;
   799	
   800			case 0x32: /* InRange */
   801				switch (field->physical & 0xff) {
   802				case 0x21: map_key(BTN_TOOL_MOUSE); break;
   803				case 0x22: map_key(BTN_TOOL_FINGER); break;
   804				default: map_key(BTN_TOOL_PEN); break;
   805				}
   806				break;
   807	
   808			case 0x3b: /* Battery Strength */
   809				hidinput_setup_battery(device, HID_INPUT_REPORT, field);
   810				usage->type = EV_PWR;
   811				return;
   812	
   813			case 0x3c: /* Invert */
   814				map_key_clear(BTN_TOOL_RUBBER);
   815				break;
   816	
   817			case 0x3d: /* X Tilt */
   818				map_abs_clear(ABS_TILT_X);
   819				break;
   820	
   821			case 0x3e: /* Y Tilt */
   822				map_abs_clear(ABS_TILT_Y);
   823				break;
   824	
   825			case 0x33: /* Touch */
   826			case 0x42: /* TipSwitch */
   827			case 0x43: /* TipSwitch2 */
   828				device->quirks &= ~HID_QUIRK_NOTOUCH;
   829				map_key_clear(BTN_TOUCH);
   830				break;
   831	
   832			case 0x44: /* BarrelSwitch */
   833				map_key_clear(BTN_STYLUS);
   834				break;
   835	
   836			case 0x45: /* ERASER */
   837				/*
   838				 * This event is reported when eraser tip touches the surface.
   839				 * Actual eraser (BTN_TOOL_RUBBER) is set by Invert usage when
   840				 * tool gets in proximity.
   841				 */
   842				map_key_clear(BTN_TOUCH);
   843				break;
   844	
   845			case 0x46: /* TabletPick */
   846			case 0x5a: /* SecondaryBarrelSwitch */
   847				map_key_clear(BTN_STYLUS2);
   848				break;
   849	
   850			case 0x5b: /* TransducerSerialNumber */
   851				usage->type = EV_MSC;
   852				usage->code = MSC_SERIAL;
   853				bit = input->mscbit;
   854				max = MSC_MAX;
   855				break;
   856	
   857			default:  goto unknown;
   858			}
   859			break;
   860	
   861		case HID_UP_TELEPHONY:
   862			switch (usage->hid & HID_USAGE) {
   863			case 0x2f: map_key_clear(KEY_MICMUTE);		break;
   864			case 0xb0: map_key_clear(KEY_NUMERIC_0);	break;
   865			case 0xb1: map_key_clear(KEY_NUMERIC_1);	break;
   866			case 0xb2: map_key_clear(KEY_NUMERIC_2);	break;
   867			case 0xb3: map_key_clear(KEY_NUMERIC_3);	break;
   868			case 0xb4: map_key_clear(KEY_NUMERIC_4);	break;
   869			case 0xb5: map_key_clear(KEY_NUMERIC_5);	break;
   870			case 0xb6: map_key_clear(KEY_NUMERIC_6);	break;
   871			case 0xb7: map_key_clear(KEY_NUMERIC_7);	break;
   872			case 0xb8: map_key_clear(KEY_NUMERIC_8);	break;
   873			case 0xb9: map_key_clear(KEY_NUMERIC_9);	break;
   874			case 0xba: map_key_clear(KEY_NUMERIC_STAR);	break;
   875			case 0xbb: map_key_clear(KEY_NUMERIC_POUND);	break;
   876			case 0xbc: map_key_clear(KEY_NUMERIC_A);	break;
   877			case 0xbd: map_key_clear(KEY_NUMERIC_B);	break;
   878			case 0xbe: map_key_clear(KEY_NUMERIC_C);	break;
   879			case 0xbf: map_key_clear(KEY_NUMERIC_D);	break;
   880			default: goto ignore;
   881			}
   882			break;
   883	
   884		case HID_UP_CONSUMER:	/* USB HUT v1.12, pages 75-84 */
   885			switch (usage->hid & HID_USAGE) {
   886			case 0x000: goto ignore;
   887			case 0x030: map_key_clear(KEY_POWER);		break;
   888			case 0x031: map_key_clear(KEY_RESTART);		break;
   889			case 0x032: map_key_clear(KEY_SLEEP);		break;
   890			case 0x034: map_key_clear(KEY_SLEEP);		break;
   891			case 0x035: map_key_clear(KEY_KBDILLUMTOGGLE);	break;
   892			case 0x036: map_key_clear(BTN_MISC);		break;
   893	
   894			case 0x040: map_key_clear(KEY_MENU);		break; /* Menu */
   895			case 0x041: map_key_clear(KEY_SELECT);		break; /* Menu Pick */
   896			case 0x042: map_key_clear(KEY_UP);		break; /* Menu Up */
   897			case 0x043: map_key_clear(KEY_DOWN);		break; /* Menu Down */
   898			case 0x044: map_key_clear(KEY_LEFT);		break; /* Menu Left */
   899			case 0x045: map_key_clear(KEY_RIGHT);		break; /* Menu Right */
   900			case 0x046: map_key_clear(KEY_ESC);		break; /* Menu Escape */
   901			case 0x047: map_key_clear(KEY_KPPLUS);		break; /* Menu Value Increase */
   902			case 0x048: map_key_clear(KEY_KPMINUS);		break; /* Menu Value Decrease */
   903	
   904			case 0x060: map_key_clear(KEY_INFO);		break; /* Data On Screen */
   905			case 0x061: map_key_clear(KEY_SUBTITLE);	break; /* Closed Caption */
   906			case 0x063: map_key_clear(KEY_VCR);		break; /* VCR/TV */
   907			case 0x065: map_key_clear(KEY_CAMERA);		break; /* Snapshot */
   908			case 0x069: map_key_clear(KEY_RED);		break;
   909			case 0x06a: map_key_clear(KEY_GREEN);		break;
   910			case 0x06b: map_key_clear(KEY_BLUE);		break;
   911			case 0x06c: map_key_clear(KEY_YELLOW);		break;
   912			case 0x06d: map_key_clear(KEY_ASPECT_RATIO);	break;
   913	
   914			case 0x06f: map_key_clear(KEY_BRIGHTNESSUP);		break;
   915			case 0x070: map_key_clear(KEY_BRIGHTNESSDOWN);		break;
   916			case 0x072: map_key_clear(KEY_BRIGHTNESS_TOGGLE);	break;
   917			case 0x073: map_key_clear(KEY_BRIGHTNESS_MIN);		break;
   918			case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX);		break;
   919			case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO);		break;
   920	
   921			case 0x079: map_key_clear(KEY_KBDILLUMUP);	break;
   922			case 0x07a: map_key_clear(KEY_KBDILLUMDOWN);	break;
   923			case 0x07c: map_key_clear(KEY_KBDILLUMTOGGLE);	break;
   924	
   925			case 0x082: map_key_clear(KEY_VIDEO_NEXT);	break;
   926			case 0x083: map_key_clear(KEY_LAST);		break;
   927			case 0x084: map_key_clear(KEY_ENTER);		break;
   928			case 0x088: map_key_clear(KEY_PC);		break;
   929			case 0x089: map_key_clear(KEY_TV);		break;
   930			case 0x08a: map_key_clear(KEY_WWW);		break;
   931			case 0x08b: map_key_clear(KEY_DVD);		break;
   932			case 0x08c: map_key_clear(KEY_PHONE);		break;
   933			case 0x08d: map_key_clear(KEY_PROGRAM);		break;
   934			case 0x08e: map_key_clear(KEY_VIDEOPHONE);	break;
   935			case 0x08f: map_key_clear(KEY_GAMES);		break;
   936			case 0x090: map_key_clear(KEY_MEMO);		break;
   937			case 0x091: map_key_clear(KEY_CD);		break;
   938			case 0x092: map_key_clear(KEY_VCR);		break;
   939			case 0x093: map_key_clear(KEY_TUNER);		break;
   940			case 0x094: map_key_clear(KEY_EXIT);		break;
   941			case 0x095: map_key_clear(KEY_HELP);		break;
   942			case 0x096: map_key_clear(KEY_TAPE);		break;
   943			case 0x097: map_key_clear(KEY_TV2);		break;
   944			case 0x098: map_key_clear(KEY_SAT);		break;
   945			case 0x09a: map_key_clear(KEY_PVR);		break;
   946	
   947			case 0x09c: map_key_clear(KEY_CHANNELUP);	break;
   948			case 0x09d: map_key_clear(KEY_CHANNELDOWN);	break;
   949			case 0x0a0: map_key_clear(KEY_VCR2);		break;
   950	
   951			case 0x0b0: map_key_clear(KEY_PLAY);		break;
   952			case 0x0b1: map_key_clear(KEY_PAUSE);		break;
   953			case 0x0b2: map_key_clear(KEY_RECORD);		break;
   954			case 0x0b3: map_key_clear(KEY_FASTFORWARD);	break;
   955			case 0x0b4: map_key_clear(KEY_REWIND);		break;
   956			case 0x0b5: map_key_clear(KEY_NEXTSONG);	break;
   957			case 0x0b6: map_key_clear(KEY_PREVIOUSSONG);	break;
   958			case 0x0b7: map_key_clear(KEY_STOPCD);		break;
   959			case 0x0b8: map_key_clear(KEY_EJECTCD);		break;
   960			case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT);	break;
   961			case 0x0b9: map_key_clear(KEY_SHUFFLE);		break;
   962			case 0x0bf: map_key_clear(KEY_SLOW);		break;
   963	
   964			case 0x0cd: map_key_clear(KEY_PLAYPAUSE);	break;
   965			case 0x0cf: map_key_clear(KEY_VOICECOMMAND);	break;
   966			case 0x0e0: map_abs_clear(ABS_VOLUME);		break;
   967			case 0x0e2: map_key_clear(KEY_MUTE);		break;
   968			case 0x0e5: map_key_clear(KEY_BASSBOOST);	break;
   969			case 0x0e9: map_key_clear(KEY_VOLUMEUP);	break;
   970			case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);	break;
   971			case 0x0f5: map_key_clear(KEY_SLOW);		break;
   972	
   973			case 0x181: map_key_clear(KEY_BUTTONCONFIG);	break;
   974			case 0x182: map_key_clear(KEY_BOOKMARKS);	break;
   975			case 0x183: map_key_clear(KEY_CONFIG);		break;
   976			case 0x184: map_key_clear(KEY_WORDPROCESSOR);	break;
   977			case 0x185: map_key_clear(KEY_EDITOR);		break;
   978			case 0x186: map_key_clear(KEY_SPREADSHEET);	break;
   979			case 0x187: map_key_clear(KEY_GRAPHICSEDITOR);	break;
   980			case 0x188: map_key_clear(KEY_PRESENTATION);	break;
   981			case 0x189: map_key_clear(KEY_DATABASE);	break;
   982			case 0x18a: map_key_clear(KEY_MAIL);		break;
   983			case 0x18b: map_key_clear(KEY_NEWS);		break;
   984			case 0x18c: map_key_clear(KEY_VOICEMAIL);	break;
   985			case 0x18d: map_key_clear(KEY_ADDRESSBOOK);	break;
   986			case 0x18e: map_key_clear(KEY_CALENDAR);	break;
   987			case 0x18f: map_key_clear(KEY_TASKMANAGER);	break;
   988			case 0x190: map_key_clear(KEY_JOURNAL);		break;
   989			case 0x191: map_key_clear(KEY_FINANCE);		break;
   990			case 0x192: map_key_clear(KEY_CALC);		break;
   991			case 0x193: map_key_clear(KEY_PLAYER);		break;
   992			case 0x194: map_key_clear(KEY_FILE);		break;
   993			case 0x196: map_key_clear(KEY_WWW);		break;
   994			case 0x199: map_key_clear(KEY_CHAT);		break;
   995			case 0x19c: map_key_clear(KEY_LOGOFF);		break;
   996			case 0x19e: map_key_clear(KEY_COFFEE);		break;
   997			case 0x19f: map_key_clear(KEY_CONTROLPANEL);		break;
   998			case 0x1a2: map_key_clear(KEY_APPSELECT);		break;
   999			case 0x1a3: map_key_clear(KEY_NEXT);		break;
  1000			case 0x1a4: map_key_clear(KEY_PREVIOUS);	break;
  1001			case 0x1a6: map_key_clear(KEY_HELP);		break;
  1002			case 0x1a7: map_key_clear(KEY_DOCUMENTS);	break;
  1003			case 0x1ab: map_key_clear(KEY_SPELLCHECK);	break;
  1004			case 0x1ae: map_key_clear(KEY_KEYBOARD);	break;
  1005			case 0x1b1: map_key_clear(KEY_SCREENSAVER);		break;
  1006			case 0x1b4: map_key_clear(KEY_FILE);		break;
  1007			case 0x1b6: map_key_clear(KEY_IMAGES);		break;
  1008			case 0x1b7: map_key_clear(KEY_AUDIO);		break;
  1009			case 0x1b8: map_key_clear(KEY_VIDEO);		break;
  1010			case 0x1bc: map_key_clear(KEY_MESSENGER);	break;
  1011			case 0x1bd: map_key_clear(KEY_INFO);		break;
  1012			case 0x1cb: map_key_clear(KEY_ASSISTANT);	break;
  1013			case 0x201: map_key_clear(KEY_NEW);		break;
  1014			case 0x202: map_key_clear(KEY_OPEN);		break;
  1015			case 0x203: map_key_clear(KEY_CLOSE);		break;
  1016			case 0x204: map_key_clear(KEY_EXIT);		break;
  1017			case 0x207: map_key_clear(KEY_SAVE);		break;
  1018			case 0x208: map_key_clear(KEY_PRINT);		break;
  1019			case 0x209: map_key_clear(KEY_PROPS);		break;
  1020			case 0x21a: map_key_clear(KEY_UNDO);		break;
  1021			case 0x21b: map_key_clear(KEY_COPY);		break;
  1022			case 0x21c: map_key_clear(KEY_CUT);		break;
  1023			case 0x21d: map_key_clear(KEY_PASTE);		break;
  1024			case 0x21f: map_key_clear(KEY_FIND);		break;
  1025			case 0x221: map_key_clear(KEY_SEARCH);		break;
  1026			case 0x222: map_key_clear(KEY_GOTO);		break;
  1027			case 0x223: map_key_clear(KEY_HOMEPAGE);	break;
  1028			case 0x224: map_key_clear(KEY_BACK);		break;
  1029			case 0x225: map_key_clear(KEY_FORWARD);		break;
  1030			case 0x226: map_key_clear(KEY_STOP);		break;
  1031			case 0x227: map_key_clear(KEY_REFRESH);		break;
  1032			case 0x22a: map_key_clear(KEY_BOOKMARKS);	break;
  1033			case 0x22d: map_key_clear(KEY_ZOOMIN);		break;
  1034			case 0x22e: map_key_clear(KEY_ZOOMOUT);		break;
  1035			case 0x22f: map_key_clear(KEY_ZOOMRESET);	break;
  1036			case 0x232: map_key_clear(KEY_FULL_SCREEN);	break;
  1037			case 0x233: map_key_clear(KEY_SCROLLUP);	break;
  1038			case 0x234: map_key_clear(KEY_SCROLLDOWN);	break;
  1039			case 0x238: /* AC Pan */
  1040				set_bit(REL_HWHEEL, input->relbit);
  1041				map_rel(REL_HWHEEL_HI_RES);
  1042				break;
  1043			case 0x23d: map_key_clear(KEY_EDIT);		break;
  1044			case 0x25f: map_key_clear(KEY_CANCEL);		break;
  1045			case 0x269: map_key_clear(KEY_INSERT);		break;
  1046			case 0x26a: map_key_clear(KEY_DELETE);		break;
  1047			case 0x279: map_key_clear(KEY_REDO);		break;
  1048	
  1049			case 0x289: map_key_clear(KEY_REPLY);		break;
  1050			case 0x28b: map_key_clear(KEY_FORWARDMAIL);	break;
  1051			case 0x28c: map_key_clear(KEY_SEND);		break;
  1052	
  1053			case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT);	break;
  1054	
  1055			case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV);		break;
  1056			case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT);		break;
  1057			case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP);		break;
  1058			case 0x2ca: map_key_clear(KEY_KBDINPUTASSIST_NEXTGROUP);		break;
  1059			case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT);	break;
  1060			case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL);	break;
  1061	
  1062			case 0x29f: map_key_clear(KEY_SCALE);		break;
  1063	
  1064			default: map_key_clear(KEY_UNKNOWN);
  1065			}
  1066			break;
  1067	
  1068		case HID_UP_GENDEVCTRLS:
  1069			switch (usage->hid) {
  1070			case HID_DC_BATTERYSTRENGTH:
  1071				hidinput_setup_battery(device, HID_INPUT_REPORT, field);
  1072				usage->type = EV_PWR;
  1073				return;
  1074			}
  1075			goto unknown;
  1076	
  1077		case HID_UP_BATTERY:
  1078			switch (usage->hid) {
  1079			case HID_BAT_ABSOLUTESTATEOFCHARGE:
  1080				hidinput_setup_battery(device, HID_INPUT_REPORT, field);
  1081				usage->type = EV_PWR;
> 1082				device->battery_min = 0;
> 1083				device->battery_max = 100;
  1084				return;
  1085			}
  1086			goto unknown;
  1087	
  1088		case HID_UP_HPVENDOR:	/* Reported on a Dutch layout HP5308 */
  1089			set_bit(EV_REP, input->evbit);
  1090			switch (usage->hid & HID_USAGE) {
  1091			case 0x021: map_key_clear(KEY_PRINT);           break;
  1092			case 0x070: map_key_clear(KEY_HP);		break;
  1093			case 0x071: map_key_clear(KEY_CAMERA);		break;
  1094			case 0x072: map_key_clear(KEY_SOUND);		break;
  1095			case 0x073: map_key_clear(KEY_QUESTION);	break;
  1096			case 0x080: map_key_clear(KEY_EMAIL);		break;
  1097			case 0x081: map_key_clear(KEY_CHAT);		break;
  1098			case 0x082: map_key_clear(KEY_SEARCH);		break;
  1099			case 0x083: map_key_clear(KEY_CONNECT);	        break;
  1100			case 0x084: map_key_clear(KEY_FINANCE);		break;
  1101			case 0x085: map_key_clear(KEY_SPORT);		break;
  1102			case 0x086: map_key_clear(KEY_SHOP);	        break;
  1103			default:    goto ignore;
  1104			}
  1105			break;
  1106	
  1107		case HID_UP_HPVENDOR2:
  1108			set_bit(EV_REP, input->evbit);
  1109			switch (usage->hid & HID_USAGE) {
  1110			case 0x001: map_key_clear(KEY_MICMUTE);		break;
  1111			case 0x003: map_key_clear(KEY_BRIGHTNESSDOWN);	break;
  1112			case 0x004: map_key_clear(KEY_BRIGHTNESSUP);	break;
  1113			default:    goto ignore;
  1114			}
  1115			break;
  1116	
  1117		case HID_UP_MSVENDOR:
  1118			goto ignore;
  1119	
  1120		case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */
  1121			set_bit(EV_REP, input->evbit);
  1122			goto ignore;
  1123	
  1124		case HID_UP_LOGIVENDOR:
  1125			/* intentional fallback */
  1126		case HID_UP_LOGIVENDOR2:
  1127			/* intentional fallback */
  1128		case HID_UP_LOGIVENDOR3:
  1129			goto ignore;
  1130	
  1131		case HID_UP_PID:
  1132			switch (usage->hid & HID_USAGE) {
  1133			case 0xa4: map_key_clear(BTN_DEAD);	break;
  1134			default: goto ignore;
  1135			}
  1136			break;
  1137	
  1138		default:
  1139		unknown:
  1140			if (field->report_size == 1) {
  1141				if (field->report->type == HID_OUTPUT_REPORT) {
  1142					map_led(LED_MISC);
  1143					break;
  1144				}
  1145				map_key(BTN_MISC);
  1146				break;
  1147			}
  1148			if (field->flags & HID_MAIN_ITEM_RELATIVE) {
  1149				map_rel(REL_MISC);
  1150				break;
  1151			}
  1152			map_abs(ABS_MISC);
  1153			break;
  1154		}
  1155	
  1156	mapped:
  1157		/* Mapping failed, bail out */
  1158		if (!bit)
  1159			return;
  1160	
  1161		if (device->driver->input_mapped &&
  1162		    device->driver->input_mapped(device, hidinput, field, usage,
  1163						 &bit, &max) < 0) {
  1164			/*
  1165			 * The driver indicated that no further generic handling
  1166			 * of the usage is desired.
  1167			 */
  1168			return;
  1169		}
  1170	
  1171		set_bit(usage->type, input->evbit);
  1172	
  1173		/*
  1174		 * This part is *really* controversial:
  1175		 * - HID aims at being generic so we should do our best to export
  1176		 *   all incoming events
  1177		 * - HID describes what events are, so there is no reason for ABS_X
  1178		 *   to be mapped to ABS_Y
  1179		 * - HID is using *_MISC+N as a default value, but nothing prevents
  1180		 *   *_MISC+N to overwrite a legitimate even, which confuses userspace
  1181		 *   (for instance ABS_MISC + 7 is ABS_MT_SLOT, which has a different
  1182		 *   processing)
  1183		 *
  1184		 * If devices still want to use this (at their own risk), they will
  1185		 * have to use the quirk HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE, but
  1186		 * the default should be a reliable mapping.
  1187		 */
  1188		while (usage->code <= max && test_and_set_bit(usage->code, bit)) {
  1189			if (device->quirks & HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE) {
  1190				usage->code = find_next_zero_bit(bit,
  1191								 max + 1,
  1192								 usage->code);
  1193			} else {
  1194				device->status |= HID_STAT_DUP_DETECTED;
  1195				goto ignore;
  1196			}
  1197		}
  1198	
  1199		if (usage->code > max)
  1200			goto ignore;
  1201	
  1202		if (usage->type == EV_ABS) {
  1203	
  1204			int a = field->logical_minimum;
  1205			int b = field->logical_maximum;
  1206	
  1207			if ((device->quirks & HID_QUIRK_BADPAD) && (usage->code == ABS_X || usage->code == ABS_Y)) {
  1208				a = field->logical_minimum = 0;
  1209				b = field->logical_maximum = 255;
  1210			}
  1211	
  1212			if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK)
  1213				input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4);
  1214			else	input_set_abs_params(input, usage->code, a, b, 0, 0);
  1215	
  1216			input_abs_set_res(input, usage->code,
  1217					  hidinput_calc_abs_res(field, usage->code));
  1218	
  1219			/* use a larger default input buffer for MT devices */
  1220			if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0)
  1221				input_set_events_per_packet(input, 60);
  1222		}
  1223	
  1224		if (usage->type == EV_ABS &&
  1225		    (usage->hat_min < usage->hat_max || usage->hat_dir)) {
  1226			int i;
  1227			for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
  1228				input_set_abs_params(input, i, -1, 1, 0, 0);
  1229				set_bit(i, input->absbit);
  1230			}
  1231			if (usage->hat_dir && !field->dpad)
  1232				field->dpad = usage->code;
  1233		}
  1234	
  1235		/* for those devices which produce Consumer volume usage as relative,
  1236		 * we emulate pressing volumeup/volumedown appropriate number of times
  1237		 * in hidinput_hid_event()
  1238		 */
  1239		if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
  1240				(usage->code == ABS_VOLUME)) {
  1241			set_bit(KEY_VOLUMEUP, input->keybit);
  1242			set_bit(KEY_VOLUMEDOWN, input->keybit);
  1243		}
  1244	
  1245		if (usage->type == EV_KEY) {
  1246			set_bit(EV_MSC, input->evbit);
  1247			set_bit(MSC_SCAN, input->mscbit);
  1248		}
  1249	
  1250		return;
  1251	
  1252	ignore:
  1253		usage->type = 0;
  1254		usage->code = 0;
  1255	}
  1256	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28461 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] HID: input: map battery capacity (00850065)
  2021-03-27 13:05 ` [PATCH 4/4] HID: input: map battery capacity (00850065) John Chen
  2021-03-27 14:14   ` Pochang Chen
  2021-03-27 17:22   ` kernel test robot
@ 2021-03-27 17:50   ` kernel test robot
  2 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2021-03-27 17:50 UTC (permalink / raw)
  To: John Chen, linux-kernel
  Cc: kbuild-all, clang-built-linux, Rohit Pidaparthi,
	RicardoEPRodrigues, Jiri Kosina, Benjamin Tissoires, John Chen

[-- Attachment #1: Type: text/plain, Size: 29849 bytes --]

Hi John,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hid/for-next]
[also build test ERROR on linux/master linus/master jikos-hid/for-next jikos-trivial/for-next v5.12-rc4 next-20210326]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/John-Chen/HID-add-Apple-Magic-Mouse-2-support/20210327-211004
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
config: x86_64-randconfig-a012-20210327 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project d50fe9f0d6b9ee61df8830a67ea0a33c27a637e7)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/00e05cc61c9d267c5857d61fd40638d560460f89
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review John-Chen/HID-add-Apple-Magic-Mouse-2-support/20210327-211004
        git checkout 00e05cc61c9d267c5857d61fd40638d560460f89
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/hid/hid-input.c:1082:12: error: no member named 'battery_min' in 'struct hid_device'
                           device->battery_min = 0;
                           ~~~~~~  ^
>> drivers/hid/hid-input.c:1083:12: error: no member named 'battery_max' in 'struct hid_device'
                           device->battery_max = 100;
                           ~~~~~~  ^
   2 errors generated.


vim +1082 drivers/hid/hid-input.c

   568	
   569	static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
   570					     struct hid_usage *usage)
   571	{
   572		struct input_dev *input = hidinput->input;
   573		struct hid_device *device = input_get_drvdata(input);
   574		int max = 0, code;
   575		unsigned long *bit = NULL;
   576	
   577		field->hidinput = hidinput;
   578	
   579		if (field->flags & HID_MAIN_ITEM_CONSTANT)
   580			goto ignore;
   581	
   582		/* Ignore if report count is out of bounds. */
   583		if (field->report_count < 1)
   584			goto ignore;
   585	
   586		/* only LED usages are supported in output fields */
   587		if (field->report_type == HID_OUTPUT_REPORT &&
   588				(usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
   589			goto ignore;
   590		}
   591	
   592		if (device->driver->input_mapping) {
   593			int ret = device->driver->input_mapping(device, hidinput, field,
   594					usage, &bit, &max);
   595			if (ret > 0)
   596				goto mapped;
   597			if (ret < 0)
   598				goto ignore;
   599		}
   600	
   601		switch (usage->hid & HID_USAGE_PAGE) {
   602		case HID_UP_UNDEFINED:
   603			goto ignore;
   604	
   605		case HID_UP_KEYBOARD:
   606			set_bit(EV_REP, input->evbit);
   607	
   608			if ((usage->hid & HID_USAGE) < 256) {
   609				if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore;
   610				map_key_clear(hid_keyboard[usage->hid & HID_USAGE]);
   611			} else
   612				map_key(KEY_UNKNOWN);
   613	
   614			break;
   615	
   616		case HID_UP_BUTTON:
   617			code = ((usage->hid - 1) & HID_USAGE);
   618	
   619			switch (field->application) {
   620			case HID_GD_MOUSE:
   621			case HID_GD_POINTER:  code += BTN_MOUSE; break;
   622			case HID_GD_JOYSTICK:
   623					if (code <= 0xf)
   624						code += BTN_JOYSTICK;
   625					else
   626						code += BTN_TRIGGER_HAPPY - 0x10;
   627					break;
   628			case HID_GD_GAMEPAD:
   629					if (code <= 0xf)
   630						code += BTN_GAMEPAD;
   631					else
   632						code += BTN_TRIGGER_HAPPY - 0x10;
   633					break;
   634			default:
   635				switch (field->physical) {
   636				case HID_GD_MOUSE:
   637				case HID_GD_POINTER:  code += BTN_MOUSE; break;
   638				case HID_GD_JOYSTICK: code += BTN_JOYSTICK; break;
   639				case HID_GD_GAMEPAD:  code += BTN_GAMEPAD; break;
   640				default:              code += BTN_MISC;
   641				}
   642			}
   643	
   644			map_key(code);
   645			break;
   646	
   647		case HID_UP_SIMULATION:
   648			switch (usage->hid & 0xffff) {
   649			case 0xba: map_abs(ABS_RUDDER);   break;
   650			case 0xbb: map_abs(ABS_THROTTLE); break;
   651			case 0xc4: map_abs(ABS_GAS);      break;
   652			case 0xc5: map_abs(ABS_BRAKE);    break;
   653			case 0xc8: map_abs(ABS_WHEEL);    break;
   654			default:   goto ignore;
   655			}
   656			break;
   657	
   658		case HID_UP_GENDESK:
   659			if ((usage->hid & 0xf0) == 0x80) {	/* SystemControl */
   660				switch (usage->hid & 0xf) {
   661				case 0x1: map_key_clear(KEY_POWER);  break;
   662				case 0x2: map_key_clear(KEY_SLEEP);  break;
   663				case 0x3: map_key_clear(KEY_WAKEUP); break;
   664				case 0x4: map_key_clear(KEY_CONTEXT_MENU); break;
   665				case 0x5: map_key_clear(KEY_MENU); break;
   666				case 0x6: map_key_clear(KEY_PROG1); break;
   667				case 0x7: map_key_clear(KEY_HELP); break;
   668				case 0x8: map_key_clear(KEY_EXIT); break;
   669				case 0x9: map_key_clear(KEY_SELECT); break;
   670				case 0xa: map_key_clear(KEY_RIGHT); break;
   671				case 0xb: map_key_clear(KEY_LEFT); break;
   672				case 0xc: map_key_clear(KEY_UP); break;
   673				case 0xd: map_key_clear(KEY_DOWN); break;
   674				case 0xe: map_key_clear(KEY_POWER2); break;
   675				case 0xf: map_key_clear(KEY_RESTART); break;
   676				default: goto unknown;
   677				}
   678				break;
   679			}
   680	
   681			if ((usage->hid & 0xf0) == 0xb0) {	/* SC - Display */
   682				switch (usage->hid & 0xf) {
   683				case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break;
   684				default: goto ignore;
   685				}
   686				break;
   687			}
   688	
   689			/*
   690			 * Some lazy vendors declare 255 usages for System Control,
   691			 * leading to the creation of ABS_X|Y axis and too many others.
   692			 * It wouldn't be a problem if joydev doesn't consider the
   693			 * device as a joystick then.
   694			 */
   695			if (field->application == HID_GD_SYSTEM_CONTROL)
   696				goto ignore;
   697	
   698			if ((usage->hid & 0xf0) == 0x90) {	/* D-pad */
   699				switch (usage->hid) {
   700				case HID_GD_UP:	   usage->hat_dir = 1; break;
   701				case HID_GD_DOWN:  usage->hat_dir = 5; break;
   702				case HID_GD_RIGHT: usage->hat_dir = 3; break;
   703				case HID_GD_LEFT:  usage->hat_dir = 7; break;
   704				default: goto unknown;
   705				}
   706				if (field->dpad) {
   707					map_abs(field->dpad);
   708					goto ignore;
   709				}
   710				map_abs(ABS_HAT0X);
   711				break;
   712			}
   713	
   714			switch (usage->hid) {
   715			/* These usage IDs map directly to the usage codes. */
   716			case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
   717			case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
   718				if (field->flags & HID_MAIN_ITEM_RELATIVE)
   719					map_rel(usage->hid & 0xf);
   720				else
   721					map_abs_clear(usage->hid & 0xf);
   722				break;
   723	
   724			case HID_GD_WHEEL:
   725				if (field->flags & HID_MAIN_ITEM_RELATIVE) {
   726					set_bit(REL_WHEEL, input->relbit);
   727					map_rel(REL_WHEEL_HI_RES);
   728				} else {
   729					map_abs(usage->hid & 0xf);
   730				}
   731				break;
   732			case HID_GD_SLIDER: case HID_GD_DIAL:
   733				if (field->flags & HID_MAIN_ITEM_RELATIVE)
   734					map_rel(usage->hid & 0xf);
   735				else
   736					map_abs(usage->hid & 0xf);
   737				break;
   738	
   739			case HID_GD_HATSWITCH:
   740				usage->hat_min = field->logical_minimum;
   741				usage->hat_max = field->logical_maximum;
   742				map_abs(ABS_HAT0X);
   743				break;
   744	
   745			case HID_GD_START:	map_key_clear(BTN_START);	break;
   746			case HID_GD_SELECT:	map_key_clear(BTN_SELECT);	break;
   747	
   748			case HID_GD_RFKILL_BTN:
   749				/* MS wireless radio ctl extension, also check CA */
   750				if (field->application == HID_GD_WIRELESS_RADIO_CTLS) {
   751					map_key_clear(KEY_RFKILL);
   752					/* We need to simulate the btn release */
   753					field->flags |= HID_MAIN_ITEM_RELATIVE;
   754					break;
   755				}
   756				goto unknown;
   757	
   758			default: goto unknown;
   759			}
   760	
   761			break;
   762	
   763		case HID_UP_LED:
   764			switch (usage->hid & 0xffff) {		      /* HID-Value:                   */
   765			case 0x01:  map_led (LED_NUML);     break;    /*   "Num Lock"                 */
   766			case 0x02:  map_led (LED_CAPSL);    break;    /*   "Caps Lock"                */
   767			case 0x03:  map_led (LED_SCROLLL);  break;    /*   "Scroll Lock"              */
   768			case 0x04:  map_led (LED_COMPOSE);  break;    /*   "Compose"                  */
   769			case 0x05:  map_led (LED_KANA);     break;    /*   "Kana"                     */
   770			case 0x27:  map_led (LED_SLEEP);    break;    /*   "Stand-By"                 */
   771			case 0x4c:  map_led (LED_SUSPEND);  break;    /*   "System Suspend"           */
   772			case 0x09:  map_led (LED_MUTE);     break;    /*   "Mute"                     */
   773			case 0x4b:  map_led (LED_MISC);     break;    /*   "Generic Indicator"        */
   774			case 0x19:  map_led (LED_MAIL);     break;    /*   "Message Waiting"          */
   775			case 0x4d:  map_led (LED_CHARGING); break;    /*   "External Power Connected" */
   776	
   777			default: goto ignore;
   778			}
   779			break;
   780	
   781		case HID_UP_DIGITIZER:
   782			if ((field->application & 0xff) == 0x01) /* Digitizer */
   783				__set_bit(INPUT_PROP_POINTER, input->propbit);
   784			else if ((field->application & 0xff) == 0x02) /* Pen */
   785				__set_bit(INPUT_PROP_DIRECT, input->propbit);
   786	
   787			switch (usage->hid & 0xff) {
   788			case 0x00: /* Undefined */
   789				goto ignore;
   790	
   791			case 0x30: /* TipPressure */
   792				if (!test_bit(BTN_TOUCH, input->keybit)) {
   793					device->quirks |= HID_QUIRK_NOTOUCH;
   794					set_bit(EV_KEY, input->evbit);
   795					set_bit(BTN_TOUCH, input->keybit);
   796				}
   797				map_abs_clear(ABS_PRESSURE);
   798				break;
   799	
   800			case 0x32: /* InRange */
   801				switch (field->physical & 0xff) {
   802				case 0x21: map_key(BTN_TOOL_MOUSE); break;
   803				case 0x22: map_key(BTN_TOOL_FINGER); break;
   804				default: map_key(BTN_TOOL_PEN); break;
   805				}
   806				break;
   807	
   808			case 0x3b: /* Battery Strength */
   809				hidinput_setup_battery(device, HID_INPUT_REPORT, field);
   810				usage->type = EV_PWR;
   811				return;
   812	
   813			case 0x3c: /* Invert */
   814				map_key_clear(BTN_TOOL_RUBBER);
   815				break;
   816	
   817			case 0x3d: /* X Tilt */
   818				map_abs_clear(ABS_TILT_X);
   819				break;
   820	
   821			case 0x3e: /* Y Tilt */
   822				map_abs_clear(ABS_TILT_Y);
   823				break;
   824	
   825			case 0x33: /* Touch */
   826			case 0x42: /* TipSwitch */
   827			case 0x43: /* TipSwitch2 */
   828				device->quirks &= ~HID_QUIRK_NOTOUCH;
   829				map_key_clear(BTN_TOUCH);
   830				break;
   831	
   832			case 0x44: /* BarrelSwitch */
   833				map_key_clear(BTN_STYLUS);
   834				break;
   835	
   836			case 0x45: /* ERASER */
   837				/*
   838				 * This event is reported when eraser tip touches the surface.
   839				 * Actual eraser (BTN_TOOL_RUBBER) is set by Invert usage when
   840				 * tool gets in proximity.
   841				 */
   842				map_key_clear(BTN_TOUCH);
   843				break;
   844	
   845			case 0x46: /* TabletPick */
   846			case 0x5a: /* SecondaryBarrelSwitch */
   847				map_key_clear(BTN_STYLUS2);
   848				break;
   849	
   850			case 0x5b: /* TransducerSerialNumber */
   851				usage->type = EV_MSC;
   852				usage->code = MSC_SERIAL;
   853				bit = input->mscbit;
   854				max = MSC_MAX;
   855				break;
   856	
   857			default:  goto unknown;
   858			}
   859			break;
   860	
   861		case HID_UP_TELEPHONY:
   862			switch (usage->hid & HID_USAGE) {
   863			case 0x2f: map_key_clear(KEY_MICMUTE);		break;
   864			case 0xb0: map_key_clear(KEY_NUMERIC_0);	break;
   865			case 0xb1: map_key_clear(KEY_NUMERIC_1);	break;
   866			case 0xb2: map_key_clear(KEY_NUMERIC_2);	break;
   867			case 0xb3: map_key_clear(KEY_NUMERIC_3);	break;
   868			case 0xb4: map_key_clear(KEY_NUMERIC_4);	break;
   869			case 0xb5: map_key_clear(KEY_NUMERIC_5);	break;
   870			case 0xb6: map_key_clear(KEY_NUMERIC_6);	break;
   871			case 0xb7: map_key_clear(KEY_NUMERIC_7);	break;
   872			case 0xb8: map_key_clear(KEY_NUMERIC_8);	break;
   873			case 0xb9: map_key_clear(KEY_NUMERIC_9);	break;
   874			case 0xba: map_key_clear(KEY_NUMERIC_STAR);	break;
   875			case 0xbb: map_key_clear(KEY_NUMERIC_POUND);	break;
   876			case 0xbc: map_key_clear(KEY_NUMERIC_A);	break;
   877			case 0xbd: map_key_clear(KEY_NUMERIC_B);	break;
   878			case 0xbe: map_key_clear(KEY_NUMERIC_C);	break;
   879			case 0xbf: map_key_clear(KEY_NUMERIC_D);	break;
   880			default: goto ignore;
   881			}
   882			break;
   883	
   884		case HID_UP_CONSUMER:	/* USB HUT v1.12, pages 75-84 */
   885			switch (usage->hid & HID_USAGE) {
   886			case 0x000: goto ignore;
   887			case 0x030: map_key_clear(KEY_POWER);		break;
   888			case 0x031: map_key_clear(KEY_RESTART);		break;
   889			case 0x032: map_key_clear(KEY_SLEEP);		break;
   890			case 0x034: map_key_clear(KEY_SLEEP);		break;
   891			case 0x035: map_key_clear(KEY_KBDILLUMTOGGLE);	break;
   892			case 0x036: map_key_clear(BTN_MISC);		break;
   893	
   894			case 0x040: map_key_clear(KEY_MENU);		break; /* Menu */
   895			case 0x041: map_key_clear(KEY_SELECT);		break; /* Menu Pick */
   896			case 0x042: map_key_clear(KEY_UP);		break; /* Menu Up */
   897			case 0x043: map_key_clear(KEY_DOWN);		break; /* Menu Down */
   898			case 0x044: map_key_clear(KEY_LEFT);		break; /* Menu Left */
   899			case 0x045: map_key_clear(KEY_RIGHT);		break; /* Menu Right */
   900			case 0x046: map_key_clear(KEY_ESC);		break; /* Menu Escape */
   901			case 0x047: map_key_clear(KEY_KPPLUS);		break; /* Menu Value Increase */
   902			case 0x048: map_key_clear(KEY_KPMINUS);		break; /* Menu Value Decrease */
   903	
   904			case 0x060: map_key_clear(KEY_INFO);		break; /* Data On Screen */
   905			case 0x061: map_key_clear(KEY_SUBTITLE);	break; /* Closed Caption */
   906			case 0x063: map_key_clear(KEY_VCR);		break; /* VCR/TV */
   907			case 0x065: map_key_clear(KEY_CAMERA);		break; /* Snapshot */
   908			case 0x069: map_key_clear(KEY_RED);		break;
   909			case 0x06a: map_key_clear(KEY_GREEN);		break;
   910			case 0x06b: map_key_clear(KEY_BLUE);		break;
   911			case 0x06c: map_key_clear(KEY_YELLOW);		break;
   912			case 0x06d: map_key_clear(KEY_ASPECT_RATIO);	break;
   913	
   914			case 0x06f: map_key_clear(KEY_BRIGHTNESSUP);		break;
   915			case 0x070: map_key_clear(KEY_BRIGHTNESSDOWN);		break;
   916			case 0x072: map_key_clear(KEY_BRIGHTNESS_TOGGLE);	break;
   917			case 0x073: map_key_clear(KEY_BRIGHTNESS_MIN);		break;
   918			case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX);		break;
   919			case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO);		break;
   920	
   921			case 0x079: map_key_clear(KEY_KBDILLUMUP);	break;
   922			case 0x07a: map_key_clear(KEY_KBDILLUMDOWN);	break;
   923			case 0x07c: map_key_clear(KEY_KBDILLUMTOGGLE);	break;
   924	
   925			case 0x082: map_key_clear(KEY_VIDEO_NEXT);	break;
   926			case 0x083: map_key_clear(KEY_LAST);		break;
   927			case 0x084: map_key_clear(KEY_ENTER);		break;
   928			case 0x088: map_key_clear(KEY_PC);		break;
   929			case 0x089: map_key_clear(KEY_TV);		break;
   930			case 0x08a: map_key_clear(KEY_WWW);		break;
   931			case 0x08b: map_key_clear(KEY_DVD);		break;
   932			case 0x08c: map_key_clear(KEY_PHONE);		break;
   933			case 0x08d: map_key_clear(KEY_PROGRAM);		break;
   934			case 0x08e: map_key_clear(KEY_VIDEOPHONE);	break;
   935			case 0x08f: map_key_clear(KEY_GAMES);		break;
   936			case 0x090: map_key_clear(KEY_MEMO);		break;
   937			case 0x091: map_key_clear(KEY_CD);		break;
   938			case 0x092: map_key_clear(KEY_VCR);		break;
   939			case 0x093: map_key_clear(KEY_TUNER);		break;
   940			case 0x094: map_key_clear(KEY_EXIT);		break;
   941			case 0x095: map_key_clear(KEY_HELP);		break;
   942			case 0x096: map_key_clear(KEY_TAPE);		break;
   943			case 0x097: map_key_clear(KEY_TV2);		break;
   944			case 0x098: map_key_clear(KEY_SAT);		break;
   945			case 0x09a: map_key_clear(KEY_PVR);		break;
   946	
   947			case 0x09c: map_key_clear(KEY_CHANNELUP);	break;
   948			case 0x09d: map_key_clear(KEY_CHANNELDOWN);	break;
   949			case 0x0a0: map_key_clear(KEY_VCR2);		break;
   950	
   951			case 0x0b0: map_key_clear(KEY_PLAY);		break;
   952			case 0x0b1: map_key_clear(KEY_PAUSE);		break;
   953			case 0x0b2: map_key_clear(KEY_RECORD);		break;
   954			case 0x0b3: map_key_clear(KEY_FASTFORWARD);	break;
   955			case 0x0b4: map_key_clear(KEY_REWIND);		break;
   956			case 0x0b5: map_key_clear(KEY_NEXTSONG);	break;
   957			case 0x0b6: map_key_clear(KEY_PREVIOUSSONG);	break;
   958			case 0x0b7: map_key_clear(KEY_STOPCD);		break;
   959			case 0x0b8: map_key_clear(KEY_EJECTCD);		break;
   960			case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT);	break;
   961			case 0x0b9: map_key_clear(KEY_SHUFFLE);		break;
   962			case 0x0bf: map_key_clear(KEY_SLOW);		break;
   963	
   964			case 0x0cd: map_key_clear(KEY_PLAYPAUSE);	break;
   965			case 0x0cf: map_key_clear(KEY_VOICECOMMAND);	break;
   966			case 0x0e0: map_abs_clear(ABS_VOLUME);		break;
   967			case 0x0e2: map_key_clear(KEY_MUTE);		break;
   968			case 0x0e5: map_key_clear(KEY_BASSBOOST);	break;
   969			case 0x0e9: map_key_clear(KEY_VOLUMEUP);	break;
   970			case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);	break;
   971			case 0x0f5: map_key_clear(KEY_SLOW);		break;
   972	
   973			case 0x181: map_key_clear(KEY_BUTTONCONFIG);	break;
   974			case 0x182: map_key_clear(KEY_BOOKMARKS);	break;
   975			case 0x183: map_key_clear(KEY_CONFIG);		break;
   976			case 0x184: map_key_clear(KEY_WORDPROCESSOR);	break;
   977			case 0x185: map_key_clear(KEY_EDITOR);		break;
   978			case 0x186: map_key_clear(KEY_SPREADSHEET);	break;
   979			case 0x187: map_key_clear(KEY_GRAPHICSEDITOR);	break;
   980			case 0x188: map_key_clear(KEY_PRESENTATION);	break;
   981			case 0x189: map_key_clear(KEY_DATABASE);	break;
   982			case 0x18a: map_key_clear(KEY_MAIL);		break;
   983			case 0x18b: map_key_clear(KEY_NEWS);		break;
   984			case 0x18c: map_key_clear(KEY_VOICEMAIL);	break;
   985			case 0x18d: map_key_clear(KEY_ADDRESSBOOK);	break;
   986			case 0x18e: map_key_clear(KEY_CALENDAR);	break;
   987			case 0x18f: map_key_clear(KEY_TASKMANAGER);	break;
   988			case 0x190: map_key_clear(KEY_JOURNAL);		break;
   989			case 0x191: map_key_clear(KEY_FINANCE);		break;
   990			case 0x192: map_key_clear(KEY_CALC);		break;
   991			case 0x193: map_key_clear(KEY_PLAYER);		break;
   992			case 0x194: map_key_clear(KEY_FILE);		break;
   993			case 0x196: map_key_clear(KEY_WWW);		break;
   994			case 0x199: map_key_clear(KEY_CHAT);		break;
   995			case 0x19c: map_key_clear(KEY_LOGOFF);		break;
   996			case 0x19e: map_key_clear(KEY_COFFEE);		break;
   997			case 0x19f: map_key_clear(KEY_CONTROLPANEL);		break;
   998			case 0x1a2: map_key_clear(KEY_APPSELECT);		break;
   999			case 0x1a3: map_key_clear(KEY_NEXT);		break;
  1000			case 0x1a4: map_key_clear(KEY_PREVIOUS);	break;
  1001			case 0x1a6: map_key_clear(KEY_HELP);		break;
  1002			case 0x1a7: map_key_clear(KEY_DOCUMENTS);	break;
  1003			case 0x1ab: map_key_clear(KEY_SPELLCHECK);	break;
  1004			case 0x1ae: map_key_clear(KEY_KEYBOARD);	break;
  1005			case 0x1b1: map_key_clear(KEY_SCREENSAVER);		break;
  1006			case 0x1b4: map_key_clear(KEY_FILE);		break;
  1007			case 0x1b6: map_key_clear(KEY_IMAGES);		break;
  1008			case 0x1b7: map_key_clear(KEY_AUDIO);		break;
  1009			case 0x1b8: map_key_clear(KEY_VIDEO);		break;
  1010			case 0x1bc: map_key_clear(KEY_MESSENGER);	break;
  1011			case 0x1bd: map_key_clear(KEY_INFO);		break;
  1012			case 0x1cb: map_key_clear(KEY_ASSISTANT);	break;
  1013			case 0x201: map_key_clear(KEY_NEW);		break;
  1014			case 0x202: map_key_clear(KEY_OPEN);		break;
  1015			case 0x203: map_key_clear(KEY_CLOSE);		break;
  1016			case 0x204: map_key_clear(KEY_EXIT);		break;
  1017			case 0x207: map_key_clear(KEY_SAVE);		break;
  1018			case 0x208: map_key_clear(KEY_PRINT);		break;
  1019			case 0x209: map_key_clear(KEY_PROPS);		break;
  1020			case 0x21a: map_key_clear(KEY_UNDO);		break;
  1021			case 0x21b: map_key_clear(KEY_COPY);		break;
  1022			case 0x21c: map_key_clear(KEY_CUT);		break;
  1023			case 0x21d: map_key_clear(KEY_PASTE);		break;
  1024			case 0x21f: map_key_clear(KEY_FIND);		break;
  1025			case 0x221: map_key_clear(KEY_SEARCH);		break;
  1026			case 0x222: map_key_clear(KEY_GOTO);		break;
  1027			case 0x223: map_key_clear(KEY_HOMEPAGE);	break;
  1028			case 0x224: map_key_clear(KEY_BACK);		break;
  1029			case 0x225: map_key_clear(KEY_FORWARD);		break;
  1030			case 0x226: map_key_clear(KEY_STOP);		break;
  1031			case 0x227: map_key_clear(KEY_REFRESH);		break;
  1032			case 0x22a: map_key_clear(KEY_BOOKMARKS);	break;
  1033			case 0x22d: map_key_clear(KEY_ZOOMIN);		break;
  1034			case 0x22e: map_key_clear(KEY_ZOOMOUT);		break;
  1035			case 0x22f: map_key_clear(KEY_ZOOMRESET);	break;
  1036			case 0x232: map_key_clear(KEY_FULL_SCREEN);	break;
  1037			case 0x233: map_key_clear(KEY_SCROLLUP);	break;
  1038			case 0x234: map_key_clear(KEY_SCROLLDOWN);	break;
  1039			case 0x238: /* AC Pan */
  1040				set_bit(REL_HWHEEL, input->relbit);
  1041				map_rel(REL_HWHEEL_HI_RES);
  1042				break;
  1043			case 0x23d: map_key_clear(KEY_EDIT);		break;
  1044			case 0x25f: map_key_clear(KEY_CANCEL);		break;
  1045			case 0x269: map_key_clear(KEY_INSERT);		break;
  1046			case 0x26a: map_key_clear(KEY_DELETE);		break;
  1047			case 0x279: map_key_clear(KEY_REDO);		break;
  1048	
  1049			case 0x289: map_key_clear(KEY_REPLY);		break;
  1050			case 0x28b: map_key_clear(KEY_FORWARDMAIL);	break;
  1051			case 0x28c: map_key_clear(KEY_SEND);		break;
  1052	
  1053			case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT);	break;
  1054	
  1055			case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV);		break;
  1056			case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT);		break;
  1057			case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP);		break;
  1058			case 0x2ca: map_key_clear(KEY_KBDINPUTASSIST_NEXTGROUP);		break;
  1059			case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT);	break;
  1060			case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL);	break;
  1061	
  1062			case 0x29f: map_key_clear(KEY_SCALE);		break;
  1063	
  1064			default: map_key_clear(KEY_UNKNOWN);
  1065			}
  1066			break;
  1067	
  1068		case HID_UP_GENDEVCTRLS:
  1069			switch (usage->hid) {
  1070			case HID_DC_BATTERYSTRENGTH:
  1071				hidinput_setup_battery(device, HID_INPUT_REPORT, field);
  1072				usage->type = EV_PWR;
  1073				return;
  1074			}
  1075			goto unknown;
  1076	
  1077		case HID_UP_BATTERY:
  1078			switch (usage->hid) {
  1079			case HID_BAT_ABSOLUTESTATEOFCHARGE:
  1080				hidinput_setup_battery(device, HID_INPUT_REPORT, field);
  1081				usage->type = EV_PWR;
> 1082				device->battery_min = 0;
> 1083				device->battery_max = 100;
  1084				return;
  1085			}
  1086			goto unknown;
  1087	
  1088		case HID_UP_HPVENDOR:	/* Reported on a Dutch layout HP5308 */
  1089			set_bit(EV_REP, input->evbit);
  1090			switch (usage->hid & HID_USAGE) {
  1091			case 0x021: map_key_clear(KEY_PRINT);           break;
  1092			case 0x070: map_key_clear(KEY_HP);		break;
  1093			case 0x071: map_key_clear(KEY_CAMERA);		break;
  1094			case 0x072: map_key_clear(KEY_SOUND);		break;
  1095			case 0x073: map_key_clear(KEY_QUESTION);	break;
  1096			case 0x080: map_key_clear(KEY_EMAIL);		break;
  1097			case 0x081: map_key_clear(KEY_CHAT);		break;
  1098			case 0x082: map_key_clear(KEY_SEARCH);		break;
  1099			case 0x083: map_key_clear(KEY_CONNECT);	        break;
  1100			case 0x084: map_key_clear(KEY_FINANCE);		break;
  1101			case 0x085: map_key_clear(KEY_SPORT);		break;
  1102			case 0x086: map_key_clear(KEY_SHOP);	        break;
  1103			default:    goto ignore;
  1104			}
  1105			break;
  1106	
  1107		case HID_UP_HPVENDOR2:
  1108			set_bit(EV_REP, input->evbit);
  1109			switch (usage->hid & HID_USAGE) {
  1110			case 0x001: map_key_clear(KEY_MICMUTE);		break;
  1111			case 0x003: map_key_clear(KEY_BRIGHTNESSDOWN);	break;
  1112			case 0x004: map_key_clear(KEY_BRIGHTNESSUP);	break;
  1113			default:    goto ignore;
  1114			}
  1115			break;
  1116	
  1117		case HID_UP_MSVENDOR:
  1118			goto ignore;
  1119	
  1120		case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */
  1121			set_bit(EV_REP, input->evbit);
  1122			goto ignore;
  1123	
  1124		case HID_UP_LOGIVENDOR:
  1125			/* intentional fallback */
  1126		case HID_UP_LOGIVENDOR2:
  1127			/* intentional fallback */
  1128		case HID_UP_LOGIVENDOR3:
  1129			goto ignore;
  1130	
  1131		case HID_UP_PID:
  1132			switch (usage->hid & HID_USAGE) {
  1133			case 0xa4: map_key_clear(BTN_DEAD);	break;
  1134			default: goto ignore;
  1135			}
  1136			break;
  1137	
  1138		default:
  1139		unknown:
  1140			if (field->report_size == 1) {
  1141				if (field->report->type == HID_OUTPUT_REPORT) {
  1142					map_led(LED_MISC);
  1143					break;
  1144				}
  1145				map_key(BTN_MISC);
  1146				break;
  1147			}
  1148			if (field->flags & HID_MAIN_ITEM_RELATIVE) {
  1149				map_rel(REL_MISC);
  1150				break;
  1151			}
  1152			map_abs(ABS_MISC);
  1153			break;
  1154		}
  1155	
  1156	mapped:
  1157		/* Mapping failed, bail out */
  1158		if (!bit)
  1159			return;
  1160	
  1161		if (device->driver->input_mapped &&
  1162		    device->driver->input_mapped(device, hidinput, field, usage,
  1163						 &bit, &max) < 0) {
  1164			/*
  1165			 * The driver indicated that no further generic handling
  1166			 * of the usage is desired.
  1167			 */
  1168			return;
  1169		}
  1170	
  1171		set_bit(usage->type, input->evbit);
  1172	
  1173		/*
  1174		 * This part is *really* controversial:
  1175		 * - HID aims at being generic so we should do our best to export
  1176		 *   all incoming events
  1177		 * - HID describes what events are, so there is no reason for ABS_X
  1178		 *   to be mapped to ABS_Y
  1179		 * - HID is using *_MISC+N as a default value, but nothing prevents
  1180		 *   *_MISC+N to overwrite a legitimate even, which confuses userspace
  1181		 *   (for instance ABS_MISC + 7 is ABS_MT_SLOT, which has a different
  1182		 *   processing)
  1183		 *
  1184		 * If devices still want to use this (at their own risk), they will
  1185		 * have to use the quirk HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE, but
  1186		 * the default should be a reliable mapping.
  1187		 */
  1188		while (usage->code <= max && test_and_set_bit(usage->code, bit)) {
  1189			if (device->quirks & HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE) {
  1190				usage->code = find_next_zero_bit(bit,
  1191								 max + 1,
  1192								 usage->code);
  1193			} else {
  1194				device->status |= HID_STAT_DUP_DETECTED;
  1195				goto ignore;
  1196			}
  1197		}
  1198	
  1199		if (usage->code > max)
  1200			goto ignore;
  1201	
  1202		if (usage->type == EV_ABS) {
  1203	
  1204			int a = field->logical_minimum;
  1205			int b = field->logical_maximum;
  1206	
  1207			if ((device->quirks & HID_QUIRK_BADPAD) && (usage->code == ABS_X || usage->code == ABS_Y)) {
  1208				a = field->logical_minimum = 0;
  1209				b = field->logical_maximum = 255;
  1210			}
  1211	
  1212			if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK)
  1213				input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4);
  1214			else	input_set_abs_params(input, usage->code, a, b, 0, 0);
  1215	
  1216			input_abs_set_res(input, usage->code,
  1217					  hidinput_calc_abs_res(field, usage->code));
  1218	
  1219			/* use a larger default input buffer for MT devices */
  1220			if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0)
  1221				input_set_events_per_packet(input, 60);
  1222		}
  1223	
  1224		if (usage->type == EV_ABS &&
  1225		    (usage->hat_min < usage->hat_max || usage->hat_dir)) {
  1226			int i;
  1227			for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
  1228				input_set_abs_params(input, i, -1, 1, 0, 0);
  1229				set_bit(i, input->absbit);
  1230			}
  1231			if (usage->hat_dir && !field->dpad)
  1232				field->dpad = usage->code;
  1233		}
  1234	
  1235		/* for those devices which produce Consumer volume usage as relative,
  1236		 * we emulate pressing volumeup/volumedown appropriate number of times
  1237		 * in hidinput_hid_event()
  1238		 */
  1239		if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
  1240				(usage->code == ABS_VOLUME)) {
  1241			set_bit(KEY_VOLUMEUP, input->keybit);
  1242			set_bit(KEY_VOLUMEDOWN, input->keybit);
  1243		}
  1244	
  1245		if (usage->type == EV_KEY) {
  1246			set_bit(EV_MSC, input->evbit);
  1247			set_bit(MSC_SCAN, input->mscbit);
  1248		}
  1249	
  1250		return;
  1251	
  1252	ignore:
  1253		usage->type = 0;
  1254		usage->code = 0;
  1255	}
  1256	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 34064 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-03-27 17:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-27 13:05 [PATCH 0/4] HID: add Apple Magic Mouse 2 support John Chen
2021-03-27 13:05 ` [PATCH 1/4] HID: magicmouse: " John Chen
2021-03-27 13:05 ` [PATCH 2/4] HID: magicmouse: fix 3 button emulation of Mouse 2 John Chen
2021-03-27 13:05 ` [PATCH 3/4] HID: magicmouse: fix reconnection of Magic " John Chen
2021-03-27 13:05 ` [PATCH 4/4] HID: input: map battery capacity (00850065) John Chen
2021-03-27 14:14   ` Pochang Chen
2021-03-27 17:22   ` kernel test robot
2021-03-27 17:50   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).