On 三, 2016-08-31 at 15:33 +0800, Wei-Ning Huang wrote: > 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); Control methods with prefix "_" suggests this is an ACPI predefined control method, but I can not find it in ACPI spec 6.1. Can you illustrate me where I can find the definition of _TBL? thanks, rui > + 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; -- 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