From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751174AbdA1AbE (ORCPT ); Fri, 27 Jan 2017 19:31:04 -0500 Received: from mail-pg0-f51.google.com ([74.125.83.51]:34933 "EHLO mail-pg0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750775AbdA1Aa4 (ORCPT ); Fri, 27 Jan 2017 19:30:56 -0500 Date: Fri, 27 Jan 2017 16:30:08 -0800 From: Benson Leung To: Gwendal Grignou Cc: bleung@chromium.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] platform: chrome: Add Tablet Switch ACPI driver Message-ID: <20170128003007.GA4191@google.com> References: <20170123233955.7058-1-gwendal@chromium.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="CE+1k2dSO48ffgeK" Content-Disposition: inline In-Reply-To: <20170123233955.7058-1-gwendal@chromium.org> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --CE+1k2dSO48ffgeK Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable 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. >=20 > 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 ------------ > ... >=20 > Signed-off-by: Gwendal Grignou > --- > 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 >=20 > diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kc= onfig > 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. > =20 > +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 interfa= ce" > - depends on MFD_CROS_EC > - ---help--- > - This driver adds support to talk with the ChromeOS EC from use= rspace. > + 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. > =20 > - 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. > =20 > 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. > =20 > - 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. > =20 > config CROS_EC_PROTO > - bool > - help > - ChromeOS EC communication protocol helpers. > + bool > + help > + ChromeOS EC communication protocol helpers. > =20 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/M= akefile > index 4f3462783a3c..b61a0166c0ce 100644 > --- a/drivers/platform/chrome/Makefile > +++ b/drivers/platform/chrome/Makefile > @@ -1,6 +1,7 @@ > =20 > obj-$(CONFIG_CHROMEOS_LAPTOP) +=3D chromeos_laptop.o > obj-$(CONFIG_CHROMEOS_PSTORE) +=3D chromeos_pstore.o > +obj-$(CONFIG_CHROMEOS_TBMC) +=3D chromeos_tbmc.o > cros_ec_devs-objs :=3D cros_ec_dev.o cros_ec_sysfs.o \ > cros_ec_lightbar.o cros_ec_vbc.o > obj-$(CONFIG_CROS_EC_CHARDEV) +=3D cros_ec_devs.o > diff --git a/drivers/platform/chrome/chromeos_tbmc.c b/drivers/platform/c= hrome/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 > +#include > +#include > +#include > +#include > + > +#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 =3D 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 =3D 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 =3D &adev->dev; > + int ret; > + > + idev =3D devm_input_allocate_device(dev); > + if (!idev) > + return -ENOMEM; > + > + idev->name =3D "Tablet Mode Switch"; > + idev->phys =3D acpi_device_hid(adev); > + > + idev->id.bustype =3D BUS_HOST; > + idev->id.version =3D 1; > + idev->id.product =3D 0; > + idev->open =3D chromeos_tbmc_open; > + > + input_set_drvdata(idev, adev); > + adev->driver_data =3D idev; > + > + input_set_capability(idev, EV_SW, SW_TABLET_MODE); > + ret =3D 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[] =3D { > + { ACPI_DRV_NAME, 0 }, > + { } > +}; > +MODULE_DEVICE_TABLE(acpi, chromeos_tbmc_acpi_device_ids); > + > +static struct acpi_driver chromeos_tbmc_driver =3D { > + .name =3D DRV_NAME, > + .class =3D DRV_NAME, > + .ids =3D chromeos_tbmc_acpi_device_ids, > + .ops =3D { > + .add =3D chromeos_tbmc_add, > + .notify =3D 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 --=20 Benson Leung Senior Software Engineer Chrome OS Kernel Google Inc. bleung@google.com Chromium OS Project bleung@chromium.org --CE+1k2dSO48ffgeK Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBCgAGBQJYi+YPAAoJEB8J9XsKL+ZYAy4P/RkwidLNekuqGdjVijS6yhax dGQ6K8bw2eEh9PHsZnCVtG36wNXM6kGQ7mZ2nEJakv1sMqvy7+V07s6z95an/HSA r5wKj26pj7sGhxIVaoo4NqW0RuQ7DAsE7b/5dAD8/NCoaixsgMQPoUHM2fxUwxYu iEiCgoGdTmTgsisMtmebM9iMT+ng074l21CRNniTJXQ3+RLaW43CGtwJp/YTEeQa SKEUiXARN3NkB8davrfAuWn4iK+nLWCeUjSYkPJPODdArdpxnpRSBTzS7tNMQYQ0 IAOB5LeWasC1ZUFbeo7Y/F40G/zX41wt9imIo9+rMSOmGufnZr/VjdAyBz5r3p40 MFEQlqdK02Z14Yd3IAo/8S4xCMxxym0EnLiFMh7idQkXFRw+UsZSuBmfzcH1+MR+ 5/reMq5jolTq8iiO99pBNuKV2xurEaw/8c/2XX8o2PzJNDP1LnADtV+SQ2JEhIox CfDbH1LvJX7YGmAyp2ge6kb0CxN0oYFahpSZ26zDb/iLoxjQno84oOY1LCIP3ZmT wbirKX7fWJLdtX+a4YqqP02gO27AAQge/kweGOJejkuX+e5aARCSwkAzKfI6beMy CxC8oHKD06YDx3g04Bd5IBowiIH2s7yiNxRApk5et4WOHaHqE1Ykc8dlfLOn1WG6 z4WeIzJsuWJd2Hr7Vqgg =lvAv -----END PGP SIGNATURE----- --CE+1k2dSO48ffgeK--