Messages in this thread | | | Date | Fri, 27 Jan 2017 16:30:08 -0800 | From | Benson Leung <> | Subject | Re: [PATCH] platform: chrome: Add Tablet Switch ACPI driver |
| |
Hi Gwendal,
Thanks for sending this!
On Mon, Jan 23, 2017 at 03:39:55PM -0800, Gwendal Grignou wrote: > Add a kernel driver for GOOG0006, an ACPI driver reporting an event when > the tablet switch status changes. > > On an ACPI based convertible chromebook check evtest display tablet mode > switch changes: > Available devices: > .. > /dev/input/event3: Tablet Mode Switch > .. > Testing ... (interrupt to exit) > Event: time 1484879712.604360, type 5 (EV_SW), code 1 (SW_TABLET_MODE), > value 1 > Event: time 1484879712.604360, -------------- SYN_REPORT ------------ > Event: time 1484879715.132228, type 5 (EV_SW), code 1 (SW_TABLET_MODE), > value 0 > Event: time 1484879715.132228, -------------- SYN_REPORT ------------ > ... > > Signed-off-by: Gwendal Grignou <gwendal@chromium.org> > --- > drivers/platform/chrome/Kconfig | 46 ++++++++----- > drivers/platform/chrome/Makefile | 1 + > drivers/platform/chrome/chromeos_tbmc.c | 117 ++++++++++++++++++++++++++++++++ > 3 files changed, 146 insertions(+), 18 deletions(-) > create mode 100644 drivers/platform/chrome/chromeos_tbmc.c > > diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig > index 76bdae1a93bb..51f8d7df4ad4 100644 > --- a/drivers/platform/chrome/Kconfig > +++ b/drivers/platform/chrome/Kconfig > @@ -38,31 +38,41 @@ config CHROMEOS_PSTORE > If you have a supported Chromebook, choose Y or M here. > The module will be called chromeos_pstore. > > +config CHROMEOS_TBMC > + tristate "ChromeOS Tablet Switch Controller" > + depends on ACPI > + ---help--- > + This option adds a driver for the tablet switch on > + select Chrome OS systems. > + > + To compile this driver as a module, choose M here: the > + module will be called chromeos_tbmc. > + > config CROS_EC_CHARDEV > - tristate "Chrome OS Embedded Controller userspace device interface" > - depends on MFD_CROS_EC > - ---help--- > - This driver adds support to talk with the ChromeOS EC from userspace. > + tristate "Chrome OS Embedded Controller userspace device interface" > + depends on MFD_CROS_EC > + ---help--- > + This driver adds support to talk with the ChromeOS EC from userspace. > > - If you have a supported Chromebook, choose Y or M here. > - The module will be called cros_ec_dev. > + If you have a supported Chromebook, choose Y or M here. > + The module will be called cros_ec_dev. > > config CROS_EC_LPC > - tristate "ChromeOS Embedded Controller (LPC)" > - depends on MFD_CROS_EC && (X86 || COMPILE_TEST) > - help > - If you say Y here, you get support for talking to the ChromeOS EC > - over an LPC bus. This uses a simple byte-level protocol with a > - checksum. This is used for userspace access only. The kernel > - typically has its own communication methods. > + tristate "ChromeOS Embedded Controller (LPC)" > + depends on MFD_CROS_EC && (X86 || COMPILE_TEST) > + help > + If you say Y here, you get support for talking to the ChromeOS EC > + over an LPC bus. This uses a simple byte-level protocol with a > + checksum. This is used for userspace access only. The kernel > + typically has its own communication methods. > > - To compile this driver as a module, choose M here: the > - module will be called cros_ec_lpc. > + To compile this driver as a module, choose M here: the > + module will be called cros_ec_lpc. > > config CROS_EC_PROTO > - bool > - help > - ChromeOS EC communication protocol helpers. > + bool > + help > + ChromeOS EC communication protocol helpers. >
Let's leave the cleanup of the Kconfig (for whitespace) for another patch. Just add the CHROMEOS_TBMC.
> config CROS_KBD_LED_BACKLIGHT > tristate "Backlight LED support for Chrome OS keyboards" > diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile > index 4f3462783a3c..b61a0166c0ce 100644 > --- a/drivers/platform/chrome/Makefile > +++ b/drivers/platform/chrome/Makefile > @@ -1,6 +1,7 @@ > > obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o > obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o > +obj-$(CONFIG_CHROMEOS_TBMC) += chromeos_tbmc.o > cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \ > cros_ec_lightbar.o cros_ec_vbc.o > obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o > diff --git a/drivers/platform/chrome/chromeos_tbmc.c b/drivers/platform/chrome/chromeos_tbmc.c > new file mode 100644 > index 000000000000..c159eb38d79b > --- /dev/null > +++ b/drivers/platform/chrome/chromeos_tbmc.c > @@ -0,0 +1,117 @@ > +/* > + * chromeos_tbmc - Driver to detect Tablet Mode for ChromeOS convertible. > + * > + * Copyright 2017 Google, Inc > + * > + * This software is licensed under the terms of the GNU General Public > + * License version 2, as published by the Free Software Foundation, and > + * may be copied, distributed, and modified under those terms. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * On Chromebook using ACPI, this device listens for notification > + * from GOOG0006 and issue method TBMC to retrieve the status. > + * > + * GOOG0006 issues the notification when it receives EC_HOST_EVENT_MODE_CHANGE > + * from the EC. > + * Method TBMC reads EC_ACPI_MEM_DEVICE_ORIENTATION byte from the shared > + * memory region. > + */ > + > +#include <linux/acpi.h> > +#include <linux/input.h> > +#include <linux/io.h> > +#include <linux/module.h> > +#include <linux/printk.h> > + > +#define DRV_NAME "chromeos_tbmc" > +#define ACPI_DRV_NAME "GOOG0006" > + > +static int chromeos_tbmc_query_switch(struct acpi_device *adev, > + struct input_dev *idev) > +{ > + unsigned long long state; > + acpi_status status; > + > + status = acpi_evaluate_integer(adev->handle, "TBMC", NULL, &state); > + if (ACPI_FAILURE(status)) > + return -ENODEV; > + > + /* input layer checks if event is redundant */ > + input_report_switch(idev, SW_TABLET_MODE, state); > + input_sync(idev); > + > + return 0; > +} > + > +static void chromeos_tbmc_notify(struct acpi_device *adev, u32 event) > +{ > + switch (event) { > + case 0x80: > + chromeos_tbmc_query_switch(adev, adev->driver_data); > + break; > + default: > + dev_err(&adev->dev, "Unexpected event: 0x%08X\n", event); > + } > +} > + > +static int chromeos_tbmc_open(struct input_dev *idev) > +{ > + struct acpi_device *adev = input_get_drvdata(idev); > + > + return chromeos_tbmc_query_switch(adev, idev); > +} > + > +static int chromeos_tbmc_add(struct acpi_device *adev) > +{ > + struct input_dev *idev; > + struct device *dev = &adev->dev; > + int ret; > + > + idev = devm_input_allocate_device(dev); > + if (!idev) > + return -ENOMEM; > + > + idev->name = "Tablet Mode Switch"; > + idev->phys = acpi_device_hid(adev); > + > + idev->id.bustype = BUS_HOST; > + idev->id.version = 1; > + idev->id.product = 0; > + idev->open = chromeos_tbmc_open; > + > + input_set_drvdata(idev, adev); > + adev->driver_data = idev; > + > + input_set_capability(idev, EV_SW, SW_TABLET_MODE); > + ret = input_register_device(idev); > + if (ret) { > + dev_err(dev, "cannot register input device\n"); > + return ret; > + } > + return 0; > +} > + > +static const struct acpi_device_id chromeos_tbmc_acpi_device_ids[] = { > + { ACPI_DRV_NAME, 0 }, > + { } > +}; > +MODULE_DEVICE_TABLE(acpi, chromeos_tbmc_acpi_device_ids); > + > +static struct acpi_driver chromeos_tbmc_driver = { > + .name = DRV_NAME, > + .class = DRV_NAME, > + .ids = chromeos_tbmc_acpi_device_ids, > + .ops = { > + .add = chromeos_tbmc_add, > + .notify = chromeos_tbmc_notify, > + }, > +};
I talked to you about this offline, but can you check if you do or do not need special resume handling of this switch? I suspect there's a decent chance the notify might not result in an event if the tablet mode changed during the time the Chromebook is sleeping.
Thanks! Benson
-- Benson Leung Senior Software Engineer Chrome OS Kernel Google Inc. bleung@google.com Chromium OS Project bleung@chromium.org [unhandled content-type:application/pgp-signature] | |