* [PATCH 0/2] Input: add support for aXiom touchscreen controller using SPI or I2C
@ 2026-01-26 16:38 Andrew Thomas
2026-01-26 16:38 ` [PATCH 1/2] dt-bindings: input: touchscreen: add TouchNetix aXiom device tree Andrew Thomas
2026-01-26 16:38 ` [PATCH 2/2] Input: add support for aXiom touchscreen controller using SPI or I2C Andrew Thomas
0 siblings, 2 replies; 5+ messages in thread
From: Andrew Thomas @ 2026-01-26 16:38 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Henrik Rydberg
Cc: linux-input, devicetree, linux-kernel, Andrew Thomas,
Marco Felsch
Summary of the added features:
- Add input driver support for TouchNetix aXiom touchscreen controller
using either I2C or SPI.
- Support ABS_MT touch reports in axiom_process_u41_report().
- Support both polling and interrupt mode.
- Add basic documentation and provide example device tree bindings.
- Provide the basic structure to add firmware and config download in
the future via both I2C and SPI.
Many thanks,
Andrew
Signed-off-by: Andrew Thomas <andrew.thomas@touchnetix.com>
---
Andrew Thomas (2):
dt-bindings: input: touchscreen: add TouchNetix aXiom device tree
Input: add support for aXiom touchscreen controller using SPI or I2C
.../bindings/input/touchscreen/tnx,axiom.yaml | 70 +++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
drivers/input/touchscreen/Kconfig | 25 ++
drivers/input/touchscreen/Makefile | 3 +
drivers/input/touchscreen/axiom_core.c | 473 +++++++++++++++++++++
drivers/input/touchscreen/axiom_core.h | 118 +++++
drivers/input/touchscreen/axiom_i2c.c | 150 +++++++
drivers/input/touchscreen/axiom_spi.c | 155 +++++++
8 files changed, 996 insertions(+)
---
base-commit: 7ff574599464bd0e30da88aabc7be9de1021204a
change-id: 20260126-axiom-driver-submission3-f892e1ae9ec0
Best regards,
--
Andrew Thomas <andrew.thomas@touchnetix.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] dt-bindings: input: touchscreen: add TouchNetix aXiom device tree
2026-01-26 16:38 [PATCH 0/2] Input: add support for aXiom touchscreen controller using SPI or I2C Andrew Thomas
@ 2026-01-26 16:38 ` Andrew Thomas
2026-01-26 17:32 ` Rob Herring (Arm)
2026-01-27 14:16 ` Rob Herring
2026-01-26 16:38 ` [PATCH 2/2] Input: add support for aXiom touchscreen controller using SPI or I2C Andrew Thomas
1 sibling, 2 replies; 5+ messages in thread
From: Andrew Thomas @ 2026-01-26 16:38 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Henrik Rydberg
Cc: linux-input, devicetree, linux-kernel, Andrew Thomas,
Marco Felsch
---
.../bindings/input/touchscreen/tnx,axiom.yaml | 70 ++++++++++++++++++++++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
2 files changed, 72 insertions(+)
diff --git a/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml b/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml
new file mode 100644
index 000000000000..7b532471c17f
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/tnx,axiom.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TouchNetix aXiom Touchscreen Controller
+
+maintainers:
+ - Andrew Thomas <andrew.thomas@touchnetix.com>
+
+description: |
+ The TouchNetix aXiom series are high-performance touchscreen controllers
+ supporting various interface methods including I2C and SPI.
+
+properties:
+ compatible:
+ enum:
+ - tnx,axiom
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ description: Both IRQ_TYPE_LEVEL_LOW and IRQ_TYPE_EDGE_FALLING are supported
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+allOf:
+ - $ref: touchscreen.yaml#
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchscreen@66 {
+ compatible = "tnx,axiom-i2c";
+ reg = <0x66>;
+ interrupt-parent = <&gpio>;
+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+ axiom,poll-enable;
+ axiom,poll-period = <15>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchscreen@0 {
+ compatible = "tnx,axiom-spi";
+ reg = <0>;
+ interrupt-parent = <&gpio>;
+ interrupts = <24 IRQ_TYPE_EDGE_FALLING>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index f1d1882009ba..dadfc7036ed7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1636,6 +1636,8 @@ patternProperties:
description: Trusted Logic Mobility
"^tmt,.*":
description: Tecon Microprocessor Technologies, LLC.
+ "^tnx,.*":
+ description: TouchNetix
"^topeet,.*":
description: Topeet
"^topic,.*":
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] Input: add support for aXiom touchscreen controller using SPI or I2C
2026-01-26 16:38 [PATCH 0/2] Input: add support for aXiom touchscreen controller using SPI or I2C Andrew Thomas
2026-01-26 16:38 ` [PATCH 1/2] dt-bindings: input: touchscreen: add TouchNetix aXiom device tree Andrew Thomas
@ 2026-01-26 16:38 ` Andrew Thomas
1 sibling, 0 replies; 5+ messages in thread
From: Andrew Thomas @ 2026-01-26 16:38 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Henrik Rydberg
Cc: linux-input, devicetree, linux-kernel, Andrew Thomas,
Marco Felsch
---
drivers/input/touchscreen/Kconfig | 25 ++
drivers/input/touchscreen/Makefile | 3 +
drivers/input/touchscreen/axiom_core.c | 473 +++++++++++++++++++++++++++++++++
drivers/input/touchscreen/axiom_core.h | 118 ++++++++
drivers/input/touchscreen/axiom_i2c.c | 150 +++++++++++
drivers/input/touchscreen/axiom_spi.c | 155 +++++++++++
6 files changed, 924 insertions(+)
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 7d5b72ee07fa..d27292ccabc9 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -162,6 +162,31 @@ config TOUCHSCREEN_AUO_PIXCIR
To compile this driver as a module, choose M here: the
module will be called auo-pixcir-ts.
+config TOUCHSCREEN_AXIOM_CORE
+ tristate
+
+config TOUCHSCREEN_AXIOM_I2C
+ tristate "TouchNetix aXiom touchscreen (I2C)"
+ depends on I2C
+ select TOUCHSCREEN_AXIOM_CORE
+ help
+ Say Y here if the aXiom touchscreen is connected via
+ the I2C bus.
+
+ To compile this driver as a module, choose M here: the
+ module will be called axiom_i2c.
+
+config TOUCHSCREEN_AXIOM_SPI
+ tristate "TouchNetix aXiom touchscreen (SPI)"
+ depends on SPI
+ select TOUCHSCREEN_AXIOM_CORE
+ help
+ Say Y here if the aXiom touchscreen is connected via
+ the SPI bus.
+
+ To compile this driver as a module, choose M here: the
+ module will be called axiom_spi.
+
config TOUCHSCREEN_BU21013
tristate "BU21013 based touch panel controllers"
depends on I2C
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index ab9abd151078..9b7d572c4589 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -19,6 +19,9 @@ obj-$(CONFIG_TOUCHSCREEN_APPLE_Z2) += apple_z2.o
obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o
obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o
+obj-$(CONFIG_TOUCHSCREEN_AXIOM_CORE) += axiom_core.o
+obj-$(CONFIG_TOUCHSCREEN_AXIOM_I2C) += axiom_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_AXIOM_SPI) += axiom_spi.o
obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
obj-$(CONFIG_TOUCHSCREEN_BU21029) += bu21029_ts.o
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o
diff --git a/drivers/input/touchscreen/axiom_core.c b/drivers/input/touchscreen/axiom_core.c
new file mode 100644
index 000000000000..89a845ab90ba
--- /dev/null
+++ b/drivers/input/touchscreen/axiom_core.c
@@ -0,0 +1,473 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TouchNetix aXiom Touchscreen Driver
+ *
+ * Copyright (C) 2020-2026 TouchNetix Ltd.
+ *
+ * Author(s): Mark Satterthwaite <mark.satterthwaite@touchnetix.com>
+ * Pedro Torruella <pedro.torruella@touchnetix.com>
+ * Bart Prescott <bartp@baasheep.co.uk>
+ * Hannah Rossiter <hannah.rossiter@touchnetix.com>
+ * Andrew Thomas <andrew.thomas@touchnetix.com>
+ */
+
+#include <linux/device.h>
+#include <linux/input/mt.h>
+#include <linux/crc16.h>
+#include <linux/property.h>
+#include <linux/interrupt.h>
+#include <linux/unaligned.h>
+#include <linux/bitfield.h>
+#include "axiom_core.h"
+
+static bool poll_enable;
+module_param(poll_enable, bool, 0444);
+MODULE_PARM_DESC(poll_enable, "Enable polling mode [default 0=no]");
+
+static int poll_period = 10;
+module_param(poll_period, uint, 0444);
+MODULE_PARM_DESC(poll_period, "Polling period in ms [default = 10]");
+
+/* u31 device info masks */
+#define AX_DEV_ID_MASK GENMASK(14, 0)
+#define AX_MODE BIT(15)
+#define AX_FW_REV_MINOR_MASK GENMASK(7, 0)
+#define AX_FW_REV_MAJOR_MASK GENMASK(15, 8)
+#define AX_VARIANT_MASK GENMASK(5, 0)
+#define AX_FW_STATUS BIT(7)
+#define AX_TCP_REV_MASK GENMASK(15, 8)
+#define AX_BOOT_REV_MINOR_MASK GENMASK(7, 0)
+#define AX_BOOT_REV_MAJOR_MASK GENMASK(15, 8)
+#define AX_NUM_USAGES_MASK GENMASK(7, 0)
+#define AX_SILICON_REV_MASK GENMASK(11, 8)
+#define AX_RUNTIME_FW_PATCH_MASK GENMASK(15, 12)
+
+/* u31 usage table entry masks */
+#define AX_U31_USAGE_NUM_MASK GENMASK(7, 0)
+#define AX_U31_START_PAGE_MASK GENMASK(15, 8)
+#define AX_U31_NUM_PAGES_MASK GENMASK(7, 0)
+#define AX_U31_MAX_OFFSET_MASK GENMASK(14, 8)
+#define AX_U31_OFFSET_TYPE_BIT BIT(15)
+#define AX_U31_UIF_REV_MASK GENMASK(7, 0)
+#define AX_U31_USAGE_TYPE_MASK GENMASK(15, 8)
+
+/* u34 report masks */
+#define AX_U34_LEN_MASK GENMASK(6, 0)
+#define AX_U34_OVERFLOW BIT(7)
+#define AX_U34_USAGE_MASK GENMASK(15, 8)
+#define AX_U34_PAYLOAD_BUFFER (2)
+
+/* u41 report masks */
+#define AX_U41_PRESENT_MASK GENMASK(9, 0)
+#define U41_X_Y_OFFSET (2)
+#define U41_COORD_SIZE (4)
+#define U41_Z_OFFSET (42)
+
+static const char *const fw_variants[] = {
+ "3D",
+ "2D",
+ "FORCE",
+ "0D",
+ "XL",
+ "TOUCHPAD",
+};
+
+static int axiom_set_capabilities(struct input_dev *input_dev)
+{
+ input_dev->name = "TouchNetix aXiom Touchscreen";
+ input_dev->phys = "input/ts";
+
+ // Multi Touch
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, 65535, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 65535, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_DISTANCE, 0, 127, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 127, 0, 0);
+
+ // each report id in u41 can be configured separately in u42,
+ // to keep it simple have all reports ids be touch.
+ input_mt_init_slots(input_dev, U41_MAX_TARGETS, INPUT_MT_DIRECT);
+
+ return 0;
+}
+
+static struct u31_usage_entry *usage_find_entry(struct axiom *ax, u16 usage)
+{
+ u16 i;
+
+ for (i = 0; i < ax->dev_info.num_usages; i++) {
+ if (ax->usage_table[i].usage_num == usage)
+ return &ax->usage_table[i];
+ }
+
+ pr_err("aXiom-core: Usage u%02x not found in usage table\n", usage);
+ return ERR_PTR(-EINVAL);
+}
+
+static void axiom_unpack_device_info(const u8 *buf,
+ struct axiom_device_info *info)
+{
+ u16 w;
+
+ w = get_unaligned_le16(buf);
+ info->device_id = FIELD_GET(AX_DEV_ID_MASK, w);
+ info->mode = !!(w & AX_MODE);
+
+ w = get_unaligned_le16(buf + 2);
+ info->runtime_fw_rev_minor = FIELD_GET(AX_FW_REV_MINOR_MASK, w);
+ info->runtime_fw_rev_major = FIELD_GET(AX_FW_REV_MAJOR_MASK, w);
+
+ w = get_unaligned_le16(buf + 4);
+ info->device_build_variant = FIELD_GET(AX_VARIANT_MASK, w);
+ info->runtime_fw_status = !!(w & AX_FW_STATUS);
+ info->tcp_revision = FIELD_GET(AX_TCP_REV_MASK, w);
+
+ w = get_unaligned_le16(buf + 6);
+ info->bootloader_fw_rev_minor = FIELD_GET(AX_BOOT_REV_MINOR_MASK, w);
+ info->bootloader_fw_rev_major = FIELD_GET(AX_BOOT_REV_MAJOR_MASK, w);
+
+ info->jedec_id = get_unaligned_le16(buf + 8);
+
+ w = get_unaligned_le16(buf + 10);
+ info->num_usages = FIELD_GET(AX_NUM_USAGES_MASK, w);
+ info->silicon_revision = FIELD_GET(AX_SILICON_REV_MASK, w);
+ info->runtime_fw_rev_patch = FIELD_GET(AX_RUNTIME_FW_PATCH_MASK, w);
+}
+
+static void axiom_unpack_usage_table(u8 *buf, struct axiom *ax)
+{
+ struct u31_usage_entry *entry;
+ u16 report_len;
+ u8 *ptr;
+ int i;
+ u16 w;
+
+ for (i = 0; i < ax->dev_info.num_usages && i < U31_MAX_USAGES; i++) {
+ entry = &ax->usage_table[i];
+ /* Calculate offset for this specific entry */
+ ptr = buf + (i * SIZE_U31_USAGE_ENTRY);
+
+ w = get_unaligned_le16(ptr);
+ entry->usage_num = FIELD_GET(AX_U31_USAGE_NUM_MASK, w);
+ entry->start_page = FIELD_GET(AX_U31_START_PAGE_MASK, w);
+
+ w = get_unaligned_le16(ptr + 2);
+ entry->num_pages = FIELD_GET(AX_U31_NUM_PAGES_MASK, w);
+ entry->max_offset = FIELD_GET(AX_U31_MAX_OFFSET_MASK, w);
+ entry->offset_type = !!(w & AX_U31_OFFSET_TYPE_BIT);
+
+ w = get_unaligned_le16(ptr + 4);
+ entry->uifrevision = FIELD_GET(AX_U31_UIF_REV_MASK, w);
+ entry->usage_type = FIELD_GET(AX_U31_USAGE_TYPE_MASK, w);
+
+ // Convert words to bytes
+ report_len = (entry->max_offset + 1) * 2;
+ if (entry->usage_type == REPORT &&
+ report_len > ax->max_report_len) {
+ ax->max_report_len = report_len;
+ }
+ }
+}
+
+static int axiom_init_dev_info(struct axiom *ax)
+{
+ struct u31_usage_entry *u;
+ const char *variant_str;
+ char silicon_rev;
+ int err;
+ int i;
+
+ /* Read page 0 of u31 */
+ err = ax->bus_ops->read(ax->dev, 0x0, SIZE_U31_DEVICE_INFO,
+ ax->read_buf);
+ if (err)
+ return -EIO;
+
+ axiom_unpack_device_info(ax->read_buf, &ax->dev_info);
+
+ silicon_rev = (char)(0x41 + ax->dev_info.silicon_revision);
+
+ if (ax->dev_info.device_build_variant < ARRAY_SIZE(fw_variants))
+ variant_str = fw_variants[ax->dev_info.device_build_variant];
+ else
+ variant_str = "UNKNOWN";
+
+ dev_info(ax->dev, "Firmware Info:\n");
+ dev_info(ax->dev, " BL Mode : %u\n", ax->dev_info.mode);
+ dev_info(ax->dev, " Device ID : %04x\n", ax->dev_info.device_id);
+ dev_info(ax->dev, " FW Revision : %u.%u.%u-%s %s\n",
+ ax->dev_info.runtime_fw_rev_major,
+ ax->dev_info.runtime_fw_rev_minor,
+ ax->dev_info.runtime_fw_rev_patch,
+ (ax->dev_info.runtime_fw_status == 0) ? "eng" : "prod",
+ variant_str);
+ dev_info(ax->dev, " BL Revision : %02x.%02x\n",
+ ax->dev_info.bootloader_fw_rev_major,
+ ax->dev_info.bootloader_fw_rev_minor);
+ dev_info(ax->dev, " Silicon : 0x%04X (Rev %c)\n",
+ ax->dev_info.jedec_id, silicon_rev);
+ dev_info(ax->dev, " Num Usages : %u\n", ax->dev_info.num_usages);
+
+ if (ax->dev_info.num_usages > U31_MAX_USAGES) {
+ dev_err(ax->dev,
+ "Num usages (%u) exceeds maximum supported (%u)\n",
+ ax->dev_info.num_usages, U31_MAX_USAGES);
+ return -EINVAL;
+ }
+
+ /* Read the second page of u31 to get the usage table */
+ err = ax->bus_ops->read(ax->dev, 0x100,
+ sizeof(ax->usage_table[0]) *
+ ax->dev_info.num_usages,
+ ax->read_buf);
+ if (err)
+ return -EIO;
+
+ axiom_unpack_usage_table(ax->read_buf, ax);
+
+ dev_info(ax->dev, "Usage Table:\n");
+ for (i = 0; i < ax->dev_info.num_usages; i++) {
+ u = &ax->usage_table[i];
+
+ dev_info(ax->dev, " Usage: u%02x Rev: %3u Page: 0x%02x00 Num Pages: %3u\n",
+ u->usage_num, u->uifrevision, u->start_page,
+ u->num_pages);
+ }
+
+ if (ax->max_report_len > AXIOM_MAX_READ_SIZE) {
+ dev_err(ax->dev,
+ "aXiom maximum report length (%u) greater than allocated buffer size (%u).",
+ ax->max_report_len, AXIOM_MAX_READ_SIZE);
+ return -EINVAL;
+ }
+
+ /* Set u34 address to allow direct access to report reading address */
+ u = usage_find_entry(ax, 0x34);
+ if (IS_ERR(u))
+ return PTR_ERR(u);
+ ax->u34_address = u->start_page << 8;
+
+ return 0;
+}
+
+static int axiom_process_u41_report(struct axiom *ax, u8 *report)
+{
+ enum u41_target_state_e state;
+ u16 target_present;
+ bool active;
+ u8 offset;
+ int i;
+ u16 x;
+ u16 y;
+ s8 z;
+
+ target_present =
+ FIELD_GET(AX_U41_PRESENT_MASK, get_unaligned_le16(&report[0]));
+
+ for (i = 0; i < U41_MAX_TARGETS; i++) {
+ active = !!((target_present >> i) & 1);
+
+ offset = U41_X_Y_OFFSET + (i * U41_COORD_SIZE);
+ x = get_unaligned_le16(&report[offset]);
+ y = get_unaligned_le16(&report[offset + 2]);
+ z = report[U41_Z_OFFSET + i];
+
+ if (!active)
+ state = target_state_not_present;
+ else if (z >= 0)
+ state = target_state_touching;
+ else if ((z > U41_PROX_LEVEL) && (z < 0))
+ state = target_state_hover;
+ else if (z == U41_PROX_LEVEL)
+ state = target_state_prox;
+ else
+ state = target_state_not_present;
+
+ dev_dbg(ax->dev, "Target %d: x=%u y=%u z=%d present=%d\n", i, x,
+ y, z, active);
+
+ switch (state) {
+ case target_state_not_present:
+ case target_state_prox:
+
+ input_mt_slot(ax->input, i);
+ input_mt_report_slot_inactive(ax->input);
+ break;
+
+ case target_state_hover:
+ case target_state_touching:
+
+ input_mt_slot(ax->input, i);
+ input_report_abs(ax->input, ABS_MT_TRACKING_ID, i);
+ input_report_abs(ax->input, ABS_MT_POSITION_X, x);
+ input_report_abs(ax->input, ABS_MT_POSITION_Y, y);
+
+ if (state == target_state_touching) {
+ input_report_abs(ax->input, ABS_MT_DISTANCE, 0);
+ input_report_abs(ax->input, ABS_MT_PRESSURE, z);
+ } else { /* Hover */
+ input_report_abs(ax->input, ABS_MT_DISTANCE, -z);
+ input_report_abs(ax->input, ABS_MT_PRESSURE, 0);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ input_mt_sync_frame(ax->input);
+ input_sync(ax->input);
+
+ return 0;
+}
+
+static int axiom_process_report(struct axiom *ax, u8 *report)
+{
+ u16 hdr_buf = get_unaligned_le16(&report[0]);
+ struct u34_report_header hdr;
+ u16 crc_report;
+ u16 crc_calc;
+ int err;
+ u8 len;
+
+ dev_dbg(ax->dev, "Payload Data %*ph\n", ax->max_report_len, report);
+
+ hdr.report_length = FIELD_GET(AX_U34_LEN_MASK, hdr_buf);
+ hdr.overflow = !!(hdr_buf & AX_U34_OVERFLOW);
+ hdr.report_usage = FIELD_GET(AX_U34_USAGE_MASK, hdr_buf);
+
+ len = hdr.report_length << 1;
+ if (hdr.report_length == 0) {
+ dev_err(ax->dev, "Zero length report discarded.\n");
+ return -EIO;
+ }
+
+ // Length is 16 bit words and remove the size of the CRC16 itself
+ crc_report = (report[len - 1] << 8) | (report[len - 2]);
+ crc_calc = crc16(0, report, (len - 2));
+
+ if (crc_calc != crc_report) {
+ dev_err(ax->dev,
+ "CRC mismatch! Expected: %04X, Calculated CRC: %04X. Report discarded.\n",
+ crc_report, crc_calc);
+ return -EIO;
+ }
+
+ switch (hdr.report_usage) {
+ case AX_2DCTS_REPORT_ID:
+ err = axiom_process_u41_report(ax,
+ &report[AX_U34_PAYLOAD_BUFFER]);
+ break;
+
+ default:
+ break;
+ }
+
+ return err;
+}
+
+static void axiom_poll(struct input_dev *input_dev)
+{
+ struct axiom *ax = input_get_drvdata(input_dev);
+ int err;
+
+ /* Read touch reports from u34 */
+ err = ax->bus_ops->read(ax->dev, ax->u34_address, ax->max_report_len,
+ ax->read_buf);
+ if (err)
+ return;
+
+ err = axiom_process_report(ax, ax->read_buf);
+ if (err)
+ dev_err(ax->dev, "Failed to process report: %d\n", err);
+}
+
+static irqreturn_t axiom_irq(int irq, void *handle)
+{
+ struct axiom *ax = handle;
+ int err;
+
+ /* Read touch reports from u34 */
+ err = ax->bus_ops->read(ax->dev, ax->u34_address, ax->max_report_len,
+ ax->read_buf);
+ if (err)
+ goto out;
+
+ err = axiom_process_report(ax, ax->read_buf);
+ if (err)
+ dev_err(ax->dev, "Failed to process report: %d\n", err);
+
+out:
+ return IRQ_HANDLED;
+}
+
+struct axiom *axiom_probe(const struct axiom_bus_ops *bus_ops,
+ struct device *dev, int irq)
+{
+ struct input_dev *input_dev;
+ struct axiom *ax;
+ int err;
+
+ ax = devm_kzalloc(dev, sizeof(*ax), GFP_KERNEL);
+ if (!ax)
+ return ERR_PTR(-ENOMEM);
+
+ input_dev = devm_input_allocate_device(dev);
+ if (!input_dev) {
+ pr_err("ERROR: aXiom-core: Failed to allocate memory for input device!\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ ax->dev = dev;
+ ax->input = input_dev;
+ ax->bus_ops = bus_ops;
+ ax->irq = irq;
+
+ dev_info(dev, "aXiom Probe\n");
+ if (poll_enable)
+ dev_info(dev, "Polling Period : %u\n", poll_period);
+ else
+ dev_info(dev, "Device IRQ : %u\n", ax->irq);
+
+ axiom_set_capabilities(input_dev);
+
+ err = axiom_init_dev_info(ax);
+ if (err) {
+ dev_err(ax->dev, "Failed to read device info, err: %d\n", err);
+ return ERR_PTR(err);
+ }
+
+ if (poll_enable) {
+ err = input_setup_polling(input_dev, axiom_poll);
+ if (err) {
+ dev_err(ax->dev, "could not set up polling mode, %d\n",
+ err);
+ return ERR_PTR(err);
+ }
+
+ input_set_poll_interval(input_dev, poll_period);
+ } else {
+ err = devm_request_threaded_irq(ax->dev, ax->irq, NULL,
+ axiom_irq,
+ IRQF_ONESHOT,
+ "axiom_irq", ax);
+ if (err)
+ return ERR_PTR(err);
+ }
+
+ err = input_register_device(input_dev);
+ if (err) {
+ dev_err(ax->dev, "Failed to register input device: %d\n", err);
+ return ERR_PTR(err);
+ }
+
+ input_set_drvdata(input_dev, ax);
+
+ return ax;
+}
+EXPORT_SYMBOL_GPL(axiom_probe);
+
+MODULE_AUTHOR("TouchNetix <support@touchnetix.com>");
+MODULE_DESCRIPTION("aXiom touchscreen core logic");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/axiom_core.h b/drivers/input/touchscreen/axiom_core.h
new file mode 100644
index 000000000000..8ca46200bede
--- /dev/null
+++ b/drivers/input/touchscreen/axiom_core.h
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TouchNetix aXiom Touchscreen Driver
+ *
+ * Copyright (C) 2020-2026 TouchNetix Ltd.
+ *
+ * Author(s): Mark Satterthwaite <mark.satterthwaite@touchnetix.com>
+ * Pedro Torruella <pedro.torruella@touchnetix.com>
+ * Bart Prescott <bartp@baasheep.co.uk>
+ * Hannah Rossiter <hannah.rossiter@touchnetix.com>
+ * Andrew Thomas <andrew.thomas@touchnetix.com>
+ */
+
+#ifndef __AXIOM_CORE_H
+#define __AXIOM_CORE_H
+
+#include <linux/input.h>
+
+#define AX_POLLING_PERIOD_MS (10)
+
+#define AXIOM_PAGE_SIZE (256)
+// u31 has 2 pages for usage table entries. (2 * PAGE_SIZE) / U31_BYTES_PER_USAGE = 85
+#define AXIOM_MAX_READ_SIZE (2 * AXIOM_PAGE_SIZE)
+#define SIZE_U31_DEVICE_INFO (12)
+#define SIZE_U31_USAGE_ENTRY (6)
+#define U31_MAX_USAGES (85U)
+#define U41_MAX_TARGETS (10U)
+#define U41_PROX_LEVEL (-128)
+#define AXIOM_HOLDOFF_DELAY_US (40)
+
+enum ax_comms_op_e { AX_WR_OP = 0, AX_RD_OP = 1 };
+
+enum report_ids_e {
+ AX_2DCTS_REPORT_ID = 0x41,
+};
+
+enum axiom_mode_e {
+ AX_RUNTIME_STATE = 0,
+ AX_BOOTLOADER_STATE = 1,
+};
+
+enum usage_type_e {
+ UNKNOWN = 0,
+ OTHER = 1,
+ REPORT = 2,
+ REGISTER = 3,
+ REGISTER_READ_ONLY_ = 4,
+ CDU = 5,
+ CDU_READ_ONLY_ = 6,
+};
+
+struct axiom_device_info {
+ u16 device_id;
+ u8 mode;
+ u8 runtime_fw_rev_minor;
+ u8 runtime_fw_rev_major;
+ u8 device_build_variant;
+ u8 runtime_fw_status;
+ u8 tcp_revision;
+ u8 bootloader_fw_rev_minor;
+ u8 bootloader_fw_rev_major;
+ u8 jedec_id;
+ u8 num_usages;
+ u8 silicon_revision;
+ u8 runtime_fw_rev_patch;
+};
+
+struct u31_usage_entry {
+ u8 usage_num;
+ u8 start_page;
+ u8 num_pages;
+ u8 max_offset;
+ u8 offset_type;
+ u8 uifrevision;
+ u8 usage_type;
+};
+
+struct axiom_cmd_header {
+ __le16 target_address;
+ __le16 length_and_op;
+} __packed;
+
+struct axiom_bus_ops {
+ u16 bustype;
+ int (*write)(struct device *dev, u16 addr, u16 length, void *values);
+ int (*read)(struct device *dev, u16 addr, u16 length, void *values);
+};
+
+enum u41_target_state_e {
+ target_state_not_present = 0,
+ target_state_prox = 1,
+ target_state_hover = 2,
+ target_state_touching = 3,
+};
+
+struct axiom {
+ struct device *dev;
+ int irq;
+ struct input_dev *input;
+ const struct axiom_bus_ops *bus_ops;
+ struct axiom_device_info dev_info;
+ struct u31_usage_entry usage_table[U31_MAX_USAGES];
+ u16 max_report_len;
+ u16 u34_address;
+
+ u8 read_buf[AXIOM_MAX_READ_SIZE];
+};
+
+struct u34_report_header {
+ u8 report_length;
+ u8 overflow;
+ u8 report_usage;
+};
+
+struct axiom *axiom_probe(const struct axiom_bus_ops *bus_ops,
+ struct device *dev, int irq);
+
+#endif /* __AXIOM_CORE_H */
diff --git a/drivers/input/touchscreen/axiom_i2c.c b/drivers/input/touchscreen/axiom_i2c.c
new file mode 100644
index 000000000000..93b445f4ce54
--- /dev/null
+++ b/drivers/input/touchscreen/axiom_i2c.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TouchNetix aXiom Touchscreen Driver
+ *
+ * Copyright (C) 2020-2026 TouchNetix Ltd.
+ *
+ * Author(s): Mark Satterthwaite <mark.satterthwaite@touchnetix.com>
+ * Pedro Torruella <pedro.torruella@touchnetix.com>
+ * Bart Prescott <bartp@baasheep.co.uk>
+ * Hannah Rossiter <hannah.rossiter@touchnetix.com>
+ * Andrew Thomas <andrew.thomas@touchnetix.com>
+ */
+
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/unaligned.h>
+#include "axiom_core.h"
+
+static int axiom_i2c_read_block_data(struct device *dev, u16 addr, u16 length,
+ void *values)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct axiom_cmd_header cmd_header;
+ u16 len_op;
+ int err;
+
+ put_unaligned_le16(addr, &cmd_header.target_address);
+ len_op = (length & 0x7FFF) | (AX_RD_OP << 15);
+ put_unaligned_le16(len_op, &cmd_header.length_and_op);
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = sizeof(cmd_header),
+ .buf = (u8 *)&cmd_header,
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = length,
+ .buf = values,
+ },
+ };
+
+ err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (err < 0) {
+ dev_err(dev, "I2C transfer error: %d\n", err);
+ return err;
+ }
+
+ udelay(AXIOM_HOLDOFF_DELAY_US);
+
+ return err != ARRAY_SIZE(msgs) ? -EIO : 0;
+}
+
+static int axiom_i2c_write_block_data(struct device *dev, u16 addr, u16 length,
+ void *values)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct axiom_cmd_header cmd_header;
+ u16 len_op;
+ int err;
+
+ put_unaligned_le16(addr, &cmd_header.target_address);
+ len_op = (length & 0x7FFF) | (AX_WR_OP << 15);
+ put_unaligned_le16(len_op, &cmd_header.length_and_op);
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = sizeof(cmd_header),
+ .buf = (u8 *)&cmd_header,
+ },
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = length,
+ .buf = values,
+ },
+ };
+
+ err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (err < 0) {
+ dev_err(dev, "I2C transfer error: %d\n", err);
+ return err;
+ }
+
+ udelay(AXIOM_HOLDOFF_DELAY_US);
+
+ return err != ARRAY_SIZE(msgs) ? -EIO : 0;
+}
+
+static const struct axiom_bus_ops axiom_i2c_bus_ops = {
+ .bustype = BUS_I2C,
+ .write = axiom_i2c_write_block_data,
+ .read = axiom_i2c_read_block_data,
+};
+
+static int axiom_i2c_probe(struct i2c_client *client)
+{
+ struct axiom *axiom;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "I2C functionality not Supported\n");
+ return -EIO;
+ }
+
+ axiom = axiom_probe(&axiom_i2c_bus_ops, &client->dev, client->irq);
+ if (IS_ERR(axiom))
+ return dev_err_probe(&client->dev, PTR_ERR(axiom),
+ "failed to register input device\n");
+
+ return 0;
+}
+
+static const struct i2c_device_id axiom_i2c_id_table[] = {
+ { "axiom-i2c" },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, axiom_i2c_id_table);
+
+static const struct of_device_id axiom_i2c_dt_ids[] = {
+ {
+ .compatible = "tnx,axiom-i2c",
+ .data = "axiom",
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, axiom_i2c_dt_ids);
+
+static struct i2c_driver axiom_i2c_driver = {
+ .driver = {
+ .name = "axiom_i2c",
+ .of_match_table = axiom_i2c_dt_ids,
+ },
+ .id_table = axiom_i2c_id_table,
+ .probe = axiom_i2c_probe,
+};
+
+module_i2c_driver(axiom_i2c_driver);
+
+MODULE_AUTHOR("TouchNetix <support@touchnetix.com>");
+MODULE_DESCRIPTION("aXiom touchscreen I2C bus driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0.0");
diff --git a/drivers/input/touchscreen/axiom_spi.c b/drivers/input/touchscreen/axiom_spi.c
new file mode 100644
index 000000000000..a7d9d3dd66ce
--- /dev/null
+++ b/drivers/input/touchscreen/axiom_spi.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TouchNetix aXiom Touchscreen Driver
+ *
+ * Copyright (C) 2020-2026 TouchNetix Ltd.
+ *
+ * Author(s): Mark Satterthwaite <mark.satterthwaite@touchnetix.com>
+ * Pedro Torruella <pedro.torruella@touchnetix.com>
+ * Bart Prescott <bartp@baasheep.co.uk>
+ * Hannah Rossiter <hannah.rossiter@touchnetix.com>
+ * Andrew Thomas <andrew.thomas@touchnetix.com>
+ */
+
+#include <linux/of.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/input.h>
+#include <linux/unaligned.h>
+#include "axiom_core.h"
+
+#define SPI_PADDING_LEN (32)
+
+static int axiom_spi_transfer(struct device *dev, enum ax_comms_op_e op,
+ u16 addr, u16 length, void *values)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ u8 pad_buf[SPI_PADDING_LEN] = { 0 };
+ struct axiom_cmd_header cmd_header;
+ struct spi_transfer xfr_header;
+ struct spi_transfer xfr_padding;
+ struct spi_transfer xfr_payload;
+ struct spi_message msg;
+ u16 len_op;
+ int err;
+
+ put_unaligned_le16(addr, &cmd_header.target_address);
+ len_op = (length & 0x7FFF) | (AX_RD_OP << 15);
+ put_unaligned_le16(len_op, &cmd_header.length_and_op);
+
+ memset(&xfr_header, 0, sizeof(xfr_header));
+ memset(&xfr_padding, 0, sizeof(xfr_padding));
+ memset(&xfr_payload, 0, sizeof(xfr_payload));
+
+ /* Setup the SPI transfer operations */
+ xfr_header.tx_buf = &cmd_header;
+ xfr_header.len = sizeof(cmd_header);
+
+ xfr_padding.tx_buf = pad_buf;
+ xfr_padding.len = sizeof(pad_buf);
+
+ switch (op) {
+ case AX_WR_OP:
+ xfr_payload.tx_buf = values;
+ break;
+ case AX_RD_OP:
+ xfr_payload.rx_buf = values;
+ break;
+ default:
+ dev_err(dev, "%s: invalid operation: %d\n", __func__, op);
+ return -EINVAL;
+ }
+ xfr_payload.len = length;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfr_header, &msg);
+ spi_message_add_tail(&xfr_padding, &msg);
+ spi_message_add_tail(&xfr_payload, &msg);
+
+ err = spi_sync(spi, &msg);
+ if (err < 0) {
+ dev_err(&spi->dev, "Failed to SPI transfer, error: %d\n", err);
+ return err;
+ }
+
+ udelay(AXIOM_HOLDOFF_DELAY_US);
+
+ return 0;
+}
+
+static int axiom_spi_read_block_data(struct device *dev, u16 addr, u16 length,
+ void *values)
+{
+ return axiom_spi_transfer(dev, AX_RD_OP, addr, length, values);
+}
+
+static int axiom_spi_write_block_data(struct device *dev, u16 addr, u16 length,
+ void *values)
+{
+ return axiom_spi_transfer(dev, AX_WR_OP, addr, length, values);
+}
+
+static const struct axiom_bus_ops axiom_spi_bus_ops = {
+ .bustype = BUS_SPI,
+ .write = axiom_spi_write_block_data,
+ .read = axiom_spi_read_block_data,
+};
+
+static int axiom_spi_probe(struct spi_device *spi)
+{
+ struct axiom *axiom;
+ int err;
+
+ /* Set up SPI */
+ spi->bits_per_word = 8;
+ spi->mode = SPI_MODE_0;
+ spi->max_speed_hz = 4000000;
+
+ if (spi->irq == 0)
+ dev_err(&spi->dev, "No IRQ specified!\n");
+
+ err = spi_setup(spi);
+ if (err < 0) {
+ dev_err(&spi->dev, "%s: SPI setup error %d\n", __func__, err);
+ return err;
+ }
+ axiom = axiom_probe(&axiom_spi_bus_ops, &spi->dev, spi->irq);
+ if (IS_ERR(axiom))
+ return dev_err_probe(&spi->dev, PTR_ERR(axiom),
+ "failed to register input device\n");
+
+ return 0;
+}
+
+static const struct spi_device_id axiom_spi_id_table[] = {
+ { "axiom-spi" },
+ {},
+};
+MODULE_DEVICE_TABLE(spi, axiom_spi_id_table);
+
+static const struct of_device_id axiom_spi_dt_ids[] = {
+ {
+ .compatible = "tnx,axiom-spi",
+ .data = "axiom",
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, axiom_spi_dt_ids);
+
+static struct spi_driver axiom_spi_driver = {
+ .id_table = axiom_spi_id_table,
+ .driver = {
+ .name = "axiom_spi",
+ .of_match_table = axiom_spi_dt_ids,
+ },
+ .probe = axiom_spi_probe,
+};
+
+module_spi_driver(axiom_spi_driver);
+
+MODULE_AUTHOR("TouchNetix <support@touchnetix.com>");
+MODULE_DESCRIPTION("aXiom touchscreen SPI bus driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0.0");
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] dt-bindings: input: touchscreen: add TouchNetix aXiom device tree
2026-01-26 16:38 ` [PATCH 1/2] dt-bindings: input: touchscreen: add TouchNetix aXiom device tree Andrew Thomas
@ 2026-01-26 17:32 ` Rob Herring (Arm)
2026-01-27 14:16 ` Rob Herring
1 sibling, 0 replies; 5+ messages in thread
From: Rob Herring (Arm) @ 2026-01-26 17:32 UTC (permalink / raw)
To: Andrew Thomas
Cc: linux-kernel, devicetree, Marco Felsch, Conor Dooley,
Dmitry Torokhov, Krzysztof Kozlowski, Henrik Rydberg, linux-input
On Mon, 26 Jan 2026 16:38:23 +0000, Andrew Thomas wrote:
> ---
> .../bindings/input/touchscreen/tnx,axiom.yaml | 70 ++++++++++++++++++++++
> .../devicetree/bindings/vendor-prefixes.yaml | 2 +
> 2 files changed, 72 insertions(+)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.example.dtb: /example-0/i2c/touchscreen@66: failed to match any schema with compatible: ['tnx,axiom-i2c']
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.example.dtb: touchscreen@66 (tnx,axiom-i2c): 'axiom,poll-enable', 'axiom,poll-period' do not match any of the regexes: '^#.*', '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', '^(pciclass|pinctrl-single|#pinctrl-single|PowerPC),.*', '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', '^(simple-audio-card|st-plgpio|st-spics|ts|vsc8531),.*', '^100ask,.*', '^70mai,.*', '^8dev,.*', '^9tripod,.*', '^GEFanuc,.*', '^IBM,.*', '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9#+\\-._@]{0,63}$', '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*', '^acbel,.*', '^acelink,.*', '^acer,.*', '^acme,.*', '^actions,.*', '^actiontec,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^adieng,.*', '^admatec,.*', '^advantech,.*', '^aeroflexgaisler,.*', '^aesop,.*', '^airoha,.*', '^al,.*', '^alcatel,.*', '^aldec,.*', '^alfa-network,.*', '^algoltek,.*', '^allegro,.*', '^allegromicro,.*', '^alliedtelesis,.*', '^alliedvision,.*', '^allo,.*', '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*', '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*', '^amphenol,.*', '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^anbernic,.*', '^andestech,.*', '^anlogic,.*', '^anvo,.*', '^aoly,.*', '^aosong,.*', '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arcom,.*', '^arctic,.*', '^arcx,.*', '^arduino,.*', '^argon40,.*', '^ariaboard,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^armsom,.*', '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^asl-tek,.*', '^aspeed,.*', '^asrock,.*', '^asteralabs,.*', '^asus,.*', '^atheros,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axiado,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^belling,.*', '^bestar,.*', '^bhf,.*', '^bigtreetech,.*', '^bitmain,.*', '^blaize,.*', '^bluegiga,.*', '^blutek,.*', '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bsh,.*', '^bst,.*', '^bticino,.*', '^buffalo,.*', '^buglabs,.*', '^bur,.*', '^bytedance,.*', '^calamp,.*', '^calao,.*', '^calaosystems,.*', '^calxeda,.*', '^cameo,.*', '^canaan,.*', '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cct,.*', '^cdns,.*', '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^chargebyte,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chongzhou,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^cix,.*', '^clockwork,.*', '^cloos,.*', '^cloudengines,.*', '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compal,.*', '^compulab,.*', '^comvetia,.*', '^congatec,.*', '^coolpi,.*', '^coreriver,.*', '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', '^csky,.*', '^csot,.*', '^csq,.*', '^csr,.*', '^ctera,.*', '^ctu,.*', '^cubietech,.*', '^cudy,.*', '^cui,.*', '^cypress,.*', '^cyx,.*', '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^deepcomputing,.*', '^dell,.*', '^delta,.*', '^densitron,.*', '^denx,.*', '^devantech,.*', '^dfi,.*', '^dfrobot,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', '^digilent,.*', '^dimonoff,.*', '^diodes,.*', '^dioo,.*', '^djn,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^dream,.*', '^ds,.*', '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebbg,.*', '^ebs-systart,.*', '^ebv,.*', '^eckelmann,.*', '^econet,.*', '^edgeble,.*', '^edimax,.*', '^edt,.*', '^ees,.*', '^eeti,.*', '^egnite,.*', '^einfochips,.*', '^eink,.*', '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*', '^embedfire,.*', '^embest,.*', '^emcraft,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*', '^enbw,.*', '^enclustra,.*', '^endian,.*', '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^engleder,.*', '^epcos,.*', '^epfl,.*', '^epson,.*', '^esp,.*', '^est,.*', '^eswin,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*', '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*', '^ezurio,.*', '^facebook,.*', '^fairchild,.*', '^fairphone,.*', '^faraday,.*', '^fascontek,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*', '^feiyang,.*', '^fii,.*', '^firefly,.*', '^fitipower,.*', '^flipkart,.*', '^focaltech,.*', '^forlinx,.*', '^foursemi,.*', '^foxlink,.*', '^freebox,.*', '^freecom,.*', '^frida,.*', '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^fxtec,.*', '^galaxycore,.*', '^gameforce,.*', '^gardena,.*', '^gateway,.*', '^gateworks,.*', '^gcw,.*', '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gehc,.*', '^gemei,.*', '^gemtek,.*', '^genesys,.*', '^genexis,.*', '^geniatech,.*', '^giantec,.*', '^giantplus,.*', '^glinet,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^gocontroll,.*', '^goldelico,.*', '^goodix,.*', '^google,.*', '^goramo,.*', '^gplus,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*', '^haochuangyi,.*', '^haoyu,.*', '^hardkernel,.*', '^hce,.*', '^headacoustics,.*', '^hechuang,.*', '^hideep,.*', '^himax,.*', '^hinlink,.*', '^hirschmann,.*', '^hisi,.*', '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*', '^honeywell,.*', '^hoperf,.*', '^hoperun,.*', '^hp,.*', '^hpe,.*', '^hsg,.*', '^htc,.*', '^huawei,.*', '^hugsun,.*', '^huiling,.*', '^hwacom,.*', '^hxt,.*', '^hycon,.*', '^hydis,.*', '^hynitron,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*', '^icplus,.*', '^idt,.*', '^iei,.*', '^ifi,.*', '^ifm,.*', '^ilitek,.*', '^imagis,.*', '^img,.*', '^imi,.*', '^inanbo,.*', '^incircuit,.*', '^incostartec,.*', '^indiedroid,.*', '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^ingrasys,.*', '^injoinic,.*', '^innocomm,.*', '^innolux,.*', '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*', '^invensense,.*', '^inventec,.*', '^inversepath,.*', '^iom,.*', '^irondevice,.*', '^isee,.*', '^isil,.*', '^issi,.*', '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jadard,.*', '^jasonic,.*', '^jdi,.*', '^jedec,.*', '^jenson,.*', '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^jide,.*', '^joz,.*', '^jty,.*', '^jutouch,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*', '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*', '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*', '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*', '^lattice,.*', '^lckfb,.*', '^lctech,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*', '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*', '^lincolntech,.*', '^lineartechnology,.*', '^linkease,.*', '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*', '^liontron,.*', '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*', '^longcheer,.*', '^lontium,.*', '^loongmasses,.*', '^loongson,.*', '^lsi,.*', '^luckfox,.*', '^lunzn,.*', '^luxul,.*', '^lwn,.*', '^lxa,.*', '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marantec,.*', '^marvell,.*', '^maxbotix,.*', '^maxim,.*', '^maxlinear,.*', '^maxtor,.*', '^mayqueen,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*', '^mediatek,.*', '^medion,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*', '^mellanox,.*', '^memsensing,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*', '^methode,.*', '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*', '^microsys,.*', '^microtips,.*', '^mikroe,.*', '^mikrotik,.*', '^milianke,.*', '^milkv,.*', '^miniand,.*', '^minix,.*', '^mips,.*', '^miramems,.*', '^mitsubishi,.*', '^mitsumi,.*', '^mixel,.*', '^miyoo,.*', '^mntre,.*', '^mobileye,.*', '^modtronix,.*', '^moortec,.*', '^mosaixtech,.*', '^motorcomm,.*', '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*', '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*', '^mxic,.*', '^mxicy,.*', '^myir,.*', '^national,.*', '^neardi,.*', '^nec,.*', '^neofidelity,.*', '^neonode,.*', '^netcube,.*', '^netgear,.*', '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*', '^newhaven,.*', '^newvision,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nicera,.*', '^nintendo,.*', '^nlt,.*', '^nokia,.*', '^nordic,.*', '^nothing,.*', '^novatech,.*', '^novatek,.*', '^novtech,.*', '^nuclei,.*', '^numonyx,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*', '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^ocs,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*', '^olpc,.*', '^oneplus,.*', '^onie,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^openailab,.*', '^opencores,.*', '^openembed,.*', '^openpandora,.*', '^openrisc,.*', '^openwrt,.*', '^option,.*', '^oranth,.*', '^orisetech,.*', '^ortustech,.*', '^osddisplays,.*', '^osmc,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*', '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^particle,.*', '^pda,.*', '^pegatron,.*', '^pericom,.*', '^pervasive,.*', '^phicomm,.*', '^phontech,.*', '^phytec,.*', '^picochip,.*', '^pinctrl-[0-9]+$', '^pine64,.*', '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*', '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^polyhex,.*', '^pool[0-3],.*', '^portwell,.*', '^poslab,.*', '^pov,.*', '^powertip,.*', '^powervr,.*', '^powkiddy,.*', '^pri,.*', '^primeview,.*', '^primux,.*', '^probox2,.*', '^prt,.*', '^pulsedlight,.*', '^purism,.*', '^puya,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*', '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^quanta,.*', '^radxa,.*', '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raumfeld,.*', '^raydium,.*', '^raystar,.*', '^rda,.*', '^realtek,.*', '^relfor,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*', '^retronix,.*', '^revotics,.*', '^rex,.*', '^rfdigital,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*', '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^ronetix,.*', '^roofull,.*', '^roseapplepi,.*', '^rve,.*', '^saef,.*', '^sakurapi,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*', '^satoz,.*', '^sbs,.*', '^schindler,.*', '^schneider,.*', '^schulercontrol,.*', '^sciosense,.*', '^sdmc,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*', '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sercomm,.*', '^sff,.*', '^sgd,.*', '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shift,.*', '^shimafuji,.*', '^shineworld,.*', '^shiratech,.*', '^si-en,.*', '^si-linux,.*', '^sielaff,.*', '^siemens,.*', '^sifive,.*', '^siflower,.*', '^sigma,.*', '^sii,.*', '^sil,.*', '^silabs,.*', '^silan,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*', '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*', '^sinowealth,.*', '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*', '^smartfiber,.*', '^smartlabs,.*', '^smartrg,.*', '^smi,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*', '^solomon,.*', '^somfy,.*', '^sony,.*', '^sophgo,.*', '^sourceparts,.*', '^spacemit,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*', '^square,.*', '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*', '^starry,.*', '^startek,.*', '^starterkit,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*', '^storopack,.*', '^summit,.*', '^sunchip,.*', '^sundance,.*', '^sunplus,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synaptics,.*', '^synology,.*', '^synopsys,.*', '^taos,.*', '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tcu,.*', '^tdo,.*', '^team-source-display,.*', '^technexion,.*', '^technologic,.*', '^techstar,.*', '^techwell,.*', '^teejet,.*', '^teltonika,.*', '^tempo,.*', '^tenda,.*', '^tenstorrent,.*', '^terasic,.*', '^tesla,.*', '^test,.*', '^tfc,.*', '^thead,.*', '^thine,.*', '^thingyjp,.*', '^thundercomm,.*', '^thwc,.*', '^ti,.*', '^tianma,.*', '^tlm,.*', '^tmt,.*', '^tnx,.*', '^topeet,.*', '^topic,.*', '^topland,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*', '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*', '^transpeed,.*', '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^turing,.*', '^tuxedo,.*', '^tyan,.*', '^tyhx,.*', '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ufispace,.*', '^ugoos,.*', '^ultrarisc,.*', '^ultratronik,.*', '^uni-t,.*', '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^usr,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*', '^valve,.*', '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^vertexcom,.*', '^via,.*', '^vialab,.*', '^vicor,.*', '^videostrong,.*', '^virtio,.*', '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*', '^vocore,.*', '^voipac,.*', '^voltafield,.*', '^vot,.*', '^vscom,.*', '^vxt,.*', '^wacom,.*', '^wanchanglong,.*', '^wand,.*', '^waveshare,.*', '^wd,.*', '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*', '^widora,.*', '^wiligear,.*', '^willsemi,.*', '^winbond,.*', '^wingtech,.*', '^winlink,.*', '^winsen,.*', '^winstar,.*', '^wirelesstag,.*', '^wits,.*', '^wlf,.*', '^wm,.*', '^wobo,.*', '^wolfvision,.*', '^x-powers,.*', '^xen,.*', '^xes,.*', '^xiaomi,.*', '^xicor,.*', '^xillybus,.*', '^xingbangda,.*', '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*', '^yadro,.*', '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^yiming,.*', '^ylm,.*', '^yna,.*', '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^yuridenki,.*', '^yuzukihd,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*', '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*'
from schema $id: http://devicetree.org/schemas/vendor-prefixes.yaml
Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.example.dtb: /example-1/spi/touchscreen@0: failed to match any schema with compatible: ['tnx,axiom-spi']
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/20260126-axiom-driver-submission3-v1-1-d462c4a608e3@touchnetix.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] dt-bindings: input: touchscreen: add TouchNetix aXiom device tree
2026-01-26 16:38 ` [PATCH 1/2] dt-bindings: input: touchscreen: add TouchNetix aXiom device tree Andrew Thomas
2026-01-26 17:32 ` Rob Herring (Arm)
@ 2026-01-27 14:16 ` Rob Herring
1 sibling, 0 replies; 5+ messages in thread
From: Rob Herring @ 2026-01-27 14:16 UTC (permalink / raw)
To: Andrew Thomas
Cc: Dmitry Torokhov, Krzysztof Kozlowski, Conor Dooley,
Henrik Rydberg, linux-input, devicetree, linux-kernel,
Marco Felsch
On Mon, Jan 26, 2026 at 04:38:23PM +0000, Andrew Thomas wrote:
> ---
Also needs a commit message and S-o-b.
> .../bindings/input/touchscreen/tnx,axiom.yaml | 70 ++++++++++++++++++++++
> .../devicetree/bindings/vendor-prefixes.yaml | 2 +
> 2 files changed, 72 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml b/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml
> new file mode 100644
> index 000000000000..7b532471c17f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml
> @@ -0,0 +1,70 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/input/touchscreen/tnx,axiom.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: TouchNetix aXiom Touchscreen Controller
> +
> +maintainers:
> + - Andrew Thomas <andrew.thomas@touchnetix.com>
> +
> +description: |
Don't need '|' if no formatting to preserve.
> + The TouchNetix aXiom series are high-performance touchscreen controllers
> + supporting various interface methods including I2C and SPI.
> +
> +properties:
> + compatible:
> + enum:
> + - tnx,axiom
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + description: Both IRQ_TYPE_LEVEL_LOW and IRQ_TYPE_EDGE_FALLING are supported
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> +
> +allOf:
> + - $ref: touchscreen.yaml#
> + - $ref: /schemas/spi/spi-peripheral-props.yaml#
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/irq.h>
> +
> + i2c {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + touchscreen@66 {
> + compatible = "tnx,axiom-i2c";
> + reg = <0x66>;
> + interrupt-parent = <&gpio>;
> + interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
> + axiom,poll-enable;
> + axiom,poll-period = <15>;
> + };
> + };
> +
> + - |
> + #include <dt-bindings/interrupt-controller/irq.h>
> +
> + spi {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + touchscreen@0 {
> + compatible = "tnx,axiom-spi";
> + reg = <0>;
> + interrupt-parent = <&gpio>;
> + interrupts = <24 IRQ_TYPE_EDGE_FALLING>;
> + };
> + };
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index f1d1882009ba..dadfc7036ed7 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -1636,6 +1636,8 @@ patternProperties:
> description: Trusted Logic Mobility
> "^tmt,.*":
> description: Tecon Microprocessor Technologies, LLC.
> + "^tnx,.*":
> + description: TouchNetix
> "^topeet,.*":
> description: Topeet
> "^topic,.*":
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-01-27 14:16 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-26 16:38 [PATCH 0/2] Input: add support for aXiom touchscreen controller using SPI or I2C Andrew Thomas
2026-01-26 16:38 ` [PATCH 1/2] dt-bindings: input: touchscreen: add TouchNetix aXiom device tree Andrew Thomas
2026-01-26 17:32 ` Rob Herring (Arm)
2026-01-27 14:16 ` Rob Herring
2026-01-26 16:38 ` [PATCH 2/2] Input: add support for aXiom touchscreen controller using SPI or I2C Andrew Thomas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox