linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/4] HID: i2c-hid: Reorganize to allow supporting goodix,gt7375p
@ 2020-11-09 21:36 Douglas Anderson
  2020-11-09 21:36 ` [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules Douglas Anderson
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Douglas Anderson @ 2020-11-09 21:36 UTC (permalink / raw)
  To: jkosina, benjamin.tissoires, gregkh, Dmitry Torokhov
  Cc: kai.heng.feng, hdegoede, robh+dt, linux-input, swboyd, andrea,
	Douglas Anderson, Anson Huang, Bjorn Andersson, Catalin Marinas,
	Geert Uytterhoeven, Jiri Kosina, Krzysztof Kozlowski, Li Yang,
	Masahiro Yamada, Michael Walle, Olof Johansson, Pavel Balan,
	Shawn Guo, Vinod Koul, Will Deacon, Xiaofei Tan, You-Sheng Yang,
	devicetree, linux-arm-kernel, linux-kernel


The goal of this series is to support the Goodix GT7375P touchscreen.
This touchscreen is special because it has power sequencing
requirements that necessitate driving a reset GPIO.

To do this, we totally rejigger the way i2c-hid is organized so that
it's easier to jam the Goodix support in there.

This series was:
- Tested on a device that uses normal i2c-hid.
- Tested on a device that has a Goodix i2c-hid device.
- NOT tested on any ACPI devices (just compile tested).

Changes in v5:
- Add shutdown_tail op and use it in ACPI.
- Added mention of i2c-hid in the yaml itself as per Rob.
- Adjusted subject as per Rob.
- i2chid_subclass_data => i2chid_ops.
- power_up_device => power_up (same with power_down).
- subclass => ops.

Changes in v4:
- ("arm64: defconfig: Update config names for i2c-hid rejigger") new for v4.
- Fully rejigger so ACPI and OF are full subclasses.
- Totally redid based on the new subclass system.

Changes in v3:
- Fixed compatible in example.
- Removed Benjamin as a maintainer.
- Rework to use subclassing.
- Updated description.

Changes in v2:
- ("dt-bindings: HID: i2c-hid: Introduce bindings for the Goodix GT7375P") new in v2.
- Get timings based on the compatible string.
- Use a separate compatible string for this new touchscreen.

Douglas Anderson (4):
  HID: i2c-hid: Reorganize so ACPI and OF are separate modules
  arm64: defconfig: Update config names for i2c-hid rejigger
  dt-bindings: input: HID: i2c-hid: Introduce bindings for the Goodix
    GT7375P
  HID: i2c-hid: Introduce goodix-i2c-hid using i2c-hid core

 .../bindings/input/goodix,gt7375p.yaml        |  65 +++++
 arch/arm64/configs/defconfig                  |   3 +-
 drivers/hid/Makefile                          |   2 +-
 drivers/hid/i2c-hid/Kconfig                   |  47 +++-
 drivers/hid/i2c-hid/Makefile                  |   6 +-
 drivers/hid/i2c-hid/i2c-hid-acpi.c            | 170 ++++++++++++
 drivers/hid/i2c-hid/i2c-hid-core.c            | 252 +++---------------
 drivers/hid/i2c-hid/i2c-hid-of-goodix.c       | 120 +++++++++
 drivers/hid/i2c-hid/i2c-hid-of.c              | 147 ++++++++++
 drivers/hid/i2c-hid/i2c-hid.h                 |  25 ++
 include/linux/platform_data/i2c-hid.h         |  41 ---
 11 files changed, 615 insertions(+), 263 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/goodix,gt7375p.yaml
 create mode 100644 drivers/hid/i2c-hid/i2c-hid-acpi.c
 create mode 100644 drivers/hid/i2c-hid/i2c-hid-of-goodix.c
 create mode 100644 drivers/hid/i2c-hid/i2c-hid-of.c
 delete mode 100644 include/linux/platform_data/i2c-hid.h

-- 
2.29.2.222.g5d2a92d10f8-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules
  2020-11-09 21:36 [PATCH v5 0/4] HID: i2c-hid: Reorganize to allow supporting goodix,gt7375p Douglas Anderson
@ 2020-11-09 21:36 ` Douglas Anderson
  2020-11-09 23:23   ` Doug Anderson
  2020-11-10  9:01   ` Hans de Goede
  2020-11-09 21:36 ` [PATCH v5 2/4] arm64: defconfig: Update config names for i2c-hid rejigger Douglas Anderson
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Douglas Anderson @ 2020-11-09 21:36 UTC (permalink / raw)
  To: jkosina, benjamin.tissoires, gregkh, Dmitry Torokhov
  Cc: kai.heng.feng, hdegoede, robh+dt, linux-input, swboyd, andrea,
	Douglas Anderson, Jiri Kosina, Masahiro Yamada, Pavel Balan,
	Xiaofei Tan, You-Sheng Yang, linux-kernel

This patch rejiggers the i2c-hid code so that the OF (Open Firmware
aka Device Tree) and ACPI support is separated out a bit.  The OF and
ACPI drivers are now separate modules that wrap the core module.

Essentially, what we're doing here:
* Make "power up" and "power down" a function that can be (optionally)
  implemented by a given user of the i2c-hid core.
* The OF and ACPI modules are drivers on their own, so they implement
  probe / remove / suspend / resume / shutdown.  The core code
  provides implementations that OF and ACPI can call into.

We'll organize this so that we now have 3 modules: the old i2c-hid
module becomes the "core" module and two new modules will depend on
it, handling probing the specific device.

As part of this work, we'll remove the i2c-hid "platform data"
concept since it's not needed.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

Changes in v5:
- Add shutdown_tail op and use it in ACPI.
- i2chid_subclass_data => i2chid_ops.
- power_up_device => power_up (same with power_down).
- subclass => ops.

Changes in v4:
- Fully rejigger so ACPI and OF are full subclasses.

Changes in v3:
- Rework to use subclassing.

Changes in v2:
- Get timings based on the compatible string.
- Use a separate compatible string for this new touchscreen.

 drivers/hid/Makefile                  |   2 +-
 drivers/hid/i2c-hid/Kconfig           |  32 +++-
 drivers/hid/i2c-hid/Makefile          |   5 +-
 drivers/hid/i2c-hid/i2c-hid-acpi.c    | 170 +++++++++++++++++
 drivers/hid/i2c-hid/i2c-hid-core.c    | 252 ++++----------------------
 drivers/hid/i2c-hid/i2c-hid-of.c      | 147 +++++++++++++++
 drivers/hid/i2c-hid/i2c-hid.h         |  25 +++
 include/linux/platform_data/i2c-hid.h |  41 -----
 8 files changed, 412 insertions(+), 262 deletions(-)
 create mode 100644 drivers/hid/i2c-hid/i2c-hid-acpi.c
 create mode 100644 drivers/hid/i2c-hid/i2c-hid-of.c
 delete mode 100644 include/linux/platform_data/i2c-hid.h

diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 4acb583c92a6..8d0c15a0d652 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -138,7 +138,7 @@ obj-$(CONFIG_USB_HID)		+= usbhid/
 obj-$(CONFIG_USB_MOUSE)		+= usbhid/
 obj-$(CONFIG_USB_KBD)		+= usbhid/
 
-obj-$(CONFIG_I2C_HID)		+= i2c-hid/
+obj-$(CONFIG_I2C_HID_CORE)	+= i2c-hid/
 
 obj-$(CONFIG_INTEL_ISH_HID)	+= intel-ish-hid/
 obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER)	+= intel-ish-hid/
diff --git a/drivers/hid/i2c-hid/Kconfig b/drivers/hid/i2c-hid/Kconfig
index c4e5dfeab2bd..819b7521c182 100644
--- a/drivers/hid/i2c-hid/Kconfig
+++ b/drivers/hid/i2c-hid/Kconfig
@@ -2,18 +2,40 @@
 menu "I2C HID support"
 	depends on I2C
 
-config I2C_HID
-	tristate "HID over I2C transport layer"
+config I2C_HID_ACPI
+	tristate "HID over I2C transport layer ACPI driver"
 	default n
-	depends on I2C && INPUT
-	select HID
+	depends on I2C && INPUT && ACPI
+	help
+	  Say Y here if you use a keyboard, a touchpad, a touchscreen, or any
+	  other HID based devices which is connected to your computer via I2C.
+	  This driver supports ACPI-based systems.
+
+	  If unsure, say N.
+
+	  This support is also available as a module.  If so, the module
+	  will be called i2c-hid-acpi.  It will also build/depend on the
+	  module i2c-hid.
+
+config I2C_HID_OF
+	tristate "HID over I2C transport layer Open Firmware driver"
+	default n
+	depends on I2C && INPUT && OF
 	help
 	  Say Y here if you use a keyboard, a touchpad, a touchscreen, or any
 	  other HID based devices which is connected to your computer via I2C.
+	  This driver supports Open Firmware (Device Tree)-based systems.
 
 	  If unsure, say N.
 
 	  This support is also available as a module.  If so, the module
-	  will be called i2c-hid.
+	  will be called i2c-hid-of.  It will also build/depend on the
+	  module i2c-hid.
 
 endmenu
+
+config I2C_HID_CORE
+	tristate
+	default y if I2C_HID_ACPI=y || I2C_HID_OF=y
+	default m if I2C_HID_ACPI=m || I2C_HID_OF=m
+	select HID
diff --git a/drivers/hid/i2c-hid/Makefile b/drivers/hid/i2c-hid/Makefile
index 681b3896898e..9b4a73446841 100644
--- a/drivers/hid/i2c-hid/Makefile
+++ b/drivers/hid/i2c-hid/Makefile
@@ -3,7 +3,10 @@
 # Makefile for the I2C input drivers
 #
 
-obj-$(CONFIG_I2C_HID)				+= i2c-hid.o
+obj-$(CONFIG_I2C_HID_CORE)			+= i2c-hid.o
 
 i2c-hid-objs					=  i2c-hid-core.o
 i2c-hid-$(CONFIG_DMI)				+= i2c-hid-dmi-quirks.o
+
+obj-$(CONFIG_I2C_HID_ACPI)			+= i2c-hid-acpi.o
+obj-$(CONFIG_I2C_HID_OF)			+= i2c-hid-of.o
diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c
new file mode 100644
index 000000000000..5f09635d00ce
--- /dev/null
+++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c
@@ -0,0 +1,170 @@
+/*
+ * HID over I2C ACPI Subclass
+ *
+ * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
+ * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France
+ * Copyright (c) 2012 Red Hat, Inc
+ *
+ * This code was forked out of the core code, which was partly based on
+ * "USB HID support for Linux":
+ *
+ *  Copyright (c) 1999 Andreas Gal
+ *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
+ *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
+ *  Copyright (c) 2007-2008 Oliver Neukum
+ *  Copyright (c) 2006-2010 Jiri Kosina
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+
+#include "i2c-hid.h"
+
+struct i2c_hid_acpi {
+	struct i2chid_ops ops;
+	struct i2c_client *client;
+	bool power_fixed;
+};
+
+static const struct acpi_device_id i2c_hid_acpi_blacklist[] = {
+	/*
+	 * The CHPN0001 ACPI device, which is used to describe the Chipone
+	 * ICN8505 controller, has a _CID of PNP0C50 but is not HID compatible.
+	 */
+	{"CHPN0001", 0 },
+	{ },
+};
+
+static int i2c_hid_acpi_get_descriptor(struct i2c_client *client)
+{
+	static guid_t i2c_hid_guid =
+		GUID_INIT(0x3CDFF6F7, 0x4267, 0x4555,
+			  0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE);
+	union acpi_object *obj;
+	struct acpi_device *adev;
+	acpi_handle handle;
+	u16 hid_descriptor_address;
+
+	handle = ACPI_HANDLE(&client->dev);
+	if (!handle || acpi_bus_get_device(handle, &adev)) {
+		dev_err(&client->dev, "Error could not get ACPI device\n");
+		return -ENODEV;
+	}
+
+	if (acpi_match_device_ids(adev, i2c_hid_acpi_blacklist) == 0)
+		return -ENODEV;
+
+	obj = acpi_evaluate_dsm_typed(handle, &i2c_hid_guid, 1, 1, NULL,
+				      ACPI_TYPE_INTEGER);
+	if (!obj) {
+		dev_err(&client->dev, "Error _DSM call to get HID descriptor address failed\n");
+		return -ENODEV;
+	}
+
+	hid_descriptor_address = obj->integer.value;
+	ACPI_FREE(obj);
+
+	return hid_descriptor_address;
+}
+
+static int i2c_hid_acpi_power_up(struct i2chid_ops *ops)
+{
+	struct i2c_hid_acpi *ihid_of =
+		container_of(ops, struct i2c_hid_acpi, ops);
+	struct device *dev = &ihid_of->client->dev;
+	struct acpi_device *adev;
+
+	/* Only need to call acpi_device_fix_up_power() the first time */
+	if (ihid_of->power_fixed)
+		return 0;
+	ihid_of->power_fixed = true;
+
+	adev = ACPI_COMPANION(dev);
+	if (adev)
+		acpi_device_fix_up_power(adev);
+
+	return 0;
+}
+
+static void i2c_hid_acpi_shutdown_tail(struct i2chid_ops *ops)
+{
+	struct i2c_hid_acpi *ihid_of =
+		container_of(ops, struct i2c_hid_acpi, ops);
+	struct device *dev = &ihid_of->client->dev;
+	acpi_device_set_power(ACPI_COMPANION(dev), ACPI_STATE_D3_COLD);
+}
+
+int i2c_hid_acpi_probe(struct i2c_client *client,
+		       const struct i2c_device_id *dev_id)
+{
+	struct device *dev = &client->dev;
+	struct i2c_hid_acpi *ihid_acpi;
+	u16 hid_descriptor_address;
+	int ret;
+
+	ihid_acpi = devm_kzalloc(&client->dev, sizeof(*ihid_acpi), GFP_KERNEL);
+	if (!ihid_acpi)
+		return -ENOMEM;
+
+	ihid_acpi->ops.power_up = i2c_hid_acpi_power_up;
+	ihid_acpi->ops.shutdown_tail = i2c_hid_acpi_shutdown_tail;
+
+	ret = i2c_hid_acpi_get_descriptor(client);
+	if (ret < 0)
+		return ret;
+	hid_descriptor_address = ret;
+
+	if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
+		device_set_wakeup_capable(dev, true);
+		device_set_wakeup_enable(dev, false);
+	}
+
+	return i2c_hid_core_probe(client, &ihid_acpi->ops,
+				  hid_descriptor_address);
+}
+
+static const struct dev_pm_ops i2c_hid_acpi_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_core_suspend, i2c_hid_core_resume)
+};
+
+static const struct acpi_device_id i2c_hid_acpi_match[] = {
+	{"ACPI0C50", 0 },
+	{"PNP0C50", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match);
+
+static const struct i2c_device_id i2c_hid_acpi_id_table[] = {
+	{ "hid", 0 },
+	{ "hid-over-i2c", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, i2c_hid_acpi_id_table);
+
+static struct i2c_driver i2c_hid_acpi_driver = {
+	.driver = {
+		.name	= "i2c_hid_acpi",
+		.pm	= &i2c_hid_acpi_pm,
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+		.acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
+	},
+
+	.probe		= i2c_hid_acpi_probe,
+	.remove		= i2c_hid_core_remove,
+	.shutdown	= i2c_hid_core_shutdown,
+	.id_table	= i2c_hid_acpi_id_table,
+};
+
+module_i2c_driver(i2c_hid_acpi_driver);
+
+MODULE_DESCRIPTION("HID over I2C ACPI driver");
+MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index aeff1ffb0c8b..9551ba96dc49 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -35,12 +35,8 @@
 #include <linux/kernel.h>
 #include <linux/hid.h>
 #include <linux/mutex.h>
-#include <linux/acpi.h>
-#include <linux/of.h>
 #include <linux/regulator/consumer.h>
 
-#include <linux/platform_data/i2c-hid.h>
-
 #include "../hid-ids.h"
 #include "i2c-hid.h"
 
@@ -156,10 +152,10 @@ struct i2c_hid {
 
 	wait_queue_head_t	wait;		/* For waiting the interrupt */
 
-	struct i2c_hid_platform_data pdata;
-
 	bool			irq_wake_enabled;
 	struct mutex		reset_lock;
+
+	struct i2chid_ops	*ops;
 };
 
 static const struct i2c_hid_quirks {
@@ -884,144 +880,36 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid)
 	return 0;
 }
 
-#ifdef CONFIG_ACPI
-static const struct acpi_device_id i2c_hid_acpi_blacklist[] = {
-	/*
-	 * The CHPN0001 ACPI device, which is used to describe the Chipone
-	 * ICN8505 controller, has a _CID of PNP0C50 but is not HID compatible.
-	 */
-	{"CHPN0001", 0 },
-	{ },
-};
-
-static int i2c_hid_acpi_pdata(struct i2c_client *client,
-		struct i2c_hid_platform_data *pdata)
+static int i2c_hid_core_power_up(struct i2c_hid *ihid)
 {
-	static guid_t i2c_hid_guid =
-		GUID_INIT(0x3CDFF6F7, 0x4267, 0x4555,
-			  0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE);
-	union acpi_object *obj;
-	struct acpi_device *adev;
-	acpi_handle handle;
-
-	handle = ACPI_HANDLE(&client->dev);
-	if (!handle || acpi_bus_get_device(handle, &adev)) {
-		dev_err(&client->dev, "Error could not get ACPI device\n");
-		return -ENODEV;
-	}
-
-	if (acpi_match_device_ids(adev, i2c_hid_acpi_blacklist) == 0)
-		return -ENODEV;
-
-	obj = acpi_evaluate_dsm_typed(handle, &i2c_hid_guid, 1, 1, NULL,
-				      ACPI_TYPE_INTEGER);
-	if (!obj) {
-		dev_err(&client->dev, "Error _DSM call to get HID descriptor address failed\n");
-		return -ENODEV;
-	}
-
-	pdata->hid_descriptor_address = obj->integer.value;
-	ACPI_FREE(obj);
-
-	return 0;
-}
-
-static void i2c_hid_acpi_fix_up_power(struct device *dev)
-{
-	struct acpi_device *adev;
-
-	adev = ACPI_COMPANION(dev);
-	if (adev)
-		acpi_device_fix_up_power(adev);
-}
-
-static void i2c_hid_acpi_enable_wakeup(struct device *dev)
-{
-	if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
-		device_set_wakeup_capable(dev, true);
-		device_set_wakeup_enable(dev, false);
-	}
-}
-
-static void i2c_hid_acpi_shutdown(struct device *dev)
-{
-	acpi_device_set_power(ACPI_COMPANION(dev), ACPI_STATE_D3_COLD);
-}
+	if (!ihid->ops->power_up)
+		return 0;
 
-static const struct acpi_device_id i2c_hid_acpi_match[] = {
-	{"ACPI0C50", 0 },
-	{"PNP0C50", 0 },
-	{ },
-};
-MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match);
-#else
-static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
-		struct i2c_hid_platform_data *pdata)
-{
-	return -ENODEV;
+	return ihid->ops->power_up(ihid->ops);
 }
 
-static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {}
-
-static inline void i2c_hid_acpi_enable_wakeup(struct device *dev) {}
-
-static inline void i2c_hid_acpi_shutdown(struct device *dev) {}
-#endif
-
-#ifdef CONFIG_OF
-static int i2c_hid_of_probe(struct i2c_client *client,
-		struct i2c_hid_platform_data *pdata)
+static void i2c_hid_core_power_down(struct i2c_hid *ihid)
 {
-	struct device *dev = &client->dev;
-	u32 val;
-	int ret;
-
-	ret = of_property_read_u32(dev->of_node, "hid-descr-addr", &val);
-	if (ret) {
-		dev_err(&client->dev, "HID register address not provided\n");
-		return -ENODEV;
-	}
-	if (val >> 16) {
-		dev_err(&client->dev, "Bad HID register address: 0x%08x\n",
-			val);
-		return -EINVAL;
-	}
-	pdata->hid_descriptor_address = val;
-
-	return 0;
-}
+	if (!ihid->ops->power_down)
+		return;
 
-static const struct of_device_id i2c_hid_of_match[] = {
-	{ .compatible = "hid-over-i2c" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, i2c_hid_of_match);
-#else
-static inline int i2c_hid_of_probe(struct i2c_client *client,
-		struct i2c_hid_platform_data *pdata)
-{
-	return -ENODEV;
+	ihid->ops->power_down(ihid->ops);
 }
-#endif
 
-static void i2c_hid_fwnode_probe(struct i2c_client *client,
-				 struct i2c_hid_platform_data *pdata)
+static void i2c_hid_core_shutdown_tail(struct i2c_hid *ihid)
 {
-	u32 val;
+	if (!ihid->ops->shutdown_tail)
+		return;
 
-	if (!device_property_read_u32(&client->dev, "post-power-on-delay-ms",
-				      &val))
-		pdata->post_power_delay_ms = val;
+	ihid->ops->shutdown_tail(ihid->ops);
 }
 
-static int i2c_hid_probe(struct i2c_client *client,
-			 const struct i2c_device_id *dev_id)
+int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
+		       u16 hid_descriptor_address)
 {
 	int ret;
 	struct i2c_hid *ihid;
 	struct hid_device *hid;
-	__u16 hidRegister;
-	struct i2c_hid_platform_data *platform_data = client->dev.platform_data;
 
 	dbg_hid("HID probe called for i2c 0x%02x\n", client->addr);
 
@@ -1042,44 +930,17 @@ static int i2c_hid_probe(struct i2c_client *client,
 	if (!ihid)
 		return -ENOMEM;
 
-	if (client->dev.of_node) {
-		ret = i2c_hid_of_probe(client, &ihid->pdata);
-		if (ret)
-			return ret;
-	} else if (!platform_data) {
-		ret = i2c_hid_acpi_pdata(client, &ihid->pdata);
-		if (ret)
-			return ret;
-	} else {
-		ihid->pdata = *platform_data;
-	}
-
-	/* Parse platform agnostic common properties from ACPI / device tree */
-	i2c_hid_fwnode_probe(client, &ihid->pdata);
+	ihid->ops = ops;
 
-	ihid->pdata.supplies[0].supply = "vdd";
-	ihid->pdata.supplies[1].supply = "vddl";
-
-	ret = devm_regulator_bulk_get(&client->dev,
-				      ARRAY_SIZE(ihid->pdata.supplies),
-				      ihid->pdata.supplies);
+	ret = i2c_hid_core_power_up(ihid);
 	if (ret)
 		return ret;
 
-	ret = regulator_bulk_enable(ARRAY_SIZE(ihid->pdata.supplies),
-				    ihid->pdata.supplies);
-	if (ret < 0)
-		return ret;
-
-	if (ihid->pdata.post_power_delay_ms)
-		msleep(ihid->pdata.post_power_delay_ms);
-
 	i2c_set_clientdata(client, ihid);
 
 	ihid->client = client;
 
-	hidRegister = ihid->pdata.hid_descriptor_address;
-	ihid->wHIDDescRegister = cpu_to_le16(hidRegister);
+	ihid->wHIDDescRegister = cpu_to_le16(hid_descriptor_address);
 
 	init_waitqueue_head(&ihid->wait);
 	mutex_init(&ihid->reset_lock);
@@ -1089,11 +950,7 @@ static int i2c_hid_probe(struct i2c_client *client,
 	 * real computation later. */
 	ret = i2c_hid_alloc_buffers(ihid, HID_MIN_BUFFER_SIZE);
 	if (ret < 0)
-		goto err_regulator;
-
-	i2c_hid_acpi_fix_up_power(&client->dev);
-
-	i2c_hid_acpi_enable_wakeup(&client->dev);
+		goto err_powered;
 
 	device_enable_async_suspend(&client->dev);
 
@@ -1102,16 +959,16 @@ static int i2c_hid_probe(struct i2c_client *client,
 	if (ret < 0) {
 		dev_dbg(&client->dev, "nothing at this address: %d\n", ret);
 		ret = -ENXIO;
-		goto err_regulator;
+		goto err_powered;
 	}
 
 	ret = i2c_hid_fetch_hid_descriptor(ihid);
 	if (ret < 0)
-		goto err_regulator;
+		goto err_powered;
 
 	ret = i2c_hid_init_irq(client);
 	if (ret < 0)
-		goto err_regulator;
+		goto err_powered;
 
 	hid = hid_allocate_device();
 	if (IS_ERR(hid)) {
@@ -1150,14 +1007,14 @@ static int i2c_hid_probe(struct i2c_client *client,
 err_irq:
 	free_irq(client->irq, ihid);
 
-err_regulator:
-	regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies),
-			       ihid->pdata.supplies);
+err_powered:
+	i2c_hid_core_power_down(ihid);
 	i2c_hid_free_buffers(ihid);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(i2c_hid_core_probe);
 
-static int i2c_hid_remove(struct i2c_client *client)
+int i2c_hid_core_remove(struct i2c_client *client)
 {
 	struct i2c_hid *ihid = i2c_get_clientdata(client);
 	struct hid_device *hid;
@@ -1170,24 +1027,25 @@ static int i2c_hid_remove(struct i2c_client *client)
 	if (ihid->bufsize)
 		i2c_hid_free_buffers(ihid);
 
-	regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies),
-			       ihid->pdata.supplies);
+	i2c_hid_core_power_down(ihid);
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(i2c_hid_core_remove);
 
-static void i2c_hid_shutdown(struct i2c_client *client)
+void i2c_hid_core_shutdown(struct i2c_client *client)
 {
 	struct i2c_hid *ihid = i2c_get_clientdata(client);
 
 	i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
 	free_irq(client->irq, ihid);
 
-	i2c_hid_acpi_shutdown(&client->dev);
+	i2c_hid_core_shutdown_tail(ihid);
 }
+EXPORT_SYMBOL_GPL(i2c_hid_core_shutdown);
 
 #ifdef CONFIG_PM_SLEEP
-static int i2c_hid_suspend(struct device *dev)
+int i2c_hid_core_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct i2c_hid *ihid = i2c_get_clientdata(client);
@@ -1214,14 +1072,14 @@ static int i2c_hid_suspend(struct device *dev)
 			hid_warn(hid, "Failed to enable irq wake: %d\n",
 				wake_status);
 	} else {
-		regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies),
-				       ihid->pdata.supplies);
+		i2c_hid_core_power_down(ihid);
 	}
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(i2c_hid_core_suspend);
 
-static int i2c_hid_resume(struct device *dev)
+int i2c_hid_core_resume(struct device *dev)
 {
 	int ret;
 	struct i2c_client *client = to_i2c_client(dev);
@@ -1230,13 +1088,7 @@ static int i2c_hid_resume(struct device *dev)
 	int wake_status;
 
 	if (!device_may_wakeup(&client->dev)) {
-		ret = regulator_bulk_enable(ARRAY_SIZE(ihid->pdata.supplies),
-					    ihid->pdata.supplies);
-		if (ret)
-			hid_warn(hid, "Failed to enable supplies: %d\n", ret);
-
-		if (ihid->pdata.post_power_delay_ms)
-			msleep(ihid->pdata.post_power_delay_ms);
+		i2c_hid_core_power_up(ihid);
 	} else if (ihid->irq_wake_enabled) {
 		wake_status = disable_irq_wake(client->irq);
 		if (!wake_status)
@@ -1271,37 +1123,9 @@ static int i2c_hid_resume(struct device *dev)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(i2c_hid_core_resume);
 #endif
 
-static const struct dev_pm_ops i2c_hid_pm = {
-	SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_suspend, i2c_hid_resume)
-};
-
-static const struct i2c_device_id i2c_hid_id_table[] = {
-	{ "hid", 0 },
-	{ "hid-over-i2c", 0 },
-	{ },
-};
-MODULE_DEVICE_TABLE(i2c, i2c_hid_id_table);
-
-
-static struct i2c_driver i2c_hid_driver = {
-	.driver = {
-		.name	= "i2c_hid",
-		.pm	= &i2c_hid_pm,
-		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
-		.acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
-		.of_match_table = of_match_ptr(i2c_hid_of_match),
-	},
-
-	.probe		= i2c_hid_probe,
-	.remove		= i2c_hid_remove,
-	.shutdown	= i2c_hid_shutdown,
-	.id_table	= i2c_hid_id_table,
-};
-
-module_i2c_driver(i2c_hid_driver);
-
 MODULE_DESCRIPTION("HID over I2C core driver");
 MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
 MODULE_LICENSE("GPL");
diff --git a/drivers/hid/i2c-hid/i2c-hid-of.c b/drivers/hid/i2c-hid/i2c-hid-of.c
new file mode 100644
index 000000000000..15d533be2b24
--- /dev/null
+++ b/drivers/hid/i2c-hid/i2c-hid-of.c
@@ -0,0 +1,147 @@
+/*
+ * HID over I2C Open Firmware Subclass
+ *
+ * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
+ * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France
+ * Copyright (c) 2012 Red Hat, Inc
+ *
+ * This code was forked out of the core code, which was partly based on
+ * "USB HID support for Linux":
+ *
+ *  Copyright (c) 1999 Andreas Gal
+ *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
+ *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
+ *  Copyright (c) 2007-2008 Oliver Neukum
+ *  Copyright (c) 2006-2010 Jiri Kosina
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/regulator/consumer.h>
+
+#include "i2c-hid.h"
+
+struct i2c_hid_of {
+	struct i2chid_ops ops;
+
+	struct i2c_client *client;
+	struct regulator_bulk_data supplies[2];
+	int post_power_delay_ms;
+};
+
+static int i2c_hid_of_power_up(struct i2chid_ops *ops)
+{
+	struct i2c_hid_of *ihid_of = container_of(ops, struct i2c_hid_of, ops);
+	struct device *dev = &ihid_of->client->dev;
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ihid_of->supplies),
+				    ihid_of->supplies);
+	if (ret) {
+		dev_warn(dev, "Failed to enable supplies: %d\n", ret);
+		return ret;
+	}
+
+	if (ihid_of->post_power_delay_ms)
+		msleep(ihid_of->post_power_delay_ms);
+
+	return 0;
+}
+
+static void i2c_hid_of_power_down(struct i2chid_ops *ops)
+{
+	struct i2c_hid_of *ihid_of = container_of(ops, struct i2c_hid_of, ops);
+
+	regulator_bulk_disable(ARRAY_SIZE(ihid_of->supplies),
+			       ihid_of->supplies);
+}
+
+static int i2c_hid_of_probe(struct i2c_client *client,
+			    const struct i2c_device_id *dev_id)
+{
+	struct device *dev = &client->dev;
+	struct i2c_hid_of *ihid_of;
+	u16 hid_descriptor_address;
+	int ret;
+	u32 val;
+
+	ihid_of = devm_kzalloc(&client->dev, sizeof(*ihid_of), GFP_KERNEL);
+	if (!ihid_of)
+		return -ENOMEM;
+
+	ihid_of->ops.power_up = i2c_hid_of_power_up;
+	ihid_of->ops.power_down = i2c_hid_of_power_down;
+
+	ret = of_property_read_u32(dev->of_node, "hid-descr-addr", &val);
+	if (ret) {
+		dev_err(&client->dev, "HID register address not provided\n");
+		return -ENODEV;
+	}
+	if (val >> 16) {
+		dev_err(&client->dev, "Bad HID register address: 0x%08x\n",
+			val);
+		return -EINVAL;
+	}
+	hid_descriptor_address = val;
+
+	if (!device_property_read_u32(&client->dev, "post-power-on-delay-ms",
+				      &val))
+		ihid_of->post_power_delay_ms = val;
+
+	ihid_of->supplies[0].supply = "vdd";
+	ihid_of->supplies[1].supply = "vddl";
+	ret = devm_regulator_bulk_get(&client->dev,
+				      ARRAY_SIZE(ihid_of->supplies),
+				      ihid_of->supplies);
+	if (ret)
+		return ret;
+
+	return i2c_hid_core_probe(client, &ihid_of->ops,
+				  hid_descriptor_address);
+}
+
+static const struct dev_pm_ops i2c_hid_of_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_core_suspend, i2c_hid_core_resume)
+};
+
+static const struct of_device_id i2c_hid_of_match[] = {
+	{ .compatible = "hid-over-i2c" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, i2c_hid_of_match);
+
+static const struct i2c_device_id i2c_hid_of_id_table[] = {
+	{ "hid", 0 },
+	{ "hid-over-i2c", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, i2c_hid_of_id_table);
+
+static struct i2c_driver i2c_hid_of_driver = {
+	.driver = {
+		.name	= "i2c_hid_of",
+		.pm	= &i2c_hid_of_pm,
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+		.of_match_table = of_match_ptr(i2c_hid_of_match),
+	},
+
+	.probe		= i2c_hid_of_probe,
+	.remove		= i2c_hid_core_remove,
+	.shutdown	= i2c_hid_core_shutdown,
+	.id_table	= i2c_hid_of_id_table,
+};
+
+module_i2c_driver(i2c_hid_of_driver);
+
+MODULE_DESCRIPTION("HID over I2C OF driver");
+MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/i2c-hid/i2c-hid.h b/drivers/hid/i2c-hid/i2c-hid.h
index a8c19aef5824..13e666ec366c 100644
--- a/drivers/hid/i2c-hid/i2c-hid.h
+++ b/drivers/hid/i2c-hid/i2c-hid.h
@@ -3,6 +3,7 @@
 #ifndef I2C_HID_H
 #define I2C_HID_H
 
+#include <linux/i2c.h>
 
 #ifdef CONFIG_DMI
 struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name);
@@ -17,4 +18,28 @@ static inline char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
 { return NULL; }
 #endif
 
+/**
+ * struct i2chid_ops - Ops provided to the core.
+ *
+ * @power_up: do sequencing to power up the device.
+ * @power_down: do sequencing to power down the device.
+ * @shutdown_tail: called at the end of shutdown.
+ */
+struct i2chid_ops {
+	int (*power_up)(struct i2chid_ops *ops);
+	void (*power_down)(struct i2chid_ops *ops);
+	void (*shutdown_tail)(struct i2chid_ops *ops);
+};
+
+int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
+		       u16 hid_descriptor_address);
+int i2c_hid_core_remove(struct i2c_client *client);
+
+void i2c_hid_core_shutdown(struct i2c_client *client);
+
+#ifdef CONFIG_PM_SLEEP
+int i2c_hid_core_suspend(struct device *dev);
+int i2c_hid_core_resume(struct device *dev);
+#endif
+
 #endif
diff --git a/include/linux/platform_data/i2c-hid.h b/include/linux/platform_data/i2c-hid.h
deleted file mode 100644
index c628bb5e1061..000000000000
--- a/include/linux/platform_data/i2c-hid.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * HID over I2C protocol implementation
- *
- * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
- * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#ifndef __LINUX_I2C_HID_H
-#define __LINUX_I2C_HID_H
-
-#include <linux/regulator/consumer.h>
-#include <linux/types.h>
-
-/**
- * struct i2chid_platform_data - used by hid over i2c implementation.
- * @hid_descriptor_address: i2c register where the HID descriptor is stored.
- * @supplies: regulators for powering on the device.
- * @post_power_delay_ms: delay after powering on before device is usable.
- *
- * Note that it is the responsibility of the platform driver (or the acpi 5.0
- * driver, or the flattened device tree) to setup the irq related to the gpio in
- * the struct i2c_board_info.
- * The platform driver should also setup the gpio according to the device:
- *
- * A typical example is the following:
- *	irq = gpio_to_irq(intr_gpio);
- *	hkdk4412_i2c_devs5[0].irq = irq; // store the irq in i2c_board_info
- *	gpio_request(intr_gpio, "elan-irq");
- *	s3c_gpio_setpull(intr_gpio, S3C_GPIO_PULL_UP);
- */
-struct i2c_hid_platform_data {
-	u16 hid_descriptor_address;
-	struct regulator_bulk_data supplies[2];
-	int post_power_delay_ms;
-};
-
-#endif /* __LINUX_I2C_HID_H */
-- 
2.29.2.222.g5d2a92d10f8-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v5 2/4] arm64: defconfig: Update config names for i2c-hid rejigger
  2020-11-09 21:36 [PATCH v5 0/4] HID: i2c-hid: Reorganize to allow supporting goodix,gt7375p Douglas Anderson
  2020-11-09 21:36 ` [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules Douglas Anderson
@ 2020-11-09 21:36 ` Douglas Anderson
  2020-11-09 21:36 ` [PATCH v5 3/4] dt-bindings: input: HID: i2c-hid: Introduce bindings for the Goodix GT7375P Douglas Anderson
  2020-11-09 21:36 ` [PATCH v5 4/4] HID: i2c-hid: Introduce goodix-i2c-hid using i2c-hid core Douglas Anderson
  3 siblings, 0 replies; 11+ messages in thread
From: Douglas Anderson @ 2020-11-09 21:36 UTC (permalink / raw)
  To: jkosina, benjamin.tissoires, gregkh, Dmitry Torokhov
  Cc: kai.heng.feng, hdegoede, robh+dt, linux-input, swboyd, andrea,
	Douglas Anderson, Anson Huang, Bjorn Andersson, Catalin Marinas,
	Geert Uytterhoeven, Krzysztof Kozlowski, Li Yang, Michael Walle,
	Olof Johansson, Shawn Guo, Vinod Koul, Will Deacon,
	linux-arm-kernel, linux-kernel

The i2c-hid driver has been split in two.  Let's enable both halves.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

(no changes since v4)

Changes in v4:
- ("arm64: defconfig: Update config names for i2c-hid rejigger") new for v4.

 arch/arm64/configs/defconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 5cfe3cf6f2ac..9258d623331e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -725,7 +725,8 @@ CONFIG_SND_SOC_WM8904=m
 CONFIG_SND_SOC_WSA881X=m
 CONFIG_SND_SIMPLE_CARD=m
 CONFIG_SND_AUDIO_GRAPH_CARD=m
-CONFIG_I2C_HID=m
+CONFIG_I2C_HID_ACPI=m
+CONFIG_I2C_HID_OF=m
 CONFIG_USB_CONN_GPIO=m
 CONFIG_USB=y
 CONFIG_USB_OTG=y
-- 
2.29.2.222.g5d2a92d10f8-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v5 3/4] dt-bindings: input: HID: i2c-hid: Introduce bindings for the Goodix GT7375P
  2020-11-09 21:36 [PATCH v5 0/4] HID: i2c-hid: Reorganize to allow supporting goodix,gt7375p Douglas Anderson
  2020-11-09 21:36 ` [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules Douglas Anderson
  2020-11-09 21:36 ` [PATCH v5 2/4] arm64: defconfig: Update config names for i2c-hid rejigger Douglas Anderson
@ 2020-11-09 21:36 ` Douglas Anderson
  2020-11-09 21:36 ` [PATCH v5 4/4] HID: i2c-hid: Introduce goodix-i2c-hid using i2c-hid core Douglas Anderson
  3 siblings, 0 replies; 11+ messages in thread
From: Douglas Anderson @ 2020-11-09 21:36 UTC (permalink / raw)
  To: jkosina, benjamin.tissoires, gregkh, Dmitry Torokhov
  Cc: kai.heng.feng, hdegoede, robh+dt, linux-input, swboyd, andrea,
	Douglas Anderson, Rob Herring, devicetree, linux-kernel

This adds new bindings for the Goodix GT7375P touchscreen.  While this
touchscreen's communications are based on the generic "i2c-over-hid"
protocol, it needs special power sequencing and thus gets its own
compatible and bindings.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---

Changes in v5:
- Added mention of i2c-hid in the yaml itself as per Rob.
- Adjusted subject as per Rob.

Changes in v3:
- Fixed compatible in example.
- Removed Benjamin as a maintainer.
- Updated description.

Changes in v2:
- ("dt-bindings: HID: i2c-hid: Introduce bindings for the Goodix GT7375P") new in v2.

 .../bindings/input/goodix,gt7375p.yaml        | 65 +++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/goodix,gt7375p.yaml

diff --git a/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml b/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml
new file mode 100644
index 000000000000..fe1c5016f7f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/goodix,gt7375p.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Goodix GT7375P touchscreen
+
+maintainers:
+  - Douglas Anderson <dianders@chromium.org>
+
+description:
+  Supports the Goodix GT7375P touchscreen.
+  This touchscreen uses the i2c-hid protocol but has some non-standard
+  power sequencing required.
+
+properties:
+  compatible:
+    items:
+      - const: goodix,gt7375p
+
+  reg:
+    enum:
+      - 0x5d
+      - 0x14
+
+  interrupts:
+    maxItems: 1
+
+  reset-gpios:
+    true
+
+  vdd-supply:
+    description: The 3.3V supply to the touchscreen.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - reset-gpios
+  - vdd-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      ap_ts: touchscreen@5d {
+        compatible = "goodix,gt7375p";
+        reg = <0x5d>;
+
+        interrupt-parent = <&tlmm>;
+        interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+
+        reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
+        vdd-supply = <&pp3300_ts>;
+      };
+    };
-- 
2.29.2.222.g5d2a92d10f8-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v5 4/4] HID: i2c-hid: Introduce goodix-i2c-hid using i2c-hid core
  2020-11-09 21:36 [PATCH v5 0/4] HID: i2c-hid: Reorganize to allow supporting goodix,gt7375p Douglas Anderson
                   ` (2 preceding siblings ...)
  2020-11-09 21:36 ` [PATCH v5 3/4] dt-bindings: input: HID: i2c-hid: Introduce bindings for the Goodix GT7375P Douglas Anderson
@ 2020-11-09 21:36 ` Douglas Anderson
  3 siblings, 0 replies; 11+ messages in thread
From: Douglas Anderson @ 2020-11-09 21:36 UTC (permalink / raw)
  To: jkosina, benjamin.tissoires, gregkh, Dmitry Torokhov
  Cc: kai.heng.feng, hdegoede, robh+dt, linux-input, swboyd, andrea,
	Douglas Anderson, Jiri Kosina, Masahiro Yamada, linux-kernel

Goodix i2c-hid touchscreens are mostly i2c-hid compliant but have some
special power sequencing requirements, including the need to drive a
reset line during the sequencing.

Let's use the new rejiggering of i2c-hid to support this with a thin
wrapper driver to support the first Goodix i2c-hid touchscreen:
GT7375P

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

Changes in v5:
- i2chid_subclass_data => i2chid_ops.
- power_up_device => power_up (same with power_down).
- subclass => ops.

Changes in v4:
- Totally redid based on the new subclass system.

Changes in v3:
- Rework to use subclassing.

 drivers/hid/i2c-hid/Kconfig             |  19 +++-
 drivers/hid/i2c-hid/Makefile            |   1 +
 drivers/hid/i2c-hid/i2c-hid-of-goodix.c | 120 ++++++++++++++++++++++++
 3 files changed, 138 insertions(+), 2 deletions(-)
 create mode 100644 drivers/hid/i2c-hid/i2c-hid-of-goodix.c

diff --git a/drivers/hid/i2c-hid/Kconfig b/drivers/hid/i2c-hid/Kconfig
index 819b7521c182..a16c6a69680b 100644
--- a/drivers/hid/i2c-hid/Kconfig
+++ b/drivers/hid/i2c-hid/Kconfig
@@ -32,10 +32,25 @@ config I2C_HID_OF
 	  will be called i2c-hid-of.  It will also build/depend on the
 	  module i2c-hid.
 
+config I2C_HID_OF_GOODIX
+	tristate "Driver for Goodix hid-i2c based devices on OF systems"
+	default n
+	depends on I2C && INPUT && OF
+	help
+	  Say Y here if you want support for Goodix i2c devices that use
+	  the i2c-hid protocol on Open Firmware (Device Tree)-based
+	  systems.
+
+	  If unsure, say N.
+
+	  This support is also available as a module.  If so, the module
+	  will be called i2c-hid-of-goodix.  It will also build/depend on
+	  the module i2c-hid.
+
 endmenu
 
 config I2C_HID_CORE
 	tristate
-	default y if I2C_HID_ACPI=y || I2C_HID_OF=y
-	default m if I2C_HID_ACPI=m || I2C_HID_OF=m
+	default y if I2C_HID_ACPI=y || I2C_HID_OF=y || I2C_HID_OF_GOODIX=y
+	default m if I2C_HID_ACPI=m || I2C_HID_OF=m || I2C_HID_OF_GOODIX=m
 	select HID
diff --git a/drivers/hid/i2c-hid/Makefile b/drivers/hid/i2c-hid/Makefile
index 9b4a73446841..302545a771f3 100644
--- a/drivers/hid/i2c-hid/Makefile
+++ b/drivers/hid/i2c-hid/Makefile
@@ -10,3 +10,4 @@ i2c-hid-$(CONFIG_DMI)				+= i2c-hid-dmi-quirks.o
 
 obj-$(CONFIG_I2C_HID_ACPI)			+= i2c-hid-acpi.o
 obj-$(CONFIG_I2C_HID_OF)			+= i2c-hid-of.o
+obj-$(CONFIG_I2C_HID_OF_GOODIX)			+= i2c-hid-of-goodix.o
diff --git a/drivers/hid/i2c-hid/i2c-hid-of-goodix.c b/drivers/hid/i2c-hid/i2c-hid-of-goodix.c
new file mode 100644
index 000000000000..eada0363ef62
--- /dev/null
+++ b/drivers/hid/i2c-hid/i2c-hid-of-goodix.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Goodix touchscreens that use the i2c-hid protocol.
+ *
+ * Copyright 2020 Google LLC
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/regulator/consumer.h>
+
+#include "i2c-hid.h"
+
+struct goodix_i2c_hid_timing_data {
+	unsigned int post_gpio_reset_delay_ms;
+	unsigned int post_power_delay_ms;
+};
+
+struct i2c_hid_of_goodix {
+	struct i2chid_ops ops;
+
+	struct regulator *vdd;
+	struct gpio_desc *reset_gpio;
+	const struct goodix_i2c_hid_timing_data *timings;
+};
+
+static int goodix_i2c_hid_power_up(struct i2chid_ops *ops)
+{
+	struct i2c_hid_of_goodix *ihid_goodix =
+		container_of(ops, struct i2c_hid_of_goodix, ops);
+	int ret;
+
+	ret = regulator_enable(ihid_goodix->vdd);
+	if (ret)
+		return ret;
+
+	if (ihid_goodix->timings->post_power_delay_ms)
+		msleep(ihid_goodix->timings->post_power_delay_ms);
+
+	gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 0);
+	if (ihid_goodix->timings->post_gpio_reset_delay_ms)
+		msleep(ihid_goodix->timings->post_gpio_reset_delay_ms);
+
+	return 0;
+}
+
+static void goodix_i2c_hid_power_down(struct i2chid_ops *ops)
+{
+	struct i2c_hid_of_goodix *ihid_goodix =
+		container_of(ops, struct i2c_hid_of_goodix, ops);
+
+	gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1);
+	regulator_disable(ihid_goodix->vdd);
+}
+
+static int i2c_hid_of_goodix_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
+{
+	struct i2c_hid_of_goodix *ihid_goodix;
+
+	ihid_goodix = devm_kzalloc(&client->dev, sizeof(*ihid_goodix),
+				   GFP_KERNEL);
+	if (!ihid_goodix)
+		return -ENOMEM;
+
+	ihid_goodix->ops.power_up = goodix_i2c_hid_power_up;
+	ihid_goodix->ops.power_down = goodix_i2c_hid_power_down;
+
+	/* Start out with reset asserted */
+	ihid_goodix->reset_gpio =
+		devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(ihid_goodix->reset_gpio))
+		return PTR_ERR(ihid_goodix->reset_gpio);
+
+	ihid_goodix->vdd = devm_regulator_get(&client->dev, "vdd");
+	if (IS_ERR(ihid_goodix->vdd))
+		return PTR_ERR(ihid_goodix->vdd);
+
+	ihid_goodix->timings = device_get_match_data(&client->dev);
+
+	return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001);
+}
+
+static const struct goodix_i2c_hid_timing_data goodix_gt7375p_timing_data = {
+	.post_power_delay_ms = 10,
+	.post_gpio_reset_delay_ms = 120,
+};
+
+static const struct of_device_id goodix_i2c_hid_of_match[] = {
+	{ .compatible = "goodix,gt7375p", .data = &goodix_gt7375p_timing_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, goodix_i2c_hid_of_match);
+
+static const struct dev_pm_ops goodix_i2c_hid_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_core_suspend, i2c_hid_core_resume)
+};
+
+static struct i2c_driver goodix_i2c_hid_ts_driver = {
+	.driver = {
+		.name	= "i2c_hid_of_goodix",
+		.pm	= &goodix_i2c_hid_pm,
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+		.of_match_table = of_match_ptr(goodix_i2c_hid_of_match),
+	},
+	.probe		= i2c_hid_of_goodix_probe,
+	.remove		= i2c_hid_core_remove,
+	.shutdown	= i2c_hid_core_shutdown,
+};
+module_i2c_driver(goodix_i2c_hid_ts_driver);
+
+MODULE_AUTHOR("Douglas Anderson <dianders@chromium.org>");
+MODULE_DESCRIPTION("Goodix i2c-hid touchscreen driver");
+MODULE_LICENSE("GPL v2");
-- 
2.29.2.222.g5d2a92d10f8-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules
  2020-11-09 21:36 ` [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules Douglas Anderson
@ 2020-11-09 23:23   ` Doug Anderson
  2020-11-10  9:01   ` Hans de Goede
  1 sibling, 0 replies; 11+ messages in thread
From: Doug Anderson @ 2020-11-09 23:23 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Greg Kroah-Hartman, Dmitry Torokhov
  Cc: Kai-Heng Feng, Hans de Goede, Rob Herring,
	open list:HID CORE LAYER, Stephen Boyd, Andrea Borgia,
	Jiri Kosina, Masahiro Yamada, Pavel Balan, Xiaofei Tan,
	You-Sheng Yang, LKML

Hi,

On Mon, Nov 9, 2020 at 1:37 PM Douglas Anderson <dianders@chromium.org> wrote:
>
> +int i2c_hid_acpi_probe(struct i2c_client *client,
> +                      const struct i2c_device_id *dev_id)
> +{
> +       struct device *dev = &client->dev;
> +       struct i2c_hid_acpi *ihid_acpi;
> +       u16 hid_descriptor_address;
> +       int ret;
> +
> +       ihid_acpi = devm_kzalloc(&client->dev, sizeof(*ihid_acpi), GFP_KERNEL);
> +       if (!ihid_acpi)
> +               return -ENOMEM;
> +

Turns out one way to find some folks to help me test this code is to
break them.  Maybe not a good way, but a way.  :(

There should have been a:

ihid_acpi->client = client;

...here.  If you're willing to look at Chrome OS gerrit pages, you can
find the fix at <https://crrev.com/c/2527946>.

If everything about this patch looks good, I'm OK w/ a maintainer
fixing this when applying.  I'm also happy to send out a v6, but I'll
wait a little bit in case there are other comments.


-Doug

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules
  2020-11-09 21:36 ` [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules Douglas Anderson
  2020-11-09 23:23   ` Doug Anderson
@ 2020-11-10  9:01   ` Hans de Goede
  2020-11-10 22:17     ` Doug Anderson
  1 sibling, 1 reply; 11+ messages in thread
From: Hans de Goede @ 2020-11-10  9:01 UTC (permalink / raw)
  To: Douglas Anderson, jkosina, benjamin.tissoires, gregkh, Dmitry Torokhov
  Cc: kai.heng.feng, robh+dt, linux-input, swboyd, andrea, Jiri Kosina,
	Masahiro Yamada, Pavel Balan, Xiaofei Tan, You-Sheng Yang,
	linux-kernel

Hi,

On 11/9/20 10:36 PM, Douglas Anderson wrote:
> This patch rejiggers the i2c-hid code so that the OF (Open Firmware
> aka Device Tree) and ACPI support is separated out a bit.  The OF and
> ACPI drivers are now separate modules that wrap the core module.
> 
> Essentially, what we're doing here:
> * Make "power up" and "power down" a function that can be (optionally)
>   implemented by a given user of the i2c-hid core.
> * The OF and ACPI modules are drivers on their own, so they implement
>   probe / remove / suspend / resume / shutdown.  The core code
>   provides implementations that OF and ACPI can call into.
> 
> We'll organize this so that we now have 3 modules: the old i2c-hid
> module becomes the "core" module and two new modules will depend on
> it, handling probing the specific device.
> 
> As part of this work, we'll remove the i2c-hid "platform data"
> concept since it's not needed.
> 
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> 
> Changes in v5:
> - Add shutdown_tail op and use it in ACPI.
> - i2chid_subclass_data => i2chid_ops.
> - power_up_device => power_up (same with power_down).
> - subclass => ops.
> 

Thanks this looks good to now, 2 small remarks below (since you are
going to do a v6 anyways). Feel free to ignore these remarks if
you prefer to keep things as is.

And feel free to add my reviewed-by to v6 of this patch:

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

<snip>

> diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c
> new file mode 100644
> index 000000000000..5f09635d00ce
> --- /dev/null
> +++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c
> @@ -0,0 +1,170 @@

<snip>

> +static const struct i2c_device_id i2c_hid_acpi_id_table[] = {
> +	{ "hid", 0 },
> +	{ "hid-over-i2c", 0 },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(i2c, i2c_hid_acpi_id_table);

Hmm, I do not think these old-style i2c-ids are necessarry at
all in this driver. I expect all use-cases to use either
of or acpi matches.

This was already present in the code before though, so
please ignore this remark. This is just something which
I noticed and thought was worth while pointing out as
a future cleanup.

<snip>

> diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
> index aeff1ffb0c8b..9551ba96dc49 100644
> --- a/drivers/hid/i2c-hid/i2c-hid-core.c
> +++ b/drivers/hid/i2c-hid/i2c-hid-core.c
> @@ -35,12 +35,8 @@
>  #include <linux/kernel.h>
>  #include <linux/hid.h>
>  #include <linux/mutex.h>
> -#include <linux/acpi.h>
> -#include <linux/of.h>
>  #include <linux/regulator/consumer.h>

I think you can drop this regulator include here now too ?


> diff --git a/drivers/hid/i2c-hid/i2c-hid-of.c b/drivers/hid/i2c-hid/i2c-hid-of.c
> new file mode 100644
> index 000000000000..15d533be2b24
> --- /dev/null
> +++ b/drivers/hid/i2c-hid/i2c-hid-of.c
<snip>

> +static const struct dev_pm_ops i2c_hid_of_pm = {
> +	SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_core_suspend, i2c_hid_core_resume)
> +};

This dev_pm_ops struct is identical to the one in i2c-hid-acpi.c
and the one which you introduce later in i2c-hid-of-goodix.c
is also identical, so that is 3 copies.

Maybe just put a shared dev_pm_ops struct in the i2c-core
(and don't export the suspend/resume handlers) ?

Regards,

Hans


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules
  2020-11-10  9:01   ` Hans de Goede
@ 2020-11-10 22:17     ` Doug Anderson
  2020-11-11  0:04       ` Dmitry Torokhov
  2020-11-11 11:13       ` Hans de Goede
  0 siblings, 2 replies; 11+ messages in thread
From: Doug Anderson @ 2020-11-10 22:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jiri Kosina, Benjamin Tissoires, Greg Kroah-Hartman,
	Dmitry Torokhov, Kai-Heng Feng, Rob Herring,
	open list:HID CORE LAYER, Stephen Boyd, Andrea Borgia,
	Jiri Kosina, Masahiro Yamada, Pavel Balan, Xiaofei Tan,
	You-Sheng Yang, LKML

Hi,

On Tue, Nov 10, 2020 at 1:01 AM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi,
>
> On 11/9/20 10:36 PM, Douglas Anderson wrote:
> > This patch rejiggers the i2c-hid code so that the OF (Open Firmware
> > aka Device Tree) and ACPI support is separated out a bit.  The OF and
> > ACPI drivers are now separate modules that wrap the core module.
> >
> > Essentially, what we're doing here:
> > * Make "power up" and "power down" a function that can be (optionally)
> >   implemented by a given user of the i2c-hid core.
> > * The OF and ACPI modules are drivers on their own, so they implement
> >   probe / remove / suspend / resume / shutdown.  The core code
> >   provides implementations that OF and ACPI can call into.
> >
> > We'll organize this so that we now have 3 modules: the old i2c-hid
> > module becomes the "core" module and two new modules will depend on
> > it, handling probing the specific device.
> >
> > As part of this work, we'll remove the i2c-hid "platform data"
> > concept since it's not needed.
> >
> > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > ---
> >
> > Changes in v5:
> > - Add shutdown_tail op and use it in ACPI.
> > - i2chid_subclass_data => i2chid_ops.
> > - power_up_device => power_up (same with power_down).
> > - subclass => ops.
> >
>
> Thanks this looks good to now, 2 small remarks below (since you are
> going to do a v6 anyways). Feel free to ignore these remarks if
> you prefer to keep things as is.
>
> And feel free to add my reviewed-by to v6 of this patch:
>
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Thanks!


> > +static const struct i2c_device_id i2c_hid_acpi_id_table[] = {
> > +     { "hid", 0 },
> > +     { "hid-over-i2c", 0 },
> > +     { },
> > +};
> > +MODULE_DEVICE_TABLE(i2c, i2c_hid_acpi_id_table);
>
> Hmm, I do not think these old-style i2c-ids are necessarry at
> all in this driver. I expect all use-cases to use either
> of or acpi matches.
>
> This was already present in the code before though, so
> please ignore this remark. This is just something which
> I noticed and thought was worth while pointing out as
> a future cleanup.

Yeah, I wasn't sure if there was anyone using them.

Hrm.  Thinking about it, though, is it really OK for two drivers to
both have the same table listed?  I'm not sure how that would work.
Do you know?

I don't know a ton about ACPI, but for device tree I know i2c has a
fallback mode.  Specifically having this table means that we'll match
compatible strings such as:

  "zipzapzing,hid"
  "kapowzers,hid-over-i2c"

In other words it'll ignore the vendor part and just match on the
second half.  Just to make sure I wasn't remembering that from a dream
I tried it and it worked.  I don't see any mainline device trees that
look like that, though.  I could delete it, though it doesn't really
take up much space and it seems nice to keep it working in case anyone
was relying on it?

For ACPI is there a similar fallback?  If not then it seems like it'd
be easy to remove it from there...


> <snip>
>
> > diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
> > index aeff1ffb0c8b..9551ba96dc49 100644
> > --- a/drivers/hid/i2c-hid/i2c-hid-core.c
> > +++ b/drivers/hid/i2c-hid/i2c-hid-core.c
> > @@ -35,12 +35,8 @@
> >  #include <linux/kernel.h>
> >  #include <linux/hid.h>
> >  #include <linux/mutex.h>
> > -#include <linux/acpi.h>
> > -#include <linux/of.h>
> >  #include <linux/regulator/consumer.h>
>
> I think you can drop this regulator include here now too ?

Good point.


> > diff --git a/drivers/hid/i2c-hid/i2c-hid-of.c b/drivers/hid/i2c-hid/i2c-hid-of.c
> > new file mode 100644
> > index 000000000000..15d533be2b24
> > --- /dev/null
> > +++ b/drivers/hid/i2c-hid/i2c-hid-of.c
> <snip>
>
> > +static const struct dev_pm_ops i2c_hid_of_pm = {
> > +     SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_core_suspend, i2c_hid_core_resume)
> > +};
>
> This dev_pm_ops struct is identical to the one in i2c-hid-acpi.c
> and the one which you introduce later in i2c-hid-of-goodix.c
> is also identical, so that is 3 copies.
>
> Maybe just put a shared dev_pm_ops struct in the i2c-core
> (and don't export the suspend/resume handlers) ?

Sounds good.

-Doug

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules
  2020-11-10 22:17     ` Doug Anderson
@ 2020-11-11  0:04       ` Dmitry Torokhov
  2020-11-11 11:10         ` Hans de Goede
  2020-11-11 11:13       ` Hans de Goede
  1 sibling, 1 reply; 11+ messages in thread
From: Dmitry Torokhov @ 2020-11-11  0:04 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Hans de Goede, Jiri Kosina, Benjamin Tissoires,
	Greg Kroah-Hartman, Kai-Heng Feng, Rob Herring,
	open list:HID CORE LAYER, Stephen Boyd, Andrea Borgia,
	Jiri Kosina, Masahiro Yamada, Pavel Balan, Xiaofei Tan,
	You-Sheng Yang, LKML

On Tue, Nov 10, 2020 at 02:17:27PM -0800, Doug Anderson wrote:
> Hi,
> 
> On Tue, Nov 10, 2020 at 1:01 AM Hans de Goede <hdegoede@redhat.com> wrote:
> >
> > Hi,
> >
> > On 11/9/20 10:36 PM, Douglas Anderson wrote:
> > > This patch rejiggers the i2c-hid code so that the OF (Open Firmware
> > > aka Device Tree) and ACPI support is separated out a bit.  The OF and
> > > ACPI drivers are now separate modules that wrap the core module.
> > >
> > > Essentially, what we're doing here:
> > > * Make "power up" and "power down" a function that can be (optionally)
> > >   implemented by a given user of the i2c-hid core.
> > > * The OF and ACPI modules are drivers on their own, so they implement
> > >   probe / remove / suspend / resume / shutdown.  The core code
> > >   provides implementations that OF and ACPI can call into.
> > >
> > > We'll organize this so that we now have 3 modules: the old i2c-hid
> > > module becomes the "core" module and two new modules will depend on
> > > it, handling probing the specific device.
> > >
> > > As part of this work, we'll remove the i2c-hid "platform data"
> > > concept since it's not needed.
> > >
> > > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > > ---
> > >
> > > Changes in v5:
> > > - Add shutdown_tail op and use it in ACPI.
> > > - i2chid_subclass_data => i2chid_ops.
> > > - power_up_device => power_up (same with power_down).
> > > - subclass => ops.
> > >
> >
> > Thanks this looks good to now, 2 small remarks below (since you are
> > going to do a v6 anyways). Feel free to ignore these remarks if
> > you prefer to keep things as is.
> >
> > And feel free to add my reviewed-by to v6 of this patch:
> >
> > Reviewed-by: Hans de Goede <hdegoede@redhat.com>
> 
> Thanks!
> 
> 
> > > +static const struct i2c_device_id i2c_hid_acpi_id_table[] = {
> > > +     { "hid", 0 },
> > > +     { "hid-over-i2c", 0 },
> > > +     { },
> > > +};
> > > +MODULE_DEVICE_TABLE(i2c, i2c_hid_acpi_id_table);
> >
> > Hmm, I do not think these old-style i2c-ids are necessarry at
> > all in this driver. I expect all use-cases to use either
> > of or acpi matches.
> >
> > This was already present in the code before though, so
> > please ignore this remark. This is just something which
> > I noticed and thought was worth while pointing out as
> > a future cleanup.
> 
> Yeah, I wasn't sure if there was anyone using them.
> 
> Hrm.  Thinking about it, though, is it really OK for two drivers to
> both have the same table listed?  I'm not sure how that would work.
> Do you know?
> 
> I don't know a ton about ACPI, but for device tree I know i2c has a
> fallback mode.  Specifically having this table means that we'll match
> compatible strings such as:
> 
>   "zipzapzing,hid"
>   "kapowzers,hid-over-i2c"
> 
> In other words it'll ignore the vendor part and just match on the
> second half.  Just to make sure I wasn't remembering that from a dream
> I tried it and it worked.  I don't see any mainline device trees that
> look like that, though.  I could delete it, though it doesn't really
> take up much space and it seems nice to keep it working in case anyone
> was relying on it?
> 
> For ACPI is there a similar fallback?  If not then it seems like it'd
> be easy to remove it from there...

Just a random thought - will all this still be working with ACPI PRP0001
and DT-style compatible string and properties in _DSD?

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules
  2020-11-11  0:04       ` Dmitry Torokhov
@ 2020-11-11 11:10         ` Hans de Goede
  0 siblings, 0 replies; 11+ messages in thread
From: Hans de Goede @ 2020-11-11 11:10 UTC (permalink / raw)
  To: Dmitry Torokhov, Doug Anderson
  Cc: Jiri Kosina, Benjamin Tissoires, Greg Kroah-Hartman,
	Kai-Heng Feng, Rob Herring, open list:HID CORE LAYER,
	Stephen Boyd, Andrea Borgia, Jiri Kosina, Masahiro Yamada,
	Pavel Balan, Xiaofei Tan, You-Sheng Yang, LKML

Hi,

On 11/11/20 1:04 AM, Dmitry Torokhov wrote:
> On Tue, Nov 10, 2020 at 02:17:27PM -0800, Doug Anderson wrote:
>> Hi,
>>
>> On Tue, Nov 10, 2020 at 1:01 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>>
>>> Hi,
>>>
>>> On 11/9/20 10:36 PM, Douglas Anderson wrote:
>>>> This patch rejiggers the i2c-hid code so that the OF (Open Firmware
>>>> aka Device Tree) and ACPI support is separated out a bit.  The OF and
>>>> ACPI drivers are now separate modules that wrap the core module.
>>>>
>>>> Essentially, what we're doing here:
>>>> * Make "power up" and "power down" a function that can be (optionally)
>>>>   implemented by a given user of the i2c-hid core.
>>>> * The OF and ACPI modules are drivers on their own, so they implement
>>>>   probe / remove / suspend / resume / shutdown.  The core code
>>>>   provides implementations that OF and ACPI can call into.
>>>>
>>>> We'll organize this so that we now have 3 modules: the old i2c-hid
>>>> module becomes the "core" module and two new modules will depend on
>>>> it, handling probing the specific device.
>>>>
>>>> As part of this work, we'll remove the i2c-hid "platform data"
>>>> concept since it's not needed.
>>>>
>>>> Signed-off-by: Douglas Anderson <dianders@chromium.org>
>>>> ---
>>>>
>>>> Changes in v5:
>>>> - Add shutdown_tail op and use it in ACPI.
>>>> - i2chid_subclass_data => i2chid_ops.
>>>> - power_up_device => power_up (same with power_down).
>>>> - subclass => ops.
>>>>
>>>
>>> Thanks this looks good to now, 2 small remarks below (since you are
>>> going to do a v6 anyways). Feel free to ignore these remarks if
>>> you prefer to keep things as is.
>>>
>>> And feel free to add my reviewed-by to v6 of this patch:
>>>
>>> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
>>
>> Thanks!
>>
>>
>>>> +static const struct i2c_device_id i2c_hid_acpi_id_table[] = {
>>>> +     { "hid", 0 },
>>>> +     { "hid-over-i2c", 0 },
>>>> +     { },
>>>> +};
>>>> +MODULE_DEVICE_TABLE(i2c, i2c_hid_acpi_id_table);
>>>
>>> Hmm, I do not think these old-style i2c-ids are necessarry at
>>> all in this driver. I expect all use-cases to use either
>>> of or acpi matches.
>>>
>>> This was already present in the code before though, so
>>> please ignore this remark. This is just something which
>>> I noticed and thought was worth while pointing out as
>>> a future cleanup.
>>
>> Yeah, I wasn't sure if there was anyone using them.
>>
>> Hrm.  Thinking about it, though, is it really OK for two drivers to
>> both have the same table listed?  I'm not sure how that would work.
>> Do you know?
>>
>> I don't know a ton about ACPI, but for device tree I know i2c has a
>> fallback mode.  Specifically having this table means that we'll match
>> compatible strings such as:
>>
>>   "zipzapzing,hid"
>>   "kapowzers,hid-over-i2c"
>>
>> In other words it'll ignore the vendor part and just match on the
>> second half.  Just to make sure I wasn't remembering that from a dream
>> I tried it and it worked.  I don't see any mainline device trees that
>> look like that, though.  I could delete it, though it doesn't really
>> take up much space and it seems nice to keep it working in case anyone
>> was relying on it?
>>
>> For ACPI is there a similar fallback?  If not then it seems like it'd
>> be easy to remove it from there...
> 
> Just a random thought - will all this still be working with ACPI PRP0001
> and DT-style compatible string and properties in _DSD?

That should keep working. Unless someone mixes a DT-style compatible string
with the PNP0C50 ACPI HID specific DSM for getting the hid_descriptor_address
(instead of a DT style property). But that would be a really weird mix to
use and obviously would go against both the PNP0C50 and the PRP0001 specs.

Regards,

Hans




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules
  2020-11-10 22:17     ` Doug Anderson
  2020-11-11  0:04       ` Dmitry Torokhov
@ 2020-11-11 11:13       ` Hans de Goede
  1 sibling, 0 replies; 11+ messages in thread
From: Hans de Goede @ 2020-11-11 11:13 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Jiri Kosina, Benjamin Tissoires, Greg Kroah-Hartman,
	Dmitry Torokhov, Kai-Heng Feng, Rob Herring,
	open list:HID CORE LAYER, Stephen Boyd, Andrea Borgia,
	Jiri Kosina, Masahiro Yamada, Pavel Balan, Xiaofei Tan,
	You-Sheng Yang, LKML

Hi,

On 11/10/20 11:17 PM, Doug Anderson wrote:
> Hi,
> 
> On Tue, Nov 10, 2020 at 1:01 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>
>> Hi,
>>
>> On 11/9/20 10:36 PM, Douglas Anderson wrote:
>>> This patch rejiggers the i2c-hid code so that the OF (Open Firmware
>>> aka Device Tree) and ACPI support is separated out a bit.  The OF and
>>> ACPI drivers are now separate modules that wrap the core module.
>>>
>>> Essentially, what we're doing here:
>>> * Make "power up" and "power down" a function that can be (optionally)
>>>   implemented by a given user of the i2c-hid core.
>>> * The OF and ACPI modules are drivers on their own, so they implement
>>>   probe / remove / suspend / resume / shutdown.  The core code
>>>   provides implementations that OF and ACPI can call into.
>>>
>>> We'll organize this so that we now have 3 modules: the old i2c-hid
>>> module becomes the "core" module and two new modules will depend on
>>> it, handling probing the specific device.
>>>
>>> As part of this work, we'll remove the i2c-hid "platform data"
>>> concept since it's not needed.
>>>
>>> Signed-off-by: Douglas Anderson <dianders@chromium.org>
>>> ---
>>>
>>> Changes in v5:
>>> - Add shutdown_tail op and use it in ACPI.
>>> - i2chid_subclass_data => i2chid_ops.
>>> - power_up_device => power_up (same with power_down).
>>> - subclass => ops.
>>>
>>
>> Thanks this looks good to now, 2 small remarks below (since you are
>> going to do a v6 anyways). Feel free to ignore these remarks if
>> you prefer to keep things as is.
>>
>> And feel free to add my reviewed-by to v6 of this patch:
>>
>> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
> 
> Thanks!
> 
> 
>>> +static const struct i2c_device_id i2c_hid_acpi_id_table[] = {
>>> +     { "hid", 0 },
>>> +     { "hid-over-i2c", 0 },
>>> +     { },
>>> +};
>>> +MODULE_DEVICE_TABLE(i2c, i2c_hid_acpi_id_table);
>>
>> Hmm, I do not think these old-style i2c-ids are necessarry at
>> all in this driver. I expect all use-cases to use either
>> of or acpi matches.
>>
>> This was already present in the code before though, so
>> please ignore this remark. This is just something which
>> I noticed and thought was worth while pointing out as
>> a future cleanup.
> 
> Yeah, I wasn't sure if there was anyone using them.
> 
> Hrm.  Thinking about it, though, is it really OK for two drivers to
> both have the same table listed?  I'm not sure how that would work.
> Do you know?

Ah I missed that you are adding the i2c_device_id table to
both the new -acpi and -of drivers.

That indeed is not a good idea.

> I don't know a ton about ACPI, but for device tree I know i2c has a
> fallback mode.  Specifically having this table means that we'll match
> compatible strings such as:
> 
>   "zipzapzing,hid"
>   "kapowzers,hid-over-i2c"
> 
> In other words it'll ignore the vendor part and just match on the
> second half.

Yeah I know about that clever hack the i2c subsys has. 

> Just to make sure I wasn't remembering that from a dream
> I tried it and it worked.  I don't see any mainline device trees that
> look like that, though.  I could delete it, though it doesn't really
> take up much space and it seems nice to keep it working in case anyone
> was relying on it?

Ack, so in the of case there is a reason to keep this. But ACPI binding
does not use anything similar, so the old-style i2c_device_id table
should probably be removed from the -acpi driver.

> For ACPI is there a similar fallback?  If not then it seems like it'd
> be easy to remove it from there...
> 
> 
>> <snip>
>>
>>> diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
>>> index aeff1ffb0c8b..9551ba96dc49 100644
>>> --- a/drivers/hid/i2c-hid/i2c-hid-core.c
>>> +++ b/drivers/hid/i2c-hid/i2c-hid-core.c
>>> @@ -35,12 +35,8 @@
>>>  #include <linux/kernel.h>
>>>  #include <linux/hid.h>
>>>  #include <linux/mutex.h>
>>> -#include <linux/acpi.h>
>>> -#include <linux/of.h>
>>>  #include <linux/regulator/consumer.h>
>>
>> I think you can drop this regulator include here now too ?
> 
> Good point.
> 
> 
>>> diff --git a/drivers/hid/i2c-hid/i2c-hid-of.c b/drivers/hid/i2c-hid/i2c-hid-of.c
>>> new file mode 100644
>>> index 000000000000..15d533be2b24
>>> --- /dev/null
>>> +++ b/drivers/hid/i2c-hid/i2c-hid-of.c
>> <snip>
>>
>>> +static const struct dev_pm_ops i2c_hid_of_pm = {
>>> +     SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_core_suspend, i2c_hid_core_resume)
>>> +};
>>
>> This dev_pm_ops struct is identical to the one in i2c-hid-acpi.c
>> and the one which you introduce later in i2c-hid-of-goodix.c
>> is also identical, so that is 3 copies.
>>
>> Maybe just put a shared dev_pm_ops struct in the i2c-core
>> (and don't export the suspend/resume handlers) ?
> 
> Sounds good.

Regards,

Hans


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-11-11 11:13 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-09 21:36 [PATCH v5 0/4] HID: i2c-hid: Reorganize to allow supporting goodix,gt7375p Douglas Anderson
2020-11-09 21:36 ` [PATCH v5 1/4] HID: i2c-hid: Reorganize so ACPI and OF are separate modules Douglas Anderson
2020-11-09 23:23   ` Doug Anderson
2020-11-10  9:01   ` Hans de Goede
2020-11-10 22:17     ` Doug Anderson
2020-11-11  0:04       ` Dmitry Torokhov
2020-11-11 11:10         ` Hans de Goede
2020-11-11 11:13       ` Hans de Goede
2020-11-09 21:36 ` [PATCH v5 2/4] arm64: defconfig: Update config names for i2c-hid rejigger Douglas Anderson
2020-11-09 21:36 ` [PATCH v5 3/4] dt-bindings: input: HID: i2c-hid: Introduce bindings for the Goodix GT7375P Douglas Anderson
2020-11-09 21:36 ` [PATCH v5 4/4] HID: i2c-hid: Introduce goodix-i2c-hid using i2c-hid core Douglas Anderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).