Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH v2 4/4] HID: Intel-thc-hid: Intel-quicki2c: Add output report support
From: Even Xu @ 2025-12-09  7:52 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: srinivas.pandruvada, linux-input, linux-kernel, Even Xu,
	Rui Zhang
In-Reply-To: <20251209075215.1535371-1-even.xu@intel.com>

Add support for HID output reports in the intel-quicki2c driver by
implementing the output_report callback in the HID low-level driver
interface.

This enables proper communication with HID devices that require
output report functionality, such as setting device configuration or
updating device firmware.

Tested-by: Rui Zhang <rui1.zhang@intel.com>
Signed-off-by: Even Xu <even.xu@intel.com>
---
 .../intel-quicki2c/quicki2c-hid.c             |  8 ++++++++
 .../intel-quicki2c/quicki2c-protocol.c        | 19 +++++++++++++++++++
 .../intel-quicki2c/quicki2c-protocol.h        |  1 +
 3 files changed, 28 insertions(+)

diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.c b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.c
index 5c3ec95bb3fd..580a760b3ffc 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.c
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.c
@@ -83,6 +83,13 @@ static int quicki2c_hid_power(struct hid_device *hid, int lvl)
 	return 0;
 }
 
+static int quicki2c_hid_output_report(struct hid_device *hid, u8 *buf, size_t count)
+{
+	struct quicki2c_device *qcdev = hid->driver_data;
+
+	return quicki2c_output_report(qcdev, buf, count);
+}
+
 static struct hid_ll_driver quicki2c_hid_ll_driver = {
 	.parse = quicki2c_hid_parse,
 	.start = quicki2c_hid_start,
@@ -91,6 +98,7 @@ static struct hid_ll_driver quicki2c_hid_ll_driver = {
 	.close = quicki2c_hid_close,
 	.power = quicki2c_hid_power,
 	.raw_request = quicki2c_hid_raw_request,
+	.output_report = quicki2c_hid_output_report,
 };
 
 /**
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
index a287d9ee09c3..41271301215a 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
@@ -195,6 +195,25 @@ int quicki2c_set_report(struct quicki2c_device *qcdev, u8 report_type,
 	return buf_len;
 }
 
+int quicki2c_output_report(struct quicki2c_device *qcdev, void *buf, size_t buf_len)
+{
+	ssize_t len;
+	int ret;
+
+	len = quicki2c_init_write_buf(qcdev, 0, 0, false, buf, buf_len,
+				      qcdev->report_buf, qcdev->report_len);
+	if (len < 0)
+		return -EINVAL;
+
+	ret = thc_dma_write(qcdev->thc_hw, qcdev->report_buf, len);
+	if (ret) {
+		dev_err(qcdev->dev, "Output Report failed, ret %d\n", ret);
+		return ret;
+	}
+
+	return buf_len;
+}
+
 #define HIDI2C_RESET_TIMEOUT		5
 
 int quicki2c_reset(struct quicki2c_device *qcdev)
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.h b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.h
index db70e08c8b1c..6642cefb8a67 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.h
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.h
@@ -13,6 +13,7 @@ int quicki2c_get_report(struct quicki2c_device *qcdev, u8 report_type,
 			unsigned int reportnum, void *buf, size_t buf_len);
 int quicki2c_set_report(struct quicki2c_device *qcdev, u8 report_type,
 			unsigned int reportnum, void *buf, size_t buf_len);
+int quicki2c_output_report(struct quicki2c_device *qcdev, void *buf, size_t buf_len);
 int quicki2c_get_device_descriptor(struct quicki2c_device *qcdev);
 int quicki2c_get_report_descriptor(struct quicki2c_device *qcdev);
 int quicki2c_reset(struct quicki2c_device *qcdev);
-- 
2.40.1


^ permalink raw reply related

* [PATCH v2 3/4] HID: Intel-thc-hid: Intel-quicki2c: Support writing output report format
From: Even Xu @ 2025-12-09  7:52 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: srinivas.pandruvada, linux-input, linux-kernel, Even Xu,
	Rui Zhang, Ilpo Järvinen
In-Reply-To: <20251209075215.1535371-1-even.xu@intel.com>

There are two output formats requested in the HID-over-I2C specification:
- Command format (set feature/set report): encoded command written to
  command register, followed by data written to data register
- Output report format: all data written directly to output register

Current quicki2c_init_write_buf() implementation only supports the
command format.

Extend quicki2c_init_write_buf() to automatically detect the output
format based on the presence of command parameters and prepare the
appropriate output buffer accordingly.

Tested-by: Rui Zhang <rui1.zhang@intel.com>
Signed-off-by: Even Xu <even.xu@intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 .../intel-quicki2c/quicki2c-protocol.c          | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
index ab390ce79c21..a287d9ee09c3 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
@@ -30,13 +30,18 @@ static ssize_t quicki2c_init_write_buf(struct quicki2c_device *qcdev, u32 cmd, s
 	if (buf_len > write_buf_len)
 		return -EINVAL;
 
-	memcpy(write_buf, &qcdev->dev_desc.cmd_reg, HIDI2C_REG_LEN);
-	offset += HIDI2C_REG_LEN;
-	memcpy(write_buf + offset, &cmd, cmd_len);
-	offset += cmd_len;
+	if (cmd_len) {
+		memcpy(write_buf, &qcdev->dev_desc.cmd_reg, HIDI2C_REG_LEN);
+		offset += HIDI2C_REG_LEN;
+		memcpy(write_buf + offset, &cmd, cmd_len);
+		offset += cmd_len;
 
-	if (append_data_reg) {
-		memcpy(write_buf + offset, &qcdev->dev_desc.data_reg, HIDI2C_REG_LEN);
+		if (append_data_reg) {
+			memcpy(write_buf + offset, &qcdev->dev_desc.data_reg, HIDI2C_REG_LEN);
+			offset += HIDI2C_REG_LEN;
+		}
+	} else {
+		memcpy(write_buf, &qcdev->dev_desc.output_reg, HIDI2C_REG_LEN);
 		offset += HIDI2C_REG_LEN;
 	}
 
-- 
2.40.1


^ permalink raw reply related

* [PATCH v2 2/4] HID: Intel-thc-hid: Intel-quicki2c: Use put_unaligned_le16 for __le16 writes
From: Even Xu @ 2025-12-09  7:52 UTC (permalink / raw)
  To: jikos, bentiss; +Cc: srinivas.pandruvada, linux-input, linux-kernel, Even Xu
In-Reply-To: <20251209075215.1535371-1-even.xu@intel.com>

Replace memcpy operations with put_unaligned_le16() when writing 16-bit
little-endian values to the write buffer.

This change improves code clarity and ensures proper handling of unaligned
memory access.

Signed-off-by: Even Xu <even.xu@intel.com>
---
 drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
index 013cbbb39efd..ab390ce79c21 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
@@ -41,9 +41,7 @@ static ssize_t quicki2c_init_write_buf(struct quicki2c_device *qcdev, u32 cmd, s
 	}
 
 	if (data && data_len) {
-		__le16 len = cpu_to_le16(data_len + HIDI2C_LENGTH_LEN);
-
-		memcpy(write_buf + offset, &len, HIDI2C_LENGTH_LEN);
+		put_unaligned_le16(data_len + HIDI2C_LENGTH_LEN, write_buf + offset);
 		offset += HIDI2C_LENGTH_LEN;
 		memcpy(write_buf + offset, data, data_len);
 	}
-- 
2.40.1


^ permalink raw reply related

* [PATCH v2 0/4] Add output report support for QuickI2C driver
From: Even Xu @ 2025-12-09  7:52 UTC (permalink / raw)
  To: jikos, bentiss; +Cc: srinivas.pandruvada, linux-input, linux-kernel, Even Xu

This patch serial adds support for HID output reports in the Quicki2c
driver by implementing the output_report callback in the HID low-level
driver interface.

This change introduces:
- Refine QuickI2C driver to use size_t for all length-related variables
- Enhance the quicki2c_init_write_buf() function by adding support for
  writing to the output register based on the content being written
- Add quicki2c_hid_output_report() and quicki2c_output_report() function
  that processe the HID output reports request

This enables proper communication with HID devices that require output
report functionality, such as setting device configuration or updating
device firmware.

Change log:
v2:
 - Fix a return error code check bug in [patch 4/4]

Even Xu (4):
  HID: Intel-thc-hid: Intel-quicki2c: Use size_t for all length
    variables
  HID: Intel-thc-hid: Intel-quicki2c: Use put_unaligned_le16 for __le16
    writes
  HID: Intel-thc-hid: Intel-quicki2c: Support writing output report
    format
  HID: Intel-thc-hid: Intel-quicki2c: Add output report support

 .../intel-quicki2c/quicki2c-dev.h             |  2 +-
 .../intel-quicki2c/quicki2c-hid.c             |  8 ++
 .../intel-quicki2c/quicki2c-protocol.c        | 95 +++++++++++--------
 .../intel-quicki2c/quicki2c-protocol.h        |  5 +-
 4 files changed, 68 insertions(+), 42 deletions(-)

-- 
2.40.1


^ permalink raw reply

* [PATCH v2 1/4] HID: Intel-thc-hid: Intel-quicki2c: Use size_t for all length variables
From: Even Xu @ 2025-12-09  7:52 UTC (permalink / raw)
  To: jikos, bentiss; +Cc: srinivas.pandruvada, linux-input, linux-kernel, Even Xu
In-Reply-To: <20251209075215.1535371-1-even.xu@intel.com>

Convert all length-related variables in the QuickI2C protocol layer to use
size_t type to follow kernel coding conventions.

This includes:
- All buffer length parameters and variables
- Return values of quicki2c_encode_cmd() function which represents
  encoded command buffer size.
- Return values of quicki2c_init_write_buf() function which represents
  process result: either prepared output buffer size or error code.

This change improves type consistency and aligns with standard kernel
practices for memory size representation, reducing potential issues
with size calculations and comparisons.

Signed-off-by: Even Xu <even.xu@intel.com>
---
 .../intel-quicki2c/quicki2c-dev.h             |  2 +-
 .../intel-quicki2c/quicki2c-protocol.c        | 55 +++++++++----------
 .../intel-quicki2c/quicki2c-protocol.h        |  4 +-
 3 files changed, 28 insertions(+), 33 deletions(-)

diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
index 2cb5471a8133..33a1e3db1cb2 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
@@ -213,7 +213,7 @@ struct quicki2c_device {
 	u8 *report_descriptor;
 	u8 *input_buf;
 	u8 *report_buf;
-	u32 report_len;
+	size_t report_len;
 
 	wait_queue_head_t reset_ack_wq;
 	bool reset_ack;
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
index a63f8c833252..013cbbb39efd 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c
@@ -13,11 +13,11 @@
 #include "quicki2c-hid.h"
 #include "quicki2c-protocol.h"
 
-static int quicki2c_init_write_buf(struct quicki2c_device *qcdev, u32 cmd, int cmd_len,
-				   bool append_data_reg, u8 *data, int data_len,
-				   u8 *write_buf, int write_buf_len)
+static ssize_t quicki2c_init_write_buf(struct quicki2c_device *qcdev, u32 cmd, size_t cmd_len,
+				       bool append_data_reg, u8 *data, size_t data_len,
+				       u8 *write_buf, size_t write_buf_len)
 {
-	int buf_len, offset = 0;
+	size_t buf_len, offset = 0;
 
 	buf_len = HIDI2C_REG_LEN + cmd_len;
 
@@ -51,10 +51,10 @@ static int quicki2c_init_write_buf(struct quicki2c_device *qcdev, u32 cmd, int c
 	return buf_len;
 }
 
-static int quicki2c_encode_cmd(struct quicki2c_device *qcdev, u32 *cmd_buf,
-			       u8 opcode, u8 report_type, u8 report_id)
+static size_t quicki2c_encode_cmd(struct quicki2c_device *qcdev, u32 *cmd_buf,
+				  u8 opcode, u8 report_type, u8 report_id)
 {
-	int cmd_len;
+	size_t cmd_len;
 
 	*cmd_buf = FIELD_PREP(HIDI2C_CMD_OPCODE, opcode) |
 		   FIELD_PREP(HIDI2C_CMD_REPORT_TYPE, report_type);
@@ -72,22 +72,20 @@ static int quicki2c_encode_cmd(struct quicki2c_device *qcdev, u32 *cmd_buf,
 }
 
 static int write_cmd_to_txdma(struct quicki2c_device *qcdev, int opcode,
-			      int report_type, int report_id, u8 *buf, int buf_len)
+			      int report_type, int report_id, u8 *buf, size_t buf_len)
 {
-	size_t write_buf_len;
-	int cmd_len, ret;
+	size_t cmd_len;
+	ssize_t len;
 	u32 cmd;
 
 	cmd_len = quicki2c_encode_cmd(qcdev, &cmd, opcode, report_type, report_id);
 
-	ret = quicki2c_init_write_buf(qcdev, cmd, cmd_len, buf ? true : false, buf,
+	len = quicki2c_init_write_buf(qcdev, cmd, cmd_len, buf ? true : false, buf,
 				      buf_len, qcdev->report_buf, qcdev->report_len);
-	if (ret < 0)
-		return ret;
-
-	write_buf_len = ret;
+	if (len < 0)
+		return len;
 
-	return thc_dma_write(qcdev->thc_hw, qcdev->report_buf, write_buf_len);
+	return thc_dma_write(qcdev->thc_hw, qcdev->report_buf, len);
 }
 
 int quicki2c_set_power(struct quicki2c_device *qcdev, enum hidi2c_power_state power_state)
@@ -126,13 +124,13 @@ int quicki2c_get_report_descriptor(struct quicki2c_device *qcdev)
 }
 
 int quicki2c_get_report(struct quicki2c_device *qcdev, u8 report_type,
-			unsigned int reportnum, void *buf, u32 buf_len)
+			unsigned int reportnum, void *buf, size_t buf_len)
 {
 	struct hidi2c_report_packet *rpt;
-	size_t write_buf_len, read_len = 0;
-	int cmd_len, rep_type;
+	size_t cmd_len, read_len = 0;
+	int rep_type, ret;
+	ssize_t len;
 	u32 cmd;
-	int ret;
 
 	if (report_type == HID_INPUT_REPORT) {
 		rep_type = HIDI2C_INPUT;
@@ -145,25 +143,22 @@ int quicki2c_get_report(struct quicki2c_device *qcdev, u8 report_type,
 
 	cmd_len = quicki2c_encode_cmd(qcdev, &cmd, HIDI2C_GET_REPORT, rep_type, reportnum);
 
-	ret = quicki2c_init_write_buf(qcdev, cmd, cmd_len, true, NULL, 0,
+	len = quicki2c_init_write_buf(qcdev, cmd, cmd_len, true, NULL, 0,
 				      qcdev->report_buf, qcdev->report_len);
-	if (ret < 0)
-		return ret;
-
-	write_buf_len = ret;
+	if (len < 0)
+		return len;
 
 	rpt = (struct hidi2c_report_packet *)qcdev->input_buf;
 
-	ret = thc_swdma_read(qcdev->thc_hw, qcdev->report_buf, write_buf_len,
-			     NULL, rpt, &read_len);
+	ret = thc_swdma_read(qcdev->thc_hw, qcdev->report_buf, len, NULL, rpt, &read_len);
 	if (ret) {
-		dev_err_once(qcdev->dev, "Get report failed, ret %d, read len (%zu vs %d)\n",
+		dev_err_once(qcdev->dev, "Get report failed, ret %d, read len (%zu vs %zu)\n",
 			     ret, read_len, buf_len);
 		return ret;
 	}
 
 	if (HIDI2C_DATA_LEN(le16_to_cpu(rpt->len)) != buf_len || rpt->data[0] != reportnum) {
-		dev_err_once(qcdev->dev, "Invalid packet, len (%d vs %d) report id (%d vs %d)\n",
+		dev_err_once(qcdev->dev, "Invalid packet, len (%d vs %zu) report id (%d vs %d)\n",
 			     le16_to_cpu(rpt->len), buf_len, rpt->data[0], reportnum);
 		return -EINVAL;
 	}
@@ -174,7 +169,7 @@ int quicki2c_get_report(struct quicki2c_device *qcdev, u8 report_type,
 }
 
 int quicki2c_set_report(struct quicki2c_device *qcdev, u8 report_type,
-			unsigned int reportnum, void *buf, u32 buf_len)
+			unsigned int reportnum, void *buf, size_t buf_len)
 {
 	int rep_type;
 	int ret;
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.h b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.h
index bf4908cce59c..db70e08c8b1c 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.h
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.h
@@ -10,9 +10,9 @@ struct quicki2c_device;
 
 int quicki2c_set_power(struct quicki2c_device *qcdev, enum hidi2c_power_state power_state);
 int quicki2c_get_report(struct quicki2c_device *qcdev, u8 report_type,
-			unsigned int reportnum, void *buf, u32 buf_len);
+			unsigned int reportnum, void *buf, size_t buf_len);
 int quicki2c_set_report(struct quicki2c_device *qcdev, u8 report_type,
-			unsigned int reportnum, void *buf, u32 buf_len);
+			unsigned int reportnum, void *buf, size_t buf_len);
 int quicki2c_get_device_descriptor(struct quicki2c_device *qcdev);
 int quicki2c_get_report_descriptor(struct quicki2c_device *qcdev);
 int quicki2c_reset(struct quicki2c_device *qcdev);
-- 
2.40.1


^ permalink raw reply related

* Re: [PATCH] input: byd: use %*ph for Z packet dump
From: Dmitry Torokhov @ 2025-12-09  5:43 UTC (permalink / raw)
  To: Vivek BalachandharTN
  Cc: linux-input, linux-kernel, Thomas Gleixner, Ingo Molnar
In-Reply-To: <20251202033120.2264474-1-vivek.balachandhar@gmail.com>

On Tue, Dec 02, 2025 at 03:31:20AM +0000, Vivek BalachandharTN wrote:
> Replace the hand-rolled %02x formatting of the Z packet warning in the
> BYD driver with the %*ph format specifier. %*ph is the preferred helper
> for printing a buffer in hexadecimal and makes the logging clearer and
> more consistent.
> 
> Signed-off-by: Vivek BalachandharTN <vivek.balachandhar@gmail.com>

Applied, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 2/2] Input: Add support for Wacom W9000-series penabled touchscreens
From: Dmitry Torokhov @ 2025-12-09  5:41 UTC (permalink / raw)
  To: Hendrik Noack
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-input,
	devicetree, linux-kernel
In-Reply-To: <k5rhkjmttba4aznb3xa44pqaxepsfkbe5ap6g2ln3rcgunvkky@262tpqra76v7>

On Mon, Dec 08, 2025 at 09:35:09PM -0800, Dmitry Torokhov wrote:
> Hi Hendrik,
> 
> On Fri, Dec 05, 2025 at 05:49:52PM +0100, Hendrik Noack wrote:
> > +
> > +	struct gpio_desc *flash_mode_gpio;

Forgot to ask - what does this do? We do not seem to be using it except
for requesting.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 2/2] Input: Add support for Wacom W9000-series penabled touchscreens
From: Dmitry Torokhov @ 2025-12-09  5:35 UTC (permalink / raw)
  To: Hendrik Noack
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-input,
	devicetree, linux-kernel
In-Reply-To: <20251205164952.17709-1-hendrik-noack@gmx.de>

Hi Hendrik,

On Fri, Dec 05, 2025 at 05:49:52PM +0100, Hendrik Noack wrote:
> Add driver for two Wacom W9007A variants. These are penabled touchscreens
> supporting passive Wacom Pens and use I2C.
> 
> Signed-off-by: Hendrik Noack <hendrik-noack@gmx.de>
> ---
>  drivers/input/touchscreen/Kconfig       |  12 +
>  drivers/input/touchscreen/Makefile      |   1 +
>  drivers/input/touchscreen/wacom_w9000.c | 480 ++++++++++++++++++++++++
>  3 files changed, 493 insertions(+)
>  create mode 100644 drivers/input/touchscreen/wacom_w9000.c
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 7d5b72ee07fa..40f7af0a681a 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -610,6 +610,18 @@ config TOUCHSCREEN_WACOM_I2C
>  	  To compile this driver as a module, choose M here: the module
>  	  will be called wacom_i2c.
>  
> +config TOUCHSCREEN_WACOM_W9000
> +	tristate "Wacom W9000-series penabled touchscreen (I2C)"
> +	depends on I2C
> +	help
> +	  Say Y here if you have a Wacom W9000-series penabled I2C touchscreen.
> +	  This driver supports model W9007A.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called wacom_w9000.
> +
>  config TOUCHSCREEN_LPC32XX
>  	tristate "LPC32XX touchscreen controller"
>  	depends on ARCH_LPC32XX
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index ab9abd151078..aa3915df83b2 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -102,6 +102,7 @@ tsc2007-$(CONFIG_TOUCHSCREEN_TSC2007_IIO)	+= tsc2007_iio.o
>  obj-$(CONFIG_TOUCHSCREEN_TSC2007)	+= tsc2007.o
>  obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001)	+= wacom_w8001.o
>  obj-$(CONFIG_TOUCHSCREEN_WACOM_I2C)	+= wacom_i2c.o
> +obj-$(CONFIG_TOUCHSCREEN_WACOM_W9000)	+= wacom_w9000.o
>  obj-$(CONFIG_TOUCHSCREEN_WDT87XX_I2C)	+= wdt87xx_i2c.o
>  obj-$(CONFIG_TOUCHSCREEN_WM831X)	+= wm831x-ts.o
>  obj-$(CONFIG_TOUCHSCREEN_WM97XX)	+= wm97xx-ts.o
> diff --git a/drivers/input/touchscreen/wacom_w9000.c b/drivers/input/touchscreen/wacom_w9000.c
> new file mode 100644
> index 000000000000..05c928646bc3
> --- /dev/null
> +++ b/drivers/input/touchscreen/wacom_w9000.c
> @@ -0,0 +1,480 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Wacom W9000-series penabled I2C touchscreen driver
> + *
> + * Copyright (c) 2025 Hendrik Noack <hendrik-noack@gmx.de>
> + *
> + * Partially based on vendor driver:
> + *	Copyright (C) 2012, Samsung Electronics Co. Ltd.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/input.h>
> +#include <linux/input/touchscreen.h>
> +#include <linux/unaligned.h>
> +
> +// Message length

Prefer C-style comments /* */

> +#define COM_COORD_NUM_MAX	12
> +#define COM_QUERY_NUM_MAX	9

What does "COM" stand for?
> +
> +// Commands
> +#define COM_QUERY		0x2a
> +
> +struct wacom_w9000_variant {
> +	int com_coord_num;

unsigned?

> +	int com_query_num;
> +	char *name;

const?

> +};
> +
> +struct wacom_w9000_data {
> +	struct i2c_client *client;
> +	struct input_dev *input_dev;
> +	const struct wacom_w9000_variant *variant;
> +	unsigned int fw_version;
> +
> +	struct touchscreen_properties prop;
> +	unsigned int max_pressure;
> +
> +	struct regulator *regulator;
> +
> +	struct gpio_desc *flash_mode_gpio;
> +	struct gpio_desc *pen_inserted_gpio;
> +
> +	unsigned int irq;
> +	unsigned int pen_insert_irq;
> +
> +	bool pen_inserted;
> +	bool pen_proximity;
> +};
> +
> +static int wacom_w9000_read(struct i2c_client *client, u8 command, int len, char *data)
> +{
> +	struct i2c_msg xfer[2];

	struct i2c_msg xfer[] = {
		{
			.addr = client->addr,
			.buf = &comand,
			.len = sizeof(command),
		},
		{
			...
		},
	};
> +	bool retried = false;
> +	int ret;
> +
> +	/* Write register */
> +	xfer[0].addr = client->addr;
> +	xfer[0].flags = 0;
> +	xfer[0].len = 1;
> +	xfer[0].buf = &command;
> +
> +	/* Read data */
> +	xfer[1].addr = client->addr;
> +	xfer[1].flags = I2C_M_RD;
> +	xfer[1].len = len;
> +	xfer[1].buf = data;
> +
> +retry:

Why do we need a retry? Is it because the controller might be asleep?
If so can we wake it up explicitly?

> +	ret = i2c_transfer(client->adapter, xfer, 2);
> +	if (ret == 2) {

ARRAY_SIZE(xfer)

> +		ret = 0;
> +	} else if (!retried) {
> +		retried = true;
> +		goto retry;
> +	} else {
> +		if (ret >= 0)
> +			ret = -EIO;
> +		dev_err(&client->dev, "%s: i2c transfer failed (%d)\n", __func__, ret);
> +	}
> +
> +	return ret;
> +}
> +
> +static int wacom_w9000_query(struct wacom_w9000_data *wacom_data)
> +{
> +	struct i2c_client *client = wacom_data->client;
> +	struct device *dev = &wacom_data->client->dev;
> +	bool retried = false;
> +	int ret;
> +	u8 data[COM_QUERY_NUM_MAX];
> +
> +retry:
> +	ret = wacom_w9000_read(client, COM_QUERY, wacom_data->variant->com_query_num, data);
> +	if (ret)
> +		return ret;
> +
> +	if (data[0] == 0x0f) {
> +		wacom_data->fw_version = get_unaligned_be16(&data[7]);
> +	} else if (!retried) {
> +		retried = true;
> +		goto retry;
> +	} else {
> +		return -EIO;
> +	}
> +
> +	dev_dbg(dev, "query: %X, %X, %X, %X, %X, %X, %X, %X, %X, %d\n", data[0], data[1], data[2],
> +		data[3], data[4], data[5], data[6], data[7], data[8], retried);

Please print hex data with "%*ph".

> +
> +	wacom_data->prop.max_x = get_unaligned_be16(&data[1]);
> +	wacom_data->prop.max_y = get_unaligned_be16(&data[3]);
> +	wacom_data->max_pressure = get_unaligned_be16(&data[5]);
> +
> +	dev_dbg(dev, "max_x:%d, max_y:%d, max_pressure:%d, fw:0x%X", wacom_data->prop.max_x,

fw: %#X

> +		wacom_data->prop.max_y, wacom_data->max_pressure,
> +		wacom_data->fw_version);
> +
> +	return 0;
> +}
> +
> +static void wacom_w9000_coord(struct wacom_w9000_data *wacom_data)
> +{
> +	struct i2c_client *client = wacom_data->client;
> +	struct device *dev = &wacom_data->client->dev;
> +	int ret;
> +	u8 data[COM_COORD_NUM_MAX];
> +	bool touch, rubber, side_button;
> +	u16 x, y, pressure;
> +	u8 distance;
> +
> +	ret = i2c_master_recv(client, data, wacom_data->variant->com_coord_num);
> +	if (ret != wacom_data->variant->com_coord_num) {
> +		if (ret >= 0)
> +			ret = -EIO;
> +		dev_err(dev, "%s: i2c receive failed (%d)\n", __func__, ret);
> +		return;
> +	}
> +
> +	dev_dbg(dev, "data: %X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X", data[0], data[1],
> +		data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10],
> +		data[11]);

"data: %*ph"

> +
> +	if (data[0] & BIT(7)) {
> +		wacom_data->pen_proximity = 1;

= true

> +
> +		touch = !!(data[0] & BIT(4));
> +		side_button = !!(data[0] & BIT(5));
> +		rubber = !!(data[0] & BIT(6));
> +
> +		x = get_unaligned_be16(&data[1]);
> +		y = get_unaligned_be16(&data[3]);
> +		pressure = get_unaligned_be16(&data[5]);
> +		distance = data[7];
> +
> +		if (!((x <= wacom_data->prop.max_x) && (y <= wacom_data->prop.max_y))) {

Too many parens. Also maybe

		if (x > wacom_data->prop.max_x || y > wacom_data->prop.max_y)

> +			dev_warn(dev, "Coordinates out of range x=%d, y=%d", x, y);
> +			return;
> +		}
> +
> +		touchscreen_report_pos(wacom_data->input_dev, &wacom_data->prop, x, y, false);
> +		input_report_abs(wacom_data->input_dev, ABS_PRESSURE, pressure);
> +		input_report_abs(wacom_data->input_dev, ABS_DISTANCE, distance);
> +		input_report_key(wacom_data->input_dev, BTN_STYLUS, side_button);
> +		input_report_key(wacom_data->input_dev, BTN_TOUCH, touch);
> +		input_report_key(wacom_data->input_dev, BTN_TOOL_PEN, !rubber);
> +		input_report_key(wacom_data->input_dev, BTN_TOOL_RUBBER, rubber);
> +		input_sync(wacom_data->input_dev);
> +	} else {
> +		if (wacom_data->pen_proximity) {

Can be collapsed "else if"

> +			input_report_abs(wacom_data->input_dev, ABS_PRESSURE, 0);
> +			input_report_abs(wacom_data->input_dev, ABS_DISTANCE, 0);
> +			input_report_key(wacom_data->input_dev, BTN_STYLUS, 0);
> +			input_report_key(wacom_data->input_dev, BTN_TOUCH, 0);
> +			input_report_key(wacom_data->input_dev, BTN_TOOL_PEN, 0);
> +			input_report_key(wacom_data->input_dev, BTN_TOOL_RUBBER, 0);
> +			input_sync(wacom_data->input_dev);
> +
> +			wacom_data->pen_proximity = 0;

= false

> +		}
> +	}
> +}
> +
> +static irqreturn_t wacom_w9000_interrupt(int irq, void *dev_id)
> +{
> +	struct wacom_w9000_data *wacom_data = dev_id;
> +
> +	wacom_w9000_coord(wacom_data);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t wacom_w9000_interrupt_pen_insert(int irq, void *dev_id)
> +{
> +	struct wacom_w9000_data *wacom_data = dev_id;
> +	struct device *dev = &wacom_data->client->dev;
> +	int ret;

	int error;

> +
> +	wacom_data->pen_inserted = gpiod_get_value(wacom_data->pen_inserted_gpio);

This runs in a thread, use "can sleep" variant.

> +
> +	input_report_switch(wacom_data->input_dev, SW_PEN_INSERTED, wacom_data->pen_inserted);
> +	input_sync(wacom_data->input_dev);
> +
> +	if (!wacom_data->pen_inserted && !regulator_is_enabled(wacom_data->regulator)) {

What if the regulator is shared with something else? You should not
operate based on the state, just do what you need (i.e. enable or
disable).

> +		ret = regulator_enable(wacom_data->regulator);
> +		if (ret) {
> +			dev_err(dev, "Failed to enable regulators: %d\n", ret);
> +			return IRQ_HANDLED;
> +		}
> +		msleep(200);
> +		enable_irq(wacom_data->irq);
> +	} else if (wacom_data->pen_inserted && regulator_is_enabled(wacom_data->regulator)) {
> +		disable_irq(wacom_data->irq);
> +		regulator_disable(wacom_data->regulator);
> +	}
> +
> +	dev_dbg(dev, "Pen inserted changed to %d", wacom_data->pen_inserted);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int wacom_w9000_open(struct input_dev *dev)
> +{
> +	struct wacom_w9000_data *wacom_data = input_get_drvdata(dev);
> +	int ret;

	int error;

> +
> +	if (!wacom_data->pen_inserted && !regulator_is_enabled(wacom_data->regulator)) {
> +		ret = regulator_enable(wacom_data->regulator);
> +		if (ret) {
> +			dev_err(&wacom_data->client->dev, "Failed to enable regulators: %d\n",
> +				ret);
> +			return ret;
> +		}
> +		msleep(200);
> +		enable_irq(wacom_data->irq);
> +	}
> +	return 0;
> +}
> +
> +static void wacom_w9000_close(struct input_dev *dev)
> +{
> +	struct wacom_w9000_data *wacom_data = input_get_drvdata(dev);
> +
> +	if (regulator_is_enabled(wacom_data->regulator)) {
> +		disable_irq(wacom_data->irq);
> +		regulator_disable(wacom_data->regulator);
> +	}
> +}
> +
> +static int wacom_w9000_probe(struct i2c_client *client)
> +{
> +	struct device *dev = &client->dev;
> +	struct wacom_w9000_data *wacom_data;
> +	struct input_dev *input_dev;
> +	int ret;

	int error;

> +	u32 val;
> +
> +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> +		dev_err(dev, "i2c_check_functionality error\n");
> +		return -EIO;
> +	}
> +
> +	wacom_data = devm_kzalloc(dev, sizeof(*wacom_data), GFP_KERNEL);
> +	if (!wacom_data)
> +		return -ENOMEM;
> +
> +	wacom_data->variant = i2c_get_match_data(client);
> +
> +	wacom_data->client = client;
> +
> +	input_dev = devm_input_allocate_device(dev);
> +	if (!input_dev)
> +		return -ENOMEM;
> +	wacom_data->input_dev = input_dev;
> +
> +	wacom_data->irq = client->irq;
> +	i2c_set_clientdata(client, wacom_data);
> +
> +	wacom_data->regulator = devm_regulator_get(dev, "vdd");
> +	if (IS_ERR(wacom_data->regulator))
> +		return dev_err_probe(dev, PTR_ERR(wacom_data->regulator),
> +				     "Failed to get regulators\n");
> +
> +	wacom_data->flash_mode_gpio = devm_gpiod_get_optional(dev, "flash-mode", GPIOD_OUT_LOW);
> +	if (IS_ERR(wacom_data->flash_mode_gpio))
> +		return dev_err_probe(dev, PTR_ERR(wacom_data->flash_mode_gpio),
> +				     "Failed to get flash-mode gpio\n");
> +
> +	wacom_data->pen_inserted_gpio = devm_gpiod_get_optional(dev, "pen-inserted", GPIOD_IN);
> +	if (IS_ERR(wacom_data->pen_inserted_gpio))
> +		return dev_err_probe(dev, PTR_ERR(wacom_data->pen_inserted_gpio),
> +				     "Failed to get pen-insert gpio\n");
> +
> +	ret = regulator_enable(wacom_data->regulator);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to enable regulators\n");
> +
> +	msleep(200);
> +
> +	ret = wacom_w9000_query(wacom_data);
> +	if (ret)
> +		goto err_disable_regulators;

I do not think you need power past this point until you open the device.
Maybe turn it off right here?

> +
> +	input_dev->name = wacom_data->variant->name;
> +	input_dev->id.bustype = BUS_I2C;
> +	input_dev->dev.parent = dev;
> +	input_dev->id.vendor = 0x56a;
> +	input_dev->id.version = wacom_data->fw_version;
> +	input_dev->open = wacom_w9000_open;
> +	input_dev->close = wacom_w9000_close;
> +
> +	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
> +	input_set_capability(input_dev, EV_KEY, BTN_TOOL_PEN);
> +	input_set_capability(input_dev, EV_KEY, BTN_TOOL_RUBBER);
> +	input_set_capability(input_dev, EV_KEY, BTN_STYLUS);
> +
> +	// Calculate x and y resolution from size in devicetree
> +	ret = device_property_read_u32(dev, "touchscreen-x-mm", &val);
> +	if (ret)
> +		input_abs_set_res(input_dev, ABS_X, 100);

If you do not have resolution data simply do not set it.

> +	else
> +		input_abs_set_res(input_dev, ABS_X, wacom_data->prop.max_x / val);

Don't you parse prop below so here max_x and max_y are both 0?

> +	ret = device_property_read_u32(dev, "touchscreen-y-mm", &val);
> +	if (ret)
> +		input_abs_set_res(input_dev, ABS_Y, 100);
> +	else
> +		input_abs_set_res(input_dev, ABS_Y, wacom_data->prop.max_y / val);
> +
> +	input_set_abs_params(input_dev, ABS_X, 0, wacom_data->prop.max_x, 4, 0);
> +	input_set_abs_params(input_dev, ABS_Y, 0, wacom_data->prop.max_y, 4, 0);
> +	input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_data->max_pressure, 0, 0);
> +	input_set_abs_params(input_dev, ABS_DISTANCE, 0, 255, 0, 0);
> +
> +	touchscreen_parse_properties(input_dev, false, &wacom_data->prop);
> +
> +	ret = devm_request_threaded_irq(dev, wacom_data->irq, NULL, wacom_w9000_interrupt,
> +					IRQF_ONESHOT | IRQF_NO_AUTOEN, client->name, wacom_data);
> +	if (ret) {
> +		dev_err(dev, "Failed to register interrupt\n");
> +		goto err_disable_regulators;
> +	}
> +
> +	if (wacom_data->pen_inserted_gpio) {
> +		input_set_capability(input_dev, EV_SW, SW_PEN_INSERTED);
> +		wacom_data->pen_insert_irq = gpiod_to_irq(wacom_data->pen_inserted_gpio);
> +		ret = devm_request_threaded_irq(dev, wacom_data->pen_insert_irq, NULL,
> +						wacom_w9000_interrupt_pen_insert, IRQF_ONESHOT |
> +						IRQF_NO_AUTOEN | IRQF_TRIGGER_RISING |
> +						IRQF_TRIGGER_FALLING, "wacom_pen_insert",

Rely on DT to define triggers. Use IRQF_ONESHOT only.

> +						wacom_data);
> +		if (ret) {
> +			dev_err(dev, "Failed to register pen-insert interrupt\n");
> +			goto err_disable_regulators;
> +		}
> +
> +		wacom_data->pen_inserted = gpiod_get_value(wacom_data->pen_inserted_gpio);
> +		if (wacom_data->pen_inserted)
> +			regulator_disable(wacom_data->regulator);
> +		else
> +			enable_irq(wacom_data->irq);
> +	} else {
> +		enable_irq(wacom_data->irq);

Can this be moved into "open"?

> +	}
> +
> +	input_set_drvdata(input_dev, wacom_data);
> +
> +	input_report_switch(wacom_data->input_dev, SW_PEN_INSERTED, wacom_data->pen_inserted);
> +	input_sync(wacom_data->input_dev);
> +
> +	if (wacom_data->pen_inserted_gpio)
> +		enable_irq(wacom_data->pen_insert_irq);
> +
> +	ret = input_register_device(wacom_data->input_dev);
> +	if (ret) {
> +		dev_err(dev, "Failed to register input device: %d\n", ret);
> +		goto err_disable_regulators;
> +	}
> +
> +	return 0;
> +
> +err_disable_regulators:
> +	regulator_disable(wacom_data->regulator);
> +	return ret;
> +}
> +
> +static void wacom_w9000_remove(struct i2c_client *client)
> +{
> +	struct wacom_w9000_data *wacom_data = i2c_get_clientdata(client);
> +
> +	if (regulator_is_enabled(wacom_data->regulator))
> +		regulator_disable(wacom_data->regulator);

Please move this to "close" and drop wacom_w9000_remove() altogether.

> +}
> +
> +static int wacom_w9000_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct wacom_w9000_data *wacom_data = i2c_get_clientdata(client);
> +	struct input_dev *input_dev = wacom_data->input_dev;
> +
> +	mutex_lock(&input_dev->mutex);

	guard(mutex)(&input_dev->mutex);

> +
> +	if (regulator_is_enabled(wacom_data->regulator)) {
> +		disable_irq(wacom_data->irq);
> +		regulator_disable(wacom_data->regulator);
> +	}
> +
> +	mutex_unlock(&input_dev->mutex);
> +
> +	return 0;
> +}
> +
> +static int wacom_w9000_resume(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct wacom_w9000_data *wacom_data = i2c_get_clientdata(client);
> +	struct input_dev *input_dev = wacom_data->input_dev;
> +	int ret = 0;
> +
> +	mutex_lock(&input_dev->mutex);

	guard(mutex)(&input_dev->mutex);
> +
> +	if (!wacom_data->pen_inserted && !regulator_is_enabled(wacom_data->regulator)) {
> +		ret = regulator_enable(wacom_data->regulator);
> +		if (ret) {
> +			dev_err(&wacom_data->client->dev, "Failed to enable regulators: %d\n",
> +				ret);
> +		} else {
> +			msleep(200);
> +			enable_irq(wacom_data->irq);
> +		}
> +	}
> +
> +	mutex_unlock(&input_dev->mutex);
> +
> +	return ret;
> +}
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(wacom_w9000_pm, wacom_w9000_suspend, wacom_w9000_resume);
> +
> +static const struct wacom_w9000_variant w9007a_lt03 = {
> +	.com_coord_num	= 8,
> +	.com_query_num	= 9,
> +	.name = "Wacom W9007 LT03 Digitizer",
> +};
> +
> +static const struct wacom_w9000_variant w9007a_v1 = {
> +	.com_coord_num	= 12,
> +	.com_query_num	= 9,
> +	.name = "Wacom W9007 V1 Digitizer",
> +};
> +
> +static const struct of_device_id wacom_w9000_of_match[] = {
> +	{ .compatible = "wacom,w9007a-lt03", .data = &w9007a_lt03, },
> +	{ .compatible = "wacom,w9007a-v1", .data = &w9007a_v1, },
> +	{},

	{ }

No need for trailing comma on a sentinel entry.

> +};
> +MODULE_DEVICE_TABLE(of, wacom_w9000_of_match);
> +
> +static const struct i2c_device_id wacom_w9000_id[] = {
> +	{ .name = "w9007a-lt03", .driver_data = (kernel_ulong_t)&w9007a_lt03 },
> +	{ .name = "w9007a-v1", .driver_data = (kernel_ulong_t)&w9007a_v1 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, wacom_w9000_id);
> +
> +static struct i2c_driver wacom_w9000_driver = {
> +	.driver = {
> +		.name	= "wacom_w9000",
> +		.of_match_table = wacom_w9000_of_match,
> +		.pm	= pm_sleep_ptr(&wacom_w9000_pm),
> +	},
> +	.probe		= wacom_w9000_probe,
> +	.remove		= wacom_w9000_remove,
> +	.id_table	= wacom_w9000_id,
> +};
> +module_i2c_driver(wacom_w9000_driver);
> +
> +/* Module information */
> +MODULE_AUTHOR("Hendrik Noack <hendrik-noack@gmx.de>");
> +MODULE_DESCRIPTION("Wacom W9000-series penabled touchscreen driver");
> +MODULE_LICENSE("GPL");

Thanks.

-- 
Dmitry

^ permalink raw reply

* [PATCH] HID: hid-asus: Implement fn lock for Asus ProArt P16
From: Connor Belli @ 2025-12-09  0:00 UTC (permalink / raw)
  To: linux-input; +Cc: jikos, bentiss, connorbelli2003

This patch implements support for the fn lock key on the 2025 Asus
ProArt P16. The implementation for this is based on how fn lock is
implemented in the hid-lenovo driver. Unfortunately, I am not too
experienced with driver development, so I'm not sure adding the
handler directly in asus_event is the best solution for this.

Signed-off-by: Connor Belli <connorbelli2003@gmail.com>
---
 drivers/hid/hid-asus.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index a444d41e53b6..402b3e5d1a5c 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -89,6 +89,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
 #define QUIRK_ROG_NKEY_KEYBOARD		BIT(11)
 #define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12)
 #define QUIRK_ROG_ALLY_XPAD		BIT(13)
+#define QUIRK_HID_FN_LOCK		BIT(14)
 
 #define I2C_KEYBOARD_QUIRKS			(QUIRK_FIX_NOTEBOOK_REPORT | \
 						 QUIRK_NO_INIT_REPORTS | \
@@ -132,6 +133,8 @@ struct asus_drvdata {
 	int battery_stat;
 	bool battery_in_query;
 	unsigned long battery_next_query;
+	struct work_struct fn_lock_sync_work;
+	bool fn_lock;
 };
 
 static int asus_report_battery(struct asus_drvdata *, u8 *, int);
@@ -316,6 +319,7 @@ static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size)
 static int asus_event(struct hid_device *hdev, struct hid_field *field,
 		      struct hid_usage *usage, __s32 value)
 {
+	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
 	if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 &&
 	    (usage->hid & HID_USAGE) != 0x00 &&
 	    (usage->hid & HID_USAGE) != 0xff && !usage->type) {
@@ -323,6 +327,12 @@ static int asus_event(struct hid_device *hdev, struct hid_field *field,
 			 usage->hid & HID_USAGE);
 	}
 
+	if (drvdata->quirks & QUIRK_HID_FN_LOCK &&
+		usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) {
+		drvdata->fn_lock = !drvdata->fn_lock;
+		schedule_work(&drvdata->fn_lock_sync_work);
+	}
+
 	return 0;
 }
 
@@ -457,6 +467,21 @@ static int asus_kbd_disable_oobe(struct hid_device *hdev)
 	return 0;
 }
 
+static int asus_kbd_set_fn_lock(struct hid_device *hdev, bool enabled)
+{
+	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xd0, 0x4e, !!enabled };
+
+	return asus_kbd_set_report(hdev, buf, sizeof(buf));
+}
+
+static void asus_sync_fn_lock(struct work_struct *work)
+{
+	struct asus_drvdata *drvdata =
+	container_of(work, struct asus_drvdata, fn_lock_sync_work);
+
+	asus_kbd_set_fn_lock(drvdata->hdev, drvdata->fn_lock);
+}
+
 static void asus_schedule_work(struct asus_kbd_leds *led)
 {
 	unsigned long flags;
@@ -928,6 +953,12 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
 	    asus_kbd_register_leds(hdev))
 		hid_warn(hdev, "Failed to initialize backlight.\n");
 
+	if (drvdata->quirks & QUIRK_HID_FN_LOCK) {
+		drvdata->fn_lock = true;
+		INIT_WORK(&drvdata->fn_lock_sync_work, asus_sync_fn_lock);
+		asus_kbd_set_fn_lock(hdev, true);
+	}
+
 	return 0;
 }
 
@@ -1259,6 +1290,9 @@ static void asus_remove(struct hid_device *hdev)
 		cancel_work_sync(&drvdata->kbd_backlight->work);
 	}
 
+	if (drvdata->quirks & QUIRK_HID_FN_LOCK)
+		cancel_work_sync(&drvdata->fn_lock_sync_work);
+
 	hid_hw_stop(hdev);
 }
 
@@ -1386,7 +1420,7 @@ static const struct hid_device_id asus_devices[] = {
 	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2),
-	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_HID_FN_LOCK },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR),
 	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
-- 
2.52.0


^ permalink raw reply related

* Re: (subset) [PATCH v5 00/11] mfd: macsmc: add rtc, hwmon and hid subdevices
From: Alexandre Belloni @ 2025-12-08 22:09 UTC (permalink / raw)
  To: Sven Peter, Janne Grunau, Alyssa Rosenzweig, Neal Gompa,
	Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jean Delvare, Guenter Roeck, Dmitry Torokhov, Jonathan Corbet,
	James Calligeros
  Cc: asahi, linux-arm-kernel, devicetree, linux-kernel, linux-rtc,
	linux-hwmon, linux-input, linux-doc, Mark Kettenis, Hector Martin
In-Reply-To: <20251112-macsmc-subdevs-v5-0-728e4b91fe81@gmail.com>

On Wed, 12 Nov 2025 21:16:46 +1000, James Calligeros wrote:
> This series adds support for the remaining SMC subdevices. These are the
> RTC, hwmon, and HID devices. They are being submitted together as the RTC
> and hwmon drivers both require changes to the SMC DT schema.
> 
> The RTC driver is responsible for getting and setting the system clock,
> and requires an NVMEM cell. This series replaces Sven's original RTC driver
> submission [1].
> 
> [...]

Applied, thanks!

[01/11] dt-bindings: rtc: Add Apple SMC RTC
        https://git.kernel.org/abelloni/c/07049187e830
[03/11] rtc: Add new rtc-macsmc driver for Apple Silicon Macs
        https://git.kernel.org/abelloni/c/49a51df427db

Best regards,

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* Re: [PATCH v10 05/11] HID: asus: move vendor initialization to probe
From: Ilpo Järvinen @ 2025-12-08 17:11 UTC (permalink / raw)
  To: Antheas Kapenekakis
  Cc: platform-driver-x86, linux-input, LKML, Jiri Kosina,
	Benjamin Tissoires, Corentin Chary, Luke D . Jones, Hans de Goede,
	Denis Benato
In-Reply-To: <20251122110032.4274-6-lkml@antheas.dev>

On Sat, 22 Nov 2025, Antheas Kapenekakis wrote:

> ROG NKEY devices have multiple HID endpoints, around 3-4. One of those
> endpoints has a usage page of 0xff31, and is the one that emits keyboard
> shortcuts and controls RGB/backlight. Currently, this driver places
> the usage page check under asus_input_mapping and then inits backlight
> in asus_input_configured which is unnecessarily complicated and prevents
> probe from performing customizations on the vendor endpoint.
> 
> Simplify the logic by introducing an is_vendor variable into probe that
> checks for usage page 0xff31. Then, use this variable to move backlight
> initialization into probe instead of asus_input_configured, and remove
> the backlight check from asus_input_mapping.

In the changelogs, please add () after any name that refers to a C 
function so the reader immediately knows you're talking about a function.

> Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
> ---
>  drivers/hid/hid-asus.c | 35 ++++++++++++++++++-----------------
>  1 file changed, 18 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> index 2a412e10f916..faac971794c0 100644
> --- a/drivers/hid/hid-asus.c
> +++ b/drivers/hid/hid-asus.c
> @@ -48,6 +48,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
>  #define T100CHI_MOUSE_REPORT_ID 0x06
>  #define FEATURE_REPORT_ID 0x0d
>  #define INPUT_REPORT_ID 0x5d
> +#define HID_USAGE_PAGE_VENDOR 0xff310000
>  #define FEATURE_KBD_REPORT_ID 0x5a
>  #define FEATURE_KBD_REPORT_SIZE 64
>  #define FEATURE_KBD_LED_REPORT_ID1 0x5d
> @@ -127,7 +128,6 @@ struct asus_drvdata {
>  	struct input_dev *tp_kbd_input;
>  	struct asus_kbd_leds *kbd_backlight;
>  	const struct asus_touchpad_info *tp;
> -	bool enable_backlight;
>  	struct power_supply *battery;
>  	struct power_supply_desc battery_desc;
>  	int battery_capacity;
> @@ -318,7 +318,7 @@ static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size)
>  static int asus_event(struct hid_device *hdev, struct hid_field *field,
>  		      struct hid_usage *usage, __s32 value)
>  {
> -	if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 &&
> +	if ((usage->hid & HID_USAGE_PAGE) == HID_USAGE_PAGE_VENDOR &&
>  	    (usage->hid & HID_USAGE) != 0x00 &&
>  	    (usage->hid & HID_USAGE) != 0xff && !usage->type) {
>  		hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n",
> @@ -941,11 +941,6 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
>  
>  	drvdata->input = input;
>  
> -	if (drvdata->enable_backlight &&
> -	    !asus_kbd_wmi_led_control_present(hdev) &&
> -	    asus_kbd_register_leds(hdev))
> -		hid_warn(hdev, "Failed to initialize backlight.\n");
> -
>  	return 0;
>  }
>  
> @@ -1018,15 +1013,6 @@ static int asus_input_mapping(struct hid_device *hdev,
>  			return -1;
>  		}
>  
> -		/*
> -		 * Check and enable backlight only on devices with UsagePage ==
> -		 * 0xff31 to avoid initializing the keyboard firmware multiple
> -		 * times on devices with multiple HID descriptors but same
> -		 * PID/VID.
> -		 */
> -		if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT)
> -			drvdata->enable_backlight = true;
> -
>  		set_bit(EV_REP, hi->input->evbit);
>  		return 1;
>  	}
> @@ -1143,8 +1129,11 @@ static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
>  
>  static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
>  {
> -	int ret;
> +	struct hid_report_enum *rep_enum;
>  	struct asus_drvdata *drvdata;
> +	struct hid_report *rep;
> +	bool is_vendor = false;
> +	int ret;
>  
>  	drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
>  	if (drvdata == NULL) {
> @@ -1228,12 +1217,24 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
>  		return ret;
>  	}
>  
> +	/* Check for vendor for RGB init and handle generic devices properly. */
> +	rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
> +	list_for_each_entry(rep, &rep_enum->report_list, list) {
> +		if ((rep->application & HID_USAGE_PAGE) == HID_USAGE_PAGE_VENDOR)
> +			is_vendor = true;
> +	}
> +
>  	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
>  	if (ret) {
>  		hid_err(hdev, "Asus hw start failed: %d\n", ret);
>  		return ret;
>  	}
>  
> +	if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) &&
> +	    !asus_kbd_wmi_led_control_present(hdev) &&
> +	    asus_kbd_register_leds(hdev))
> +		hid_warn(hdev, "Failed to initialize backlight.\n");
> +
>  	/*
>  	 * Check that input registration succeeded. Checking that
>  	 * HID_CLAIMED_INPUT is set prevents a UAF when all input devices
> 

-- 
 i.


^ permalink raw reply

* Re: [PATCH v10 07/11] platform/x86: asus-wmi: Add support for multiple kbd led handlers
From: Ilpo Järvinen @ 2025-12-08 17:09 UTC (permalink / raw)
  To: Antheas Kapenekakis
  Cc: platform-driver-x86, linux-input, LKML, Jiri Kosina,
	Benjamin Tissoires, Corentin Chary, Luke D . Jones, Hans de Goede,
	Denis Benato
In-Reply-To: <20251122110032.4274-8-lkml@antheas.dev>

On Sat, 22 Nov 2025, Antheas Kapenekakis wrote:

> Some devices, such as the Z13 have multiple Aura devices connected
> to them by USB. In addition, they might have a WMI interface for
> RGB. In Windows, Armoury Crate exposes a unified brightness slider
> for all of them, with 3 brightness levels.
> 
> Therefore, to be synergistic in Linux, and support existing tooling
> such as UPower, allow adding listeners to the RGB device of the WMI
> interface. If WMI does not exist, lazy initialize the interface.
> 
> Since hid-asus and asus-wmi can both interact with the led objects
> including from an atomic context, protect the brightness access with a
> spinlock and update the values from a workqueue. Use this workqueue to
> also process WMI keyboard events, so they are handled asynchronously.
> 
> Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
> ---
>  drivers/platform/x86/asus-wmi.c            | 183 ++++++++++++++++++---
>  include/linux/platform_data/x86/asus-wmi.h |  15 ++
>  2 files changed, 173 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index 64cfc0bf98dd..84cde34ab6a8 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -31,13 +31,13 @@
>  #include <linux/pci.h>
>  #include <linux/pci_hotplug.h>
>  #include <linux/platform_data/x86/asus-wmi.h>
> -#include <linux/platform_data/x86/asus-wmi-leds-ids.h>
>  #include <linux/platform_device.h>
>  #include <linux/platform_profile.h>
>  #include <linux/power_supply.h>
>  #include <linux/rfkill.h>
>  #include <linux/seq_file.h>
>  #include <linux/slab.h>
> +#include <linux/spinlock.h>
>  #include <linux/types.h>
>  #include <linux/units.h>
>  
> @@ -256,6 +256,9 @@ struct asus_wmi {
>  	int tpd_led_wk;
>  	struct led_classdev kbd_led;
>  	int kbd_led_wk;
> +	bool kbd_led_notify;
> +	bool kbd_led_avail;
> +	bool kbd_led_registered;
>  	struct led_classdev lightbar_led;
>  	int lightbar_led_wk;
>  	struct led_classdev micmute_led;
> @@ -264,6 +267,7 @@ struct asus_wmi {
>  	struct work_struct tpd_led_work;
>  	struct work_struct wlan_led_work;
>  	struct work_struct lightbar_led_work;
> +	struct work_struct kbd_led_work;
>  
>  	struct asus_rfkill wlan;
>  	struct asus_rfkill bluetooth;
> @@ -1615,6 +1619,106 @@ static void asus_wmi_battery_exit(struct asus_wmi *asus)
>  
>  /* LEDs ***********************************************************************/
>  
> +struct asus_hid_ref {
> +	struct list_head listeners;
> +	struct asus_wmi *asus;
> +	/* Protects concurrent access from hid-asus and asus-wmi to leds */
> +	spinlock_t lock;
> +};
> +
> +static struct asus_hid_ref asus_ref = {
> +	.listeners = LIST_HEAD_INIT(asus_ref.listeners),
> +	.asus = NULL,
> +	/*
> +	 * Protects .asus, .asus.kbd_led_{wk,notify}, and .listener refs. Other
> +	 * asus variables are read-only after .asus is set.
> +	 *
> +	 * The led cdev device is not protected because it calls backlight_get
> +	 * during initialization, which would result in a nested lock attempt.
> +	 *
> +	 * The led cdev is safe to access without a lock because if
> +	 * kbd_led_avail is true it is initialized before .asus is set and never
> +	 * changed until .asus is dropped. If kbd_led_avail is false, the led

It's actually not as straightforward when it comes to visibility of memory 
writes but you seem to end up being safe because you take the spinlock in 
between so that should ensure kbd_led_avail gets set before .asus is 
assigned. If that wouldn't be there, you'd have needed a memory barrier to 
ensure the writes are guaranteed to be visible in the desired ordering.

> +	 * cdev is registered by the workqueue, which is single-threaded and
> +	 * cancelled before asus-wmi would access the led cdev to unregister it.
> +	 *
> +	 * A spinlock is used, because the protected variables can be accessed
> +	 * from an IRQ context from asus-hid.
> +	 */
> +	.lock = __SPIN_LOCK_UNLOCKED(asus_ref.lock),
> +};
> +
> +/*
> + * Allows registering hid-asus listeners that want to be notified of
> + * keyboard backlight changes.
> + */
> +int asus_hid_register_listener(struct asus_hid_listener *bdev)
> +{
> +	struct asus_wmi *asus;
> +
> +	guard(spinlock_irqsave)(&asus_ref.lock);
> +	list_add_tail(&bdev->list, &asus_ref.listeners);
> +	asus = asus_ref.asus;
> +	if (asus)
> +		queue_work(asus->led_workqueue, &asus->kbd_led_work);
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(asus_hid_register_listener);
> +
> +/*
> + * Allows unregistering hid-asus listeners that were added with
> + * asus_hid_register_listener().
> + */
> +void asus_hid_unregister_listener(struct asus_hid_listener *bdev)
> +{
> +	guard(spinlock_irqsave)(&asus_ref.lock);
> +	list_del(&bdev->list);
> +}
> +EXPORT_SYMBOL_GPL(asus_hid_unregister_listener);
> +
> +static void do_kbd_led_set(struct led_classdev *led_cdev, int value);
> +
> +static void kbd_led_update_all(struct work_struct *work)
> +{
> +	struct asus_wmi *asus;
> +	bool registered, notify;
> +	int ret, value;
> +
> +	asus = container_of(work, struct asus_wmi, kbd_led_work);
> +
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> +		registered = asus->kbd_led_registered;
> +		value = asus->kbd_led_wk;
> +		notify = asus->kbd_led_notify;
> +	}
> +
> +	if (!registered) {
> +		/*
> +		 * This workqueue runs under asus-wmi, which means probe has
> +		 * completed and asus-wmi will keep running until it finishes.
> +		 * Therefore, we can safely register the LED without holding
> +		 * a spinlock.
> +		 */
> +		ret = devm_led_classdev_register(&asus->platform_device->dev,
> +						 &asus->kbd_led);
> +		if (!ret) {
> +			scoped_guard(spinlock_irqsave, &asus_ref.lock)
> +				asus->kbd_led_registered = true;
> +		} else {
> +			pr_warn("Failed to register keyboard backlight LED: %d\n", ret);
> +			return;
> +		}
> +	}
> +
> +	if (value >= 0)
> +		do_kbd_led_set(&asus->kbd_led, value);
> +	if (notify) {
> +		scoped_guard(spinlock_irqsave, &asus_ref.lock)
> +			asus->kbd_led_notify = false;
> +		led_classdev_notify_brightness_hw_changed(&asus->kbd_led, value);
> +	}
> +}
> +
>  /*
>   * These functions actually update the LED's, and are called from a
>   * workqueue. By doing this as separate work rather than when the LED
> @@ -1661,7 +1765,8 @@ static void kbd_led_update(struct asus_wmi *asus)
>  {
>  	int ctrl_param = 0;
>  
> -	ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock)
> +		ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);

Unrelated to this series, it would be nice to name that 0x80 and the 0x7F 
field.

-- 
 i.

>  	asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
>  }
>  
> @@ -1694,14 +1799,23 @@ static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
>  
>  static void do_kbd_led_set(struct led_classdev *led_cdev, int value)
>  {
> +	struct asus_hid_listener *listener;
>  	struct asus_wmi *asus;
>  	int max_level;
>  
>  	asus = container_of(led_cdev, struct asus_wmi, kbd_led);
>  	max_level = asus->kbd_led.max_brightness;
>  
> -	asus->kbd_led_wk = clamp_val(value, 0, max_level);
> -	kbd_led_update(asus);
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock)
> +		asus->kbd_led_wk = clamp_val(value, 0, max_level);
> +
> +	if (asus->kbd_led_avail)
> +		kbd_led_update(asus);
> +
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> +		list_for_each_entry(listener, &asus_ref.listeners, list)
> +			listener->brightness_set(listener, asus->kbd_led_wk);
> +	}
>  }
>  
>  static void kbd_led_set(struct led_classdev *led_cdev,
> @@ -1716,10 +1830,11 @@ static void kbd_led_set(struct led_classdev *led_cdev,
>  
>  static void kbd_led_set_by_kbd(struct asus_wmi *asus, enum led_brightness value)
>  {
> -	struct led_classdev *led_cdev = &asus->kbd_led;
> -
> -	do_kbd_led_set(led_cdev, value);
> -	led_classdev_notify_brightness_hw_changed(led_cdev, asus->kbd_led_wk);
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> +		asus->kbd_led_wk = value;
> +		asus->kbd_led_notify = true;
> +	}
> +	queue_work(asus->led_workqueue, &asus->kbd_led_work);
>  }
>  
>  static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
> @@ -1729,10 +1844,18 @@ static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
>  
>  	asus = container_of(led_cdev, struct asus_wmi, kbd_led);
>  
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> +		if (!asus->kbd_led_avail)
> +			return asus->kbd_led_wk;
> +	}
> +
>  	retval = kbd_led_read(asus, &value, NULL);
>  	if (retval < 0)
>  		return retval;
>  
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock)
> +		asus->kbd_led_wk = value;
> +
>  	return value;
>  }
>  
> @@ -1844,7 +1967,9 @@ static int camera_led_set(struct led_classdev *led_cdev,
>  
>  static void asus_wmi_led_exit(struct asus_wmi *asus)
>  {
> -	led_classdev_unregister(&asus->kbd_led);
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock)
> +		asus_ref.asus = NULL;
> +
>  	led_classdev_unregister(&asus->tpd_led);
>  	led_classdev_unregister(&asus->wlan_led);
>  	led_classdev_unregister(&asus->lightbar_led);
> @@ -1882,22 +2007,26 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
>  			goto error;
>  	}
>  
> -	if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) {
> -		pr_info("using asus-wmi for asus::kbd_backlight\n");
> -		asus->kbd_led_wk = led_val;
> -		asus->kbd_led.name = "asus::kbd_backlight";
> -		asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
> -		asus->kbd_led.brightness_set = kbd_led_set;
> -		asus->kbd_led.brightness_get = kbd_led_get;
> -		asus->kbd_led.max_brightness = 3;
> +	asus->kbd_led.name = "asus::kbd_backlight";
> +	asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
> +	asus->kbd_led.brightness_set = kbd_led_set;
> +	asus->kbd_led.brightness_get = kbd_led_get;
> +	asus->kbd_led.max_brightness = 3;
> +	asus->kbd_led_avail = !kbd_led_read(asus, &led_val, NULL);
> +	INIT_WORK(&asus->kbd_led_work, kbd_led_update_all);
>  
> +	if (asus->kbd_led_avail) {
> +		asus->kbd_led_wk = led_val;
>  		if (num_rgb_groups != 0)
>  			asus->kbd_led.groups = kbd_rgb_mode_groups;
> +	} else {
> +		asus->kbd_led_wk = -1;
> +	}
>  
> -		rv = led_classdev_register(&asus->platform_device->dev,
> -					   &asus->kbd_led);
> -		if (rv)
> -			goto error;
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> +		asus_ref.asus = asus;
> +		if (asus->kbd_led_avail || !list_empty(&asus_ref.listeners))
> +			queue_work(asus->led_workqueue, &asus->kbd_led_work);
>  	}
>  
>  	if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_WIRELESS_LED)
> @@ -4372,6 +4501,7 @@ static int asus_wmi_get_event_code(union acpi_object *obj)
>  
>  static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
>  {
> +	enum led_brightness led_value;
>  	unsigned int key_value = 1;
>  	bool autorelease = 1;
>  
> @@ -4388,19 +4518,22 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
>  		return;
>  	}
>  
> +	scoped_guard(spinlock_irqsave, &asus_ref.lock)
> +		led_value = asus->kbd_led_wk;
> +
>  	if (code == NOTIFY_KBD_BRTUP) {
> -		kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
> +		kbd_led_set_by_kbd(asus, led_value + 1);
>  		return;
>  	}
>  	if (code == NOTIFY_KBD_BRTDWN) {
> -		kbd_led_set_by_kbd(asus, asus->kbd_led_wk - 1);
> +		kbd_led_set_by_kbd(asus, led_value - 1);
>  		return;
>  	}
>  	if (code == NOTIFY_KBD_BRTTOGGLE) {
> -		if (asus->kbd_led_wk == asus->kbd_led.max_brightness)
> +		if (led_value == asus->kbd_led.max_brightness)
>  			kbd_led_set_by_kbd(asus, 0);
>  		else
> -			kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
> +			kbd_led_set_by_kbd(asus, led_value + 1);
>  		return;
>  	}
>  
> diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
> index 419491d4abca..d347cffd05d5 100644
> --- a/include/linux/platform_data/x86/asus-wmi.h
> +++ b/include/linux/platform_data/x86/asus-wmi.h
> @@ -172,12 +172,20 @@ enum asus_ally_mcu_hack {
>  	ASUS_WMI_ALLY_MCU_HACK_DISABLED,
>  };
>  
> +/* Used to notify hid-asus when asus-wmi changes keyboard backlight */
> +struct asus_hid_listener {
> +	struct list_head list;
> +	void (*brightness_set)(struct asus_hid_listener *listener, int brightness);
> +};
> +
>  #if IS_REACHABLE(CONFIG_ASUS_WMI)
>  void set_ally_mcu_hack(enum asus_ally_mcu_hack status);
>  void set_ally_mcu_powersave(bool enabled);
>  int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval);
>  int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval);
>  int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval);
> +int asus_hid_register_listener(struct asus_hid_listener *cdev);
> +void asus_hid_unregister_listener(struct asus_hid_listener *cdev);
>  #else
>  static inline void set_ally_mcu_hack(enum asus_ally_mcu_hack status)
>  {
> @@ -198,6 +206,13 @@ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
>  {
>  	return -ENODEV;
>  }
> +static inline int asus_hid_register_listener(struct asus_hid_listener *bdev)
> +{
> +	return -ENODEV;
> +}
> +static inline void asus_hid_unregister_listener(struct asus_hid_listener *bdev)
> +{
> +}
>  #endif
>  
>  #endif	/* __PLATFORM_DATA_X86_ASUS_WMI_H */
> 

^ permalink raw reply

* Re: Regression: SYNA3602 I2C touchpad broken in Linux 6.17.7 (works in 6.17.6 and previous versions)
From: Thorsten Leemhuis @ 2025-12-08 13:54 UTC (permalink / raw)
  To: Vijay
  Cc: regressions, linux-kernel, linux-input, linux-pm, linux-acpi,
	Benjamin Tissoires, jikos
In-Reply-To: <CAMBhvbZHcOwd-i04TGMXdbvi1vmpnyPD1p7SgkUtjfFsc+9nWQ@mail.gmail.com>

On 12/8/25 13:13, Vijay wrote:
> 
> Yes, the touchpad is not working in 6.18 also, getting the same errors
> as mentioned previously, 

That's really good to know, thx!

Thing is: I fear that nobody will look into this, unless you or somebody
else affected checks which change broke things. Benjamin mentioned three
you could try reverting in 6.17.y; alternatively, perform a bisection in
6.17.y. For details, see:
https://docs.kernel.org/admin-guide/verify-bugs-and-bisect-regressions.html

Ciao, Thorsten


> On Thu, 4 Dec 2025 at 20:40, Thorsten Leemhuis
> <regressions@leemhuis.info <mailto:regressions@leemhuis.info>> wrote:
> 
>     Lo!
> 
>     @AM Vijay: 6.17.y will be EOL in about ten days, so this is unlikely to
>     get fixed there. The big question is:
> 
>     Is 6.18 affected?
> 
>     If it is, we need your help identifying want went wrong; if not, then
>     it's likely not worth looking closer into this
> 
>     Ciao, Thorsten
> 
>     On 11/28/25 09:05, Benjamin Tissoires wrote:
>     > Hi,
>     >
>     > On Fri, Nov 28, 2025 at 7:40 AM Vijay <vijayg0127@gmail.com
>     <mailto:vijayg0127@gmail.com>> wrote:
>     >>
>     >> Hello,
>     >>
>     >> I would like to report a regression in the Linux kernel affecting
>     I2C-HID
>     >> touchpads that run through the Intel ISH + DesignWare I2C controller.
>     >>
>     >> Hardware:
>     >> - Laptop: Infinix Y4 Max
>     >> - CPU: Intel (13th gen core i5)
>     >> - Touchpad: SYNA3602:00 093A:35ED (I2C HID)
>     >> - Bus path: SYNA3602 → i2c_designware → Intel ISH → HID
>     >> - OS: Linux (Arch/CachyOS)
>     >> - Kernel config: Default distro config
>     >>
>     >> Regression summary:
>     >> - Touchpad works perfectly in Linux 6.17.6 and below versions
>     >> - Touchpad stops working in Linux 6.17.7 and all newer versions
>     (6.17.8, 6.17.9, etc.)
>     >> - Desktop environment does not matter (Hyprland/GNOME both fail)
>     >> - The failure happens before userspace loads
>     >> - Touchpad also works fine in Linux 6.12 LTS
>     >>
>     >> This is a kernel-level regression introduced between:
>     >>     Good: Linux 6.17.6
>     >>     Bad:  Linux 6.17.7
>     >>
>     >> **Dmesg logs from broken kernel (6.17.7 and newer):**
>     >>
>     >>     i2c-SYNA3602:00: can't add hid device: -110
>     >>     hid_sensor_hub: reading report descriptor failed
>     >>     intel-hid INTC1078:00: failed to enable HID power button
>     >
>     > Looks like i2c-hid can't even communicate with any I2C device, so this
>     > is slightly worrying.
>     >
>     >>
>     >> And the DesignWare I2C controller logs around the failure:
>     >>     i2c_designware 0000:00:15.0: controller timed out
>     >>     i2c_designware 0000:00:15.0: lost arbitration
>     >>     i2c_designware 0000:00:15.0: transfer aborted (status = -110)
>     >>
>     >> These errors appear only on 6.17.7+ and not on 6.17.6.
>     >>
>     >> On working versions (6.17.6 and 6.12 LTS), the touchpad
>     initializes normally:
>     >>
>     >>     input: SYNA3602:00 093A:35ED Touchpad as /devices/.../input/
>     inputX
>     >>     hid-multitouch: I2C HID v1.00 device initialized
>     >>     i2c_designware 0000:00:15.0: controller operating normally
>     >>
>     >> This narrow regression window should make it possible to identify
>     the offending
>     >> change in either:
>     >> - HID core
>     >> - I2C-HID
>     >> - Intel ISH HID
>     >> - DesignWare I2C controller
>     >> - ACPI timing changes
>     >>
>     >> I can provide:
>     >> - Full dmesg (working and broken)
>     >> - acpidump
>     >
>     > Are you running on a full vanilla kernel?
>     >
>     > The changelog between 6.17.6 and 6.17.7 is rather small, so it should
>     > be easy enough to bisect and get the offending commit.
>     >
>     > I have my suspicions on:
>     > f1971d5ba2ef ("genirq/manage: Add buslock back in to enable_irq()")
>     > b990b4c6ea6b ("genirq/manage: Add buslock back in to
>     __disable_irq_nosync()")
>     > 3c97437239df ("genirq/chip: Add buslock back in to irq_set_handler()")
>     >
>     > Because anything else is unrelated to any component involved in
>     i2c-hid.
>     > (But that's also assuming you are running vanilla kernels without any
>     > extra patches.)
>     >
>     > OTOH, I've booted a 6.17.8 and 6.17.7 shipped by Fedora and I don't
>     > see any issues related to i2c-hid, so those 3 commits might not be the
>     > culprits.
>     >
>     >
>     >>
>     >> Please let me know what additional data is needed.
>     >
>     > Can you do a bisect between v6.17.7 and v6.17.6?
>     >
>     > Cheers,
>     > Benjamin
>     >
>     >>
>     >> Thank you,
>     >> Vijay.
>     >
>     >
>     >
> 


^ permalink raw reply

* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
From: Romain Gantois @ 2025-12-08  8:57 UTC (permalink / raw)
  To: Guenter Roeck, Jonathan Cameron
  Cc: H. Nikolaus Schaller, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, David Lechner, Nuno Sá,
	Andy Shevchenko, Thomas Petazzoni, linux-kernel, devicetree,
	linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi, Peter Rosin,
	Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich, Kevin Tsai,
	Linus Walleij, Dmitry Torokhov, Eugen Hristev, Vinod Koul,
	Kishon Vijay Abraham I, Sebastian Reichel, Chen-Yu Tsai,
	Support Opensource, Paul Cercueil, Iskren Chernev,
	Marek Szyprowski, Matheus Castello, Saravanan Sekar,
	Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
	Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
	Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
	Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
	Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
	Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
	linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
	linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
	linux-stm32, Andy Shevchenko
In-Reply-To: <20251207184818.2ad7cef7@jic23-huawei>


[-- Attachment #1.1: Type: text/plain, Size: 2582 bytes --]

On Sunday, 7 December 2025 19:48:18 CET Jonathan Cameron wrote:
> On Tue, 25 Nov 2025 08:37:20 -0800
> 
> Guenter Roeck <linux@roeck-us.net> wrote:
> > On 11/25/25 02:25, H. Nikolaus Schaller wrote:
> > ...
> > 
> > > Another suggestion: what extending the "regulator-fixed",
> > > "regulator-gpio",
> > > "regulator-fixed-clock" pattern by some
> > > "regulator-gpio-iio-dac-current-limiter" driver to make it independent
> > > of your specific chip?
> > 
> > The name is terrible ;-), but that is what I would have suggested as well.
> > I don't see anything chip specific in this code. If there is a need for
> > a regulator driver which uses gpio to enable it and a DAC for current
> > limiting, it should be made generic.
> 
> Agreed - something generic is the ideal way to go.
> 
> However, before going too far it is worth exploring what are common circuits
> with these things to identify what parameters we need to describe how the
> DAC channel is used - e.g is linear scaling enough?  You'll need to that to
> define a DT binding. If it turns out to be too complex, then fallback to
> specific compatibles in a generic driver to cover the ones that don't fit
> with a common scheme.  A similar case we already have is discrete
> components as analog front ends for ADCs - mostly they fall into a few
> categories and we have drivers covering those, but some are very odd indeed
> and for those ones we do have a driver even though they don't have anything
> to control as such - most extreme case being when it's a non linear analog
> sensor.
> 

I actually did use a modified version of iio-rescale in my downstream code. My 
use case includes an OpAmp inverter circuit placed in front of a DAC, and it's 
useful for me to be able to describe this in a modular fashion, as two IIO 
device tree nodes representing respectively the DAC and the OpAmp circuit 
front-end.

Moreover, the LTM8054 takes a voltage on its CTL pin and infers a current 
limit from it. This is also something which could be represented as a sort of 
AFE node.

 LTM8054 output voltage control:           
+---+ +------------+ +--------------------+
|DAC+->Inverter AFE+->Feedback circuit AFE|
+---+ +------------+ +--------------------+
                                           
 LTM8054 output current limit control:     
+---+ +--------------------+               
|DAC+->Voltage-controller  |               
+---+ |current limiter AFE |               
      +--------------------+               

Thanks,

-- 
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #1.2: Type: text/html, Size: 7606 bytes --]

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH] HID: validate report length and constants
From: Benjamin Tissoires @ 2025-12-08  8:54 UTC (permalink / raw)
  To: Davide Beatrici
  Cc: Terry Junge, linux-kernel, linux-input, jikos, benjamin.tissoires
In-Reply-To: <8aefde3322ab7676034cae9d291fc5b6@davidebeatrici.dev>

On Dec 05 2025, Davide Beatrici wrote:
> > report 8 has csize=16 rsize=16
> > report 0 has csize=1 rsize=8
> > report 0 is too short, (1 < 8)
> > 
> > Which means we do enter the test and execute the memset()...
> 
> I added further debug prints to trace the flow after that:
> 
> hid-generic 0003:373B:1107.000F: report 8 has csize=16 rsize=16
> hid-generic 0003:373B:1107.000F: Calling hiddev_report_event()
> hid-generic 0003:373B:1107.000F: Calling hidraw_report_event()
> hid-generic 0003:373B:1107.000F: Calling hid_process_report()
> hid-generic 0003:373B:1107.000F: Calling hidinput_report_event()
> hid-generic 0003:373B:1107.000E: report 0 has csize=1 rsize=8
> hid-generic 0003:373B:1107.000E: report 0 is too short, (1 < 8)
> hid-generic 0003:373B:1107.000E: Calling hidraw_report_event()
> hid-generic 0003:373B:1107.000E: Calling hid_process_report()
> hid-generic 0003:373B:1107.000E: Calling hidinput_report_event()
> hid-generic 0003:373B:1107.0010: report 0 has csize=7 rsize=7
> hid-generic 0003:373B:1107.0010: Calling hidraw_report_event()
> hid-generic 0003:373B:1107.0010: Calling hid_process_report()
> hid-generic 0003:373B:1107.0010: Calling hidinput_report_event()
> 
> The last report is a normal mouse movement.

Thanks for the logs.

So the most conservative change should be to either:
- have a HID-BPF program that strips out reports of size 1
- have a new kernel driver for this device which maps to .raw_event()
	and rejects reports of size 1.

AFAICT, all the transport drivers are allocating the buffer with enough
space, so the memset should be safe, meaning that we can not enforce
the size to be at least the report size without risking of breaking
devices as this code has been around for a while.

IMO, the simplest is the HID-BPF route, as it's a matter of going to the
udev-hid-bpf project [1], add your program in the testing dir, and
submit a merge request. This way your device will be fixed and I'll
eventually take care of putting the HID-BPF program in
drivers/hid/bpf/progs so it gets installed in all distributions.


Cheers,
Benjamin

[1] https://gitlab.freedesktop.org/libevdev/udev-hid-bpf

^ permalink raw reply

* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
From: Jonathan Cameron @ 2025-12-07 18:48 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: H. Nikolaus Schaller, Romain Gantois, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, David Lechner,
	Nuno Sá, Andy Shevchenko, Thomas Petazzoni, linux-kernel,
	devicetree, linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
	Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
	Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
	Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
	Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
	Marek Szyprowski, Matheus Castello, Saravanan Sekar,
	Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
	Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
	Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
	Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
	Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
	Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
	linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
	linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
	linux-stm32, Andy Shevchenko
In-Reply-To: <9b43da0b-61e1-49bb-acc2-392de3817db7@roeck-us.net>

On Tue, 25 Nov 2025 08:37:20 -0800
Guenter Roeck <linux@roeck-us.net> wrote:

> On 11/25/25 02:25, H. Nikolaus Schaller wrote:
> ...
> > Another suggestion: what extending the "regulator-fixed", "regulator-gpio",
> > "regulator-fixed-clock" pattern by some "regulator-gpio-iio-dac-current-limiter"
> > driver to make it independent of your specific chip?
> >   
> The name is terrible ;-), but that is what I would have suggested as well.
> I don't see anything chip specific in this code. If there is a need for
> a regulator driver which uses gpio to enable it and a DAC for current limiting,
> it should be made generic.

Agreed - something generic is the ideal way to go.

However, before going too far it is worth exploring what are common circuits with
these things to identify what parameters we need to describe how the DAC channel
is used - e.g is linear scaling enough?  You'll need to that to define a DT
binding. If it turns out to be too complex, then fallback to specific
compatibles in a generic driver to cover the ones that don't fit with a common
scheme.  A similar case we already have is discrete components as analog front
ends for ADCs - mostly they fall into a few categories and we have drivers
covering those, but some are very odd indeed and for those ones we do have a
driver even though they don't have anything to control as such - most extreme
case being when it's a non linear analog sensor. 

The mention of a DAC as part of the analog feedback circuit sounds harder
too generalise but that's specific to this particular buck-boost device,
it's board specific so probably doesn't change the above.

> 
> > By the way, are you aware of this feature of the regulator-gpio driver?
> > 
> > https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/regulator/gpio-regulator.c#L97
> > 
> > Just to note: I am neither maintainer nor doing any decisions on this, just asking
> > questions for curiosity and from experience and giving hints for alternative approaches,
> > where I hope they help to find the really best solution.
> >   
> Same here.

Only covering the thing you are consuming so not my problem to maintain either ;)

Jonathan

> 
> Thanks,
> Guenter
> 


^ permalink raw reply

* Re: [PATCH] MAINTAINERS: Change Linus Walleij mail address
From: Jonathan Cameron @ 2025-12-07 14:04 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Bartosz Golaszewski, linux-kernel, linux-gpio, linux-iio,
	linux-input, dri-devel, linux-arm-kernel
In-Reply-To: <20251130-linusw-kernelorg-email-v1-1-bcdbff7b896c@kernel.org>

On Sun, 30 Nov 2025 17:14:45 +0100
Linus Walleij <linusw@kernel.org> wrote:

> I will be using my kernel.org mail address going forward.
> 
> There is no point in splitting this MAINTAINERS patch up
> per subsystem, I will just include it with the rest of my
> patches to pin control in the next merge window.

Trivial but wrap a tiny bit short of the normal 75 chars.

> 
> Signed-off-by: Linus Walleij <linusw@kernel.org>

FWIW
Acked-by: Jonathan Cameron <jonathan.cameron@huawei.com> #for-iio

Good opportunity to say thanks for all your effort in a broad range
of places!

Jonathan

> ---
>  MAINTAINERS | 58 +++++++++++++++++++++++++++++-----------------------------
>  1 file changed, 29 insertions(+), 29 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 181a58ec4a8d..13f61acdc8f7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -195,7 +195,7 @@ F:	drivers/pinctrl/pinctrl-upboard.c
>  F:	include/linux/mfd/upboard-fpga.h
>  
>  AB8500 BATTERY AND CHARGER DRIVERS
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  F:	Documentation/devicetree/bindings/power/supply/*ab8500*
>  F:	drivers/power/supply/*ab8500*
>  
> @@ -2045,7 +2045,7 @@ F:	Documentation/devicetree/bindings/display/arm,hdlcd.yaml
>  F:	drivers/gpu/drm/arm/hdlcd_*
>  
>  ARM INTEGRATOR, VERSATILE AND REALVIEW SUPPORT
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/arm/arm,integrator.yaml
> @@ -2203,7 +2203,7 @@ F:	Documentation/devicetree/bindings/memory-controllers/arm,pl35x-smc.yaml
>  F:	drivers/memory/pl353-smc.c
>  
>  ARM PRIMECELL SSP PL022 SPI DRIVER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/spi/spi-pl022.yaml
> @@ -2216,7 +2216,7 @@ F:	drivers/tty/serial/amba-pl01*.c
>  F:	include/linux/amba/serial.h
>  
>  ARM PRIMECELL VIC PL190/PL192 DRIVER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/interrupt-controller/arm,vic.yaml
> @@ -2633,7 +2633,7 @@ F:	tools/perf/util/cs-etm.*
>  
>  ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE
>  M:	Hans Ulli Kroll <ulli.kroll@googlemail.com>
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
>  S:	Maintained
>  T:	git https://github.com/ulli-kroll/linux.git
> @@ -3035,7 +3035,7 @@ F:	include/dt-bindings/clock/mstar-*
>  F:	include/dt-bindings/gpio/msc313-gpio.h
>  
>  ARM/NOMADIK/Ux500 ARCHITECTURES
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
>  S:	Maintained
>  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
> @@ -3732,7 +3732,7 @@ F:	Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml
>  F:	drivers/media/i2c/ak7375.c
>  
>  ASAHI KASEI AK8974 DRIVER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-iio@vger.kernel.org
>  S:	Supported
>  W:	http://www.akm.com/
> @@ -6758,7 +6758,7 @@ S:	Maintained
>  F:	drivers/pinctrl/pinctrl-cy8c95x0.c
>  
>  CYPRESS CY8CTMA140 TOUCHSCREEN DRIVER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-input@vger.kernel.org
>  S:	Maintained
>  F:	drivers/input/touchscreen/cy8ctma140.c
> @@ -6778,13 +6778,13 @@ Q:	http://patchwork.linuxtv.org/project/linux-media/list/
>  F:	drivers/media/common/cypress_firmware*
>  
>  CYTTSP TOUCHSCREEN DRIVER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-input@vger.kernel.org
>  S:	Maintained
>  F:	drivers/input/touchscreen/cyttsp*
>  
>  D-LINK DIR-685 TOUCHKEYS DRIVER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-input@vger.kernel.org
>  S:	Supported
>  F:	drivers/input/keyboard/dlink-dir685-touchkeys.c
> @@ -7653,13 +7653,13 @@ T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	drivers/gpu/drm/tiny/appletbdrm.c
>  
>  DRM DRIVER FOR ARM PL111 CLCD
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	drivers/gpu/drm/pl111/
>  
>  DRM DRIVER FOR ARM VERSATILE TFT PANELS
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml
> @@ -7709,7 +7709,7 @@ F:	Documentation/devicetree/bindings/display/panel/ebbg,ft8719.yaml
>  F:	drivers/gpu/drm/panel/panel-ebbg-ft8719.c
>  
>  DRM DRIVER FOR FARADAY TVE200 TV ENCODER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	drivers/gpu/drm/tve200/
> @@ -7903,14 +7903,14 @@ F:	include/dt-bindings/clock/qcom,dsi-phy-28nm.h
>  F:	include/uapi/drm/msm_drm.h
>  
>  DRM DRIVER FOR NOVATEK NT35510 PANELS
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml
>  F:	drivers/gpu/drm/panel/panel-novatek-nt35510.c
>  
>  DRM DRIVER FOR NOVATEK NT35560 PANELS
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml
> @@ -8028,7 +8028,7 @@ F:	Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml
>  F:	drivers/gpu/drm/panel/panel-raydium-rm67191.c
>  
>  DRM DRIVER FOR SAMSUNG DB7430 PANELS
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml
> @@ -8112,7 +8112,7 @@ F:	Documentation/devicetree/bindings/display/solomon,ssd13*.yaml
>  F:	drivers/gpu/drm/solomon/ssd130x*
>  
>  DRM DRIVER FOR ST-ERICSSON MCDE
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	Documentation/devicetree/bindings/display/ste,mcde.yaml
> @@ -8144,7 +8144,7 @@ F:	Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml
>  F:	drivers/gpu/drm/bridge/ti-sn65dsi86.c
>  
>  DRM DRIVER FOR TPO TPG110 PANELS
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	Documentation/devicetree/bindings/display/panel/tpo,tpg110.yaml
> @@ -8188,7 +8188,7 @@ F:	drivers/gpu/drm/vmwgfx/
>  F:	include/uapi/drm/vmwgfx_drm.h
>  
>  DRM DRIVER FOR WIDECHIPS WS2401 PANELS
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
>  F:	Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml
> @@ -9482,7 +9482,7 @@ F:	include/linux/fanotify.h
>  F:	include/uapi/linux/fanotify.h
>  
>  FARADAY FOTG210 USB2 DUAL-ROLE CONTROLLER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-usb@vger.kernel.org
>  S:	Maintained
>  F:	drivers/usb/fotg210/
> @@ -10669,7 +10669,7 @@ F:	drivers/gpio/gpio-sloppy-logic-analyzer.c
>  F:	tools/gpio/gpio-sloppy-logic-analyzer.sh
>  
>  GPIO SUBSYSTEM
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  M:	Bartosz Golaszewski <brgl@bgdev.pl>
>  L:	linux-gpio@vger.kernel.org
>  S:	Maintained
> @@ -13033,7 +13033,7 @@ F:	Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
>  F:	drivers/iio/imu/inv_icm42600/
>  
>  INVENSENSE MPU-3050 GYROSCOPE DRIVER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-iio@vger.kernel.org
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml
> @@ -13948,7 +13948,7 @@ F:	drivers/auxdisplay/ks0108.c
>  F:	include/linux/ks0108.h
>  
>  KTD253 BACKLIGHT DRIVER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/leds/backlight/kinetic,ktd253.yaml
>  F:	drivers/video/backlight/ktd253-backlight.c
> @@ -14159,7 +14159,7 @@ F:	drivers/ata/pata_arasan_cf.c
>  F:	include/linux/pata_arasan_cf_data.h
>  
>  LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-ide@vger.kernel.org
>  S:	Maintained
>  F:	drivers/ata/pata_ftide010.c
> @@ -19663,7 +19663,7 @@ F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
>  F:	drivers/pci/controller/dwc/*imx6*
>  
>  PCI DRIVER FOR INTEL IXP4XX
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml
>  F:	drivers/pci/controller/pci-ixp4xx.c
> @@ -19774,7 +19774,7 @@ F:	drivers/pci/controller/cadence/pci-j721e.c
>  F:	drivers/pci/controller/dwc/pci-dra7xx.c
>  
>  PCI DRIVER FOR V3 SEMICONDUCTOR V360EPC
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-pci@vger.kernel.org
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/pci/v3,v360epc-pci.yaml
> @@ -20219,7 +20219,7 @@ K:	(?i)clone3
>  K:	\b(clone_args|kernel_clone_args)\b
>  
>  PIN CONTROL SUBSYSTEM
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-gpio@vger.kernel.org
>  S:	Maintained
>  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git
> @@ -21631,7 +21631,7 @@ F:	Documentation/devicetree/bindings/watchdog/realtek,otto-wdt.yaml
>  F:	drivers/watchdog/realtek_otto_wdt.c
>  
>  REALTEK RTL83xx SMI DSA ROUTER CHIPS
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  M:	Alvin Šipraga <alsi@bang-olufsen.dk>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/net/dsa/realtek.yaml
> @@ -23384,7 +23384,7 @@ S:	Supported
>  F:	net/smc/
>  
>  SHARP GP2AP002A00F/GP2AP002S00F SENSOR DRIVER
> -M:	Linus Walleij <linus.walleij@linaro.org>
> +M:	Linus Walleij <linusw@kernel.org>
>  L:	linux-iio@vger.kernel.org
>  S:	Maintained
>  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git
> 
> ---
> base-commit: 6156424a7d001cceeafe59b52209d6f36719b51d
> change-id: 20251130-linusw-kernelorg-email-0791125070f4
> 
> Best regards,


^ permalink raw reply

* Re: [PATCH] iio: inkern: Use namespaced exports
From: Jonathan Cameron @ 2025-12-07 14:01 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Romain Gantois, MyungJoo Ham, Chanwoo Choi, Guenter Roeck,
	Peter Rosin, David Lechner, Nuno Sá, Andy Shevchenko,
	Lars-Peter Clausen, Michael Hennerich, Mariel Tinaco, Kevin Tsai,
	Linus Walleij, Dmitry Torokhov, Eugen Hristev, Vinod Koul,
	Kishon Vijay Abraham I, Chen-Yu Tsai, Hans de Goede,
	Support Opensource, Paul Cercueil, Iskren Chernev,
	Krzysztof Kozlowski, Marek Szyprowski, Matheus Castello,
	Saravanan Sekar, Matthias Brugger, AngeloGioacchino Del Regno,
	Casey Connolly, Pali Rohár, Orson Zhai, Baolin Wang,
	Chunyan Zhang, Amit Kucheria, Thara Gopinath, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Claudiu Beznea,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Sylwester Nawrocki, Olivier Moysan, Arnaud Pouliquen,
	Maxime Coquelin, Alexandre Torgue, Thomas Petazzoni, linux-kernel,
	linux-hwmon, linux-iio, linux-input, linux-phy, linux-pm,
	linux-mips, linux-mediatek, linux-arm-msm, linux-sound,
	linux-stm32
In-Reply-To: <g7bgtp5p6s55cbpvw7nrpc7gkhwvmmwqfdiau6orsxu652vo5u@cemulnvsyjah>

On Mon, 1 Dec 2025 21:29:34 +0100
Sebastian Reichel <sebastian.reichel@collabora.com> wrote:

> Hi,
> 
> On Mon, Dec 01, 2025 at 11:59:43AM +0100, Romain Gantois wrote:
> > Use namespaced exports for IIO consumer API functions.
> > 
> > Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
> > ---  
> 
> The commit message is missing why this change is being done.
> 
> Otherwise I expect this will flow through the IIO tree. I think it
> should be done via an immutable branch in case new drivers will be
> added during the same development cycle.
Sure. I'll spin an immutable branch on rc1 once updated patch series
and rc1 are available.

Romain, thanks for doing this btw!

Jonathan

> 
> With better commit description:
> 
> Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com> # for power-supply
> 
> Greetings,
> 
> -- Sebastian
> 
> >  drivers/extcon/extcon-adc-jack.c                |  1 +
> >  drivers/hwmon/iio_hwmon.c                       |  1 +
> >  drivers/hwmon/ntc_thermistor.c                  |  1 +
> >  drivers/iio/adc/envelope-detector.c             |  1 +
> >  drivers/iio/afe/iio-rescale.c                   |  1 +
> >  drivers/iio/buffer/industrialio-buffer-cb.c     |  1 +
> >  drivers/iio/buffer/industrialio-hw-consumer.c   |  1 +
> >  drivers/iio/dac/ad8460.c                        |  1 +
> >  drivers/iio/dac/dpot-dac.c                      |  1 +
> >  drivers/iio/dac/ds4424.c                        |  2 +-
> >  drivers/iio/inkern.c                            | 54 ++++++++++++-------------
> >  drivers/iio/light/cm3605.c                      |  1 +
> >  drivers/iio/light/gp2ap002.c                    |  1 +
> >  drivers/iio/multiplexer/iio-mux.c               |  1 +
> >  drivers/iio/potentiostat/lmp91000.c             |  1 +
> >  drivers/input/joystick/adc-joystick.c           |  1 +
> >  drivers/input/keyboard/adc-keys.c               |  1 +
> >  drivers/input/touchscreen/colibri-vf50-ts.c     |  1 +
> >  drivers/input/touchscreen/resistive-adc-touch.c |  1 +
> >  drivers/phy/motorola/phy-cpcap-usb.c            |  1 +
> >  drivers/power/supply/ab8500_btemp.c             |  1 +
> >  drivers/power/supply/ab8500_charger.c           |  1 +
> >  drivers/power/supply/ab8500_fg.c                |  1 +
> >  drivers/power/supply/axp20x_ac_power.c          |  1 +
> >  drivers/power/supply/axp20x_battery.c           |  1 +
> >  drivers/power/supply/axp20x_usb_power.c         |  1 +
> >  drivers/power/supply/axp288_fuel_gauge.c        |  1 +
> >  drivers/power/supply/cpcap-battery.c            |  1 +
> >  drivers/power/supply/cpcap-charger.c            |  1 +
> >  drivers/power/supply/da9150-charger.c           |  1 +
> >  drivers/power/supply/generic-adc-battery.c      |  1 +
> >  drivers/power/supply/ingenic-battery.c          |  1 +
> >  drivers/power/supply/intel_dc_ti_battery.c      |  1 +
> >  drivers/power/supply/lego_ev3_battery.c         |  1 +
> >  drivers/power/supply/lp8788-charger.c           |  1 +
> >  drivers/power/supply/max17040_battery.c         |  1 +
> >  drivers/power/supply/mp2629_charger.c           |  1 +
> >  drivers/power/supply/mt6370-charger.c           |  1 +
> >  drivers/power/supply/qcom_smbx.c                |  1 +
> >  drivers/power/supply/rn5t618_power.c            |  1 +
> >  drivers/power/supply/rx51_battery.c             |  1 +
> >  drivers/power/supply/sc27xx_fuel_gauge.c        |  1 +
> >  drivers/power/supply/twl4030_charger.c          |  1 +
> >  drivers/power/supply/twl4030_madc_battery.c     |  1 +
> >  drivers/power/supply/twl6030_charger.c          |  1 +
> >  drivers/thermal/qcom/qcom-spmi-adc-tm5.c        |  1 +
> >  drivers/thermal/qcom/qcom-spmi-temp-alarm.c     |  1 +
> >  drivers/thermal/renesas/rzg3s_thermal.c         |  1 +
> >  drivers/thermal/thermal-generic-adc.c           |  1 +
> >  sound/soc/codecs/audio-iio-aux.c                |  1 +
> >  sound/soc/samsung/aries_wm8994.c                |  1 +
> >  sound/soc/samsung/midas_wm1811.c                |  1 +
> >  sound/soc/stm/stm32_adfsdm.c                    |  1 +
> >  53 files changed, 79 insertions(+), 28 deletions(-)
> > 
> > diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c
> > index 7e3c9f38297b..e735f43dcdeb 100644
> > --- a/drivers/extcon/extcon-adc-jack.c
> > +++ b/drivers/extcon/extcon-adc-jack.c
> > @@ -210,3 +210,4 @@ module_platform_driver(adc_jack_driver);
> >  MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
> >  MODULE_DESCRIPTION("ADC Jack extcon driver");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c
> > index e376d4cde5ad..4c7843fbcc50 100644
> > --- a/drivers/hwmon/iio_hwmon.c
> > +++ b/drivers/hwmon/iio_hwmon.c
> > @@ -222,3 +222,4 @@ module_platform_driver(iio_hwmon_driver);
> >  MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
> >  MODULE_DESCRIPTION("IIO to hwmon driver");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c
> > index d21f7266c411..417807fad80b 100644
> > --- a/drivers/hwmon/ntc_thermistor.c
> > +++ b/drivers/hwmon/ntc_thermistor.c
> > @@ -706,3 +706,4 @@ MODULE_DESCRIPTION("NTC Thermistor Driver");
> >  MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
> >  MODULE_LICENSE("GPL");
> >  MODULE_ALIAS("platform:ntc-thermistor");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/adc/envelope-detector.c b/drivers/iio/adc/envelope-detector.c
> > index 5b16fe737659..fea20e7e6cd9 100644
> > --- a/drivers/iio/adc/envelope-detector.c
> > +++ b/drivers/iio/adc/envelope-detector.c
> > @@ -406,3 +406,4 @@ module_platform_driver(envelope_detector_driver);
> >  MODULE_DESCRIPTION("Envelope detector using a DAC and a comparator");
> >  MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/afe/iio-rescale.c b/drivers/iio/afe/iio-rescale.c
> > index ecaf59278c6f..d7f55109af3e 100644
> > --- a/drivers/iio/afe/iio-rescale.c
> > +++ b/drivers/iio/afe/iio-rescale.c
> > @@ -609,3 +609,4 @@ module_platform_driver(rescale_driver);
> >  MODULE_DESCRIPTION("IIO rescale driver");
> >  MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c
> > index 3e27385069ed..608ea9afc15a 100644
> > --- a/drivers/iio/buffer/industrialio-buffer-cb.c
> > +++ b/drivers/iio/buffer/industrialio-buffer-cb.c
> > @@ -153,3 +153,4 @@ EXPORT_SYMBOL_GPL(iio_channel_cb_get_iio_dev);
> >  MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
> >  MODULE_DESCRIPTION("Industrial I/O callback buffer");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/buffer/industrialio-hw-consumer.c b/drivers/iio/buffer/industrialio-hw-consumer.c
> > index 526b2a8d725d..d7ff086ed783 100644
> > --- a/drivers/iio/buffer/industrialio-hw-consumer.c
> > +++ b/drivers/iio/buffer/industrialio-hw-consumer.c
> > @@ -211,3 +211,4 @@ EXPORT_SYMBOL_GPL(iio_hw_consumer_disable);
> >  MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
> >  MODULE_DESCRIPTION("Hardware consumer buffer the IIO framework");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/dac/ad8460.c b/drivers/iio/dac/ad8460.c
> > index 6e45686902dd..ad654819ca22 100644
> > --- a/drivers/iio/dac/ad8460.c
> > +++ b/drivers/iio/dac/ad8460.c
> > @@ -955,3 +955,4 @@ MODULE_AUTHOR("Mariel Tinaco <mariel.tinaco@analog.com");
> >  MODULE_DESCRIPTION("AD8460 DAC driver");
> >  MODULE_LICENSE("GPL");
> >  MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/dac/dpot-dac.c b/drivers/iio/dac/dpot-dac.c
> > index d1b8441051ae..49dbdb7df955 100644
> > --- a/drivers/iio/dac/dpot-dac.c
> > +++ b/drivers/iio/dac/dpot-dac.c
> > @@ -254,3 +254,4 @@ module_platform_driver(dpot_dac_driver);
> >  MODULE_DESCRIPTION("DAC emulation driver using a digital potentiometer");
> >  MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c
> > index a8198ba4f98a..33d6692f46fe 100644
> > --- a/drivers/iio/dac/ds4424.c
> > +++ b/drivers/iio/dac/ds4424.c
> > @@ -14,7 +14,6 @@
> >  #include <linux/iio/iio.h>
> >  #include <linux/iio/driver.h>
> >  #include <linux/iio/machine.h>
> > -#include <linux/iio/consumer.h>
> >  
> >  #define DS4422_MAX_DAC_CHANNELS		2
> >  #define DS4424_MAX_DAC_CHANNELS		4
> > @@ -321,3 +320,4 @@ MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");
> >  MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");
> >  MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
> > index 1e5eb5a41271..c75c3a8d233f 100644
> > --- a/drivers/iio/inkern.c
> > +++ b/drivers/iio/inkern.c
> > @@ -281,7 +281,7 @@ struct iio_channel *fwnode_iio_channel_get_by_name(struct fwnode_handle *fwnode,
> >  
> >  	return ERR_PTR(-ENODEV);
> >  }
> > -EXPORT_SYMBOL_GPL(fwnode_iio_channel_get_by_name);
> > +EXPORT_SYMBOL_NS_GPL(fwnode_iio_channel_get_by_name, "IIO_CONSUMER");
> >  
> >  static struct iio_channel *fwnode_iio_channel_get_all(struct device *dev)
> >  {
> > @@ -386,7 +386,7 @@ struct iio_channel *iio_channel_get(struct device *dev,
> >  
> >  	return iio_channel_get_sys(name, channel_name);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_channel_get);
> > +EXPORT_SYMBOL_NS_GPL(iio_channel_get, "IIO_CONSUMER");
> >  
> >  void iio_channel_release(struct iio_channel *channel)
> >  {
> > @@ -395,7 +395,7 @@ void iio_channel_release(struct iio_channel *channel)
> >  	iio_device_put(channel->indio_dev);
> >  	kfree(channel);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_channel_release);
> > +EXPORT_SYMBOL_NS_GPL(iio_channel_release, "IIO_CONSUMER");
> >  
> >  static void devm_iio_channel_free(void *iio_channel)
> >  {
> > @@ -418,7 +418,7 @@ struct iio_channel *devm_iio_channel_get(struct device *dev,
> >  
> >  	return channel;
> >  }
> > -EXPORT_SYMBOL_GPL(devm_iio_channel_get);
> > +EXPORT_SYMBOL_NS_GPL(devm_iio_channel_get, "IIO_CONSUMER");
> >  
> >  struct iio_channel *devm_fwnode_iio_channel_get_by_name(struct device *dev,
> >  							struct fwnode_handle *fwnode,
> > @@ -437,7 +437,7 @@ struct iio_channel *devm_fwnode_iio_channel_get_by_name(struct device *dev,
> >  
> >  	return channel;
> >  }
> > -EXPORT_SYMBOL_GPL(devm_fwnode_iio_channel_get_by_name);
> > +EXPORT_SYMBOL_NS_GPL(devm_fwnode_iio_channel_get_by_name, "IIO_CONSUMER");
> >  
> >  struct iio_channel *iio_channel_get_all(struct device *dev)
> >  {
> > @@ -506,7 +506,7 @@ struct iio_channel *iio_channel_get_all(struct device *dev)
> >  		iio_device_put(chans[i].indio_dev);
> >  	return ERR_PTR(ret);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_channel_get_all);
> > +EXPORT_SYMBOL_NS_GPL(iio_channel_get_all, "IIO_CONSUMER");
> >  
> >  void iio_channel_release_all(struct iio_channel *channels)
> >  {
> > @@ -518,7 +518,7 @@ void iio_channel_release_all(struct iio_channel *channels)
> >  	}
> >  	kfree(channels);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_channel_release_all);
> > +EXPORT_SYMBOL_NS_GPL(iio_channel_release_all, "IIO_CONSUMER");
> >  
> >  static void devm_iio_channel_free_all(void *iio_channels)
> >  {
> > @@ -541,7 +541,7 @@ struct iio_channel *devm_iio_channel_get_all(struct device *dev)
> >  
> >  	return channels;
> >  }
> > -EXPORT_SYMBOL_GPL(devm_iio_channel_get_all);
> > +EXPORT_SYMBOL_NS_GPL(devm_iio_channel_get_all, "IIO_CONSUMER");
> >  
> >  static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
> >  			    enum iio_chan_info_enum info)
> > @@ -585,7 +585,7 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val)
> >  
> >  	return iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_channel_raw);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_channel_raw, "IIO_CONSUMER");
> >  
> >  int iio_read_channel_average_raw(struct iio_channel *chan, int *val)
> >  {
> > @@ -597,7 +597,7 @@ int iio_read_channel_average_raw(struct iio_channel *chan, int *val)
> >  
> >  	return iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_AVERAGE_RAW);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_channel_average_raw);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_channel_average_raw, "IIO_CONSUMER");
> >  
> >  int iio_multiply_value(int *result, s64 multiplier,
> >  		       unsigned int type, int val, int val2)
> > @@ -701,7 +701,7 @@ int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
> >  	return iio_convert_raw_to_processed_unlocked(chan, raw, processed,
> >  						     scale);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
> > +EXPORT_SYMBOL_NS_GPL(iio_convert_raw_to_processed, "IIO_CONSUMER");
> >  
> >  int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2,
> >  			       enum iio_chan_info_enum attribute)
> > @@ -714,13 +714,13 @@ int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2,
> >  
> >  	return iio_channel_read(chan, val, val2, attribute);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_channel_attribute);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_channel_attribute, "IIO_CONSUMER");
> >  
> >  int iio_read_channel_offset(struct iio_channel *chan, int *val, int *val2)
> >  {
> >  	return iio_read_channel_attribute(chan, val, val2, IIO_CHAN_INFO_OFFSET);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_channel_offset);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_channel_offset, "IIO_CONSUMER");
> >  
> >  int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
> >  				     unsigned int scale)
> > @@ -748,20 +748,20 @@ int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
> >  							     scale);
> >  	}
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_channel_processed_scale);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_channel_processed_scale, "IIO_CONSUMER");
> >  
> >  int iio_read_channel_processed(struct iio_channel *chan, int *val)
> >  {
> >  	/* This is just a special case with scale factor 1 */
> >  	return iio_read_channel_processed_scale(chan, val, 1);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_channel_processed);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_channel_processed, "IIO_CONSUMER");
> >  
> >  int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
> >  {
> >  	return iio_read_channel_attribute(chan, val, val2, IIO_CHAN_INFO_SCALE);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_channel_scale);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_channel_scale, "IIO_CONSUMER");
> >  
> >  static int iio_channel_read_avail(struct iio_channel *chan,
> >  				  const int **vals, int *type, int *length,
> > @@ -790,7 +790,7 @@ int iio_read_avail_channel_attribute(struct iio_channel *chan,
> >  
> >  	return iio_channel_read_avail(chan, vals, type, length, attribute);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_avail_channel_attribute);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_avail_channel_attribute, "IIO_CONSUMER");
> >  
> >  int iio_read_avail_channel_raw(struct iio_channel *chan,
> >  			       const int **vals, int *length)
> > @@ -807,7 +807,7 @@ int iio_read_avail_channel_raw(struct iio_channel *chan,
> >  
> >  	return ret;
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_avail_channel_raw);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_avail_channel_raw, "IIO_CONSUMER");
> >  
> >  static int iio_channel_read_max(struct iio_channel *chan,
> >  				int *val, int *val2, int *type,
> > @@ -863,7 +863,7 @@ int iio_read_max_channel_raw(struct iio_channel *chan, int *val)
> >  
> >  	return iio_channel_read_max(chan, val, NULL, &type, IIO_CHAN_INFO_RAW);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_max_channel_raw);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_max_channel_raw, "IIO_CONSUMER");
> >  
> >  static int iio_channel_read_min(struct iio_channel *chan,
> >  				int *val, int *val2, int *type,
> > @@ -919,7 +919,7 @@ int iio_read_min_channel_raw(struct iio_channel *chan, int *val)
> >  
> >  	return iio_channel_read_min(chan, val, NULL, &type, IIO_CHAN_INFO_RAW);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_min_channel_raw);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_min_channel_raw, "IIO_CONSUMER");
> >  
> >  int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type)
> >  {
> > @@ -933,7 +933,7 @@ int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type)
> >  
> >  	return 0;
> >  }
> > -EXPORT_SYMBOL_GPL(iio_get_channel_type);
> > +EXPORT_SYMBOL_NS_GPL(iio_get_channel_type, "IIO_CONSUMER");
> >  
> >  static int iio_channel_write(struct iio_channel *chan, int val, int val2,
> >  			     enum iio_chan_info_enum info)
> > @@ -957,13 +957,13 @@ int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2,
> >  
> >  	return iio_channel_write(chan, val, val2, attribute);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_write_channel_attribute);
> > +EXPORT_SYMBOL_NS_GPL(iio_write_channel_attribute, "IIO_CONSUMER");
> >  
> >  int iio_write_channel_raw(struct iio_channel *chan, int val)
> >  {
> >  	return iio_write_channel_attribute(chan, val, 0, IIO_CHAN_INFO_RAW);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_write_channel_raw);
> > +EXPORT_SYMBOL_NS_GPL(iio_write_channel_raw, "IIO_CONSUMER");
> >  
> >  unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan)
> >  {
> > @@ -978,7 +978,7 @@ unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan)
> >  
> >  	return i;
> >  }
> > -EXPORT_SYMBOL_GPL(iio_get_channel_ext_info_count);
> > +EXPORT_SYMBOL_NS_GPL(iio_get_channel_ext_info_count, "IIO_CONSUMER");
> >  
> >  static const struct iio_chan_spec_ext_info *
> >  iio_lookup_ext_info(const struct iio_channel *chan, const char *attr)
> > @@ -1013,7 +1013,7 @@ ssize_t iio_read_channel_ext_info(struct iio_channel *chan,
> >  	return ext_info->read(chan->indio_dev, ext_info->private,
> >  			      chan->channel, buf);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_channel_ext_info);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_channel_ext_info, "IIO_CONSUMER");
> >  
> >  ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr,
> >  				   const char *buf, size_t len)
> > @@ -1027,7 +1027,7 @@ ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr,
> >  	return ext_info->write(chan->indio_dev, ext_info->private,
> >  			       chan->channel, buf, len);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_write_channel_ext_info);
> > +EXPORT_SYMBOL_NS_GPL(iio_write_channel_ext_info, "IIO_CONSUMER");
> >  
> >  ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf)
> >  {
> > @@ -1038,4 +1038,4 @@ ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf)
> >  
> >  	return do_iio_read_channel_label(chan->indio_dev, chan->channel, buf);
> >  }
> > -EXPORT_SYMBOL_GPL(iio_read_channel_label);
> > +EXPORT_SYMBOL_NS_GPL(iio_read_channel_label, "IIO_CONSUMER");
> > diff --git a/drivers/iio/light/cm3605.c b/drivers/iio/light/cm3605.c
> > index 0c17378e27d1..1bd11292d005 100644
> > --- a/drivers/iio/light/cm3605.c
> > +++ b/drivers/iio/light/cm3605.c
> > @@ -325,3 +325,4 @@ module_platform_driver(cm3605_driver);
> >  MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
> >  MODULE_DESCRIPTION("CM3605 ambient light and proximity sensor driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c
> > index a0d8a58f2704..04b1f6eade0e 100644
> > --- a/drivers/iio/light/gp2ap002.c
> > +++ b/drivers/iio/light/gp2ap002.c
> > @@ -717,3 +717,4 @@ module_i2c_driver(gp2ap002_driver);
> >  MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
> >  MODULE_DESCRIPTION("GP2AP002 ambient light and proximity sensor driver");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c
> > index b742ca9a99d1..e193913f5af7 100644
> > --- a/drivers/iio/multiplexer/iio-mux.c
> > +++ b/drivers/iio/multiplexer/iio-mux.c
> > @@ -464,3 +464,4 @@ module_platform_driver(mux_driver);
> >  MODULE_DESCRIPTION("IIO multiplexer driver");
> >  MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c
> > index eccc2a34358f..7d993f2acda4 100644
> > --- a/drivers/iio/potentiostat/lmp91000.c
> > +++ b/drivers/iio/potentiostat/lmp91000.c
> > @@ -423,3 +423,4 @@ module_i2c_driver(lmp91000_driver);
> >  MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
> >  MODULE_DESCRIPTION("LMP91000 digital potentiostat");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/input/joystick/adc-joystick.c b/drivers/input/joystick/adc-joystick.c
> > index ff44f9978b71..4fa42f88bcfa 100644
> > --- a/drivers/input/joystick/adc-joystick.c
> > +++ b/drivers/input/joystick/adc-joystick.c
> > @@ -329,3 +329,4 @@ module_platform_driver(adc_joystick_driver);
> >  MODULE_DESCRIPTION("Input driver for joysticks connected over ADC");
> >  MODULE_AUTHOR("Artur Rojek <contact@artur-rojek.eu>");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/input/keyboard/adc-keys.c b/drivers/input/keyboard/adc-keys.c
> > index f1753207429d..d687459a0c80 100644
> > --- a/drivers/input/keyboard/adc-keys.c
> > +++ b/drivers/input/keyboard/adc-keys.c
> > @@ -202,3 +202,4 @@ module_platform_driver(adc_keys_driver);
> >  MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
> >  MODULE_DESCRIPTION("Input driver for resistor ladder connected on ADC");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c
> > index 98d5b2ba63fb..89c4d7b2b89e 100644
> > --- a/drivers/input/touchscreen/colibri-vf50-ts.c
> > +++ b/drivers/input/touchscreen/colibri-vf50-ts.c
> > @@ -372,3 +372,4 @@ module_platform_driver(vf50_touch_driver);
> >  MODULE_AUTHOR("Sanchayan Maity");
> >  MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/input/touchscreen/resistive-adc-touch.c b/drivers/input/touchscreen/resistive-adc-touch.c
> > index 7e761ec73273..2fefd652864c 100644
> > --- a/drivers/input/touchscreen/resistive-adc-touch.c
> > +++ b/drivers/input/touchscreen/resistive-adc-touch.c
> > @@ -301,3 +301,4 @@ module_platform_driver(grts_driver);
> >  MODULE_AUTHOR("Eugen Hristev <eugen.hristev@microchip.com>");
> >  MODULE_DESCRIPTION("Generic ADC Resistive Touch Driver");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
> > index 7cb020dd3423..9591672b0511 100644
> > --- a/drivers/phy/motorola/phy-cpcap-usb.c
> > +++ b/drivers/phy/motorola/phy-cpcap-usb.c
> > @@ -717,3 +717,4 @@ MODULE_ALIAS("platform:cpcap_usb");
> >  MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
> >  MODULE_DESCRIPTION("CPCAP usb phy driver");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c
> > index e5202a7b6209..36b0c52a4b8b 100644
> > --- a/drivers/power/supply/ab8500_btemp.c
> > +++ b/drivers/power/supply/ab8500_btemp.c
> > @@ -829,3 +829,4 @@ MODULE_LICENSE("GPL v2");
> >  MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy");
> >  MODULE_ALIAS("platform:ab8500-btemp");
> >  MODULE_DESCRIPTION("AB8500 battery temperature driver");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c
> > index 5f4537766e5b..6e49d1b28254 100644
> > --- a/drivers/power/supply/ab8500_charger.c
> > +++ b/drivers/power/supply/ab8500_charger.c
> > @@ -3751,3 +3751,4 @@ MODULE_LICENSE("GPL v2");
> >  MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy");
> >  MODULE_ALIAS("platform:ab8500-charger");
> >  MODULE_DESCRIPTION("AB8500 charger management driver");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c
> > index 9dd99722667a..5fa559f796aa 100644
> > --- a/drivers/power/supply/ab8500_fg.c
> > +++ b/drivers/power/supply/ab8500_fg.c
> > @@ -3252,3 +3252,4 @@ MODULE_LICENSE("GPL v2");
> >  MODULE_AUTHOR("Johan Palsson, Karl Komierowski");
> >  MODULE_ALIAS("platform:ab8500-fg");
> >  MODULE_DESCRIPTION("AB8500 Fuel Gauge driver");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/axp20x_ac_power.c b/drivers/power/supply/axp20x_ac_power.c
> > index 5f6ea416fa30..e9049d6229df 100644
> > --- a/drivers/power/supply/axp20x_ac_power.c
> > +++ b/drivers/power/supply/axp20x_ac_power.c
> > @@ -421,3 +421,4 @@ module_platform_driver(axp20x_ac_power_driver);
> >  MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
> >  MODULE_DESCRIPTION("AXP20X and AXP22X PMICs' AC power supply driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
> > index 50ca8e110085..ee8701a6e907 100644
> > --- a/drivers/power/supply/axp20x_battery.c
> > +++ b/drivers/power/supply/axp20x_battery.c
> > @@ -1155,3 +1155,4 @@ module_platform_driver(axp20x_batt_driver);
> >  MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs");
> >  MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
> > index e75d1e377ac1..599adcf84968 100644
> > --- a/drivers/power/supply/axp20x_usb_power.c
> > +++ b/drivers/power/supply/axp20x_usb_power.c
> > @@ -1080,3 +1080,4 @@ module_platform_driver(axp20x_usb_power_driver);
> >  MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
> >  MODULE_DESCRIPTION("AXP20x PMIC USB power supply status driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c
> > index a3d71fc72064..c6897dd808fc 100644
> > --- a/drivers/power/supply/axp288_fuel_gauge.c
> > +++ b/drivers/power/supply/axp288_fuel_gauge.c
> > @@ -817,3 +817,4 @@ MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>");
> >  MODULE_AUTHOR("Todd Brandt <todd.e.brandt@linux.intel.com>");
> >  MODULE_DESCRIPTION("Xpower AXP288 Fuel Gauge Driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c
> > index 8106d1edcbc2..542c3c70e3cb 100644
> > --- a/drivers/power/supply/cpcap-battery.c
> > +++ b/drivers/power/supply/cpcap-battery.c
> > @@ -1176,3 +1176,4 @@ module_platform_driver(cpcap_battery_driver);
> >  MODULE_LICENSE("GPL v2");
> >  MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
> >  MODULE_DESCRIPTION("CPCAP PMIC Battery Driver");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c
> > index d0c3008db534..89bc0fc3c9f8 100644
> > --- a/drivers/power/supply/cpcap-charger.c
> > +++ b/drivers/power/supply/cpcap-charger.c
> > @@ -977,3 +977,4 @@ MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
> >  MODULE_DESCRIPTION("CPCAP Battery Charger Interface driver");
> >  MODULE_LICENSE("GPL v2");
> >  MODULE_ALIAS("platform:cpcap-charger");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/da9150-charger.c b/drivers/power/supply/da9150-charger.c
> > index 27f36ef5b88d..58449df6068c 100644
> > --- a/drivers/power/supply/da9150-charger.c
> > +++ b/drivers/power/supply/da9150-charger.c
> > @@ -644,3 +644,4 @@ module_platform_driver(da9150_charger_driver);
> >  MODULE_DESCRIPTION("Charger Driver for DA9150");
> >  MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c
> > index f5f2566b3a32..d18c8ee40405 100644
> > --- a/drivers/power/supply/generic-adc-battery.c
> > +++ b/drivers/power/supply/generic-adc-battery.c
> > @@ -298,3 +298,4 @@ module_platform_driver(gab_driver);
> >  MODULE_AUTHOR("anish kumar <yesanishhere@gmail.com>");
> >  MODULE_DESCRIPTION("generic battery driver using IIO");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/ingenic-battery.c b/drivers/power/supply/ingenic-battery.c
> > index b111c7ce2be3..5be269f17bff 100644
> > --- a/drivers/power/supply/ingenic-battery.c
> > +++ b/drivers/power/supply/ingenic-battery.c
> > @@ -190,3 +190,4 @@ module_platform_driver(ingenic_battery_driver);
> >  MODULE_DESCRIPTION("Battery driver for Ingenic JZ47xx SoCs");
> >  MODULE_AUTHOR("Artur Rojek <contact@artur-rojek.eu>");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/intel_dc_ti_battery.c b/drivers/power/supply/intel_dc_ti_battery.c
> > index 56b0c92e9d28..1a16ded563bc 100644
> > --- a/drivers/power/supply/intel_dc_ti_battery.c
> > +++ b/drivers/power/supply/intel_dc_ti_battery.c
> > @@ -387,3 +387,4 @@ MODULE_ALIAS("platform:" DEV_NAME);
> >  MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>");
> >  MODULE_DESCRIPTION("Intel Dollar Cove (TI) battery driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/lego_ev3_battery.c b/drivers/power/supply/lego_ev3_battery.c
> > index 28454de05761..414816662b06 100644
> > --- a/drivers/power/supply/lego_ev3_battery.c
> > +++ b/drivers/power/supply/lego_ev3_battery.c
> > @@ -231,3 +231,4 @@ module_platform_driver(lego_ev3_battery_driver);
> >  MODULE_LICENSE("GPL");
> >  MODULE_AUTHOR("David Lechner <david@lechnology.com>");
> >  MODULE_DESCRIPTION("LEGO MINDSTORMS EV3 Battery Driver");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
> > index f0a680c155c4..8c6ec98362d0 100644
> > --- a/drivers/power/supply/lp8788-charger.c
> > +++ b/drivers/power/supply/lp8788-charger.c
> > @@ -727,3 +727,4 @@ MODULE_DESCRIPTION("TI LP8788 Charger Driver");
> >  MODULE_AUTHOR("Milo Kim");
> >  MODULE_LICENSE("GPL");
> >  MODULE_ALIAS("platform:lp8788-charger");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c
> > index c1640bc6accd..1fe658bfecc1 100644
> > --- a/drivers/power/supply/max17040_battery.c
> > +++ b/drivers/power/supply/max17040_battery.c
> > @@ -635,3 +635,4 @@ module_i2c_driver(max17040_i2c_driver);
> >  MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
> >  MODULE_DESCRIPTION("MAX17040 Fuel Gauge");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/mp2629_charger.c b/drivers/power/supply/mp2629_charger.c
> > index d281c1059629..ed49f9a04c8c 100644
> > --- a/drivers/power/supply/mp2629_charger.c
> > +++ b/drivers/power/supply/mp2629_charger.c
> > @@ -660,3 +660,4 @@ module_platform_driver(mp2629_charger_driver);
> >  MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>");
> >  MODULE_DESCRIPTION("MP2629 Charger driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/mt6370-charger.c b/drivers/power/supply/mt6370-charger.c
> > index e6db961d5818..2d02fdf37d70 100644
> > --- a/drivers/power/supply/mt6370-charger.c
> > +++ b/drivers/power/supply/mt6370-charger.c
> > @@ -941,3 +941,4 @@ module_platform_driver(mt6370_chg_driver);
> >  MODULE_AUTHOR("ChiaEn Wu <chiaen_wu@richtek.com>");
> >  MODULE_DESCRIPTION("MediaTek MT6370 Charger Driver");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/qcom_smbx.c b/drivers/power/supply/qcom_smbx.c
> > index b1cb925581ec..63b88754155c 100644
> > --- a/drivers/power/supply/qcom_smbx.c
> > +++ b/drivers/power/supply/qcom_smbx.c
> > @@ -1050,3 +1050,4 @@ module_platform_driver(qcom_spmi_smb);
> >  MODULE_AUTHOR("Casey Connolly <casey.connolly@linaro.org>");
> >  MODULE_DESCRIPTION("Qualcomm SMB2 Charger Driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/rn5t618_power.c b/drivers/power/supply/rn5t618_power.c
> > index 40dec55a9f73..a3f30e390c11 100644
> > --- a/drivers/power/supply/rn5t618_power.c
> > +++ b/drivers/power/supply/rn5t618_power.c
> > @@ -821,3 +821,4 @@ module_platform_driver(rn5t618_power_driver);
> >  MODULE_ALIAS("platform:rn5t618-power");
> >  MODULE_DESCRIPTION("Power supply driver for RICOH RN5T618");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/rx51_battery.c b/drivers/power/supply/rx51_battery.c
> > index b0220ec2d926..57266921dc8e 100644
> > --- a/drivers/power/supply/rx51_battery.c
> > +++ b/drivers/power/supply/rx51_battery.c
> > @@ -246,3 +246,4 @@ MODULE_ALIAS("platform:rx51-battery");
> >  MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");
> >  MODULE_DESCRIPTION("Nokia RX-51 battery driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c
> > index a7ed9de8a289..1719ec4173e6 100644
> > --- a/drivers/power/supply/sc27xx_fuel_gauge.c
> > +++ b/drivers/power/supply/sc27xx_fuel_gauge.c
> > @@ -1350,3 +1350,4 @@ module_platform_driver(sc27xx_fgu_driver);
> >  
> >  MODULE_DESCRIPTION("Spreadtrum SC27XX PMICs Fual Gauge Unit Driver");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/twl4030_charger.c b/drivers/power/supply/twl4030_charger.c
> > index 04216b2bfb6c..151f7b24e9b9 100644
> > --- a/drivers/power/supply/twl4030_charger.c
> > +++ b/drivers/power/supply/twl4030_charger.c
> > @@ -1144,3 +1144,4 @@ MODULE_AUTHOR("Gražvydas Ignotas");
> >  MODULE_DESCRIPTION("TWL4030 Battery Charger Interface driver");
> >  MODULE_LICENSE("GPL");
> >  MODULE_ALIAS("platform:twl4030_bci");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/twl4030_madc_battery.c b/drivers/power/supply/twl4030_madc_battery.c
> > index 3935162e350b..9b3785d1643c 100644
> > --- a/drivers/power/supply/twl4030_madc_battery.c
> > +++ b/drivers/power/supply/twl4030_madc_battery.c
> > @@ -237,3 +237,4 @@ MODULE_LICENSE("GPL");
> >  MODULE_AUTHOR("Lukas Märdian <lukas@goldelico.com>");
> >  MODULE_DESCRIPTION("twl4030_madc battery driver");
> >  MODULE_ALIAS("platform:twl4030_madc_battery");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/power/supply/twl6030_charger.c b/drivers/power/supply/twl6030_charger.c
> > index b4ec26ff257c..82911a811f4e 100644
> > --- a/drivers/power/supply/twl6030_charger.c
> > +++ b/drivers/power/supply/twl6030_charger.c
> > @@ -579,3 +579,4 @@ module_platform_driver(twl6030_charger_driver);
> >  
> >  MODULE_DESCRIPTION("TWL6030 Battery Charger Interface driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
> > index d7f2e6ca92c2..bb6222c8cc5f 100644
> > --- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
> > +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
> > @@ -1069,3 +1069,4 @@ module_platform_driver(adc_tm5_driver);
> >  
> >  MODULE_DESCRIPTION("SPMI PMIC Thermal Monitor ADC driver");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
> > index f39ca0ddd17b..fb003ca96454 100644
> > --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
> > +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
> > @@ -904,3 +904,4 @@ module_platform_driver(qpnp_tm_driver);
> >  MODULE_ALIAS("platform:spmi-temp-alarm");
> >  MODULE_DESCRIPTION("QPNP PMIC Temperature Alarm driver");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/thermal/renesas/rzg3s_thermal.c b/drivers/thermal/renesas/rzg3s_thermal.c
> > index e25e36c99a88..7ced8f76a0ec 100644
> > --- a/drivers/thermal/renesas/rzg3s_thermal.c
> > +++ b/drivers/thermal/renesas/rzg3s_thermal.c
> > @@ -270,3 +270,4 @@ module_platform_driver(rzg3s_thermal_driver);
> >  MODULE_DESCRIPTION("Renesas RZ/G3S Thermal Sensor Unit Driver");
> >  MODULE_AUTHOR("Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c
> > index 7c844589b153..cfdb8e674dd2 100644
> > --- a/drivers/thermal/thermal-generic-adc.c
> > +++ b/drivers/thermal/thermal-generic-adc.c
> > @@ -228,3 +228,4 @@ module_platform_driver(gadc_thermal_driver);
> >  MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
> >  MODULE_DESCRIPTION("Generic ADC thermal driver using IIO framework with DT");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/sound/soc/codecs/audio-iio-aux.c b/sound/soc/codecs/audio-iio-aux.c
> > index 588e48044c13..864a5a676495 100644
> > --- a/sound/soc/codecs/audio-iio-aux.c
> > +++ b/sound/soc/codecs/audio-iio-aux.c
> > @@ -312,3 +312,4 @@ module_platform_driver(audio_iio_aux_driver);
> >  MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
> >  MODULE_DESCRIPTION("IIO ALSA SoC aux driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c
> > index 3723329b266d..b6f0f3c0d393 100644
> > --- a/sound/soc/samsung/aries_wm8994.c
> > +++ b/sound/soc/samsung/aries_wm8994.c
> > @@ -700,3 +700,4 @@ module_platform_driver(aries_audio_driver);
> >  MODULE_DESCRIPTION("ALSA SoC ARIES WM8994");
> >  MODULE_LICENSE("GPL");
> >  MODULE_ALIAS("platform:aries-audio-wm8994");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/sound/soc/samsung/midas_wm1811.c b/sound/soc/samsung/midas_wm1811.c
> > index 239e958b88d3..12c4962f901d 100644
> > --- a/sound/soc/samsung/midas_wm1811.c
> > +++ b/sound/soc/samsung/midas_wm1811.c
> > @@ -773,3 +773,4 @@ module_platform_driver(midas_driver);
> >  MODULE_AUTHOR("Simon Shields <simon@lineageos.org>");
> >  MODULE_DESCRIPTION("ASoC support for Midas");
> >  MODULE_LICENSE("GPL v2");
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
> > index c914d1c46850..dabcd2759187 100644
> > --- a/sound/soc/stm/stm32_adfsdm.c
> > +++ b/sound/soc/stm/stm32_adfsdm.c
> > @@ -407,3 +407,4 @@ MODULE_DESCRIPTION("stm32 DFSDM DAI driver");
> >  MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
> >  MODULE_LICENSE("GPL v2");
> >  MODULE_ALIAS("platform:" STM32_ADFSDM_DRV_NAME);
> > +MODULE_IMPORT_NS("IIO_CONSUMER");
> > 
> > ---
> > base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
> > change-id: 20251127-iio-inkern-use-namespaced-exports-41fc09223b5e
> > 
> > Best regards,
> > -- 
> > Romain Gantois <romain.gantois@bootlin.com>
> >   


^ permalink raw reply

* Re: [PATCH] iio: inkern: Use namespaced exports
From: Jonathan Cameron @ 2025-12-07 14:00 UTC (permalink / raw)
  To: Romain Gantois
  Cc: MyungJoo Ham, Chanwoo Choi, Guenter Roeck, Peter Rosin,
	Nuno Sá, Andy Shevchenko, Lars-Peter Clausen,
	Michael Hennerich, Mariel Tinaco, Kevin Tsai, Linus Walleij,
	Dmitry Torokhov, Eugen Hristev, Vinod Koul,
	Kishon Vijay Abraham I, Sebastian Reichel, Chen-Yu Tsai,
	Hans de Goede, Support Opensource, Paul Cercueil, Iskren Chernev,
	Krzysztof Kozlowski, Marek Szyprowski, Matheus Castello,
	Saravanan Sekar, Matthias Brugger, AngeloGioacchino Del Regno,
	Casey Connolly, Pali Rohár, Orson Zhai, Baolin Wang,
	Chunyan Zhang, Amit Kucheria, Thara Gopinath, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Claudiu Beznea,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Sylwester Nawrocki, Olivier Moysan, Arnaud Pouliquen,
	Maxime Coquelin, Alexandre Torgue, David Lechner,
	Thomas Petazzoni, linux-kernel, linux-hwmon, linux-iio,
	linux-input, linux-phy, linux-pm, linux-mips, linux-mediatek,
	linux-arm-msm, linux-sound, linux-stm32
In-Reply-To: <5948030.DvuYhMxLoT@fw-rgant>

On Tue, 02 Dec 2025 08:30:58 +0100
Romain Gantois <romain.gantois@bootlin.com> wrote:

> On Monday, 1 December 2025 18:15:54 CET David Lechner wrote:
> > On 12/1/25 4:59 AM, Romain Gantois wrote:  
> > > Use namespaced exports for IIO consumer API functions.
> > > 
> > > Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
> > > ---  
> > 
> > ...
> >   
> > > diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c
> > > index a8198ba4f98a..33d6692f46fe 100644
> > > --- a/drivers/iio/dac/ds4424.c
> > > +++ b/drivers/iio/dac/ds4424.c
> > > @@ -14,7 +14,6 @@
> > > 
> > >  #include <linux/iio/iio.h>
> > >  #include <linux/iio/driver.h>
> > >  #include <linux/iio/machine.h>
> > > 
> > > -#include <linux/iio/consumer.h>  
> > 
> > Unrelated change?  
> 
> Indeed, I'll leave that out in v2.

Please spin a precursor patch that makes that change.
That way we can easily check all files either both include that header
and have the namespace enabled, or neither.

I might merge this is a slightly funny way that leave it initially
not meeting that rule so that the precursor isn't in the immutable branch
for other subsystems but lets keep it logical in the patch set!

Jonathan

> 
> > >  #define DS4422_MAX_DAC_CHANNELS		2
> > >  #define DS4424_MAX_DAC_CHANNELS		4
> > > 
> > > @@ -321,3 +320,4 @@ MODULE_AUTHOR("Ismail H. Kose
> > > <ismail.kose@maximintegrated.com>");> 
> > >  MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");
> > >  MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");
> > >  MODULE_LICENSE("GPL v2");
> > > 
> > > +MODULE_IMPORT_NS("IIO_CONSUMER");  
> > 
> > Is this actually needed if we don't use anything from consumer.h?  
> 
> No, it's not.
> 
> Thanks,
> 


^ permalink raw reply

* [PATCH] HID: Elecom: Add support for ELECOM M-XT3DRBK (018C)
From: Arnoud Willemsen @ 2025-12-07  2:43 UTC (permalink / raw)
  To: jikos, bentiss; +Cc: linux-input, linux-kernel, Arnoud Willemsen

Wireless/new version of the Elecom trackball mouse M-XT3DRBK has a
product id that differs from the existing M-XT3DRBK.
The report descriptor format also seems to have changed and matches
other (newer?) models instead (except for six buttons instead of eight).
This patch follows the same format as the patch for the M-XT3URBK (018F)
by Naoki Ueki (Nov 3rd 2025) to enable the sixth mouse button.

dmesg output:
[  292.074664] usb 1-2: new full-speed USB device number 7 using xhci_hcd
[  292.218667] usb 1-2: New USB device found, idVendor=056e, idProduct=018c, bcdDevice= 1.00
[  292.218676] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  292.218679] usb 1-2: Product: ELECOM TrackBall Mouse
[  292.218681] usb 1-2: Manufacturer: ELECOM

usbhid-dump output:
001:006:000:DESCRIPTOR         1765072638.050578
 05 01 09 02 A1 01 09 01 A1 00 85 01 05 09 19 01
 29 05 15 00 25 01 95 08 75 01 81 02 95 01 75 00
 81 01 05 01 09 30 09 31 16 00 80 26 FF 7F 75 10
 95 02 81 06 C0 A1 00 05 01 09 38 15 81 25 7F 75
 08 95 01 81 06 C0 A1 00 05 0C 0A 38 02 95 01 75
 08 15 81 25 7F 81 06 C0 C0 06 01 FF 09 00 A1 01
 85 02 09 00 15 00 26 FF 00 75 08 95 07 81 02 C0
 05 0C 09 01 A1 01 85 05 15 00 26 3C 02 19 00 2A
 3C 02 75 10 95 01 81 00 C0 05 01 09 80 A1 01 85
 03 19 81 29 83 15 00 25 01 95 03 75 01 81 02 95
 01 75 05 81 01 C0 06 BC FF 09 88 A1 01 85 04 95
 01 75 08 15 00 26 FF 00 19 00 2A FF 00 81 00 C0
 06 02 FF 09 02 A1 01 85 06 09 02 15 00 26 FF 00
 75 08 95 07 B1 02 C0

Signed-off-by: Arnoud Willemsen <mail@lynthium.com>
---
 drivers/hid/hid-elecom.c | 15 +++++++++++++--
 drivers/hid/hid-ids.h    |  3 ++-
 drivers/hid/hid-quirks.c |  3 ++-
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
index 981d1b6e9658..2003d2dcda7c 100644
--- a/drivers/hid/hid-elecom.c
+++ b/drivers/hid/hid-elecom.c
@@ -77,7 +77,7 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		break;
 	case USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB:
 	case USB_DEVICE_ID_ELECOM_M_XT3URBK_018F:
-	case USB_DEVICE_ID_ELECOM_M_XT3DRBK:
+	case USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC:
 	case USB_DEVICE_ID_ELECOM_M_XT4DRBK:
 		/*
 		 * Report descriptor format:
@@ -102,6 +102,16 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		 */
 		mouse_button_fixup(hdev, rdesc, *rsize, 12, 30, 14, 20, 8);
 		break;
+	case USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C:
+		/*
+		 * Report descriptor format:
+		 * 22: button bit count
+		 * 30: padding bit count
+		 * 24: button report size
+		 * 16: button usage maximum
+		 */
+		mouse_button_fixup(hdev, rdesc, *rsize, 22, 30, 24, 16, 6);
+		break;
 	case USB_DEVICE_ID_ELECOM_M_DT2DRBK:
 	case USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C:
 		/*
@@ -122,7 +132,8 @@ static const struct hid_device_id elecom_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index d31711f1aaec..e1dbb3107fb3 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -451,7 +451,8 @@
 #define USB_DEVICE_ID_ELECOM_M_XGL20DLBK	0x00e6
 #define USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB	0x00fb
 #define USB_DEVICE_ID_ELECOM_M_XT3URBK_018F	0x018f
-#define USB_DEVICE_ID_ELECOM_M_XT3DRBK	0x00fc
+#define USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC	0x00fc
+#define USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C	0x018c
 #define USB_DEVICE_ID_ELECOM_M_XT4DRBK	0x00fd
 #define USB_DEVICE_ID_ELECOM_M_DT1URBK	0x00fe
 #define USB_DEVICE_ID_ELECOM_M_DT1DRBK	0x00ff
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index c89a015686c0..77e0f3e885b3 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -412,7 +412,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
-- 
2.52.0



^ permalink raw reply related

* [syzbot] [input?] WARNING in cm109_input_open
From: syzbot @ 2025-12-06 18:43 UTC (permalink / raw)
  To: dmitry.torokhov, linux-input, linux-kernel, syzkaller-bugs

Hello,

syzbot found the following issue on:

HEAD commit:    4a26e7032d7d Merge tag 'core-bugs-2025-12-01' of git://git..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=106814c2580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=cabbc708f0a470fb
dashboard link: https://syzkaller.appspot.com/bug?extid=fed3fab8533934671abc
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/41d09ea4104d/disk-4a26e703.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/e8c0f32d0475/vmlinux-4a26e703.xz
kernel image: https://storage.googleapis.com/syzbot-assets/f19b39e18b64/bzImage-4a26e703.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+fed3fab8533934671abc@syzkaller.appspotmail.com

------------[ cut here ]------------
URB ffff88802aa55600 submitted while active
WARNING: drivers/usb/core/urb.c:380 at 0x0, CPU#1: kworker/1:4/5904
Modules linked in:
CPU: 1 UID: 0 PID: 5904 Comm: kworker/1:4 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025
Workqueue: usb_hub_wq hub_event
RIP: 0010:usb_submit_urb+0x7e/0x1890 drivers/usb/core/urb.c:380
Code: 89 f0 48 c1 e8 03 42 80 3c 38 00 74 08 4c 89 f7 e8 97 b3 32 fb 49 83 3e 00 74 36 e8 fc 30 cd fa 48 8d 3d c5 fe 98 08 48 89 de <67> 48 0f b9 3a b8 f0 ff ff ff e9 8b 00 00 00 e8 de 30 cd fa b8 ea
RSP: 0018:ffffc900042deaf0 EFLAGS: 00010287
RAX: ffffffff86f3b5f4 RBX: ffff88802aa55600 RCX: 0000000000100000
RDX: ffffc9001bb8f000 RSI: ffff88802aa55600 RDI: ffffffff8f8cb4c0
RBP: 000000000000000f R08: ffffffff8f801377 R09: 1ffffffff1f0026e
R10: dffffc0000000000 R11: fffffbfff1f0026f R12: 0000000000000cc0
R13: ffff88806f531048 R14: ffff88802aa55608 R15: dffffc0000000000
FS:  0000000000000000(0000) GS:ffff8881261c5000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f9bb61a17e0 CR3: 0000000078b0f000 CR4: 0000000000350ef0
Call Trace:
 <TASK>
 cm109_input_open+0x1fe/0x4b0 drivers/input/misc/cm109.c:566
 input_open_device+0x1d3/0x390 drivers/input/input.c:601
 kbd_connect+0xed/0x140 drivers/tty/vt/keyboard.c:1584
 input_attach_handler drivers/input/input.c:994 [inline]
 input_register_device+0xd00/0x1140 drivers/input/input.c:2378
 cm109_usb_probe+0x118c/0x1690 drivers/input/misc/cm109.c:797
 usb_probe_interface+0x668/0xc30 drivers/usb/core/driver.c:396
 call_driver_probe drivers/base/dd.c:-1 [inline]
 really_probe+0x26d/0x9e0 drivers/base/dd.c:659
 __driver_probe_device+0x18c/0x2f0 drivers/base/dd.c:801
 driver_probe_device+0x4f/0x430 drivers/base/dd.c:831
 __device_attach_driver+0x2ce/0x530 drivers/base/dd.c:959
 bus_for_each_drv+0x251/0x2e0 drivers/base/bus.c:462
 __device_attach+0x2b8/0x400 drivers/base/dd.c:1031
 bus_probe_device+0x185/0x260 drivers/base/bus.c:537
 device_add+0x7b6/0xb50 drivers/base/core.c:3689
 usb_set_configuration+0x1a87/0x20e0 drivers/usb/core/message.c:2210
 usb_generic_driver_probe+0x8d/0x150 drivers/usb/core/generic.c:250
 usb_probe_device+0x1c4/0x390 drivers/usb/core/driver.c:291
 call_driver_probe drivers/base/dd.c:-1 [inline]
 really_probe+0x26d/0x9e0 drivers/base/dd.c:659
 __driver_probe_device+0x18c/0x2f0 drivers/base/dd.c:801
 driver_probe_device+0x4f/0x430 drivers/base/dd.c:831
 __device_attach_driver+0x2ce/0x530 drivers/base/dd.c:959
 bus_for_each_drv+0x251/0x2e0 drivers/base/bus.c:462
 __device_attach+0x2b8/0x400 drivers/base/dd.c:1031
 bus_probe_device+0x185/0x260 drivers/base/bus.c:537
 device_add+0x7b6/0xb50 drivers/base/core.c:3689
 usb_new_device+0xa39/0x16f0 drivers/usb/core/hub.c:2694
 hub_port_connect drivers/usb/core/hub.c:5566 [inline]
 hub_port_connect_change drivers/usb/core/hub.c:5706 [inline]
 port_event drivers/usb/core/hub.c:5870 [inline]
 hub_event+0x2958/0x4a20 drivers/usb/core/hub.c:5952
 process_one_work kernel/workqueue.c:3263 [inline]
 process_scheduled_works+0xad1/0x1770 kernel/workqueue.c:3346
 worker_thread+0x8a0/0xda0 kernel/workqueue.c:3427
 kthread+0x711/0x8a0 kernel/kthread.c:463
 ret_from_fork+0x52d/0xa60 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
 </TASK>
----------------
Code disassembly (best guess):
   0:	89 f0                	mov    %esi,%eax
   2:	48 c1 e8 03          	shr    $0x3,%rax
   6:	42 80 3c 38 00       	cmpb   $0x0,(%rax,%r15,1)
   b:	74 08                	je     0x15
   d:	4c 89 f7             	mov    %r14,%rdi
  10:	e8 97 b3 32 fb       	call   0xfb32b3ac
  15:	49 83 3e 00          	cmpq   $0x0,(%r14)
  19:	74 36                	je     0x51
  1b:	e8 fc 30 cd fa       	call   0xfacd311c
  20:	48 8d 3d c5 fe 98 08 	lea    0x898fec5(%rip),%rdi        # 0x898feec
  27:	48 89 de             	mov    %rbx,%rsi
* 2a:	67 48 0f b9 3a       	ud1    (%edx),%rdi <-- trapping instruction
  2f:	b8 f0 ff ff ff       	mov    $0xfffffff0,%eax
  34:	e9 8b 00 00 00       	jmp    0xc4
  39:	e8 de 30 cd fa       	call   0xfacd311c
  3e:	b8                   	.byte 0xb8
  3f:	ea                   	(bad)


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

^ permalink raw reply

* Re: [PATCH v10 00/11] HID: asus: Fix ASUS ROG Laptop's Keyboard backlight handling
From: Antheas Kapenekakis @ 2025-12-05 23:03 UTC (permalink / raw)
  To: Kelsios
  Cc: platform-driver-x86, linux-input, linux-kernel, Jiri Kosina,
	Benjamin Tissoires, Corentin Chary, Luke D . Jones, Hans de Goede,
	Ilpo Järvinen, Denis Benato
In-Reply-To: <3ec43b6f-a284-4af7-bcae-8aee11929abb@proton.me>

On Fri, 5 Dec 2025 at 23:13, Kelsios <K3lsios@proton.me> wrote:
>
> Hello,
>
> I would like to report a regression affecting keyboard backlight brightness control on my ASUS ROG Zephyrus G16 (model GU605CW).
>
> Using kernel 6.17.9-arch1-1.1-g14 with the latest HID ASUS patchset v10, keyboard *color* control works correctly, but *brightness* control no longer responds at all. The issue is reproducible on every boot. This problem is not present when using patchset v8, where both color and brightness work as expected.
>
> Important detail: the issue occurs even **without** asusctl installed, so it must be within the kernel HID/WMI handling and is unrelated to userspace tools.
>
> Output of dmesg is available here [1], please let me know if any additional information is required.
>
> Thank you for your time and work on supporting these ASUS laptops.
>
> Best regards,
> Kelsios
>
> [1] https://pastebin.com/ZFC13Scf

[ 1.035986] asus 0003:0B05:19B6.0001: Asus failed to receive handshake ack: -32

Oh yeah, asus_kbd_init no longer works with spurious inits so it broke
devices marked with QUIRK_ROG_NKEY_LEGACY

There are three ways to approach this. One is to ignore the error...
second is to drop the quirk... third is to check for the usages for ID1, ID2...

I would tend towards dropping the ID2 init and ignoring the error for
ID1... Unless an EPIPE would cause the device to close

Antheas

> On 11/22/25 1:00 PM, Antheas Kapenekakis wrote:
> > This is a two part series which does the following:
> >   - Clean-up init sequence
> >   - Unify backlight handling to happen under asus-wmi so that all Aura
> >     devices have synced brightness controls and the backlight button works
> >     properly when it is on a USB laptop keyboard instead of one w/ WMI.
> >
> > For more context, see cover letter of V1. Since V5, I removed some patches
> > to make this easier to merge.
> >
> > ---
> > V9: https://lore.kernel.org/all/20251120094617.11672-1-lkml@antheas.dev/
> > V8: https://lore.kernel.org/all/20251101104712.8011-1-lkml@antheas.dev/
> > V7: https://lore.kernel.org/all/20251018101759.4089-1-lkml@antheas.dev/
> > V6: https://lore.kernel.org/all/20251013201535.6737-1-lkml@antheas.dev/
> > V5: https://lore.kernel.org/all/20250325184601.10990-1-lkml@antheas.dev/
> > V4: https://lore.kernel.org/lkml/20250324210151.6042-1-lkml@antheas.dev/
> > V3: https://lore.kernel.org/lkml/20250322102804.418000-1-lkml@antheas.dev/
> > V2: https://lore.kernel.org/all/20250320220924.5023-1-lkml@antheas.dev/
> > V1: https://lore.kernel.org/all/20250319191320.10092-1-lkml@antheas.dev/
> >
> > Changes since V9:
> >   - No functional changes
> >   - Rebase to review-ilpo-next
> >   - Fix armoury series conflict by removing the file asus-wmi-leds-ids on
> >     "remove unused keyboard backlight quirk" + imports
> >     Dismiss Luke's review as this patch diverged
> >   - Reword paragraph in "Add support for multiple kbd led handlers" to be
> >     more verbose
> >   - Use kfree in fortify patch
> >   - Fix minor style quirks from --nonstict checkpatch run
> >
> > Changes since V8:
> >   - No functional changes
> >   - Move legacy init patch to second, modify first patch so that their
> >     diff is minimized
> >   - Split "prevent binding to all HID devices on ROG" into two patches:
> >     - moving backlight initialization into probe
> >     - early exit to skip ->init check and rename
> >     - Remove skipping vendor fixups for non-vendor devices. It is not possible
> >       to read usages before the report fixups are applied, so it did not work
> >   - In that patch, reword a comment to be single line and make is_vendor a bool
> >   - Dismiss Luke's tags from "Add support for multiple kbd led handlers" as it
> >     has drifted too far since he reviewed/tested it.
> >
> > Changes since V7:
> >   - Readd legacy init quirk for Dennis
> >   - Remove HID_QUIRK_INPUT_PER_APP as a courtesy to asusctl
> >   - Fix warning due to enum_backlight receiving negative values
> >
> > Changes since V6:
> >   - Split initialization refactor into three patches, update commit text
> >     to be clearer in what it does
> >   - Replace spinlock accesses with guard and scoped guard in all patches
> >   - Add missing includes mentioned by Ilpo
> >   - Reflow, tweak comment in prevent binding to all HID devices on ROG
> >   - Replace asus_ref.asus with local reference in all patches
> >   - Add missing kernel doc comments
> >   - Other minor nits from Ilpo
> >   - User reported warning due to scheduling work while holding a spinlock.
> >     Restructure patch for multiple handlers to limit when spinlock is held to
> >     variable access only. In parallel, setup a workqueue to handle registration
> >     of led device and setting brightness. This is required as registering the
> >     led device triggers kbd_led_get which needs to hold the spinlock to
> >     protect the led_wk value. The workqueue is also required for the hid
> >     event passthrough to avoid scheduling work while holding the spinlock.
> >     Apply the workqueue to wmi brightness buttons as well, as that was
> >     omitted before this series and WMI access was performed.
> >   - On "HID: asus: prevent binding to all HID devices on ROG", rename
> >     quirk HANDLE_GENERIC to SKIP_REPORT_FIXUP and only skip report fixup.
> >     This allows other quirks to apply (applies quirk that fixes keyboard
> >     being named as a pointer device).
> >
> > Changes since V5:
> >   - It's been a long time
> >   - Remove addition of RGB as that had some comments I need to work on
> >   - Remove folio patch (already merged)
> >   - Remove legacy fix patch 11 from V4. There is a small chance that
> >     without this patch, some old NKEY keyboards might not respond to
> >     RGB commands according to Luke, but the kernel driver does not do
> >     RGB currently. The 0x5d init is done by Armoury crate software in
> >     Windows. If an issue is found, we can re-add it or just remove patches
> >     1/2 before merging. However, init could use the cleanup.
> >
> > Changes since V4:
> >   - Fix KConfig (reported by kernel robot)
> >   - Fix Ilpo's nits, if I missed anything lmk
> >
> > Changes since V3:
> >   - Add initializer for 0x5d for old NKEY keyboards until it is verified
> >     that it is not needed for their media keys to function.
> >   - Cover init in asus-wmi with spinlock as per Hans
> >   - If asus-wmi registers WMI handler with brightness, init the brightness
> >     in USB Asus keyboards, per Hans.
> >   - Change hid handler name to asus-UNIQ:rgb:peripheral to match led class
> >   - Fix oops when unregistering asus-wmi by moving unregister outside of
> >     the spin lock (but after the asus reference is set to null)
> >
> > Changes since V2:
> >   - Check lazy init succeds in asus-wmi before setting register variable
> >   - make explicit check in asus_hid_register_listener for listener existing
> >     to avoid re-init
> >   - rename asus_brt to asus_hid in most places and harmonize everything
> >   - switch to a spinlock instead of a mutex to avoid kernel ooops
> >   - fixup hid device quirks to avoid multiple RGB devices while still exposing
> >     all input vendor devices. This includes moving rgb init to probe
> >     instead of the input_configured callbacks.
> >   - Remove fan key (during retest it appears to be 0xae that is already
> >     supported by hid-asus)
> >   - Never unregister asus::kbd_backlight while asus-wmi is active, as that
> >   - removes fds from userspace and breaks backlight functionality. All
> >   - current mainline drivers do not support backlight hotplugging, so most
> >     userspace software (e.g., KDE, UPower) is built with that assumption.
> >     For the Ally, since it disconnects its controller during sleep, this
> >     caused the backlight slider to not work in KDE.
> >
> > Changes since V1:
> >   - Add basic RGB support on hid-asus, (Z13/Ally) tested in KDE/Z13
> >   - Fix ifdef else having an invalid signature (reported by kernel robot)
> >   - Restore input arguments to init and keyboard function so they can
> >     be re-used for RGB controls.
> >   - Remove Z13 delay (it did not work to fix the touchpad) and replace it
> >     with a HID_GROUP_GENERIC quirk to allow hid-multitouch to load. Squash
> >     keyboard rename into it.
> >   - Unregister brightness listener before removing work queue to avoid
> >     a race condition causing corruption
> >   - Remove spurious mutex unlock in asus_brt_event
> >   - Place mutex lock in kbd_led_set after LED_UNREGISTERING check to avoid
> >     relocking the mutex and causing a deadlock when unregistering leds
> >   - Add extra check during unregistering to avoid calling unregister when
> >     no led device is registered.
> >   - Temporarily HID_QUIRK_INPUT_PER_APP from the ROG endpoint as it causes
> >     the driver to create 4 RGB handlers per device. I also suspect some
> >     extra events sneak through (KDE had the @@@@@@).
> >
> > Antheas Kapenekakis (11):
> >   HID: asus: simplify RGB init sequence
> >   HID: asus: initialize additional endpoints only for legacy devices
> >   HID: asus: use same report_id in response
> >   HID: asus: fortify keyboard handshake
> >   HID: asus: move vendor initialization to probe
> >   HID: asus: early return for ROG devices
> >   platform/x86: asus-wmi: Add support for multiple kbd led handlers
> >   HID: asus: listen to the asus-wmi brightness device instead of
> >     creating one
> >   platform/x86: asus-wmi: remove unused keyboard backlight quirk
> >   platform/x86: asus-wmi: add keyboard brightness event handler
> >   HID: asus: add support for the asus-wmi brightness handler
> >
> >  drivers/hid/hid-asus.c                        | 205 ++++++++--------
> >  drivers/platform/x86/asus-wmi.c               | 223 +++++++++++++++---
> >  .../platform_data/x86/asus-wmi-leds-ids.h     |  50 ----
> >  include/linux/platform_data/x86/asus-wmi.h    |  28 +++
> >  4 files changed, 322 insertions(+), 184 deletions(-)
> >  delete mode 100644 include/linux/platform_data/x86/asus-wmi-leds-ids.h
> >
> >
> > base-commit: 2643187ccb8628144246ee9d44da5e3ac428f9c3
>
>
>


^ permalink raw reply

* Re: [PATCH v10 00/11] HID: asus: Fix ASUS ROG Laptop's Keyboard backlight handling
From: Antheas Kapenekakis @ 2025-12-05 23:04 UTC (permalink / raw)
  To: Kelsios
  Cc: platform-driver-x86, linux-input, linux-kernel, Jiri Kosina,
	Benjamin Tissoires, Corentin Chary, Luke D . Jones, Hans de Goede,
	Ilpo Järvinen, Denis Benato
In-Reply-To: <CAGwozwEeZ5KKZWvhC1i-jS5Yike5gVeFK0yyu56L2-e5JvmsPQ@mail.gmail.com>

On Sat, 6 Dec 2025 at 00:03, Antheas Kapenekakis <lkml@antheas.dev> wrote:
>
> On Fri, 5 Dec 2025 at 23:13, Kelsios <K3lsios@proton.me> wrote:
> >
> > Hello,
> >
> > I would like to report a regression affecting keyboard backlight brightness control on my ASUS ROG Zephyrus G16 (model GU605CW).
> >
> > Using kernel 6.17.9-arch1-1.1-g14 with the latest HID ASUS patchset v10, keyboard *color* control works correctly, but *brightness* control no longer responds at all. The issue is reproducible on every boot. This problem is not present when using patchset v8, where both color and brightness work as expected.
> >
> > Important detail: the issue occurs even **without** asusctl installed, so it must be within the kernel HID/WMI handling and is unrelated to userspace tools.
> >
> > Output of dmesg is available here [1], please let me know if any additional information is required.
> >
> > Thank you for your time and work on supporting these ASUS laptops.
> >
> > Best regards,
> > Kelsios
> >
> > [1] https://pastebin.com/ZFC13Scf
>
> [ 1.035986] asus 0003:0B05:19B6.0001: Asus failed to receive handshake ack: -32
>
> Oh yeah, asus_kbd_init no longer works with spurious inits so it broke
> devices marked with QUIRK_ROG_NKEY_LEGACY
>
> There are three ways to approach this. One is to ignore the error...
> second is to drop the quirk... third is to check for the usages for ID1, ID2...
>
> I would tend towards dropping the ID2 init and ignoring the error for
> ID1... Unless an EPIPE would cause the device to close

Benjamin correctly caught the deviation

> Antheas
>
> > On 11/22/25 1:00 PM, Antheas Kapenekakis wrote:
> > > This is a two part series which does the following:
> > >   - Clean-up init sequence
> > >   - Unify backlight handling to happen under asus-wmi so that all Aura
> > >     devices have synced brightness controls and the backlight button works
> > >     properly when it is on a USB laptop keyboard instead of one w/ WMI.
> > >
> > > For more context, see cover letter of V1. Since V5, I removed some patches
> > > to make this easier to merge.
> > >
> > > ---
> > > V9: https://lore.kernel.org/all/20251120094617.11672-1-lkml@antheas.dev/
> > > V8: https://lore.kernel.org/all/20251101104712.8011-1-lkml@antheas.dev/
> > > V7: https://lore.kernel.org/all/20251018101759.4089-1-lkml@antheas.dev/
> > > V6: https://lore.kernel.org/all/20251013201535.6737-1-lkml@antheas.dev/
> > > V5: https://lore.kernel.org/all/20250325184601.10990-1-lkml@antheas.dev/
> > > V4: https://lore.kernel.org/lkml/20250324210151.6042-1-lkml@antheas.dev/
> > > V3: https://lore.kernel.org/lkml/20250322102804.418000-1-lkml@antheas.dev/
> > > V2: https://lore.kernel.org/all/20250320220924.5023-1-lkml@antheas.dev/
> > > V1: https://lore.kernel.org/all/20250319191320.10092-1-lkml@antheas.dev/
> > >
> > > Changes since V9:
> > >   - No functional changes
> > >   - Rebase to review-ilpo-next
> > >   - Fix armoury series conflict by removing the file asus-wmi-leds-ids on
> > >     "remove unused keyboard backlight quirk" + imports
> > >     Dismiss Luke's review as this patch diverged
> > >   - Reword paragraph in "Add support for multiple kbd led handlers" to be
> > >     more verbose
> > >   - Use kfree in fortify patch
> > >   - Fix minor style quirks from --nonstict checkpatch run
> > >
> > > Changes since V8:
> > >   - No functional changes
> > >   - Move legacy init patch to second, modify first patch so that their
> > >     diff is minimized
> > >   - Split "prevent binding to all HID devices on ROG" into two patches:
> > >     - moving backlight initialization into probe
> > >     - early exit to skip ->init check and rename
> > >     - Remove skipping vendor fixups for non-vendor devices. It is not possible
> > >       to read usages before the report fixups are applied, so it did not work
> > >   - In that patch, reword a comment to be single line and make is_vendor a bool
> > >   - Dismiss Luke's tags from "Add support for multiple kbd led handlers" as it
> > >     has drifted too far since he reviewed/tested it.
> > >
> > > Changes since V7:
> > >   - Readd legacy init quirk for Dennis
> > >   - Remove HID_QUIRK_INPUT_PER_APP as a courtesy to asusctl
> > >   - Fix warning due to enum_backlight receiving negative values
> > >
> > > Changes since V6:
> > >   - Split initialization refactor into three patches, update commit text
> > >     to be clearer in what it does
> > >   - Replace spinlock accesses with guard and scoped guard in all patches
> > >   - Add missing includes mentioned by Ilpo
> > >   - Reflow, tweak comment in prevent binding to all HID devices on ROG
> > >   - Replace asus_ref.asus with local reference in all patches
> > >   - Add missing kernel doc comments
> > >   - Other minor nits from Ilpo
> > >   - User reported warning due to scheduling work while holding a spinlock.
> > >     Restructure patch for multiple handlers to limit when spinlock is held to
> > >     variable access only. In parallel, setup a workqueue to handle registration
> > >     of led device and setting brightness. This is required as registering the
> > >     led device triggers kbd_led_get which needs to hold the spinlock to
> > >     protect the led_wk value. The workqueue is also required for the hid
> > >     event passthrough to avoid scheduling work while holding the spinlock.
> > >     Apply the workqueue to wmi brightness buttons as well, as that was
> > >     omitted before this series and WMI access was performed.
> > >   - On "HID: asus: prevent binding to all HID devices on ROG", rename
> > >     quirk HANDLE_GENERIC to SKIP_REPORT_FIXUP and only skip report fixup.
> > >     This allows other quirks to apply (applies quirk that fixes keyboard
> > >     being named as a pointer device).
> > >
> > > Changes since V5:
> > >   - It's been a long time
> > >   - Remove addition of RGB as that had some comments I need to work on
> > >   - Remove folio patch (already merged)
> > >   - Remove legacy fix patch 11 from V4. There is a small chance that
> > >     without this patch, some old NKEY keyboards might not respond to
> > >     RGB commands according to Luke, but the kernel driver does not do
> > >     RGB currently. The 0x5d init is done by Armoury crate software in
> > >     Windows. If an issue is found, we can re-add it or just remove patches
> > >     1/2 before merging. However, init could use the cleanup.
> > >
> > > Changes since V4:
> > >   - Fix KConfig (reported by kernel robot)
> > >   - Fix Ilpo's nits, if I missed anything lmk
> > >
> > > Changes since V3:
> > >   - Add initializer for 0x5d for old NKEY keyboards until it is verified
> > >     that it is not needed for their media keys to function.
> > >   - Cover init in asus-wmi with spinlock as per Hans
> > >   - If asus-wmi registers WMI handler with brightness, init the brightness
> > >     in USB Asus keyboards, per Hans.
> > >   - Change hid handler name to asus-UNIQ:rgb:peripheral to match led class
> > >   - Fix oops when unregistering asus-wmi by moving unregister outside of
> > >     the spin lock (but after the asus reference is set to null)
> > >
> > > Changes since V2:
> > >   - Check lazy init succeds in asus-wmi before setting register variable
> > >   - make explicit check in asus_hid_register_listener for listener existing
> > >     to avoid re-init
> > >   - rename asus_brt to asus_hid in most places and harmonize everything
> > >   - switch to a spinlock instead of a mutex to avoid kernel ooops
> > >   - fixup hid device quirks to avoid multiple RGB devices while still exposing
> > >     all input vendor devices. This includes moving rgb init to probe
> > >     instead of the input_configured callbacks.
> > >   - Remove fan key (during retest it appears to be 0xae that is already
> > >     supported by hid-asus)
> > >   - Never unregister asus::kbd_backlight while asus-wmi is active, as that
> > >   - removes fds from userspace and breaks backlight functionality. All
> > >   - current mainline drivers do not support backlight hotplugging, so most
> > >     userspace software (e.g., KDE, UPower) is built with that assumption.
> > >     For the Ally, since it disconnects its controller during sleep, this
> > >     caused the backlight slider to not work in KDE.
> > >
> > > Changes since V1:
> > >   - Add basic RGB support on hid-asus, (Z13/Ally) tested in KDE/Z13
> > >   - Fix ifdef else having an invalid signature (reported by kernel robot)
> > >   - Restore input arguments to init and keyboard function so they can
> > >     be re-used for RGB controls.
> > >   - Remove Z13 delay (it did not work to fix the touchpad) and replace it
> > >     with a HID_GROUP_GENERIC quirk to allow hid-multitouch to load. Squash
> > >     keyboard rename into it.
> > >   - Unregister brightness listener before removing work queue to avoid
> > >     a race condition causing corruption
> > >   - Remove spurious mutex unlock in asus_brt_event
> > >   - Place mutex lock in kbd_led_set after LED_UNREGISTERING check to avoid
> > >     relocking the mutex and causing a deadlock when unregistering leds
> > >   - Add extra check during unregistering to avoid calling unregister when
> > >     no led device is registered.
> > >   - Temporarily HID_QUIRK_INPUT_PER_APP from the ROG endpoint as it causes
> > >     the driver to create 4 RGB handlers per device. I also suspect some
> > >     extra events sneak through (KDE had the @@@@@@).
> > >
> > > Antheas Kapenekakis (11):
> > >   HID: asus: simplify RGB init sequence
> > >   HID: asus: initialize additional endpoints only for legacy devices
> > >   HID: asus: use same report_id in response
> > >   HID: asus: fortify keyboard handshake
> > >   HID: asus: move vendor initialization to probe
> > >   HID: asus: early return for ROG devices
> > >   platform/x86: asus-wmi: Add support for multiple kbd led handlers
> > >   HID: asus: listen to the asus-wmi brightness device instead of
> > >     creating one
> > >   platform/x86: asus-wmi: remove unused keyboard backlight quirk
> > >   platform/x86: asus-wmi: add keyboard brightness event handler
> > >   HID: asus: add support for the asus-wmi brightness handler
> > >
> > >  drivers/hid/hid-asus.c                        | 205 ++++++++--------
> > >  drivers/platform/x86/asus-wmi.c               | 223 +++++++++++++++---
> > >  .../platform_data/x86/asus-wmi-leds-ids.h     |  50 ----
> > >  include/linux/platform_data/x86/asus-wmi.h    |  28 +++
> > >  4 files changed, 322 insertions(+), 184 deletions(-)
> > >  delete mode 100644 include/linux/platform_data/x86/asus-wmi-leds-ids.h
> > >
> > >
> > > base-commit: 2643187ccb8628144246ee9d44da5e3ac428f9c3
> >
> >
> >


^ permalink raw reply

* Re: [PATCH v10 00/11] HID: asus: Fix ASUS ROG Laptop's Keyboard backlight handling
From: Kelsios @ 2025-12-05 22:13 UTC (permalink / raw)
  To: Antheas Kapenekakis, platform-driver-x86, linux-input
  Cc: linux-kernel, Jiri Kosina, Benjamin Tissoires, Corentin Chary,
	Luke D . Jones, Hans de Goede, Ilpo Järvinen, Denis Benato

Hello,

I would like to report a regression affecting keyboard backlight brightness control on my ASUS ROG Zephyrus G16 (model GU605CW).

Using kernel 6.17.9-arch1-1.1-g14 with the latest HID ASUS patchset v10, keyboard *color* control works correctly, but *brightness* control no longer responds at all. The issue is reproducible on every boot. This problem is not present when using patchset v8, where both color and brightness work as expected.

Important detail: the issue occurs even **without** asusctl installed, so it must be within the kernel HID/WMI handling and is unrelated to userspace tools.

Output of dmesg is available here [1], please let me know if any additional information is required.

Thank you for your time and work on supporting these ASUS laptops.

Best regards,
Kelsios

[1] https://pastebin.com/ZFC13Scf

On 11/22/25 1:00 PM, Antheas Kapenekakis wrote:
> This is a two part series which does the following:
>   - Clean-up init sequence
>   - Unify backlight handling to happen under asus-wmi so that all Aura
>     devices have synced brightness controls and the backlight button works
>     properly when it is on a USB laptop keyboard instead of one w/ WMI.
> 
> For more context, see cover letter of V1. Since V5, I removed some patches
> to make this easier to merge.
> 
> ---
> V9: https://lore.kernel.org/all/20251120094617.11672-1-lkml@antheas.dev/
> V8: https://lore.kernel.org/all/20251101104712.8011-1-lkml@antheas.dev/
> V7: https://lore.kernel.org/all/20251018101759.4089-1-lkml@antheas.dev/
> V6: https://lore.kernel.org/all/20251013201535.6737-1-lkml@antheas.dev/
> V5: https://lore.kernel.org/all/20250325184601.10990-1-lkml@antheas.dev/
> V4: https://lore.kernel.org/lkml/20250324210151.6042-1-lkml@antheas.dev/
> V3: https://lore.kernel.org/lkml/20250322102804.418000-1-lkml@antheas.dev/
> V2: https://lore.kernel.org/all/20250320220924.5023-1-lkml@antheas.dev/
> V1: https://lore.kernel.org/all/20250319191320.10092-1-lkml@antheas.dev/
> 
> Changes since V9:
>   - No functional changes
>   - Rebase to review-ilpo-next
>   - Fix armoury series conflict by removing the file asus-wmi-leds-ids on
>     "remove unused keyboard backlight quirk" + imports
>     Dismiss Luke's review as this patch diverged
>   - Reword paragraph in "Add support for multiple kbd led handlers" to be
>     more verbose
>   - Use kfree in fortify patch
>   - Fix minor style quirks from --nonstict checkpatch run
> 
> Changes since V8:
>   - No functional changes
>   - Move legacy init patch to second, modify first patch so that their
>     diff is minimized
>   - Split "prevent binding to all HID devices on ROG" into two patches:
>     - moving backlight initialization into probe
>     - early exit to skip ->init check and rename
>     - Remove skipping vendor fixups for non-vendor devices. It is not possible
>       to read usages before the report fixups are applied, so it did not work
>   - In that patch, reword a comment to be single line and make is_vendor a bool
>   - Dismiss Luke's tags from "Add support for multiple kbd led handlers" as it
>     has drifted too far since he reviewed/tested it.
> 
> Changes since V7:
>   - Readd legacy init quirk for Dennis
>   - Remove HID_QUIRK_INPUT_PER_APP as a courtesy to asusctl
>   - Fix warning due to enum_backlight receiving negative values
> 
> Changes since V6:
>   - Split initialization refactor into three patches, update commit text
>     to be clearer in what it does
>   - Replace spinlock accesses with guard and scoped guard in all patches
>   - Add missing includes mentioned by Ilpo
>   - Reflow, tweak comment in prevent binding to all HID devices on ROG
>   - Replace asus_ref.asus with local reference in all patches
>   - Add missing kernel doc comments
>   - Other minor nits from Ilpo
>   - User reported warning due to scheduling work while holding a spinlock.
>     Restructure patch for multiple handlers to limit when spinlock is held to
>     variable access only. In parallel, setup a workqueue to handle registration
>     of led device and setting brightness. This is required as registering the
>     led device triggers kbd_led_get which needs to hold the spinlock to
>     protect the led_wk value. The workqueue is also required for the hid
>     event passthrough to avoid scheduling work while holding the spinlock.
>     Apply the workqueue to wmi brightness buttons as well, as that was
>     omitted before this series and WMI access was performed.
>   - On "HID: asus: prevent binding to all HID devices on ROG", rename
>     quirk HANDLE_GENERIC to SKIP_REPORT_FIXUP and only skip report fixup.
>     This allows other quirks to apply (applies quirk that fixes keyboard
>     being named as a pointer device).
> 
> Changes since V5:
>   - It's been a long time
>   - Remove addition of RGB as that had some comments I need to work on
>   - Remove folio patch (already merged)
>   - Remove legacy fix patch 11 from V4. There is a small chance that
>     without this patch, some old NKEY keyboards might not respond to
>     RGB commands according to Luke, but the kernel driver does not do
>     RGB currently. The 0x5d init is done by Armoury crate software in
>     Windows. If an issue is found, we can re-add it or just remove patches
>     1/2 before merging. However, init could use the cleanup.
> 
> Changes since V4:
>   - Fix KConfig (reported by kernel robot)
>   - Fix Ilpo's nits, if I missed anything lmk
> 
> Changes since V3:
>   - Add initializer for 0x5d for old NKEY keyboards until it is verified
>     that it is not needed for their media keys to function.
>   - Cover init in asus-wmi with spinlock as per Hans
>   - If asus-wmi registers WMI handler with brightness, init the brightness
>     in USB Asus keyboards, per Hans.
>   - Change hid handler name to asus-UNIQ:rgb:peripheral to match led class
>   - Fix oops when unregistering asus-wmi by moving unregister outside of
>     the spin lock (but after the asus reference is set to null)
> 
> Changes since V2:
>   - Check lazy init succeds in asus-wmi before setting register variable
>   - make explicit check in asus_hid_register_listener for listener existing
>     to avoid re-init
>   - rename asus_brt to asus_hid in most places and harmonize everything
>   - switch to a spinlock instead of a mutex to avoid kernel ooops
>   - fixup hid device quirks to avoid multiple RGB devices while still exposing
>     all input vendor devices. This includes moving rgb init to probe
>     instead of the input_configured callbacks.
>   - Remove fan key (during retest it appears to be 0xae that is already
>     supported by hid-asus)
>   - Never unregister asus::kbd_backlight while asus-wmi is active, as that
>   - removes fds from userspace and breaks backlight functionality. All
>   - current mainline drivers do not support backlight hotplugging, so most
>     userspace software (e.g., KDE, UPower) is built with that assumption.
>     For the Ally, since it disconnects its controller during sleep, this
>     caused the backlight slider to not work in KDE.
> 
> Changes since V1:
>   - Add basic RGB support on hid-asus, (Z13/Ally) tested in KDE/Z13
>   - Fix ifdef else having an invalid signature (reported by kernel robot)
>   - Restore input arguments to init and keyboard function so they can
>     be re-used for RGB controls.
>   - Remove Z13 delay (it did not work to fix the touchpad) and replace it
>     with a HID_GROUP_GENERIC quirk to allow hid-multitouch to load. Squash
>     keyboard rename into it.
>   - Unregister brightness listener before removing work queue to avoid
>     a race condition causing corruption
>   - Remove spurious mutex unlock in asus_brt_event
>   - Place mutex lock in kbd_led_set after LED_UNREGISTERING check to avoid
>     relocking the mutex and causing a deadlock when unregistering leds
>   - Add extra check during unregistering to avoid calling unregister when
>     no led device is registered.
>   - Temporarily HID_QUIRK_INPUT_PER_APP from the ROG endpoint as it causes
>     the driver to create 4 RGB handlers per device. I also suspect some
>     extra events sneak through (KDE had the @@@@@@).
> 
> Antheas Kapenekakis (11):
>   HID: asus: simplify RGB init sequence
>   HID: asus: initialize additional endpoints only for legacy devices
>   HID: asus: use same report_id in response
>   HID: asus: fortify keyboard handshake
>   HID: asus: move vendor initialization to probe
>   HID: asus: early return for ROG devices
>   platform/x86: asus-wmi: Add support for multiple kbd led handlers
>   HID: asus: listen to the asus-wmi brightness device instead of
>     creating one
>   platform/x86: asus-wmi: remove unused keyboard backlight quirk
>   platform/x86: asus-wmi: add keyboard brightness event handler
>   HID: asus: add support for the asus-wmi brightness handler
> 
>  drivers/hid/hid-asus.c                        | 205 ++++++++--------
>  drivers/platform/x86/asus-wmi.c               | 223 +++++++++++++++---
>  .../platform_data/x86/asus-wmi-leds-ids.h     |  50 ----
>  include/linux/platform_data/x86/asus-wmi.h    |  28 +++
>  4 files changed, 322 insertions(+), 184 deletions(-)
>  delete mode 100644 include/linux/platform_data/x86/asus-wmi-leds-ids.h
> 
> 
> base-commit: 2643187ccb8628144246ee9d44da5e3ac428f9c3



^ permalink raw reply

* [PATCH 2/2] Input: Add support for Wacom W9000-series penabled touchscreens
From: Hendrik Noack @ 2025-12-05 16:49 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Hendrik Noack, linux-input, devicetree, linux-kernel
In-Reply-To: <20251205152858.14415-1-hendrik-noack@gmx.de>

Add driver for two Wacom W9007A variants. These are penabled touchscreens
supporting passive Wacom Pens and use I2C.

Signed-off-by: Hendrik Noack <hendrik-noack@gmx.de>
---
 drivers/input/touchscreen/Kconfig       |  12 +
 drivers/input/touchscreen/Makefile      |   1 +
 drivers/input/touchscreen/wacom_w9000.c | 480 ++++++++++++++++++++++++
 3 files changed, 493 insertions(+)
 create mode 100644 drivers/input/touchscreen/wacom_w9000.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 7d5b72ee07fa..40f7af0a681a 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -610,6 +610,18 @@ config TOUCHSCREEN_WACOM_I2C
 	  To compile this driver as a module, choose M here: the module
 	  will be called wacom_i2c.
 
+config TOUCHSCREEN_WACOM_W9000
+	tristate "Wacom W9000-series penabled touchscreen (I2C)"
+	depends on I2C
+	help
+	  Say Y here if you have a Wacom W9000-series penabled I2C touchscreen.
+	  This driver supports model W9007A.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called wacom_w9000.
+
 config TOUCHSCREEN_LPC32XX
 	tristate "LPC32XX touchscreen controller"
 	depends on ARCH_LPC32XX
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index ab9abd151078..aa3915df83b2 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -102,6 +102,7 @@ tsc2007-$(CONFIG_TOUCHSCREEN_TSC2007_IIO)	+= tsc2007_iio.o
 obj-$(CONFIG_TOUCHSCREEN_TSC2007)	+= tsc2007.o
 obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001)	+= wacom_w8001.o
 obj-$(CONFIG_TOUCHSCREEN_WACOM_I2C)	+= wacom_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_WACOM_W9000)	+= wacom_w9000.o
 obj-$(CONFIG_TOUCHSCREEN_WDT87XX_I2C)	+= wdt87xx_i2c.o
 obj-$(CONFIG_TOUCHSCREEN_WM831X)	+= wm831x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_WM97XX)	+= wm97xx-ts.o
diff --git a/drivers/input/touchscreen/wacom_w9000.c b/drivers/input/touchscreen/wacom_w9000.c
new file mode 100644
index 000000000000..05c928646bc3
--- /dev/null
+++ b/drivers/input/touchscreen/wacom_w9000.c
@@ -0,0 +1,480 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Wacom W9000-series penabled I2C touchscreen driver
+ *
+ * Copyright (c) 2025 Hendrik Noack <hendrik-noack@gmx.de>
+ *
+ * Partially based on vendor driver:
+ *	Copyright (C) 2012, Samsung Electronics Co. Ltd.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/touchscreen.h>
+#include <linux/unaligned.h>
+
+// Message length
+#define COM_COORD_NUM_MAX	12
+#define COM_QUERY_NUM_MAX	9
+
+// Commands
+#define COM_QUERY		0x2a
+
+struct wacom_w9000_variant {
+	int com_coord_num;
+	int com_query_num;
+	char *name;
+};
+
+struct wacom_w9000_data {
+	struct i2c_client *client;
+	struct input_dev *input_dev;
+	const struct wacom_w9000_variant *variant;
+	unsigned int fw_version;
+
+	struct touchscreen_properties prop;
+	unsigned int max_pressure;
+
+	struct regulator *regulator;
+
+	struct gpio_desc *flash_mode_gpio;
+	struct gpio_desc *pen_inserted_gpio;
+
+	unsigned int irq;
+	unsigned int pen_insert_irq;
+
+	bool pen_inserted;
+	bool pen_proximity;
+};
+
+static int wacom_w9000_read(struct i2c_client *client, u8 command, int len, char *data)
+{
+	struct i2c_msg xfer[2];
+	bool retried = false;
+	int ret;
+
+	/* Write register */
+	xfer[0].addr = client->addr;
+	xfer[0].flags = 0;
+	xfer[0].len = 1;
+	xfer[0].buf = &command;
+
+	/* Read data */
+	xfer[1].addr = client->addr;
+	xfer[1].flags = I2C_M_RD;
+	xfer[1].len = len;
+	xfer[1].buf = data;
+
+retry:
+	ret = i2c_transfer(client->adapter, xfer, 2);
+	if (ret == 2) {
+		ret = 0;
+	} else if (!retried) {
+		retried = true;
+		goto retry;
+	} else {
+		if (ret >= 0)
+			ret = -EIO;
+		dev_err(&client->dev, "%s: i2c transfer failed (%d)\n", __func__, ret);
+	}
+
+	return ret;
+}
+
+static int wacom_w9000_query(struct wacom_w9000_data *wacom_data)
+{
+	struct i2c_client *client = wacom_data->client;
+	struct device *dev = &wacom_data->client->dev;
+	bool retried = false;
+	int ret;
+	u8 data[COM_QUERY_NUM_MAX];
+
+retry:
+	ret = wacom_w9000_read(client, COM_QUERY, wacom_data->variant->com_query_num, data);
+	if (ret)
+		return ret;
+
+	if (data[0] == 0x0f) {
+		wacom_data->fw_version = get_unaligned_be16(&data[7]);
+	} else if (!retried) {
+		retried = true;
+		goto retry;
+	} else {
+		return -EIO;
+	}
+
+	dev_dbg(dev, "query: %X, %X, %X, %X, %X, %X, %X, %X, %X, %d\n", data[0], data[1], data[2],
+		data[3], data[4], data[5], data[6], data[7], data[8], retried);
+
+	wacom_data->prop.max_x = get_unaligned_be16(&data[1]);
+	wacom_data->prop.max_y = get_unaligned_be16(&data[3]);
+	wacom_data->max_pressure = get_unaligned_be16(&data[5]);
+
+	dev_dbg(dev, "max_x:%d, max_y:%d, max_pressure:%d, fw:0x%X", wacom_data->prop.max_x,
+		wacom_data->prop.max_y, wacom_data->max_pressure,
+		wacom_data->fw_version);
+
+	return 0;
+}
+
+static void wacom_w9000_coord(struct wacom_w9000_data *wacom_data)
+{
+	struct i2c_client *client = wacom_data->client;
+	struct device *dev = &wacom_data->client->dev;
+	int ret;
+	u8 data[COM_COORD_NUM_MAX];
+	bool touch, rubber, side_button;
+	u16 x, y, pressure;
+	u8 distance;
+
+	ret = i2c_master_recv(client, data, wacom_data->variant->com_coord_num);
+	if (ret != wacom_data->variant->com_coord_num) {
+		if (ret >= 0)
+			ret = -EIO;
+		dev_err(dev, "%s: i2c receive failed (%d)\n", __func__, ret);
+		return;
+	}
+
+	dev_dbg(dev, "data: %X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X", data[0], data[1],
+		data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10],
+		data[11]);
+
+	if (data[0] & BIT(7)) {
+		wacom_data->pen_proximity = 1;
+
+		touch = !!(data[0] & BIT(4));
+		side_button = !!(data[0] & BIT(5));
+		rubber = !!(data[0] & BIT(6));
+
+		x = get_unaligned_be16(&data[1]);
+		y = get_unaligned_be16(&data[3]);
+		pressure = get_unaligned_be16(&data[5]);
+		distance = data[7];
+
+		if (!((x <= wacom_data->prop.max_x) && (y <= wacom_data->prop.max_y))) {
+			dev_warn(dev, "Coordinates out of range x=%d, y=%d", x, y);
+			return;
+		}
+
+		touchscreen_report_pos(wacom_data->input_dev, &wacom_data->prop, x, y, false);
+		input_report_abs(wacom_data->input_dev, ABS_PRESSURE, pressure);
+		input_report_abs(wacom_data->input_dev, ABS_DISTANCE, distance);
+		input_report_key(wacom_data->input_dev, BTN_STYLUS, side_button);
+		input_report_key(wacom_data->input_dev, BTN_TOUCH, touch);
+		input_report_key(wacom_data->input_dev, BTN_TOOL_PEN, !rubber);
+		input_report_key(wacom_data->input_dev, BTN_TOOL_RUBBER, rubber);
+		input_sync(wacom_data->input_dev);
+	} else {
+		if (wacom_data->pen_proximity) {
+			input_report_abs(wacom_data->input_dev, ABS_PRESSURE, 0);
+			input_report_abs(wacom_data->input_dev, ABS_DISTANCE, 0);
+			input_report_key(wacom_data->input_dev, BTN_STYLUS, 0);
+			input_report_key(wacom_data->input_dev, BTN_TOUCH, 0);
+			input_report_key(wacom_data->input_dev, BTN_TOOL_PEN, 0);
+			input_report_key(wacom_data->input_dev, BTN_TOOL_RUBBER, 0);
+			input_sync(wacom_data->input_dev);
+
+			wacom_data->pen_proximity = 0;
+		}
+	}
+}
+
+static irqreturn_t wacom_w9000_interrupt(int irq, void *dev_id)
+{
+	struct wacom_w9000_data *wacom_data = dev_id;
+
+	wacom_w9000_coord(wacom_data);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wacom_w9000_interrupt_pen_insert(int irq, void *dev_id)
+{
+	struct wacom_w9000_data *wacom_data = dev_id;
+	struct device *dev = &wacom_data->client->dev;
+	int ret;
+
+	wacom_data->pen_inserted = gpiod_get_value(wacom_data->pen_inserted_gpio);
+
+	input_report_switch(wacom_data->input_dev, SW_PEN_INSERTED, wacom_data->pen_inserted);
+	input_sync(wacom_data->input_dev);
+
+	if (!wacom_data->pen_inserted && !regulator_is_enabled(wacom_data->regulator)) {
+		ret = regulator_enable(wacom_data->regulator);
+		if (ret) {
+			dev_err(dev, "Failed to enable regulators: %d\n", ret);
+			return IRQ_HANDLED;
+		}
+		msleep(200);
+		enable_irq(wacom_data->irq);
+	} else if (wacom_data->pen_inserted && regulator_is_enabled(wacom_data->regulator)) {
+		disable_irq(wacom_data->irq);
+		regulator_disable(wacom_data->regulator);
+	}
+
+	dev_dbg(dev, "Pen inserted changed to %d", wacom_data->pen_inserted);
+
+	return IRQ_HANDLED;
+}
+
+static int wacom_w9000_open(struct input_dev *dev)
+{
+	struct wacom_w9000_data *wacom_data = input_get_drvdata(dev);
+	int ret;
+
+	if (!wacom_data->pen_inserted && !regulator_is_enabled(wacom_data->regulator)) {
+		ret = regulator_enable(wacom_data->regulator);
+		if (ret) {
+			dev_err(&wacom_data->client->dev, "Failed to enable regulators: %d\n",
+				ret);
+			return ret;
+		}
+		msleep(200);
+		enable_irq(wacom_data->irq);
+	}
+	return 0;
+}
+
+static void wacom_w9000_close(struct input_dev *dev)
+{
+	struct wacom_w9000_data *wacom_data = input_get_drvdata(dev);
+
+	if (regulator_is_enabled(wacom_data->regulator)) {
+		disable_irq(wacom_data->irq);
+		regulator_disable(wacom_data->regulator);
+	}
+}
+
+static int wacom_w9000_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct wacom_w9000_data *wacom_data;
+	struct input_dev *input_dev;
+	int ret;
+	u32 val;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_err(dev, "i2c_check_functionality error\n");
+		return -EIO;
+	}
+
+	wacom_data = devm_kzalloc(dev, sizeof(*wacom_data), GFP_KERNEL);
+	if (!wacom_data)
+		return -ENOMEM;
+
+	wacom_data->variant = i2c_get_match_data(client);
+
+	wacom_data->client = client;
+
+	input_dev = devm_input_allocate_device(dev);
+	if (!input_dev)
+		return -ENOMEM;
+	wacom_data->input_dev = input_dev;
+
+	wacom_data->irq = client->irq;
+	i2c_set_clientdata(client, wacom_data);
+
+	wacom_data->regulator = devm_regulator_get(dev, "vdd");
+	if (IS_ERR(wacom_data->regulator))
+		return dev_err_probe(dev, PTR_ERR(wacom_data->regulator),
+				     "Failed to get regulators\n");
+
+	wacom_data->flash_mode_gpio = devm_gpiod_get_optional(dev, "flash-mode", GPIOD_OUT_LOW);
+	if (IS_ERR(wacom_data->flash_mode_gpio))
+		return dev_err_probe(dev, PTR_ERR(wacom_data->flash_mode_gpio),
+				     "Failed to get flash-mode gpio\n");
+
+	wacom_data->pen_inserted_gpio = devm_gpiod_get_optional(dev, "pen-inserted", GPIOD_IN);
+	if (IS_ERR(wacom_data->pen_inserted_gpio))
+		return dev_err_probe(dev, PTR_ERR(wacom_data->pen_inserted_gpio),
+				     "Failed to get pen-insert gpio\n");
+
+	ret = regulator_enable(wacom_data->regulator);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable regulators\n");
+
+	msleep(200);
+
+	ret = wacom_w9000_query(wacom_data);
+	if (ret)
+		goto err_disable_regulators;
+
+	input_dev->name = wacom_data->variant->name;
+	input_dev->id.bustype = BUS_I2C;
+	input_dev->dev.parent = dev;
+	input_dev->id.vendor = 0x56a;
+	input_dev->id.version = wacom_data->fw_version;
+	input_dev->open = wacom_w9000_open;
+	input_dev->close = wacom_w9000_close;
+
+	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+	input_set_capability(input_dev, EV_KEY, BTN_TOOL_PEN);
+	input_set_capability(input_dev, EV_KEY, BTN_TOOL_RUBBER);
+	input_set_capability(input_dev, EV_KEY, BTN_STYLUS);
+
+	// Calculate x and y resolution from size in devicetree
+	ret = device_property_read_u32(dev, "touchscreen-x-mm", &val);
+	if (ret)
+		input_abs_set_res(input_dev, ABS_X, 100);
+	else
+		input_abs_set_res(input_dev, ABS_X, wacom_data->prop.max_x / val);
+	ret = device_property_read_u32(dev, "touchscreen-y-mm", &val);
+	if (ret)
+		input_abs_set_res(input_dev, ABS_Y, 100);
+	else
+		input_abs_set_res(input_dev, ABS_Y, wacom_data->prop.max_y / val);
+
+	input_set_abs_params(input_dev, ABS_X, 0, wacom_data->prop.max_x, 4, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, wacom_data->prop.max_y, 4, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_data->max_pressure, 0, 0);
+	input_set_abs_params(input_dev, ABS_DISTANCE, 0, 255, 0, 0);
+
+	touchscreen_parse_properties(input_dev, false, &wacom_data->prop);
+
+	ret = devm_request_threaded_irq(dev, wacom_data->irq, NULL, wacom_w9000_interrupt,
+					IRQF_ONESHOT | IRQF_NO_AUTOEN, client->name, wacom_data);
+	if (ret) {
+		dev_err(dev, "Failed to register interrupt\n");
+		goto err_disable_regulators;
+	}
+
+	if (wacom_data->pen_inserted_gpio) {
+		input_set_capability(input_dev, EV_SW, SW_PEN_INSERTED);
+		wacom_data->pen_insert_irq = gpiod_to_irq(wacom_data->pen_inserted_gpio);
+		ret = devm_request_threaded_irq(dev, wacom_data->pen_insert_irq, NULL,
+						wacom_w9000_interrupt_pen_insert, IRQF_ONESHOT |
+						IRQF_NO_AUTOEN | IRQF_TRIGGER_RISING |
+						IRQF_TRIGGER_FALLING, "wacom_pen_insert",
+						wacom_data);
+		if (ret) {
+			dev_err(dev, "Failed to register pen-insert interrupt\n");
+			goto err_disable_regulators;
+		}
+
+		wacom_data->pen_inserted = gpiod_get_value(wacom_data->pen_inserted_gpio);
+		if (wacom_data->pen_inserted)
+			regulator_disable(wacom_data->regulator);
+		else
+			enable_irq(wacom_data->irq);
+	} else {
+		enable_irq(wacom_data->irq);
+	}
+
+	input_set_drvdata(input_dev, wacom_data);
+
+	input_report_switch(wacom_data->input_dev, SW_PEN_INSERTED, wacom_data->pen_inserted);
+	input_sync(wacom_data->input_dev);
+
+	if (wacom_data->pen_inserted_gpio)
+		enable_irq(wacom_data->pen_insert_irq);
+
+	ret = input_register_device(wacom_data->input_dev);
+	if (ret) {
+		dev_err(dev, "Failed to register input device: %d\n", ret);
+		goto err_disable_regulators;
+	}
+
+	return 0;
+
+err_disable_regulators:
+	regulator_disable(wacom_data->regulator);
+	return ret;
+}
+
+static void wacom_w9000_remove(struct i2c_client *client)
+{
+	struct wacom_w9000_data *wacom_data = i2c_get_clientdata(client);
+
+	if (regulator_is_enabled(wacom_data->regulator))
+		regulator_disable(wacom_data->regulator);
+}
+
+static int wacom_w9000_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct wacom_w9000_data *wacom_data = i2c_get_clientdata(client);
+	struct input_dev *input_dev = wacom_data->input_dev;
+
+	mutex_lock(&input_dev->mutex);
+
+	if (regulator_is_enabled(wacom_data->regulator)) {
+		disable_irq(wacom_data->irq);
+		regulator_disable(wacom_data->regulator);
+	}
+
+	mutex_unlock(&input_dev->mutex);
+
+	return 0;
+}
+
+static int wacom_w9000_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct wacom_w9000_data *wacom_data = i2c_get_clientdata(client);
+	struct input_dev *input_dev = wacom_data->input_dev;
+	int ret = 0;
+
+	mutex_lock(&input_dev->mutex);
+
+	if (!wacom_data->pen_inserted && !regulator_is_enabled(wacom_data->regulator)) {
+		ret = regulator_enable(wacom_data->regulator);
+		if (ret) {
+			dev_err(&wacom_data->client->dev, "Failed to enable regulators: %d\n",
+				ret);
+		} else {
+			msleep(200);
+			enable_irq(wacom_data->irq);
+		}
+	}
+
+	mutex_unlock(&input_dev->mutex);
+
+	return ret;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(wacom_w9000_pm, wacom_w9000_suspend, wacom_w9000_resume);
+
+static const struct wacom_w9000_variant w9007a_lt03 = {
+	.com_coord_num	= 8,
+	.com_query_num	= 9,
+	.name = "Wacom W9007 LT03 Digitizer",
+};
+
+static const struct wacom_w9000_variant w9007a_v1 = {
+	.com_coord_num	= 12,
+	.com_query_num	= 9,
+	.name = "Wacom W9007 V1 Digitizer",
+};
+
+static const struct of_device_id wacom_w9000_of_match[] = {
+	{ .compatible = "wacom,w9007a-lt03", .data = &w9007a_lt03, },
+	{ .compatible = "wacom,w9007a-v1", .data = &w9007a_v1, },
+	{},
+};
+MODULE_DEVICE_TABLE(of, wacom_w9000_of_match);
+
+static const struct i2c_device_id wacom_w9000_id[] = {
+	{ .name = "w9007a-lt03", .driver_data = (kernel_ulong_t)&w9007a_lt03 },
+	{ .name = "w9007a-v1", .driver_data = (kernel_ulong_t)&w9007a_v1 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, wacom_w9000_id);
+
+static struct i2c_driver wacom_w9000_driver = {
+	.driver = {
+		.name	= "wacom_w9000",
+		.of_match_table = wacom_w9000_of_match,
+		.pm	= pm_sleep_ptr(&wacom_w9000_pm),
+	},
+	.probe		= wacom_w9000_probe,
+	.remove		= wacom_w9000_remove,
+	.id_table	= wacom_w9000_id,
+};
+module_i2c_driver(wacom_w9000_driver);
+
+/* Module information */
+MODULE_AUTHOR("Hendrik Noack <hendrik-noack@gmx.de>");
+MODULE_DESCRIPTION("Wacom W9000-series penabled touchscreen driver");
+MODULE_LICENSE("GPL");
-- 
2.43.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox