[PATCH] ACPI / button: add support for tablet mode switch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Wei-Ning Huang <wnhuang@xxxxxxxxxxxx>

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@xxxxxxxxxxxx>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux