lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1472628817-3145-1-git-send-email-wnhuang@google.com>
Date:   Wed, 31 Aug 2016 15:33:37 +0800
From:   Wei-Ning Huang <wnhuang@...omium.org>
To:     "Rafael J . Wysocki" <rjw@...ysocki.net>,
        Len Brown <lenb@...nel.org>, linux-acpi@...r.kernel.org,
        linux-kernel@...r.kernel.org
Cc:     Wei-Ning Huang <wnhuang@...gle.com>,
        Wei-Ning Huang <wnhuang@...omium.org>
Subject: [PATCH] ACPI / button: add support for tablet mode switch

From: Wei-Ning Huang <wnhuang@...omium.org>

ACPI PNP device HID 'PNP0C60' is a device that indicates tablet mode
status. Add support for mapping this device to the SW_TABLET_MODE input
event.

Signed-off-by: Wei-Ning Huang <wnhuang@...omium.org>
---
 drivers/acpi/button.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 148f4e5..50e9de6 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -53,6 +53,11 @@
 #define ACPI_BUTTON_DEVICE_NAME_LID	"Lid Switch"
 #define ACPI_BUTTON_TYPE_LID		0x05
 
+#define ACPI_BUTTON_SUBCLASS_TABLET	"tablet"
+#define ACPI_BUTTON_HID_TABLET		"PNP0C60"
+#define ACPI_BUTTON_DEVICE_NAME_TABLET	"Tablet Mode Switch"
+#define ACPI_BUTTON_TYPE_TABLET		0x07
+
 #define ACPI_BUTTON_LID_INIT_IGNORE	0x00
 #define ACPI_BUTTON_LID_INIT_OPEN	0x01
 #define ACPI_BUTTON_LID_INIT_METHOD	0x02
@@ -70,6 +75,7 @@ static const struct acpi_device_id button_device_ids[] = {
 	{ACPI_BUTTON_HID_SLEEPF, 0},
 	{ACPI_BUTTON_HID_POWER,  0},
 	{ACPI_BUTTON_HID_POWERF, 0},
+	{ACPI_BUTTON_HID_TABLET, 0},
 	{"", 0},
 };
 MODULE_DEVICE_TABLE(acpi, button_device_ids);
@@ -305,6 +311,23 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
 	}
 }
 
+static int acpi_tablet_send_state(struct acpi_device *device)
+{
+	struct acpi_button *button = acpi_driver_data(device);
+	unsigned long long state;
+	acpi_status status;
+
+	status = acpi_evaluate_integer(device->handle, "_TBL", NULL, &state);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	/* input layer checks if event is redundant */
+	input_report_switch(button->input, SW_TABLET_MODE, state);
+	input_sync(button->input);
+
+	return 0;
+}
+
 static void acpi_button_notify(struct acpi_device *device, u32 event)
 {
 	struct acpi_button *button = acpi_driver_data(device);
@@ -318,6 +341,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
 		input = button->input;
 		if (button->type == ACPI_BUTTON_TYPE_LID) {
 			acpi_lid_update_state(device);
+		} else if (button->type == ACPI_BUTTON_TYPE_TABLET) {
+			acpi_tablet_send_state(device);
 		} else {
 			int keycode;
 
@@ -407,6 +432,11 @@ static int acpi_button_add(struct acpi_device *device)
 		strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
 		sprintf(class, "%s/%s",
 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
+	} else if (!strcmp(hid, ACPI_BUTTON_HID_TABLET)) {
+		button->type = ACPI_BUTTON_TYPE_TABLET;
+		strcpy(name, ACPI_BUTTON_DEVICE_NAME_TABLET);
+		sprintf(class, "%s/%s",
+			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_TABLET);
 	} else {
 		printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
 		error = -ENODEV;
@@ -437,6 +467,10 @@ static int acpi_button_add(struct acpi_device *device)
 	case ACPI_BUTTON_TYPE_LID:
 		input_set_capability(input, EV_SW, SW_LID);
 		break;
+
+	case ACPI_BUTTON_TYPE_TABLET:
+		input_set_capability(input, EV_SW, SW_TABLET_MODE);
+		break;
 	}
 
 	error = input_register_device(input);
@@ -450,6 +484,8 @@ static int acpi_button_add(struct acpi_device *device)
 		 */
 		lid_device = device;
 	}
+	if (button->type == ACPI_BUTTON_TYPE_TABLET)
+		acpi_tablet_send_state(device);
 
 	printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
 	return 0;
-- 
2.8.0.rc3.226.g39d4020

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ